Friday, May 16, 2008

In Place Editing: Extended

Background



A long time ago (a couple years seems like forever these days), Flex guru Ely Greenfield created and posted a collection of In Place Editing Controls that each basically use composition to combine some form of read-only control, such as Label or Text, with an editable control, such as TextInput or TextArea.

The editable and non-editable controls are mutually exclusive (e.g. only one is shown at a time) and are both driven by the same data so that they function as a single component with 2 distinct views or modes. Each IPE control has an editable attribute that defines which view should be shown. To make it the hotness, Ely also includes a FlipBitmap transition between edit and non-edit modes.

In this post, I will describe a few techniques I used (including some minor tweaks to his controls) to support more complex form layouts with in place editing. A lot of this work was done in collaboration with my close friend and colleague, Frankie Loscavio, who has been my inspiration to get started blogging!

IPE In Action



So, recently I was working on a project that was suited for this type of functionality and I decided to dust off Ely's IPE controls and give them try. For the most part, the controls worked as I had expected/remembered, however, the biggest problem I ran into was that I couldn't independently size the editable and non-editable controls.

So lets use an example. Here are 3 IPETextInput fields with a width set to 140. In both editable and non-editable modes, the width is the same, fixed value.

Note: Red dotted lines indicate component bounds for purpose of illustrating fixed dimension.

ipe1.png


Now, this is fine as long as you have all of your fields on separate lines, but my project had a very dense form with a lot of information, so space was at a premium. What I wanted to happen was to have the read-only mode show information collapsed down to its actual size and with related information on the same line. By contrast. the edit mode would show the form fields at the requisite larger sizes, which typically required them to be on separate lines.

Layout Concepts



Read Only Layout



Typically, the optimal layout for read-only data is naturally condensed, often with additional delimiters between particular fields that indicate their relationship rather than their actual value.

The best example is probably an address. The city, state and zip code are each distinct fields; however, they are typically formatted together in one line:

Atlanta, GA 30319-1234

The aspects to note here are that all fields are on the same line and are sized to the dimension of their content (text), and that various delimiters exist between fields based on existence of adjacent fields. For example, the hyphen in the zip code should only appear if both parts (5 + 4) of the zip code exist.

A simpler example could be a person's name:

Ryan Patrick Swanson

In read only view, the layout only requires that the fields are on the same line and collapsed to the size of the text.

Editing Layout



The optimal layout for an editable form is quite different from the read-only layout. Each input field is usually a fixed dimension that is large enough to display the typical length of data. Also, to be aesthetically pleasing, the fields will usually be sized to line up with each other. This often means that fields that would be together on the same line when in read-only layout are on separate lines for editing to allow for a larger input field.

First Step: Box is your friend



Many people I talk to are familiar with HBox and VBox, but often aren't aware that they are just specific-use subclasses of the Box class, which has a direction attribute that can be changed at runtime to switch the axis of layout for the Box's child components. If you haven't guessed it yet, this is how we solve half our problem.

So now we take our previous example put the 3 controls into a Box that will switch direction from vertical to horizontal as the form changes from editable to non-editable.

ipe3.png


...and the code that would accomplish this:

[Bindable] private var editing:Boolean = false;
...
<mx:Box horizontalGap="0" verticalGap="0" direction="{(editing) ? 'vertical' : 'horizontal'}">
<ipeControls:IPETextInput id="firstNameField" editable="{editing}"
text="{contact.firstName}" />
<ipeControls:IPETextInput id="middleNameField" editable="{editing}"
text="{contact.middleName}" />
<ipeControls:IPETextInput id="lastNameField" editable="{editing}"
text="{contact.lastName}" />
</mx:Box>


Second Step: measureText() is also your Friend



