Fork me on GitHub
#membrane
<
2020-08-27
>
genekim04:08:48

@smith.adriane Thank you!!! Wow, trying it right now!

šŸ¤ž 3
phronmophobic04:08:36

I forgot to mention you'll need to update you membrane dependency to [com.phronemophobic/membrane "0.9.12-beta"]

genekim04:08:44

Wow!!! It works!!! Not quite sure I understand how this magic worksā€¦ Amazing! Mouse scrolling is reversed ā€”Ā on mac trackpad, text scrolls opposite way expectedā€¦. Trying to flip some signs to see if it fixes it. šŸ™‚

genekim04:08:07

@smith.adriane So funny ā€”Ā itā€™s so autonomic, itā€™s difficult to remember which way textboxes are ā€œsupposedā€ to scroll! šŸ˜†

phronmophobic04:08:26

I think that's because I got used to the wrong way a long time ago and probably coded it to work the wrong way

phronmophobic04:08:45

mac books switched it at some point

genekim04:08:45

Thatā€™s super funny ā€”Ā so this bypasses all the native widget mouse handlingā€¦ far out. šŸ™‚ Stand byā€¦. hopefully will have positive result shortly!

phronmophobic04:08:26

it's not a great fix, but you can change the scroll direction by wrapping the scrollview with:

(defn fix-scroll [elem]
  (ui/on-scroll (fn [[sx sy]]
                  (ui/scroll elem [(- sx) (- sy)]))
                elem))
eg:
(defn test-scrollview []
  [(ui/translate 10 10
                 (fix-scroll
                  (get-scrollview :my-scrollview [300 300]
                                  (ui/label lorem-ipsum))))])

genekim04:08:19

