blob: c5b99aa35e95d6ae5e127a3434d6cc9c03bf658a [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////////////////////////
package spark.skins.android4
{
import flash.display.BlendMode;
import flash.events.Event;
import mx.core.DPIClassification;
import mx.core.IVisualElement;
import mx.core.UIComponent;
import spark.components.ToggleSwitch;
import spark.components.supportClasses.StyleableTextField;
import spark.core.SpriteVisualElement;
import spark.skins.android4.assets.ToggleSwitchBackground;
import spark.skins.android4.assets.ToggleSwitchThumb_off;
import spark.skins.mobile.supportClasses.MobileSkin;
/**
* ActionScript-based Android 4.x specific skin for the ToggleSwitch control.
* This class is responsible for most of the
* graphics drawing, with additional fxg assets.
*
*
* @langversion 3.0
* @playerversion AIR 3
* @productversion Flex 4.6
*
* @see spark.components.ToggleSwitch
*/
public class ToggleSwitchSkin extends MobileSkin
{
//----------------------------------------------------------------------------------------------
//
// Skin parts
//
//----------------------------------------------------------------------------------------------
/**
* The thumb skin part.
*
* @langversion 3.0
* @playerversion AIR 3
* @productversion Flex 4.6
*/
public var thumb:IVisualElement;
/**
* The track skin part.
*
* @langversion 3.0
* @playerversion AIR 3
* @productversion Flex 4.6
*/
public var track:IVisualElement;
//----------------------------------
// hostComponent
//----------------------------------
private var _hostComponent:ToggleSwitch;
public var selectedLabelDisplay:LabelDisplayComponent;
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
public function get hostComponent():ToggleSwitch
{
return _hostComponent;
}
public function set hostComponent(value:ToggleSwitch):void
{
if (_hostComponent)
_hostComponent.removeEventListener("thumbPositionChanged", thumbPositionChanged_handler);
_hostComponent = value;
if (_hostComponent)
_hostComponent.addEventListener("thumbPositionChanged", thumbPositionChanged_handler);
}
//----------------------------------
// selectedLabel
//----------------------------------
private var _selectedLabel:String;
/**
* The text of the label showing when the component is selected.
* Subclasses can set or override this property to customize the selected label.
*
* @langversion 3.0
* @playerversion AIR 3
* @productversion Flex 4.6
*/
protected function get selectedLabel():String
{
return _selectedLabel;
}
protected function set selectedLabel(value:String):void
{
_selectedLabel = value;
}
//----------------------------------
// unselectedLabel
//----------------------------------
private var _unselectedLabel:String;
/**
* The text of the label showing when the component is not selected.
* Subclasses can set or override this property to customize the unselected label.
*
* @langversion 3.0
* @playerversion AIR 3
* @productversion Flex 4.6
*/
protected function get unselectedLabel():String
{
return _unselectedLabel;
}
protected function set unselectedLabel(value:String):void
{
_unselectedLabel = value;
}
/**
* The contents inside the skin, not including the outline
* stroke
*/
private var contents:UIComponent;
private var switchTrack:Class;
private var switchOff:Class;
private var switchOn:Class;
protected var trackWidth:Number;
protected var trackHeight:Number;
protected var layoutThumbWidth:Number;
protected var layoutThumbHeight:Number;
private var thumbOn:IVisualElement;
private var thumbOff:IVisualElement;
public function ToggleSwitchSkin()
{
super();
switchTrack = spark.skins.android4.assets.ToggleSwitchBackground;
switchOn = spark.skins.android4.assets.ToggleSwitchThumb_on;
switchOff = spark.skins.android4.assets.ToggleSwitchThumb_off;
switch(applicationDPI)
{
case DPIClassification.DPI_640:
{
layoutThumbWidth = 188;
layoutThumbHeight = 96;
trackWidth = 388;
trackHeight = 96;
break;
}
case DPIClassification.DPI_480:
{
layoutThumbWidth = 140;
layoutThumbHeight = 72;
trackWidth = 291;
trackHeight = 72;
break;
}
case DPIClassification.DPI_320:
{
layoutThumbWidth = 94;
layoutThumbHeight = 48;
trackWidth = 194;
trackHeight = 48;
break;
}
case DPIClassification.DPI_240:
{
layoutThumbWidth = 70;
layoutThumbHeight = 36;
trackWidth = 146;
trackHeight = 36;
break;
}
case DPIClassification.DPI_120:
{
layoutThumbWidth = 35;
layoutThumbHeight = 18;
trackWidth = 73;
trackHeight = 18;
break;
}
default:
{
layoutThumbWidth = 47;
layoutThumbHeight = 24;
trackWidth = 97;
trackHeight = 24;
break;
}
}
selectedLabel = resourceManager.getString("components","toggleSwitchSelectedLabel");
unselectedLabel = resourceManager.getString("components","toggleSwitchUnselectedLabel");
}
override protected function createChildren():void
{
super.createChildren();
contents = new UIComponent();
contents.blendMode = BlendMode.LAYER;
addChild(contents);
drawTrack();
drawThumbs();
drawLabel();
}
override protected function measure():void
{
// The skin must be at least as large as the thumb
measuredMinWidth = layoutThumbWidth;
measuredMinHeight = layoutThumbHeight;
// The preferred size will display all label text
var labelWidth:Number = getElementPreferredWidth(selectedLabelDisplay);
measuredWidth = layoutThumbWidth + labelWidth;
measuredHeight = layoutThumbHeight;
}
override protected function commitCurrentState():void
{
toggleSelectionState();
layoutThumbs();
layoutLabel();
}
//The label is called selectedLabelDisplay because the hostComponent expects it
protected function drawLabel():void
{
selectedLabelDisplay = new LabelDisplayComponent();
selectedLabelDisplay.id = "selectedLabelDisplay";
selectedLabelDisplay.text = selectedLabel;
setElementSize(selectedLabelDisplay,thumb.width,thumb.height);
contents.addChild(selectedLabelDisplay);
}
//Draw the track behind everything else
protected function drawTrack():void
{
if(track == null)
{
track = new switchTrack();
track.width = trackWidth;
track.height = trackHeight;
contents.addChildAt(SpriteVisualElement(track),0);
}
}
//Draw both thumbs. Set skinpart thumb to be thumbOff because default state of the switch is OFF
protected function drawThumbs():void
{
drawThumbOff();
drawThumbOn();
if(thumb == null)
{
thumb = thumbOff;
}
}
//Thumb ON the right side; Thumb OFF is on the left side
protected function layoutThumbs():void
{
setElementPosition(thumbOn,trackWidth/2,0);
setElementPosition(thumbOff,0,0);
}
//Label display sould be at the same location as the thumb
protected function layoutLabel():void
{
if(selectedLabelDisplay != null)
{
if(currentState.indexOf("AndSelected") != -1)
{
setElementPosition(selectedLabelDisplay,trackWidth/2,0);
}
else
{
setElementPosition(selectedLabelDisplay,0,0);
}
}
}
//Depending on current state, set skinpart thumb accordingly
protected function toggleSelectionState():void
{
if(currentState.indexOf("AndSelected") != -1)
{
thumbOn.visible = true;
thumbOff.visible = false;
thumb = thumbOn;
selectedLabelDisplay.text = selectedLabel;
}
else
{
thumbOff.visible = true;
thumbOn.visible = false;
thumb = thumbOff;
selectedLabelDisplay.text = unselectedLabel;
}
}
protected function drawThumbOn():void
{
thumbOn = new switchOn();
thumbOn.width = layoutThumbWidth;
thumbOn.height = layoutThumbHeight;
contents.addChildAt(SpriteVisualElement(thumbOn),1);
}
protected function drawThumbOff():void
{
thumbOff = new switchOff();
thumbOff.width = layoutThumbWidth;
thumbOff.height = layoutThumbHeight;
contents.addChildAt(SpriteVisualElement(thumbOff),1);
}
//Hostcomponent dispatches this event whenever the thumb position changes
protected function thumbPositionChanged_handler(event:Event):void
{
moveSlidingContent();
}
//Move the current thumb and label along with the animating content
protected function moveSlidingContent():void
{
if (!hostComponent)
return;
var x:Number = (track.getLayoutBoundsWidth() - thumb.getLayoutBoundsWidth()) *
hostComponent.thumbPosition + track.getLayoutBoundsX();
var y:Number = thumb.getLayoutBoundsY();
setElementPosition(thumb, x, y);
setElementPosition(selectedLabelDisplay, x, y);
}
}
}
import flash.events.Event;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import spark.components.supportClasses.StyleableTextField;
import spark.core.IDisplayText;
use namespace mx_internal;
/**
* @private
* Component combining two labels to create the effect of text and its drop
* shadow. The component can be used with advanced style selectors and the
* styles "color", "textShadowColor", and "textShadowAlpha". Based off of
* ActionBar.TitleDisplayComponent. These two should eventually be factored.
*/
class LabelDisplayComponent extends UIComponent implements IDisplayText
{
public var shadowYOffset:Number = 0;
private var labelChanged:Boolean = false;
private var labelDisplay:StyleableTextField;
private var labelDisplayShadow:StyleableTextField;
private var _text:String;
public function LabelDisplayComponent()
{
super();
_text = "";
}
override public function get baselinePosition():Number
{
return labelDisplay.baselinePosition;
}
override protected function createChildren():void
{
super.createChildren();
labelDisplay = StyleableTextField(createInFontContext(StyleableTextField));
labelDisplay.styleName = this;
labelDisplay.editable = false;
labelDisplay.selectable = false;
labelDisplay.multiline = false;
labelDisplay.wordWrap = false;
labelDisplay.addEventListener(FlexEvent.VALUE_COMMIT,
labelDisplay_valueCommitHandler);
labelDisplayShadow = StyleableTextField(createInFontContext(StyleableTextField));
labelDisplayShadow.styleName = this;
labelDisplayShadow.colorName = "textShadowColor";
labelDisplayShadow.editable = false;
labelDisplayShadow.selectable = false;
labelDisplayShadow.multiline = false;
labelDisplayShadow.wordWrap = false;
addChild(labelDisplayShadow);
addChild(labelDisplay);
}
override protected function commitProperties():void
{
super.commitProperties();
if (labelChanged)
{
labelDisplay.text = text;
invalidateSize();
invalidateDisplayList();
labelChanged = false;
}
}
override protected function measure():void
{
if (labelDisplay.isTruncated)
labelDisplay.text = text;
labelDisplay.commitStyles();
measuredWidth = labelDisplay.getPreferredBoundsWidth();
measuredHeight = labelDisplay.getPreferredBoundsHeight();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (labelDisplay.isTruncated)
labelDisplay.text = text;
labelDisplay.commitStyles();
var labelHeight:Number = labelDisplay.getPreferredBoundsHeight();
var labelY:Number = (unscaledHeight - labelHeight) / 2;
var labelWidth:Number = Math.min(unscaledWidth, labelDisplay.getPreferredBoundsWidth());
var labelX:Number = (unscaledWidth - labelWidth) / 2;
labelDisplay.setLayoutBoundsSize(labelWidth, labelHeight);
labelDisplay.setLayoutBoundsPosition(labelX, labelY);
labelDisplay.truncateToFit();
labelDisplayShadow.commitStyles();
labelDisplayShadow.setLayoutBoundsSize(labelWidth, labelHeight);
labelDisplayShadow.setLayoutBoundsPosition(labelX, labelY + shadowYOffset);
labelDisplayShadow.alpha = getStyle("textShadowAlpha");
// unless the label was truncated, labelDisplayShadow.text was set in
// the value commit handler
if (labelDisplay.isTruncated)
labelDisplayShadow.text = labelDisplay.text;
}
private function labelDisplay_valueCommitHandler(event:Event):void
{
labelDisplayShadow.text = labelDisplay.text;
}
public function get text():String
{
return _text;
}
public function set text(value:String):void
{
_text = value;
labelChanged = true;
invalidateProperties();
}
public function get isTruncated():Boolean
{
return labelDisplay.isTruncated;
}
public function showShadow(value:Boolean):void
{
labelDisplayShadow.visible = value;
}
}