For many years and in working with many interface technologies, I have wished I had a relatively simple and valid way to determine the dimension that text will be rendered with a control that has some (arbitrary and unknown to me) styling applied to it. Props to Adobe on this one, Flex has it and after really digging into the underlying source code, it appears to be done in a way that I approve of (if you know me, this doesn't happen too often)!

UIComponent includes 2 functions for measuring text in the context of the stylesheets applied to the class that extends UIComponent: measureText() and measureHTMLText().

In working with Frankie Loscavio on a similar problem regarding measurement of styled text, he initially discovered these functions and we have since found a number of uses for them. For more information on measureText(), please read his blog posting.

So the solution to our problem is to simply set (through bindings) the width of our components conditionally (based on an editing flag) between a fixed size for editing and a measured size for read-only.

<ipeControls:IPETextInput id="firstNameField" editable="{editing}"
text="{contact.firstName}"
width="{(editing) ? 150 :
Math.max(firstNameField.label.measureText(firstNameField.text).width + 4, 1)}" />


Note: I have found I sometimes need to add an offset (4 in the example above) to the measured value, and I am assuming this may be due to padding or some other aspect of the component that is not included in the measurement.

Final Product



So combining these concepts and adding a little polish, here is a simple example of a contact form with name and address information. Full source code is included (right click -> View Source).




Example

Flex Project

Cheers,
Ryan

Friday, May 2, 2008

Flex Builder License Reset

I recently ran into a license key issue with Flex Builder and wanted to share my resolution to the problem.

In a nutshell, I had upgraded from Flex 2 to Flex 3, but accidentally got the Standard version instead of Pro.  I had already entered the license key for Standard and when I went to enter the key for Pro, it balked since it was expecting a Flex 3 Standard to Flex 3 Pro ($499) license key, but the one I purchased was for Flex 2 Pro to Flex 3 Pro ($299).

I simply wanted to get back to the dialog where I could enter my previous Flex 2 Pro key and the new Flex 3 Pro key.

I figured out that I could resolve my problem by first clearing the license # from my license.properties file at:

Windows: %ALLUSERSPROFILE%\Application Data\Adobe\Flex\license.properties
Mac: /Library/Application Support/Adobe/Flex/license.properties

I then restarted Flex Builder and was able to enter my new license information successfully.

Cheers!
Ryan
Blogged with the Flock Browser

Monday, February 25, 2008

Papervision3D Holiday Card for Think Inc.

This past fall I worked with Bryan Wills and the team at Think Interactive, Inc. to create a 3D Holiday Card using Flex 3 Beta 2 and Papervision3D v1.0.

As is often the case, this project was fairly aggressive regarding time and budget, but fortunately using Flex 3 and some open source code we were able to get a final solution that performs decently and is pretty fun to use.

You can try out the application here: Happy Holidays from THINK Interactive.

Where's the Source Code?

I will try to get the source code posted soon if I am able to get it approved by the guys at Think. And I'm sure I'll get it out sooner if people request it (curse me) in the comments.

Holiday Introduction - Setting the Stage

Since this is a holiday card, there is a nice flash movie to set the holiday mood. Bryan Wills did the majority of this work and as always, he does a great job!

thinkholidayintro_thumb.jpg
thinkholidayhouse_thumb.jpg
thinkholidayowners_thumb.jpg

Holiday Party in a Snow Globe

The intro movie completes as you are zoomed into the snow globe at which point you will be in a PaperVision3D environment that has the whole Think Inc. staff inside wearing their holiday garb. Since there are a LOT of people inside, we quickly found that trying to render true 3D COLLADA models of all of the employees was too costly, both in performance and dev time, so we simply load optimized PNG images into Plane components and then manage their rotation so they will always face the camera as it flies around the room.

We initially included COLLADA models for christmas trees, candy canes, presents, etc., but again found it made the room too cluttered and impacted performance too much. This reflects the number of images we were loading (and quality of images that we required) as well as the included audio. In general we have found PaperVision3D to perform very well even with COLLADA models. There are also a number of capabilities with culling and other techniques that can gain performance, but were outside the scope and timeline of this project.

As a side note, we found some clipping issues with Planes close to the camera's focal point, which you may notice this as you navigate around the app. Comments and ideas for fixing this are welcome, though of course, this one is out the door already!

thinkholidayparty_thumb.jpg

