AS3 Scroller, odd interaction with constraint layout? - actionscript-3

I have a form that uses constraint layouts (left/right/top/bottom) to position the main form inside a background. When I use the form in a popup TitleWindow, it lays out and sizes the components (and sets the TitleWindow size) as I would expect.
When trying to use the same set of components inside a Scroller, the layout is incorrect - the background gets resized to fit the Scroller, while the interior form is the correct size (but the right/bottom constraints aren't applied).
This simplified program demonstrates the issue. Without the Scroller, the form lays out correctly, and if the WindowedApplication is resized to show the entire form it looks correct.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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="400" height="400">
<fx:Declarations>
<s:SolidColor id="bgFill" color="#8080c0"/>
<s:SolidColor id="whiteFill" color="#ffffff"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
protected function checkSizes():void
{
trace('Base is ' + base.width + 'x' + base.height);
trace('Background is ' + bg.width + 'x' + bg.height);
trace('Border is ' + border.width + 'x' + border.height);
trace('Form is ' + form.width + 'x' + form.height);
}
]]>
</fx:Script>
<s:Group id="base">
<s:Rect id="bg"
left="0" right="0" top="0" bottom="0"
fill="{bgFill}"/>
<s:Rect id="border"
left="10" right="10" top="10" bottom="10"
fill="{whiteFill}"/>
<s:VGroup id="form" left="20" right="20" top="20" bottom="20">
<s:Button width="600" height="600"
label="Push Me!"
click="checkSizes()"/>
</s:VGroup>
</s:Group>
</s:WindowedApplication>
Clicking the button shows the component sizes as I'd expect:
Base is 640x640
Background is 640x640
Border is 620x620
Form is 600x600
If I add a scroller to fit the parent window, base, bg and border all fit inside the scroller, rather than being sized to fit as borders around form:
<s:Scroller width="100%" height="100%">
<s:Group id="base">
...
Base is 385x361
Background is 385x361
Border is 365x341
Form is 600x600
Oddly enough, if I put an extra group around base, then everyone lays out correctly...
<s:Scroller width="100%" height="100%">
<s:Group id="dummy">
<s:Group id="base">
...
Before I start digging through the Scroller and ScrollerSkin source, anyone know if I'm off my rocker and doing something worng in the first scroller example? I'd rather not create extra layers of components that I don't need.

The scroller restricts its first (and only) child to stay within his bounds, it will move the viewport of that child when you scroll.
Because your main application restricts the size of the scroller to 400x400, the base will never exceed 400x400 aswell.
If you add the dummy, base is free to expand as much as it wants but dummy will be restricted to expand.
I hope this explains it a bit. If not ask me more =)

Related

Flex 4 <s:Group> Wrap <s:Label>

I have the following example of a <s:Group> component within Flex 4:
<s:Group left="10" top="10" right="10">
<s:layout>
<s:HorizontalLayout gap="20"/>
</s:layout>
<s:Image id="image" source="{data.imageURL}"/>
<s:Label right="0" styleName="description" text="{data.description}"/>
</s:Group>
Is there a way that I can wrap the <s:Label> component onto a new line if it becomes too long for both the width of the image and label within the group?
Thank you for your time.
To make the Label word wrap the text, it needs to have a width of some kind, so it knows where to start wrapping.
All of these labels have a width specified one way or another, and should word wrap if nec:
<s:Label id="fixedWidth" width="100"/>
<s:Label id="percentWidth" width="25%"/>
<s:Label id="constraintBasedWidth" left="0" right="0"/>
<s:Label id="maxWidth" maxWidth="100"/>
Perhaps you can try using maxWidth on the label. This should put it next to the image and let it wrap longer text.
There is also the maxDisplayedLines property, which you might find useful.
Sounds like you want TileLayout. That will arrange the components horizontally and wrap when it runs out of space.

Switch window size in flex

