Flex 2 :: DeskTopFX :: The flex desktop component

January 18th, 2007

Hi,

Well as you can see from my nill posts, this seems to be a consistent theme for me right now but, there is good reason. I have spent the last 5 months creating a framework that will enable some very complex applications with the flip of a switch.

The DeskTopFX component really is only a piece of the pie when it comes to Teoti Graphix's TEOFX framework(aka Mysterious effects).

The short of this post is not that 'hey look, it's windows' but, hey look at what I can create with a component!

<containers:DeskTopFX id="desktop"
    contextMenuEnabled="true"
    taskBarRenderer="com.teotiGraphix.barControls.TaskBarModule"
    taskBarPosition="bottom"
    width="100%" height="100%"
    backgroundImage="@Embed(source='../assets/images/Winter.jpg')"
    backgroundSize="100%">
   
    <application:MyApp/>
    <modules:MyModule/>
    <... etc>
   
</containers:DeskTopFX>
 

This code creates a desktop. The task bar is a module(IFactory) meaning you could use inline item renderers, custom component etc.

So we have some exectue API's, style API's, module fun stuff and this ties into the other component I have been making.

The manager framework has a SelectionManager that you can use in this component to select icons etc. The windows of cource are fully resizeable, moveable, snappable, iconizable and min-max able. :)

Here are some various screen shots of the windows.

Explorer like and modal.

The built in Menu api in the WindowFX. This functionality is inherited from the FrameFX class.

The custom titleBar contextMenu.

Stay tuned for more information. Perfection takes a while and that is what we are about. These components are all getting developed together in the same framework, so time has gone by a bit longer.

One thing to remember is that all of this is skinable and the UI is not 'fixed'. We use renderers and abstract data packets whenever possible to decouple the model of the component from the view of the component.

Peace, Mike

Flex2 :: DocumentFX :: A new look at Flex Documentation

November 15th, 2006

Hello,

It's been awhile since I have posted but...

I have been in the laboratory cooking up some futuristic solutions to the everyday problem of component documentation.

Take a look at the screenshot below, click on it to maximize to see the full image. This is DocumentFXExplorer. What you are looking at is the new revolutionary way of getting to know TEOComponents. Current and future customers of Teoti Graphix will be delighted to see that our number ONE goal is to perfect component documentation.

The screen shot shows a FULL Flex 2 user interface that (for now) mirrors Adobe's ASDoc's to a T. What you may have not know is that all of our documentation since the Alpha release of Flex 2 is created by DocumentFX, not the ASDoc command line tool. The documenter is actually the application called DocumentFX, the image is the DocumentFXExplorer.

BTW, this screen shot is the ASDoc module, not to be confused with the actual DocumentFXExplorer application. This module has been loaded from the main view.

What is the difference?

DocumentFX is the AS3 engine, project manager, file manager, analyzer, renderer… etc. It produces all our docs, publishes zip files and even ftps zips to our server for updates.

DocumentFXExplorer is the User Interface that our customers will use to learn about our components, save book marks to methods, properties, create live doc comments and even run our examples right inside the UI right next to the element descriptions!

They will see updates to the API, current notices, and much more. The majik of the explorer is DocumentFX has a render mode that creates an XML representation of all classes, interfaces and package structures so that the explorer just loads XML. Yup, the image you see is just XML nothing more.

If you look at our web site and see the HTML asdoc's you can see another output and that is HTML. The explorer can create live flowcharts of the class-interface hierarchies(Package Trees) and a variety of other kewl stuff that will help expedite learning.

The explorer will also have a wiki plug-in, forum board(Flex 2 style) and any other applications my fellow devs can think of. This is going to turn into a central hub for Flex 2 learning in the future also. The power of this paradigm cannot be matched in development time with AJAX and HTML. Apollo will help because I can integrate HTML rich text views and get the best of both worlds.

Eventually, I plan on either making this an online service to unite fellow component developer(some type of unified store) or turn it into an Apollo application. Or, so both of the previously mentioned.

Another great thing is this explorer will showcase our many user interface, dnd, windows ,manager components in it's own user interface~! How kewl is that.

Since I used heavy composition, I can see this eventually creating documentation for any language you want. Just create a plug-in module for say javascript and since we use polymorphic interface calls, vola, a new parser!

