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.

79 comments:

MotionMaker said...

These are great. Thanks I am using ResizableTitleWindow skin for a popup I have.

I noticed the TitleWindow content in not contained of clipped when you resize to smaller size.

Anonymous said...

Thanks for these great controls.
I'm wondering if there is an easy way to find out if a resize is triggered by the resizeHandle?

Chris Callendar said...

HI there,

When the resize is happening 3 events get fired:
1. resizeStart - before the resize happens (it is cancelable too)
2. resizing- while the resize is happening
3. resizeEnd - after the mouse up event, when the resize has finished.

These 3 events only get fired when you resize with the resize handle.
They are dispatched by the resizeComponent, so add your listener on that component, not the ResizeManager.
There are constants for those 3 values on the ResizeManager class.

I had a typo on the resizeEnd constant, so it was previously ResizeEnd in case you are using an old version. But if you just use the constant in ResizeManager then it should work regardless.
e.g.
resizeComponent.addEventListener(ResizeManager.RESIZE_END, handler);

Cheers,
Chris

Sören said...

Works like a charm!
Thanks for your help.

Anonymous said...

Any chance your going to migrate your moveable resizable containers over to Flex 4 also?

Markus said...

Hi,

this is what i was looking for. Thanks for that!!
Is it possible to make the Panel draggable as well? That would be very helpful.
Thank you for your great coding!

Chris Callendar said...

Anonymous - I believe I have migrated all the moveable resizable containers to Flex 4, that is what this blog is about!

Markus - to make the Panel draggable, just look at how the ResizableTitleWindowSkin is done, and adjust the ResizablePanelSkin to match it. I didn't bother doing that one since the TitleWindow and Panel classes are so similar.

You could also probably use a Panel with the skinClass set to the ResizableTitleWindowSkin, but it would have the close button visible...

Markus Ringel said...

Hi Chris,

thanks for the quick respond.
I used the ResizableTitleWindowSkin but unfortunately the instance is not draggable. I looked up the code in ResizableTitleWindowSkin but i could not find any hints for the draggable/moveable implementations.
For my application i need 2 Panels/Containers which are both resizable and draggable, so that the user can decide by himself where or how big he wants the Panels.
Your code was very helpful so far and i hope that i dont ask for too much help( i guess you are busy man :), anway i hope we can solve this problem.

thanks again for your help,
Markus

Anonymous said...

Thanks for the big help.

However, I cannot find the lib package for ResizeManager. More specifically, the maven artifact for it. Can you point me to the library package? Thanks.

Chris Callendar said...

Hi Markus,
I guess I should have looked at the source code first... sorry. I've migrated the MoveManager class over from Flex 3, and updated the example above to include one with a resizable draggable TitleWindow that uses a new skin called ResizableDraggableTitleWindowSkin. It is very simple to do the same for a Panel - Make a copy of the ResizablePanelSkin (or just edit it) and add in these lines from the ResizableDraggableTitleWindowSkin:


[Bindable]
public var moveManager:MoveManager;

// inside the creation complete handler:
moveManager = new MoveManager(hostComponent, topGroup);


Note that the dragComponent is set to the topGroup, unlike the TitleWindowSkin that defines a separate moveArea Group and adds a DragHandle component.

Chris

Chris Callendar said...

Hi Anonymous,

I don't provide a library package or a maven artifact. The source code is available above by right clicking on the example and choosing View Source. From there you can download the source code and use it as you choose - either include it in your Flex Project, or make a new Flex Library Project, or whatever.

Chris

markus said...

hi Chris,
i have to say that you are really fast. Anyway i did it the same way you did (i should have waited a few more hours :).
Just wanna tell you that i found a little bug, when you resize the panel/titlewindow you can cross the border from your parent even if the constrains are set.
Great work though!!

markus said...

Hi Chris,

also another question: How can i integrate a css file into the skin? Because in the code you refer to a style parameter, for example the cornerradius. i mean i can hack it hard into the code but i guess that is not really clean.
hope to hear a suggestion from you!
Have a great weekend! thumbs up for your support!