So me and a friend have made a tool using flex which we have released, we made the window 680x480 and people are saying its too small for them.
So what i want to do is include possibly a switch or something that switches the size from 640x480 to 800x600, so you have both options available to use.
I just wondered if this was possible? I have searched google all morning and cant find exactly what i need.
I am also pretty novice at this... my friend is the coder but he has no idea and no time to sort this out, so would be a great help if i could get some insight here please.
I failed to mention, it's not a scale, i have all the assets in the package for 800x600 aswell as the standard files so, i guess would be a state change, but i'm not sure if its possible to change state to a larger page.
Thanks.
Well, basically, you can occupy 100% width and 100% height by your SWF within the containing HTML page.
Then if you need a fixed size, you can organize your application within a Group container and size it accordingly.
Try this:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
width="100%"
height="100%"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:Group horizontalCenter="0" verticalCenter="0" width="{resolutionDropDownList.selectedItem.w}" height="{resolutionDropDownList.selectedItem.h}">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#FF0000"/>
</s:fill>
</s:Rect>
</s:Group>
<s:HGroup top="10" horizontalCenter="0" gap="5" verticalAlign="baseline">
<s:Label text="Size:"/>
<s:DropDownList id="resolutionDropDownList" labelField="label" selectedIndex="0">
<s:dataProvider>
<s:ArrayList>
<fx:Object w="640" h="480" label="640x480"/>
<fx:Object w="800" h="600" label="800x600"/>
</s:ArrayList>
</s:dataProvider>
</s:DropDownList>
</s:HGroup>
</s:Application>
Veeeeeery rough convertion from 640x480 to 800x600 resolution:
stage.scaleX = 800 / 640;
stage.scaleY = 600 / 480;

create custom chrome adobe air desktop application using flex4 sparks controls

I have googled around but the only resource for teaching me how to create an Adobe Air Desktop Application uses mx controls instead.
inside app-xml i have set transparent to true and systemChrome to none.
the following is my main mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:dragdrop="org.robotlegs.demos.draganddrop.*"
xmlns:view="org.robotlegs.demos.draganddrop.view.*"
mouseOver="layoutCanvas.visible = true;"
mouseOut="layoutCanvas.visible = false;"
>
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
s|Application {
background-alpha:"0.7";
padding: 0px;
}
</fx:Style>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<dragdrop:DragAndDropContext contextView="{this}"/>
</fx:Declarations>
<s:Image id="background" width="100%" height="100%"
source="#Embed('theme/assets/MaxBackground.png')"/>
<s:BorderContainer id="layoutCanvas" width="100%" height="100%" visible="false">
<s:Image id="applicationClose" right="5" top="2"
click="stage.nativeWindow.close()"
source="#Embed('theme/assets/buttons/CLOSE WINDOW icon.png')"/>
<s:Image id="applicationMaximize" right="25" top="2"
click="stage.nativeWindow.maximize()"
source="#Embed('theme/assets/buttons/EXPAND WINDOW icon.png')"/>
<s:Image id="applicationMinimize" right="45" top="2"
click="stage.nativeWindow.minimize()"
source="#Embed('theme/assets/buttons/COLLAPSED WINDOW icon.png')"/>
</s:BorderContainer>
</s:WindowedApplication>
I have two issues.
1) the initial application window size. How can i set this to 100% full screen?
2) there is a strange grey horizontal footer at the bottom. How do i get rid of it? See here
I do not wish to use mx controls. I want to use sparks controls as much as possible.
Thank you.
1) the initial application window size. How can i set this to 100% full screen?
To do this you can add a CREATION_COMPLETE handler to your application and within that handler add a line similar to:
this.maximize() where this is you WindowedApplication.
2) there is a strange grey horizontal footer at the bottom
From the sounds of it, this is the status bar. Try setting the showStatusBar property on you WindowedApplication root tag to false :
showStatusBar="false"
Hope this helps.

Browser scrollbar issue when embedded with swf

I am developing a flex application which is embedded in a html file. The issue is I am not able to get the browser scroll bars, once the browser window resizes. I have tried setting overflow:scroll in the css code for html, but didn't work.
Consider an example like:
<?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" minWidth="600" minHeight="400" width="100%" height="100%">
<s:BorderContainer left="30" right="30" height="120" width="100%" backgroundColor="#FFFFFF" borderVisible="true">
<s:Label x="10" y="10" fontSize="12" fontFamily="Arial" fontStyle="normal" text="PCA title"/>
</s:BorderContainer>
<s:BorderContainer left="30" right="30" top="150" height="100%" bottom="30" width="100%" backgroundColor="#000000" borderVisible="true">
</s:BorderContainer>
</s:Application>
Here if i set the absolute values for height and weight as height="768" and weight="1366", i do get the scrollbars. But i am developing the application using relative coordinates so that it works across all machines irrespective of their screen sizes. So, i cannot specify absolute value for height and weight.
Can someone help me with this as to how to get the scrollbars working without disturbing my relative coordinate system.
I'm not certain that I understand your question correctly, but I think you need SWFFit.
This is a JavaScript tool that can limit the minimum and maximum sizes of the container of your Flash object, and will force the browser to supply scrollbars when required.

