I have a title window based component in Flex 4 that has two states: A & B.
The title window is wider in state B.
I want the title window to animate when I switch states by using the Resize effect to widen the component.
What's the correct way to do this? Should define state specific width for the component or should I just run a transition effect that does this? The first option seems cleaner to me, but I can't figure out how to tell flex to use an effect and figure out by itself how much to resize the component..
Assaf, You can use tween, Parallel, Move and Resize properties for the same.
I implemented something similar to your request: I needed to add a transition effect, (Resize effect), between two states included in a TitleWindow component. This is how I did it:
My two states:
<s:states>
<s:State name="State1"/>
<s:State name="myInfoState"/>
</s:states>
My transition effect:
<s:transitions>
<s:Transition id="myTransition" fromState="*" toState="myInfoState">
<s:Parallel target="{this}">
<s:Resize duration="400"/>
</s:Parallel>
</s:Transition>
</s:transitions>
Note the {this} property. This is because my TitleWindow doesn't have an id.
Finally, you just need to call your currentState declaration as always:
<s:Button click="currentState = 'myInfoState'"/>
I guess that the keyword is {this} instead of the element's id.
Greetings from Pachuca, México!
Related
I have a very general question and have prepared a simple test case.
When using BasicLayout (i.e. absolute positioning) - what is the best approach to place a Flex component in the center of the application?
In the test case below I'm using x="{width/2}" but this gives me at least 2 problems:
How do I account for the component dimensions (the ProgressBar in the test case)?
Is the binding {width/2} a good idea to use? Wouldn't it send unnecessary DATA_CHANGE events in some cases?
And finally I wonder, how this all applies to full screen applications using StageScaleMode.SHOW_ALL - because currently my application is aligned to the top-left in the full screen mode and there is a white dead zone on the right of it. (Which is at least a change from pure Flash/AS3 behaviour, where the full screen content is displayed in the center of the screen and 2 dead zones on the left and right).
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="700" height="525"
backgroundColor="#CCFFCC"
initialize="systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL">
<fx:Script>
<![CDATA[
private function fullScreen(event:MouseEvent):void {
stage.displayState =
stage.displayState == StageDisplayState.NORMAL ?
StageDisplayState.FULL_SCREEN :
StageDisplayState.NORMAL;
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="connected" />
</s:states>
<s:CheckBox right="10" bottom="10"
label="Full screen"
click="fullScreen(event)" />
<mx:ProgressBar indeterminate="true"
x="{width/2}" y="{height/2}"
label="Connecting..." labelPlacement="center"
includeIn="normal" />
</s:Application>
Way easier than that: just use horizontalCenter and verticalCenter properties of UIComponent. When used inside a BasicLayout the component will always be centered. Like this:
<mx:ProgressBar indeterminate="true"
horizontalCenter="0" verticalCenter="0"
label="Connecting..." labelPlacement="center" />
If you give these properties a value other than '0' the component will be offset from the middle by the amount of pixels you specify as a value. (e.g. horizontalCenter="50" will offset the component 50 pixels to the right of the center of the parent component)
That white space is probably due to your usage of systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL. Just remove that line. Why are you doing that anyway?
edit
Just noticed you're using a fixed 'width' and 'height' on your Application: you'll have to make those '100%' if you want your app to really fill the screen. This is another possible cause for that white space.
To get your application centered (rather than left/right aligned) when using systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL, set systemManager.stage.align to the empty string - i.e.:
// in your Application creationComplete handler
systemManager.stage.scaleMode = StageScaleMode.SHOW_ALL;
systemManager.stage.align = "";
I typically do 2 things,
I place objects inside VGroups/HGroups with alignment, I also use relative widths eg percentages.
Think like in the old days of using HTML tables. It works very well especially if your canvas is resized allot.
All of my canvases have to be resizeable as I like to only write my apps once, for pc, mobile etc, so I just make everything scalable by default.
I'm trying to create my own modal window (the built in popup manager won't work for this application) and get objects behind the window to be blurred. The code below is obviously wrong since it doesn't work but can someone point me in the right direction? Do I have to manually blur each object behind the window?
<s:Button label="Testing" left="512" top="300">
</s:Button>
<s:Rect width="1024" height="768" alpha=".5">
<s:fill>
<s:SolidColor color="#000000">
</s:SolidColor>
</s:fill>
<s:filters>
<s:BlurFilter>
</s:BlurFilter>
</s:filters>
</s:Rect>
Your code is obviously just going to blur that black rectangle and nothing else. The issue here is that you want to blur the entire application, except the modal window.
I can think of two solutions:
solution 1
Put your entire application in a separate class and apply the filter to that:
<s:Application>
<s:States>
<s:State name="normal" />
<s:State name="modal" />
</s:States>
<view:Main>
<view:filters.modal>
<s:BlurFilter>
</view:filters.modal>
</view:Main>
<s:Group includeIn="modal">
<view:ModalWindow />
</s:Group>
</s:Application>
(this is not a working code sample: its purpose is just to convey the idea)
Solution 2
Take a screenshot of your app (create a BitMap) before the window pops up. Place that image over your app and apply the blur filter to that image. Then place the modal window. You couldn't click on anything because of the image overlaying everything, but that's the behavior you want from a modal window.
Can transitions be added to a source code that uses includeIn and excludeFrom to show/hide elements? It seems that elements are hidden immediately not allowing enough time for the transition to be played.
In this documentation article, a method with visible and includeInLayout properties is used but that would mean I would need to rewrite my MXML code which I'd rather avoid.
Yes, Flex 4 transitions work well with states.
I think you need to look closer at the AddAction and RemoveAction tags.
There is a nice introduction video made by Chet Haase, called "Flex 4 States And Transitions".
Try google it
Yes, that is precisely a use case for transitions (hiding/showing elements nicely with states).
Take the following example:
<s:Transition fromState="stateA" toState="stateB" autoReverse="true">
<s:Sequence>
<s:Fade targets="{[componentA]}"/>
<s:Resize targets="{[componentB]}"/>
</s:Sequence>
</s:Transition>
<s:Transition fromState="stateB" toState="stateA" autoReverse="true">
<s:Sequence>
<s:Resize targets="{[componentB]}"/>
<s:AddAction target="{componentA}"/>
<s:Fade targets="{[componentB]}"/>
</s:Sequence>
</s:Transition>
The example above, componentA is only shown in stateB while componentB is resized to accommodate it. When transitioning from stateA to stateB (i.e. componentA is going away), componentA is faded out first and then the outer container is resized. When transitioning from stateB to stateA (i.e. adding componentA within componentB), componentB is first resized, then componentA is added with a fade-in effect (note the need to specify the exact point within the sequence when componentA is actually added).
By default TitleWindows seem to have no padding. I tried the properties "left", "right" etc and it doesn't work. Actually I'd like to have a default for my whole app, so I tried creating a skin but no matter where in the skin I add 'left="50"' it just doesn't create padding on the left. You'd think that you should add it to the element with id="contentGroup", as described on this Adobe Skinning help page, but that does not work.
Surely this is something almost everyone wants to do?
The contentGroup in the default TitleWindowSkin is inside a VerticalLayout which does not respect top/left/right/bottom constraints.
You could do this by duplicating the default TitleWindowSkin and wrapping the contentGroup with a Group with width/height of 100%:
...
<s:Group width="100%" height="100%">
<!--- #copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup" top="10" left="10" right="10" bottom="10" minWidth="0" minHeight="0" />
</s:Group>
...
Since the TitleWindow extends the Panel component, it doesn't support the padding properties a HGroup or VGroup based component would. As far as I know, there's no way to skin a TitleWindow so that the padding properties are automatically set.
All I do is set the x and y coordinates of my components within the TitleWindow so that they are laid out where I want them.
In my Flex3 app I have some floating windows which contain variable amounts of text. The windows are meant to be user-resizable. Currently, while I can resize the windows OK, I can't get the text in a TextArea in the window to re-flow when the window is resized. I've come across blog postings that there's a size bug in TextArea that means that setting the text content does not re-size the TextArea properly, together with suggested workarounds. In my case, the content stays the same but the geometry of the container changes. What seems to be happening is that the TextArea adopts a fixed size when it is first rendered, and no amount of resizing the container changes that. Can anyone suggest a means of creating a fluid text area in Flex?
Ian
By binding the textArea's width to its container's with, you can manage to keep the margins and borders and don't have to deal with percentages.
Also, your textArea will be resized each time its parent changes in size.
i'm thinking of something like this:
<fx:Script>
<![CDATA[
import spark.layouts.supportClasses.LayoutBase;
protected function onButtonClicked(event:MouseEvent):void
{
currentState = (event.target.selected ? 'largeState' : 'smallState');
}
]]>
</fx:Script>
<s:TitleWindow id="window" width="300" height="200">
<s:TextArea width="{window.width - 10}" height="{window.height - 60}"
text="{IMyConsts.LOREMIPSUM}" borderVisible="false" />
<s:ToggleButton id="btnEffect" bottom="5" click="onButtonClicked(event)"
label="{btnEffect.selected ? 'Go smaller' : 'Go larger'}" />
</s:TitleWindow>
<s:states>
<s:State name="smallState" />
<s:State name="largeState" />
</s:states>
<s:transitions>
<s:Transition fromState="smallState" toState="*">
<s:Resize target="{window}" widthTo="400" heightTo="300" />
</s:Transition>
<s:Transition fromState="largeState" toState="*">
<s:Resize target="{window}" widthTo="300" heightTo="250" />
</s:Transition>
</s:transitions>
I found a great example of fluid windows please do visit it. They provide source code also so may be you would get better idea.
http://examples.adobe.com/flex3/devnet/dashboard/main.html
You could try Text Layout Framework from Adobe:
http://labs.adobe.com/technologies/textlayout/
I can take a whack at this... but don't laugh..
I am not sure if you need to use a particular container but in any event, set the width and height to 100% and use Grid > GridRow and GridItem to size and resize Text Control you can specify the width of the table or just use it just like an HTML table in Flex to manipulate the size of controls and containers....
hope that helps...