Teoti Graphix is also on the verge of releasing some fantastic new component sets, so stayed tuned. The blog has been a ghost town of late but, that will soon change.

Peace, Mike

Flex 2 :: DND Containers ! :: Abstract and powerful

October 19th, 2006

Hello,

Well, I have had some encouraging words lately. This is my driving force, if I can inspire people to create with their mind and not worry about rules, I have accomplished my duty. :)

Well, as you know I have a lot of 'large' components coming up, not controls but framework components. I thought I would post this one as it's still in beta but a good Thursday look, I love Thursdays.

The screen shot below shows you the TaskPaneFX and TaskListFX. If you search this blog you will find more on them but, these are not even the same animals.

Ok, what are we looking at Mike?

1. A fully abstracted drag and drop container system(framework).
2. The bar is a 'barRenderer' (for you Campbell Anderson) that implements the ITitleBar and ITitleBarDataRenderer.
3. The TaskPaneFX is the Blue bar, the TaskListFX is the Orange bar.
4. pane and list a both capable of dnd.
5. effects and movement for this new 'movement' of Flex 2.
6. Saves and Loads the ENTIRE work space application to-from mxml/xml/object
7. all composities are implemented as renderers and hold abstrat data.
8. plus so much other stuff, that is why there are asdoc's :)

The bar

Inheritance, we get some nasty debates but, anybody that doesn’t think inheritance has a time and place, leave your comments at the door.

The title bar gets inherited back a ways in an abstract class called BarWorkSpaceFX. This bar can be positioned at LayoutPosition TOP, LEFT, BOTTOM, RIGHT all calculated with viewMetrics.

The title bar has interface properties of like title, titleIcon, showCloseButton, showMinMaxButton, showIconizeButton, normal styles and skins and dispatches events for the buttons. This functionality comes from the TitleBarModule class.

The bar is great because you can swap any bar that implements that interface and dispatches those events. So if you don't like my title bar in the component you buy, swap with a subclass one of my bar classes and make your own!(you don’t even have to subclass my class) Gone are the days of 'how do I add a button to the Panel's title bar~!'.

The bar also implements it's own layout state. This enables it to do some funky stuff. Like when the Panel in the swf example minimizes.

Note: You could also use a right click, undock to window for dragging around. This is not in the example though.

The dnd Container

What we have here is the DNDWorkSpace class that is a subclass of the BarWorkSpace class. This class implements the IDragClient interface. Oh yeah, did I mention that the bar implements the IDragButton!?

This class sets up all dnd with the PaneDragManager and OverlayManager. Oh yeah, black boxes, those are for airplanes. Managers are for managing UIComponent layers. Think of a component as having distinct layers. Each layer utilizes inheritence, managers manage each layer.

The container also adds a dragButtonRenderer. This could be another bar, button whatever. If you don't want to have the bar drag, then add a button or graphic somewhere else in the container! This instance also is ruled by the LayoutPosition TOP, LEFT, BOTTOM, RIGHT and CENTER.. RIGHT_CLICK etc.

The DNDWorkSpace class has properties like dragTolerance, dragEnabled, dropEnabled all that fun stuff.

This class does not add effects that is for the next class, PaneFX.

The pane Container

The PaneFX class adds properties like isOpen, openDragPosition, closedDragPosition and effect styles.

This class sets us up for a draggable view of some sort. This will be the super class of some great components. It's also the superclass of the TaskPaneFX and TaskListFX. These to components are 'demonstrations' of what the framework can 'produce'.

What is a framework if it cannot be implemented?

The TaskPaneFX is written to only accept TaskList as children. This is because the TaskPaneFX can open and close a single child, all or and array of children with the;

multiSetIsOpen(numArrList:Object = null, bFlag:Boolean = true);

method. The pane and list also have a barDoubleClickEnabled property as you can see from the example.

More to come...

The manager's

The managers are where all the fun stuff happen. The OverlayManager is right out of my ResizeManagerFX component. If you have looked at that component you can see the power of this manager. The simple little overlay used on the example is just a simple skin.

In the framework we have popUpOverlayRenderer and clientOverlayRenderer not all components use both but it's there if they need it.

The framework also has methods subclasses need to implement like getClientOverlay() nad getPopUpOverlay() that are public methods from the IOverlayClient interface.

This way the overlay manager can call the methods through the interface and the current client dished the correct overlay for the current procedure.