Chris Callendar said...

Hi Markus,

I've updated the example above so that the Constrain checkbox also constrains the resize. I added very similar code to the ResizeManager as was in the MoveManager. I don't expect it to work perfectly, but it is a start that people can build off of I hope.

As for CSS in the skins, each control (TitleWindow, Panel, etc) defines a set of styles that it checks for, like cornerRadius. So you can either do inline styles like this:

<s:TitleWindow cornerRadius="7" skinClass="..."/>

Or you can do this:
<fx:Style>
.resizePanel {
resize-direction: vertical;
corner-radius: 7;
}
</fx:Style>
<s:Panel styleName="resizePanel" skinClass="..."/>

All my skin classes are copies of the default skins class, so ResizablePanelSkin is a copy of PanelSkin, with a few tiny changes to add the resizeHandle and ResizeManager. So all the same styles that the Panel class allows should still work with my skins.

I usually find the best to find out which styles are supported is either too look at the source code, or the API docs like this one for Panel. Near the top it shows the properties and styles available, and farther down it shows a more detailed list of all the styles, including the inherited ones.

Hope that helps.
Chris

Chris Callendar said...

Oh, and to actually include a CSS file, you'd do this:

<fx:Style source="assets/css/applicationcss"/>

Cubesfactory.com said...

Hey, great work but I have a little problem with it.
The thing is, if your component has a minWidth and you keep moving your mouse as if you were reducing its size, then the shrinking stops. Wich is good! But then, when you start moving your mouse toward the edge again, the component starts to expand even though your mouse is still inside the component.
Arg, this is hard to explain... Do you understand what I mean? My english isnt so good.
Thank you if you get it and have a solution!

Chris Callendar said...

Hi,

I think I know what you mean. You are resizing, and you reach the minimum size, and so the resizing stops, but your mouse keeps moving, and then if you start moving your mouse back out again, the resize immediate starts expanding even though your mouse is no longer over the drag handle.

I've seen this many times, but never tried to fix or prevent this from happening. I realize that it is not ideal, but in my opinion it is not serious enough to try and fix!

I would think that a possible solution is to compare the mouse position to the resize handle position, and then you could prevent any resizing from happening if the mouse isn't over the resize handle.

Cubesfactory.com said...

Hey, checking if the mouse was over the handle gave not so good result. I did work something out though, did this quickly so I am not sure how optimised it is but it works.
If you are interested tell me, I'll send you my code.
Thanks again.

LouD said...

When resizing the component, the children components dont seem to be containtained by the parent. So that when you resize the parent to smaller than the children they are not hidden by the panel.

Is there a way to keep them within the panels bounds?

Chris Callendar said...

Hi LouD,

Good observation. The children will not be affected by the parent being resized unless their positions or sizes are set to be relative to the parent. E.g. height="100%" or bottom="0".

One thing you could do is put a Scrolleras the only child of the parent, and set it to width/height = 100% then when you resize the children of the Scroller would be contained inside, and the scrollbars would allow you to still see the children.

Otherwise, there is a property that you can set to clip the content:
Group.clipAndEnableScrolling. Since the TitleWindow and Panel classes don't extend GroupBase, they don't have this property. So you can either add a single Group child to the TitleWindow and set the clipAndEnableScrolling property to true, or you can access the contentGroup property on the resizable window/panel (on creation complete) and set the clip property in action script. Or you can modify the skin class directly (e.g. ResizableTitleWindowSkin) and set the clipAndEnableScrolling property right on the contentGroup Group control in the skin.

Hope this helps.
Chris

Chris Callendar said...

For more information about clipping content inside a panel, check out this great post on flexexamples.com.

birpal said...

thank u so much for posting this blog...useful stuff!

Amritha said...

thanks so much for this! I still can't believe that flex doesn't have a simple way to do resizing.

Either way I'm trying to apply this stuff to a scrollPanel that I am trying to make resizable. I imported this from Flash Catalyst and it created a scrollPanel skin.

I initially tried to add the scrollPanel to a resizablepanel and resize it that way, but no matter what I do, the panel doesn't seem to contain the contents of the scrollPanel when I resize.

