Sunday, December 12, 2010

Flex 4 Custom TabBar

I needed a drag enabled spark TabBar so you could reorder its tabs.  I searched the web and could only find the SuperTabBar component in the FlexLib library.  But that was still based off the old mx components.

So, I bunkered down and created a drag enabled TabBar.  You can reorder and close each tab.  I based this CustomTabBar class off of Saturn Boy's TeffificTabBar component, so I was able to get the closing tabs functionality for free :)

The real challenge was adding in the dragging functionality of the tabs.  Luckily, the spark TabBar is based off the ListBase class.  This means I could just follow along with how the spark List component does its dragEnabled/dropEnabled functionality.

Take a look at the sample below.
View the sample (right click to view source)


Tuesday, December 7, 2010

Flex 4 Dashboard

Here is the start of a Flex 4 dashboard application that I put together.  It uses my WindowManager class with five window modifiers.  Let me say right away, I completely ripped off the design from Adobe's Connect Now.  My dashboard is far from being finished and really just more of a shell than anything else.  In future posts, I will go over adding content to it.  As of right now, I was trying to mimic the windowing functionality of Adobe's Connect Now.

View the dashboard (right click to view source)

Below I will discuss how the dashboard application works.

You can now define a window bounds area by using the windowBoundsAreaFunction property on the WindowManager class.  You can use the windowManager.windowBoundsArea property in your window modifier classes.  Take a look at the WindowBoundaryEnforcer class to see how this works.  You don't need to define the windowBoundsAreaFunction.  By default, the bounds will be positioned at 0,0 and height and width of the flex app.  I needed this feature since I didn't want the windows to be dragged over the header and footer parts of the application.

Next up, I am using five window modifiers to mimic the windowing functionality that Adobe's Connect Now has.  I have already talked about the WindowSnapper, WindowBoundaryEnforcer and WindowEffects modifiers in a previous post, so I will only discuss the two new ones I have created for this dashboard.
  • WindowFiller
  • WindowMover
The WindowFiller modifier will find and place a newly added window in the largest amount of space available on the dashboard.  For example, the first window that you add will fill the screen.  If you resize the first window down, the second window you add will fill the newly created space.

The WindowMover modifier is responsible for moving and resizing the windows when the application is resized.  Try it out by adding some windows and resizing your browser window.  Thinking about it now, maybe I should have named this modifier WindowScaler.  I whipped this modifier up in about a hour, so it is not completely pixel perfect, but it gets the job done for now.

I am pretty happy with the way the WindowManager class is turning out.  My main goal has been the ability to just drop it in to my application and get the expected windowing functionality that I needed.  You can see this in action.  Just comment out the WindowManagement class in my dashboard sample and you will see the dashboard is still fully functional but just without the windowing features that you get with the WindowManager and its window modifiers.

I still have plenty of features that I want to work on.  My task list is below:
  • Maximizing of windows
  • Minimizing of windows
  • Saving and restoring windows - this is partially completed
  • Embedded/tabbed windows - this would allow drag and drop of windows into other windows
  • Window layouts
  • Anchoring of windows
Plenty of stuff to do...


Saturday, December 4, 2010

Window Manager Update

Update - Take a look at the Flex 4 sample dashboard application using my WindowManager class here.

For the past couple of weeks I have been fooling around with the re-factoring of my WindowManager class.  One thing kept bugging me about the class.  With every new feature I would add, the class got larger and I started to get lost in my own code.  To alleviate these growing pains, I modularized it.  Like in the real world, most managers don't do any of the heavy lifting.  They delegate the work to team members.  The WindowManager class now delegates the work to what I am calling window modifiers.  Window modifiers are the ones responsible for the heavy lifting.

The WindowManager class initially had two features, window snapping and window enforcing of boundaries.  These two features were the first candidates to get split into separate window modifier classes.
  • WindowSnapper
  • WindowBoundaryEnforcer
Not much goes on in the WindowManager class now.  It's pretty simple.  The WindowManager class just passes key window events such as windowAdd, windowMoving, windowMoveEnd and windowResizing to each window modifier that has been registered.  Each window modifier manipulates the window however its been programmed to.  In order to be a window modifier, it needs to implement the IWindowModifier class.  I have made it easy and created a WindowModifier base class that you can just extend and override the methods that will get you your required functionality.

Below is an example of the WindowManager class with the two window modifiers mentioned above.  One major change I should note is that the WindowManager class will now only manage TitleWindows that implement the IManagedWindow interface.  This was a design decision for times where I needed a TitleWindow that I didn't want to be managed by the WindowManager.

View Sample 1 (right click the sample to view source)

The great thing about this modularization is that you only need to include what you need.  For instance, if you have an existing Flex application and all you want is to enforce boundaries on your windows, then all you need to do is declare the WindowManager class somewhere, add the WindowBoundaryEnforcer window modifier to it, and update your existing windows to implement the IManagedWindow interface.

Lets take a look at WindowBoundaryEnforcer window modifier class in detail to get a better idea on what it takes to be a window modifier.
First, the WindowBoundaryEnforcer class extends the base WindowModifier class.  This is the easiest route to take since we are only after a couple of window events.  Next, we override five methods.
  • onWindowAdd(window:TitleWindow):void
  • onWindowMoving(window:TitleWindow, bounds:Rectangle):void
  • onWindowResizing(window:CustomTitleWindow, bounds:Rectangle):void
  • onWindowMoveEnd(window:TitleWindow, bounds:Rectangle):void
  • onModifiersComplete():void
There are more methods a window modifier could override, but in the case of the WindowBoundaryEnforcer, these are the only methods it needs to do its job.  Take a look at the source for the WindowBoundaryEnforcer class to get a better understanding.

Here is another simple sample of a window modifier in action.  In the sample below, I have added a Window Effects window modifier.  It overrides one method.
  • onWindowAdd(window:TitleWindow):void
It is pretty basic, when the window is added, it adds a Rotate3D and Fade effect to the added window.

View Sample 2 (right click the sample to view source)

Here is one last sample showing how window modifiers work.  In the sample below, I have included four window modifiers.  The WindowSnapper, WindowBoundaryEnforcer, WindowEffects and a new WindowSaver class that is responsible for saving the position of the window and re-positioning when the window is added again.  When you view the sample for the first time, the windows will first be positioned at 0,0.  After you move or resize a window, the window position and size will get stored in a shared object.  After positioning and resizing the windows, close the application.  When you view the application again, the windows should be positioned and sized to where you last left them.

View Sample 3 (right click the sample to view source)

In the next post, I will show you some more window modifiers that I have created and also the start of a Flex 4 dashboard entirely based off the WindowManager class and its window modifiers.