Unable to Align data in Datagrid - actionscript-3

Hi I have issue with alignment of data in the spark datagrid column after Rendering. All the headers are aligned towards left, however i would like to do the following
1. Middle the column header name.
2. Align the text to right.
3.Freeze the first column so that when i do horizontal scroll, the first column should not move horizontally.
Any help in this regard would be highly grateful.
Thanks and regards
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
clipAndEnableScrolling="true">
<fx:Script>
<![CDATA[
import flashx.textLayout.formats.BackgroundColor;
import mx.controls.Alert;
import mx.states.SetStyle;
private const POSITIVE_COLOR:uint = 0x000000; // Black
private const NEGATIVE_COLOR:uint = 0xFF0000; // Red
override public function prepare(hasBeenRecycled:Boolean):void {
if (this.data) {
if (column.labelFunction != null ) {
lblData.text = column.labelFunction( data, column );
setStyle("color", (parseInt(this.data.st1) < 0) ? NEGATIVE_COLOR : POSITIVE_COLOR);
} else {
lblData.text = data[column.dataField];
}
}
}
]]>
</fx:Script>
<s:Label id="lblData" top="9" left="7" textAlign="right"/>
</s:GridItemRenderer>

2/ Align the text to right.
I'll start with the easiest one.
In your custom item renderer, you're still aligning to the left (left="7"). You have two options to fix this:
<s:Label id="lblData" top="9" right="7"/>
will align the Label to the right and cause text overflow to the left
<s:Label id="lblData" top="9" left="7" right="7" textAlign="right"/>
will make the Label take all the available space, align the text to the right and truncate the text if it's too big
1/ Middle the column header name.
I think the only way is to create a custom headerRenderer.
copy the entire DefaultGridHeaderRenderer
find the Label with id "labelDisplay"
change its textAlign property to center
assign the custom headerRenderer:
<s:GridColumn headerRenderer="path.to.CenteredHeaderRenderer"/>
3/ Freeze the first column so that when i do horizontal scroll, the first column should not move horizontally.
I'm afraid this is going to require some serious hacking. If you don't want to dive in and create a customized DataGrid, I think your best bet is to fake it:
create a List to represent the fixed column
create a DataGrid to represent the other columns
turn off the List's vertical scrollbar: you wanna controll the scrolling through the grid
bind their vertical scrolling position: when the DataGrid is vertically scrolled, the List must follow and vice-versa
bind their selected items
do some skinning to make it look like one DataGrid

Related

ItemRenderer Objects Changing Properties

