Best way to make elements non-selectable in Flex - apache-flex

All,
As part of requirements for a new feature of "locking" a page, it is desired to have all elements on a locked page be non-selectable. This is not to be confused with disabled. All elements should appear as if the page were active, but not be selectable.
The current thought is to create a clear canvas and place it over the existing elements. With this thought, I have two questions:
if you can think of a better way to make all items non-selectable than applying a clear canvas element over the existing elements could you describe it?
if not, what is the best way to retrofit existing implementations to accept the overlayed canvas item? BTW, all .mxml pages inherit from a custom .as file.
Sorry if this is not very descriptive, however, I am new to Flex and have spent many days trying to figure this out.
Thanks,
Todd

You could also set the mouseChildren property of the page to false so the elements will not receive any mouseEvents

All,
To fully "lock" a screen from user manipulation, one must combine Chris Bos's and www.Flextras.com's answers: disable mouse input (mouseChildren) and disable keyboard focus (focusEnabled).
Todd

Would the focusEnabled property work for you?
Documentation says it only relates to "Tabbing", but my memory says it relates to all sorts of selection.

Related

Flex TextArea autocomplete, not TextInput

Does anyone know of a TextArea component with autocomplete? I understand Flextras.com's Autocomplete can be reskinned as a TextArea but wouldn't know where to begin.
If you just wanted to auto complete on each word, similar to (Ctrl-Space) in most IDEs, then you could try doing it yourself.
I would imagine that you would catch the change event on the text area then do some comparison (something like startsWith) of the characters preceding the carat against some pre-populated collection of words.
Flextras poses a good question, in how do you display suggestions. One idea would be to use a custom context menu, discussed here, containing your suggestions. There's also a decision to be made on when to display it. Do you display it constantly as the user types, or maybe when they use a key combination (Ctrl-Space).
It's an interesting challenge.

Flex: accessing child through navigating the hiererachy

I have a generic function to build rows of controls (each row comprising of sliders, radio buttons, reset buttons, text display) etc, and some functionality to change underlying data based on these
As I didn't want to write specific code for each row, I had code written by which I can detect the row on which there has been a mouseevent, and though the row access each individual control
The hierarchy used is titleWindow (part of popup)->skinnable container->HGroup->control
When I trace for a radiobutton, I get the path as follows Electric_Modify.TitleWindowSkin2620._TitleWindowSkin_Group1.contents.contentGroup.0.RadioButton2645
The '0' before the radioButton stands for the first Hgroup id->named as 0
I tried accessing the radio button as follows- 5th element in the HGroup
((this.contentGroup.getChildAt(row)as Group).getChildAt(4) as RadioButton).enabled=false;
and get a message "Cannot access a property or method of a null object reference" on this line. How should I navigate the hierarchy to reach the element?
You should be using getElementAt(...) and not getChildAt(...).
The get element functions represent a "higher level" element hierarchy which is needed to make skinning easier.
((this.getElementAt(row) as IVisualElementContainer).getElementAt(4) as RadioButton).enabled = false;
It should look something like that, but the exact hierarchy depends on what's in your app.
#drkstr
Thanks for your input... I thought of an alternate approach that worked for me...I mapped out the parent of the HGroup via
parent1=hgrp.parent; and then referenced these buttons as follows
((parent1.getChildAt(row)as Group).getChildAt(4) as RadioButton)
This works like a dream...I presume your suggestion would let me jump across the intermediate layers
#J_A_X/ #Constantiner: Thanks for the suggestion. I have no idea why we didn't think through and go down the DataGroup path. Prima facie seems simpler... we got to creating the UI controls in MXML laying out controls serially,and when it came to making it generic, we literally replicated the MXML approach in AS. Started off easy, till it caused problems like above. We will fix this to a better approach, when we upgrade versions. It works for now

How to find the first focusable component in a container?

