Clarify: A Fresh Start
A number of months ago my brother Greg and I (Greg is my business partner) realized that we faced a dilemma. For the last 3 1/2 years our company, Blue Mango Learning Systems, has focused primarily on one desktop application. We released ScreenSteps 2 back in January of 2008 and have been working on it ever since. ScreenSteps is essentially a screen capture tool with a built-in document editor but over the years it has evolved into an application that focuses primarily on visual documentation.
The problem was that the underlying concept of capturing images and quickly creating a document out of them was also very handy for the daily communications people have with customers, co-workers and others.
While ScreenSteps certainly enables you to capture images, add text and send off the resulting document, the UI and workflow are not optimized for this type of use. It is optimized for creating documentation. In addition, we found that the marketing message became muddled when trying to tell people that ScreenSteps is a documentation tool as well as a tool for daily communications.
After weighing our options Greg and I decided that we needed to create a separate application designed specifically for creating these quick communications that we have on a daily basis. A new application would allow us to design with a single focus in mind and it would allow us to focus the stories we would tell when marketing. So we got to work and on October 11, 2011 we released Clarify.
Starting work on Clarify was very refreshing. From a programming perspective I had been able to see the long term effects of design decisions I had made in ScreenSteps. Some were good, some were bad and some made me cringe. Also, LiveCode as a development tool has evolved considerably over the last 4 years which meant I would have lots of new features available as I designed the foundation that Clarify would be built on.
For example, since I started ScreenSteps object behaviors were introduced to LiveCode. I would have designed a number of components in ScreenSteps very differently if behaviors had been available. With Clarify I could start with a clean slate, pulling in the ideas that had worked, improve the ideas that would benefit from new features in LiveCode and find better solutions for the ideas that flopped.
In this article I want to look at a few things that were done differently in Clarify given the perspective gained from ScreenSteps.
Outsourcing The Graphical Work
From the very beginning Greg and I decided we would outsource of all the UI and icon work. We are NOT designers and we knew from experience that we could not come up with a design that we would be proud of. Furthermore, when we would try to do the graphic work ourselves we would spend an enormous amount of time trying to come up with a design that was acceptable. It ended up being a waste of time with an unsatisfying result.
For the Clarify UI design we brought in the team at Worry Free Labs. Greg and I would mockup ideas on paper and certain features working in LiveCode and then hand it off to Worry Free Labs. They would come back with gorgeous graphics and we could focus on what we do best. The team a pleasure to work with and the resulting UI is better than anything we imagined.
When it comes to cross-platform desktop application icons, these days you need one that scales from 512x512 all the way down to 16x16. It has to look great on your website, the OS X dock, the Mac App Store and on Windows. This can be a tall order. Based on previous work we had seen we turned to the team at SoftFacade and this is what they came up with:
By going out and finding specialists in the areas where we had no expertise, Clarify became a much better product.
Behaviors and Controllers
When I started writing ScreenSteps the concept of behaviors didn't exist. One custom object that I made that is common to both ScreenSteps and Clarify is the image annotator object. This is the object that displays an image and allows the user to draw arrows, rectangles, ovals, etc. on top of the image. An instance of an image annotator is highlighted in red in the screenshot below.
Prior to behaviors in LiveCode I used libraries to share code among multiple instances of the image annotator. The library would process system events, check whether or not the target of the event was an image annotator and then perform an action if it was. This approach did work and it kept me from having to duplicate the image annotator code across every instance of the the object.
There is a significant flaw with this design, however: Events that should be processed by each instance of the image annotator were being handled farther down the message path than they should of been.
This design breaks the natural message hierarchy order that one would expect for a control on a card. The group/card/stack that the image annotator was placed in would respond to system events before the image annotator itself (e.g. mouseDown and mouseUp) which can lead to unintended behavior.
I could have used a front script rather than a library when I originally designed the image annotator. Frontscripts handle messages before they reach objects as opposed to libraries that handle them after. The problem is that there is a 10 script limit when working with frontscripts. If you used frontscripts for each custom object in your application the limit could become a problem.
Needless to say, being able to rewrite the image annotator using behaviors made my programming life much easier. I could attach a shared script to each image annotator object and no longer had to worry about issues with the message path. When I handled a mouseUp event in the image annotator behavior I knew it was being processed at the proper place in the message hierarchy.
Another area where I used behaviors was in document windows. Each document you open in Clarify spawns a new document editor window that is based on a template. Since each document window uses the exact same code I decided to create a Document Controller Library to manage everything.
In the image above you can see that the Document Window Controller library is a stack. This stack is inserted into the message path as a library. This library is in charge of managing all of the open documents. It can create new documents, open existing documents, close document, list all of the open documents, etc.
You can also see in the image above that the stack has a Document Window Behavior button. This button contains the behavior script used by the Document Window Template stack seen below. This stack is the template that is duplicated each time a new document is opened or created.
Creating Custom Objects
Another area of ScreenSteps I wanted to improve in Clarify was how I interacted with data that the user provided. For example, in ScreenSteps and Clarify the user can configure web export accounts. These accounts tell the application how to connect to web services in order to upload content.
In ScreenSteps I had a rudimentary interface for working with this data but it was a little hokey as it was designed before multi-dimensional arrays were available in LiveCode. With Clarify I wanted to improve upon the initial design using the multi-dimensional arrays that were now available to me.
My goal was to treat each account as a separate data object and have interactions with each data object would go through a defined API. Doing so ensures that all property values can be validated when set. I can also define a property that is not stored internally but rather parsed into its component parts before being stored in the data object (think of a URL for example).
In the image below you can see the code used for the web export data object. The code resides in a library stack so it is accessible from any script in the application. All web export accounts reside in a script local variable of this stack script. The API provides a way to get and set values in the script local array as well as a way to restore objects from a previous session or retrieve all of the objects in the current session.
Clarify has a couple of different data objects that have APIs like the one shown above. The design ensures data integrity and provides a clean interface for working with the data in different areas of the application. All of the grunt work is handled behind the API and not duplicated anywhere else.
Being able to start fresh with an application design is a great feeling. I feel like I have a solid code foundation going forward that will be easy to maintain as we build upon it. I'm really looking forward to going through this same process with ScreenSteps for the next major upgrade. The new lock screen enhancements in LiveCode 5.0 will make some great UI transitions possible.