Resize layout after a loaded image gets resized - apache-flex

So I'm loading a really big pic in this mx:Image manteinAspectRatio enabled with a height constraint and as usual it doesn't work (Flex is definitely not for me):
<?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">
<s:Rect top="0" right="0" bottom="0" left="0">
<s:fill>
<mx:SolidColor color="#000000"/>
</s:fill>
</s:Rect>
<s:VGroup id="a" top="0" right="0" bottom="0" left="0" horizontalAlign="center" verticalAlign="middle">
<s:Group id="b">
<s:Rect id="c" top="0" right="0" bottom="0" left="0" radiusX="10" radiusY="10">
<s:fill>
<mx:SolidColor color="#cccccc"/>
</s:fill>
</s:Rect>
<s:VGroup id="d" paddingTop="10" paddingRight="10" paddingBottom="10" paddingLeft="10">
<mx:Image id="e" source="big.jpg" maxHeight="300" maintainAspectRatio="true" />
</s:VGroup>
</s:Group>
</s:VGroup>
</s:Application>
The big.jpg has more width than height so when it's resized the wrapping containers get the correct new height but they still have the old width.
I've tried to call validateNow() on every element, invalidate, callLater(), resize event, compete event... I'm a noob getting tired of AS 3.0
UPDATE:
Reading J_A_X answer I ended up with this:
<?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">
<fx:Script>
<![CDATA[
import flash.events.Event;
import mx.controls.Image;
private function fix(event:Event):void {
var img:Image = event.target as Image;
var h:uint = 300;
img.width *= h / img.height;
img.height = h;
img.removeEventListener("updateComplete", fix);
}
]]>
</fx:Script>
<s:Rect top="0" right="0" bottom="0" left="0">
<s:fill>
<mx:SolidColor color="#000000"/>
</s:fill>
</s:Rect>
<s:VGroup top="0" right="0" bottom="0" left="0" horizontalAlign="center" verticalAlign="middle">
<s:Group>
<s:Rect top="0" right="0" bottom="0" left="0" radiusX="10" radiusY="10">
<s:fill>
<mx:SolidColor color="#cccccc"/>
</s:fill>
</s:Rect>
<s:VGroup paddingTop="10" paddingRight="10" paddingBottom="10" paddingLeft="10">
<mx:Image source="big.jpg" maintainAspectRatio="false" updateComplete="fix(event)" />
</s:VGroup>
</s:Group>
</s:VGroup>
</s:Application>
I hope that helps another one dealing with Flex.

After looking at Image, it seems that it needs explicit height/width or else it won't scale down properly. It's a bit stupid not to scale to the maxHeight, but you could always use Flex 4.5 Image class instead or just create your own to handle max height/width.

Related

Web app in Flex 4

