Building Drag and Drop Experiences in the UcompOS RPF

The UcompOS RPF couldn’t rightfully be called a “Rich Productivity Framework” if it didn’t have a model to support drag and drop interactivity.  Drag and Drop behavior could perhaps be considered one of the key characteristics of an application that helped to define the term “Rich Internet Application” in the early 2000s.

This discussion doesn’t focus on building drag and drop interactivity within a single UcompOS application.  Obviously, you can implement whatever sort of drag and drop interactivity within a singular UcompOS HTML, Flash, Flex, or AIR application without restriction or consideration of UcompOS mechanics.

The real power in a UcompOS Rich Portal Application is in implementing inter-application drag and drop interactivity.

Dragging names from an address book application to an e-mail application, dragging images from a file manager to a text editor, highlighting multiple resources and dragging them to a widget to perform some operation on the items simultaneously – these are some of the experiences that can be created.

The mechanics of drag and drop UcompOS implementations are worthy of discussion.  There are some important considerations that need to be made in order for the UcompOS Portal to enable your applications to be configured appropriately for inter-application dragging and dropping.

Sandboxing in the UcompOS RPF

The philosophy of the UcompOS RPF is to achieve the highest degree of sandboxing possible while still achieving our interaction objectives.

Our sandboxing is less for security purposes and more to create an isolated, self-contained environment for a UcompOS entity that is free from unintentional disruption by other UcompOS entities.

Communication between applications in the UcompOS RPF should exclusively occur using the classes built into the SDK.

In no way should you plan to, or should you need to, attempt to directly access classes, properties, or methods of other UcompOS entities within an individual UcompOS entity. You should exclusively rely on the powerful implementation of a UcompOS entity’s public API methods, Services Dictionary, and Proxy Components.

The one exception to this is the implementation of dragging and dropping across two different UcompOS entities.  But the UcompOS Portal handles all the logic for you so that you don’t need to worry about anything other than what should be dragged and what should be allowed to be a drop target and how it should behave when receiving a drop.

The topic of sandboxing in the Flash Player and loading SWF content into other SWF content is a necessarily thorough and rigorous conversation.

In the UcompOS RPF, any SWF content – be it a UcompOS application or sub-application – is loaded into the UcompOS Portal with an implementation of the SWFLoader class.

The SWFLoader has some very important properties that essentially articulate the permissions the child SWF content has in terms of accessing information (classes, properties, methods) of the parent SWF content it was loaded into.

One of the chief goals of the UcompOS RPF is complete disaggregation.  The framework wants you to be able to place resources at any network address without consequence.

Therefore, all SWF content is loaded into the UcompOS Portal with the trustContent property set with a true value.

There are three different ways SWF content is loaded into the UcompOS Portal as listed below:

  • SWF-based UcompOS application loaded invisibly into the UcompOS run-time
  • SWF-based sub-application loaded into a UcompOS Window
  • SWF-based sub-application loaded into a UcompOS Artifact

When you load SWF content into the UcompOS Portal, you can articulate how tightly it is to be sandboxed.

As far as SWF-based UcompOS applications loading invisibly into the UcompOS run-time, you can set a sandbox=”true” or sandbox=”false” attribute to the root tag in that application’s manifest file.  The default condition is sandbox=”true”.

Also, if you look at the signatures of the add(); methods of both UcompOSWindowProxy and UcompOSArtifactProxy, you’ll see they both have sandbox parameters that default to a true value.

By default, a SWF loaded into a UcompOS Window or UcompOS Artifact will take on the sandbox configuration of its root UcompOS Application.

From an implementation point of view, the only difference between the two configurations is SWF content loaded with the sandbox=”true” configuration has the following property set to the SWFLoader used to load the content:

swfLoader.loadForCompatibility = true;

According to the Adobe’s ActionScript 3 documentation:

“Set this property to
true

to indicate that the loaded application might be compiled with a different version of the Flex framework and you want your application to be able to interact with it. Setting the value of the
loadForCompatibility

property to
true

also causes the LoaderContext of the Loader to load the sub-application into a sibling application domain of the main application, rather than a child application domain.”

A full discussion of the LoaderContext and ApplicationDomain classes is outside the scope of this blog posting, but essentially, setting the loadForCompatibility property to true is a form of sandboxing in that you are able to load Flex content created with a different version of the SDK than the parent SWF content.

Unless you have very specific reasons, in most all cases you’ll leave the sandbox property in its default configuration (sandbox=true).

Our plan is that we will always keep the UcompOS Portal running on the latest public release of Flex 4 so leaving sandbox=true will insure you won’t have to continue to update your Flex-based UcompOS content.

Scenarios for when you would want to set sandbox=false are complex and sophisticated and will be covered in an upcoming posting.

The Marshall Plan

The implications laid out above are somewhat important to elaborate upon.

