How to add a background gradient to an Application? - apache-flex

I'm a Flex newbie and am porting a pure Flash/AS3 application to Flex 4.5.
In my original Flash/AS3 application I had a Sprite acting as a background. I put it underneath all other DisplayObjects and fill it with a linear gradient of random color. It looked good and seemed to work well with Flash Components (Buttons, Checkboxes, TexFields), because they are transparent.
So in my new Flex program (with BasicLayout), I've tried creating a Rect too:
<s:Rect left="0" top="0" right="0" bottom="0">
<s:stroke>
<s:LinearGradientStroke id="_bgcolor" rotation="90" weight="1">
<s:GradientEntry color="0x33FFFF" alpha="0.55" />
<s:GradientEntry color="0x99FFFF" alpha="0.2475" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
But this doesn't work well, the Rect is obscured by the other Flex components:
Is there a quick way of adding a backround gradient to a Flex application (something as simple as backgroundColor="#CCCCCC") or do I have to study "skinning docs" (and will skinning of an Application help here, since the problem seems to be that the Flex components are opaque?)

Looks like the default white background overlays your custom Rect.
Try adding contentBackgroundAlpha="0" to hide the component background without messing with skins.

You used <stroke> instead of <fill>
<s:Rect left="0" top="0" right="0" bottom="0">
<s:fill>
<s:LinearGradient id="_bgcolor" rotation="90">
<s:GradientEntry color="0x33FFFF" alpha="0.55" />
<s:GradientEntry color="0x99FFFF" alpha="0.2475" />
</s:LinearGradient>
</s:fill>
</s:Rect>

You're missing content group
<s:Group id="chrome" left="0" right="0" top="0" bottom="0" visible.closedGroup="false">
<s:Rect left="0" top="0" right="0" bottom="0">
<s:fill>
<s:LinearGradient id="_bgcolor" rotation="90">
<s:GradientEntry color="0x33FFFF" alpha="0.55" />
<s:GradientEntry color="0x99FFFF" alpha="0.2475" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0">
<s:layout>
<s:BasicLayout/>
</s:layout>
</s:Group>
</s:Group>

Related

How can I change a Spark WindowedApplication StatusBar skin programatically?

Currently I'm using the ideas in this post to skin my s:WindowedApplication, so in the declaration of my component I have skinClass="StatusBarSkin1". Also in my preinitialize function I have a method which puts the correct text onto the status bar using the label, which works fine.
The problem arises when I try and set the skinClass in my CSS, so I can change between StatusBarSkin1 and StatusBarSkin2. So I'm doing something like:
Style1.css
----------
.mainWindow
{
skinClass: ClassReference("StatusBarSkin1");
}
Style2.css
----------
.mainWindow
{
skinClass: ClassReference("StatusBarSkin2");
}
If I do this, the theme loads fine, but the text for the status bar won't display; and if I set the theme in the WindowedApplication itself, then I can't change the skin on the status bar when I change CSS files using a method.
Is there a better way to implement this than what I'm doing now?
EDIT:
The statusbar object is just an HGroup with some labels and stuff in it.
The statusbar skin is given by this code:
<s:Group id="statusBar"
width="100%"
minHeight="20">
<!-- status bar fill -->
<s:Rect left="0"
right="0"
top="0"
bottom="0">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0x575757" />
<s:GradientEntry color="0x373737" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- status bar highlight -->
<s:Rect left="1"
right="1"
top="1"
bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90"
weight="1">
<s:GradientEntry color="0x575757" />
<s:GradientEntry color="0x373737" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- status text -->
<!--- #copy spark.components.WindowedApplication#statusText -->
<s:Label id="statusText" />
<s:Group id="statusBarSkin" />
</s:Group>
and then my preinit function is
private function InitStatusBar():void
{
statusGroup = new StatusBar();
(statusBar as Group).addElement(statusGroup);
}

Custom Drag and Drop Component: When i add a skin, drag and drop no longer works?

I have a skinnableContainer that acts as a container for other drag and droppable items. This container's drop functionality is added from it's parent at the same moment the container is added.
This all works fine until I add a skin class to the skinnableContainer, now none of the draggable items can drop into the container as it did before.
I assume that the Group component wrapping the content from within the skin is acting as a block somehow, but I'm not sure how to allow the drop functionality through it?
Any ideas?
EDIT skin code below:
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" alpha.disabled="0.5">
<fx:Metadata>
[HostComponent("spark.components.SkinnableContainer")]
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<!-- layer 1: border -->
<s:Rect left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5">
<s:stroke>
<s:SolidColorStroke color="0" alpha="0.50" weight="1" />
</s:stroke>
</s:Rect>
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" >
<s:layout>
<s:VerticalLayout/>
</s:layout>
</s:Group>
</s:Skin>
Your custom skin has no background fill, hence it's completely transparent except for the border. Because of this there is no "hitzone" to drop your items on (right now you will probably be able to drop them if you target exactly that 1px border).
The solution - obviously - is to give it a fill. No worries, if you want it to look transparent, just set its alpha to 0.
<s:Rect left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5">
<s:fill>
<s:SolidColor alpha="0" />
</s:fill>
<s:stroke>
<s:SolidColorStroke alpha="0.50" />
</s:stroke>
</s:Rect>

BorderContainer Corner Rounding Only At Top Or Bottom

