How to build efficient button skins with larger hitareas than visible area - apache-flex

What I'm trying to do: build a super simple button skin (say a small circle when in up state, slightly larger circle when in over / down states) that has a larger mouse hit area than visible area. In other words, I'd like the button to look like a 5x5 circle when in up state, but transition to over state when the mouse is in a 15x15 pixel area around such circle - in order to make clicking on the button easier.
What I've done in the past is to use a transparent ellipse behind the the visible ellipse. This works nicely but seems like a waste of memory (not much, although if you start having a lot of these buttons it adds up) and rendering cycles (transparency). I thought I could avoid this by wrapping the ellipse in a group with a given size and listen to its mouse events, but somehow no mouse events seem to fire on such a group - not sure why.
I guess I'd love to know if anyone knows an efficient way to do this. Also would love to know why such a group won't fire mouse events, but I guess that's secondary. Simple code snippet below:
the application:
<?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" minWidth="955" minHeight="600">
<s:Button x="100" y="100" skinClass="mySkin"/>
</s:Application>
the button skin:
<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009">
<fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.states.OverrideBase;
protected function group1_rollOverHandler(event:MouseEvent):void
{
trace("roll over");
}
]]>
</fx:Script>
<s:states>
<s:State name="up"/>
<s:State name="over"/>
<s:State name="down"/>
<s:State name="disabled"/>
</s:states>
<s:Group width="15" height="15" rollOver="group1_rollOverHandler(event)">
<s:Ellipse height.up="5" height="12" width="12" width.up="5"
x="0" y="0" x.up="3" y.up="3">
<s:fill>
<s:SolidColor color="0x222222"/>
</s:fill>
</s:Ellipse>
</s:Group>
</s:SparkSkin>

I wouldn't worry about the memory of an Ellipse inside of a SparkSkin. If you are that concerned about memory, you would want to roll your own Button
However, there are a couple of very minor performance enhancements that won't effect the implementation:
Use Skin instead of SparkSkin. it is lighter weight.
Use Rect for the hitarea. It is lighter weight than Ellipse

Related

adding a background image in flex 4.6

Doing a Flex 4.6 mobile app I am trying to add an asset .png file to be displayed as the background to the application across all the different views and orientations. Has anyone worked out a way to do this yet?
Any help would be appreciated :)
I've been in this hole and I know the way out.
You'll need to create a skin class for your application. It doesn't have to be too complex here's what my file (appSkin.mxml) looks like.
<?xml version="1.0" encoding="utf-8"?><s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>
[HostComponent("spark.components.View")]
</fx:Metadata>
<!-- states -->
<s:states>
<s:State name="disabled" />
<s:State name="normal" />
</s:states>
<s:BitmapImage source="#Embed('assets/bg.png')" width="100%" height="100%" />
<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />
<!-- SkinParts
name=contentGroup, type=spark.components.Group, required=false
-->
Then you'll need to declare that file as your application's skinClass in your application's opening tag…
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="320"
creationComplete="creationCompleteHandler()" xmlns:views="views.*" skinClass="skins.appSkin">
Then you'll have to do one final step. Each of your View components are carrying an opaque background layer so in each of them you'll want to explicitly set that backgroundAlpha value to 0.
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Start" backgroundAlpha="0">
And that should accomplish your mission of maintaining a common background image for your application across multiple views.
Try something like this:
<s:View>
<fx:Script>
[Embed(source="myImage.gif")]
public var myImage :Class;
</fx:Script>
<s:Image source="myImage" width="100%" height="100%"/>
</s:View>
Info about Embedding images in Flex
However, I don't expect perfect results. A PNG is a pre-rendered bitmap. Most likely it will not look right across all views and orientations [and resolutions] because elements of the PNG may be skewed, stretched, or compressed, with it is resized on the fly; for example when switching from portrait to landscape.

Inconsistent Flex Effects

