So far, we've danced around the props
parameter that is the initial argument in an init function; we've acknowledged what it is, but haven't really discussed why it's there or how Clojure Desktop Toolkit facilitates its usage. After you've read this chapter, you will understand:
props
atom allows you to link together all parts of a user interfaceYou already know that an init function has the signature:
(fn [props parent] ,,,,)
and that the props
parameter is an atom containing a map.
The application
function creates this props
value, and the same atom is passed to every init function during construction of the user interface. This provides an opportunity for init functions to:
Let's explore this.
When defining a user interface, it can be necessary to save a reference to a particular user interface control so one can reference and/or manipulate it later. For this, use the id!
function. By convention, user interface elements' keywords should use the ui
namespace.
For example:
(shell SWT/SHELL_TRIM (id! :ui/shell))
These ID keywords then are defined as keys in the props map and are available there subsequently for retrieving the associated user interface widget.
If you need to set an arbitrary top-level property value, use reset-prop!
.
(shell SWT/SHELL_TRIM (id! :ui/shell)
(reset-prop! :closing false))
Similarly, Clojure Desktop Toolkit defines:
update-in-prop!
and Clojure's update-in
functionassoc-in-prop!
and Clojure's assoc-in
functionThese Clojure Desktop Toolkit functions do what one would expect to the props atom based on the behavior of the similarly-named Clojure functions.
Since the props atom is a parameter to an init function, one can simply write an init function in a place where one needs to access props. We've already discussed how to do this the manual way:
(shell SWT/SHELL_TRIM (id! :ui/shell)
(reset-prop! :closing false)
(fn [props _parent]
(println (str "Is shell disposed? " (.isDisposed (:ui/shell props))))))
There is API support for this, too.
If you want to explicitly designate your init function (and get arity checking from the compiler), you can use definit
instead of fn
here.
(shell SWT/SHELL_TRIM (id! :ui/shell)
"Shell title"
(reset-prop! :closing false)
(definit [props parent]
(println (str "Shell title " (.getText (:ui/shell @props))))))
Continuing our contrived example, by convention, the final init function in a top-level shell is named defmain
because this is normally where data loading/binding occurs.
(shell SWT/SHELL_TRIM (id! :ui/shell)
(reset-prop! :closing false)
(defmain [props parent]
(println (str "Is shell disposed? " (.isDisposed (:ui/shell @props))))))
Semantically, these all mean literally the same thing, except that the version with fn
doesn't check that you pass exactly the props
and parent
parameters and no others.
Clojure desktop Toolkit maintains a props "map" behind the scenes. This map can be transformed at any step in the process of constructing a user interface, and it can contain mutable state that the entire user interface needs in order to function correctly. Common things to store in this map include:
To facilitate this, Clojure Desktop Toolkit supplies functions for adding or changing data in this map mirrored after Clojure's own functions for transforming maps.
In addition, CLojure Desktop Toolkit supplies utilities for creating custom init functions when direct access to the props map is necessary.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close