This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-13
Channels
- # announcements (12)
- # babashka (88)
- # beginners (60)
- # biff (10)
- # calva (56)
- # clerk (9)
- # clj-kondo (5)
- # clojure (70)
- # clojure-austin (3)
- # clojure-conj (2)
- # clojure-dev (69)
- # clojure-europe (53)
- # clojure-nl (1)
- # clojure-norway (28)
- # clojure-uk (1)
- # clojurescript (27)
- # copenhagen-clojurians (3)
- # cursive (10)
- # datascript (1)
- # datomic (10)
- # fulcro (3)
- # funcool (1)
- # garden (7)
- # helix (5)
- # holy-lambda (5)
- # hyperfiddle (39)
- # introduce-yourself (6)
- # jobs-discuss (15)
- # lsp (3)
- # malli (5)
- # membrane (19)
- # missionary (1)
- # nrepl (6)
- # off-topic (44)
- # pathom (17)
- # pomegranate (3)
- # react (7)
- # releases (1)
- # shadow-cljs (39)
- # tools-deps (16)
- # xtdb (28)
Hey I'm coming back to membrane to draw some visuals after not using it for a bit. I'm a little rusty so mainly asking this to see if I'm missing something obvious. I'm using skija as the drawing platform. I have this code:
(ui/with-style :membrane.ui/style-stroke
(apply ui/horizontal-layout
(for [[colnum row->v]
{4 {1 "id0", 2 "id1", 3 "id2"},
5 {1 "id3", 2 "id4", 3 "id5", 4 "id6"},
6 {1 "id7", 2 "id8", 3 "id9", 4 "id10"},
7 {1 "id11", 2 "id12", 3 "id13"},
8 {1 "id14"}}]
(apply ui/vertical-layout
(for [[peer v] row->v]
(ui/padding 20
(let [rect (ui/rectangle 50 50)
label (ui/center (ui/label v) (ui/bounds rect) )]
[rect label])))))))
Which in the attached image.
Is there a way in membrane to draw a line from one of these rectangles to another one? That is, if I can keep a reference to all the rect
records, is there a way to get the absolute location of any two of them given a common parent? Is the only obvious way to do this (without re-implementing the layout engine) by pre-calculating coordinates manually and not using the horizontal/vertical layout features?There's more than one way to do it.
I think the way I would do it is traverse the created views to get a mapping of rect coordinates that you could use. horizontal and vertical layout are really just measuring and stacking items. It seems like you're working with a fairly regular grid, so it wouldn't be unreasonable to write a few helper functions to do the layout within the grid.
I'll write some example code. One sec.
ok, here's quick sketch. It's a little longer than I'd like, but hopefully most of the uninteresting parts can be hidden away in a util.clj
or similar.
This solution uses zippers. I can update the example with something else, but zippers do a really great job of fulfilling the OO equivalent parent/back references.
The other thing to note is the introduction of IContentOffset
. ui/bounds
and ui/origin
conflate hitboxes, view extents, and probably a few other things. This is a known problem and something I'd like to fix in membrane, but I'm also trying to avoid partial fixes until I get a chance to think things through a bit more (or reference someone else who has thought it through).
I think @U63D7UXJB has also been working on diagramming and maybe has some tips.
I've also done some basic diagramming. It would be nice to investigate building a standalone library similar to mermaid.
If the layout is grid based, I might also explicitly model that.
It's easy to create a protocol which you use to lay out elements eg top-left bottom-right, also easy to write your own eg horizontal-layout
What would be more involved/interesting might be changing how events get dispatched based on capture but it's not super necessary as they just get passed along
It's tricky because it seems like working at a higher level like this (without pixel coords, or possibly any coords, but as you say, explicit nominal coords might be worth it too) is desirable when possible, but it takes a bit of effort to get there too, it's sort of unclear before implementing a couple options which will be the nicest to actually use
I think because html DOM is such a cluster fuck people might assume rolling your own here is harder than it is
I should keep a list of missing utilities somewhere so that they can either be added to membrane or packaged in helper libraries.
I always hit this pattern of problem where I want to draw say a graph, look up some libraries, find one that looks nice, say https://js.cytoscape.org/#notation/graph-model (i tried this first. Well, after graphviz which also wasn't really doing what I want without hacks). But then before the day is over I always hit something that is basically impossible to express cleanly in that framework. Like I wanted to add labels to the x and y axis here, you can't do that in cytoscape without awkwardly using separate graph items as labels, or shoving the graph in a dom and trying to line things up there. Like it seems like it would be ideal if a "graph" library could just plug into an existing ui/layout engine (like membrane 🙂 ) and it's job is just to draw the lines nicely between things with splines and whatever nice graph features. But instead every visualization/charting/etc library re-implements it's own layout/coordinate stuff in a non-compatible way, and they all have a learning curve, and you always hit limitations (at least I always do)
Yeah I've felt this, if they yielded effects/data it would help but people also want interactions
Added a https://github.com/phronmophobic/membrane/discussions/66#discussioncomment-5085064 in github discussions to start keeping track of "missing pieces".