There is probably only a handful of things that are probably less understood at the SDK level as to how just exactly the Drag-Drop event sequence is generated, captured, and handled. First off, the UIComponent is the one where events can be registered but does absolutely nothing about dispatching or even ‘psuedo-dispatching’ through an intermediary.


Not In Here:

Case is point – we all know about the DragManager, and how you have to enable certain targets to allow the capture sequence to generate events for the final drop event, however it’s really the SystemManager that handles a bunch of marshalling for you – since it sits at the near root level it knows about MouseEvents for just about every object.

It’s this ferrying back and forth between the InterManagerRequest.DRAG_MANAGER_REQUEST event between the DragManager and ultimately passed through the Implementor (ie DragManagerImpl), and the SystemManager, is what creates the DragEvent to eventually be fired via the DragProxy. This is why the documentation says it is important to trigger the allowDragDrop method from within the DragEvent.ENTER event – because the target is then assigned directly to the proxy instance.


The design detail:
You want to be able to create item renderers in a list that apply different styles depending on different visual cues or the data itself. For example lets take the TSA’s security approach with colors – the text changes for each level of severity.

The problem:
The problem is in handling the default case where every item renderer style should be the same, in the protected method of makeRowsAndColumns():Point After the itemrenderer instance has been created it’s styleName is set to the listContent container. This is important because no amount of setting through the ClassFactory properties, or setting styles anywhere in the pre-construction phase will save these unique values since it’s reset after it’s created.

The solution:
The one I came up with overrides the actual styleName property itself, where with a bit of checking we can safely ignore only the request coming from this creation area. This looks to make sure the object requesting the new stylename reference isn’t a ListContentBaseHolder or List so long as there is a stylename already set. Remember – properties are populated immediately after construction and before the initialization phase, that means this styleName will have already had something set on it from our ClassFactory in the List/Tree instance when setting our renderer.

override public function set styleName(value:Object):void
if (!super.styleName || (!(value is ListBaseContentHolder) && !(value is ListBase))) super.styleName = value;

Now in the List/Tree instance we can set our styleName:

<mx:Tree itemRenderer=”{myRendererFactory}” />
private function get myRendererFactory():IFactory
var cf:ClassFactory = new ClassFactory(MyRenderer); = {styleName:myStyleName};
return cf;

I found only a few references to this, but not much of a well documented solution, so for those who stumble upon this needing one, you’re in luck.

The problem: The ComboBox does not dispatch a change event under all circumstances, most notably when you use the keyboard to select find the particular item in the list. Think of a states combo, where by ‘n’ will first cycle to Nebraska. This then closes the combo, but does not appropriately fire the change event as it would if you manually scrolled and selected ‘Nebraska’ from the list.

Why the problem exists: The combo is a composition of a TextInput, a Button, and a List. While the appropriate change event listener is added to the input, it’s not added to the List to it’s fullest extent. It only checks to see if non-printing characters are used to see if the user is attempting to scroll the list with the arrow or page-up / page-down keys. Thus, when using a normal alpha-numeric filter,  this doesn’t reflect itself in the parent combo control.

The fix: This fix is unusually difficult in light of the fact of one of my earlier rants that at best all properties and / or methods of a highly public and distributed platform, ie the SDK should only ever be protected. Literally all accessors to both the instance list and it’s combo listeners are private? What the hell?

Further proof of their own exacerbation, is a comment that literally says starting around Line 1512:

private function displayDropdown(show:Boolean, trigger:Event = null):void

// Subclasses may extend to do pre-processing
// before the dropdown is displayed
// or override to implement special display behavior

So remind me, how is that possible with a private selector? Oh yeah.

So the only way around this is to override the downArrowButton_buttonDownHandler() handler, and use the mx_internal::isShowingDropdown property to find if the list is about to be shown, and get a reference to the list by grabbing the dropdown property where you will attach your own ListEvent.CHANGE listener. In this handler you proxy dispatch a clone from the ComboBox point of view, and you finally have a change event that now works.

Finally, create another Event.REMOVED_FROM_STAGE event in the createChildren() method, since destroyDropdown() is also private (note to self: !#$#@!) to clean up your additional change event to prevent  a memory leak.

A quick example of a photo gallery using the standard SDK SliderIn a world of visuals (well at least our little world of RIA development), this is freakishly basic. [Edit: After trying to get this to show up as an inline swf using WP-SWFObject, I gave up on it since it refuses to put up the content, so instead it'll have to be a retarded link for now.]

So essentially while it works, the control doesn’t tell you anything about what you’re about to see, other than an index of the photo which lets face it isn’t that helpful. Knowing previously there is a reference property to the sliderDataTipClass, I began to look up how to implement my own. Essentially all I want is something relatively basic that shows a scaled-down thumbnail of the image (you can get a lot more detail out of it once you know the basic mechanics of how to set one up). (more…)