flex positioning a button within a panel - apache-flex

All I'm trying to do is place a button inside of a panel, rotate that button (so it is vertical) and place it on the edge of the panel. I can;t seem to do this correctly. Here is my code:
<mx:Panel id="weekList" width="260" height="100%" x="-500" title="Weeks" >
<mx:List id="weekButtonList" width="260" borderVisible="false" contentBackgroundAlpha="0" dataProvider="{_data.mappoints.week.#number}" itemClick="onWeekClick(event);" >
<mx:itemRenderer>
<mx:Component>
<mx:Button buttonMode="true" right="20" width="260" height="50" label="Week {data}" />
</mx:Component>
</mx:itemRenderer>
</mx:List>
<mx:HBox id="closeButtonHolder" rotation="90" width="100" >
<mx:Button label="OPEN" click="weekListToggle()" />
</mx:HBox>
</mx:Panel>
If you look at the part of the script you will see I am trying to rotate it and move it to the left. I am just trying to move it somewhere, and nothing is working. Also, the text seems to dissapear when I rotate it on a 90% axis. Anyone know what I can do for this?

Use mx:Canvas and set its width to 100%, like so:
<mx:Canvas width="100%">
<mx:Button buttonMode="true" right="20" width="260" height="50" label="Week {data}" />
</mx:Canvas>
InvertedSpear has answered the other part of your question, so I won't repeat that.

In order to rotate text you have to embed the font. I'll play around and see if I can get you a more complete answer for your other issue.
OK, here are some of your problems.
1) The x of your panel is -500 so it is WAY off the screen, maybe you need that for some reason but in my test it just pushed out of view.
2) rotation requires embedding fonts
3) when you rotate any UI component within another the default pivot is on the upper left hand corner, so when the button rotates, it actually rotates out of view. This is not easy to understand when you read it so here's a visual, consider the upper left hand corner of the container as 0,0 in XY coordinates:
normal hbox/button layout:
0,0_________________________________
| ________________________________ |
| | | | <-container outside
| | UI component | |
| |______________________________| |
|__________________________________|
rotated layout:
___________0,0__________________________
| | |
| UI | container |
| component| |
| | |
| |___________________________|
| |
| |
| |
| |
|__________|
See how the button has rotated outside of the visible area (in your case it is no longer on the panel) Solution would be to use a canvas or something that will allow you to pull the HBox away from the edge of the panel.

Related

How can I draw a joined border around two components?

