knowing the exact index clicked in a Flex tree event - apache-flex

Please, i have a tree component that dispatches an itemOpen event.
When the black triangle next to the yellow folder is clicked, that folder opens to expose its children.
Is there anyway to know the index of the open folder? there is a rowIndex property in the target property of the openItem event that stores the index but it is not accessible. Does anyone knows or have come across situations like this one?
Thanks

There is a function called itemRendererToIndex(itemRenderer:IListItemRenderer):int
ItemRenderer you can get from the dispatched event.
Adobe Documentation
Code smaple :
protected function tree1_itemOpenHandler(event:TreeEvent):void
{
var index:int = tree.itemRendererToIndex(event.itemRenderer);
trace(index);
}

You can always find the selectedItem using Tree(event.target).selectedItem. Thus, you can get the index of this item in your dataprovider. Hope it helps.

Related

Flex/AS3: Detecting whe the Image's source has changed

I have an image which its source depends on a bindable property of another object.
I'd like to know when this source changes, for example, by capturing the bind event or another related event of the Image control.
Thanks in advance.
There's a few ways to do this. One was is to use Bindsetter
private function creationComplete(event:FlexEvent):void{
BindingUtils.bindSetter(changeImage,hostObject,"image"); //assuming hostObject contains the property "image"
}
private function changeImage(imageSource:String){
//Set the image in here... do whatever else you wanted to do.
}

Flex4 Right Click Spark List using ContextMenu()

I would like to add custom right clicks to a number of spark list controls.
I have tried the following as an item renderer. (as per the flex 4 cook book).
Full Render code here http://pastebin.com/Kx8tJ1cY
When I right click on the Spark List I simply get the Adobe Default Context menu.
This is the same default behaviour I had before I added any code to this.
Could anyone tell me how to add right clicks to List Items in Flex 4.
Please and Thank you.
I found the problem/solution. You cant use context menus if there are Vboxes or Tab Navigators. Which is insane because it means I cant do relative layout properly or decent variable width design.
Quoted from: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
Christopher Huyler posted something similar (source code available here). From the article:
Start out by grabbing the Javascript code from Google's code repository.
Step 1 – Setup custom context menu code
Create a new Flex project in Flex Builder. Copy rightclick.js and swfobject.js into the html-template folder of your project. From here, I had to make several changes…
I modified the RightClick.init() function to accept an object and container value as input. This allows me to pass in the name of the application as the object instead of having it be called the same thing every time.
I included rightclick.js and swfobject.js in the header of index.template.html.
I added a new div to the body called “flashcontent”.
I added an onload handler to the body tag to initialize RightClick
I replaced AC_FL_RunContent(…) with new SWFObject(…) making sure to maintain all template variables.
After making these changes, I verified that no right-click context menu appears in my application.
Step 2 – Listen for the rightClick event
Next I added a few lines to the main mxml file of my application to listen for the ExternalInterface event that will be dispatched when I right-click my appliction.
private function handleCreationComplete():void
{
ExternalInterface.addCallback("rightClick", handleRightClick);
}
private function handleRightClick():void
{
Alert.show("Right Click Success!");
}
Step 3 – Dispatch an event to the correct object
Getting the event to the main application is easy, but we actually want the appropriate child object to be notified when the right-click event occurs. Since I am not using any double-click events in my application I decided I would treat every right-click event like a double-click event. Users without a two button mouse (aka Mac users) can simply double-click to get the same menu while users with a two button mouse just have to right-click. Here is how I make sure the event is dispatched to the appropriate object.
private function handleRightClick():void
{
var objects:Array = systemManager.getObjectsUnderPoint(
new Point(mouseX,mouseY));
if (objects.length>0)
{
var object:Object = objects[objects.length-1];
var relatedObject:InteractiveObject;
if (object is InteractiveObject)
relatedObject = object as InteractiveObject;
else if (object.parent && object.parent is InteractiveObject)
relatedObject = object.parent;
var event:MouseEvent = new MouseEvent(
MouseEvent.DOUBLE_CLICK,true,false,mouseX,mouseY,
relatedObject);
object.dispatchEvent(event);
}
}
I hope this helps!

Flex: Lose Component Focus

