How can I create a context menu on the fly in a textArea in AS3/AIR? - apache-flex

I am migrating an application from Flex/Flash to Flex/AIR 32.
Many years ago I began using the flextenibles SpellCheck module. It creates a custom component for textArea which will underline misspelled words then display misspelled word in a context menu.
I have successfully migrated it, however the only way to get the custom context menu to popup is by very carefully right mouse clicking the squiggly line under the text, not the text itself. When I right click the text it displays a default context menu. It actually never gets to the function to build custom context menu. I have place the following code in a variety of places in the custom class which extends mx.controls.textArea;
private function creationCompleteHandler(event:Event):void
{
this.contextMenu = new ContextMenu;
this.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT,showMenu);
}
Including in the constructor and its original location createChildren with the same behavior.
In the Flex/flash version right clicking the text would bring up the custom context menu.
Edit:
As I do more debugging, I find "this.textField" from within the component is firing MouseEvent.CONTEXT_MENU, and it is never getting to the "this.contextMenu" event.

Well I found a work around.
I used the following to create the event listener;
this.textField.addEventListener(MouseEvent.CONTEXT_MENU,showMenu);
Then I changed the handler to use the event data from a mouseEvent instead of contextMenuEvent, this seems to work.

Related

Is there a way to show tooltip on disabled QWidget

I have a Qt form, where I have a button and menu. For various reasons I can disable certain elements, e.g button or some actions in the menu.
Is there a way I could show a tooltip or when the mouse is hovered over the disabled button or menu item with an explanation as to why it is disabled?
I am using Qt 4.8.
Thanks!
You can set the tooltip dynamically based on the state of the QWidget or by simply toggling both at the same time. Upon disabling/enabling the widget from somewhere just call QWidget::setToolTip(...) with the QString you want the tooltip to display when hovering with the mouse over the given widget. For example if you have a public slot called toggleButton(bool toggleFlag) which toggles the enable-setting of a button you can do:
void MyWidget::toggleButton(bool toggleFlag) {
this->ui->myButton->setEnabled(toggleFlag);
this->ui->myButton->setToolTip(toggleFlag ? QString("Enabled wohoo!") : QString("Disabled because I like it"));
}
You can of course do also change the tooltip by calling QWidget::isEnabled() and act upon its return value. Since you haven't given any code I can only assume how you toggle your button(s) so that's all I can give you for now.
UPDATE: It was pointed in the comments that tooltips don't work with disabled widgets due not receiving mouse events. Both statements are not true (note that I have used the same tooltip message since due to lack of minimal working example I didn't want to write a whole new project from scratch and used an existing one of mine instead):
Hovering a disabled button triggers the tooltip
Hovering an enabled button triggers the tooltip

How to completely initialise a component but not add it to the display? Flex

I need to completely initialize a custom component in my Flex app (i.e. I should be able to access it from action script and get its properties and its children etc), But I do not want to add it to the display or make it visible.
I have tried to add it to my visible component, but keep it visible, but often many of its properties are set only when it is drawn, so i don't get what i need.
Is there a way to add a custom component to some sort of 'Virtual' display, that is not visible to the user?
You could add the component to an invisible Sprite - that way the component itself could both be on the stage and have its own visible property set to true.
Did you try using initialize()? After a view is added to the display list, the initialization stage begins. Calling initialize() before addChild() should let you initialize the view without needing to first add it to the stage.
For more info visit:
http://flexscript.wordpress.com/2008/10/24/flex-component-lifecycle-and-flex-component-framework/
http://blog.deadinkvinyl.com/2008/10/05/flex-3-addchild-and-initialize/
Not sure if possible without adding it to the display list, although I'd wish it were to some extent.
I once had to make custom drag proxy, which didn't work with the real component, because of some weird skinning issues. So instead I had PopupMananger add a box as a popup, added my component to the box, called validateNow on the component, drew it in a bitmap data, removed the popup, and used the bitmap data as the proxy.
So what you were trying was missing a call to validateNow most likely.

keydown event reusable code - how can I write it once and use anywhere in my flex application

