Bogdanp / racket-gui-easy

Declarative GUIs in Racket.
https://docs.racket-lang.org/gui-easy/index.html
134 stars 18 forks source link

List view + dialog + slider appears not to update correctly #17

Closed benknoble closed 2 years ago

benknoble commented 2 years ago

Demo:

#lang racket

(require racket/gui/easy
         racket/gui/easy/operator)

(define/obs @counters '((0 . 0)
                        (1 . 10)
                        (2 . 30)))

(define (update-count counts k proc)
  (for/list ([entry (in-list counts)])
    (if (eq? (car entry) k)
      (cons k (proc (cdr entry)))
      entry)))

(define (counter @count action)
  (hpanel
    #:stretch '(#t #f)
    (text (@count . ~> . number->string))
    (button "Update" (thunk (render (dialog (slider @count action)))))))

(let ([@c (@ 0)])
  (render
    (window
      (counter @c (λ (new-count) (:= @c new-count))))))
(render
  (window
    #:size '(#f 200)
    (list-view
      @counters
      #:key car
      (λ (k @entry)
        (counter
          (~> @entry cdr)
          (λ (count)
            (<~ @counters (λ (counts)
                            (update-count counts k (const count))))))))))

Interact with the single counter window and you'll notice the slider and the count are (effectively) perfectly sync'd.

Interact with the other window and you'll noticed that only the first mouse click in a click-and-drag on the slider updates the display. Worse, closing the dialog and opening another sometimes updates the display of a previous counter to the correct value.

Adding "debug prints" shows that the state is in fact updated correctly; it is only the display that is not updated.

This is a MRE of a problem I'm facing in another project, hence the toy counters.

Bogdanp commented 2 years ago

Thanks for the report! I've pushed a commit that should fix the consistency problem. Even after this fix, the list view window is less interactive than the other one (the labels only change when you stop moving the progress widget). That's due to the way list views batch updates together, and fixing that might be more involved.

Bogdanp commented 2 years ago

I've pushed another change that disables the batching because I don't think it was really helping in the first place.

Also, this isn't documented, but the library comes with a minimal debugger which you can use to observe observables in lieu of changing the code to add print statements. If you run your code from either DrRacket or racket-mode you can just (require racket/gui/easy/debugger) followed by (start-debugger) at the REPL.

benknoble commented 2 years ago

I updated today and confirm the example no longer demonstrates the bug, thank you!