I have a (hopefully) quick question. I've got some stepper boxes. Though really this could apply to any interactive component. I want the selected box to lose focus when when I click anywhere else ( stage included ). Is there an easy way to do this? I can't seem to find an effective way to make it lose focus.
In case anyone else finds their way here seeking a solution to this problem, here is the answer:
private function onGlobalMouseUp(event : MouseEvent) : void {
var fm:FocusManager = new FocusManager(stage);
//Since Flash Player can set focus on subcomponents as well as on components themselves,
//findFocusManagerComponent is used to find the component that either has focus or contains the subcomponent
//that has focus. If, for example, a TextField contained within a TextArea component has focus, findFocusManagerComponent
//will return the TextArea component, and not the TextField. This being the case, we can definitely determine
//whether the target object of the MouseUp event is a component (or is part of a component). If the target
//object is NOT a component (nor contained within one), then we clear all component focus.
if(fm.findFocusManagerComponent(event.target as InteractiveObject) is UIComponent){
//target of MouseUp is either a UIComponent, or is contained within a UIComponent, so do nothing.
}else{
//target of MouseUp is neither a UIComponent, nor is it contained within a UIComponent, so set component focus to null.
fm.setFocus(null);
}
}
So here's the solution I've come up with that works very well. I have a function called add() which has been assigned to applicationComplete. In that function I include:
this.skin.addEventListener( MouseEvent.MOUSE_UP, loseFocus );
Which calls:
private function loseFocus( e : MouseEvent ) : void
{
if ( e.eventPhase == EventPhase.AT_TARGET )
{
this.focusManager.deactivate();
}
}
Simple enough, and does what I was looking for. "Phase" filter is necessary to keep other components from registering the clicks.
As an important note: this.skin needs to be the event target. The stage is never exposed to the mouse in a Flex application.
Example Application Code
If someone has a better solution, please suggest one!
Perhaps you should check out FocusManager.hideFocus().
Maybe tie it into the focusOut event of your UIComponent.
Flex API

flex3:How to override function set label of a button

Flex 3 question:
I trying here to avoid having to bind resources to all my components labels ( ie a button) and find a way to have this automated.
Problem:
It corrupts the layout in design mode to bind directly in the mxml label="{resourceManager.getString('myResources', 'submit')}" and makes the design view useless. but when declaring bindings elsewhere, in actionScript or via a bind tag, it is counter productive and prone to many errors and miss.
Proposition:
I would like to create my own button that automatically invoke resources to localize a button label. So the author puts "Submit" in the mxml description of my button, and when running it would take the value of the label ie "submit" and use resourceManager.getString('myResources', 'submit').
but I can't find the way to override the set label function, Is it possible if yes how? else how can I go about it?
Maybe I am missing an essential process here that would make the use of resources more elegant, as well as how to override such thing as a button's label.
Thanks for your advices.
Create a component called MyButton, extending Button. Then use this:
override public function set label(value:String):void {
super.label = resourceManager.getString('myResources', value) || value;
}
Assuming the resource manager returns "null" or "undefined" this will work, and will only replace the value if it exists in "myResources".
If you don't want to override every component you need to do this with, then you can add a FlexEvent.CREATION_COMPLETE event on every component. Then use a single generic function to do your label localization.

Adding dynamic DisplayObjects in Flex

I am adding DisplayObjects to a Canvas using
ContentContainer.addChild(c);
Where ContentContainer is my Canvas object and c is the DisplayObject I have created at run-time
Some of these DisplayObjects also have children of there own which are added at run-time prior to the DisplayObject being added to the Canvas
I then need to iterate over all the children of ContentContainer but the first time I do this, it says that ContentContainer has no children (ie, ContentContainer.numChildren = 0). If I do it again tho then it is fine and returns the correct number of children.
Is there something I need to call to get ContentContainer to recalculate how many children it has?
As Michael noted it would be helpful to see the code but you might want to look into the Event overview and About the creation policy sections in the docs - http://livedocs.adobe.com/flex/3/html/help.html?content=containers_intro_3.html
Specifically the childAdd event might be what you want to listen for before you iterate over it:
add Dispatched by a component after the component has been added to its container and the parent and the child are in a consistent state. This event is dispatched after the container has dispatched the childAdd event and all changes that need to be made as result of the addition have happened.
=Ryan
ryan#adobe.com
I did a similar task with a callLater in order to wait till after a dragdrop completed before recalculating some tasks. This might work for you.
public function myFunct():void{
//do your adding
callLater(
function():void{
//do your loop
}
)
}

Resources