I have a Component that has a specific background image. The code looks like:
<mx:backgroundImage>#Embed(source='img1.png')</mx:backgroundImage>
<mx:states>
<mx:State name='state2'>
<mx:SetStyle name="backgroundImage">
<mx:value>#Embed(source='img2.png')</mx:value>
</mx:SetStyle>
</mx:State>
</mx:states>
But when I change the state to 'state2', it doesn't actually change anything.
Am I missing anything specific here?
The default target is the main app.
So you are actually setting the background of the entire app in state2 and not the Component.
Here is an example with the VBox
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:states>
<mx:State name="state2">
<mx:SetStyle name="backgroundImage" target="{VBox1}">
<mx:value>
#Embed(source='img2.jpg')
</mx:value>
</mx:SetStyle>
</mx:State>
</mx:states>
<mx:VBox id="VBox1" x="0" y="0" width="50%" height="50%">
<mx:backgroundImage>
#Embed(source='img1.jpg')
</mx:backgroundImage>
</mx:VBox>
</mx:Application>
Also if you are using Flex 3 Builder you can always switch to Design mode to see changes from Base state to a new state. It should be in the top right corner.
EDIT for components
Main file
<cbsh:BackSwitch>
</cbsh:BackSwitch>
</mx:Application>
Component
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
<mx:states>
<mx:State name="state2">
<mx:SetStyle name="backgroundImage" target="{this}">
<mx:value>
#Embed(source='img2.jpg')
</mx:value>
</mx:SetStyle>
</mx:State>
</mx:states>
<mx:backgroundImage>
#Embed(source='img1.jpg')
</mx:backgroundImage>
<mx:Button x="437" y="269" label="Switch!" click="currentState='state2';"/>
</mx:VBox>
I haven't dealt with this specifically, but my intuition is that it is having a problem with the way the value is set.
Have you tried this:
mx:setStyle setStyle name="backgroundImage value="#Embed(source='img2.png')" />
Because this seems to be kind of a weird error, my temporary solution is to have two canvases with different backgrounds that flip visibility depending on the state
Related
Inside my 3.6 Flex module, I am using a List with a custom ItemRenderer:
<mx:List id="chatsList" y="0" left="2" right="6"
width="100%" height="100%" dataProvider="{chatsArrayCollection}"
horizontalScrollPolicy="off" itemRenderer="MessageRendererModerated"
styleName="dataList" variableRowHeight="true" verticalScrollPolicy="auto" >
</mx:List>
When I add items to chatsArrayCollection at position 0, I want the list to scroll down and the new item to fade in nicely.
Something similar is shown here.
However, this doesn't work for me, and I suspect because I'm using custom itemRenderer.
MessageRendererModerated is defined as a canvas with some text and a link to an image:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" minHeight="94"
creationComplete="onCreationComplete();" resize="onResize();"
scaleY="1" width="100%"
horizontalScrollPolicy="off" blendMode="layer"
borderStyle="solid" borderThickness="0"
xmlns:rtl="views.rtl.*" > ...
I have tried different ways to solve this but none helped.
Many thanks!
UPDATE:
Following the comments I got below - I did try to use the itemsChangeEffect as mentioned in the example I found. However, it didn't work as expected.
I'm trying to set the hand cursor on an HBox. I've tried buttonMode and useHandCursor but have had no luck. This example displays the busy cursor. Can anyone tell me how to make it display the flashPlayer's hand cursor?
<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:components="com.dn2k.components.*" >
<fx:Script>
<![CDATA[
private var cursorID:int;
//cursorManager
protected function box_mouseOverHandler(event:MouseEvent):void
{
cursorManager.setBusyCursor()
}
]]>
</fx:Script>
<mx:HBox id="box" useHandCursor="true" buttonMode="true" mouseChildren="false" backgroundColor="0xcc0000" mouseOver="box_mouseOverHandler(event)">
<s:Label text="Hiya sexy..."/>
</mx:HBox>
This code shows it perfectly while mouse is over container:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<mx:HBox backgroundColor="0xcc0000" buttonMode="true" id="box" mouseChildren="false" useHandCursor="true">
<s:Label text="Hiya sexy..." />
</mx:HBox>
</s:Application>
If you want to set hand cursor in Label you must set mouseChildren=”false” and below is the revised code
<mx:HBox backgroundColor="0xcc0000" buttonMode="true" id="box" useHandCursor="true">
<s:Label text="Hiya sexy..." buttonMode="true" mouseChildren="false" useHandCursor="true" />
</mx:HBox>
Hope this works for you.
What Jeff said. Also you can use CursorManager.setCursor(). You'll have to embed a graphic for the cursor though.
You can also use the newer Mouse class which provides a higher frame rate native cursor.
<mx:HBox rollOver="Mouse.cursor = MouseCursor.BUTTON"
backgroundColor="0" backgroundAlpha="0"
rollOut="Mouse.cursor = MouseCursor.AUTO"/>
The background color and background alpha are used to draw out graphics that are used as the hit area. In empty Spark containers there is a mouseEnabledWhereTransparent property that I don't think existed in mx containers. Here is documentation on it:
When true, this property ensures that the entire bounds of the Group
respond to mouse events such as click and roll over. This property
only goes in to effect if mouse, touch, or flash player gesture events
are added to this instance. In addition, it assumes that the calls to
addEventListener()/removeEventListener() are not superfluous.
Having said that it seems that this works without setting the mouseEnabledWhereTransparent property:
<s:Group id="testingHitGroup" left="10" top="10"
rollOver="cursorObject_rollOver(event)" width="100" height="100"/>
Again, a theming question. Because the project I'm working on requires older libraries that extend mx components (such as TitleWindow and TabNavigator), I can't use what I know about Spark skinning directly. However, since the project is being programmed using the default Spark theme (with my modifications on top) rather than the Halo theme, I apparently don't have access to the styles I need (namely backgroundImage and contentBackgroundImage which apparently require Halo to be active). Simply setting Halo to be the theme will break other things, not the least of which my own theme. Plans are in the works to replace the older libraries or at least patch them better to Flex 4, but as of right now, I need a way to style/skin these components without modifying them directly.
It would be ridiculous to be unable to add a background image to a TitleWindow's content area! I've searched the internet high and low all day and tried countless variations of styles, skins, selectors, and combinations thereof with no luck. Doesn't anyone know how to add a background image to the content of a mx TitleWindow while using the Flex 4.1 sdk?!
Actually, it's not the only way, it's -as you've mentioned- the hardcoded way: sorry about that.
You can also skin your TitleWindow component to accept background images.
To create the appropriate skin with all the necessary states, you can copy the base skin: spark.skins.spark.TitleWindowSkin as MyTitleWindowSkin, and add some customization to it:
In the MetaData tag you should enter the name of your custom TitleWindow class:
<fx:Metadata>
<![CDATA[
[HostComponent("my.package.CustomTitleWindow")]
]]>
</fx:Metadata>
To accept backgroundImage,
you should declare a variable:
[Bindable] private var
backgroundImage:*;
override the
updateDisplayList(unscaledWidth,
unscaledHeight) method, and inside
of it initialize this member:
backgroundImage =
getStyle("backgroundImage");
in the <!-- layer 2: background fill
--> section, after the solid-color-fill (<s:Rect
id="background"...), you should put
the following snippet:
<s:Rect id="backgroundImg"
left="1" right="1"
top="{topGroup ? topGroup.height : 0}"
bottom="{bottomGroup ? bottomGroup.height : 0}">
<s:fill>
<!-- BackgroundImage -->
<s:BitmapFill id="img" source="{backgroundImage}"
smooth="true" fillMode="scale" />
</s:fill>
</s:Rect>
Next you need to create a new class (my.package.CustomTitleWindow), that extends TitleWindow, set its skin, and bind the backgroundImage style:
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
skinClass="my.package.MyTitleWindowSkin">
<fx:Metadata>
[Style(name="backgroundImage", type="*")]
</fx:Metadata>
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
at the end a small test (which worked fine at my side, and i hope it's closer to what you're looking for):
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<my:CustomTitleWindow title="Window without background image"
width="100%" height="50%" />
<my:CustomTitleWindow title="Window with background image"
width="100%" height="50%" backgroundImage="{IMyConstants.MYLOGO}" />
</s:VGroup>
Update
For setting the skin and the background image from a css file, you only need some minor modifications:
Create a CSS file with content:
/* CSS file */
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace my "your.package.*";
my|CustomTitleWindow {
skin-class: ClassReference("your.package.MyTitleWindowSkin");
}
.twWithBgImage {
background-image: Embed("icons/logo.png");
}
The test would look like:
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<my:CustomTitleWindow title="Window without background image"
width="100%" height="50%" />
<my:CustomTitleWindow title="Window with background image"
width="100%" height="50%" styleName="twWithBgImage" />
</s:VGroup>
and you need to remove the skin declaration from the CustomTitleWindow class: skinClass="your.package.MyTitleWindowSkin".
Of course you don't need to apply the skin to the my|CustomTitleWindow class, you could use it just for a css class, this way you surely don't need to modify your existing component.
Update -- without custom component
Forget the CustomTitleWindow class.
skinnedtw.css
/* CSS file */
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
.twWithBgImage {
skin-class: ClassReference("your.package.MyTitleWindowSkin");
background-image: Embed("icons/logo.png");
}
TestApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Style source="assets/skinnedtw.css" />
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<s:TitleWindow title="Window without background image"
width="100%" height="50%">
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
<s:TitleWindow title="Window with background image"
width="100%" height="50%" styleName="twWithBgImage">
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
</s:VGroup>
</s:WindowedApplication>
My output still looks like this:
if you don't have explicit members in your mx:TitleWindow, than you should consider using
a spark BorderContainer as its first child, since you can specify a background image to that.
i'm thinking of something like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="absolute"
width="400" height="300" backgroundAttachment="">
<s:BorderContainer backgroundImage="{IMyConstants.MYLOGO}"
width="100%" height="100%" backgroundAlpha=".5" />
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<mx:Button label="Do something" />
</mx:VBox>
</mx:TitleWindow>
i hope i understood your problem, and this helps.
I have made this short example to demonstrate some problems I'm having.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Canvas
id="buttonCanvas"
x="100" y="100" opaqueBackground="#000000" width="80%" height="300"
creationComplete="init(event)">
<mx:Button x="5" y="5"/>
<mx:Button x="5" y="50"/>
</mx:Canvas>
<mx:Script>
<![CDATA[
private function init(event:Event):void{
buttonCanvas.addEventListener(MouseEvent.ROLL_OUT, function(event:Event):void{
buttonCanvas.opaqueBackground=(buttonCanvas.opaqueBackground==0)? 0x666666:0;
});
}
]]>
</mx:Script>
</mx:Application>
I don't understand the following:
Why don't the percentage or absolute dimensions affect the canvas size?
Why does the roll_out event fire when the mouse leaves a button (even when it is still inside the canvas).
I'm going nuts trying to figure this out. Any help would be greatly appreciated!
Maybe you wanted to use backgroundColor style and not opaqueBackground property?
Just glancing at this, I can tell you that the default value for opaqueBackground is null, not 0.
I have a panel with a button in it. Clicking on the button will direct the panel to state "State2" adding another two buttons into the panel. During the state change, I want the panel to resize first and then show the newly added two buttons, so I applied transitions onto the state change.
My question is:
If I put the two buttons within a HBox directly under the addChild tag, it works fine. However, if I create a new component with the same code (HBox with two buttons in it) and then add the new component to the panel (Comp in the code commented), it won't show the resize effect.
Could someone tell me how to fix this? Thanks in advance.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*">
<mx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
currentState="State2";
}
]]>
</mx:Script>
<mx:transitions>
<mx:Transition>
<mx:Sequence targets="{[comp,panel1]}">
<mx:Resize target="{panel1}" />
<mx:AddChildAction />
</mx:Sequence>
</mx:Transition>
</mx:transitions>
<mx:states>
<mx:State name="State2">
<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:HBox id="comp">
<mx:Button label="B" />
<mx:Button label="C" />
</mx:HBox>
<!--<local:Comp id="comp" />-->
</mx:AddChild>
</mx:State>
</mx:states>
<mx:Panel layout="horizontal" borderThickness="1" borderStyle="solid" id="panel1" title="AB">
<mx:Button label="A" click="button1_clickHandler(event)"/>
</mx:Panel>
</mx:Application>
I guess <mx:AddChild> tag can handle only one component at a time.
You will get your sweet resize effect if you separate your custom component to another <mx:AddChild> tag, similar to the code below:
<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:HBox id="comp">
<mx:Button label="B" />
<mx:Button label="C" />
<!-- Don't put your custom component here. -->
</mx:HBox>
</mx:AddChild>
<!-- Use separated AddChild. Still add to same relativeTo object -->
<mx:AddChild relativeTo="{panel1}" position="lastChild">
<local:Comp id="comp2" />
</mx:AddChild>
I hope you got what you want.