membrane

Ben Sless 2022-10-23T11:48:15.160689Z

Rendering html or other structured text: Parsing is easy, we have libraries for that, but how should things like formatting and links be handled? How do we make a bit of text out of a haystack clickable?

phronmophobic 2022-10-23T16:13:56.306939Z

There's not currently great support for formatted text. The over-engineered way to do it is to use something like https://github.com/phronmophobic/clj-cef. I'd like to provide a good default option for formatted text within membrane at some point. It seems like the java swing library has some support, http://www.java2s.com/Code/Java/2D-Graphics-GUI/ParagraphLayout.htm. Skia has text shaping as well. I'd have to look into it, but I think they might use the same libraries under the hood. > How do we make a bit of text out of a haystack clickable? The main idea is to have a function that maps mouse events to :navigate-url intents or whatever you want to call the intents. A similar thing is done by https://github.com/phronmophobic/membrane/blob/7156976969d2b95cd2cea5feae73ee3780a79e80/src/membrane/basic_components.cljc#L300. You can use membrane.ui/index-for-position to map [x y] coordinates to an index within some text. If you can test which ranges have text, then you should be good to go.

phronmophobic 2022-10-23T16:40:39.001749Z

Still needs some hammock time, but for representing formatted text, I was looking at https://github.com/IGJoshua/ropes or https://github.com/mogenslund/liquid/blob/master/src/liq/buffer.cljc

Ben Sless 2022-10-23T17:13:23.337799Z

Another option that anything that can take text as argument wouldn't just take string, but also some contextual types that add scope, e.g. (text "hello " (bold "world"))

👍 1
Ben Sless 2022-10-23T17:15:35.446149Z

That also solves the issue of both user defined and local styles. These will just look up the proper style in the scope, and you can override the scope a-la (with-style {...} content)

Ben Sless 2022-10-23T17:16:24.414319Z

A stack/environment model looks like the most natural fit for the problem, wdyt?

phronmophobic 2022-10-23T17:18:23.537109Z

depends on the use case

phronmophobic 2022-10-23T17:19:31.674889Z

seems reasonable, but text is tricky and I'd like to do a deep dive on the topic at some point

phronmophobic 2022-10-23T17:24:01.776689Z

what do existing implementations do? how do people like them? what are the trade offs? does this integrate with styling? how does it integrate with events? is it efficient for large documents? is it editable? etc.

phronmophobic 2022-10-23T17:25:13.510009Z

I also wouldn't be opposed to a good 80/20 option that's not too much work to implement

phronmophobic 2022-10-23T17:27:35.316439Z

membrane.ui/label isn't great and it'd be nice to have some better support, but I want to avoid having a bunch of incremental implementations: label2, Text, Text2, FormattedText3

phronmophobic 2022-10-23T17:28:48.787309Z

another short-term solution is to give better access to the options that already exist in Swing, JavaFX, and Skia

phronmophobic 2022-10-23T17:29:14.716919Z

and just try to build a small wrapper on top that is the least common denominator of each

phronmophobic 2022-10-23T17:32:08.683849Z

I am open to alternatives. It feels like the first thing everyone tries is 1) scrollviews and 2) formatted text. Probably because the web makes both of them easy 🤷

Ben Sless 2022-10-23T18:07:31.858169Z

uh, sorry? 🙃

Ben Sless 2022-10-23T18:07:50.083469Z

I found out Swing can just take html

Ben Sless 2022-10-23T18:08:25.594079Z

frame.add(new JLabel("<html>Text color: <font color='red'>red</font></html>"));
Disgusting, isn't it?

phronmophobic 2022-10-23T18:08:36.400809Z

haha

phronmophobic 2022-10-23T18:09:49.031999Z

I don't think it will present the same as all the webkit based options, but probably good enough for some use cases.

Ben Sless 2022-10-23T18:12:06.061359Z

True but it works well with my ad-hoc model, where (text "Text color: " (color :red "red")) can be rendered pretty easily to it

Ben Sless 2022-10-23T18:12:11.324929Z

So that's 1-0 for the good guys

1
Ben Sless 2022-10-23T18:14:56.822429Z

For JavaFX there isn't a solution out of the box, either open a new label, or use something like https://github.com/FXMisc/RichTextFX

phronmophobic 2022-10-23T18:16:14.658469Z

I haven't tried embedding Swing like JLabel. Is it easy to extract it's draw function?

phronmophobic 2022-10-23T18:16:33.970679Z

I imagine there's a way to do it, but haven't tried

phronmophobic 2022-10-23T18:58:09.156209Z

Swing, putting the pain in paint

😄 2
phronmophobic 2022-10-23T19:21:14.934479Z

(import 'javax.swing.JLabel
        'javax.swing.JComponent)

(extend-type javax.swing.JComponent
  IDraw
  (draw [this]
    (.paint this *g*))

  ui/IOrigin
  (-origin [_]
    [0 0 ])

  IBounds
  (-bounds [_]
    (let [dim (.getPreferredSize jlabel)]
      [(.width dim) (.height dim)])))

(defn set-preferred-size [jcomp]
  (let [dim  (.getPreferredSize jcomp)]
   (.setBounds jcomp 0 0 (.width dim) (.height dim))))
(defn my-draw []
  (ui/vertical-layout
   (doto (JLabel. "hsdfkj i\n thereasdf asdf")
     set-preferred-size)

   (ui/label "membrane!!")))

(run #(my-draw))

phronmophobic 2022-10-23T19:21:31.829049Z

I really gotta work on not being nerd sniped so easily

phronmophobic 2022-10-23T19:22:17.976679Z

It's interesting, there's actually some pretty good stuff in the Swing library if you dig deep enough.

Ben Sless 2022-10-23T19:23:29.671739Z

Shake the swing tree, see what falls out

phronmophobic 2022-10-23T20:13:09.392329Z

This seems really neat. I wonder if I can write a macro or something that turns a bunch of the swing components into membrane components.

phronmophobic 2022-10-23T21:01:56.899589Z

I've been against implementing any sort of embedding with the reasoning that if you provide a quick start complected option and a slow start simple option, users will choose the quick start option every time. Maybe there's an automatic method to use Swing or other native components simply!!

Ben Sless 2022-10-24T03:03:29.552979Z

I wasn't planning to encourage embedding, was hoping more for membrane components (pretty, simple, elegant)

phronmophobic 2022-10-24T03:06:36.793399Z

yea, the long term plan is to have a graphical editor that plays well with programmer tools. not sure if you saw https://github.com/phronmophobic/schematic/blob/main/src/com/phronemophobic/membrane/figma.clj, but it's a proof of concept for importing figma files. There's still a few missing drawing primitives, but it's surprisingly close.

👀 1
phronmophobic 2022-10-24T03:07:49.271429Z

a lot of UI libraries take while to get decent looking components because you have reimplement design files. I'm hoping I can leap-frog that step.

phronmophobic 2022-10-24T03:38:24.903359Z

phronmophobic 2022-10-24T03:39:23.502239Z

still needs some work, but it seems plausible

Ben Sless 2022-10-24T03:42:39.566149Z

The final boss - text

🤣 1
phronmophobic 2022-10-24T03:43:54.345289Z

it's so true. that, and animations

Ben Sless 2022-10-24T04:06:47.129489Z

What I like about the idea of contextual blocks for text properties is it at least plays with membrane's model of path updates. I'm cautiously optimistic

👍 1