I've created a simple effect in Flex, code below, but it does not execute correctly... When I rollOver the icon, MOST of the time the effect plays, and when I rollOut of the image the effect should play in reverse, but rarely does...
Is my code or logic incorrect? FYI - I'm using Flash Builder 4.6.
<?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" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:Move id="detail_fade" target="{detail_panel}" xFrom="218" xTo="400" />
</fx:Declarations>
<s:Panel id="detail_panel" x="218" y="10" width="728" height="580" title="something">
</s:Panel>
<s:VGroup x="7" y="5" width="200" height="200">
<s:Image source="images/Airfield Icon.jpg"
rollOver="detail_fade.play()" rollOut="detail_fade.reverse()"/>
</s:VGroup>
As Mahesh pointed out in his comment, reverse() will only reverse an effect that is actually playing. Which is why you only see it happening sometimes: i.e. when you're quick enough to roll_out before the effect has ended.
You should instead use:
detail_fade.play(null, true);
The first argument of the play method, is an Array of the targets of your effect. Since you've already given it a target, you don't need to pass it again (that's why it says null).
The second argument is a Boolean telling the effect to play in the inverse direction if set to true. It is of course false by default.
Now, you may notice that when you roll_out quickly, the effect will jump to the end and start playing in the other direction from there.
This can be fixed like so:
if (detail_fade.isPlaying) detail_fade.reverse();
else detail_fade.play(null, true);

Spark RichEditableText weirdness when heightInLines="1"

Try this:
<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">
<s:Panel id="pnl">
<s:RichEditableText id="richEdTxt"
width="200"
maxChars="100" />
</s:Panel>
</s:Application>
Now set heightInLines="1":
<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">
<s:Panel id="pnl">
<s:RichEditableText id="richEdTxt"
width="200"
maxChars="100"
heightInLines="1" />
</s:Panel>
</s:Application>
See the problem when you fill up the RichEditableText with characters? Keep typing the word hello until you cross outside of the first visible area of the RichEditableText. things get weird. Try it out. Anyone have any ideas how to prevent the weirdness? (the text starts jumping up and down)
This is a bug that appears to have been fixed in a later SDK - but I can't seem to find the JIRA ticket for it.

Setting background image in Flex 4.5

I have written a custom skin in Flex 4.5, which shows a custom image. I want this to my background image, so how can I set this skin to the application container?
Thanks
You skin the application like any other component, the skinClass attribute of course! :)
How?
Here is my app.mxml :
<?xml version="1.0"?>
<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"
skinClass="MyAppSkin">
</s:Application>
Now, here I make a simple skin with a background image stretched to fit!
Full source of my MyAppSkin.mxml file here (too big to post here): http://pastebin.com/Hwu9tc1Y
Here is the important part (only part really customized - rest is standard) :
<s:Group id="backgroundRect">
<s:BitmapImage source="#Embed('beach.jpg')" left="0" right="0" top="0" bottom="0" scaleMode="stretch"/>
</s:Group>
What happens when you apply a skin is that it searches for certain elements by id (backgroundRect being the one we're interested in) and applying them. To customize, simply change the parts of the skin you want. I replaced the standard background solid color fill with this group with an image.
Piece of cake sir!
Make sense?
How about this:
<s:BitmapImage source="#Embed('paper1.jpg')"
left="0" right="0"
width="100%" height="100%"
/>
Set background image and add components
<mx:VBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
<s:List>
<s:ArrayCollection>
<fx:String>One</fx:String>
<fx:String>Two</fx:String>
<fx:String>Three</fx:String>
<fx:String>Four</fx:String>
<fx:String>Five</fx:String>
</s:ArrayCollection>
</s:List>
</mx:VBox>
</s:Group>

Flex4: Combo Box with CheckBox Inside

Apologies for all the simple questions but they are born of my sudden and unplanned migration from flex 3 to flex 4.
Ok I have a combo box which I would like to show a list of selectable check boxes.
<s:ComboBox x="181" y="-7" width="233" id="dropISLIST" itemRenderer="IsListFilterCheckBox" dataProvider="{GetIsList.lastResult.ReportFilterList.ReportFilter}" color="#000000"/>
To this end I have built the following item renderer.
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" width="142" height="22">
<s:CheckBox x="0" y="2" label="{data}" color="#000000"/>
</s:ItemRenderer>
Now that all works fine, how ever, I can not "Check" a box, what I would like to be able to do is have the user be able to select a number of check boxes. And then also figure out what they have checked.
Any help in this regard would be greatly apreciated thank you so much in advance.
Regards
Craig
Try this component. It should do everything you are needing
http://www.carballares.es/en/arcadio/?page_id=352

Resources