April 26, 2006

My blog has moved

Hi folks. I've decided to move my blog off the Adobe servers and onto my own domain. The new address is http://kuwamoto.org/.

The blog at this address will no longer be updated.

If you have any links, please update them. Thanks!

Posted by sho at 10:14 PM

April 17, 2006

Openings on the Adobe Flex team

Hi folks. We are still looking for great people to help us build Flex and Flex Builder.

Here are the openings in the US:

WW020602-Developer, Flex Enterprise
TB010604-Senior Quality Engineer
LM020604-Flex Builder QE Engineer
WW020603-Architect, Flex Enterprise
SK120506-Computer Scientist
HW020602-Computer Scientist - Flex Builder

And here are the openings in India:

Senior Computer Scientist
Quality Engineer
Quality Manager

If you or someone you know is a good fit for these positions, let us know!

Thanks!

Posted by sho at 11:09 AM

April 10, 2006

New Flex component - Sliding Drawer v 0.5

I created a panel that slides into view when you mouse near the edge of the screen as part of a personal project. I'm distributing the sliding drawer under creative commons so that other people can use it.

To use the drawer component, just add the tag to your view:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ui="sho.ui.*">
	
    <ui:Drawer title="Left" dockSide="left">
        < !-- drawer contents go here -- >
    </ui:Drawer>

</mx:Application>

This results in a drawer that pulls out from the left edge of the screen like so:

DrawerDemo.png

NOTE: Requires Flash Player 8.5 beta 2.

[Demo - sliding Drawers]
[Source code]

Known issues:

Posted by sho at 10:36 AM

April 5, 2006

AS3 -- on the lack of private and protected constructors

As I was talking about using objects as enums, someone made a comment about the lack of private and protected constructors. I know that the this is a sore spot, so I thought I'd explain my view of how we got here, and give my two cents.

The problem is that unlike what we did with ActionScript 2, we are working tightly with people from Mozilla and others to standardize on ECMAScript edition 4. The ECMAScript standard is not final, but we are adhering as closely as we can to the spec as it develops.

Private and protected constructors is not something that the group has been able to tackle yet, and it is a nontrivial change to the language that requires lots of careful thought.

Ideally, we would have been able to think through all the ramifications of private and protected constructors and work with other ECMA members to make sure the design was sound, but that just wasn't possible in the amount of time we had.

Given this, there were three choices:

1) Delay ActionScipt 3 (and Flex, etc.) significantly.
2) Just "go with" a quick and dirty implementation of private and protected constructors for AS3 and risk compatibility problems down the road once the ECMA spec becomes final.
3) Don't allow private and protected constructors for now.

We went with option (3).

The main uses of private and protected constructors are singletons and abstract base classes. In both of these cases, I agree that the lack of real private and protected constructors is a pain. There are hackarounds which will work for now, but I am eagerly awaiting the day when we don't have to use them anymore.

As for the specific use case described in the previous post (using objects as enumerations), the main thing that private/protected constructors allows you to do is to ensure that the set of "enum" values cannot be extended later by someone else.

I personally like having this level of control, but I am willing to live without it. It "feels better" to create a system where no one can add any more values to the enumeration, but in practice,

a) If people create new values for the enumeration and try to use them with code that wasn't expecting those values, it will obviously break. So who is going to do this?

b) If people create new values for the enumeration and use them only within their own code... well... it kind of breaks the spirit of what an enumeration is, but it might be just fine.

Here's a concrete example of scenario (b). Imagine that I create a text control with three values for alignment: LEFT, RIGHT, and CENTER. Someone subclasses this control, and wants to create a fourth enumeration value: JUSTIFY. This new value would obviously only be useful for this person's subclass, but who am I to say that he/she shouldn't create it?

Like I said, I would ideally like the option of controlling what can and can't get extended, but in the case of enumerations, I'm ok with not having that control for now.

Posted by sho at 9:03 AM

April 4, 2006

AS3 technique -- using object instances as "enums"

