Resizable TitleWindow in Flex 4

The spark TitleWindow allows you to drag it around the stage through the use of a skin part called “moveArea”. By attaching mouse handlers to the moveArea, the TitleWindow can be dragged around the screen. In a similar fashion, we can add another skin part called “resizeHandle” to allow the TitleWindow to be resizable.

To do this, we will subclass TitleWindow and implement mouse handlers that are attached to the new resizeHandle skin part. These mouse handlers change the width and height of the window as the user drags the skin part.

Here is a simple example of this resizable TitleWindow:

View Source

In this example we add the mouseMove and mouseUp Handlers to the systemManager’s sandboxRoot to ensure we are able to drag over sub applications that are compiled with different versions of Flex. Read more about this at the “Marshall Plan” spec.

Note: This sample requires Flex SDK 4.0.0.13266 or higher. You can get the latest SDK builds from opensource.adobe.com.

38 thoughts on “Resizable TitleWindow in Flex 4”

  1. Awesome! Thanks, this really helps a lot, I’m sure everyone needs a component like this at some point πŸ™‚

  2. Hi Kevin,

    thank you for that component! It’s a lifesaver. I recently tried to subclass it with MXML and I wonder how I can apply a layout property that looks like this

    to it. I can easily do this with the spark TitleWindow but not with yours unfortunately. The compiler then shows the error

    Could not resolve to a component implementation.

    It would be very handy to apply a different layout just like with the original spark TitleWindow, I just can’t figure out how. Do you have an idea?

    Regards, Thilo

  3. @Thilo

    The code examples got consumed by WordPress I guess πŸ˜‰ I hope this post works:

    The layout property looks like this:

    <s:layout>
    <s:BasicLayout/>
    </s:layout>

    And the error was:

    Could not resolve <s:layout> to a component implementation.

  4. I’m trying to add a ResizableTitleWindow to a BorderContainer instead of using PopUpManager.addPopUp(rtw, this, false). I’ve tried calling PopUpManager.addPopUp(rtw, borderContainer, false) and borderContainer.addElement(rtw). Neither of these work. Any ideas?

  5. Kevin,
    Great work on the component. I am very new to Flex and have been stumped by a problem that I can’t seem to figure out. Your example reminded me of it. What if I want to add more buttons to the title bar area of a spark title window? More descriptively, say I want a help button next to the close button that pops it’s own title window on click? I was experimenting and got something to work by customizing a skin, but I’m very curious to see someone else’s take on the subject.
    In the past, I’ve gotten it to work on the panel component but I was curious if it would work on the title window component as well.
    Thanks in advance.

  6. Hello

    Thanks for this code. I use this, and I have a probleme with the right click. The resizable title windows block the right click ont the element.

    Can I use the right click with this example ?

    Thanks in advance

  7. @Steve
    When you add a popup, the parent parameter is not the actual parent of the popup. Instead, the parent is the SystemManager and the PopUpManager just uses the parent to position the popup.

    The third one should work. Try that one again? If it doesn’t, send me more code. Thanks for your question!

  8. @Matt
    I would approach it the same way that the close button is done in TitleWindow. Basically, you can extend or modify ResizableTitleWindow to have a “helpButton” skin part. You can then attach behavior to the helpButton’s click event. Don’t forget to include the skin part in the skin as well!

    Thanks for your comment and questions!

  9. This is a great component. Thanks! I did find a bug that if you resize the dialog to be smaller than the components that it contains, it will often crash AIR. The fix is to enforce a minimum size for the dialog. In ResizableTitleWindow.as add:

    private var minWidth:Number = 100;
    private var minHeight:Number = 100;

    public function setMinimumSize(newMinWidth:Number, newMinHeight:Number):void{
    if (newMinWidth > 0) {minWidth = newMinWidth;}
    if (newMinHeight > 0) {minHeight = newMinHeight;}}

    In resizeHandle_mouseMoveHandler() add this before “event.updateAfterEvent()”:

    var newWidth:Number = prevWidth + (event.stageX – clickOffset.x);
    var newHeight:Number = prevHeight + (event.stageY – clickOffset.y);
    if (newWidth < minWidth) {newWidth = minWidth;}
    if (newHeight < minHeight) {newHeight = minHeight;}
    width = newWidth;
    height = newHeight;

  10. Hi! I found this component by google and it is really good. I want to added it into my own open source project which contains some useful components I wrote by myself. Of course I’ll add your copyright in documents. Could I do this? Here is my project page: http://code.google.com/p/richflex/ and your code is added in org.galaxy.richflex.components.Dialog class. If you do not agree I do this, I’ll remove this code. Thank you! Nice work!

  11. @Cheng Liang
    Feel free to use the code from this post in your project. We appreciate you providing a link back to this post because it might be useful for people browsing your code to have a place to get more information if they need to. Thanks for letting us know! πŸ™‚

  12. @Cheng Liang

    Hi, Cheng,

    Is there source codes or swc can be download from your Google code repo?

    http://code.google.com/p/richflex/

    The components and utilities in the project list seems to be interesting and best of all, you are using 4.1 SDK. It’s not easy to find 4.1 components now. If you have your project setup there, I may also be able to contribute to your project as well.

    Thanks.

    Jason Chen

  13. Hi,

    I have a question about the component. If I set no explicit width/height for the ResizableTitleWindow and the contents have width=100% instance then, like TitleWindow, it will size to the content and resize in reaction to the content changing. But when you drag resize then the window stops reacting to changes in the content’s dimensions. Conversely, if you resize the content before you drag then try dragging the content will not resize to the window.

    I think it’s because when you explicitly set the width/height properties the percentWidth/percentHeight is set to NaN, you can’t just set it back straight back to 100% after setting it explicitly though as the explicit change will not have time to take effect (or something), can you suggest anything?

    Many Thanks,
    Stu

  14. @Stu
    Thanks for your question. I think what you’re trying to ask is how to resize the TitleWindow without affecting its width/height/percentWidth/percentHeight properties? I haven’t tried this myself yet, but I think your best bet would be to change:

    width = prevWidth + (event.stageX – clickOffset.x);
    height = prevHeight + (event.stageY – clickOffset.y);

    to

    var w:Number = prevWidth + (event.stageX – clickOffset.x);
    var h:Number = prevHeight + (event.stageY – clickOffset.y);
    this.setLayoutBoundsSize(w, h);

    If that doesn’t work, you can also try setActualSize() instead of setLayoutBoundsSize(). The idea behind this is to cause the window to resize, but not side affect any of the RTW’s properties. Try it and let me know if it works!

  15. Great component. Thanks!

    Has anybody implemented a mouseover handler which changes the cursor to a resize cursor when the mouse is over the resizeHandle?

  16. Hi,

    I have a question regarding your component. How can i include interactive elements inside the titleWindow popup eg. graph, datagrid etc. ?

  17. Enforcing a fixed size should be done something like this…

    Change these lines in resizeHandle_mouseMoveHandler:
    skin.width = prevWidth + (event.stageX – clickOffset.x);
    skin.height = prevHeight + (event.stageY – clickOffset.y);

    Override the measure function:
    override protected function measure():void
    {
    if(skin)
    {
    var skinMinWidth:Number = isNaN(skin.minWidth) ? 200 : skin.minWidth;
    var skinMaxWidth:Number = isNaN(skin.maxWidth) ? 200 : skin.maxWidth;

    measuredWidth = Math.max(skinMinWidth, skin.getExplicitOrMeasuredWidth());
    measuredHeight = Math.max(skinMaxWidth, skin.getExplicitOrMeasuredHeight());

    measuredMinWidth = skinMinWidth;
    measuredMinHeight = skinMaxWidth;
    }
    }

  18. Justin :
    Enforcing a fixed size should be done something like this…
    Change these lines in resizeHandle_mouseMoveHandler:
    skin.width = prevWidth + (event.stageX – clickOffset.x);
    skin.height = prevHeight + (event.stageY – clickOffset.y);
    Override the measure function:
    override protected function measure():void

    {
    if(skin)
    {
    var skinMinWidth:Number = isNaN(skin.minWidth) ? 200 : skin.minWidth;
    var skinMaxWidth:Number = isNaN(skin.maxWidth) ? 200 : skin.maxWidth;
    measuredWidth = Math.max(skinMinWidth, skin.getExplicitOrMeasuredWidth());
    measuredHeight = Math.max(skinMaxWidth, skin.getExplicitOrMeasuredHeight());
    measuredMinWidth = skinMinWidth;
    measuredMinHeight = skinMaxWidth;
    }
    }

    Sorry, couple of typos

    var skinMinWidth:Number = isNaN(skin.minWidth) ? 200 : skin.minWidth;
    var skinMinHeight:Number = isNaN(skin.minHeight) ? 200 : skin.minHeight;

    measuredWidth = Math.max(skinMinWidth, skin.getExplicitOrMeasuredWidth());
    measuredHeight = Math.max(skinMinHeight, skin.getExplicitOrMeasuredHeight());

  19. Hi,

    Any idea if I could apply this sort of resizing to an item renderer?

    Or at least some tips on how to go about it.

    C

  20. well done sir!!! this component was more useful…I will modify it for specific purposes in the future, so it would be great if you can put this inside a google code project or do I put it in the richflex project http://code.google.com/p/richflex/ ?

  21. @Avinash
    Feel free to use the code from this post in your project. We appreciate you providing a link back to this post because it might be useful for people browsing your code to have a place to get more information if they need to.

  22. Thank you for this nice component. I already had my own resizable component, but yours has better tweaks than mine.

    My component however, have more features like:
    showPopUp(…), showPopUpCentered(…), removePopUp, resizeEnabled, dragEnabled, autoClose (automatically removes the popup when CloseEvent.CLOSE is fired), closeOnESC, and a cursor skin for resizing. I can share the component if anybody needs it.

    I had a question though:
    The closeOnESC feature should close the dialog whenever the “ESC” button is pressed. However, this doesn’t work all the time… when it doesn’t work, I have to click on a component inside the dialog in order for it to work. However, if I just click on the title bar of the dialog, hit ESC, it doesn’t work.

  23. I have the same question Mike Haggerty, “How changes the cursor to a resize cursor when the mouse is over the resizeHandle?”

Comments are closed.