I need to round at only the top or bottom of a border container not all four corners, is their some CSS that I can use or do I have to create two new skins. I was reading their used to be a property for this for HBox back in the old days, is their not a property for BorderContainer now?
With BorderContainer you can't. However, the visual effect you want to achieve can easily be created with SkinnableContainer and a custom skin. In fact BorderContainer is just a specific form of SkinnableContainer.
So instead of BorferContainer create a SkinnableContainer with property 'skinClass':
<s:SkinnableContainer left="0" right="0" top="0" bottom="0"
skinClass="my.app.skins.TopRoundedCornerSkin">
<!--- your components go here --->
</s:SkinnableContainer>
Then create the skin class TopRoundedCornerSkin.mxml like so:
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>
[HostComponent("spark.components.SkinnableContainer")]
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<s:Rect id="background" left="0" right="0" top="0" bottom="0"
topLeftRadiusX="10" topLeftRadiusY="10"
topRightRadiusX="10" topRightRadiusY="10">
<s:fill>
<s:SolidColor color="0xffffff" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color="0x000000" />
</s:stroke>
</s:Rect>
<s:Group id="contentGroup" left="10" right="10" top="10" bottom="10"
minWidth="0" minHeight="0" />
</s:Skin>
On the background rectangle, we set 4 radius properties to create the rounded corner you need.

Is this a PrintDataGrid bug or restriction or my lack of understanding?

I'm trying to implement PrintDataGrid in my application and I'm encountering a peculiar problem. The printout is skipping last several rows in the printout of each page.
I have narrowed down to what's causing this issue. My application-level custom skin provides Flex scrolling capability to the entire application. Presence of this scrollbar in the custom skin is causing PrintDataGrid to skip last rows. In fact, number of rows skipped depends on the height of the browser. If you reduce the browser height, you skip more rows!
Is this a bug PrintDataGrid or a restriction (cannot have PrintDataGrid within Scroller) or I'm missing something?
Please help as I'm struggling with this for several days!
Here is simple code to reproduce the issue:
Main Application:
Application custom skin class:ApplicationSkinCustom.mxml
============================================
#see spark.components.Application
#langversion 3.0
#playerversion Flash 10
#playerversion AIR 1.5
#productversion Flex 4
-->
<fx:Metadata>
<![CDATA[
/**
* A strongly typed property that references the component to which this skin is applied.
*/
[HostComponent("spark.components.Application")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
/**
* #private
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number) : void
{
bgRectFill.color = getStyle('backgroundColor');
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalWithControlBar" />
<s:State name="disabledWithControlBar" />
</s:states>
<!-- fill -->
<!---
A rectangle with a solid color fill that forms the background of the application.
The color of the fill is set to the Application's backgroundColor property.
-->
<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0" >
<s:fill>
<s:SolidColor id="bgRectFill" color="#FFFFFF"/>
</s:fill>
</s:Rect>
<s:Scroller left="1" top="1" right="1" bottom="1" id="scroller">
<s:Group left="0" right="0" top="0" bottom="0">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify" />
</s:layout>
<!---
#private
Application Control Bar
-->
<s:Group
id="topGroup"
minWidth="0"
minHeight="0"
includeIn="normalWithControlBar, disabledWithControlBar"
>
<!-- layer 0: control bar highlight -->
<s:Rect left="0" right="0" top="0" bottom="1" >
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xFFFFFF" />
<s:GradientEntry color="0xD8D8D8" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 1: control bar fill -->
<s:Rect left="1" right="1" top="1" bottom="2" >
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xEDEDED" />
<s:GradientEntry color="0xCDCDCD" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- layer 2: control bar divider line -->
<s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
<s:fill>
<s:SolidColor color="0x000000" />
</s:fill>
</s:Rect>
<!-- layer 3: control bar -->
<!--- #copy spark.components.Application#controlBarGroup -->
<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
</s:layout>
</s:Group>
</s:Group>
<!--- #copy spark.components.SkinnableContainer#contentGroup -->
<!--<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />-->
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />
</s:Group>
</s:Scroller>
This is apparently a known bug with the Flex printing library and Scroller controls. You can read about my discussions on this here:
http://forums.adobe.com/message/3626759
The first thing I would try is getting rid of the custom skin, processing your print job, and then re-applying the custom skin. This might do the trick. If that does work, but doesn't look the way you want, then you can work on creating a variant of your custom application skin that doesn't have a scroller. You would apply that before starting the print job, and then restore the original custom application skin after the print job completes.
The user may briefly see the "alternate" version of your app when they click the print button, but it should only be for a split second at most.
-Josh

Flex4 TabBar skinning

I have trying to skin TabBar and NavigatorContent.
Please see image for explanation - All tabs are transparent (alpha 0.6) and also their borders.
How can I remove top border from NavigatorContent under selected buttonTab ?
How its must be:
Trying to use BlendMode.ERASE:
Application code:
...
<s:SkinnableContainer blendMode="layer" ... skinClass="skins.TabBorder">
<mx:ViewStack ...>
<s:NavigatorContent label="Search" skinClass="skins.TabSkin" />
<s:NavigatorContent label="Customer Info" skinClass="skins.TabSkin" />
</mx:ViewStack>
<s:TabBar dataProvider="{myViewStack}" ... />
</s:SkinnableContainer>
...
skins.TabBorder:
<s:Rect left="0" right="0" top="25" bottom="0" radiusX="6" topLeftRadiusX="0">
<s:stroke>
<s:SolidColorStroke color="#ffffff" alpha="0.3" />
</s:stroke>
</s:Rect>
skins.TabBarButtunSkin:
<!-- its black rect which clears all under -->
<s:Rect blendMode="erase" top="0" left="0" right="0" bottom="-2" topLeftRadiusX="6" topRightRadiusX="6" includeIn="selectedStates, overStates">
<s:fill>
<s:SolidColor color="#000000" />
</s:fill>
</s:Rect>
Perhaps there is an easier way?
<... borderSides=”left bottom right” borderStyle=”solid” borderThickness=”1″ ...>
also you can write your own skin
or extend the component itself

Resources