Flex: gap between graphics - apache-flex

I have a group with inside it 2 Graphics, I set the gap in the vertical layout of the group to 0 but there still is a gap of 1 pixel between the 2 graphics. Any idea how to get rid of this?
<?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" minWidth="955" minHeight="600">
<s:Group>
<s:layout>
<s:VerticalLayout gap="0"/>
</s:layout>
<s:Graphic height="100">
<s:Path data="M 50 0 L 50 100 Z" height="100">
<s:stroke>
<s:SolidColorStroke color="#333333"/>
</s:stroke>
</s:Path>
</s:Graphic>
<s:Graphic height="1">
<s:Path data="M 0 0 L 100 0 Z" height="1">
<s:stroke>
<s:SolidColorStroke color="#333333"/>
</s:stroke>
</s:Path>
</s:Graphic>
</s:Group>
</s:Application>

The simple answer to your question is that the gap seems to come from the explicit height you give to the first graphic. Simply remove it and the gap will be gone.
The (IMO) better answer is that this code seems a bit convoluted for creating simple graphics.
There is no reason you should wrap each line in a Graphics class. You can extend Graphic to create a standalone, reusable graphic class though.
There is a Line class for drawing straight lines. Much easier than using Path
If you absolutely need the VerticalLayout, you could rewrite that code like this:
<s:Group>
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="center" />
</s:layout>
<s:Line height="100">
<s:stroke>
<s:SolidColorStroke color="#333333" />
</s:stroke>
</s:Line>
<s:Line width="100">
<s:stroke>
<s:SolidColorStroke color="#333333" />
</s:stroke>
</s:Line>
</s:Group>
But if you don't really need it for some reason, it can even be reduced to this:
<s:Group>
<s:Line height="100" horizontalCenter="0">
<s:stroke>
<s:SolidColorStroke color="#333333" />
</s:stroke>
</s:Line>
<s:Line width="100" bottom="0">
<s:stroke>
<s:SolidColorStroke color="#333333" />
</s:stroke>
</s:Line>
</s:Group>

Related

How to get clip content to work on mx TabNavigator?

I have a TabNavigator and before that a ViewStack with TabBar that would not clip it's contents. It over flows the border or appears under other components positioned further down the screen. Has anyone run into this before?
Here is my code:
<mx:VDividedBox width="300" height="100%">
<mx:TabNavigator id="firstViewStack"
borderStyle="solid"
width="100%"
height="100%"
clipContent="true">
<s:NavigatorContent id="content1"
label="ITEMS">
<views:Items height="550" width="100%" />
</s:NavigatorContent>
<s:NavigatorContent id="eventsContent" label="ITEMS 2">
<views:Items height="880" width="100%"/>
</s:NavigatorContent>
</mx:TabNavigator>
</mx:VDividedBox>
UPDATE
I've included a animated gif of me resizing the tab content. As you can see the mask appears to be sized to the content rather than the available area??? Notice the border of the tab navigator along the size is being overlapped when resizing.
I set the minimum height on all of the content to lower values and height to 100% on all the content so it is not as high but you can see the content is still not getting clipped.
I also tried with a VGroup rather than a VDividedBox and it doesn't matter.
Here is another code example:
<s:VGroup top="50" left="50" width="400">
<mx:TabNavigator width="100%" height="300">
<s:NavigatorContent label="TAB">
<s:Group width="100%" height="400">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#ff0000"/>
</s:fill>
</s:Rect>
</s:Group>
</s:NavigatorContent>
<s:NavigatorContent label="TAB">
<s:Group width="100%" height="400">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#0000ff"/>
</s:fill>
</s:Rect>
</s:Group>
</s:NavigatorContent>
</mx:TabNavigator>
<s:Button width="100%" label="HELLO WORLD"/>
<s:Button width="100%" label="HELLO WORLD"/>
</s:VGroup>
I have implemented 2 approaches - one with a Scroller and another with autosize.
Here is an example
Here is the code:
<?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"
minWidth="955" minHeight="600">
<s:HGroup width="100%" height="100%" left="50" top="50">
<!-- Using Scroller-->
<s:VGroup width="400">
<mx:TabNavigator width="100%" height="300">
<s:NavigatorContent label="TAB" width="100%" height="100%">
<s:Scroller width="100%" height="100%">
<s:Group>
<s:Group width="100%" height="400">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#ff0000"/>
</s:fill>
</s:Rect>
</s:Group>
</s:Group>
</s:Scroller>
</s:NavigatorContent>
<s:NavigatorContent label="TAB" width="100%" height="100%">
<s:Scroller width="100%" height="100%">
<s:Group>
<s:Group width="100%" height="600">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#0000ff"/>
</s:fill>
</s:Rect>
</s:Group>
</s:Group>
</s:Scroller>
</s:NavigatorContent>
</mx:TabNavigator>
<s:Button width="100%" label="HELLO WORLD"/>
<s:Button width="100%" label="HELLO WORLD"/>
</s:VGroup>
<s:Spacer width="60"/>
<!-- Using Autosize-->
<s:VGroup top="50" left="50" width="400">
<mx:TabNavigator width="100%" minHeight="300" resizeToContent="true" >
<s:NavigatorContent label="TAB" width="100%" height="100%">
<s:Group width="100%" height="400">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#ff0000"/>
</s:fill>
</s:Rect>
</s:Group>
</s:NavigatorContent>
<s:NavigatorContent label="TAB" width="100%" height="100%">
<s:Group width="100%" height="500">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="#0000ff"/>
</s:fill>
</s:Rect>
</s:Group>
</s:NavigatorContent>
</mx:TabNavigator>
<s:Button width="100%" label="HELLO WORLD"/>
<s:Button width="100%" label="HELLO WORLD"/>
</s:VGroup>
</s:HGroup>
</s:Application>

