Fork me on GitHub
#humbleui
<
2023-08-16
>
Nick Cellino05:08:59

Hello 👋 I’m playing around with HumbleUI and have a basic question. How do I make the UI “reactive” to changes in state? I assumed this is what the ui/dynamic macro helps with but I’m having trouble. For example, in the code below, I would have thought that evaluating (reset! *message "Goodbye") would change the message displayed in the window, but I’m not seeing that - the message stays as “Hello”

(ns ui-test
  (:require [io.github.humbleui.ui :as ui]))

(def *message (atom "Hello"))

(def ui
  (ui/default-theme {}
    (ui/center
      (ui/dynamic _ [message @*message]
        (ui/label message)))))

(ui/start-app!
  (ui/window
    {:title "Humble 🐝 UI"}
    ui))

(comment
  (reset! *message "Goodbye"))

Niki13:08:48

dynamic is a temporary solution, and it’s not reactive

Niki13:08:20

You should call window/request-frame after you change your atom. Dynamic will pick up the change but it won't trigger re-render by itself

Nick Cellino13:08:00

Ah okay. Is that what the examples in dev/examples are using?

Niki14:08:51

Yes and no

Niki14:08:36

Most of the examples don’t do that because they have e.g. button and when you press a button it needs to repaint itself. So there’s no need to request repaint explicitly. But it’s just a coincidence, don’t rely on it

Niki14:08:55

The best way is to add-watch to your state and call request-frame. See e.g. examples.treemap

Nick Cellino14:08:32

Okay will look into that later after work. Thank you 🙏 I watched your Wordle video on YouTube and was curious how the UI seemed to update when you updated any aspect of the state (like the currently :typing word or :guesses, etc)

Nick Cellino14:08:15

maybe that’s just the coincidental repainting you mentioned?

Nick Cellino21:08:30

Okay got it working! In case it helps anyone else, here’s a minimal example:

(ns ui-test
  (:require [io.github.humbleui.ui :as ui]
            [io.github.humbleui.window :as window]))

(def *message (atom "Hello!"))

(def example-ui
  (ui/default-theme {}
    (ui/center
      (ui/dynamic _ [message @*message]
        (ui/label message)))))

(ui/start-app!
  (let [window (ui/window
                  {:title "Humble 🐝 UI"}
                  example-ui)]
    (add-watch *message :message
      (fn [_ _ _ _]
        (window/request-frame window)))
    window))

(comment
  ; Evaluate the form below and UI will update
  (reset! *message "Goodbye"))

👍 2