| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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.components.supportClasses |
| { |
| |
| import flash.display.DisplayObject; |
| import flash.events.Event; |
| import flash.events.FocusEvent; |
| import flash.events.MouseEvent; |
| import flash.geom.Point; |
| |
| import mx.core.InteractionMode; |
| import mx.events.FlexEvent; |
| import mx.events.ResizeEvent; |
| import mx.events.SandboxMouseEvent; |
| import mx.events.TouchInteractionEvent; |
| |
| import spark.components.Button; |
| import spark.events.TrackBaseEvent; |
| |
| /** |
| * Dispatched when the value of the control changes |
| * as a result of user interaction. |
| * |
| * @eventType flash.events.Event.CHANGE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="change", type="flash.events.Event")] |
| |
| /** |
| * Dispatched at the end of a user interaction |
| * or when an animation ends. |
| * |
| * @eventType mx.events.FlexEvent.CHANGE_END |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="changeEnd", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched at the start of a user interaction |
| * or when an animation starts. |
| * |
| * @eventType mx.events.FlexEvent.CHANGE_START |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="changeStart", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched when the thumb is pressed and then moved by the mouse. |
| * This event is always preceded by a <code>thumbPress</code> event. |
| * |
| * @eventType spark.events.TrackBaseEvent.THUMB_DRAG |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="thumbDrag", type="spark.events.TrackBaseEvent")] |
| |
| /** |
| * Dispatched when the thumb is pressed, meaning |
| * the user presses the mouse button over the thumb. |
| * |
| * @eventType spark.events.TrackBaseEvent.THUMB_PRESS |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="thumbPress", type="spark.events.TrackBaseEvent")] |
| |
| /** |
| * Dispatched when the thumb is released, |
| * meaning the user releases the mouse button after |
| * a <code>thumbPress</code> event. |
| * |
| * @eventType spark.events.TrackBaseEvent.THUMB_RELEASE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="thumbRelease", type="spark.events.TrackBaseEvent")] |
| |
| /** |
| * Normal State |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [SkinState("normal")] |
| |
| /** |
| * Disabled State |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [SkinState("disabled")] |
| |
| /** |
| * Duration in milliseconds for a sliding animation |
| * when you click on the track to move a thumb. This style is |
| * used for both Sliders and Scrollbars. For Sliders, any click |
| * on the track will cause an animation using this style, as the thumb |
| * will move to the clicked position. For ScrollBars, this style is |
| * used only when shift-clicking on the track, which causes the thumb |
| * to move to the clicked position. Clicking on a ScrollBar track when |
| * the shift key is not pressed will result in paging behavior instead. |
| * The <code>smoothScrolling</code> style must also be set on the |
| * ScrollBar to get animated behavior when shift-clicking. |
| * |
| * <p>This duration is for an animation that covers the entire distance of the |
| * track; smaller distances will use a proportionally smaller duration.</p> |
| * |
| * @default 300 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="slideDuration", type="Number", format="Time", inherit="no")] |
| |
| /** |
| * The TrackBase class is a base class for components with a track |
| * and one or more thumb buttons, such as Slider and ScrollBar. It |
| * declares two required skin parts: <code>thumb</code> and |
| * <code>track</code>. |
| * The TrackBase class also provides the code for |
| * dragging the thumb button, which is shared by the Slider and ScrollBar classes. |
| * |
| * @mxml |
| * |
| * <p>The <code><s:TrackBase></code> tag inherits all of the tag |
| * attributes of its superclass and adds the following tag attributes:</p> |
| * |
| * <pre> |
| * <s:TrackBase |
| * <strong>Styles</strong> |
| * slideDuration="300" |
| * |
| * <strong>Events</strong> |
| * change="<i>No default</i>" |
| * changing="<i>No default</i>" |
| * thumbDrag="<i>No default</i>" |
| * thumbPress="<i>No default</i>" |
| * thumbRelease="<i>No default</i>" |
| * /> |
| * </pre> |
| * |
| * @see spark.components.supportClasses.Slider |
| * @see spark.components.supportClasses.ScrollBar |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public class TrackBase extends Range |
| { |
| include "../../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function TrackBase():void |
| { |
| super(); |
| addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); |
| addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Skins |
| // |
| //-------------------------------------------------------------------------- |
| |
| [SkinPart(required="false")] |
| |
| /** |
| * A skin part that defines a button |
| * that can be dragged along the track to increase or |
| * decrease the <code>value</code> property. |
| * Updates to the <code>value</code> property |
| * automatically update the position of the thumb button |
| * with respect to the track. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public var thumb:Button; |
| |
| [SkinPart(required="false")] |
| |
| /** |
| * A skin part that defines a button |
| * that, when pressed, sets the <code>value</code> property |
| * to the value corresponding with the current button position on the track. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public var track:Button; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| private var mouseDownTarget:DisplayObject; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden properties: Range |
| // |
| //-------------------------------------------------------------------------- |
| |
| //--------------------------------- |
| // maximum |
| //--------------------------------- |
| |
| [Inspectable(category="General", defaultValue="100.0")] |
| |
| /** |
| * @private |
| * Overidden so that this property can be the source of a binding expression. |
| */ |
| override public function get maximum():Number |
| { |
| return super.maximum; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set maximum(value:Number):void |
| { |
| if (value == super.maximum) |
| return; |
| |
| super.maximum = value; |
| invalidateDisplayList(); |
| } |
| |
| //--------------------------------- |
| // minimum |
| //--------------------------------- |
| |
| [Inspectable(category="General", defaultValue="0.0")] |
| |
| /** |
| * @private |
| * Overidden so that this property can be the source of a binding expression. |
| */ |
| override public function get minimum():Number |
| { |
| return super.minimum; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set minimum(value:Number):void |
| { |
| if (value == super.minimum) |
| return; |
| |
| super.minimum = value; |
| invalidateDisplayList(); |
| } |
| |
| //--------------------------------- |
| // scaleX |
| //--------------------------------- |
| |
| /** |
| * @private |
| * Overridden so that we can call invalidateDisplayList() |
| * when scaleX changes since the positioning of the thumb |
| * is incorrect when scaleX = 0 thanks to globalToLocal/localToGlobal(). |
| * |
| * <p>We override it here in TrackBase instead of where the issue |
| * actually exists (HScrollBar, HSlider, VScrollBar, VSlider) because it |
| * is easier this way and most subclasses who rely on updateSkinDisplayList() |
| * will probably run in to this issue.</p> |
| */ |
| override public function set scaleX(value:Number):void |
| { |
| if (value == super.scaleX) |
| return; |
| |
| // if we were scaled at 0 and are being set to something else, |
| // invalidate the display list (see comment above) |
| if (super.scaleX == 0) |
| invalidateDisplayList(); |
| |
| super.scaleX = value; |
| } |
| |
| //--------------------------------- |
| // scaleY |
| //--------------------------------- |
| |
| /** |
| * @private |
| * Overridden so that we can call invalidateDisplayList() |
| * when scaleY changes since the positioning of the thumb |
| * is incorrect when scaleY = 0 thanks to globalToLocal/localToGlobal(). |
| * |
| * <p>We override it here in TrackBase instead of where the issue |
| * actually exists (HScrollBar, HSlider, VScrollBar, VSlider) because it |
| * is easier this way and most subclasses who rely on updateSkinDisplayList() |
| * will probably run in to this issue.</p> |
| */ |
| override public function set scaleY(value:Number):void |
| { |
| if (value == super.scaleY) |
| return; |
| |
| // if we were scaled at 0 and are being set to something else, |
| // invalidate the display list (see comment above) |
| if (super.scaleY == 0) |
| invalidateDisplayList(); |
| |
| super.scaleY = value; |
| } |
| |
| //--------------------------------- |
| // value |
| //--------------------------------- |
| |
| [Bindable(event="valueCommit")] // Warning: must match the Bindable tag in Range |
| [Inspectable(category="General", defaultValue="0.0")] |
| |
| /** |
| * @private |
| * Overidden so that this property can be the source of a binding expression. |
| */ |
| override public function get value():Number |
| { |
| return super.value; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set value(newValue:Number):void |
| { |
| if (newValue == super.value) |
| return; |
| |
| super.value = newValue; |
| invalidateDisplayList(); |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function setValue(value:Number):void |
| { |
| super.setValue(value); |
| invalidateDisplayList(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Converts a track-relative x,y pixel location into a value between |
| * the minimum and maximum, inclusive. |
| * |
| * <p>TrackBase subclasses must override this method and perform conversions |
| * that take their own geometry into account. |
| * |
| * For example, a vertical slider might compute a value like this: |
| * <pre> |
| * return (y / track.height) * (maximum - minimum); |
| * </pre> |
| * </p> |
| * |
| * <p>By default, this method returns <code>minimum</code>.</p> |
| * |
| * @param x The x coordinate of the location relative to the track's origin. |
| * @param y The y coordinate of the location relative to the track's origin. |
| * @return A value between the minimum and maximum, inclusive. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function pointToValue(x:Number, y:Number):Number |
| { |
| return minimum; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function changeValueByStep(increase:Boolean = true):void |
| { |
| var prevValue:Number = this.value; |
| |
| super.changeValueByStep(increase); |
| |
| if (value != prevValue) |
| dispatchEvent(new Event(Event.CHANGE)); |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function getCurrentSkinState():String |
| { |
| return enabled ? "normal" : "disabled"; |
| } |
| |
| /** |
| * @private |
| * Warning: the goal of the listeners added here (and removed below) is to |
| * give the TrackBase a change to fixup the thumb's size and position |
| * after the skin's BasicLayout has run. This particular implementation |
| * is a hack and it begs a solution to the general problem of what we've |
| * called "cooperative layout". More about that here: |
| * http://opensource.adobe.com/wiki/display/flexsdk/Cooperative+Subtree+Layout |
| */ |
| override protected function partAdded(partName:String, instance:Object):void |
| { |
| super.partAdded(partName, instance); |
| |
| if (instance == thumb) |
| { |
| thumb.addEventListener(MouseEvent.MOUSE_DOWN, thumb_mouseDownHandler); |
| thumb.addEventListener(TouchInteractionEvent.TOUCH_INTERACTION_STARTING, thumb_touchInteractionStartingHandler); |
| thumb.addEventListener(ResizeEvent.RESIZE, thumb_resizeHandler); |
| thumb.addEventListener(FlexEvent.UPDATE_COMPLETE, thumb_updateCompleteHandler); |
| thumb.stickyHighlighting = true; |
| } |
| else if (instance == track) |
| { |
| track.addEventListener(ResizeEvent.RESIZE, track_resizeHandler); |
| |
| // track is only clickable if in mouse interactionMode |
| if (getStyle("interactionMode") == InteractionMode.MOUSE) |
| track.addEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler); |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function partRemoved(partName:String, instance:Object):void |
| { |
| super.partRemoved(partName, instance); |
| |
| if (instance == thumb) |
| { |
| thumb.removeEventListener(MouseEvent.MOUSE_DOWN, thumb_mouseDownHandler); |
| thumb.removeEventListener(TouchInteractionEvent.TOUCH_INTERACTION_STARTING, thumb_touchInteractionStartingHandler); |
| thumb.removeEventListener(ResizeEvent.RESIZE, thumb_resizeHandler); |
| thumb.removeEventListener(FlexEvent.UPDATE_COMPLETE, thumb_updateCompleteHandler); |
| } |
| else if (instance == track) |
| { |
| track.removeEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler); |
| track.removeEventListener(ResizeEvent.RESIZE, track_resizeHandler); |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| override public function styleChanged(styleName:String):void |
| { |
| var allStyles:Boolean = styleName == null || styleName == "styleName"; |
| |
| super.styleChanged(styleName); |
| |
| if (allStyles || styleName == "interactionMode") |
| { |
| if (track) |
| { |
| // track is only clickable if in mouse interactionMode |
| if (getStyle("interactionMode") == InteractionMode.MOUSE) |
| track.addEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler); |
| else |
| track.removeEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler); |
| } |
| } |
| } |
| |
| /** |
| * @private |
| * If the component is in focus, then it should respond to mouseWheel events. We listen to these |
| * events on systemManager in the capture phase because this behavior should have the highest priority. |
| */ |
| override protected function focusInHandler(event:FocusEvent):void |
| { |
| super.focusInHandler(event); |
| systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_WHEEL, system_mouseWheelHandler, true); |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function focusOutHandler(event:FocusEvent):void |
| { |
| super.focusOutHandler(event); |
| systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_WHEEL, system_mouseWheelHandler, true); |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function updateDisplayList(w:Number, h:Number):void |
| { |
| super.updateDisplayList(w, h); |
| updateSkinDisplayList(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event Handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Location of the mouse down event on the thumb, relative to the thumb's origin. |
| * Used to update the value property when the mouse is dragged. |
| */ |
| private var clickOffset:Point; |
| |
| /** |
| * Sets the bounds of skin parts, typically the thumb, whose geometry isn't fully |
| * specified by the skin's layout. |
| * |
| * <p>Most subclasses override this method to update the thumb's size, position, and |
| * visibility, based on the <code>minimum</code>, <code>maximum</code>, and <code>value</code> properties. </p> |
| * |
| * <p>By default, this method does nothing.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| * |
| */ |
| protected function updateSkinDisplayList():void {} |
| |
| /** |
| * @private |
| * Redraw whenever added to the stage to ensure the calculations |
| * in updateSkinDisplayList() are correct. |
| */ |
| private function addedToStageHandler(event:Event):void |
| { |
| updateSkinDisplayList(); |
| } |
| |
| /** |
| * @private |
| */ |
| private function track_resizeHandler(event:Event):void |
| { |
| updateSkinDisplayList(); |
| } |
| |
| /** |
| * @private |
| */ |
| private function thumb_resizeHandler(event:Event):void |
| { |
| updateSkinDisplayList(); |
| } |
| |
| /** |
| * @private |
| */ |
| private function thumb_updateCompleteHandler(event:Event):void |
| { |
| updateSkinDisplayList(); |
| thumb.removeEventListener(FlexEvent.UPDATE_COMPLETE, thumb_updateCompleteHandler); |
| } |
| |
| /** |
| * @private |
| * Handles the <code>mouseWheel</code> event when the component is in focus. The thumb is |
| * moved by the amount of the mouse event delta multiplied by the <code>stepSize</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function system_mouseWheelHandler(event:MouseEvent):void |
| { |
| if (!event.isDefaultPrevented()) |
| { |
| var newValue:Number = nearestValidValue(value + event.delta * stepSize, stepSize); |
| setValue(newValue); |
| dispatchEvent(new Event(Event.CHANGE)); |
| event.preventDefault(); |
| } |
| } |
| |
| //--------------------------------- |
| // Thumb dragging handlers |
| //--------------------------------- |
| |
| /** |
| * @private |
| * Handle mouse-down events on the scroll thumb. Records |
| * the mouse down point in clickOffset. |
| */ |
| protected function thumb_mouseDownHandler(event:MouseEvent):void |
| { |
| systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_MOVE, |
| system_mouseMoveHandler, true); |
| systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_UP, |
| system_mouseUpHandler, true); |
| systemManager.getSandboxRoot().addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, |
| system_mouseUpHandler); |
| |
| clickOffset = thumb.globalToLocal(new Point(event.stageX, event.stageY)); |
| |
| dispatchEvent(new TrackBaseEvent(TrackBaseEvent.THUMB_PRESS)); |
| dispatchEvent(new FlexEvent(FlexEvent.CHANGE_START)); |
| } |
| |
| /** |
| * @private |
| */ |
| protected function thumb_touchInteractionStartingHandler(event:TouchInteractionEvent):void |
| { |
| // cancel this event b/c I want to control it |
| event.preventDefault(); |
| } |
| |
| /** |
| * @private |
| * Capture mouse-move events anywhere on or off the stage. |
| * First, we calculate the new value based on the new position |
| * using calculateNewValue(). Then, we move the thumb to |
| * the new value's position. Last, we set the value and |
| * dispatch a "change" event if the value changes. |
| */ |
| protected function system_mouseMoveHandler(event:MouseEvent):void |
| { |
| if (!track) |
| return; |
| |
| var p:Point = track.globalToLocal(new Point(event.stageX, event.stageY)); |
| var newValue:Number = pointToValue(p.x - clickOffset.x, p.y - clickOffset.y); |
| newValue = nearestValidValue(newValue, snapInterval); |
| |
| if (newValue != value) |
| { |
| setValue(newValue); |
| dispatchEvent(new TrackBaseEvent(TrackBaseEvent.THUMB_DRAG)); |
| dispatchEvent(new Event(Event.CHANGE)); |
| } |
| |
| event.updateAfterEvent(); |
| } |
| |
| /** |
| * @private |
| * Handle mouse-up events anywhere on or off the stage. |
| */ |
| protected function system_mouseUpHandler(event:Event):void |
| { |
| systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_MOVE, |
| system_mouseMoveHandler, true); |
| systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_UP, |
| system_mouseUpHandler, true); |
| systemManager.getSandboxRoot().removeEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, |
| system_mouseUpHandler); |
| |
| dispatchEvent(new TrackBaseEvent(TrackBaseEvent.THUMB_RELEASE)); |
| dispatchEvent(new FlexEvent(FlexEvent.CHANGE_END)); |
| } |
| |
| //--------------------------------- |
| // Track down handlers |
| //--------------------------------- |
| |
| /** |
| * @private |
| * Handle mouse-down events for the scroll track. Subclasses |
| * should override this method if they want the track to |
| * recognize mouse clicks on the track. |
| */ |
| protected function track_mouseDownHandler(event:MouseEvent):void { } |
| |
| //--------------------------------- |
| // Mouse click handlers |
| //--------------------------------- |
| |
| /** |
| * @private |
| * Capture any mouse down event and listen for a mouse up event |
| */ |
| private function mouseDownHandler(event:MouseEvent):void |
| { |
| systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_UP, |
| system_mouseUpSomewhereHandler, true); |
| systemManager.getSandboxRoot().addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, |
| system_mouseUpSomewhereHandler); |
| |
| mouseDownTarget = DisplayObject(event.target); |
| } |
| |
| /** |
| * @private |
| */ |
| private function system_mouseUpSomewhereHandler(event:Event):void |
| { |
| systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_UP, |
| system_mouseUpSomewhereHandler, true); |
| systemManager.getSandboxRoot().removeEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, |
| system_mouseUpSomewhereHandler); |
| |
| // If we got a mouse down followed by a mouse up on a different target in the skin, |
| // we want to dispatch a click event. |
| if (mouseDownTarget != event.target && event is MouseEvent && contains(DisplayObject(event.target))) |
| { |
| var mEvent:MouseEvent = event as MouseEvent; |
| // Convert the mouse coordinates from the target to the TrackBase |
| var mousePoint:Point = new Point(mEvent.localX, mEvent.localY); |
| mousePoint = globalToLocal(DisplayObject(event.target).localToGlobal(mousePoint)); |
| |
| dispatchEvent(new MouseEvent(MouseEvent.CLICK, mEvent.bubbles, mEvent.cancelable, mousePoint.x, |
| mousePoint.y, mEvent.relatedObject, mEvent.ctrlKey, mEvent.altKey, |
| mEvent.shiftKey, mEvent.buttonDown, mEvent.delta)); |
| } |
| |
| mouseDownTarget = null; |
| } |
| } |
| |
| } |