Apologies for the vague title. I could not think of a better way to word it in so few words.
Basically, I am creating a custom ItemRenderer (IR). The IR has a label on the left side and an icon on the right side. The icon on the right side is dynamic (can be either an add or remove icon or nothing at all). This works beautifully and gives me the control I need over it.
Now, the problem is that when I scroll the list in my mobile application, the icons change.
How it should look:
How it looks after scrolling using a finger (or mouse in emulator) by dragging on Test3:
As you can see, the icons change but the labels do not. I have dragEnabled, dropEnabled, and dragMoveEnabled all set to false on my Spark List component. The only time the icon selection runs is on creationComplete, so there is no way it is choosing a different icon at some point. I can also verify that the data itself is what it should be after this change occurs.
Here is the MXML that creates the item:
<s:HGroup width="100%" verticalAlign="middle" left="{this.sideSpacing}" right="{this.sideSpacing}" top="{this.sideSpacing}" bottom="{this.sideSpacing}">
<s:Label id="text" width="100%"/>
<s:Image id="actionIcon" buttonMode="true" click="actionIconClick( event );">
<s:filters>
<s:DropShadowFilter alpha=".45" angle="90" distance="3" blurX="3" blurY="3" quality="3"/>
</s:filters>
</s:Image>
</s:HGroup>
<s:Rect width="100%" height="1" bottom="0" alpha=".1">
<s:fill>
<s:SolidColor color="#000000"/>
</s:fill>
</s:Rect>
And the possibly over-elaborate AS3 for selecting which icon should be displayed:
private function creationComplete( e:Event ):void {
if ( this.data.actionIcon != null ) {
this.actionIconType = this.data.actionIcon;
if ( this.data.actionIcon == ACTION_ICON_ADD ) {
this.actionIcon.source = this.addBitmapSource;
}
else if ( this.data.actionIcon == ACTION_ICON_REMOVE ) {
this.actionIcon.source = this.removeBitmapSource;
}
else {
this.actionIcon.source = null;
this.actionIcon.visible = false;
this.actionIcon.includeInLayout = false;
}
}
else {
this.actionIcon.source = null;
this.actionIcon.visible = false;
this.actionIcon.includeInLayout = false;
}
}
What could be causing this issue?
Basically, you need to update your renderer's label and icon when the dataChange event is fired. CreationComplete is only fired once. The list isn't really scrolled, just that the data in the itemRenderers change; causing it to look like things are scrolling. I call this renderer recycling.
Here is a component I created for a mobile app that does what you want. It displays a label and an icon (AKA the Decorator). When scrolling the label and icon are both updated. You can use a very similar approach.
<?xml version="1.0" encoding="utf-8"?>
<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
dataChange="onDataChange(event)" alpha=".7" width="100%" cacheAsBitmap="true">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.dotcomit.magondaMaze.managers.BoardDataManager;
import com.dotcomit.magondaMaze.managers.StatManager;
import mx.events.FlexEvent;
[Embed(source="assets/images/chooseLevel/completed78x78.png")]
private var completedImage:Class;
public var statManager :StatManager = StatManager.instance;
protected function onDataChange(event:FlexEvent):void
{
var itemAsXML :XML = data as XML;
var results :String = itemAsXML.#id + '. ' + itemAsXML.#title;
label = results;
if( statManager.isBoardComplete(itemAsXML.#id)){
this.decorator = completedImage;
} else {
this.decorator = null;
}
}
]]>
</fx:Script>
</s:IconItemRenderer>
I'll also add that the IconItemRenderer component--which my code above extends--is designed to do exactly what you need. So, you may not have to re-write the wheel so to speak.

Effects for TextArea letters (Flex)

How do I add effects (shadow, glow) to all letters in the component TextArea (Spark 4)?
I see it is an old question, but since i fell in the same problem today i'm posting my solution.
You can access to the RichEditableText component of the TextArea using textDisplay as stated here:
The RichEditableText can be accessed as textDisplay and the Scroller
as scroller
RichEditableText is extended from UIComponent, so filters, which can be applied to UIComponents ("You can apply filters to any visual component that is derived from UIComponent"), can be applied to it.
In order to apply, for example, a DropShadowFilter to all letters in the component myTextArea:TextArea i have used the following lines of code:
var richTextComponent:UIComponent = myTextArea.textDisplay as UIComponent;
var shadow:spark.filters.DropShadowFilter = new spark.filters.DropShadowFilter;
richTextComponent.filters = [shadow];
Hope this helps someone :-)
I don't think you can do it using Flex (or at least I never have). You would need to do it using AS3
<s:Label id="label1" text="Shadow Me" />
<fx:Script>
<![CDATA[
import flash.filters.*;
private function creationComplete():void{
var dropshadow:DropShadowFilter = new DropShadowFilter( 3,90,0x000000,.5,4,4,3,3 );
this.label1.filters = [ dropshadow ];
}
]]>
</fx:Script>
contentBackgroundAlpha="0" borderVisible="false"
By using Filter class we can apply shadow glow effect for a s:TextArea component. The sample code is:
<s:TextArea contentBackgroundAlpha="0" borderAlpha="0">
<s:filters>
<s:DropShadowFilter distance="5" angle="45" color="#666666"/>
</s:filters>
<s:content>
Testing text area content
</s:content>
</s:TextArea>
Refer the link http://www.roseindia.net/tutorial/flex/flex4/components/filters.html for applying more filters (DropShadowFilter, GlowFilter, BlurFilter and BevelFilter).
Just add a skin to your TextArea component then add a shadow to the RichEditableText inside the skin.
<fx:Declarations>
<s:DropShadowFilter id="shadow2"/>
</fx:Declarations>
<s:RichEditableText id="textDisplay" heightInLines="10" widthInChars="15" filters="{[shadow2]}"/>
It worked for me, you have just to adjust the shadow to have a nice look.

