I'm trying to design a desktop UI for schematics, layout, drawing stuff. Just looking for high level advice from actual software designers.
Assuming an in-memory "database", (clojure map of arbitrary depth for all user data, and possibly another one for application preferences, etc.), I'm examining how to do the model-view-controller thing on these, where the data may be rendered and modified by any one or more of:
Modifying any one of these should show up immediately in every other active view, both text and graphical, not after clicking "ok"... so no modal boxes allowed. If for some reason the table view, an inspector view, and a graphical rendering are all in view, dragging the corner of the box graphically should immediately show up in the text, etc.
The platform in question is JavaFX, but I'd like a clean separation between UI and everything else, so I want to avoid bind
ing in the JFX sense, as that ties my design data very tightly to JFX Properties, increases the graininess of the model, and forces me to work outside the standard clojure functions for dealing with data, and/or deal heavily with the whole getValue
/setValue
world.
I'm still assuming at least some statefulness/mutability, and the use of built-in Clojure functionality such as the ability to add-watch
on an atom/var/ref and let the runtime signal dependent functions.
Platform-specific interaction will rest tightly with the actual UI, such as reifying ActionListener
s, and dealing with ObservableValue
s etc., and will attempt to minimize the reliance on things like JavaFX Property
for actual application data. I'm not entertaining FRP for this.
I don't mind extending JFX interfaces or making up my own protocols to use application-specific defrecord
s, but I'd prefer for the application data to remain as straight Clojure data, unsullied by the platform.
The question is how to set this all up, with closest adherence to the immutable model. I see a few options:
(deref...)
junk. I believe this is how JFX would want to do this, with giant arrays of Properties at the leaf nodes, etc., which feels bloated. With this approach it doesn't seem much better than just coding it up in Java/C++.I also need the ability for one data template to be instantiated many times. So for example if the user changes a symbol or shape which is used in multiple places, a single edit will apply everywhere. I believe this also requires some type of "pointer"-like behavior. I think I can store a atom to the model, then instantiate as needed, and it can work in any of the above grain models.
Any other approaches? Is trying to do a GUI editor-like tool in a functional language just stupid? Thanks
I don't think is stupid to use a functional language to do a GUI editor-like tool. But I can't claim to have an answer to your question. Here are some links that might help you in your journey:
Erik Meijer has a good quote about functional vs imperative code:
...no matter whether it's Haskell, C# Java, F#, Scala, Python, PHP think about the idea of having a sea of imperative code that interacts with the outside world and in there have islands of pure code where you write your functions in a pure way. But you have to decide how big the islands are and how big the sea is. But the answer is never that there are only islands or only sea. A good programmer knows exactly the right balance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With