mouseOver and mouseOut on changing size canvas - apache-flex

I am building a graphic component in MXML that has different states, each state having its own size.
I have a "normal" state and a "highlighted state", the highlighted one having a higher height.
On this components I implemented a function to be executed on each mouseOver and mouseOut to change from normal state to highlighted state and back.
My problem is, in the highlighted mode, the mouseout event is triggered according to the size of the normal state.
Here is the code:
<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:controller="com.*"
mouseOver="mouseOverHandler(event)" mouseOut="mouseOutHandler(event)"
width="230" height.Playing="40" height.Normal="21" height.Highlighted="40">
<mx:states>
<mx:State name="Normal" />
<mx:State name="Playing" />
<mx:State name="Highlighted" />
</mx:states>
<mx:Button includeIn="Highlighted" left="19" bottom="2" width="15" height="15" />
</mx:Canvas>
Is there something wrong in the way I use mouseOuver and mouseOut ?
Thanks,
Alexandre

I am building a graphic component in
MXML that has different states, each
state having its own size.
You have a misunderstanding of how the Flex Component Architecture works. A component never sizes itself. It is always up to the parent to size it's children. You can override the measure method to set measuredWidth and measuredHeight; however these are only suggestions provided to the component's parent. It is up the component to decide whether to accept them or no.
So, in your example, you can change the height/width of the button (a child); but you cannot change the height/width of the canvas (The component you're extending) and expect it to stick.
Without seeing the code that contains this canvas component, it's hard to say for sure what is going on. But, in this case, you should override the measure method to change the measuredWidth / measuredHeight. Something like this:
override protected measure():void{
if(currentState=='Normal'){
measuredWidth = 0;
measuredHeight = 0;
} else {
measuredWidth = button.width;
measuredHeight = button.height;
}
}
When the state changes, be sure to call the invalidateSize() method. You can do this by listening to the currentStateChange event.
In theory, that will cause the component to change the measuredWidth/measuredHeight; which will force the parent to also redraw itself, accommodating for the new measuredWidth/measuredHeight.
MXML masks a lot of these details.

Related

Flex accessing custom component's children properties

Is there a way to access children's properties of a custom components from mxml and not from the actionscript.
For example, i have a component "A"
<s:Group>
<mx:UIComponent id='childA'/>
<mx:UIComponent id='childB'/>
</s:Group>
And somewhere in the application i want to do something like this
<s:HGroup>
<components:A>
/*I want to access properties of this children objects*/
<childA width="20"/>
<childB color="0xFFFFFF"/>
</components:A>
<components:A>
/*And here too*/
<childA width="60"/>
<childB color="0x000000"/>
</components:A>
</s:HGroup>
You can do this in ActionScript; but not in MXML. In ActionScript:
componentAInstance.childA.width = 20;
componentAInstance.childB.setStyle('color',0xFFFFFF);
This is what we call a horrible break in encapsulation; becahse the "parent" should not need to know about the implementation details of its children.
ComponentA should know how to size and position its own children; in this chase childA and childB. It should not need help from ComponentA's parent.
You may find benefit in reading this blog post about how component's should communicate with each other.

Loss of image quality when zooming in Flex Mobile application

i have a mobile application that i am creating in Adobe Flex (Flash Builder 4), and i am trying to create a zoom function. The one i have works, but the point is to be able to more easily read words that are in the image (the images are .jpg files). The images are 2550x3300 originally, but as soon as you zoom, the image quality reduces drastically, and nothing is readable.
My code for the zoom function is included below.
protected function onZoom(e:TransformGestureEvent, img:Image):void
{
img.transformAround(new Vector3D(e.localX, e.localY, 0), new Vector3D(img.scaleX*e.scaleX, img.scaleY*e.scaleY, 0));
}
and this is the code for the image object:
<s:Image id="titlepage" includeIn="title_page" x="0" y="0" width="320" height="415"
gesturePan="onPan(event, titlepage)"
gestureSwipe="onSwipe(event)"
gestureZoom="onZoom(event, titlepage)"
source="#Embed('assets/myImage.jpg')"/>
Image quality would be improved by setting smooth to true for anti-aliasing.
<s:Image smooth="true" />
There are many ways to handle registration issues - you might be interested in Yahoo Astra utils DynamicRegistration class.
Maybe something like this?
<fx:Script>
<![CDATA[
import com.yahoo.astra.utils.DynamicRegistration;
protected function image_gestureZoomHandler(event:TransformGestureEvent):void
{
DynamicRegistration.scale(image,
new Point(event.localX, event.localY),
image.scaleX *= event.scaleX,
image.scaleY *= event.scaleY);
}
]]>
</fx:Script>
<s:Image id="image"
smooth="true"
gestureZoom="image_gestureZoomHandler(event)" />
I'm not positive on this, but I think the 'transform' functions creates a bitmap out of your Image which is why you're losing quality. Try using the 'smoothing' attribute on your image.
From there, it's simply scaling and moving your image incrementally. However, what I'm not sure about is if the localX/Y property is from the original place of touch, or of the new position on the container (ie. if you're pinch/zooming from the middle and it scales, will the point still be on the middle or slightly top left).
I'll try to test this out on my phone and see what I come up with.

How to set the a background image of a RichTextEditor in Flex 4

I have tried setting the background image this way, but it doesn't work. Any ideas how to set the background image of a rich text control in flex as easy as possible? Thanks
.rte{
...
backgroundImage: "assets/globe.jpg";
}
and
<mx:RichTextEditor id="rt"
...
styleName="rte"
/>
Unfortunately, you can't.
The docs for RichTextEditor show that it doesn't support a backgroundImage property, and the component is not skinnable.
Therefore, I'd suggest creating your own wrapper component, which accepts an image, like so:
<!-- Note: Using Canvas becuase your post indicates Flex 3, if using Flex 4, please use Group -->
<Canvas>
<mx:Image width="100%" height="100%" />
<RichTextEditor />
</Canvas>
The RichTextEditor component doesn't support background images last I checked. What you'd want to do is create a custom RTE skin where you add an image behind the actual text, then within the skin, have the do getStyle('backgroundImage') and set it in a bindable private var which is then binded to the image.
That's about it. It's either use this skin or you can always wrap your RTE within a BitmapImage or some other kind of component that supports background images.
EDIT: Sorry, didn't see that this was Flex3. In that case, you'll need to extend your RTE component and add the Image component manually by overriding the createChildren function and then changing the value of the image by overriding the updateDisplayList function using the same getStyle function as mentioned above.
It can be done by setting RTE TextArea's backgroundAlpha to 0
<mx:RichTextEditor id="richTextEditor"
backgroundImage="#Embed('<imagepath>')" width="100%" height="100%"
initialize="{richTextEditor.textArea.setStyle('backgroundAlpha', '0') }"
/>
Note:Please modify image path and you can also set style through CSS/Style tag
Hopefully this will helps

Flex: rotating buttons and changing focus

I've got a problem with rotated buttons in Flex. They seem to contaminate other components' focus rectangles.
Take the following source code, which couldn't be much simpler:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:VBox width="100%" height="100%">
<mx:Spacer height="100" />
<mx:Button rotation="10" />
<mx:TextArea rotation="0" />
</mx:VBox>
</mx:WindowedApplication>
Now execute it. Click in the text area, the focus rectangle is correct. Press tab twice, the focus rectangle aroung the TextArea is rotated!
Is there a fix for this, or should I avoid rotating buttons altogether?
I'm using Flex SDK 3.5.
Thanks,
Daniel
I as well recently stumbled upon this bug. Here's a link to suggested fix.
However, I was wondering if there's a more general solution rather then extending each and every component and overriding adjustFocusRect.
I came up with extending FocusManger and overriding the getter for focusPane as follows:
override public function get focusPane():Sprite
{
var fp:Sprite = super.focusPane;
if (fp && fp.numChildren != 0)
fp.getChildAt(0).rotation = 0;
return super.focusPane;
}
and set it as application's focus manager:
private function onPreinitialize():void
{
application.focusManager = new FocusManagerEx(this);
}
This seems to work, though would be nice if some expert could tell if there aren't any pitfalls I'm not aware of.
Seems like a bug in Flex SDK. I see next options:
disable focus rectangles with focusSkin="{null}"
implement your own skin and handle rotations correctly
move to Spark, since 3.5 is the (currently)
last SDK of third generation
try to fix it yourself (I feel it will be
tricky...)
Also, you may file a bug in Adobe's tracker, but they're deep into 4-th generation of Flex.
Update: 3.6 nightly build contains this bug, too.

How to bind Flex Effects to the effects target properties?

I'm trying to reuse effects. To achieve this, i was hoping that i could bind some of the effect's properties to the effect's target. Here's what i wanted to do:
<mx:transitions>
<mx:Transition toState="Ready">
<mx:Parallel targets="{[b1, b2, b3]}" perElementOffset="200" duration="500">
<mx:Move xFrom="{target.x-100}" xBy="100">
<!-- possibly a fade effect too -->
</mx:Parellel>
</mx:Transition>
</mx:transitions>
<mx:VBox>
<mx:Button id="b1"/>
<mx:Button id="b2"/>
<mx:Button id="b3"/>
</mx:VBox>
The above code assumes, a state change on application createComplete to Ready state.
In my futile attempt with the above code, i tried to create 1 effect that would animate the entrance of 3 buttons all laid out using VBox. I'm (trying to) avoiding 2 things:
Absolute layout hence hand coded coordinates. I want to exploit the containers.
Effect code duplication
Results:
- Compiler complains target is not defined. I've tried to put whole list of ideas into that field but to no avail. I've tried:
{this.target.x}
{effectId.target.x}
{propertyThatReturnsTheObject.x}
Can this be done? Thanks in advance.
if you give the Move Effect an id, can you bind to {moveId.target}. Its not clear that your second case is it...
I suspect the compiler is looking for target in a different scope to the one you think it is...
Certainly, target isn't a bindable attribute, so this may be academic anyway.

Resources