Flex item renderer - change alpha when clicked

I want to change the alpha of Rect when list item is clicked but I could not solve that. And I don't know how exactly do this as I'm doing it on Rectangle inside item renderer, is there any suggestion?
CODE:
<s:List id="list" labelField="name" dataProvider="{items}" top="20" bottom="20" left="20" right="20"
contentBackgroundAlpha="0"
change="list_changeHandler(event)">
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer width="100%" height="200" autoDrawBackground="false" contentBackgroundAlpha="0">
<s:Group width="100%" height="100%">
<s:Rect id="rect" left="0" right="0" top="0" bottom="0" alpha="0.3">
<s:fill>
<s:SolidColor color="#FFFFFF"
/>
</s:fill>
</s:Rect>
<s:Image source="{data.icon}" top="30" horizontalCenter="0"/>
<s:Label text="{data.name}" top="100" horizontalCenter="0" color="#101010" fontWeight="bold" fontSize="16"/>
<s:Label text="{data.line1}" top="130" horizontalCenter="0" color="#343434" fontSize="14"/>
<s:Label text="{data.line2}" top="150" horizontalCenter="0" color="#343434" fontSize="14"/>
</s:Group>
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
<s:layout>
<s:TileLayout requestedColumnCount="3" requestedColumnCount.landscape="4" columnAlign="justifyUsingWidth"/>
</s:layout>
</s:List>
You can use the ItemRenderer's states for this. Add these states to your ItemRenderer:
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:Rect left="0" right="0" top="0" bottom="0">
<s:fill>
<s:SolidColor color.normal="0x0000ff"
color.hovered="0x00ff00"
color.selected="0xff0000" />
</s:fill>
</s:Rect>
With this code your renderer will be blue by default; it will turn green when you hover over it; and red when you select it. The same can of course be done with the alpha value.

ComboBox auto close

