Wednesday, February 25, 2009

Darren on Flex: Flexins, Drag 'n' Drop Mixin

I present to you the Drag'n'Drop Mixin

I've managed to embed an instance of my Drag'n'Drop showcase app here, but I cannot seem to influence the size of it. I recommend you visit the mixin's demo page here For those of you who are not interested in my posturing and story-telling, you can review the source for this application here at GitHub.

So how does it work?

You simply include <dnd:DnDMixin /> as a child of any container type and this enables that container as a drop target and any child as a drag source. It's as simple as that.

That's how you use it... How does it work?

Ok, here's an excerpt from the project's README file:
These mixins are designed to be used in MXML, leveraging components' event-driven life-cylce. They should be used as 'drop-ins', similar to usage model for inline item-renderers.
In addition to this, I exploit the Container.rawChildren property, due to the fact that this mixin is a content-less UI component and should not interfere with content-full UI components. When an application is loaded all declared UI components are processed through an event-driven life-cycle. The life-cycle events the dnd-mixin is interested in are:
FlexEvent.ADD:
Registration happens in the constructor, the earliest possible opportunity at the object level. More significantly, registration occurs before this (typically, one time) event is dispatched. The handler for this event deregisters from this same event, removes the dnd-mixin from the container and then adds it back but to the rawChildren. The handler then registers interest in the DragEvent.DRAG_ENTER, DragEvent.DRAG_OVER, DragEvent.DRAG_EXIT and DragEvent.DRAG_DROP events. The corresponding handlers implement the necessary mechanics to provide drag'n'drop functionality; I refer you to the source code as it's pretty straight forward and not that interesting, especially if you've implemented D'n'D yourself before. The handler also registers interest in the following events:
ChildExistenceChangedEvent.CHILD_ADD:
Through this event the dnd-mixin is notified whenever a component is added to the parent container. The addition of a child as far as the dnd-mixin is concerned, indicates a successful drag'n'drop operation to this parent container. Thus this event signals this dnd-mixin instance to take control of the D'n'D processing for this child component (to which a reference can be obtained from the event object). This handler registers interest in the following events on each managed child component:
MouseEvent.MOUSE_MOVE:
The registered handler simply detects the drag gesture (initiation) and delegates the operation to the DragManager.
DragEvent.DRAG_COMPLETE:
The registered handler basically just adds the dragged component to the new container, which implicitly removes it from its current/previous parent. Doing so dispatches the ChildExistenceChangedEvents, as explained here.
ChildExistenceChangedEvent.CHILD_REMOVE:
Similar to CHILD_ADD, this CHILD_REMOVE event notifies the dnd-mixin whenever a component is removed from the parent container. The removal of a child likewise indicates a successful drag'n'drop operation away from this parent container. Hence this event signals this dnd-mixin instance to relinquish control for D'n'D processing. This is explicit and is implemented through deregistering interest in the MouseEvent.MOUSE_MOVE and DragEvent.DRAG_COMPLETE events.
And that's all there is to it. Try it out above or here. As you'll see there is nothing spectacular about the end result; it's functional. The benefit is the improved readability in your code gained from the clean separation, reduced duplication and declarative style the mixins adopt. While I declare this dnd-mixin is fully functional I don't presume it will suit the needs of all drag'n'drop use cases. I have also observed a bug in the rendering of dragged items that were previously clipped by the parent's right edge. I think I recall a colleague encountering this problem (and solving it) so I'll ask her about it at the next available chance.

What's next?

Drag source filtering. This will support the use case if you want to allow some types of things to be dropped, but not others. The implementation for this is actually complete (see here); a blog will follow soon. If you want to use it, you know where the source/binaries are. Enjoy

Monday, February 16, 2009

How To: Use Google Code as a Maven Repository

While working on my new Flexins Project and blogging accordingly, I decided to explore using Maven and Flex-Mojos to build the libraries and showcase applications. I have a local install of Nexus, where I hide away most of the complexity that would otherwise be in my settings.xml files. I typically deploy to this repo for my own benefit where I might chose to make it public in the future so I can work on stuff (drag in deps) from anywhere. However, it is not a viable option if my or your aim is to truly make one's binaries publicly available (saving the curious the trouble of a compiling source). Some how I stumbled on to Don Brown's Weblog, where he talks about turning a Google Code project, that is the site itself with its SVN, into a Maven repository. I have not yet done this myself, but the details are here. Cheers