Before I tackled this myself, I thought I pick the minds of the SO community.
Let's assume I have an Image that's used a button. By default, the image has no border around it. Clicking on this Image will cause another component be displayed beneath it or next to it. When the second component is displayed, I want to draw a joined border around the Image and the second component.
The second component would not be visible by default. It would only be visible after clicking on the Image by using the popupManager, PopUpAnchor, setting the visible property, etc.
Example before clicking:
+--------------------------------+
| |
| XXX <-- My Image |
| XXX |
| |
| |
| |
| |
| |
| |
| |
+--------------------------------+
Example after clicking:
+--------------------------------+
| +---+ |
| |XXX| <-- My Image |
| |XXX|_______________ |
| | | |
| | My Second | |
| | Component | |
| | | |
| | | |
| +-------------------+ |
| |
+--------------------------------+
How difficult would it be to create something like this?
If you are using flex4 / spark, then you should consider skinning (anyway, the borderSides style is available only in Halo).
here is a small sample to achieve the behavior shown at the images:
It uses a custom component with two states (collapsed and expanded).
The text is only attached in the expanded state, and so are the border skins.
For this you'll need two skin classes that will be applied to the image- and to the text component's parent.
The Application:
<?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:my="*">
<s:VGroup width="100%" height="100%" paddingLeft="20" paddingTop="20">
<my:ExpandableImage id="component" width="300" />
<s:Button label="{component.currentState}" click="component.changeState(event);" />
</s:VGroup>
</s:WindowedApplication>
ExpandableImage.mxml //the custom component with two states
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
verticalGap="0" width="100%"
currentState="collapsedState">
<fx:Script>
<![CDATA[
public function changeState(event:MouseEvent):void
{
if (currentState == 'collapsedState')
currentState = 'expandedState';
else
currentState = 'collapsedState';
}
]]>
</fx:Script>
<mx:VBox id="imgHolder" borderSkin="MyImageSkin"
width="50" height="50" includeIn="collapsedState, expandedState" cornerRadius="5"
backgroundAlpha="1" borderAlpha="0" backgroundColor="#FFFFFF" borderColor="#000000">
<mx:Image id="img" source="{IMyConstants.MYLOGO}"
width="48" height="48"
mouseEnabled="true" click="changeState(event)" />
</mx:VBox>
<mx:VBox id="txtHolder" borderSkin="MyDetailsSkin"
width="100%" height="100%" includeIn="expandedState" cornerRadius="5"
backgroundAlpha="1" borderAlpha=".5" backgroundColor="#FFFFFF" borderColor="#000000">
<mx:Text id="txt" text="{IMyConstants.LOREMIPSUM}"
width="100%" />
</mx:VBox>
<mx:states>
<s:State name="collapsedState" />
<s:State name="expandedState" />
</mx:states>
<mx:transitions>
<mx:Transition fromState="collapsedState" toState="expandedState">
<s:Parallel duration="500">
<mx:Resize target="{this}" />
<mx:SetStyleAction target="{imgHolder}"
name="borderAlpha" value=".5" />
</s:Parallel>
</mx:Transition>
<mx:Transition fromState="expandedState" toState="collapsedState">
<s:Parallel duration="500">
<mx:Resize target="{this}" />
<mx:SetStyleAction target="{imgHolder}"
name="borderAlpha" value="0" />
</s:Parallel>
</mx:Transition>
</mx:transitions>
</mx:VBox>
MyImageSkin.as //the skin to be applied on the image component's parent
public class MyImageSkin extends RectangularBorder
{
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
var cornerRadius:Number = getStyle("cornerRadius");
var borderColor:int = getStyle("borderColor");
var borderAlpha:Number = getStyle("borderAlpha");
var backgroundColor:int = getStyle("backgroundColor");
var backgroundAlpha:Number = getStyle("backgroundAlpha");
graphics.clear();
//border
drawRoundRect(0, 0, unscaledWidth, unscaledHeight,
{tl: cornerRadius, tr:cornerRadius, bl: 0, br: 0},
borderColor, borderAlpha);
//content
drawRoundRect(1, 1, unscaledWidth-2, unscaledHeight-1,
{tl: cornerRadius, tr:cornerRadius, bl: 0, br: 0},
backgroundColor, backgroundAlpha);
}
}
MyDetailsSkin.as //the skin to be applied on the text's parent
public class MyDetailsSkin extends RectangularBorder
{
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
var cornerRadius:Number = getStyle("cornerRadius");
var borderColor:int = getStyle("borderColor");
var borderAlpha:Number = getStyle("borderAlpha");
var backgroundColor:int = getStyle("backgroundColor");
var backgroundAlpha:Number = getStyle("backgroundAlpha");
graphics.clear();
//border
drawRoundRect(0, 0, unscaledWidth, unscaledHeight,
{tl: 0, tr:cornerRadius, bl: cornerRadius, br: cornerRadius},
borderColor, borderAlpha);
//content
drawRoundRect(1, 1, unscaledWidth-2, unscaledHeight-2,
{tl: 0, tr:cornerRadius, bl: cornerRadius, br: cornerRadius},
backgroundColor, backgroundAlpha);
//clear separator
drawRoundRect(1, 0, 49, 1, {tl: 0, tr:1, bl: 1, br: 1}, backgroundColor, 1);
}
}
i really hope this helps
Pretty sure you can do this with styles
Add a third container i marked with ****
turn the top and right borders off on my new container(***)
turn the bottom border off on your image container
turn the top border off on your second component
+--------------------------------+
| +---+**************** |
| |XXX| <-- My Image * |
| |XXX|_______________* |
| | | |
| | My Second | |
| | Component | |
| | | |
| | | |
| +-------------------+ |
| |
+--------------------------------+

Flex image component not canvas container when added to canvas

I am adding a flex image component to a mx:canvas component with a fairly large image. I have the horizontal and vertical scroll policies set to "on", but when I add the image to the canvas, it doesn't expand to show the whole image (the scrollbars aren't activated).
Anybody else have this issue.
The code is pretty straightforward:
<mx:Canvas id="myCanvas" minWidth="0" minHeight="0" horizontalScrollPolicy="on" verticalScrollPolicy="on">
</mx:Canvas>
and the script adding the image
var newImg:Image = new Image();
newImg.source = $value.sourceImg;
newImg.x = $value.positionX;
newImg.y = $value.positionY;
newImg.scaleX = $value.scaleX * _scaleRatio ;
newImg.scaleY = $value.scaleY * _scaleRatio;
newImg.rotation = $value.rotation;
myCanvas.addChild(newImg);
Ok, So I had to use clipCOntent = true. I had clipContent="false", I thought the meant that it would clip the image and anything outside the bounds could just be scrolled, buut it actually just clips it and doesn't offer a scroll.
It would be helpful if you posted your code, but without seeing it I would recommend setting minWidth="0" on the canvas. This is an old trick to force a re-measure of the canvas so it shows the scroll bars properly. Hope that helps.
Try using canvas.rawChildren.addChild(img) instead of canvas.addChild(img). That's worked for me before, otherwise you'll need to hook into the Flex component measuring system - but this is very seldomly necessary.
Cheers
Create a first canvas (viewCanvas) and place another canvas inside it (imageCanvas).
Set the scroll policies on the imageCanvas to 'off'. This should work, and the viewCanvas should have scrollbars. Note that no width/height are specified on the imageCanvas or image in code below
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Canvas id="viewCanvas" x="95" y="65" width="169" height="159">
<mx:Canvas id="imageCanvas" x="0" y="0" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Image x="0" y="0">
<mx:source>http://www.beach-holiday.cn/beach-holiday/pics/2009/09/florida-fort-lauderdale.jpg</mx:source>
</mx:Image>
</mx:Canvas>
</mx:Canvas>
</mx:Application>