Just after posting the updated version of the CompletionInput control, it occured to me that I should read through the source code to make sure there's nothing too strange lurking in there.

One thing that might warrant some explanation is why I used object instances to represent "enums". This is a technique that should be familiar to Java developers but may not be familiar to all AS developers.

In LoopResult.as, I define constants like this:

public class LoopResult {
    public static const KEEP_GOING : LoopResult = new LoopResult();
    public static const STOP : LoopResult = new LoopResult(); 
}

Whereas in CompletionInput.as, I define them like this:

public class CompletionInput extends mx.controls.TextInput 
{
    public static const COMPLETION_FAILED    : int = 1;
    public static const COMPLETION_SUCCEEDED : int = 2;
    public static const COMPLETION_ASYNC     : int = 3;
    ...
}

In both cases, I use these static members as if they were "enums".

	...
	return LoopResult.KEEP_GOING;
or
	return CompletionInput.COMPLETION_SUCCEEDED;

The main difference between the two is that the first version is typesafe -- I can declare my function as returning a LoopResult, not an int or a String.

PRO:
CON:

Posted by sho at 10:16 AM

April 3, 2006

Flex auto complete text input control v0.6

Here is a new version of the auto complete text input control, which is a cross between Google suggest, the "save information I typed in forms" preference found in browsers, and the HTML <select> control.

If you provide a static list of items to the control, the control can do the filtering. Alternatively, you can create a function to give suggestions (which is necessary if you are doing the filtering on the server).

As before, there is a "mustSelect" flag which turns the control into a sort of super version of the HTML <select> tag. The main benefit to using this instead of <select> is that using the keyboard to narrow down your choices is much easier.

Finally, I added the ability to automatically save form data as local storage and provide hints based on this data. This makes it behave similarly to HTML text fields in most browsers.

Unlike how browsers work (so far...) you can individually delete these hints. I hate it when I mistype something into a field and I get a hint for that typo every time I visit the app! With these controls, you can right mouse on any of the hints you don't like and delete them.

NOTE: Flex beta 2 is REQUIRED for viewing or using this control.
[Sample -- Simple form using CompletionInput]
[Source code]

Known issues:

Let me know what you think. And if you find any bugs, please let me know (especially if you have a fix!!)

Posted by sho at 10:41 AM

Layering Flex over AJAX and collaborating with data services -- whoa!

Christophe just posted an example of how to layer Flex over AJAX to do video chat and shared whiteboard as an overlay to Google Maps. You could use this to draw a route on a map for someone else to see, for example.

I think my head is going to explode.

http://coenraets.com/viewarticle.jsp?articleId=100

Posted by sho at 9:11 AM

March 28, 2006

Last minute change - speaking at FITC

Hi folks.

As it turns out, I will be speaking at FITC in place of Christian Cantrell*, who is on leave. Nominally, the talk is on Flex Builder, but I'd like to solicit your opinion -- what should I be talking about? Is it worthwhile to have a one hour session focused purely on the tool? There is only one other Flex talk, which is a Flex overview given by Chafic.

The reason I am asking is that my gut tells me that spending 50% of the time on the framework and 50% of the time on the tool feels like the wrong balance.

* (footnote) This is ironic, because Christian was actually filling in for me, because I was originally unable to do FITC because of my schedule, which has since changed.

Posted by sho at 10:19 PM

March 21, 2006

Flex 2.0 beta 2 now available

Flex 2.0 beta 2 is now available at labs.adobe.com.

Highlights
--

All the gory details are available at http://labs.macromedia.com/wiki/index.php/Flex:Beta_1_to_Beta_2_Changes

Posted by sho at 8:49 AM

March 8, 2006

FAB - Flex / AJAX bridge

FAB - Flex/AJAX Bridge - is a library created by Ely Greenfield, who is a good friend and Flex Architect.

