I have a few different views & screens which all use a few variants of Group, VGroup or HGroup and to have them laid out correctly, I find myself having to write and rewrite again with either
gap="0"
or with TileLayout
horizontalGap="0" verticalGap="0"
to get them all to layout correctly, and how I want. Currently the only option I see of being able to set them to zero globally is to set up a heavy global listener, ie.
protected function globalListener():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, true);
}
protected function onAddedToStage(event:Event):void
{
var g:Group = event.target as Group;
if(g)
{
if( g.layout.hasOwnProperty('gap') )
{
g.layout['gap'] = 0;
}
else
{
var l:TileLayout = g.layout as TileLayout;
if(l)
{
l.verticalGap = l.horizontalGap = 0;
}
}
}
}
or creating a new package with these layouts, and adding gap=0 to them,
package overrides.gapless
{
import spark.components.HGroup;
public class HGroup extends spark.components.HGroup
{
public function HGroup()
{
gap = 0;
}
}
}
and
package overrides.gapless
{
import spark.layouts.TileLayout;
public class TileLayout extends spark.layouts.TileLayout
{
public function TileLayout()
{
horizontalGap = 0;
verticalGap = 0;
}
}
}
and the like. I've checked the source code of the relevant files (mainly VerticalLayout, HorizontalLayout and TileLayout) and can see the values hardcoded in, but still can't fully believe there's no other way to do it.
I've only recently started delving into Flex, and am loving it's skinning options, but am a bit mystified about this one.
Thanks for any and all help as to how to do this.
Related
when i use the following tree renderer class the the informtions in the tree gets chopped. Is there any solution to fix this bug. please help me.
The PLTree class is as follows:
import flash.events.Event;
import mx.events.ScrollEvent;
import mx.controls.Tree;
import mx.core.ScrollPolicy;
import mx.core.mx_internal;
import mx.events.TreeEvent;
public class PLTree extends Tree
{
private var _lastWidth:Number = 0;
private var _lastHeight:Number = 0;
public function PLTree() {
super();
horizontalScrollPolicy = ScrollPolicy.AUTO;
}
override public function get maxHorizontalScrollPosition():Number
{
return mx_internal::_maxHorizontalScrollPosition;
}
override public function set maxHorizontalScrollPosition(value:Number):void
{
mx_internal::_maxHorizontalScrollPosition = value;
dispatchEvent(new Event("maxHorizontalScrollPositionChanged"));
scrollAreaChanged = true;
invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
var diffWidth:Number = measureWidthOfItems(0,0) - (unscaledWidth - viewMetrics.left - viewMetrics.right);
if (diffWidth <= 0) {
maxHorizontalScrollPosition = 0;
horizontalScrollPolicy = ScrollPolicy.OFF;
} else {
maxHorizontalScrollPosition = diffWidth;
horizontalScrollPolicy = ScrollPolicy.ON;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
override protected function scrollHandler(event:Event):void
{
if (mx_internal::isOpening)
return;
// TextField.scroll bubbles so you might see it here
if (event is ScrollEvent){
super.scrollHandler(event);
invalidateDisplayList();
}
}
}
i am attaching the image file of how it looks when executed.
When surfing using google i found a suggesion to fix this bug is it the right way ?
(
Issue: Text getting chopped of at end.
Fix: change
maxHorizontalScrollPosition = diffWidth;
to
maxHorizontalScrollPosition = diffWidth + 10;
or what ever correction factor you need.
)
Kindly help me .Thanks a lot in advance.
Looking at your picture, I'd suspect the issue has nothing to do with the specific tree, and is only slightly related to the renderer. Instead, I think that when the container holding the Tree is created, it doesn't have a size, and when the Tree sizes its renderers, it gives them the wrong size. Since List-based controls don't set the actual width on renderers, choosing to set explicitWidth instead, the renderers aren't triggered into changing their size.
Check out http://www.developria.com/2009/12/handling-delayed-instantiation-1.html for more explicit details and fixes.
similar to the scroll handler in the above mentioned program. Use a mouse wheel scroll handler to handle that event as follows:
override protected function mouseWheelHandler(eventMouse:MouseEvent):void
{ if (mx_internal::isOpening)
return;
if (eventMouse is MouseEvent){
super.mouseWheelHandler(eventMouse);
invalidateDisplayList();
}
}
This is the code that i compiled using mxmlc the free flex sdk. It compiled and i ran it. Helloworld not displayed
package
{
import org.flixel.*;
public class PlayState extends FlxState
{
override public function create():void
{
add(new FlxText(0,0,100,"Hello, World!")); //adds a 100x20 text field at position 0,0 (upper left)
}
}
}
Expected output is = HelloWorld. But is not displayed
You'll need to provide an FlxGame subclass too. It may be easiest for you to take an existing Flixel project that works out of the box such as AdamAtomic's HelloWorld and modify it to suit your needs.
Try this instead:
package
{
import org.flixel.*;
public class HelloWorld extends FlxState
{
private var title_text:FlxText;
public function HelloWorld() { }
override public function create():void
{
title_text = new FlxText(20, 0, 300, 'Lunarium');
title_text.setFormat(null, 50, 0xffffffff, "center");
add(title_text);
}
override public function update():void
{
if(FlxG.keys.X)
{
FlxG.fade(0xff131c1b, 1, onFade);
}
super.update();
}
protected function onFade():void
{
//FlxG.switchState(new SmallPlay2());
}
}
}
There are plenty of tool tips to help you figure out what the different settings mean. I found flixel rather easy to use coming from a Multimedia Fusion 2 background.
Enjoy!
I'm trying to set the height of a vertical bar (activityBar) but it does not appear to do anything. i have tried something similar with the whole component, but setting the dimensions does nothing (even in the mxml used to instantiate the class). Indeed, I've added transparent graphics just to give the component some dimensions
I'm not sure what I'm doing wrong. It's something bad though; my approach seems dire.
FYI: I'm trying to create a mic activity bar that will respond to the mic by simply setting the height of the activityBar child (which seems to me to be more efficient than redrawing the graphics each time).
Thanks for your help!
package components {
import mx.core.UIComponent;
public class MicActivityBar extends UIComponent {
public var activityBar:UIComponent;
// Constructor
public function MicActivityBar() {
super();
this.opaqueBackground = 0xcc4444;
graphics.beginFill(0xcccccc, 0);
graphics.drawRect(0,-15,5,30);
graphics.endFill();// background for bar
activityBar = new UIComponent();
activityBar.graphics.beginFill(0xcccccc, 0.8);
activityBar.graphics.drawRect(0,-15,5,20);
activityBar.graphics.endFill();
activityBar.height=10;
addChild(activityBar);
}
}
}
package components {
import mx.core.UIComponent;
public class MicActivityBar extends UIComponent {
public var activityBar:UIComponent;
private var _w:Number;
// Constructor
public function MicActivityBar() {
super();
this.opaqueBackground = 0xcc4444;
graphics.beginFill(0xcccccc, 0);
graphics.drawRect(0,-15,5,30);
graphics.endFill();// background for bar
activityBar = new UIComponent();
activityBar.graphics.beginFill(0xcccccc, 0.8);
activityBar.graphics.drawRect(0,-15,5,20);
activityBar.graphics.endFill();
activityBar.height=10;
addChild(activityBar);
}
public function get w():Number {
return _w;
}
public function set w(value:Number):void {
_w = value;
}
override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
this.height=w;
this.weight=w;
}
}
}
See my updated code above.
package {
import mx.controls.LinkButton;
import flash.text.TextLineMetrics;
public class multiLineLinkButton extends LinkButton {
override protected function createChildren():void {
super.createChildren();
if (textField){
textField.wordWrap = true;
textField.multiline = true;
}
}
override public function measureText(s:String):TextLineMetrics {
textField.text = s;
var lineMetrics:TextLineMetrics = textField.getLineMetrics(0);
lineMetrics.width = textField.textWidth;
lineMetrics.height = textField.textHeight;
return lineMetrics;
}
}
my issue here is if you use this component you will see that the text is bunched up into a very small area. It does not fill the entire width of the linkButton. Anyone know why this is happening?
The container is probably not wide enough. Set the container percentWidth to 100 and see if it fixes your problem. You can also set the LinkButton to a fixed width and see if that helps.
How would one create a custom MXML component in flex which is based on an existing component but draws an overlay over this existing component in certain situations.
Ideally, the new component should be based on (derive from) the exiting component so that occurrences of the existing component could just be swapped out with the new one.
I tried to override updateDisplayList() in the new component and to paint the overlay using this.graphics. This resulted in the overlay being drawn underneath the children of the existing component. I also tried to do the drawing upon receiving a render-event which lead to similar results.
When the external condition which should trigger the display of the overlay changes, I call invalidateDisplayList() on my new component. That works to trigger the drawing for both cases described above. The remaining problem seems to be to figure out how to draw on top of all the other components once they are added.
The following example should illustrate what I tried to do; when overlayEnabled was set and the component's invalidateDisplayList() method was called, the red rectangle would get painted in the background....
// NewComponent.mxml
<ExistingComponent ...>
<mx:Script>
...
public var overlayEnabled:Boolean;
override protected updateDisplayList(...) {
super.updateDisplayList(...)
if (overlayEnabled) {
var g:Graphics = this.graphics;
g.beginFill(0xFF0000, 0.5);
g.drawRect(0, 0, width, height);
g.endFill();
}
}
...
</mx:Script>
</ExistingComponent>
Also, feel free to suggest different approaches.
You will have to add a DisplayObject for you overlay and insure when you call updateDisplayList that it is place on the top of the other.
public var overlayEnabled:Boolean;
public overlayHolder:(whatever display object you want to use)
override protected updateDisplayList(...) {
super.updateDisplayList(...)
if (overlayEnabled) {
if (overlayHolder.parent != this){
addChild(overlayHolder);
} else {
if (numChildren > 0)
setChildIndex(overlayHolder, numChildren-1);
}
var g:Graphics = overlayHolder.graphics;
g.beginFill(0xFF0000, 0.5);
g.drawRect(0, 0, width, height);
g.endFill();
} else if (overlayHolder.parent == this) {
removeChild(overlayHolder);
}
}
Edit:
One property you can use to add your overlay to the display list can be the rawchildren:
package {
import flash.display.Graphics;
import flash.display.Sprite;
import mx.containers.VBox;
public class MyVBox extends VBox {
public var overlayEnabled : Boolean = true;
public var overlay : Sprite = new Sprite();
public function MyVBox() {
super();
}
protected override function updateDisplayList(unscaledWidth : Number, unscaledHeight : Number) : void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (overlayEnabled) {
if (overlay.parent != this) {
rawChildren.addChild(overlay);
} else {
if (rawChildren.numChildren > 0)
rawChildren.setChildIndex(overlay, rawChildren.numChildren - 1);
}
var g : Graphics = overlay.graphics;
g.beginFill(0xFF0000, 0.5);
g.drawRect(0, 0, width, height);
g.endFill();
} else if (overlay.parent == this) {
rawChildren.removeChild(overlay);
}
}
}
}