We want to be able to load SWF content created with any version of the Flex SDK into the UcompOS Portal, and then we still want to be able to enable it to participate in drag and drop interactivity with other SWF content, that may have been produced with still other versions of the Flex SDK.

How is this possible?  After all, classes such as the DragManager are involved and certainly it seems we’ll run into compatibility issues.

The answer is taking advantage of a concept the people at Adobe have created that they call the Marshall Plan.  I recommend you explore this important topic.  It deals with how data is marshalled across the boundaries between two different SWFs.

As of the Beta 2 release of Flex 4, the classes that enable this marshalling to automatically occur are no longer automatically compiled into the SWF.  You have to explicitly add them at compilation time.

This must be added as an argument to the Flex compiler for your application:

-includes=mx.managers.systemClasses.MarshallingSupport

Failure to add this to a Flex 4 Beta 2 UcompOS application that is set up for dragging and dropping will yield unpredictable results, and even run-time errors.

Building a Simple Drag and Drop Example

If you have two different UcompOS entities – one the drag source, the other the drag destination – you would set each of them up as if they were both in the same overall application.

You’d set up the drag source to specify the behavior of the drag initiation, and your drag destination to implement your desired behavior of when items are dragged and dropped onto the target.

There is another scenario however and it involves dragging and dropping to a UcompOS Artifact.

In our example, we want to build a very simple example that shows a UcompOS Flex application that employs a DataGrid.  We then want to implement an artifact and enable the user to drag and drop an item from the DataGrid to the artifact.

When the item is dropped, we want to throw a simple HTML alert that outputs some information about the item that was just dropped.

Here are the three resources used to accomplish this task:

The Dock Manifest

<applications>
 <application background="true" default="true">
   http://applications.ucompass.com/SampleApps/UcompOSExamples/assets/manifests/DragAndDropExample.xml
 </application>
</applications>

The Application Manifest

<application selfLoading=”true” width=”206″ height=”250″ preloaderTitle=”Drag and Drop Example”>
 
 <source>
  <base>http://applications.ucompass.com/SampleApps/UcompOSExamples/bin-debug/DragAndDropExample.swf</base>
 </source>
 
 <titles>
  <title default=”true” locale=”en_US”>UcompOS Drag and Drop Example</title>
 </titles>
 
 <icons>
  <icon default=”true” locale=”en_US”>
   http://applications.ucompass.com/SampleApps/UcompOSExamples/assets/png/nature/Cloud-48×48.png
  </icon>
 </icons>
 
</application>

The Application Code

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/halo"
 applicationComplete="start();" height="200" width="200">
 <fx:Script>
 <![CDATA[
 import com.ucompass.ucompos.sdk.SDKClient;
 import com.ucompass.ucompos.sdk.events.SDKEvent;
 import com.ucompass.ucompos.sdk.proxycomponents.UcompOSArtifactProxy;
 import com.ucompass.ucompos.sdk.proxycomponents.UcompOSHTMLProxy;
 
 import mx.collections.ArrayCollection;
 [Bindable]
 private var _people:ArrayCollection = new ArrayCollection([
 {Name:"Ed",Age:36},
 {Name:"Max",Age:2},
 {Name:"Mason",Age:1},
 {Name:"Abigail",Age:1}]);
 
 private function start():void
 {
 SDKClient.getInstance(this);
 var artifact:UcompOSArtifactProxy = new UcompOSArtifactProxy();
 artifact.add("Drag Here!",null,
 "http://applications.ucompass.com/SampleApps/UcompOSExamples/assets/png/nature/Cloud-48x48.png",
 300,300);
 artifact.dragDropManager(true,"items",["Name","Age"]);
 artifact.addEventListener(UcompOSArtifactProxy.DRAG_DROP,dragDropHandler);
 }
 
 private function dragDropHandler(event:SDKEvent):void
 {
 var droppedItems:Array = event.data.dragDropData;
 var droppedItem:Object = event.data.dragDropData[0];
 var h:UcompOSHTMLProxy = new UcompOSHTMLProxy();
 h.alert("Your name is "+droppedItem.Name+" and you are "+droppedItem.Age+".");
 }
 
 ]]>
 </fx:Script>
 <mx:DataGrid width="200" height="200" dataProvider="{_people}" dragEnabled="true">
 <mx:columns>
 <mx:DataGridColumn dataField="Name"/>
 <mx:DataGridColumn dataField="Age"/>
 </mx:columns>
 </mx:DataGrid>
</s:Application>

Video Demo

Drag and Drop Example

How UcompOS Flash/Flex Applications are Sandboxed in the UcompOS Portal

There are numerous paradigms for launching UcompOS Applications in the UcompOS Portal.

In many instances, the UcompOS Application itself will be a non-visual entity thought of as perhaps the Model and Controller in an MVC style implementation and then the UcompOS Application would launch individual sub-applications in UcompOS Window, UcompOS Browser Window, or UcompOS Artifact instances which could be considered the View in the MVC implementation.

