Since it's time for my [to-be] weekly report I wrote down a few words about my progress.
First comes the boring stuff (not boring in a sense that it is boring for me to do, but may be rather boring for the reader). From now on lein-droid correctly handles multiple Android devices connected to the machine. If there is only one of them it directs all device-specific commands (like install or run) to it, otherwise it prompts user to choose the correct device. The user can also specify the device from the command line since all device-specific commands now accept additional arguments same as adb binary (like -d for the only connected device, -e for emulator, or -s SERIAL_NUMBER for the very particular thing).
I added a code-gen task that generates R.java files from the available resources (like images, strings and XML layouts). After the file is compiled with the compile task and goes all the way to the final application.
A minor change in sign task - now it automatically creates a debug keystore if it can't find one. The default path for the keystore is /home/username/.android/debug.keystore (the one Eclipse uses) but if you can change it by providing a value to the :profiles/:dev/:android/:keystore-path in project.clj.
So with all these changes lein-droid bumped to version 0.0.2 and is available on Clojars.
Now to the fun part. I extended and sophisticated my UI toolkit by providing a convenient way of defining "keyword to real thing" relations. Let me substantiate this. Since my initial intent was (and is) to generate in compile time as much as possible, the toolkit needs to know in compile time what the user has passed to it. Class names are not entirely great for this since they are just symbols (so we have to believe user that this symbol will be resolved into the class name when compiled). But if the class names are bound to the respective keywords beforehand then it is safer and easier to use these keywords. Furthermore we need some kind of ad-hoc hierarchy between elements (I partly mentioned it in my previous post). Some attributes (like :layout-height and :layout-width) require special treatment when generating code, and we would like to reuse these specific handlers across multiple elements.
One thing I'm not quite comfortable with is that I had to add eval into the UI-generating facility. I added it to let user manipulate his UI tree any way he wants before feeding it to the defui macro. Without eval user must provide the whole tree as-is to the macro call. In order to better explain what I mean a little demonstration follows.
Image may be NSFW.
Clik here to view.
First I define a simple map of attributes that all my buttons will share. It means that all buttons would fill the entire vertical space they are granted and adjust themselves space-equally in the horizontal dimension. An interesting point arises here. We just defined an ad-hoc style for a button to reuse in any other button (or any other View). A feature that required certain implementation in XML we received for free, just for the fact that we're using the same language for both data (UI in this case) and logic.
Then I write a function called number-button that given a number returns an element of our DSL for describing a button. As you could already see I don't write all number buttons manually, I just call this function with different arguments to generate templates for different buttons. I say "templates" because they will be turned into real buttons later by defui macro.
The final block is how the complete interface is defined. Don't mind the stuff function - it equals (comp vec concat) because I have to insert the generated buttons to the LinearLayouts and every element in the tree looks like [type attributes & inner-elements], so I need to actually append every button to the :linear-layout vector (I might change this in future, perhaps). There are some undefined functions which are not necessary for the demonstration. The whole application code is available here.
There are still a couple of sad things I discovered while working on this. The stack overflows when compiling some elaborate macro. It even overflows on the simplest usages of for macro. Fortunately the separation helps, so if an overflow happens I promote some parts to separate functions and it helps. Though it may seriously hamper productivity when devising really complex layouts.
Anyways that's it for now. Thank you for reading and I'll be happy to answer any questions that may arise.
First comes the boring stuff (not boring in a sense that it is boring for me to do, but may be rather boring for the reader). From now on lein-droid correctly handles multiple Android devices connected to the machine. If there is only one of them it directs all device-specific commands (like install or run) to it, otherwise it prompts user to choose the correct device. The user can also specify the device from the command line since all device-specific commands now accept additional arguments same as adb binary (like -d for the only connected device, -e for emulator, or -s SERIAL_NUMBER for the very particular thing).
I added a code-gen task that generates R.java files from the available resources (like images, strings and XML layouts). After the file is compiled with the compile task and goes all the way to the final application.
A minor change in sign task - now it automatically creates a debug keystore if it can't find one. The default path for the keystore is /home/username/.android/debug.keystore (the one Eclipse uses) but if you can change it by providing a value to the :profiles/:dev/:android/:keystore-path in project.clj.
So with all these changes lein-droid bumped to version 0.0.2 and is available on Clojars.
Now to the fun part. I extended and sophisticated my UI toolkit by providing a convenient way of defining "keyword to real thing" relations. Let me substantiate this. Since my initial intent was (and is) to generate in compile time as much as possible, the toolkit needs to know in compile time what the user has passed to it. Class names are not entirely great for this since they are just symbols (so we have to believe user that this symbol will be resolved into the class name when compiled). But if the class names are bound to the respective keywords beforehand then it is safer and easier to use these keywords. Furthermore we need some kind of ad-hoc hierarchy between elements (I partly mentioned it in my previous post). Some attributes (like :layout-height and :layout-width) require special treatment when generating code, and we would like to reuse these specific handlers across multiple elements.
One thing I'm not quite comfortable with is that I had to add eval into the UI-generating facility. I added it to let user manipulate his UI tree any way he wants before feeding it to the defui macro. Without eval user must provide the whole tree as-is to the macro call. In order to better explain what I mean a little demonstration follows.
(def button-attributesThis code generates the UI you see on the screenshot. It's a bit messy and isn't probably what I would write in the real application. Right, it's rather a proof of concept. Let me describe it step by step.
{:layout-width 0
:layout-weight 1
:layout-height :fill})
(defn number-button [i]
[:button
(assoc button-attributes
:text (str i)
:onClickListener `(on-click
(add-symbol ~i)))])
(defui
(stuff
[:linear-layout {:orientation :vertical
:layout-width :fill
:layout-height :fill}
[:edit {:id ::edit
:layout-width :fill}]]
(map (fn [i]
(stuff
[:linear-layout {:orientation :horizontal
:layout-width :fill
:layout-height 0
:layout-weight 1}]
(map (fn [j]
(let [n (+ (* i 3) j)]
(number-button n)))
(range 1 4))))
(range 3))
[[:linear-layout {:orientation :horizontal
:layout-width :fill
:layout-height 0
:layout-weight 1}
[:button (assoc button-attributes
:text (str \u2190)
:onClickListener '(on-click (delete-symbol)))]
(number-button 0)
[:button (assoc button-attributes
:text "Call"
:onClickListener '(on-click (call-number)))]]]))
Image may be NSFW.
Clik here to view.

Then I write a function called number-button that given a number returns an element of our DSL for describing a button. As you could already see I don't write all number buttons manually, I just call this function with different arguments to generate templates for different buttons. I say "templates" because they will be turned into real buttons later by defui macro.
The final block is how the complete interface is defined. Don't mind the stuff function - it equals (comp vec concat) because I have to insert the generated buttons to the LinearLayouts and every element in the tree looks like [type attributes & inner-elements], so I need to actually append every button to the :linear-layout vector (I might change this in future, perhaps). There are some undefined functions which are not necessary for the demonstration. The whole application code is available here.
There are still a couple of sad things I discovered while working on this. The stack overflows when compiling some elaborate macro. It even overflows on the simplest usages of for macro. Fortunately the separation helps, so if an overflow happens I promote some parts to separate functions and it helps. Though it may seriously hamper productivity when devising really complex layouts.
Anyways that's it for now. Thank you for reading and I'll be happy to answer any questions that may arise.