Are you familiar with the scrollPanel component? I'm guessing the path I have to take is to adjust the skin of the scrollPanel to make it resizable. Could you provide me some tips on how to go about doing this?

thanks sooo much

Chris Callendar said...

Hi Amritha,

I'm not familiar with the scrollPanel component, sorry.

But yes, I think the general approach is to modify the skin to add in the resize handle and resize functionality.

To see how this is done in the other skins, right click on the example above and go to View Source. From there you can either download the whole source code as a zip file, or you can navigate in the left tree to one of the skin classes, under src/flex.utils.spark.resize.

For example look at the ResizableTitleWindowSkin.mxml file. I think the only things added to the skin are the resizeManager reference and the created() function (in a script block), and the <resize:ResizeHandleLines> tag at the bottom. This tag is the one that shows the resize handle, so position it appropriately in your scrollPanel.

Hope this helps.
Chris

Anonymous said...

Hi Chris,

Is there a way I can disable the resizing of the TitleWindow?

Thanks,
Arshad.

Chris Callendar said...

Hi Arshad,

Just set the resizable="false" property. To disable moving the window, set movable="false".

Anonymous said...

Chris,

I have added the TitleWindow in the following way. where can I set the movable and resizable properties, as they are not available on the TitleWindow?



Thanks again,
Arshad.

Chris Callendar said...

Hi Arshad,

Sorry I don't see how your added the TitleWindow. Comments don't show up XML properly.

I should have be more clear in my first response - if you are using a TitleWindow with the ResizableTitleWindowSkin, then it is already resizable. If you want it to be movable/draggable, then you have to use the ResizableDraggableTitleWindowSkin, just as in the example on the right hand side above.

If you want to toggle whether the window is resizable, you would do something like this:
(window.skin as ResizableDraggableTitleWindowSkin).resizeManager.enabled = false;

And to toggle whether it is movable:
(window.skin as ResizableDraggableTitleWindowSkin).moveManager.enabled = false;

Kingpin said...

Is it possible to add an icon at the top left of the title bar? I found other examples but they were subclasses, not skins...

Chris Callendar said...

Hi Kingpin,

Do add an icon in the title bar, you'd have to either edit the ResizableTitleWindowSkin, or make a new copy of it and add the icon in.

If you look at the ResizableTitleWindowSkin class, find the titleDisplay Label. Then add in your <BitmapImage> or <Image> tag to the left of it. And don't forget to change the left value on the titleDisplay to shift it to the right.

Rupak said...

I am wondering how I can add a minimize, maximize, restore buttons along with the close button to the Movable & Draggable Title Window. I understand I have add more buttons with custom skins (just like TitleWindowCloseButtonSkin) but how to transmit their clicks upto the TitleWindow just like "close" is transmitted for close button when clicked.

Chris Callendar said...

Hi Rupak,

As you probably already saw, the way the close event works is the TitleWindowSkin has a close button, and the TitleWindow classes adds a MouseEvent.CLICK event listener to that button in the partAdded() function. When the click event happens, the TitleWindow then fires the CloseEvent.

So you could do the same thing with minimize, maximize, and restore. I would make a new class that extends TitleWindow and uses your custom skin (which could be similar to ResizableTitleWindowSkin but has the extra title bar buttons).
Then in this new class, add in the skin part references like this:
[SkinPart(required="false")]
public var minimizeButton:Button;


And override the partAdded function, in which you put something like this:
minimizeButton.addEventListener(MouseEvent.CLICK, minimizeClickHandler, false, 0, true);
And do the reverse in the partRemoved function to remove the event listener.

Then you can either have your new class dispatch a custom "minimize" event, or you can just handle the minimizing (resizing) yourself. If I was doing it I might use states to handle the different cases - normal, minimized (titlebar only), and maximized. The benefit of using states is that you can more easily add in transitions (animations) between the states like Resize.