Another thing to note is the TaskPaneFX 'can' be dragged and dropped but is not implemented in this example.

Yes, there are still some bugs in this and there are some tween and move rules I haven’t created yet in the managers IE moving a component to a 0 index, the removeTween isn't working correctly.

Well, I have to run but, I hope this gets you engines reving for what Flex 2 can really do. Remember, this is not an Application it is components in disguise. ;-)

PS Do you notice the ‘WorkSpaceFX’ word? HAHA This means that there are two methods in the base class of the framework;

-saveWorkSpace()
-loadWorkSpace(xml)

This allows you to save the WHOLE STATE of the application into mxml! Then you can reload it whenever you want and the same exact UI will be created.

All of my components inherit this or implement the IWorkSpace interface. So you can save a whole UI session with one click for your user. I am doing this with this exact interface. Click on the save workspace button. This is not fine tuned yet.

Peace, Mike

Flex 2 :: Tree :: Walking the Tree method

October 16th, 2006

Hi,

I thought I would post this method to show some of you that the dataDescriptor rocks. One thing you will notice in the method below is there is an if() check on the model at every turn. With experience comes wisdom and I have found this is essential in creating methods that test the sands of time.

Also note, the method is 'actually' two methods. The first half of the method will back step on the item's parent. The nice thing about this is, if you do pass startAtParent as true, the first part of the method only gets executed once in the recursion algorithm. It's main purpose is to get the item's parent and siblings, loop through them and then branch down the chain.

This is handy if you want to know the item's sibling branches. If you do not need the sibling branches, pass startAtParent as false and you bypass the first part of the method and go straight to the item.

If the item is a leaf, it will just trace the leaf item. If the item is a branch, it will then recurse through the whole composite structure of the item passed.

I hope this helps people, and you can discover some of the fascinating aspects about recursion and dataDescriptors. OOP is all about abstraction and decoupling through dataDescriptors. Adobe has found a wonderful balance in all the composite controls they have made thus far.

Look for the comments where you could break into your own method branch.

/**
 * This method will traverse a Tree's model independent of it's
 * type.
 *
 * <p>Note :: This method may look long and arduous but, rest assured
 * it has all the checks to perform like a champ. Also, you 'could'
 * refactor part of this method but, for the sake of explanation, I
 * kept it all in one place.</p>
 *
 * <p>Remember, I had coupled the model to this method by tracing
 * @label, obviously you do not need to do this. The intention of
 * this example is to show you that the dataDescriptor seperates
 * the models type and is awesome. It enables you to create a tight
 * method like this without type checks on the model.</p>
 *
 * @param tree The Tree instance that will be examined by the method.
 * @param item An item found in the dataProvider of the Tree passed in.
 * @param startAtParent A boolean that determines if the method upon
 * initialization will back up one leve3l to the item passed in and
 * start it's recursion at the item's parent node.
 */

public function walkTree(tree:Tree, item:Object, startAtParent:Boolean = false):void
{
    // get the Tree's data descriptor
    var descriptor:ITreeDataDescriptor = tree.dataDescriptor;
    var cursor:IViewCursor;
   
    var parentItem:Object;
    var childItem:Object;
    var childItems:Object;
   
    // if the item is null, stop
    if (item == null)
        return;
       
    // do we back up one level to the item's parent
    if (startAtParent)
    {
        // get the parent
        parentItem = tree.getParentItem(item);
        // is the parent real
        if (parentItem)
        {
            trace("|-- Parent Node ", parentItem[tree.labelField]);
            // if the parent is a branch
            if (descriptor.isBranch(parentItem))
            {
                // if the branch has children to run through
                if (descriptor.hasChildren(parentItem))
                {
                    // get the children of the branch
                    // this part of the algorithm contains the item
                    // passed
                    childItems = descriptor.getChildren(parentItem);
                }
            }
            // if the branch has valid child items
            if (childItems)
            {
                // create our back step cursor
                cursor = childItems.createCursor();
                // loop through the items parent's children (item)
                while (!cursor.afterLast)
                {
                    // get the current child item
                    childItem = cursor.current;

                    var label:String = childItem[tree.labelField];
                    var branch:Boolean = descriptor.isBranch(childItem);
                   
                    // good place for a custom method()
                    trace("Sibling Nodes :: ", label, "Is Branch :: ", branch);
                   
                    // if the child item is a branch
                    if (descriptor.isBranch(childItem))
                        // traverse the childs branch all the way down
                        // before returning
                        walkTree(tree, childItem);
                    // do it again!
                    cursor.moveNext();
                }
            }
        }
    }
    else // we don't want the parent OR this is the second iteration
    {
        // if we are a branch
        if (descriptor.isBranch(item))
        {
            // if the branch has children to run through
            if (descriptor.hasChildren(item))
            {
                // get the children of the branch
                childItems = descriptor.getChildren(item);
            }
           
            // if the child items exist
            if (childItems)
            {
                // create our cursor pointer
                cursor = childItems.createCursor();
                // loop through all of the children
                // if one of these children are a branch we will recurse
                while (!cursor.afterLast)
                {
                    // get the current child item
                    childItem = cursor.current;

                    var label:String =  childItem[tree.labelField];
                    var branch:Boolean = descriptor.isBranch(childItem);
                   
                    // good place for a custom method()
                    trace("-- Sub Node :: ", label, "Is Branch :: ", branch);

                    // if the child item is a branch
                    if (descriptor.isBranch(childItem))
                        // traverse the childs branch all the way down
                        // before returning
                        walkTree(tree, childItem);
                    // check the next child
                    cursor.moveNext();
                }
            }
        }
    }
}
 

