Flex: Setting the resgistration point on a display object - apache-flex

What is the best way to change/set a registration point on a Flex 3 display object? I know this isn't really built in to easily change, but does anyone have any suggestions on how I could extend UIComponent to achieve this?

For some reason, the Flash Player API doesn't expose the registration point of DisplayObjects (and the Flash IDE makes them a pain to modify once an object is created). The best solution, as David pointed out, is to add your component as a child of another component (UIComponent would be fine). So, for example, if I had a Button and I wanted its registration point at its center, I'd add it as a child of a UIComponent (not Canvas) and offset the child by setting its position to (-button.width/2, -button.height/2).

Put your DisplayObject inside a sprite and set the DisplayObject's x & y positions to the negitive of your target registration point. Apply all transforms to the Sprite container.

Put it inside a Canvas container, with its clipContent attribute set to false. Within the canvas, you can put your object wherever you like.

Related

flex 4 - depth property not working as expected

I am developing an isometric game.
I have a parent UIComponent (WorldMap). The player can choose MapElement s (game items) and drop them in the playable area WorldMap. This MapElement also is a UIComponent which contains child controls such as Sprite, Image, Label and custom Flex components to hold various information.
Now, I have written a logic to determine which one should appear in back and which one should appear in front in the Isometric area which I am calling idx (index) and I am seeting this value to the depth property of the MapElement.
I have added three components in the order shown in below pic and I have set the depth property each of them as 11077,11168 and 10630. If the depth property worked properly the 3rd item should have gone behind the 1st item but it seems like they are appearing in the order of they have added (default behavior)
If I am not wrong the depth value can be anything
Can some one help me?
I am aware of another solution using swapChildren, swapChildrenAt and and also addChildAt methods (which I don't want to use for my project specific reason) but I need to find out whats wrong with the depth
The problem, as I think, in your WorldMap component which, as you said, is UIComponent. Diving deeper to depth property shows that depth setter launches invalidateLayering method, which is empty in UIComponent and overrides with logic only in Group which is main container for every Flex 4 component. And here's example:
http://www.tink.ws/blog/flex-4-uicomponent-depth/
So, it looks like, you need to use at least Group or SkinnableContainer as your WorldMap in order to achieve depth property to work correctly.
Use UIComponent.addChildAt(child:DisplayObject, index:int). addChildAt adds a child DisplayObject instance to this DisplayObjectContainer instance. The child is added at the index position specified. An index of 0 represents the back (bottom) of the display list for this DisplayObjectContainer object.

difference between <s:Line> and graphics.lineTo()

If I skin a button and use the AS3 graphice.clear() and graphics.lineTo and beginFill to create a shape, the button overlaps other items in the container.
When I use the and mxml to create the same shape, the button is neatly positioned inside the container.
Why is that?
This is probably happening because Flex is unable to calculate the size of your dynamically drawn button, while the MXML version allows the size to be calculated prior to being displayed. You may need to override the measure method to calculate the width/height. If that's not the issue, then post some code so we can take a closer look. Hope that helps.
Because the Line Object is doing a bunch of checks and extra work you aren't doing when you use the Graphics object. Look at the code for spark.primitives.Line to see what its doing that you aren't.

What's the easiest way to create an extensible custom container in Flex?

I want to create an MXML container component that has some of its own chrome -- a standard query display, et al -- and that supports the addition of child components to it. Something a lot like the existing mx:Panel class, which includes a title label, but acts like a plain mx:Box with regards to adding children.
What's the easiest way to do this?
Edit:
To be clear, I want to be able to extend the container using MXML, so the "Multiple visual children" problem is relevant.
Extend a container and add a title label. Probably the <mx:Canvas/> will work here. Make the title a public var and include a var for the styleName of the label.
Then override the addChild() method so that any child that is added is added instead to the that is your container.
Leave enough space for your title when you position your Box element (i.e., give its y property enough space. If there is no title you may want to reclaim that space.
That's the basics. Customize to your heart's content.
EDITED TO ADD: I do this creating an ActionScript class first, extending the container I am targeting, and I add the "furniture" — items the class will always use, like title in your case — by overriding createChildren and calling super.addChild(item) for those items. Calling addChild from then on, even in MXML markup, adds items to the inner container.
We do this with states.
We put the chrome for the base container in a state (in mx:AddChild elements) and then use the initialize event to switch to that state when the control is created. All the chrome is then added to the container.
That gets round the multiple sets of visual children problem.
The downsides to this approach are:
You don't see the chrome when editing descendents of the base.
You can't directly access the parent chrome controls from descendent components as they are not there at compile time (instead, you need to define properties, methods or events on the base that the descendents can access)
However, it works well for us.

How do I enable autoresizing for a Flex UIComponent?

I have a class which extends UIComponent and draws directly onto a Sprite contained within. Currently I'm (probably incorrectly) listening to the Event.RESIZE event and drawing the contents when the width and height are non-zero. The problem is that even though I've passed percentage widths to the instance tag, it doesn't appear to be resized along with other Flex components on the page, certainly the resize event isn't being fired at all.
I've hacked it for the moment by binding the width and height to a container which does resize, but how should I really be handling this?
Update :
It turns out I was setting the width and height somewhere in the redraw method (I have no recollection of why I did this!). I shall go hang my head in shame now...
I think you need to provide more information. I'm doing exactly the same, and it works smoothly for me. Perhaps the answer lies somewhere else: e.g. exactly what type of container do you use? Isn't it possible that the space gained/lost on resizing gets allocated to some other component within the cointainer? Try substituting your own component with an mx:Box with some colored background, and see if that resizes with the container.

Any advice on 'breaking' an object out of its layout in Flex - for animation purposes?

If I have an object in a layout in Flex what is a good way to 'break it out' of that layout to be able to animate it.
For instance I have an image and a caption arranged at an angle. I want to make the image 'zoom out' slightly when the mouse rolls over it. Since its in a layout container is active if I were to resize it then obviously it would move around everything else.
I dont think I can achieve what I want by just setting includeinlayout=false.
Any experience with best practices on this?
My best idea I'm wondering about is making the image invisible and creating another image at the same location by using the screen coordinate conversion functions. This jsut semes clumsy
Wrap your object in a fixed size Canvas so that the layout upstream will remain the same. Then position the object manually within that container and then set its includeInLayout to false. At that point, you could do whatever you wanted with the interior object. Oh, also set clipContent to false. This should work whether you want it to grow or shrink.
If this is an itemrenderer or something that you've wrapped into a class, you could handle all of this in the class definition and make it transparent to consumers of the object. You'd also be able to write a mouseOver function that did what you wanted with the interior object that should zoom.

Resources