I have a small issue related to my web App developed in Flex 4.6.
I have an app which has 800 x 600 px and in some screens, not all the content is shown and no scroll appear in the browser.
How can I setup the app to be able to show the y-scroll in the browser?
Regards.
I had similar problem - with a card game as Flex 4 web app 700 x 525 px - played mostly by older folks and they often have fonts/webpage zoomed (for example by using CTRL and + keys in browser) - which caused the UI be offset (like PopUpWindow not centered) etc.
My solution has been to use a custom app skin.
Here some excerpts of my code:
MyApp.mxml:
<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"
initialize="systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL"
skinClass="MySkin">
...
MySkin.mxml: (even works in full screen mode)
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Metadata>
<![CDATA[
[HostComponent("spark.components.Application")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
....
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalWithControlBar" />
<s:State name="disabledWithControlBar" />
</s:states>
<s:Group id="mainGroup" x="0" y="0" width="700" height="525">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify" />
</s:layout>
<s:Group id="contentGroup" width="700" height="100%" minWidth="0" minHeight="0" />
<s:Group id="topGroup" minWidth="0" minHeight="0"
includeIn="normalWithControlBar, disabledWithControlBar" >
<s:Rect left="1" right="1" top="1" bottom="1" >
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="#66BBEE" />
<s:GradientEntry color="#3399CC" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Rect left="2" right="2" bottom="0" height="1" alpha="0.5">
<s:fill>
<s:SolidColor color="#333333" />
</s:fill>
</s:Rect>
<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="6" paddingRight="6" paddingTop="6" paddingBottom="6" gap="10" />
</s:layout>
</s:Group>
</s:Group>
</s:Group>
</s:Skin>
You need to add an Scroller to the components that you want to scroll and make sure you have set verticalScrollPolicy to "auto".
http://help.adobe.com/en_US/flex/using/WSb04c7610c3432839-13869d09121418556f1-7ffc.html

I need an itemRenderer for a ColumnSeries

Can some one give me the code for an itemRenderer for a ColumnSeries currently my best effort is as follows...
Defining the itemRenderer
columnSeries.setStyle("itemRenderer","comp.EmptyBox");
comp.EmptyBox
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true">
<s:Rect id="lblData" top="0" left="0" right="0" bottom="0">
<s:fill>
<s:SolidColor color="0xFFFFCC" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color="0x660099" weight="2" />
</s:stroke>
</s:Rect>
And currently my error is a type cohersion due to a badly constructed itemRenderer.
Try this:
columnSeries.setStyle("itemRenderer", new ClassFactory(comp.EmptyBox));

Problem with depth between two components in flex

I know what i am about to ask may be all too simple but i have been unable to find a solution to my problem.
I am developing an AIR app. I have a custom skin for windowedapplication of spark components. In that skin i have added a bitmapimage to set a background for the windowedapplication.
Also, i have a custom component called 'header', what it does is draw a few table headers.
Now, if i add header as <ui:header width="100%" and height="40"\>in the skins right after the bitmapimage then the header shows up as it is supposed to. But, if i put the header within the windowedapplication then it displays underneath the bitmapimage, which cant be seen unless the bitmapimage is removed.
I tried to fix this problem by changing the depth of the bitmapimage and the header component accordingly in order to make them appear in the right order but, this is not working for me.
If you have an idea, please help me out.
Thanks
Here are bits of the code
`
<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" skinClass="ui.uiskin"
height = "728" width="910"
xmlns:ui="ui.*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<ui:header x="0" y="{.0258*height}" depth="0"
height="{0.0774*height}" width="100%"/>
</s:WindowedApplication>
`
uiskin is
`
<s:Skin 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:ui="com.youspin.components.ui.*"
depth="-10">
<!-- host component -->
<fx:Metadata>
[HostComponent("spark.components.WindowedApplication")]
</fx:Metadata>
<fx:Script>
<![CDATA[
]]>
</fx:Script>
<!-- states -->
<s:states>
<s:State name="disabledAndInactive" />
<s:State name="normalAndInactive" />
<s:State name="disabled" />
<s:State name="normal" />
</s:states>
<s:BitmapImage source="#Embed('../../images/ui/background.png')" depth="-10"/>
<s:TitleBar left="0" right="0" top="1"
height="{0.0258*height}"
skinClass="titleSkin"/>
<ui:header x="0" y="{.0258*height}" depth="0"
height="{0.0774*height}" width="100%"/>
</s:Skin>
`
and header is
`
<?xml version="1.0" encoding="utf-8"?>
<s:Group 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="100%" height="100%"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Rect width="100%" height="{.04*height}">
<s:fill>
<s:SolidColor color="black"/>
</s:fill>
</s:Rect>
<s:Rect width="100%" height="100%"
left="0" top="2"
alpha=".2"
>
<s:fill>
<s:SolidColor color="black"/>
</s:fill>
</s:Rect>
<s:Group 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="100%" height="100%"
top="2" left="0"
id="headingsGroup"
>
<mx:Image source="#Embed('../../images/header/logo.png')"
width="{0.2*headingsGroup.width}"
left="{0.015*headingsGroup.width}" top="{0.04*headingsGroup.height}"/>
<!-- left line drop -->
<s:Rect left="{.25*headingsGroup.width}" top="0"
width="2" height="{.23*headingsGroup.height}">
<s:fill>
<s:SolidColor color="black"/>
</s:fill>
</s:Rect>
<!-- middle line drop -->
<s:Rect left="{.50*headingsGroup.width}" top="0"
width="2" height="{.23*headingsGroup.height}">
<s:fill>
<s:SolidColor color="black"/>
</s:fill>
</s:Rect>
<!-- side line drop -->
<s:Rect left="{.75*headingsGroup.width}" top="0"
width="2" height="{.23*headingsGroup.height}">
<s:fill>
<s:SolidColor color="black"/>
</s:fill>
</s:Rect>
<s:Label text="artist"
top="{0.06*headingsGroup.height}"
horizontalCenter="{-0.125*headingsGroup.width}"
styleName="balonez"/>
<s:Label text="song"
top="{0.06*headingsGroup.height}"
horizontalCenter="{0.125*headingsGroup.width}"
styleName="balonez"/>
<s:Label text="album"
top="{0.06*headingsGroup.height}"
horizontalCenter="{0.375*headingsGroup.width}"
styleName="balonez"/>
<!-- bottom line -->
<s:Rect left="{.25*headingsGroup.width}" top="{.22*headingsGroup.height}"
width="{.75*headingsGroup.width}" height="2">
<s:fill>
<s:SolidColor color="black"/>
</s:fill>
</s:Rect>
</s:Group>
<fx:Style>
#font-face {
src:url("../../fonts/balonez fantasia.ttf");
fontFamily: myFontFamily;
advancedAntiAliasing:true;
}
.balonez{
font-family:myFontFamily;
font-size:25;
}
</fx:Style>
</s:Group>
`
Some parts of the code are not shown here, but i guess the above should give you an idea of what i am trying to do.
What i was trying to do is that my windowedapplication has a custom skin i.e, uiskin. And also there is a separate component called 'header'. Within uiskin.mxml i have added a bitmapimage to use it as the windowedapplication's background. And within the windowedapplication i have added the header. Doing this causes the header to appear behind the image.
For now, what i have done is added the header inside the uiskin after the bitmapimage. Now, this makes the header appear above the bitmapimage. But, i actually want to place the header within the windowedapplication and not within the custom skin. Is there a way to do this.
Can you show us some code ? Because when you add components to the display list using MXML, the order you write them in is important. For instance, the following code will add the label, and then the image. If the two components' coordinates overlap, the image will cover the label. The mxml part of a flex component is ran over from the top to the bottom. See ?
<s:Label
id="labelContent"
width="100%" height="100%"/>
<s:Image id="imageContent" horizontalCenter="0" verticalCenter="0"/>
I found the answer to my question. All that was needed was a group tag to make the content of the windowed application display above the image set in the windowedapplication skin
<s:Group id="contentGroup" left="0" top="0" right="0" bottom="0" />
Take care to keep the id as well, it didn't work for me when i removed the id. Also, here is the link if anyone needs it.
I Understand some of the things posted by you. If u place the Image and then header, the header hides the image. my solution is this
have a Hgroup with 100% 100% height width
<s:HGroup width="100%" height="100%">
<ui:header width="100%" height="40"\>
<s:Image width="100%" height="60%"\>
</s:HGroup>

Is this a PrintDataGrid bug or restriction or my lack of understanding?

I'm trying to implement PrintDataGrid in my application and I'm encountering a peculiar problem. The printout is skipping last several rows in the printout of each page.
I have narrowed down to what's causing this issue. My application-level custom skin provides Flex scrolling capability to the entire application. Presence of this scrollbar in the custom skin is causing PrintDataGrid to skip last rows. In fact, number of rows skipped depends on the height of the browser. If you reduce the browser height, you skip more rows!
Is this a bug PrintDataGrid or a restriction (cannot have PrintDataGrid within Scroller) or I'm missing something?
Please help as I'm struggling with this for several days!
Here is simple code to reproduce the issue:
Main Application:
Application custom skin class:ApplicationSkinCustom.mxml
============================================
#see spark.components.Application
#langversion 3.0
#playerversion Flash 10
#playerversion AIR 1.5
#productversion Flex 4
-->
<fx:Metadata>
<![CDATA[
/**
* A strongly typed property that references the component to which this skin is applied.
*/
[HostComponent("spark.components.Application")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
/**
* #private
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number) : void
{
bgRectFill.color = getStyle('backgroundColor');
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalWithControlBar" />
<s:State name="disabledWithControlBar" />
</s:states>
<!-- fill -->
<!---
A rectangle with a solid color fill that forms the background of the application.
The color of the fill is set to the Application's backgroundColor property.
-->
<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0" >
<s:fill>
<s:SolidColor id="bgRectFill" color="#FFFFFF"/>
</s:fill>
</s:Rect>
<s:Scroller left="1" top="1" right="1" bottom="1" id="scroller">
<s:Group left="0" right="0" top="0" bottom="0">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify" />
</s:layout>
<!---
#private
Application Control Bar
-->
<s:Group
id="topGroup"
minWidth="0"
minHeight="0"
includeIn="normalWithControlBar, disabledWithControlBar"
>
<!-- layer 0: control bar highlight -->
<s:Rect left="0" right="0" top="0" bottom="1" >
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xFFFFFF" />
<s:GradientEntry color="0xD8D8D8" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 1: control bar fill -->
<s:Rect left="1" right="1" top="1" bottom="2" >
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xEDEDED" />
<s:GradientEntry color="0xCDCDCD" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- layer 2: control bar divider line -->
<s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
<s:fill>
<s:SolidColor color="0x000000" />
</s:fill>
</s:Rect>
<!-- layer 3: control bar -->
<!--- #copy spark.components.Application#controlBarGroup -->
<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
</s:layout>
</s:Group>
</s:Group>
<!--- #copy spark.components.SkinnableContainer#contentGroup -->
<!--<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />-->
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />
</s:Group>
</s:Scroller>
This is apparently a known bug with the Flex printing library and Scroller controls. You can read about my discussions on this here:
http://forums.adobe.com/message/3626759
The first thing I would try is getting rid of the custom skin, processing your print job, and then re-applying the custom skin. This might do the trick. If that does work, but doesn't look the way you want, then you can work on creating a variant of your custom application skin that doesn't have a scroller. You would apply that before starting the print job, and then restore the original custom application skin after the print job completes.
The user may briefly see the "alternate" version of your app when they click the print button, but it should only be for a split second at most.
-Josh

Flex - How to change open DropDownList height

Using FB4, I want to change the height of an open spark DropDownList. By default, it shows up to 6 items before scrolling. My dropdownlist contains 7 items, so I want to change the height of the open dropdown list to fit all 7 items without scrolling. As a workaround, I've changed the font size of the items so that they are smaller and all 7 fit, but the smaller font doesn't look good. Is there a way to change this height? I'm rather new to Flash, so if it's a complicated solution, please be detailed :-).
Isn't it easier if you use the property requestedRowCount of the verticalLayout?
<s:DropDownList dataProvider="{myDataProvider}">
<s:layout>
<s:VerticalLayout requestedRowCount="10"/>
</s:layout>
</s:DropDownList>
The issue is, in Flex 4, the DropDownListSkin has defined maxHeight="134" for the default skin you are probably using. That forces the scrollbar to appear if the objects stretch beyond that height. All you need to do is copy/paste their DropDownListSkin code into a custom skin, and apply that to your DropDownList via CSS:
VariableHeightDropDownListSkin
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
alpha.disabled=".5">
<!-- host component -->
<fx:Metadata>
<![CDATA[
/**
* #copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.DropDownList")]
]]>
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="open" />
<s:State name="disabled" />
</s:states>
<s:PopUpAnchor id="popUp" displayPopUp.normal="false" displayPopUp.open="true" includeIn="open"
left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto"
popUpPosition="below" popUpWidthMatchesAnchorWidth="true">
<!-- removed maxHeight! -->
<s:Group id="dropDown" minHeight="22">
<!-- border/fill -->
<s:Rect left="0" right="0" top="0" bottom="0">
<s:stroke>
<s:SolidColorStroke color="0x5380D0" />
</s:stroke>
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Scroller left="0" top="0" right="0" bottom="0" focusEnabled="false" minViewportInset="1">
<s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="contentJustify"/>
</s:layout>
</s:DataGroup>
</s:Scroller>
<s:filters>
<s:DropShadowFilter blurX="20" blurY="20" distance="7" angle="90" alpha="0.45" color="0x6087CC" />
</s:filters>
</s:Group>
</s:PopUpAnchor>
<s:Button id="openButton" left="0" right="0" top="0" bottom="0" focusEnabled="false"
skinClass="spark.skins.spark.DropDownListButtonSkin" />
<s:Label id="labelDisplay" verticalAlign="middle" lineBreak="explicit"
mouseEnabled="false" mouseChildren="false"
left="7" right="30" top="2" bottom="2" width="75" verticalCenter="1" />
</s:Skin>
Sample Application
<?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">
<fx:Style>
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace s "library://ns.adobe.com/flex/spark";
s|DropDownList
{
skinClass: ClassReference("VariableHeightDropDownListSkin");
}
</fx:Style>
<s:DropDownList labelField="name" horizontalCenter="0" verticalCenter="0">
<s:layout>
<s:VerticalLayout requestedRowCount="7"/>
</s:layout>
<s:dataProvider>
<mx:ArrayCollection>
<fx:Object name="one"/>
<fx:Object name="two"/>
<fx:Object name="three"/>
<fx:Object name="four"/>
<fx:Object name="five"/>
<fx:Object name="six"/>
<fx:Object name="seven"/>
</mx:ArrayCollection>
</s:dataProvider>
</s:DropDownList>
</s:Application>
Let me know if that helps,
Lance
viatropos answer will work, however you should try and avoid overriding an entire skin as much as possible.
In this case, you will notice that in viatropos's VariableHeightDropDownListSkin code that the Group where he removed the maxHeight attribute, there is also an "id" specified.
Now look at the documentation for DropDownList and you will notice in the SkinParts section that there is a "dropDown" skin part. This is actually a property of DropDownList.
So instead of overriding the skin, you can simply use actionscript (I use UIComponent.DEFAULT_MAX_HEIGHT here, but you can use whichever you wish):
(MyDropDownList.dropDown as UIComponent).maxHeight = UIComponent.DEFAULT_MAX_HEIGHT;
Unfortunately, this is a lot more complicated in Flex 4 than it was in Flex 3:
You should be able to define a layout for the DropDownList with a higher requestedRowCount (details here), but for > 6 rows you need to do more work (Flex issue SDK-25364).
in FB3 it's rowCount cause the dropdown is a descendant of a list control. FB4 is probably similar.
myDropdown.rowCount = 7;
I usually use something more like
myDropdown.rowCount = myDataProvider.lenght();

Resources