Flex / ActionScript - Click Through An Element To Application Behind Air App - apache-flex

I'm attempting to build a desktop AIR app using flex/Action Script in Flash Builder.
My desired functionality is this:
- transparent background
- semitransparent (alpha 0.5) item/element that ignores all mouse events and "passes clicks through" to the application behind the app
So essentially what I want to have is that the element handles mouse events in exactly the same way a transparent background does - ie. it is like you're clicking on the application behind
Here is a code example of what I have tried. In the below example clicking on the button fires the "window clicked" alert to demonstrate that the click is being ignored by the button and reaching the window with the transparent background. When I remove the click handler though, clicking on the button does not result in the click being passed through to application behind, like a click anywhere else on the transparent background does.
Any ideas?
<?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"
alwaysInFront="true"
creationComplete="maximize();">
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
s|WindowedApplication
{
skinClass:ClassReference("spark.skins.spark.SparkChromeWindowedApplicationSkin");
background-color:#999999;
background-alpha:"0";
}
</fx:Style>
<fx:Script>
import mx.controls.Alert;
public function windowClicked():void{
Alert.show("window clicked");
}
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Window id="mainWindow" height="100%" width="100%" mouseChildren="false" backgroundAlpha="0">
<s:Button label="Click Through Me Please" alpha="0.5"/>
</s:Window>
</s:WindowedApplication>

I made a quick comment to your question but thought I would elaborate in an answer.
Since I'm sure you are going to do more than your example up there, here is how those properties work:
mouseEnabled="false" - this says you can't click me but you can click my children. This works well when you are disabling a single item or want click event to pass through an item to it's children.
mouseChildren="false" - this says you can't click my children. This is useful if you are goin to build complex overlays in your app that might contain 10 display objects and want want the mouse to ignore them all.
Hope this helps!

Related

Text in TextArea on AIR mobile app disappears after displaying for a moment

I'm having a very odd issue where I am trying to use a text area to display some text on a mobile AIR app. It works fine whenever I am using the phone emulator on my desktop to debug, however whenever I put the app on my phone, the text displays, then disappears. I've also noticed that if I lock the screen and unlock, the text will display just fine when I come back.
Here's the code:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Program Overview">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
private var text:String = "Hey how are ya";
]]>
</fx:Script>
<s:TextArea text="{text}" editable="false" />
</s:View>
One other interesting thing to note is that it only happens on certain Views, and only on Views in the first ViewNavigator tab. This leads me to believe that there isn't really anything wrong with my use of the TextArea, but something else happening at a higher level in the application. Any ideas on what I should look for?
I think than the problem can be solved if you add the skinClass:
this is for TextArea:
<s:TextArea id="text1" skinClass="spark.skins.mobile.TextAreaSkin" text="{myVar}"/>
this is fot TextInput:
<s:TextInput id="text2" skinClass="spark.skins.mobile.TextInputSkin" text="{myVar}"/>
I hope this help you!
I ended up replacing all of my TextArea's with StyleableTextFields as #Al_Birdy suggested and that took care of the issue. Because you can only use them in AS it made layout and styling a little bit more difficult but it was definitely worth the fix.

Flex Prevent soft keyboard from closing

I have a mobile AIR app with a simple layout:
<s:layout><s:VerticalLayout /></s:layout>
<s:TextArea width="100%" height="100%" />
<HGroup width="100%" >
<s:Button label="button" />
<s:Button label="button" />
<s:Button label="button" />
</HGroup>
The application is set to resize when the soft keyboard opens by setting resizeForSoftKeyboard="true" in the main app. The textArea uses the default Flex 4.6 skin.
My problem is, that if the user opens the keyboard by typing text into my texArea, he will be unable to click the buttons below the TextArea, because as soon as he tries to click a button the soft keyboard lowers (because the focus it out of the TextArea?) and immediately opens again (because the mouseDown position is now above the TextArea?).
How can i prevent the soft keyboard from closing, so the user is able to click the buttons between the TextArea and the keyboard?
Thanks
This is very strange. I tried running your program myself, and I have no trouble at all:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="320" resizeForSoftKeyboard="true">
<s:layout><s:VerticalLayout /></s:layout>
<s:TextArea width="100%" height="100%" />
<s:HGroup width="100%" >
<s:Button label="button" click="trace('clicked')"/>
<s:Button label="button" click="trace('clicked')" />
<s:Button label="button" click="trace('clicked')" />
</s:HGroup>
</s:Application>
The keyboard opens when I touch the text area, closes when I click a button (without opening again), and the clicks show up in the console when debugging.
You didn't post the entire app, do you have anything in the complete program that I don't? In that case, I would see if any of that could interfere with the UI.
Maybe add an event to bring up the keyboard when the button is clicked i.e. in the click event handler of that button.
Also (and I havnt tried this myself), but in the deactivate event for the keyboard for that view, add event.preventDefault()
Brian

