Flex Vgroup Absolute positioning of components - apache-flex

I have a Vgroup with some components aligned par with its layout properties(vertical). I need to add one more component at an absolute X,Y position, overriding the alignment. I tried includeinlayout=false, but the component turns invisible then. Is it possible in flex?

No, this is not possible. A VGroup will ignore properties such as X, and Y. IF the component is visible, then includeInLayout is also ignored.
You'll have to layout your extra component outside of the VGroup, or switch to a Group and layout everything absolutely.

It is not possible! But you always can get global coordinates of the needed DisplayObject and show some PopUps or other components near to this target.
MXML:
<s:VGroup x="50" y="50">
<s:Button width="250" height="250" id="b1"/>
<s:Button width="250" height="250" id="b2"/>
</s:VGroup>
<s:Button id="addon"/>
AS:
var rect:Rectangle = b2.getBounds(this);
addon.x = rect.x + rect.width - addon.width;
addon.y = rect.y;

Related

Flex depth property not working

Does the depth property apply only to Spark components? When I apply it to a non-spark container it doesn't change anything.
<mx:VBox height="100%" width="30" id="minimizeContainerLeft" clipContent="false">
</mx:VBox>
I used depth on a non Container and it worked. I used it with images. I set the depth of the element I wanted to 1 and the depth of the others to 0.
container.getElementAt(oldValue).depth = 0;
oldValue = val;
container.getElementAt(val).depth = 1;
This way I bring the one image to the front and the other to the back.

How to add an icon to an AdvancedDataGrid column header and keep word wrap feature for the text

As stated, I'm trying to obtain column headers consisting of an icon and wrappable text in a flex AdvancedDataGrid.
(EDIT: I forgot to mention an important part of the context: the columns are added dynamically, in actionscript. This apparently changes the behavior.)
I've tried using a custom mxml headerRenderer, like so:
<mx:headerRenderer>
<fx:Component>
<mx:HBox width="100%"
height="100%"
verticalAlign="middle">
<mx:Image source="<image_url>"
width="10%"
height="100%"/>
<mx:Text text="{data.headerText}"
width="90%"
height="100%"/>
</mx:HBox>
</fx:Component>
</mx:headerRenderer>
but for some reason, the text here is truncated instead of wrapped (it works outside of a renderer).
I've also tried creating a subclass of AdvancedDataGridHeaderRenderer and overriding createChildren to add the icon:
override protected function createChildren():void
{
var icon:Image = new Image();
icon.source = <image_url>;
icon.width = 16;
icon.height = 16;
addChild(icon);
super.createChildren();
}
but then, the icon and the text get superimposed.
I'm out of ideas on this. Anyone else?
It worked for me when I removed the height="100%" attribute from mx:Text in your headerRenderer.
UPDATE: it only works like this when I manually stretch the AdvancedDataGrid component. I'll look into how to make it work unconditionally.
When the height of the Text component was set to 100%, it was constrained to its parent HBox's height. Therefore when a word was wrapped and moved to the next line, it wasn't visible because the height of the Text component didn't allow for it to be visible.
If you remove this constraint, Text component's height will be determined dynamically based on its contents, as will headerRenderer's. Also add minHeight to your Text so that it is visible when it's loaded.
Here's the code (I also removed scrollbars because they were showing during resize):
<mx:headerRenderer>
<fx:Component>
<mx:HBox width="100%"
height="100%"
verticalAlign="middle"
horizontalScrollPolicy="off"
verticalScrollPolicy="off">
<mx:Image source="<image_url>"
width="10%"
height="100%"/>
<mx:Text text="{data.headerText}"
width="90%"
minHeight="20"/>
</mx:HBox>
</fx:Component>
</mx:headerRenderer>
In case anyone is interested in how to do this with dynamically created columns, a combination of Hunternif's code for the renderer and some added code on column creation worked for me:
The columns need to have fixed widths and need to be invalidated to inform the AdvancedDataGrid that it needs to rerender:
var cols:Array = [];
for each (...) {
var column:AdvancedDataGridColumn = new AdvancedDataGridColumn();
...
// Fix the width of created columns
column.width = 150;
cols.push(column);
}
grid.columns = cols;
// Invalidate columns so that sizes are recalculated
grid.mx_internal::columnsInvalid = true;
// Take changes into account
grid.validateNow();

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>

Setting the gap of layout

I usually set the layout like this
<s:Group>
<s:layout>
<s:VerticalLayout gap="10"/>
</s:layout>
</s:Group>
but not sure how to specify the gap if I want to use new VerticalLayout
The VerticalLayout constructor does not have any parameters, so you won't be able to do this in-line in MXML as part of the layout property. You'll have to set the gap property on the layout after creating it. Perhaps in a creationComplete handler, do something like this:
groupID.layout.gap = 10;
You can probably even do this in-line:
<s:Group layout="{new VerticalLayout()}" id="groupID" creationComplete="{groupID.layout.gap = 10}"></s:Group>

Absolute positioning in Flex?

I need to programmatically add a set of controls with some amount of pixels between them. I can't seem to find how to do this in the Flex docs. How can I do it?
Most Containers have some logic to place the items for you, e.g. vertically or horizontally. I.e. if you want to place them horizontally with 5 pixels of space you would use a HBox (VBox for vertical layout):
<mx:HBox horizontalGap="5">
<Component1/>
<Component2/>
<etc.../>
</mx:HBox>
Or script:
...
var box: HBox = new HBox();
box.horizontalGap = 5;
box.addChild(new Component1());
box.addChild(new Component2());
addChild(box);
But if you want to place them yourself using x,y coordinates (i.e. absolute positioning) you can use Canvas:
<mx:Canvas>
<Component1 x="100" y="100"/>
<Component2 x="100" y="200"/>
<etc.../>
</mx:Canvas>
script version:
var canvas: Canvas = new Canvas();
var component1: Component1 = new Component1();
component1.x = 100;
component1.y = 100;
canvas.addChild(component1);
var component2: Component2 = new Component2();
component2.x = 100;
component2.y = 100;
canvas.addChild(component2);
Inside a container with absolute positioning, e.g. Canvas, you can position elements with x and y (or right, left, top, bottom)
elem.x = 100;
elem.y = 200;
canvas.addChild(elem);
You can also use Spacer to add some space in between components.
<mx:HBox>
<Component1 />
<mx:Spacer width="10" />
<Component2 />
</mx:HBox>
If your window can be re-sized, absolute layout is not recommended - It may be a good idea to use width="100%" and height=100% and then use the minHeight/minWidth/maxWidth etc.
In your case, you could set the minimum width/height of the spacer (between 2 components) so that the page scales proportionately.

Resources