FAB lets you control Flex applications using JavaScript. Method calls just work, and getters and setters are converted to method calls (because browsers don't support getters and setters yet).

You can even attach event listeners from JavaScript and pass function objects back and forth. For example, you can create an MXML file with a button in it and drive all of the logic from within your HTML/JavaScript.

MXML:
--
<mx:Application xmlns:mx="http://www.macromedia.com/2005/mxml">
    <fab:FABridge xmlns:fab="bridge.*" />
    <mx:Button id="okButton" label="OK" />
</mx:Application>

JavaScript:
--
function init()
{
    var flexApp = FABridge.flash.root();
    flexApp.okButton().addEventListener("click", handleClick);
}

function handleClick(event)
{
    // handle the click event here.
}


You can read more about it on Ely's blog, which I predict will be worth reading.

http://www.quietlyscheming.com/blog/2006/03/06/flex-and-ajax/

Posted by sho at 9:07 AM

March 6, 2006

Slides from Flashforward 2006

As promised, here are my slides and notes from Flashforward. Some things you will need to know:

  1. The layout syntax uses the new beta 2 syntax, which is not out yet.
  2. The notes cover a bit less material than the slides. That's because the notes were finalized before the slides were, in order to get them printed on paper for conference attendees. If I have time, I may extend the notes but with so much going on, I am not sure I will have time to do this.

[Slides - ppt] [Slides - pdf]

[Speaker notes - doc] [Speaker notes - pdf]

Posted by sho at 1:51 PM

March 2, 2006

Impressions from Flashforward

Just got back late last night from Flashforward. Quick impressions:

All in all, a great experience. I'll post notes and slides soon.

Posted by sho at 12:47 PM

February 24, 2006

Evolution of a feature - layout constraints

We spend a lot of time here on the Flex / Flex Builder team arguing over exactly how each piece of the framework should work, and how the syntax should look.

I thought it might be interesting to have a glimpse into how some of these features evolve, and why. I'm picking a particularly controversial example: layout constraints.

---

Layout constraints came about because designers in particular weren't happy using containers for layout. Actually, let me say it a different way. When you drag things around, they generally expect things to stay put, although they are fine with things moving around when it makes sense (like when you drag something into a control bar). And they want pixel level control over the position of every element.

Among coders, feedback on container based layout was mixed. Most of them "got" it, and some of them loved it. But when you step back, it wasn't good for all layouts. Boxy layouts (think forms) were just fine. More freeform layouts (think Flash) were hard to achieve.

There was also a performance issue. Nesting of containers meant nesting of movie clips. Removing the nesting, however, meant that fluid resizing layouts were hard to achieve.

---

For all these reasons, we decided to add a constraint system to Flex. We originally talked about all sorts of more complex ideas -- sibling constraints and other more exotic constraints -- but we settled the more conservative approach of only supporting constraints relative to the parent container.

Let's say that we want to put a button in the top right corner of our app. Our original syntax looked like this:

Attempt 1:
--
<mx:Panel width="100%" height="100%">
    <mx:Canvas width="100%" height="100%">
        <mx:layoutConstraints >
            <mx:EdgeAnchor target="myButton" right="30" />
        </mx:layoutConstraints>
        <mx:Button id="myButton" y="30" />
    </mx:Canvas>
</mx:Panel>

This would allow us to add new types of constraints in the future, such as sibling constraints. The downside, however, lay in the tooling. Every time you add a constraint to a control, you have to add an ID. If the user changes the ID, you have to change it in both places. It's not rocket science, but it's error prone, and it can lead to situations in which the tool is trying to be "too smart".

We moved the layout constraints to be inside the control itself. This fixed the problem of tracking IDs.

Attempt 2:
--
<mx:Panel width="100%" height="100%">
    <mx:Canvas width="100%" height="100%">
        <mx:Button y="30">
            <mx:layoutConstraints>
                <mx:EdgeAnchor right="30" />
            </mx:layoutConstraints>
        </mx:Button>
    </mx:Canvas>
</mx:Panel>

The next issue was that it was confusing to have the canvas inside the panel. People kept accidentally resizing the canvas instead of the panel, or pulling the panel out of the canvas. We also decided that the name "EdgeAnchor" was too verbose.

After much arguing about making things general vs. dealing with the specific needs in the 80% case, we decided to make Panel and Application understand how to do multiple different kinds of layout: absolute, vertical and horizontal.

Attempt 3:
--
<mx:Panel width="100%" height="100%" layout="absolute">
    <mx:Button y="30">
        <mx:layoutConstraints>
            <mx:Anchor right="30" />
        </mx:layoutConstraints>
    </mx:Button>
</mx:Panel>

Right around this time, people were dragging panels into the view, centering them, and expecting them to stay centered no matter what size the browser was. It was especially confusing because Flex Builder has snapping heuristics and the panel would snap into place when it was centered. We dealt with this by adding a centering constraint.


Attempt 4:
--
<mx:Panel width="100%" height="100%" layout="absolute">
    <mx:Button y="30">
        <mx:layoutConstraints>
            <mx:Anchor horizontalCenter="0" />
        </mx:layoutConstraints>
    </mx:Button>
</mx:Panel>

Soon after we made this change, the team was busy doing lots of what we call scenario testing: building applications in the same way our customers would. One thing about layout constraints that stuck out like a sore thumb was its verbosity. Where buttons used to be on a single line, they now occupied 5. We argued about this for a while, and decided to make layout constraints styles, partially because this was consistent with CSS.

We also decided to promote the use of "left" and "top" as opposed to "x" and "y". One might wonder how these are different, but they are. The "left" property is a constraint that specifies the desired position for the left coordinate. The "x" property is the coordinate that an object happens to be at. Thus, if you were to use a move effect to move an object programmtically, its "x" property would change, but its "left" would not.

In any case, the resulting syntax looks like this (not in beta 1, but will be part of beta 2):

Attempt 5:
--
<mx:Panel width="100%" height="100%" layout="absolute">
    <mx:Button top="30" right="30" />
</mx:Panel>

The moral
--
Why did it take so long to arrive at what appears to be an obvious syntax? Perhaps it was too obvious. When we started, we were trying to solve for many different things: forward compatibility, generalizability, and the possibility of many different kinds of constraints. Through trial and error, we arrived at the simplest way to express the basic things we need for this release.

In this case, I am confident we ended up with the right answer, but it took a while. In fact, there are people out there in the Flash community who aren't convinced that layout constraints are a good idea who I think we will turn around based on the new syntax.

Sometimes, these things take time to sort out. The answers always seem obvious in retrospect, but you can't expect to get to the right answer straight away.

Posted by sho at 9:45 PM

February 15, 2006

MXML text completion control v. 0.5 (aka down with combo boxes!)

I've always been frustrated by the way HTML applications use pull down menus. How many times have you had to pick a country out of a huge pull down menu? Do you use the mouse to scroll down to the country? What about using the keyboard? You have to keep hitting the same key over and over. Neither approach is easy.

Meanwhile, text fields that offer completion hints are starting to become standard for Flex and AJAX applications. Typicaly, these are used to let you quickly pick things that you've already typed into the box. They are not used for picking, say, a country from a list of countries.

I believe text input fields that offer hints for possible completions should be used instead of combo boxes 95% of the time. Down with combo boxes!

1) When you want to use the mouse, it is just as simple.
2) When you want to use the keyboard, it gives you better feedback on what you have typed already.
3) It gives you an obvious affordance to "start over" when you've made a typo.
4) It gives you more immediate feedback.

Here is a relatively simple version of a text completion control for MXML. Unlike most versions of this type of control, this is also optimized for the above case: picking from a list of predefined strings.

Run sample

When you want to pick from a list of predefined strings, just supply the list of all strings as the dataProvider of the control (just like how ComboBox works), and set the "mustPick" flag to true.

Let me know what you think. Are there bugs? Do you think the heuristics are wrong? Is this a good idea in general?

P.S. I've also had to include some other random classes as part of this. I plan on officially distributing these classes and other classes once they are more baked.

Posted by sho at 8:25 PM