Simple Primitive Elements in Flex 4?

Normally on other IDEs, I simply drag a Rectangle object to the body or content of my application then resize it, define colors, etc. What I discovered in Flex 4 (Flash Builder 4) was that it's not just like that (or is it?) and I can't seem to find something to drag to my application to create a Rectangle object.
My question is, how do I do it? How do I create a simple Rectangle?
There is no support for FXG elements in Flash Builder Design mode.
What you can do is, use Flash Catalyst, draw your primitives with it and copy/paste the generated code in Flash Builder.
I think I just figured out how to deal with it. I just make a new component and base it on spark.primitives.Rect. Then after that, I just assign the fill's SolidColor to whatever I need just like my component code below.
<?xml version="1.0" encoding="utf-8"?>
<s:Rect xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
[Bindable]
public var fillColor:String;
]]>
</fx:Script>
<s:fill>
<s:SolidColor color="{fillColor}" />
</s:fill>
</s:Rect>
Not sure if this is the best way but it works for me so I'll go along with it. :)

How to deal with competing effects in Flex?

I'm a beginner at Flex, and having the hardest time, working with Effects.
Right now I'm dealing with the problems faced when dealing with competing effects.
Please look at the following code. I have basically created a short reproducible tests sample which shows the problem I'm facing:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="400">
<mx:Script>
<![CDATA[
private function showmenu():void
{Menu.visible= true;
}
private function hidemenu():void
{Menu.visible= false;
}
]]>
</mx:Script>
<mx:WipeDown id="wipedown" duration="900"/>
<mx:WipeUp id="wipeUp" duration="900" />
<mx:Canvas id="main" width="400" height="400"
rollOver="showmenu();" rollOut="hidemenu();">
<mx:Button label="Show Menu"
x="100" y="20">
</mx:Button>
<mx:Canvas id="Menu" visible="false"
width="100" height="200"
backgroundColor="#B8B8B8" x="96" y="35"
showEffect="{wipedown}" hideEffect="{wipeUp}">
</mx:Canvas>
</mx:Canvas>
</mx:Application>
This basically shows a Button, and when you roll over on the button, another canvas, which is going to be a sort of menu, will be displayed. When you roll out, the Menu disappears.
The menu also has some effects, and if you try to start one effect before another is over, it gets into an infinite loop.
To reproduce what I am talking about, rollover the button, and then rollout and then quickly rollover again. You will see that the menu effects get stuck in a loop.
How do I code around this?
If you're having problems with events playing when they shouldn't, just add EffectEvent.EFFECT_START listeners to your events and use it to stop any playing events. e.g,
function _handleEffectStart(e:EffectEvent):void {
if(e.target == wipedown) {
wipeup.stop();
} else {
wipedown.stop();
}
}
Or something similar.
I cannot reproduce your problem. No matter where/when I move my mouse in or out, it never goes into a loop. Note that I'm using Flex 3.2. Maybe it depends on which version your using?
Btw, your code doesn't completely match your description: You have the rollOver and rollOut events on the canvas that also contains the canvas that you are showing and hiding. Just a guess, but I can imagine that the effect itself actually causes your mouse to be over or not over the canvas anymore, triggering the rollOver/rollOut, which then again cause the mouse to move in/out... Is that the infinite loop you're experiencing?

keydown in flex Flex

I have an small application in flex in which I have defined 2 canvases. On one of them I added controls and the other one is used to draw something and no controls are added:
<mx:Canvas x="0" y="80" width="100%" height="520%" id="Canvas1"/>
<mx:Canvas x="0" y="0" width="100%" height="80" id="Canvas2"/>
I add an keydown event handled to the application but it is triggered only after I click with the mouse on the first Canvas(the one where controls have been added). Otherwise the event is not triggered when keys are presses.
I've tried several things: to set focus on the second canvas, to add the keydown handler to the application(this),stage, canvas... Unfortunately I didn't find a solution to trigger keydown no matter where the focus is.
This is for flex 4.
<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
name="MyApp"
width="480" height="480"
creationComplete="init();">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
public function init():void
{
trace("init");
this.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
}
private function keyDown(event:KeyboardEvent):void
{
trace(event.charCode);
}
</fx:Script></s:Application>
The first problem you describe (having to click the mouse before any KeyboardEvents are dispatched) is likely due to the browser not giving focus to the Flex application itself. You can use Javascript in the HTML wrapper to programmatically give focus to the Flex app on the "body" element's "onLoad" event. I know for certain this works in Firefox and I believe it works okay in IE as well. I'll try to dig up the relevant Javascript code.
As far as the second problem, have tried adding an event listener to Application.application for catching all KeyboardEvents?

Resources