I'm using a combobox with a custom item renderer, each item containing a "delete" button to remove the corresponding item from the list. The problem is that when I click on this button, the combobox popup automatically closes, how can I force it to stay open when I click on the button ?
This is how is declared my ComboBox :
<s:ComboBox id="addressIn" width="150" height="23" skinClass="maincomponents.ServerAddressComboBoxSkin" dataProvider="{this._servers}" enabled="true" enabled.loading="false" />
The corresponding skin :
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled=".5">
<!-- host component -->
<fx:Metadata>
<![CDATA[
/**
* #copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.ComboBox")]
]]>
</fx:Metadata>
<!--
NOTE: this skin file contains sub-parts that may continue to react to
Style code. To remove this behavior create new copies of those skins
and remove the styles.
-->
<s:states>
<s:State name="normal" />
<s:State name="open" />
<s:State name="disabled" />
</s:states>
<!---
The PopUpAnchor control that opens the drop-down list.
<p>In a custom skin class that uses transitions, set the
<code>itemDestructionPolicy</code> property to <code>none</code>.</p>
-->
<s:PopUpAnchor id="popUp" displayPopUp.normal="false" displayPopUp.open="true" includeIn="open"
left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto"
popUpPosition="below" popUpWidthMatchesAnchorWidth="true">
<!---
This includes borders, background colors, scrollers, and filters.
#copy spark.components.supportClasses.DropDownListBase#dropDown
-->
<s:Group id="dropDown">
<!-- drop shadow -->
<!--- #private -->
<s:RectangularDropShadow id="dropShadow" blurX="20" blurY="20" alpha="0.45" distance="7"
angle="90" color="#000000" left="0" top="0" right="0" bottom="0"/>
<!-- border -->
<!--- #private -->
<s:Rect id="border" left="0" right="0" top="0" bottom="0">
<s:stroke>
<!--- #private -->
<s:SolidColorStroke id="borderStroke" weight="1"/>
</s:stroke>
</s:Rect>
<!-- fill -->
<!--- Defines the appearance of drop-down list's background fill. -->
<s:Rect id="background" left="1" right="1" top="1" bottom="1" >
<s:fill>
<!---
#private
The color of the drop down's background fill.
The default color is 0xFFFFFF.
-->
<s:SolidColor id="bgFill" color="0xFFFFFF" />
</s:fill>
</s:Rect>
<!--- #private -->
<s:Scroller id="scroller" left="0" top="0" right="0" bottom="0" horizontalScrollPolicy="off" skinClass="fbcomponents.skinScrollSettingsDD">
<!--- #copy spark.components.SkinnableDataContainer#dataGroup-->
<s:DataGroup id="dataGroup" clipAndEnableScrolling="true" itemRenderer="maincomponents.DataList_ServerRepeatedItem">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="contentJustify" requestedMinRowCount="1" requestedMaxRowCount="6"/>
</s:layout>
</s:DataGroup>
</s:Scroller>
</s:Group>
</s:PopUpAnchor>
<!--- The default skin is ComboBoxButtonSkin.
#copy spark.components.supportClasses.DropDownListBase#openButton
#see spark.skins.spark.ComboBoxButtonSkin -->
<s:Button id="openButton" width="20" right="0" top="0" bottom="0" focusEnabled="false"
skinClass="maincomponents.ServerAddressComboBoxButtonSkin" tabEnabled="false" />
<!--- #copy spark.components.ComboBox#textInput -->
<s:TextInput id="textInput" enabled.disabled="false"
left="0" right="19" top="0" bottom="0"
skinClass="maincomponents.ServerAddressComboBoxTextInputSkin"/>
</s:SparkSkin>
And the item renderer :
<s:ItemRenderer xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:fc="http://ns.adobe.com/flashcatalyst/2009"
xmlns:ai="http://ns.adobe.com/ai/2009"
xmlns:d="http://ns.adobe.com/fxg/2008/dt" dataChange="onDataChangeHandler(event)" valueCommit="adaptBg()"
xmlns:flm="http://ns.adobe.com/flame/2008"
minWidth="161" height="20" autoDrawBackground="false" fc:resizable="true">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.events.StateChangeEvent;
import spark.components.List;
protected function onDataChangeHandler(event:FlexEvent):void
{
this.title.text = this.data as String;
this.adaptBg();
}
protected function adaptBg():void
{
this.bg.color = (itemIndex % 2 == 0) ? 0xEFEFEF : 0xE0E0E0;
}
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="hovered"/>
<s:State name="selected"/>
</s:states>
<s:Rect x="0" y="0" width="161" height="20">
<s:fill>
<s:SolidColor id="bg" color="#EFEFEF"/>
</s:fill>
</s:Rect>
<s:Rect x="0" y="0" width="161" height="20"
visible.normal="false">
<s:fill>
<s:LinearGradient x="137" y="0" scaleX="31" rotation="90">
<s:GradientEntry ratio="0" color="#FFEDD1"/>
<s:GradientEntry ratio="0.5" color="#FFD180"/>
<s:GradientEntry ratio="0.51" color="#EBAA1D"/>
<s:GradientEntry ratio="1" color="#CF951A"/>
</s:LinearGradient>
</s:fill>
<s:fill.hovered>
<s:SolidColor alpha="0.24" color="#000000"/>
</s:fill.hovered>
</s:Rect>
<s:Button x="5" y="2" width="20" height="16" buttonDown="trace('ok');" />
<s:RichText id="title" d:id="103" d:userLabel="caldera0003" x="32" verticalCenter="1" ai:aa="2" color="#292929"
columnCount="1" fontFamily="HelveticaNeueLT Pro 57 Cn" fontSize="14"
kerning="on" tabStops="S36" flm:variant="34"
whiteSpaceCollapse="preserve"/>
<s:Rect width="274" height="31"
visible="false" alpha.hovered="0.3"
alpha.normal="0"
alpha.selected="0.5">
<s:fill>
<s:SolidColor color="0xCED7EE"/>
</s:fill>
</s:Rect>
</s:ItemRenderer>
I've mentioned it in the comments, but you pointed out there is a difference with your situation. First read my answer to this question about adding a 'delete' button to DropDownList items: Create dropdownlist with delete button in this itemrenderer
There is only one thing you need to change from that code to get what you want, i.e. the popup must stay open when an item is removed. Go to the custom ItemRenderer, find the 'delete' Button tag and just prevent the event from propagating. If the event doesn't propagate, the DropDownList will never catch it and the popup will never close when the user clicks on the Button.
<s:Button verticalCenter="0" right="10" width="16" height="16"
mouseDown="event.stopImmediatePropagation(); remove()" />
Maybe I'm understanding something wrong, but can't you just add mouseDown handler on your delete button and stop event propagation in it? Like
<s:Button x="5" y="2"
width="20" height="16"
mouseDown="button1_mouseDownHandler(event)" buttonDown="trace('ok');"
/>
and
protected function button1_mouseDownHandler(event:MouseEvent):void
{
event.stopPropagation();
...
}
Maybe you should extend your combobox to stay open when it loses focus or closes? Pressing delete button causes focus lost event to your combobox.

Flex 4 transition: Glitch with simultaneous move and resize

I'm building a user interface and I have two panels which I need to move and resize. They have to look as a single panel. It works fine when I move or resize only one. But when one moves and the other resizes at the same time... an intermittent line appears between the two.
How can I avoid this?
Here is a working example of the problem:
<?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"
xmlns:components="components.*"
frameRate="30" height="400" width="200" >
<s:states>
<s:State name="minimized" />
<s:State name="maximized" />
</s:states>
<s:transitions>
<s:Transition>
<s:Parallel duration="4000" targets="{[one, two]}">
<s:Move target="{two}" />
<s:Resize target="{one}" />
</s:Parallel>
</s:Transition>
</s:transitions>
<s:Group id="one"
width="200"
height.minimized="20" height.maximized="200"
y="0">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="black" />
</s:fill>
</s:Rect>
</s:Group>
<s:Group id="two"
width="200"
height="200"
y.minimized="20" y.maximized="200">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="black" />
</s:fill>
</s:Rect>
</s:Group>
<s:Button click="currentState=(currentState=='minimized'? 'maximized' : 'minimized')" label="{currentState}" />
</s:WindowedApplication>
Thanks in advance!
Updated: Here's a version with VGroup:
<?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"
xmlns:components="components.*"
frameRate="30" height="400" width="400" >
<s:states>
<s:State name="minimized" />
<s:State name="maximized" />
</s:states>
<s:transitions>
<s:Transition>
<s:Parallel duration="4000" targets="{[one, two, three]}">
<s:Move target="{two}" />
<s:Resize target="{one, three}" />
</s:Parallel>
</s:Transition>
</s:transitions>
<s:Group id="one"
width="200"
height.minimized="20" height.maximized="200"
y="0">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="black" />
</s:fill>
</s:Rect>
</s:Group>
<s:Group id="two"
width="200"
height="200"
y.minimized="20" y.maximized="200">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="black" />
</s:fill>
</s:Rect>
</s:Group>
<s:VGroup gap="0" left="200">
<s:Group id="three"
width="200"
height.minimized="20" height.maximized="200"
y="0">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="black" />
</s:fill>
</s:Rect>
</s:Group>
<s:Group id="four"
width="200"
height="200">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="black" />
</s:fill>
</s:Rect>
</s:Group>
</s:VGroup>
<s:Button click="currentState=(currentState=='minimized'? 'maximized' : 'minimized')" label="{currentState}" />
</s:WindowedApplication>
Place both in the same VGroup and change the height of the first panel only.

Custom SkinnableContainer Skin border

I have a SkinnableContainer that I would like to add a border to. I have already created a skin class that creates a 1 pixel border around all four sides of the container successfully, however, I would like the border to only be for the top and bottom of the container, not the sides (left, right). How can I achieve such a thing? I have attached my current skin class. Please help! Thanks in advance.
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\mySkins\MyBorderSkin.mxml -->
<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" >
<fx:Metadata>
[HostComponent("spark.components.SkinnableContainer")]
</fx:Metadata>
<!-- Define the skin states. -->
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<!-- Define a Rect to fill the area of the skin. -->
<s:Rect x="0" y="0"
height="100%" width="100%">
<s:stroke>
<s:LinearGradientStroke weight="1"/>
</s:stroke>
</s:Rect>
<!-- Define the content area of the container. -->
<s:Group id="contentGroup"
left="5" right="5" top="2" bottom="2">
<s:layout>
<s:VerticalLayout/>
</s:layout>
</s:Group>
</s:Skin>
Use something like:
<s:Line left="0" top="0" right="0">
<s:stroke>
<s:LinearGradientStroke weight="1"/>
</s:stroke>
</s:Line>
<s:Line left="0" bottom="0" right="0">
<s:stroke>
<s:LinearGradientStroke weight="1"/>
</s:stroke>
</s:Line>
instead of your Rect declaration.

Resources