One last thing, if you don't want to override TitleWindow and you want a quick solution then you could easily just make your own skin like the ResizableTitleWindowSkin, add in the extra buttons, and have them fire events like this using the hostComponent (which is your TitleWindow);
<s:Button id="minimizeButton"
click="hostComponent.dispatchEvent(new Event('minimize'))"/>


And then in ActionScript you could add a listener for that event on your title window
titleWindow.addEventListener("minimize", minimizeHandler);
Unfortunately you can't do that in MXML because it doesn't know that it fires a minimize event.
Using this approach you might find it hard to change the minimize/maximize buttons into restore.

Anyway, have fun, sounds like a good challenge :)
Chris

soufiane said...

please help me I don't anderstand the example, can some one give me o simple example how to create an resizable TextArea with flex 4?

thanks

soufiane said...

Hey Mr Chris,

please, can you give me an example how to create a resizable and movable TextAre, I tried with your example but it didn't work.

thank you

alexbychok said...

Hi
How can I disable the resizable property of TitledBorderBox?

(TitledBorderBox1.skin as ResizableTitledBorderBoxSkin).resizeManager.enabled = false; is not working.

(TitledBorderBox1.skin as flex.utils.spark.resize.ResizableTitledBorderBoxSkin).resizeManager.enabled = false; also don`t work. Flash builder shoes an error: "Access of undefined property resize in package flex.utils.spark".

Chris Callendar said...

soufiane - right click on the example above and choose "View Source", this will open a new window. Click on the "Download source (ZIP)" link in the bottom left corner of that window. Unzip that file. In your existing Flex project, copy or move the flex and assets folders from the FlexDevTips_ResizableControls/src/ into your project's src folder.

Then inside your application, do exactly the same as I've done in the ResizableControls.mxml example:

<s:TextArea height="100" width="220"
skinClass="flex.utils.spark.resize.ResizableTextAreaSkin"/>


Chris

Chris Callendar said...

Hi alexbychok,

I'm not sure why it is not working for you.
The only thing I can think of is that maybe the resizeManager hadn't been initialized yet when you tried to disabled it?
The resizeManager is created in the creationComplete handler of the ResizableTitledBorderBoxSkin.

I did the following and it worked perfectly for me:
<spark:TitledBorderBox id="resizableTitledBorderBox" height="80" width="220"
    skinClass="flex.utils.spark.resize.ResizableTitledBorderBoxSkin"
    title="ResizableTitledBorderBoxSkin">
    <spark:creationComplete>
    <![CDATA[
        (resizableTitledBorderBox.skin as ResizableTitledBorderBoxSkin).resizeManager.enabled = false;
    ]]>
    </spark:creationComplete>
</spark:TitledBorderBox>


This made the resize handle in the bottom right corner hidden.
Chris

alexbychok said...

Hi

Sorry, I did not explained the whole problem. I wrote my code in a fx:Script section like this:

protected function button1_clickHandler(event:MouseEvent):void
{ (TitledBorderBox1.skin as flex.utils.spark.resize.ResizableTitledBorderBoxSkin).resizeManager.enabled = false;
}
It did not work.

When I copied the files ResizableTitledBorderBoxSkin.mxml and ResizeManager.as in a flex.utils.spark folder and use this skin, everything was fine.

I think it's flex bug.

Anonymous said...

I am looking for a resizable title window which can be resized from all sides (not only the lower-right corner). Does anyone have the example code?

Thanks in advance!
Pat

Chris Callendar said...

The only example that I've seen where a window is resizable from all sizes is the MDI project (which is now part of FlexLib I believe).

Here is the homepage for it:
http://code.google.com/p/flexmdi/,
and here is an example of it in action:
http://www.returnundefined.com/flexmdi/explorer/.

Sören said...

Hi Chris,

I'm using your resizable controls in a prototype, created as part of my diploma thesis (http://tfacet.visualdataweb.org).

Now I want to release it as open-source under the GPL.
Unfortunately, the CC BY 2.5 seems to be incompatible to the GPL (see http://wiki.creativecommons.org/FAQ#Can_I_use_a_Creative_Commons_license_for_software.3F).

So I'm asking if it would be possible to additionally license your code under the GPL or a compatible license.

Thanks and regards,
Sören

Rich Rodecker said...

Thanks for the components, nice job. One small issue I've found, not sure if this is a bug or I'm not using this properly: in the getter for ResizeManager.resizeDirection, it will always return "both" if the _resizeDirection prop is already set to anything other than "both". I just added an else to fix it:

if (_resizeDirection == DIRECTION_BOTH) {
// first check if a style was set on the resize component
//...existing code
}else{
direction = _resizeDirection;
}

Chris Callendar said...

Thanks for catching that Rich, it is definitely a bug.
Chris

Anonymous said...

Wow this is nice work! Amazing what you can get on the web for free these days...thanks for the download...Supersize me!

Anonymous said...

thanks for your component!

I used it in my own project: ABCDiy, which will be released soon. it is a ABC file editor.

swfdiy dot com

Alan Costello said...

Got to comment as you have provided such a wonderful bit of code for free. I used the previous version with Flex 3, now using your Flex 4 version. What you did is way beyond my ability - am using the ResizableDraggableTitleWindow and it really enhanced my online educational software. Amazing stuff. I am indebted to you.

Anonymous said...

Thanks a lot, very useful!

John said...

Hey Chris!
Great set of classes! I have a question about the licensing. Can I use your resizable controls in a commercial project? And are there any conditions I should meet when I decide to use this? Can't figure out under what license it is.. GNU or CC 2.5 or something else?

Hope you can send me an email (john at 80db dot nl) or react to my comment!
Thanks,
John

Jakub Gemrot said...

Hi!

If anybody has a problem, that the window returns to its original position after you move it and resize it, read: http://stackoverflow.com/questions/2426591/why-startdrag-and-stopdrag-dont-effect-the-x-y-coordinates

I've used it to hack-fix/workaround the bug by adding this:

moveComponent.x = moveComponent.mx_internal::$x;
moveComponent.y = moveComponent.mx_internal::$y;

Into MoveManager.dragComponentMouseUp() right AFTER the first line "moveComponent.stopDrag();".

(
Don't forget to use:
import mx.core.mx_internal;
use namespace mx_internal;
)

Note that hack-fix is manually updating "x, y" members of the UIComponent which should in fact be updated by invoking "moveComponent.stopDrag();", but that line fails to do so for me (using Flex 4.5.1).

Cheers!
Jimmy

Anonymous said...

Hi Chris,
Great post.

I'm having a compilation problem with the resizableDraggableTitleWindowSkin.
It can't find the ResizeManager and the MoveManager

[Bindable]public var resizeManager:ResizeManager;
[Bindable]public var moveManager:MoveManager;

and this one:
resize:ResizeHandleLines..

I'm using Flash Builder 4.5 with the 4.5.1 SDK.

I'm a newbie and I don't know what I've done wrong..


Thanks
Laurent

Chris Callendar said...

HI Laurent,

Have you downloaded the source code from above? If you right click on the example above and click View Source, then you'll see all the source code. You can download the source as a zip file by clicking the Download source (zip) link in the bottom left corner. Inside the zip there will be the src folder structure, containing the ResizeManager and MoveManager classes (and ResizeHandleLines) under the flex.utils.spark.resize package.

If you are trying to use these classes, make sure they are in your project in the src/flex/utils/spark/resize folder, and then make sure they are added as imports like this:

import flex.utils.spark.resize.ResizeManager;

Chris

Ted said...

Hello Chris,

I had to add a couple of default states to the ResizableTextAreaSkin.mxml file to get the code to compile:

Ted said...

s:states>
s:State name="normal"/>
s:State name="disabled"/>
s:State name="disabledWithPrompt"/>
s:State name="normalWithPrompt"/>
/s:states>

Lara Leon said...

Chris, I love your resizable controls. I am using the ResizableTitleWindowSkin and I was able to create a grid inside of it an a function to close when I click on the close button. However I just need the draggable function, not the resizing. Is there a way to make the title window not to be resizable? Thanks a lot! You can send email to iwilson@tfs.tamu.edu if you would prefer to answer it by email! Thanks a lot!!!

Chris Callendar said...

Hi Lara,

It is definitely possible to prevent resizing. It can be done a number of ways, choose whichever you feel is the easiest!

In your mxml code that creates the title window, add a creationComplete event listener and disabled the resize manager. It could look something like this:

MXML:
<s:TitleWindow id="myWindow"
  creationComplete="windowCreated(event)"
  skinClass="flex.utils.spark.resize.ResizableDraggableTitleWindowSkin"> ...

ActionScript:
private function windowCreated(event:Event):void {
    (myWindow.skin as ResizableDraggableTitleWindowSkin).resizeManager.enabled = false;
}

Alternatively if you want to change this behaviour for all your windows, you can just edit the ResizableDraggableTitleWindowSkin.mxml file and add this one line at the end of the created() function:
resizeManager.enabled = false;

That way the resize manager is always disabled.

Chris

Lara Leon said...

Hi Chris, I am not sure my response to your reply went through. I just want to thank you for the great tool! I was able to disable resizing. Would be possible for the datagrid I have inside the window to resize when the user resizes the window? This would be the best for me because I like the resizing functionality but the datagrid I have does not resize with the window.

Chris Callendar said...

Hi Lara,

The datagrid should automatically resize to fill the window if you use
width="100%" height="100%"
or if you use
left="0" right="0" top="0" bottom="0"
on the datagrid. Otherwise you'd have to add resize listeners to your window, and do some math to figure out the available space for your datagrid.

Lara Leon said...

I will try that! Thank you again Chris for your answers and for a great tool! Cheers

Lara Leon said...

Chris, I changed the datagrid's width and height and now it is resizing with the window! Can you please tell me how I can have the window constrained to the parent bounds automatically? I dont want to have a check box to do that. Would that be possible? Thanks again!

Chris Callendar said...

Hi Lara,

All the source code is available above - right click and go View Source to see it. If you look at what the constrainCB CheckBox change listener does it should be pretty straight forward to modify that to your needs.

But if you need the exact steps, do this:
1. Add a creationComplete event listener to your title window.
2. In the event handler, do this (assuming your window has id="resizeWindow"):
var skin:ResizableDraggableTitleWindowSkin = (resizeWindow.skin as ResizableDraggableTitleWindowSkin);
skin.moveManager.constrainToParentBounds = true;
skin.resizeManager.constrainToParentBounds = true;

Bill Kidwell said...

Chris,

Thanks for these tips. These are still great stuff.

I am confused about the license for these samples.

Am I able to choose either Creative Commons 2.5 or LGPL v3.0?

Thanks,

Bill

Chris Callendar said...

Hi Bill,

Yes, you can choose which ever one works better for you. I originally had it under CC, but a few people complained that it wasn't open source or they couldn't use CC, so I added LGPL to keep them happy.

Cheers,
Chris

Lara Leon said...

Thank you so much Chris! Now it is perfect! I appreciate your help!!! Cheers!!! Lara

mark goldin said...

Does it work in FB 4.6? I am trying to use ResizableScrollerSkin and getting many compile errors.

Thanks

Chris Callendar said...

Hi Mark,

Have you had any luck? It definitely works with FB 4.6. If you right click on the example above, and download the whole source zip file (bottom left corner - Download source), and include it in your project you should be able to use it without compile errors.

Chris

mark goldin said...

As a matter of fact it did work. Thanks

SlyK said...

Wow, that's just right what I was searching for. Thanks!

I'm sorry for being insolent but I have some trouble in creating custom component for my app (like advanced List component with icons and one-way selecion indication). Don't want to flame here with detailed description, but if you may find couple of minutes for me I would be happy :) my ma1L: kirill{a)slyk.ru

Unknown said...
This comment has been removed by the author.
Unknown said...

Hi Chris,

I downloaded your files (fabulous stuff!), and went to run a simple test using PopUpManager and am getting this error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at classes.ui.resize::ResizableTitleWindow

The error is at the first line of this function, and 'hostComponent' is null:

private function created(event:FlexEvent):void {
if (hostComponent.minWidth == 0) {
hostComponent.minWidth = minWidth;
}
if (hostComponent.minHeight == 0) {
hostComponent.minHeight = minHeight;
}
resizeManager = new ResizeManager(hostComponent, resizeHandle);
moveManager = new MoveManager(hostComponent, moveArea);
}

The test code is pretty simple:
protected function popTitleWindow():void
{
ttw = new ResizeTest();
ttw.titleDisplay.text = "Resizable Title Window title";
ttw.width = 300;
ttw.height = 200;
ttw.addEventListener( CloseEvent.CLOSE, ttlWndw_close);

PopUpManager.addPopUp(ttw, FlexGlobals.topLevelApplication as DisplayObject, true);
PopUpManager.centerPopUp(ttw);
}

protected function ttlWndw_close(evt:CloseEvent):void {
PopUpManager.removePopUp(evt.currentTarget as IFlexDisplayObject);
}

Am I missing an import?
I am new to Flex 4.6 but have been in Flex 3-land for awhile. Thanks in advance!

Cheers,

Chris Callendar said...

Hi, sorry for the slow reply.

I'm not quite sure what the problem is. But in your error message above you said it shows:
"TypeError: Error #1009: Cannot access a property or method of a null object reference.
at classes.ui.resize::ResizableTitleWindow".

But what is "classes.ui.resize.ResizableTitleWindow"? The closest class I see in my project is "flex.utils.spark.ResizableTitleWindowSkin" - did you rename it? If so that might be your problem. It is easiest just to keep the names as is then it will all work. There are some inter-dependencies between the various skins and components.

When I download the source code and make a new project with it, the only error I see in Flash Builder 4.6 is a problem with ResizableTextAreaSkin missing 2 skin states which can easily be added. I tried making a resizable popup window using your code, and there is a problem with trying to set the title on the second line:
ttw.titleDisplay.text = "Resizable Title Window title";
You can't access the titleDisplay until the skin is set (e.g. in creationComplete).
You should instead do this:
ttw.title = "Resizable Title Window title";

Anonymous said...

Is it really working in the latest Flash Player? Or there is another reason why most of shown resizable windows don't actually resize their content?

Chris Callendar said...

They all work for me on the latest flash player in Chrome. Which ones don't work for you?

Anonymous said...

When I resize it the content of resizable window is not affected. What's a reason to resize then? Try the one is called Draggable and resizable.

Chris Callendar said...

Ah I see what you mean. Sorry I thought the resizing wasn't working, but as you did say above the content of the window isn't resized properly.

In this case (The Draggable one on the right) the child components (Labels, CheckBox) are absolutely positioned - so they aren't resized when the window size changes. To make the contents resize, then usually a VerticalLayout would be used instead of the BasicLayout. So that window would look a lot better with a VerticalLayout, some padding, and each label/checkbox using 100% width. Then they would resize much better.

So basically it's up to you to control how the contents of the containers are laid out.

aislinn said...

i must thank you for the efforts you've put in penning this blog. excellent blog post .

www.n8fan.net

Bhaskar Pandey said...

Hi Chris,
Your re-size conntrol works great, but this only deals with the height and width property not with the x and y. Can you please help me to create a resizable control which can be resized from every angle. Top-left, top-center , top-right, left-center, right-center, bottom-left,bottom-right,bottom-center. I am needing this component for my current project. Can you please help me out ?
Thanks in advance.

Chris Callendar said...

Hi Bhaskar,
I'm actually not doing any Flex development these days, so you're on your own. Hopefully my example above is a good starting point. Good luck.

Bhaskar Pandey said...

Thanks for the reply Chris. Actually I have created a multiple resize component based on your code. It works fine when I am providing the x and y to the resize component but I am using this component inside ItemRenderer that's why I need to provide this x and y to itemRenderer itself, and that is creating problem. If you can guess my problem, please suggest me some ideas to achieve the x and y for of its itemRenderer when resizing this component.
Thanks in advance.

Bhaskar Pandey said...

Hi Chris,
Fixed the issue. Thanks anyways and really without your resize component it wasn't so much easy. Thanks.