Interaction

We went through a dozen or so interaction designs before deciding to keep things simple. Users can pan the camera's view using the mouse position and navigate to view an individual person by clicking on the image of the person or by selecting the person's thumbnail (head) in the fisheye control at the bottom. (props to Ely Greenfield for the use of his Fisheye component).

Users can also use the keyboard to walk around the room, though this was considered a secondary type of navigation since most users wouldn't know to do that (and we didn't want to clutter the interface with instructions for usage).

thinkholidaybryanwills_thumb.jpg

Hope you'll check out the holiday card and give developing with Papervision3D a try. It was a blast to work with and I'm just looking for another opportunity to work on a project with it.

Ryan

Co-Author

Bryan Wills - Think Interactive, Inc.
Bryan's Blog at Think

Contributor

Frankie Loscavio - Frankie's Blog

Thanks to Frankie for all his help researching Papervision3D and COLLADA and in working with various 3D programs (Cinema 4D, 3DS Max, others). Although much of the 3D modeling work we did wasn't included in the final release, the learning experience for me was incredible. If you haven't checked out Frankie's blog and you do any Flex development or design work, you are missing out! He does some awesome work.

Credits

Flex 3 by Adobe

Papervision3D - Core Team: Carlos Ulloa, John Grden, Ralph Hauwert, Tim Knip and Andy Zupko

Fisheye component by Ely Greenfield

Thursday, November 8, 2007

I am a Hybrid

I recently updated my profile on linkedin and thought I'd post my professional summary here since it gives a little insight into my views of what I do for a living and why.

Ryan Swanson’s Summary

My goal is to create compelling user experiences through software.

This requires innovation in design and development and the fusing of capabilities and functionality with intuitive and engaging interfaces. Finding the harmony between form and function is my passion.

I am a hybrid. I am an engineer. I am an artist. I am a developer. I am a designer. I am a leader. I never stop learning, growing, evolving.

I am an entrepreneur. The entrepreneurial spirit is as relevant in a corporate development position as it is in a boutique creative design firm as it is in your own startup. It is about actively looking for a need that is not being met and pro-actively creating what is needed to meet it.

Technology does not exist for its own sake. Creative Suites, Languages, 3D Modeling and Motion Graphics Tools, Integrated Development Environments, Platforms, Protocols... These are the tools we use. Each has its benefits and trade-offs within particular context(s).

I have worked with most of them and have learned this:

Some people argue for an idea or technology they *like* the most or are most familiar with - this is successful only until the context changes.

A few of us recommend an idea or technology after considering its merit within the context for which it exists to solve a problem and will continue to challenge that evaluation knowing that in technology the context is continually changing.

The former tries to win arguments. The latter searches for truth.

I want to change the world. Let's get started!

Sunday, September 9, 2007

blog.ryanswanson.com created

Hello World!

I am finally getting my act together and starting a professional blog. I will primarily use this blog to evangelize the technologies I work with in my career as an RIA Architect and User Experience Designer/Developer, but I will also include anything I find interesting or significant within the broader fields of computing, media, design, art or science.

The technologies I work with include but are not limited to:

  • Adobe Flash, Flex and AIR

  • Adobe Creative Suite products (of which I use almost all)

  • General web technologies such as HTML, CSS, JavaScript

  • The always buzzworthy (though not really all that new for those of us who did it before the term was coined!) AJAX or Asynchronous JavaScript And XML

  • Although I am a recent Apple/Mac convert, I am now a huge fan and love my MacBook Pro, so I should include Apple, Mac, and iPhone on this list.

  • Elements of User Experience: in particular, Information Architecture, Interaction Design, Information Design, Interface Design, Navigation Design, and Visual Design

  • Art and Design in general

  • Significant advances in computing as a whole.

I have been following a number of bloggers for many years and am now hoping to make my contribution after having gained so much from so many bright lights in the community.

The following list includes the individuals whose blogs and community contributions have helped or impressed me the most. Thank you all!

(list to come)

Cheers!
Ryan