blob: 22d9daa45365ab5fcfb4e9e7b1ff810014715c91 [file] [log] [blame]
<?xml version="1.0" encoding="utf-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!---
The default skin class for Spark TabBar buttons.
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<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"
minWidth="21" minHeight="21" alpha.disabledStates="0.5">
<!-- host component -->
<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.ButtonBarButton")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling" >
import spark.components.TabBar;
static private const exclusions:Array = ["labelDisplay"];
/**
* @private
*/
override public function get colorizeExclusions():Array {return exclusions;}
/**
* @private
*/
override protected function initializationComplete():void
{
useChromeColor = true;
super.initializationComplete();
}
private var cornerRadius:Number = 4
/**
* @private
* The borderTop s:Path is just a s:Rect with the bottom edge left out.
* Given the rounded corners per the cornerRadius style, the result is
* roughly an inverted U with the specified width, height, and cornerRadius.
*
* Circular arcs are drawn with two curves per flash.display.Graphics.GraphicsUtil.
*/
private function updateBorderTop(width:Number, height:Number):void
{
var path:String = createPathData(true);
borderTop.data = path;
}
/**
* @private
* Draw the selected highlight strokes. The highlight is the same shape as the tab's
* border and is inset just within the border. It must be rendererd with three separate paths,
* since the top leg is rendered with two horizontal lines, with different stroke
* alpha values, and the left and right vertical legs are rendered with a third alpha value.
*
* Circular arcs are drawn with two curves per flash.display.Graphics.GraphicsUtil.
*/
private function updateSelectedHighlight(width:Number, height:Number):void
{
if (!selectedHighlightV)
return;
var left:Number = -0.5; // assuming stroke weight is 1.0
var right:Number = width - 0.5;
var path:String = createPathData(false);
selectedHighlightV.data = path;
// Configure the left/right sides of the two horizontal lines, defined with
// s:Rects, that appear at the top of the selected highlight.
selectedHighlightH1.x = selectedHighlightH2.x = left + cornerRadius;
selectedHighlightH1.width = selectedHighlightH2.width = (right - left) - (2 * cornerRadius);
}
/**
* @private
* This function creates the path data used by borderTop and selectedHighlight.
*/
private function createPathData(isBorder:Boolean):String
{
var left:Number = -0.5; // assuming stroke weight is 1.0
var right:Number = width - 0.5;
var top:Number = 0.5;
var bottom:Number = height;
var a:Number = cornerRadius * 0.292893218813453;
var s:Number = cornerRadius * 0.585786437626905;
// If the path is for the highlight,
// Draw the vertical part of the selected tab highlight that's rendered
// with alpha=0.07. The s:Path is configured to include only the left and
// right edges of an s:Rect, along with the top left,right rounded corners.
// Otherwise, we draw a full path.
var path:String = "";
path += "M " + left + " " + bottom;
path += " L " + left + " " + (top + cornerRadius);
path += " Q " + left + " " + (top + s) + " " + (left + a) + " " + (top + a);
path += " Q " + (left + s) + " " + top + " " + (left + cornerRadius) + " " + top;
if (isBorder)
path += " L " + (right - cornerRadius) + " " + top;
else
path += " M " + (right - cornerRadius) + " " + top;
path += " Q " + (right - s) + " " + top + " " + (right - a) + " " + (top + a);
path += " Q " + right + " " + (top + s) + " " + right + " " + (top + cornerRadius);
path += " L " + right + " " + bottom;
return path;
}
/**
* @private
* The cornerRadius style is specified by the TabBar, not the button itself.
*
* Rather than bind the corner radius properties of the s:Rect's in the markup
* below to hostComponent.owner.getStyle("cornerRadius"), we reset them here,
* each time a change in the value of the style is detected. Note that each
* corner radius property is explicitly initialized to the default value of
* the style; the initial value of the private cornerRadius property.
*/
private function updateCornerRadius():void
{
var cr:Number = getStyle("cornerRadius");
if (cornerRadius != cr)
{
cornerRadius = cr;
fill.topLeftRadiusX = cornerRadius;
fill.topRightRadiusX = cornerRadius;
lowlight.topLeftRadiusX = cornerRadius;
lowlight.topRightRadiusX = cornerRadius;
highlight.topLeftRadiusX = cornerRadius;
highlight.topRightRadiusX = cornerRadius;
highlightStroke.topLeftRadiusX = cornerRadius;
highlightStroke.topRightRadiusX = cornerRadius;
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaleHeight:Number):void
{
updateCornerRadius();
updateSelectedHighlight(unscaledWidth, unscaledHeight);
updateBorderTop(unscaledWidth, unscaledHeight);
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
</fx:Script>
<!-- states -->
<s:states>
<s:State name="up" />
<s:State name="over" stateGroups="overStates" />
<s:State name="down" stateGroups="downStates" />
<s:State name="disabled" stateGroups="disabledStates" />
<s:State name="upAndSelected" stateGroups="selectedStates, selectedUpStates" />
<s:State name="overAndSelected" stateGroups="overStates, selectedStates" />
<s:State name="downAndSelected" stateGroups="downStates, selectedStates" />
<s:State name="disabledAndSelected" stateGroups="selectedUpStates, disabledStates, selectedStates" />
</s:states>
<!-- layer 2: fill -->
<s:Rect id="fill" left="2" right="1" top="2" bottom="2" topLeftRadiusX="4" topRightRadiusX="4" width="69" height="21">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xFFFFFF"
color.selectedUpStates="0xD71BB0"
color.overStates="0xECBCED"
color.downStates="0x621379"
alpha="0.85"
alpha.overAndSelected="1" />
<s:GradientEntry color="0xD8D8D8"
color.selectedUpStates="0x986AD4"
color.over="0xF7C4F8"
color.overAndSelected="0xE6BCF9"
color.downStates="0x502672"
alpha="0.85"
alpha.overAndSelected="1" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!--- layer 3: fill lowlight @private-->
<s:Rect id="lowlight" left="1" right="1" top="1" bottom="1" topLeftRadiusX="4" topRightRadiusX="4">
<s:fill>
<s:LinearGradient rotation="270">
<s:GradientEntry color="0x000000" ratio="0.0" alpha="0.0627" />
<s:GradientEntry color="0x000000" ratio="0.48" alpha="0.0099" />
<s:GradientEntry color="0x000000" ratio="0.48001" alpha="0" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!--- layer 4: fill highlight @private-->
<s:Rect id="highlight" left="1" right="1" top="1" bottom="1" topLeftRadiusX="4" topRightRadiusX="4">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xCD9FDF"
ratio="0.0"
alpha="0.33"
alpha.selectedUpStates="0.22"
alpha.overStates="0.22"
alpha.downStates="0.12"/>
<s:GradientEntry color="0xCD9FDF"
ratio="0.48"
alpha="0.33"
alpha.selectedUpStates="0.22"
alpha.overStates="0.22"
alpha.downStates="0.12" />
<s:GradientEntry color="0xCD9FDF"
ratio="0.48001"
alpha="0" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- layer 5: highlight stroke (all states except down) -->
<s:Rect id="highlightStroke" left="1" right="1" top="1" bottom="1" topLeftRadiusX="4" topRightRadiusX="4"
excludeFrom="downStates">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xCD9FDF" alpha.overStates="0.22" alpha.selectedUpStates="0.33" />
<s:GradientEntry color="0xD8D8D8" alpha.overStates="0.22" alpha.selectedUpStates="0.33" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 6: highlight stroke, selected tab, alpha=0.0 when not selected @private -->
<s:Path id="selectedHighlightV" left="1" right="1" top="1" bottom="1" width="69" height="21">
<s:stroke>
<s:SolidColorStroke weight="1" color="0xA0FF50" alpha="0.0"
alpha.downStates="0.15"
alpha.selectedUpStates="0.15"
alpha.overAndSelected="0.15" />
</s:stroke>
</s:Path>
<s:Rect id="selectedHighlightH1" top="1" height="1">
<s:fill>
<s:SolidColor color="0xA0FF50" alpha="0.0"
alpha.downStates="0.25"
alpha.selectedUpStates="0.25"
alpha.overAndSelected="0.25" />
</s:fill>
</s:Rect>
<s:Rect id="selectedHighlightH2" top="2" height="1">
<s:fill>
<s:SolidColor color="0xA0FF50" alpha="0.0"
alpha.downStates="0.15"
alpha.selectedUpStates="0.15"
alpha.overAndSelected="0.15" />
</s:fill>
</s:Rect>
<!--- layer 7: border - put on top of the fill so it doesn't disappear when scale is less than 1 @private -->
<s:Line id="borderBottom" left="0" right="0" bottom="0">
<s:stroke>
<s:SolidColorStroke weight="1"
color="0x000000"
color.selectedStates="0x434343"
alpha="0.75"
alpha.down="0.85"
alpha.selectedStates="0.5" />
</s:stroke>
</s:Line>
<!--- @private -->
<s:Path id="borderTop" left="0" right="0" top="0" bottom="0" width="69" height="21">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0x000000"
alpha="0.5625"
alpha.down="0.6375"
alpha.selectedStates="0.6375" />
<s:GradientEntry color="0x000000"
alpha="0.75"
alpha.down="0.85"
alpha.selectedStates="0.85" />
</s:LinearGradientStroke>
</s:stroke>
</s:Path>
<!-- layer 8: text -->
<!--- Defines the appearance of the label for the tabs. -->
<s:Label id="labelDisplay" color.selectedStates="0x4736F1"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="1"
horizontalCenter="0" verticalCenter="1"
left="10" right="10" top="2" bottom="2">
</s:Label>
</s:SparkSkin>