この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
日々のお仕事シリーズ(仮称)
Flex 4 には、HSlider ( 水平 )、VSlider ( 垂直 )と、2 種類のスライダーコンポーネントが用意されていますが、最大値から最大値への進行方向がそれぞれ固定されています。 ( HSlider : 左→右、VSlider : 下→上 )
稀に、逆方向に値が増減するモノを求められることがあるのですが、そのような機能は実装されていないので、自前で用意します。
反転機能付き水平スライダーコンポーネント (ReverseHSlider.as)
package jp.classmethod.component {
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.ui.Keyboard;
import spark.components.HSlider;
/**
* <p>ReverseHSlider クラスは、オリジナルの HSlider を水平方向に反転させたコンポーネントです。</p>
* @author hirohata.taiga
*/
public class ReverseHSlider extends HSlider {
/**
* <p>水平方向の反転の有無を示すブール値です。</p>
*/
public function get isReverse():Boolean {
return _isReverse;
}
/** @private */
public function set isReverse(value:Boolean):void {
_isReverse = value;
invalidateProperties();
invalidateDisplayList();
}
/** @private */
private var _isReverse:Boolean;
/**
* <p>コンストラクタ</p>
*/
public function ReverseHSlider() {
super();
}
/** @private */
protected override function keyDownHandler(event:KeyboardEvent):void {
var keyCode_:int = event.keyCode;
if(keyCode_ == Keyboard.LEFT && _isReverse) {
keyCode_ = Keyboard.RIGHT;
}
else if(keyCode_ == Keyboard.RIGHT && _isReverse) {
keyCode_ = Keyboard.LEFT;
}
else if(keyCode_ == Keyboard.DOWN && _isReverse) {
keyCode_ = Keyboard.UP;
}
else if(keyCode_ == Keyboard.UP && _isReverse) {
keyCode_ = Keyboard.DOWN;
}
event.keyCode = keyCode_;
super.keyDownHandler(event);
}
/** @private */
protected override function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
var m:Matrix = new Matrix();
m.scale(_isReverse ? -1 : 1, 1);
m.tx = _isReverse ? unscaledWidth : 0;
transform.matrix = m;
}
}
}
反転機能付き垂直スライダーコンポーネント (ReverseVSlider.as)
package jp.classmethod.component {
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.ui.Keyboard;
import spark.components.VSlider;
/**
* <p>ReverseVSlider クラスは、オリジナルの VSlider を垂直方向に反転させたコンポーネントです。</p>
* @author hirohata.taiga
*/
public class ReverseVSlider extends VSlider {
/**
* <p>垂直方向の反転の有無を示すブール値です。</p>
*/
public function get isReverse():Boolean {
return _isReverse;
}
/** @private */
public function set isReverse(value:Boolean):void {
_isReverse = value;
invalidateProperties();
invalidateDisplayList();
}
/** @private */
private var _isReverse:Boolean;
/**
* <p>コンストラクタ</p>
*/
public function ReverseVSlider() {
super();
}
/** @private */
protected override function keyDownHandler(event:KeyboardEvent):void {
var keyCode_:int = event.keyCode;
if(keyCode_ == Keyboard.LEFT && _isReverse) {
keyCode_ = Keyboard.RIGHT;
}
else if(keyCode_ == Keyboard.RIGHT && _isReverse) {
keyCode_ = Keyboard.LEFT;
}
else if(keyCode_ == Keyboard.DOWN && _isReverse) {
keyCode_ = Keyboard.UP;
}
else if(keyCode_ == Keyboard.UP && _isReverse) {
keyCode_ = Keyboard.DOWN;
}
event.keyCode = keyCode_;
super.keyDownHandler(event);
}
/** @private */
protected override function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
var m:Matrix = new Matrix();
m.scale(1, _isReverse ? -1 : 1);
m.ty = _isReverse ? unscaledHeight : 0;
transform.matrix = m;
}
}
}
実装コード (Main.mxml)
<?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:c = "jp.classmethod.component.*"
fontSize = "20"
>
<s:VGroup width="200" verticalCenter="0" horizontalCenter="0" gap="50">
<s:ToggleButton id="tg" width="200"
label="{tg.selected?'isReverse=true':'isReverse=false'}" />
<s:VGroup width="100%" horizontalAlign="center">
<s:Label id="hLabel" text="{String(hSlider.value)}" />
<c:ReverseHSlider
id="hSlider" width="200" height="30"
isReverse="{tg.selected}" minimum="0" maximum="10" stepSize="1" />
</s:VGroup>
<s:HGroup width="100%" verticalAlign="middle" horizontalAlign="center">
<s:Label id="vLabel" width="40" text="{String(vSlider.value)}" />
<c:ReverseVSlider
id="vSlider" width="30" height="200"
isReverse="{tg.selected}" minimum="0" maximum="10" stepSize="1" />
</s:HGroup>
</s:VGroup>
</s:Application>
解説
isReverse という反転の有無を示すプロパティを用意して、描画のタイミング ( updateDisplayList() ) でプロパティの状態に応じた変換マトリックス ( 変換行列 ) を作成して、コンポーネントの Transform オブジェクトの matrix プロパティに適用させます。
これだけで反転は実現できますが、ついでに十字キー操作のお世話もしておきました。isReverse プロパティの状態に応じてイベントオブジェクトを改竄 ( 上下左右を反転 ) しています。
出力結果
出力結果は次の通り
[SWF]http://public-blog-dev.s3.amazonaws.com/wp-content/uploads/2012/02/ReverseSliderSample20120207.swf,640,480[/SWF]