Flex button skins return to default - apache-flex

I have a problem which involves skinned buttons returning to their default skins after certain actions occur in my application. Below I have included a partial screenshot where you can observe the problem.
The left button is returned to its default skin after it was clicked (the click triggers a state transition). The right button is the default skinned button. Note that my mouse is neither over nor pressing the left button.
The code for the Button Skin is as follows:
<?xml version="1.0" encoding="utf-8"?>
<fx:Metadata>
<![CDATA[
[HostComponent("spark.components.Button")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
import spark.components.Group;
static private const exclusions:Array = ["labelDisplay"];
override public function get colorizeExclusions():Array {return exclusions;}
override protected function initializationComplete():void
{
useChromeColor = true;
super.initializationComplete();
}
]]>
</fx:Script>
<s:states>
<s:State name="up" />
<s:State name="over" />
<s:State name="down" />
<s:State name="disabled" />
</s:states>
<s:Rect id="fill" left="1" right="1" top="1" bottom="1" radiusX="2">
<s:fill>
<s:LinearGradient rotation="270">
<s:GradientEntry color.down="#545454"
color.over="#444444"
color="#343434"
alpha="0.95"/>
<s:GradientEntry color.down="#767676"
color.over="#666666"
color="#565656"
alpha="0.95"/>
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Rect id="border" left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="3">
<s:stroke>
<s:SolidColorStroke id="borderStroke" weight="1" color="#343434" caps="round" joints="round" />
</s:stroke>
</s:Rect>
<s:Label id="labelDisplay"
textAlign="center" verticalAlign="middle" maxDisplayedLines="1" fontSize="12"
left="10" right="10" verticalCenter="0"
color="#FFFFFF" fontFamily="SegoeUI">
</s:Label>
Here's the code for the transition that is causing the problem:
<s:Transition fromState="State0" toState="State1">
<s:Sequence targets="{[contacts_nocontacts, contacts_list, button_contacts, button_add, button_delete, ac_vgroup]}">
<s:Parallel>
<s:Fade target="{contacts_nocontacts}" alphaFrom="1" alphaTo="0" duration="200" />
<s:Fade target="{contacts_list}" alphaFrom="1" alphaTo="0" duration="200" />
<s:Fade target="{button_add}" alphaFrom="1" alphaTo="0" duration="200" />
<s:Fade target="{button_delete}" alphaFrom="1" alphaTo="0" duration="200" />
</s:Parallel>
<s:RemoveAction targets="{[contacts_nocontacts, contacts_list, button_add, button_delete]}" />
<s:AddAction targets="{[button_contacts, ac_vgroup]}" />
<s:Parallel>
<s:Fade target="{button_contacts}" alphaFrom="0" alphaTo="1" duration="300" />
<s:Fade target="{ac_vgroup}" alphaFrom="0" alphaTo="1" duration="300" />
</s:Parallel>
</s:Sequence>
</s:Transition>

It looks like the skin is being set to the spark.skins.spark.DefaultButtonSkin (not to be confused with the normal Button skin - spark.skins.spark.ButtonSkin). This happens when you set emphasized="true" on the Button or that button is being used as a default Button in a Form.
See this thread for an example of how to customize the emphasized skin: http://forums.adobe.com/message/3811868

The problem is that the Skin is reset when focus is lost on a button that is set as Default button. It's standard behaviour, a quick fix can be found beneath (it's the same solution as the one Steven pointed out, but It's easier to have it on this actual page)
s|Button.emphasized {
skinClass: ClassReference("MyNewButtonSkin");
}
Just attach the same button skinClass on the emphasized style property of your button. The best way to do this the quickest is to do it with above CSS. On this way you can target all the buttons at once!

Related

Flex 4 button skin disabled alpha setting ignored?

I attempted to build a Flex 4 skin for a Spark button, typical practice. I adjusted the colors and other styles to my liking, including using dot selectors to specify alternate colors and such during different states. However, these are all ignored when the button is disabled. Regardless of what I do, in the disabled state, my button always has the wrong color and is alpha'd to 0.5 (even if I specifically state that alpha.disabled="1"). All the other skin states work as expected. What is going on here?
This is my custom skin. If it were working correctly, it would appear to have no shadow or highlight, and would be a gradient grey color. Instead, it appears as a 50% alpha version of the up state (shiny green).
<?xml version="1.0" encoding="utf-8"?>
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="21" minHeight="21" alpha.disabled="1">
<fx:Metadata>
<![CDATA[
[HostComponent("spark.components.Button")]
]]>
</fx:Metadata>
<s:states>
<s:State name="up" />
<s:State name="over" />
<s:State name="down" />
<s:State name="disabled" />
</s:states>
<s:Rect id="backgroundAndShadow" left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5">
<s:filters>
<s:DropShadowFilter blurX="5" blurY="5" blurX.down="3" blurY.down="3" alpha="0.5" distance="1" distance.down="0" angle="90" excludeFrom="disabled" />
</s:filters>
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color.up="#00AD00" color="#007A00" color.disabled="#cccccc" />
<s:GradientEntry color.up="#29FF29" color="#00F500" color.disabled="#bbbbbb" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Rect id="highlight" left="1" right="1" top="1" height="50%" topLeftRadiusX="4" topLeftRadiusY="4" topRightRadiusX="4" topRightRadiusY="4" excludeFrom="disabled">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="#ffffff" alpha="0.8" />
<s:GradientEntry color="#ffffff" alpha="0.3" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Label id="labelDisplay"
textAlign="center"
horizontalCenter="0" verticalCenter="1" verticalAlign="middle"
color="#ffffff" color.disabled="#555555"
fontWeight="bold"
left="2" right="2" top="2" bottom="2">
<s:filters>
<s:DropShadowFilter blurX="3" blurY="3" alpha="0.5" distance="1" distance.down="0" angle="90" excludeFrom="disabled" />
</s:filters>
</s:Label>
</s:SparkButtonSkin>
I also did this with an automatically generated skin for the Button using Flash Builder's skin creation wizard/dialog. Even then, specifically setting the alpha to 1 in disabled mode had no effect.
Edit
This is the code used to create and then disable the button:
_action1Button = new Action1Button();
view.actionGroup.addElement(_action1Button);
_action1Button.enabled = false;
The error was that _action1Button is not the actual button, rather, it's the container of the button. Doh! Switching it to _action1Button.actionButton.enabled = false; fixed the issue.
Your skin works fine for me. I get a green button in the enabled state then a grey gradient without drop shadow when enabled is false. I tested it like this (where TestSkin is your skin posted above):
<s:Button skinClass="TestSkin" enabled="false" />
I assume the problem has to do with how you are using the skin. Can you post the code where the button itself is defined?

move chromeless windowedapplication on drag in flex 4

I have implemented a chromeless windowedapplication in flex 4. But doing so i noticed that all the maximize, minimize and even the ability to drag the window around is gone. I need the ability to drag the window around. I have done a lot of googling and have been unable to come up with anything. Could somebody plz point me in the right direction.
Thanks in advance.
You'll have to create a custom skin for your WindowedApplication. If you look in the code of WindowedApplication, you'll find this:
[SkinPart (required="false")]
public var titleBar:TitleBar;
which means you can add a TitleBar to the skin, but you don't have to. As a matter of fact the default WindowedApplicationSkin doesn't have a titleBar.
Including a TitleBar in the custom skin will automatically give you the dragging behavior you're after. The default TitleBarSkin comes with the regular window buttons (minimize, maximize, close), so you may want to create a custom skin here too. One without the buttons if you don't need them.
Here's a stripped down example.
The custom skin for WindowedApplication (just a white background and a TitleBar):
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" >
<fx:Metadata>[HostComponent("Object")]</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalAndInactive" />
<s:State name="disabledAndInactive" />
</s:states>
<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0" >
<s:fill>
<s:SolidColor id="backgroundFill" color="0xffffff" />
</s:fill>
</s:Rect>
<s:TitleBar left="0" right="0" top="0" height="24"
skinClass="skin.TitleBarSkin" />
<s:Group id="contentGroup" left="0" right="0" top="25" bottom="0" />
</s:Skin>
The custom skin for your TitleBar (just a gradient background and a close button):
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
minHeight="24" >
<fx:Metadata>
[HostComponent("spark.components.windowClasses.TitleBar")]
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalAndMaximized" />
<s:State name="disabledAndMaximized" />
</s:states>
<s:Rect id="background" left="0" right="0" top="0" bottom="0">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xFFFFFF" />
<s:GradientEntry color="0xBABABA" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Button id="closeButton" label="close" right="0" verticalCenter="0" />
</s:Skin>
Apparently, the 'closeButton' is required, so you'll have to include it in the skin. But if you still want to get rid of it, just set its 'visible' and 'includeInLayout' properties to 'false'.

how can i select childern node in flex tree component?

If i want check parent node checkbox means below childerns checkbox will select automatic .
this is my code:
<fx:Script>
<![CDATA[
private function init():void {
httpTree.send();
}
]]>
</fx:Script>
<fx:Declarations>
<s:HTTPService id="httpTree" url="Assets/World.xml"
resultFormat="e4x" useProxy="false" />
</fx:Declarations>
<mx:Tree dataProvider="{httpTree.lastResult.department}"
id="treeTree" labelField="#name"
itemRenderer="com.ItemRenderForTree" width="160" height="200" />
itemRenderer file
<fx:Script>
<![CDATA[
protected function checkboxSelectHandler(event:Event):void
{
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">
<s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Group id="disclosureGroup">
<s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
</s:Group>
<s:BitmapImage source="{treeListData.icon}" />
<s:CheckBox change="checkboxSelectHandler(event)" />
<s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
</s:HGroup>
any one can help thanks....
Use tree dataDescriptor to access children nodes of clicked parent node. Maybe that could help? Does your three data have a selected property in datamodel?
You're looking for what I've always called a Schrodinger Check Box. Here is a same piece of code, including a working demo and the PNG resources for the checkbox over at adobe.
Schrodinger Check Box

In Flex 4, state transition doesn't resize in both directions (v2)

I already had another question on this issue which was successfully resolved. But now, with a slightly different example, I'm stuck again.
I have two states. When I switch from A to B, it resizes correctly, but when I switch from B back to A it happens without the smooth resize transition. What am I doing wrong?
Here's my code:
<fx:Script>
<![CDATA[
protected function rollOverHandler(event:MouseEvent):void
{
this.currentState = "AB";
}
protected function rollOutHandler(event:MouseEvent):void
{
this.currentState = "A";
}
]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>
<s:states>
<s:State name="A" />
<s:State name="AB" />
</s:states>
<s:transitions>
<s:Transition fromState="A" toState="AB" autoReverse="true">
<s:Parallel>
<s:AddAction target="{controls}"/>
<s:Resize duration="500" target="{controls}" heightFrom="0" />
</s:Parallel>
</s:Transition>
<s:Transition fromState="AB" toState="A" autoReverse="true">
<s:Parallel>
<s:Resize duration="500" target="{controls}" heightTo="0" />
<s:RemoveAction target="{controls}"/>
</s:Parallel>
</s:Transition>
</s:transitions>
<s:BorderContainer width="300"
backgroundColor="#eeeeee"
borderVisible="false"
minHeight="0">
<s:layout>
<s:VerticalLayout gap="0"/>
</s:layout>
<s:VGroup id="data">
<s:Label text="A" fontSize="40" />
</s:VGroup>
<s:VGroup id="controls"
clipAndEnableScrolling="true"
itemCreationPolicy="immediate"
includeIn="AB">
<s:Label text="B" fontSize="40" />
</s:VGroup>
</s:BorderContainer>
</s:HGroup>
Thanks in advance,
Nuno
You need to use a Sequence instead of a Parallel.

Flex viewstack children includeIn works funny

I have a viewstack with childrens which I want to show/hide depending on the state the application is
<?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"
xmlns:eworx="com.eworx.*"
xmlns:view="com.eworx.view.*"
xmlns:components="com.eworx.view.components.*"
skinClass="com.eworx.view.skins.MainAppSkin"
xmlns:layouts="com.eworx.view.layouts.*"
currentState="login"
initialize="init(event)"
creationComplete="complete(event)"
width="100%"
height="100%">
<fx:Style source="assets/css/screen.css" />
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import nl.demonsters.debugger.MonsterDebugger;
private var debugger:MonsterDebugger;
[Bindable]
public var apiUrl:String;
[Bindable]
public var customerType:String;
protected function init(event:FlexEvent):void
{
debugger = new MonsterDebugger(this);
}
protected function complete(event:FlexEvent):void
{
var activated:Boolean = FlexGlobals.topLevelApplication.parameters.activated;
var passwordReset:Boolean = FlexGlobals.topLevelApplication.parameters.passwordReset;
var message:String = FlexGlobals.topLevelApplication.parameters.message;
apiUrl = FlexGlobals.topLevelApplication.parameters.apiUrl;
if(activated)
{
Alert.show(message,"Notice");
}
if(passwordReset)
{
Alert.show(message,"Notice");
}
systemManager.addEventListener(MouseEvent.MOUSE_WHEEL,onMouseWheel,true);
}
private function onMouseWheel(e:MouseEvent):void
{
e.delta *= 5;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<eworx:Seven7Context contextView="{this}" />
<s:Fade id="fadeIn" alphaFrom="0" alphaTo="1" duration="300" />
<s:Fade id="fadeOut" alphaFrom="1" alphaTo="0" duration="300" />
<s:Rotate3D id="r3d" angleYFrom="0" angleYTo="360" duration="300" />
</fx:Declarations>
<s:states>
<s:State name="login" />
<s:State name="wholesale" />
<s:State name="retail" />
</s:states>
<view:LoginForm id="loginForm" includeIn="login" horizontalCenter="0" verticalCenter="0" />
<s:Group excludeFrom="login" width="960" horizontalCenter="0">
<s:BitmapImage width="100%" height="42" x="13" y="80" source="#Embed('assets/garnish/bar.png')" />
<mx:Image source="assets/garnish/logo.png" top="23" />
<s:HGroup verticalAlign="middle" x="198" y="47">
<s:TabBar skinClass="MainMenuTabBarSkin" dataProvider="{vs}" buttonMode="true"/>
<mx:LinkButton id="logout" label="Logout" click="{currentState='login'}" />
</s:HGroup>
<s:HGroup top="0" right="0" gap="1" verticalAlign="top">
<components:OfferList />
<components:MarginBuildersTrack />
<components:CartTrack top="0" />
</s:HGroup>
<mx:ViewStack
id="vs"
top="120"
horizontalCenter="0"
width="960"
height="100%"
resizeToContent="true" >
<view:HomePage showEffect="{fadeIn}" hideEffect="{fadeOut}" label="Home" />
<view:ShowroomPage showEffect="{fadeIn}" hideEffect="{fadeOut}" label="Showroom" />
<view:CataloguePage showEffect="{fadeIn}" hideEffect="{fadeOut}" label="Catalogue" />
<!--<view:IncentivesPage showEffect="{fadeIn}" hideEffect="{fadeOut}" label="Incentives" />-->
<view:RetailCustomerProfilePage includeIn="retail" showEffect="{fadeIn}" hideEffect="{fadeOut}" label="My Profile" />
<view:WholesaleCustomerProfilePage includeIn="wholesale" showEffect="{fadeIn}" hideEffect="{fadeOut}" label="My Profile" />
<view:ClientsPage excludeFrom="retail,login" showEffect="{fadeIn}" hideEffect="{fadeOut}" label="My Clients" />
<view:CartPage showEffect="{fadeIn}" hideEffect="{fadeOut}" label="My Cart" />
<view:OrdersPage showEffect="{fadeIn}" hideEffect="{fadeOut}" label="My Orders" />
</mx:ViewStack>
</s:Group>
</s:Application>
AS you can see I inlude the retail customer view in the retail state and the wholesale customer view in the wholesale state. The problem is that when I run my app they don't appear on neither state.
Any ideas?
This is an odd approach to me. The whole purpose of the ViewStack is to only show one item at once. This is a very odd approach.
I see you have a tabbar whose dataProvider is the ViewStack. However, your ViewStack is not created as a bindable property on the component, and you never seem to set up an initial state. So, I theorize that this is happening:
App Loads in default state, which is the empty string
ViewSTack and/or TabBar are initialized without those children
App state changes for some reason
TabBar does not update
CreationPolicy may come into play too, but I'm not sure. You'll have to step through the code to figure out what's going on. I would strongly recommend you consider an alternate approach to this. Possibly creating the tabbar navigator dataProvider manually based on user security settings or the current state.

Resources