How To: Demo Flex Apps On Blogger or Google Sites

While working on my new Flexins Project and blogging accordingly, I discovered that you can embed you Flex application into your page quite easily. Here are the rawest of raw instructions on how to do it.
Flex on Blogger
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
    id="Main" width="100%" height="100%"
    codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
    <param name="movie" value="https://sites.google.com/site/flexinsproject/flexins-catalog/dndmixin/dnd-mixin-demo-0.2.swf?attredirects=0" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#869ca7" />
    <param name="allowScriptAccess" value="sameDomain" />
    <embed src="https://sites.google.com/site/flexinsproject/flexins-catalog/dndmixin/dnd-mixin-demo-0.2.swf?attredirects=0" quality="high" bgcolor="#869ca7"
        width="100%" height="100%" name="Main" align="middle"
        play="true"
        loop="false"
        quality="high"
        allowScriptAccess="sameDomain"
        type="application/x-shockwave-flash"
        pluginspage="http://www.adobe.com/go/getflashplayer">
    </embed>
</object>
UPDATE, 27.02.2009: It seems Blogger ignores the <object>...</object> tags, so the nested <embed>...</embed> is sufficient. While I would not normally recommend removing robustness... parts of the <object>...</object> code was showing in my blog, so I got rid of it altogether. Also make sure the remaining <embed>...</embed> is format correctly i.e. no erroneous newlines; this was causing some of the parameters e.g. width and height, to be ignored.
Flex on Google Sites
<Module>
    <ModulePrefs title="__UP_title__"
    width="600"
    height="450"
    scrolling="true"
    author="Darren Bishop"
    author_email="dbishop81@gmail.com"
    description="GG to help embed Flex applications into Blogger or Google Sites">
        <Require feature="flash" />
    </ModulePrefs>
    <UserPref name="title" display_name="Title" default_value="Flex Application Embedder" />
    <UserPref name="swf_url" display_name="SW URL" />
    <Content type="html">
    <![CDATA[
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
        id="Main" width="100%" height="100%"
        codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
        <param name="movie" value="__UP_swf_url__" />
        <param name="quality" value="high" />
        <param name="bgcolor" value="#869ca7" />
        <param name="allowScriptAccess" value="sameDomain" />
        <embed src="__UP_swf_url__" quality="high" bgcolor="#869ca7"
            width="100%" height="100%" name="Main" align="middle"
            play="true"
            loop="false"
            quality="high"
            allowScriptAccess="sameDomain"
            type="application/x-shockwave-flash"
            pluginspage="http://www.adobe.com/go/getflashplayer">
        </embed>
    </object>
    ]]>
    </Content>
</Module>
Wordpress
Sorry, you are on your own. Somehow, I don't think it would be that hard to do. If you can't figure it out, feel free to ask for help. Cheers

Darren on Flex: Flexins Project Launch

I am proud to announce the launch of the Flexins Project!

This project is the result of some work I started several months ago. I started looking into ways to leverage Flex's declarative MXML to add extra behaviour to applications (or parts therein), using mixins. The project's homepage is over at Flexins Project @ Google Sites. It's in flux at the moment as I'm still getting my bearings in administering the site; please bare with me on that one. The source code is hosted at Flexins Project @ Github. I decided to give Git a spin on this project as it appears to be the emerging SCM of choice for open/public projects.

So what's it all about?

We are all familiar with includes, which work for both .as and .mxml files. This supports the code-behind style, which is a very useful separation mechanism when dealing with complex UI logic or copious event handler code. However, as a mechanism it is pretty stupid, relying only on assumption that internal dependencies (e.g. property existence) are satisfied. Of course, one can declare interfaces in .mxml and implement them in .as code-behind; I suppose this is the standard approach. The syntactical interface declaration (think: compiler) here also serves to declare (the availability of) any relevant behaviour (think: application feature) [Mixins are not necessarily or typically used this way, to add application features, but it is nonetheless the theme for my initial work]. However, firstly, the interface has to be defined and secondly the include is a waste full source include [Ok, it's debatable the real impact of this on binary size and performance blah blah blah... but from a idealist pov... it's not ideal]. I have found with this new approach to implementing mixins, you can achieve complete separation of responsibility e.g. keeping whatever it is your components are primarily supposed to do, from the behaviour implementation of the mixin. The state required for the mixin to function can be managed internally, negating the need for any interface definitions, declarations or implementations. And because the mixin is not used via a source include, there is only one compiled instance of the code in the binary. Application of the mixin is achieved through normal object-instantiation, not source inclusion everywhere the mixin behaviour is required. Another advantage of this new approach is that you do not need access to any source code; you do not need to re-write or extend some existing class in order to bolt on your desired behaviour. I will blog soon on how all this can be achieved. For now, have a look at an example of what the end result looks like; check out my Drag'n'Drop Mixin showcase. Cheers, q(^_^)p