Horizontal Layout: mx vs spark - Resizing children

In Flex 3, I used to be able to take 2 panels, lay them out with 100% width settings in an HBox. If I changed the width property of the first panel to something smaller, let's say 20%, the second would automatically update and fill in the space that used to be taken up by the first as the first resized down.
I notice in spark, this doesn't happen. I have an app with a HorizontalLayout, and a resizable panel control on the left and a panel on the right that has width="100%." When I resize my left-side panel down, the right side panel doesn't do anything. So I end up with a clean resizable panel, a bunch of wasted space, and my right-side panel just sitting there.
What I expect is that since the right-side panel has a width="100%" then if the panel to its left is resized, then there would be a corresponding growth in the right-side panel to fill in.
I've tried to manually trigger validation on properties and size without effect. I'm wondering what changed in the HorizontalLayout that no longer allows this technique to work. I would also like to know what solutions are available?
Here's some chomp chomp:
<mx:Application>
<mx:Script>
<![CDATA[
protected function resizeClick(event:MouseEvent):void
{
pnl1.percentWidth = 10; // When this would execute, pnl2 would automatically
// fill in the space previously held by pnl1.
}
]]>
</mx:Script>
<mx:HBox width="100%" height="100%">
<mx:Panel id="pnl1" width="40%" height="100%"> // Uses 40%
<mx:Button id="resizeButton" click="resizeClick(event)"/>
</mx:Panel>
<mx:Panel id="pnl2" width="100%" height="100%"/> // Fills in the rest of the available space
</mx:HBox>
</mx:Application>
Flex 4.5 doesn't automatically update the size of pnl2 when the size of pnl1 changes. I would think that since a HorizontalLayout is being used, that both children would update when the width of one of them was changed. But that just doesn't seem to be the case. I know I can create two states to accomplish this, but I was thinking that I shouldn't have to for something so trivial.
This sample works fine and illustrates correct changes of sizes:
<?xml version="1.0" encoding="utf-8"?>
<s:Application minHeight="600" minWidth="955" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:VGroup height="100%" width="100%">
<s:HSlider change="firstPanel.percentWidth = event.currentTarget.value" maximum="100" minimum="0"
value="{firstPanel.percentWidth}" />
<s:HGroup height="100%" width="100%">
<s:Panel height="100%" id="firstPanel" minWidth="0" width="40%" />
<s:Panel height="100%" width="100%" />
</s:HGroup>
</s:VGroup>
</s:Application>
So this is how I eventually solved this problem. I should have been a little more specific in my post to explain that Panel 1 is actually a "collapsible" panel that modifies its own size whenever its header button is clicked. The example above does work, but since there is no numeric control on the view to "tell" the panel.percentWidth property how much to change, I set my collapsible panel up to dispatch custom events that are handled by the wrapper. The custom events basically indicate what is happening to the collapsible panel. From there, I can handle the events separately and then control the size of Panel 2.
The solution is actually rather simple and I was hoping for something a little more "behind the scenes" but this worked fine.
<s:Application initialize="initApp(event)">
<fx:Script>
<![CDATA[
protected function initApp(event:FlexEvent):void
{
this.addEventListener("PanelCollapse", panelHandler);
this.addEventListener("PanelNormal", panelHandler);
}
protected function panelHandler(event:Event):void
{
switch(event.type)
{
case "PanelCollapse":
pnl2.percentWidth = 100;
break;
case "PanelNormal":
pnl2.percentWidth = 60;
break;
}
}
]]>
</fx:Script>
<comp:CollapsiblePanel id="pnl1" width="40%" height="100%">
</mx:Panel>
<s:Panel id="pnl2" width="100%" height="100%"/> // Fills in the rest of the available space
</s:Application>