Peace, Mike

Flex 2 :: ResizeManagerFX v1.1.0 Resize and Move

October 3rd, 2006

Hi,

UPDATED :: The links got chopped, they work now.

Well, the ResizeManagerFX component is shinning now that the move algorithm has been added.

You cannot beat this component for out of the box functionality and hassle free ease of use!

The Example Explorer
The Product Page

The manager now provides an overlay that has anchor points IE Fireworks and supports dashed lines and patterns. The move button also has styles associated with as well.

The ResizeManagerFX SWC component resizes and moves any UIComponent using the custom styles of each individual client component.

This component can save you many hours of coding(which equals money) and debugging with it's out of the box resize and move functionality.

The manager also depends on stylesheets more than most components do, for the simple reason of allowing client components to define their own styles and remain encapsulated from the resize manager and each other.

Check out the Component Explorer to see how dynamic this component really is!

The manager provides the following functionality;

  • Client component resizing and moving.
  • Disabling and enabling of move and resize functionality
  • Client component bounds checking.
  • Client component minimum and maximum width and height checks.
  • Cutom cursor skin and offset styles.
  • Resize and Move button styles and offsets.
  • Resize and Move effects with easing and duration styles.
  • Resize types of none, realtime and animated.
  • Move types of non, realtime and animated.
  • Customized look and feel for each client's overlay and popup overlay.
  • Client overlay offset in insets.
  • Overlay thicknesses, skins and alpha.
  • Anchored overlay type with dashed line pattern styles.
  • Client and Manager resize and move events.
  • Convienent interfaces so subclassing of overlays is possible.
  • One line of code for addition and removal of client components.
  • Mouse shield to protect Application while dragging or moving.
  • Plus more...

When using the manager class, use the ResizeManagerFX.addClient(component) static class method to embed the overlay inside the client component and initialize resize and move functionality.

There are various styles that control to look and resize functionality of
each client component. Check the style's of the ResizeOverlay to find out which
styles will effect the embedded overlay and which styles effect the popup overlay .

The manager will also take into account the minimum and maximum width and
height of each client component when resizing. The manager also places the popup overlay above all components and creates a mouse shield so there is no misplaced events while resizing or moving.

This component was designed based on the ever increasing need to be
able to resize and move a UIComponent anytime and anywhere.

Screenshots

The image below shows a Tree with an anchored resize overlay and custom resize button skins.

The image below shows the component being moved with moveType == MoveType.NONE which moves the client component after the mouse up.

The image below shows a TitleWindow being resized with the standard ResizeOverlay that uses lines instead of anchors. The thickness and offset of the lines can be adjusted with styles.

The image below shows the resize buttons inset and shows the actual move button. This image demonstrates that you can adjust the hit area of the move button with offset styles. You can also control the skin and alpha of the move button along with cursor styles.

The bottom line is, if you are looking for a resize manager with all the frills and just want to create an application, this is the resize manager for you.

Just think about the money you will save in development cost relative to what you will pay for the component.

Mike