Friday, February 13, 2009

Darren on Flex: Does Flex Have Serial Version Ids?

... And if it does, why don't they use them?

I came across this weird bug (see below) ages ago, that is ~6-8months, when trying to implement some custom drag'n'drop behaviour in a modular application. I had no flipping clue what it was going on about, threw my hands up in disgust and frustration and just shelved the whole thing (actually had to go earn my pay). I just recently came back to the drag'n'drop thing, developing in a singular app style. On completing what I set out to achieve (well, making satisfactory progress, [blog to follow]), I decided to revisit this bug. I found a work-around on Adobe's JIRA site but was confused by all the chatter. I Googled a bit more and found Greg Jessup's blog, where he posted the workaround some months earlier. With Greg's clear post, it was easy for me to rationalise this bug, such that I no-longer believe it is a bug... or rather not the WTF-kind. I categorize it now as a matter of some runtime-binary-compatibility issue, serializationy thingy. Hence why loading the classes in the Application (thus sharing the binary amongst the modules) solves the problem. I believe in the Java world, this is the kind of thing a serial-version-id is used to guard against, no? Anyway, cheers Greg.

Monday, September 22, 2008

Darren on Flex: Overloading the Constructor - Revisted

This is just a follow up to Overloading the Constructor to elaborate on my response to a comment made by Ben. I show how to:
  • Hide the public constructor by hiding the implementation class.
  • Expose the class via an interface.
  • Provide arbitrary factory methods in a factory class.

The Interface

//example\IPerson.as
package example {
    public interface IPerson {
        function get fullName():String
    }
}

The Factory and Implementation Class

//example\PersonFactory.as
package example {
    public class PersonFactory {  
        public function newPersonWithFirstName(firstName:String):Person {
            return new Person({firstName: firstName});
        }  
        
        public function newPersonWithLastName(lastName:String):Person {
            return new Person({lastName: lastName});
        }  
        
        public function newPersonWithFirstAndLastName(firstName:String, lastName:String):Person {
            return new Person({firstName: firstName, lastName: lastName});
        }  
        
        public function someDudeWithOnlyMiddleNames(... middleNames):Person {
            return new Person({middleNames: middleNames});
        }
        
        public function andTheFullShaBang(firstName:String, lastName:String, ... middleNames):Person {
            return new Person({firstName: firstName, middleNames: middleNames, lastName: lastName});
        }
    }
}

import example.IPerson;

class Person implements IPerson {
    private var firstName:String;
    private var lastName:String;
    private var middleNames:Array;
    
    public function get fullName():String {
        return firstName + (middleNames ? " " + middleNames.join(" ") + " ": " ") + lastName;
    }
    
    public function Person(params:Object) {
        for (var property:String in params) {
            this[property] = params[property];
        }
    }
}  

The FlexUnit Test (for good measure)

//example\PersonFactoryTest .as
package example {
    import flexunit.framework.TestCase;

    public class PersonFactoryTest extends TestCase {
        public function PersonFactoryTest(methodName:String=null) {
            super(methodName);
        }
        
        public function testCreatingBenjaminNortier():void {
            var factory:PersonFactory = new PersonFactory();
            
            var ben:IPerson = factory.newPersonWithFirstAndLastName("Benjamin", "Nortier");
            
            assertEquals("Benjamin Nortier", ben.fullName);
        }
        
        public function testCreating21stCenturyCodeWorks21ccwblogspotcomBenjaminNortierWith():void {
            var factory:PersonFactory = new PersonFactory();
            
            var ben:IPerson = factory.andTheFullShaBang("Benjamin", "Nortier", "21st Century Code Works", "21ccw.blogspot.com");
            
            assertEquals("Benjamin 21st Century Code Works 21ccw.blogspot.com Nortier", ben.fullName);
        }
    }
}
... and the results snapshot: Cheers