I am new to flex framework.
I have created an application using flex framework 4.1 which is having various components that are shown to the end user in the form of a popup window using <mx:TitleWindow>.
This titlewindow is closed either on the click of the close button (displayed in it's titlebar) or by pressing the "escape key" on the keyboard.
I coded a functionality wherein I close the current TitleWindow whenever an 'escape' button is pressed.
Here is what I did.
On the keydown event of TitleWindow I called this function
private function detectescapekeypress(event:KeyboardEvent):void
{
if(event.charCode == Keyboard.ESCAPE)
PopUpManager.removePopUp(this);
}
But this function does not work when I define it in the main home screen of my application and call it using parentApplication.detectescapekeypress(event) on the keydown event of TitleWindow
I had to repeat this code for every TitleWindow that I have used in the project.
How can I write the above functionality only once and reuse it amongst various TitleWindow and other components so that the code for the same is not repeated across various components?
Note: Every TitleWindow that I am using has different code, scripts and layout in it.
Thanks
Why don't u just extend the TitleWindow component and add that functionality to your new custom component? Then use it everywhere instead of the original TitleWindow.
I assume u're using at least SDK 4.1
Create a new mxml file called for example CustomTitleWindow.mxml and paste the following
http://www.copypastecode.com/68211/
Then change all your title windows to CustomTitleWindow.
P.S. Note that in order for the key event to be dispatched, the component must have focus.
blz

Flex 4, multiple instances of a custom component listening the same event of a parent

In short:
I need an event listener in a custom component so all its instances (without editing them) react at the same time, fired by a dispatched event in its parent container.
In detail:
I have a custom component with Tab navigator. (The tabs are intended to show different preferences for different Languages.)
I have a button bar with buttons for all the languages.
There are a lot of instances of the custom component.
I want to click in a button of the languages bar and get ALL the instances switched to the same tab (the custom component contains the logic to change the tab).
I can do it by adding the event listener for EACH INSTANCE of the custom component, so it calls an internal function that changes the tab. But it seems to be very coupled, isn't it?
I wonder if it can be done in the master CLASS of the component, so it listen for events in its parent container, whichever it is.
In my mind this code shoud work, but it doesn´t (obviously ill'use a custom event to pass the new language value):
this.parent.addEventListener("lang_change", this.change_tab);
This way I can just drop an instance of the component, and see it working for itself.
Thank you in advance
I need an event listener in a custom
component so all its instances
(without editing them) react at the
same time, fired by a dispatched event
in its parent container.
The very thing you want to do, by definition, breaks encapsulation. In an ideal world, a component should know nothing of it's parent. If the component needs to communicate with it's parent, it should dispatch an event. IF a parent needs to communicate to children it should call a public method on that child (or change a public property). From an encapsulation stand point, I cannot recommend that the child listen for events on the parent.
I want to click in a button of the
languages bar and get ALL the
instances switched to the same tab
(the custom component contains the
logic to change the tab).
So, then put a click handler for the button and do something like this:
public function onClick():void{
myCustomTabNavigator1.selectedIndex = 1
myCustomTabNavigator2.selectedIndex = 1
myCustomTabNavigator2.selectedIndex = 1
}
You can also set the selectedItem if you a reference to it. , If you have your custom TabNavigators in an Array, you can loop over them. IF the custom TabNavigators are child of your custom component you can create a method in that custom component to set the defaults and call that method on each component instead of setting selectedIndex directly.
I think you should to use some MVC model like:
Cairngorm
http://code.google.com/p/swizframework/
http://www.robotlegs.org/
http://puremvc.org/

Trouble with Flex 3 PopupManager

I'm trying to use the PopupManager class in a Flex3 AIR app to open different kinds of panels but I'm running into some problems with it. I'm using a method like the following with which all panels are opened ..
private function createPopUp(clazz:Class, modal:Boolean = false):IFlexDisplayObject
{
var p:IFlexDisplayObject = IFlexDisplayObject(PopUpManager.createPopUp(_windowParent, clazz, modal));
PopUpManager.centerPopUp(p);
return p;
}
_windowParent is a reference to the application's WindowedApplication root object. I'm running into two kinds of problems with this:
Not all popups appear modal, even if I set the modal parameter to true. This seems to happen if I open a popup panel from within another popup panel.
In some of the popup panels are ComboBoxes and the popdown menu of the comboboxes opens underneath of their parent panel (i.e. under the depth of the panel) so the menu of the combobox becomes partly or fully obstructed.
I've tried different parameters for the PopUpManager.createPopUp() childList parameter (e.g. PopUpManagerChildList.APPLICATION) but that did not change anything.
Hoping that anyone has some tips on these problems!
Nevermind! Figured out I some code that would change the depth of panels that was messing this up.

Resources