Flex Element wrongly keeps properties from previous parent - how do I reset it?

I want to put an element into another component (in this case a print template), print it, and then return it to its place. The problem is that when I return it, it has the properties of the print template! Here is a simplified example. When you click print, the label is removed and then returned but when returned it is affected by the padding of the print template! Why? How can I somehow refresh it to its proper properties? I tried all the invalidate... methods and parentChanged() but nothing worked.
<?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" width="400" height="200">
<fx:Script>
<![CDATA[
import spark.components.VGroup;
protected function button1_clickHandler(event:MouseEvent):void {
var printTemplate:VGroup = new VGroup();
printTemplate.paddingTop = 50;
printTemplate.paddingLeft = 30;
printTemplate.addElement(label);
addElement(printTemplate);
validateNow();
// print
removeElement(printTemplate);
addElement(label);
}
]]>
</fx:Script>
<s:Button label="Print" right="0" click="button1_clickHandler(event)"/>
<s:Label id="label" text="This is the label text, it should appear at the top-left."/>
</s:Application>
I would recommend you to have a separate print view-component which has a separate label which you only need to pass the right data.
OK I hacked up a solution. Put this in before adding the label back to its proper place:
var vg:VGroup = new VGroup();
vg.addElement(label);
addElement(vg);
validateNow();
removeElement(vg);
Then it gets the padding from "vg", which has no padding set. Yay. Another little hack to circumnavigate a Flex bug.

Flex 4 spark Panel has an ugly gray top part

I have a Flex 4 spark Panel I'm popping up through the PopUpManager, but it has a gray portion at the top I can't get rid of. What is that and how can I remove it?
UPDATE: An example Panel is below. I simply call PopUpManager.addPopUp(new TestPanel(), background, true); on it and receive that solid gray bar above the button.
<s:Panel xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009"
dropShadowVisible="false"
backgroundAlpha="0"
controlBarVisible="false"
borderVisible="false">
<s:VGroup>
<s:Button label="A button" width="150" height="55"/>
</s:VGroup>
</s:Panel>
So, this is how I did it. I made a custom skin: HeaderlessPanelSkin.as
public class HeaderlessPanelSkin extends PanelSkin {
public function HeaderlessPanelSkin() {
super();
topGroup.includeInLayout = false;
}
}
Then, in the panel, I just reference the new skin: skinClass="HeaderlessPanelSkin"
That should do it :)
Create new skin, and in the panel declaration use it... like so
File->New MXML Skin, Host Component is panel.
Edit the Skin properties to change it how you like, in this case the gradient colors on the header.
Sounds like the Panel TitleBar
Create a custom skin and style the title bar how you want it to appear.

Place an 'addChild' button into grid space of TabNavigator

This question is similar to the post:
"Move Button into grid space of a TabNavigator’s tabs in Flex Builder."
Move Button into grid space of a TabNavigator's tabs in Flex Builder
but with a slight difference. I wish to have a button that adds a child (tab) to the TabNavigator in the grid space (simpler with TabBar, but see below), but will not block tabs as they extend towards the button. This functionality can be seen in every web browser that uses tabs.
In addition I would like to have a scroll button appear if too many tabs are opened, and the ability to close tabs. I have tried using Doug McCune's SuperTabNavigator, which offers most of these features, but it does not offer the addChild button that I am looking for.
Is there a way to add this 'addChild' button to the grid space, or to add the features from SuperTabNavigator to TabBar?
This class will do the trick except for scrolling when there are too many tabs.
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="500" height="400">
<mx:HBox width="100%">
<mx:TabBar dataProvider="{viewstack}"/>
<mx:Button label="+" width="35" click="addTab()"/>
</mx:HBox>
<mx:ViewStack height="100%" width="100%" id="viewstack"/>
<mx:Script>
<![CDATA[
import mx.controls.Label;
import mx.containers.Panel;
//add a new container
private function addTab():void
{
var l:Label = new Label();
l.text = "Panel " + (viewstack.numChildren + 1);
var p:Panel = new Panel();
p.label = l.text;
p.addChild(l);
viewstack.addChild(p);
viewstack.selectedChild = p;
}
]]>
</mx:Script>
</mx:VBox>