@smith.adriane Holy cow, thatā€™s so helpful. I was studying how get-scrollview worksā€¦. Do I understand that youā€™re putting EDN s-expressions into the event dispatch? e.g., (list 'nil->val [0 0]). Just curious: why do this instead of putting.. I dunno.. anonymous functions instead? (LISPs are amazingā€¦)

phronmophobic05:08:45

that's a good question

phronmophobic05:08:36

the way events work is that each events are a pure function like (fn [elem event] effects) . as the simplest example, here's the checkbox code:

(defui checkbox
  "Checkbox component."
  [& {:keys [checked?]}]
  (on
   :mouse-down
   (fn [_]
     [[::toggle $checked?]])
   (ui/checkbox checked?)))

phronmophobic05:08:55

mouse-down is a pure function that says returns what effects the checkbox proposes given a mouse-down event:

> (ui/mouse-down (membrane.basic-components/checkbox :checked true ) [0 0])
([:membrane.basic-components/toggle [:membrane.component/unknown]])

phronmophobic05:08:07

to make checkbox a pure function, it not only needs to know the value of checked, but it needs an identifier for the checked? property. for membrane.component, I use lenses

phronmophobic05:08:09

there's a bunch of macrology in membrane.component that automatically tracks where property values are derived from so you don't have to worry about it, but you can also pass those values directly:

> (ui/mouse-down (membrane.basic-components/checkbox :checked? true :$checked? ['ATOM :done?] ) [0 0])
([:membrane.basic-components/toggle [ATOM :done?]])

šŸ¤Æ 3
phronmophobic05:08:05

that's what the dollar sign prefix does. the proposed effect says to toggle the path [ATOM :done?]

phronmophobic05:08:35

the path is similar to a keypath like you use in get-in or assoc-in.

phronmophobic05:08:01

lenses give you a little more power than keypaths. if you're familiar with specter, that's what I use under the hood lenses give you a little more power than just walking an associative structure. if you're familiar with

šŸ¤Æ 3
phronmophobic05:08:55

i'm not sure I'm making any sense

phronmophobic05:08:46

regarding the (list 'nil->val [0 0]). it's part of specifying the identity of the :offset property of the scroll view

:$offset [(list 'get sid) :offset (list 'nil->val [0 0])]

genekim05:08:30

šŸ¤Æ Very coolā€¦. It all works! Thanks so much for all this help ā€” I will create a new sample program, using all of these constructs, and put in a couple of suggestions for the docs in a pull request. Super fun!!!

parrot 3
phronmophobic05:08:48

so it's saying if you want to update the :offset state, tell me this path back. when I get this back, I'll do the equivalent of (-> state (get sid) :offset (or [0 0]))

genekim05:08:19

ā€¦okay, wow, never thought Iā€™d actually see Haskell-like lenses in real life, let alone in something UI-related. Iā€™m copying this off to study more tomorrow! In the meantime, Iā€™m going to hack away at the app for a bit! (Note to self: investigate potentially strange behavior around changing subscriptions, which seem to require a REPL restartā€¦) Have a great night!!!

phronmophobic05:08:48

the membrane.component is a little offbeat and deserves its own longer/better explanation which is in the works.

phronmophobic05:08:07

have a great night!

genekim05:08:42

Iā€™m making some great progress now! Another question, which hopefully has much shorter answer ā€”Ā if I want a scrollview, but wraps text, is there an easy way to do that? (Iā€™m using to print out paragraphs of textā€¦) @smith.adriane

phronmophobic05:08:22

I thought that's what the example did:

(defn test-scrollview []
  [(ui/translate 10 10
                 (fix-scroll
                  (get-scrollview :my-scrollview [300 300]
                                  (ui/label lorem-ipsum))))])

phronmophobic05:08:43

and just replace lorem-ipsum with whatever text you're trying to display

phronmophobic05:08:07

or maybe i'm missing some other requirement

genekim05:08:58

ā€¦hang onā€¦ let me post a screenshotā€¦ text that exceeds screen width is clipped, so you have to scroll right. Would love it if it wraps the text to the next lineā€¦

phronmophobic05:08:47

right, you can word wrap before passing to the label. I think I have some code that does that. one sec..

genekim05:08:59

Hahaha. You already have code for that? Thatā€™s super! PS: it occurs to me that youā€™re having to re-implement the functionality of almost all of the native windowing elements. Iā€™m not sure whether to keep asking for these changes (which Iā€™m super grateful for!!), or if this signals that youā€™re doomed to endlessly have to rebuild the wheel that every window manager/window framework has already builtā€¦ But this is very gratifying to see come together!

phronmophobic06:08:35

I thought I had that, but it uses an apache lang library that's not included and I don't remember what the maven dependency is

phronmophobic06:08:57

I think right now, there's some creature comforts missing, but I think(hope) that eventually you get to the a place where you have 80-90% of what people expect out of the box

genekim06:08:17

Roger that! Iā€™ll come up with something in the short term ā€”Ā will keep you posted! Catch you soon!!!

phronmophobic06:08:55

I found this old code as well:

(defn line-wrap [s n]
  (loop [s (seq s)
         current-line []
         lines []
         i 0]
    (if s
      (let [c (first s)]
        (cond

          (= c \newline)
          (do
            
            (recur (next s)
                   []
                   (conj lines current-line)
                   0))

          (>= i n)
          (recur s
                 []
                 (conj lines current-line)
                 0)

          :else
          (recur (next s)
                 (conj current-line c)
                 lines
                 (inc i)))
        
        )
      (clojure.string/join "\n" (map (partial apply str) lines)))))

(def line-wrap-memo (memoize line-wrap))

(defn test-scrollview []
  [(ui/translate 10 10
                 (fix-scroll
                  (get-scrollview :my-scrollview [300 300]
                                  (ui/label (line-wrap-memo lorem-ipsum 20)))))])

phronmophobic06:08:05

it's not perfect since it doesn't it will only necessarily work for non monospaced fonts

genekim06:08:49

Yep! I will either use yours or the WordUtils.wrap() in org.apache.commons.textā€¦. tomorrow. Have a great night!!! PS: hopefully Iā€™ll have my toy app done tomorrow, and I may redo it in cljfx, and compare/contrast, and write it up. I really love the feeling of doing everything without using clojurescript for once!

metal 3