Flex: Bottom-left align components?

As the title suggests, is there any way to bottom-left align components?
An <HBox .../> nested in a <Canvas .../> doesn't work because the elements in the HBox are top-aligned instead of bottom aligned.
For example, I'd like my components to be aligned like this:
+-------------+ <-- container
| components |
| | V |
| V +--+ |
| +-+ | | |
| +-+ +--+ |
+-------------+
You just need to set the verticalAlign and horizontalAlign styles on the hbox ie:
<mx:Canvas>
<mx:HBox verticalAlign="bottom" horizontalAlign="left" left="0" bottom="0"> </mx:HBox>
</mx:Canvas>
Extend the HBox and/or Box to change the positioning. I suspect you'll probably have to override the updateDisplayList method to change the way components are positioned. Probably instead of setting the y value as "0" you'll want to set it to unscaledHeight-component.width.

sequencing through several images

I'm using flex and have a few images that I need to sequence through. I may add some text under each image. What I'm trying to do is automatically sequence through these images such that a black fading effect appears briefly between each image and the next - sure you've seen that sort of thing before.
My questions are this:
should these images be considered as states of a component or what? I was going to go that way, but corrections are welcome
how to get that black fading effect between the images and the next. Any clues please
Update: found an example of it. This example has more elements, but the idea is the same, an images fades and another images loads.
http://www.lifeblue.com/flash/lb_banner.swf
You can try using a ViewStack and a Timer to iterate through its children. Just add a fade in/fade out effect on them and you'll get what you're looking for.
Something like that :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="black" creationComplete="creationCompleteHandler">
<mx:Script>
<![CDATA[
private var timer:Timer;
private function creationCompleteHandler():void
{
timer = new Timer( 2000 );
timer.addEventListener( TimerEvent.TIMER, timerHandler );
timer.start();
}
private function timerHandler( e:TimerEvent ):void
{
if( vs.selectedIndex == vs.getChildren().length - 1 )
vs.selectedIndex = 0;
else
vs.selectedIndex++;
}
]]>
</mx:Script>
<mx:Fade id="fadeIn" alphaFrom="0" alphaTo="1" duration="500" effectEnd="timer.start();"/>
<mx:Fade id="fadeOut" alphaFrom="1" alphaTo="0" duration="500" effectEnd="timer.stop();"/>
<mx:ViewStack id="vs">
<mx:Canvas showEffect="fadeIn" hideEffect="fadeOut">
<mx:Image source="picture1.jpg"/>
</mx:Canvas>
<mx:Canvas showEffect="fadeIn" hideEffect="fadeOut">
<mx:Image source="picture2.jpg"/>
</mx:Canvas>
<mx:Canvas showEffect="fadeIn" hideEffect="fadeOut">
<mx:Image source="picture3.jpg"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Application>
Note that this code isn't the most optimized one. The best would be to create a custom component with a black background and 2 Image components.
Set the alpha property of both of
them to 0
Load a picture in the first one, then
play your fade in effect
Begin to load the following picture
in the second Image component
Fade out the first one, fade in the
second, and load the following
picture in the first Image, etc.
This way you only got one Container (instead of one per picture plus the ViewStack) and 2 Images.
It will also be easier to clean them from memory if you need to.

Flex 3 Using an image as a border

I am working on an custom container and I need a border for this container. I have a 15x15 image that I am creating a 9-slice border skin with. The issue that I am having is that the border skin does not appear the way that I had hoped it would.
Here is a ss of the skin in place.
Ideally I should have a transparent box with a 5 pixel border around it.
Here is my current testing code:
CSS Code:
Box
{
borderSkin: Embed(source="15x15.png",
scaleGridLeft="5",
scaleGridTop="5",
scaleGridRight="10",
scaleGridBottom="10");
}
MXML Code:
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Style source="MainTest.css"/>
<mx:Box id="tw" width="400" height="400">
</mx:Box>
</mx:WindowedApplication>
Try this :
Box{
background-image: Embed("15x15.png",
scaleGridTop="5",
scaleGridBottom="10",
scaleGridLeft="5",
scaleGridRight="10");
background-size:"100%";
}

Resources