I'm trying to programatically set a focus on the first component of a given container. What's the best way to do it?
A couple of notes:
I haven't found any appropriate method on IFocusManager / IFocusManagerContainer interfaces. Ideally, there would be IFocusManagerContainer#getFirstFocusableComponent() but there is no such method.
The "first" component is the one that would receive focus if you were on some component just before the container and pressed TAB. It is not necessarily the first focusable child of the container (tab order plays role here).
I'd like the solution to perform well. I'm not particularly keen on traversing display list, I still hope there is some better way.
Thanks!

Flex: Custom context menu for a component

I have a Flex application, running with Flash Player, not AIR, that contains a Tree that I would like to put a custom context menu on.
Tried just doing <mx:Tree ... contextMenu="{MyClassWithStatic.menu}">, but that didn't do anything.
Went searching, and found this quote from some Adobe docs somewhere
In Flex or Flash Builder, only top-level components in the application can have context menus. For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
so went upwards, trying each parent element until I reached my <Application>-element, which is consistent with what they wrote.
Tried making a Flex component, based on Group (the default) which contained my tree, and the context menu on the top-level element there, hoping it would work, but to no avail.
Is there any other way to manage this that I haven't found yet?
The code I use to create the menu:
var menuItems:Array = [];
var rename:ContextMenuItem = new ContextMenuItem("Rename");
rename.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, renameSelectedHandler);
menuItems.push(rename);
menu.customItems = menuItems;
menu.hideBuiltInItems();
You're right, the contextmenu only works on top level components. It's a limitation of Flex which is annoying and shouldn't be there in the first place. There's not much you can do since there is no way to capture the event other than using some Javascript trickery, but even then, it doesn't tell you where you were clicking.
If I were you, I would just forget the concept and go away from using right click altogether if possible.
I can't be sure, as all the code isn't' there. But you seem to have ignored your own research. Don't use your new component, or anything which "contains" your tree. Then just stick the Tree in your application.
Also I've a memory of TreeItemRenderer not being the same as in other UIcomponents. Maybe, test your "menu" code with a Datagrid first and make sure it works. Good luck
I did not try it myself, but after reading the comments on http://michael.omnicypher.com/2007/02/flex-trees-with-context-menu_14.html it looks like you could add a context menu to the tree's item renderer.
The article and comments at http://blog.arc90.com/2008/04/21/adding-a-contextmenu-to-a-flex-tree/ are worth a look too.

How do you make Flash not render an object on the Stage?

This discussion started over here but I thought it would be nice to have a definitive answer...
So let's say you have MovieClip on the Stage (or a UIComponent for the Flex audience) - what do you have to do to not make it so that the user can't see the object but also so that the AVM2 doesn't even factor it in when rendering the stage for the user?
I always thought the answer was to set visible = false but there is an argument out there that the object has to placed outside the boundaries of the Stage (like x = 2000 which seems like a hack IMO). Does anyone know the real answer?
EDIT: I imagine the need for having flash not render the item would be to help performance.
As other answers have noted, the "hack" for moving clips outside the stage is no longer necessary. However, setting visible = false; is not a smart thing to do if performance is important. Clips that are part of the display list, but set to be invisible, can still incur a significant rendering overhead if you have enough of them. If you remove them from the playlist with removeChild(), they incur no rendering overhead (although they still take up memory).
The hack is for Flash 8 (Actionscript 2) or below. With the upgrades to Actionscript 3 and Flex 2/3 setting the visible property is enough.
Yeah, as design said, just remove it from the display list:
var s:MovieClip = new MovieClip();
s.lineStyle(1, 0xFFFFFF);
addChild(s);//shows in moviea
removeChild(s);//removes from display list, but you still have a reference to it
I havent tested that, but it should give you the general idea.
mike
If you're using Flex and its container layout system, the includeInLayout property in the UIComponent class is also useful when you don't want to display something: it specifies whether or not to factor the component in when measuring the layout.
Remove it from the display list completely (removeChild(), removeChildAt(), etc.). As long as you don't actually set the reference to the MovieClip to "null", it will still remain in memory and can be re-added to the display list when you need it again (addChild(), atChildAt(), etc.)

Resources