Sunday, September 21, 2008

Darren on Flex: Overloading the Constructor

Prologue

Back on the 3rd September 2008 some of my colleagues at Zuhlke unvailed StuffPlanner at a BCS SPA evening talk. StuffPlanner is an Agile estimation and planning tool with an opinion. Recently, I found myself ramping up my involvement in the development of StuffPlanner. Consequently, I have resumed my study and assessment of the technologies involved and their corresponding conventions and recommended usage. Henceforth, I blog briefly on the topic of constructor overloading.

Wait! ActionScript Does Not Support Overloading!

No, it doesn't... but please, keep reading. Sometime this week I received a communicade from a local colleague who is doing some pretty interesting work on the continent on the Flex platform. He asked me how to, or rather can you, overload a constructor. We (the locals) had (less) recently had a debate about this after realising that AS3 (ActionScript 3) does not support overloading, so I was primed to make a suitable response.

Default Parameters

Basically, in lieu of overloading AS3 gives you default parameters
public function DefaultValueExample(required:String, andTheCommonCase:String="DEFAULT") {
    if (!required) {
        throw new ArgumentError("You must specify required arguments");
    }

    // construct something with the required value andTheCommonCase
} 
Obviously the API designer needs to know the complete set of parameters, that is, those that must be specified and those that can have a default values. So far my references to the common-case are just to the concept of it, a place holder. The common-case represents the design challenge in using this language feature while, simultaneously, it represents the design limitation; the common-case(s) is prescribed to all the API clients irrespective of client needs. However, in practice the common-case is not a difficult trade-off to figure out and tends to be only a minor inconvenience. For example, in my experience, such cases tend to crop up during unit testing, which I anticipate will be less of a problem with TDD (yes, I am still homing my skills with TDD on Flex/AS3).

Variable Arguments

It may also be useful to use varargs to replace constructor overloading.
public function VarArgExample(... args) {
    for each (var arg:* in args) {
        // process arg...
    }
    //... then do construction
}
I reckon this has less application than default parameters as it only makes-sense/works when the (signature of the) things you are using during construction have parameters of no-type (* or Object) or a common super-type. Then you can either leverage duck-typing or polymorphism, respectively, to do smart things, which I won't discuss here.

The Factory Pattern

Oh yes, that old gem! I am a growing fan of using intention revealing names for variables and methods. It is perhaps a more common/old practice for variables (although you'd be surprised, even today), where variables are named to reveal the state it represents and/or for what it could be used to achieve. With methods, on the other hand, I sense a stigma, a taboo, in using this technique in any progressive way. Thus I feel there is a general hesitance to use this practice, as if it would imply some mediocrity in the coder's skill at writing good code. I do feel TDD development has gone some way to alleviate this, specifically, where test method names describe the example situation being tested; this some how seems more socially acceptable. And, while I'm at it, I'd like to suggest that this technique encourages you to write more cohesive methods w.r.t. what an object's methods do to contribute to the object's overall task. The reason I discuss this here (I did not plan to get into it that much) is because AS3 does not allow you to reuse method names i.e. no overloading. So rather than settling for less, why not combine intention revealing names with the Factory pattern. Now I have said it, I bet you are realizing you do this all the time (I anticipate) during testing, where you might have refactored some creational code for some objects used commonly in your tests. So what if we drop the usual XxxFactory's getInstance(), newInstances() and createInstance() cruft and adopt something more revealing?
//Person.as
public class Person {
    public function Person(firstName:String="", lastName:String="", ... middleNames) {
        // do somthing
    }  
}

//PersonFactory.as
public class PersonFactory {
    public function newPersonWithFirstName(firstname:String):Person { return new Person(firstname); }
    public function newPersonWithLastName(lastname:String):Person { return new Person(null, lastname); } // A little inconvenient
    public function newPersonWithFirstAndLastName(firstname:String, lastname:String):Person { return new Person(firstname, lastname); }
}
So what's the runtime overhead? Just the extra PersonFactory class, where the would-be constructor overloads are replaced with simple methods; let's face it, negligible. And the API overhead? Well interestingly, a problem has emerged and a pattern has been used to solve it. Furthermore, our intention revealing names should improve readability of the code and identifies a good place to refactor/relocate creational code that gets used over and over again... like, for instance, in your tests. Comments welcome.