A UcompOS Application can also be an AIR application running on the desktop launched by the UcompOS Portal and also, a UcompOS Application can be launched immediately into a UcompOS Window or UcompOS Browser Window instance by implementing specific attributes in the root of the UcompOS Application’s application manifest.

The specific implementation details of SWF-based UcompOS content being loaded as a UcompOS application or sub-application into the UcompOS Portal warrants discussion.

If you’re an experienced Flash/Flex developer, you may come to the UcompOS RPF with a pre-conceived idea about how things are implemented and how you would go about building rich experiences.

There are 3 different scenarios where SWF content will be loaded directly into the UcompOS Portal:

  1. The SWF content represents a UcompOS Application that is loaded into the UcompOS Portal run-time.  In this case the SWF content is a non-visual entity.  It gets loaded into a SWFLoader with its visible property set to false that is attached directly to the UcompOS Portal as a child.  This application then likely is involved with launching sub-applications into UcompOS Window, UcompOS Browser Window, or UcompOS Artifact instances.
  2. The SWF content represents a UcompOS sub-application that is loaded into a UcompOS Window instance.  In this case, the SWF content is a visual entity.  It gets loaded into a SWFLoader and the SWFLoader is attached as a child to a UcompOS Window instance.  A UcompOS Window instance is derived from a class that extends the MDIWindow class from the mdi package in the FlexLib project.  And of course MDIWindow extends Panel.
  3. The SWF content represents a UcompOS sub-application that is loaded into a UcompOS Artifact instance.  In this case, the SWF content is a visual entity.  A UcompOS Artifact is actually a VBox implementation that gets attached to the UcompOS Portal and then the SWFLoader is attached as a child to the VBox instance.  The UcompOS Portal is a Flex 4 application with the Halo theme compiled so that is how I am using VBox here.

Here’s the important thing to understand about the SWFLoader instances implemented in all 3 of the above scenarios.  They are implemented in one of two “sandboxed” configurations.

If you are creating a Rich Portal Application and your intentions are to load two separate UcompOS Applications into the UcompOS Portal and then do some sort of coding where your accessing something like FlexGlobals.topLevelApplication, this will not work.

All communication with other entities in the UcompOS RPF should be accomplished exclusively via the communication protocols in the UcompOS SDK using implementations such as Proxy Components and public API methods exposed in Services Dictionaries.

The goal is to keep the UcompOS Portal as “dumb” as possible and enable it to focus exclusively on being really good at its base core objectives which are:

  • An MDI (Multiple Document Interface)
  • Style and aesthetic presentation management
  • Artifact model for widget-like implementation
  • UcompOS Application run-time
  • Event Dispatchment architecture

The classes UcompOSArtifactProxy and UcompOSWindowProxy each have Boolean sandbox parameters.  Also, the root <application/> element in an application manifest has a sandbox attribute which accepts values of true or false.

The default condition if you don’t set the sandbox parameter is true.

From an implementation point of view, all SWFLoader instances attached to the UcompOS Portal have the trustContent set to true.  This may be something I rethink when moving the UcompOS RPF project to Beta but at least in my main UcompOS RPF application I am building, the domain that I serve the UcompOS Portal from will be the exclusive thing I serve from that domain as I am interested in creating the a strong degree of disaggregation. (Of course you should have a solid understanding of policy files (such as crossdomain.xml)).

In the case where the sandbox property is set to true (the default condition), the SWFLoader‘s loadForCompatibility property is also set to true.

This creates a situation where the loaded SWF application is loaded into a sibling ApplicationDomain relative to the UcompOS Portal SWF application.

The loadForCompatibility property addresses the need for a SWF to be able to load child SWFs created with different versions of Flex.

For instance, if you tried to load a Flex 3 UcompOS application or sub-application into the UcompOS Portal with its sandbox set to false, you’ll get run-time errors.

So then when or why would you want to load a UcompOS SWF application or sub-application with its sandbox property set to false?

Primarily only in instances when you wanted to implement drag and drop functionality across the boundaries of a UcompOS sub-application.

If all the drag and drop functionality is within the boundaries of the SWF, then the sandbox setting is irrelevant.

However, suppose you have two UcompOS SWF sub-applications loaded into UcompOS Window instances and you want to enable items to be dragged and dropped back and forth between them.  This would require you to set the sandbox property to false.  Also, this would require you to build your applications with Flex 4 (although I admittedly have yet to try implementing drag and drop across two different non-sandboxed Flash CS5-created applications).

In an upcoming tutorial, I’ll show a demo of building a UcompOS-based file management system like the one I have built for Educator 2 that enables drag and drop between multiple UcompOS Window instances as well as drag and drop from a UcompOS Window instance to a UcompOS Artifact instance.

The key fact to ascertain here is that strong command of the UcompOS SDK and how it is utilized to send information back and forth between entities in the UcompOS Continuum is compulsory to your developing the most powerful and effective Rich Experiences.