Monday, June 28, 2010

Flex 4 Spark Resizable Controls

Please go here for Flex 3 Resizable Containers.

I've created a bunch of skins for many of the common Spark components that allows them to be resized. Each of these skins contains a resizeHandle that when dragged allows the control to be resized. There are two resize handle classes that you can use, the default is called flex.utils.spark.resize.ResizeHandleLines. You can replace every occurrence of that class with flex.utils.spark.resize.ResizeHandleDots if you prefer.

Here are a list of resize skins:

With the exception of the ResizableLabel class, all the others are Skins, and as such can be used very simply by setting the skinClass="flex.utils.spark.resize.___Skin" property to the appropriate skin.

Another option is to create a CSS style for ALL spark.components.Scroller classes to use the flex.utils.spark.resize.ResizableScrollerSkin class like this:
<fx:Style>
@namespace "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace spark "flex.utils.spark.*";
@namespace resize "flex.utils.spark.resize.*";

/* Make all Scroller's use the resizable scroller skin. */
s|Scroller {
  skin-class: ClassReference("flex.utils.spark.resize.ResizableScrollerSkin");

</fx:Style>

** Note that I've renamed the Flex3 package flex.utils.ui.resize.* to the new Flex4/Spark package name flex.utils.spark.resize.*.

The most used skin is the ResizableScrollerSkin, it is used on TextAreas, Lists, DataGrids, Trees, ComboBoxes, DropDownLists, and anything else that uses a Scroller component. The way it works is to use a skin for the Scroller that adds the resize handle and uses custom HScrollBar and VScrollBar classes which leave room for the resize handle (the simplest way I could think to do it). Each of the resizable skins uses the ResizeManager class to handle the mouse events and resize the appropriate control.

The resizable ComboBox and DropDownList skins are slightly different in that they both save the size of the drop down list since it gets destroyed and re-created each time. It also sets the popUpWidthMatchesAnchorWidth="false" after resizing since the width no longer matches the anchor.

I've also added support for restricting the resize in only the vertical or horizontal direction. There are many ways you can do this, you can either set a style on the resize component:
.resizePanel {
  resize-direction: vertical; /* or horizontal */
}
Or you can call a static method on the ResizeManager class:
ResizeManager.setResizeDirection(resizePanel, "vertical"); // or "horizontal"
Or if you can access the ResizeManager class (usually stored in the skin class), then you can set the resizeDirection property on the manager like this:
resizeManager.resizeDirection = "vertical"; // or "horizontal";
There are constants defined in the ResizeManager class for "vertical", "horizontal", and "both" (default).

September 30th, 2010 Update:
I've added a new skin called ResizableDraggableTitleWindowSkin that uses the MoveManager class to allow dragging the TitleWindow around the screen. It also adds a small drag handle in the titlebar too.
The same could be done for other classes (e.g. Panel) by following the same procedure. All that is required is a dragComponent (the component that listens for mouse drag events) and a moveComponent (the component that gets moved - in this case it is the TitleWindow).

Here is an example of most of the skins, view-source enabled.

Tuesday, June 1, 2010

TitledBorderBox (Flex 4/Spark)

I've re-written my original TitledBorderBox class (Flex 3) to use Spark/Flex 4 components. It is slightly simpler, and hopefully more lightweight. It extends the SkinnableContainer class, and uses it's own skin (flex.utils.ui.TitledBorderBoxSkin).

Here are the properties on the component:
  • backgroundAlpha - the background alpha for the box (default: 1)
  • backgroundColor - the background color for the box (default: white)
  • backgroundVisible - if the background should be shown (default: true)
  • borderAlpha - the border alpha for the box (default: 1)
  • borderColor - the border color for the box (default: black)
  • borderWeight - the thickness of the border (default: 1)
  • borderVisible - if the border should be shown (default: true)
  • cornerRadius - the corner radius for rounded corners (default: 0)
  • dropShadowVisible - if a drop shadow is shown (default: false)
  • titleStyleName - the style name for the title label (default "windowStyles")
  • title - the title to show in the border
It also supports most of the layout properties too as styles (paddingLeft/Right/Top/Bottom, gap/horizontalGap/verticalGap, horizontal/verticalAlign, etc) for convenience.

The way the border is drawn is to simply draw a line over top of the border, but underneath the title that is the same color as the background. If you set borderVisible="false", then it will attempt to find the background color of the parent and use that instead.

Here it is in action (view source enabled, right click):

Friday, May 14, 2010

Highlight The ScrollBar Track

I'm not sure what this feature is called, but have you seen in Google Chrome when you search the current web page for a certain phrase, the vertical scroll bar will be highlighted showing you all the locations of that phrase? See the screenshot on the right for an example of what I mean.  In front of the track, but behind the scrollbar thumb are lines showing you were the search results are located. It's a nice little feature that I find quite helpful.

I've implemented the same thing in Flex for showing the scrollbar track highlighting when words in a TextArea are highlighted, and when items are selected in a List (it should work for a DataGrid too, but I haven't tested it).

The nice thing about my implementation is that it is very simple to set up.  All you have to do is set the verticalScrollBarStyleName property on your List, DataGrid or TextArea, and then create your CSS to set the trackSkin style to one of my two custom skins and it will all work.
E.g.
<mx:Style>
.highlightList {
    track-skin: ClassReference("skins.HighlightListScrollTrackSkin");
}
.highlightTextArea {
    trackSkin: ClassReference("skins.HighlightTextAreaScrollTrackSkin");
}
</mx:Style>

<mx:List verticalScrollBarStyleName="highlightList"/>

The text highlighting in the TextArea is done using some useful code that I found on this blog:
How to Highlight the Text in Flex.
I slightly modified the com.components.BlockTextArea class to make it work with my skins.HighlightTextAreaScrollTrackSkin class.

Here's the example (right click to View Source):


You can also set two more styles if you want to customize the color and alpha transparency of the highlighting:
highlight-color and highlight-alpha. Just add it to the css classes shown above.

Wednesday, April 21, 2010

Prompting Controls (Spark/Flex 4)

Here are a few useful controls written in Flex 4 for displaying prompt text, and for showing an icon in a button.

The IconButton class extends the defaults Flex 4 Button class, and adds the icon style as well as the labelPlacement (left, right, top, bottom) and paddingLeft, paddingTop, paddingRight, and paddingBottom styles.

I also made a simple extension of the TextInput class which shows a prompt text when the text input is empty and not in focus, it is called PromptingTextInput.

The third example is called ClearTextInput, it extends PromptingTextInput to show a small clear button (which is a IconButton) on the right hand side of the text input whenever there is text inside the text input.

The fourth example is what I call a PromptingList. It shows a prompt text whenever the list is empty. This is useful if you have a list that gets populated from a remote service (e.g "Loading..."), or if your list gets items added to it by the user, or by dragging items into the list (as in the example below).

Each of the prompting controls supports a style called promptStyleName which lets you set the styleName for the prompt Label.

** Note that the package structure has been renamed to flex.utils.spark.* for all Spark controls.

Here it is:

Tuesday, April 20, 2010

Divider Background Color

Here is a simple component that extends the Flex 3 mx.containers.DividedBox class to provide two styles for filling in the background behind each divider.

My component is creatively called flex.utils.ui.DividedBox. It has all the same properties and styles as its parent, plus these two styles:
  • dividerBackgroundColor - the background color behind each divider, defaults to #000000.
  • dividerBackgroundAlpha - the alpha value for the background color, defaults to 1.

Here it is in action (View Source enabled):