//////////////////////////////////////////////////////////////////////////////// // // 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.windowClasses { import flash.display.DisplayObject; import flash.display.NativeWindowDisplayState; import flash.events.Event; import flash.events.MouseEvent; import flash.events.NativeWindowDisplayStateEvent; import flash.system.Capabilities; import mx.core.IWindow; import mx.core.mx_internal; import spark.components.Button; import spark.components.supportClasses.SkinnableComponent; import spark.components.supportClasses.TextBase; import spark.events.SkinPartEvent; import spark.primitives.BitmapImage; import spark.skins.*; import spark.skins.spark.windowChrome.MacTitleBarSkin; import spark.skins.spark.windowChrome.TitleBarSkin; use namespace mx_internal; //-------------------------------------- // SkinStates //-------------------------------------- /** * The title bar is enabled and the application is maximized. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinState("normalAndMaximized")] /** * The title bar is disabled and the application is maximized. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinState("disabledAndMaximized")] //-------------------------------------- // Excluded APIs //-------------------------------------- [Exclude(name="focusBlendMode", kind="style")] [Exclude(name="focusThickness", kind="style")] /** * The TitleBar class defines the default title bar for a * WindowedApplication or a Window container. * * @see mx.core.Window * @see mx.core.WindowedApplication * * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public class TitleBar extends SkinnableComponent { include "../../core/Version.as"; //-------------------------------------------------------------------------- // // Class methods // //-------------------------------------------------------------------------- /** * @private */ private static function isMac():Boolean { return Capabilities.os.substring(0, 3) == "Mac"; } //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function TitleBar():void { super(); doubleClickEnabled = true; addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private * This is the actual object created from the _titleIcon class */ mx_internal var titleIconObject:Object; //-------------------------------------------------------------------------- // // Skin Parts // //-------------------------------------------------------------------------- //---------------------------------- // closeButton //---------------------------------- /** * The skin part that defines the Button control that corresponds to the close button. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="true")] public var closeButton:Button; //---------------------------------- // maximizeButton //---------------------------------- /** * The skin part that defines the Button control that corresponds to the maximize button. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var maximizeButton:Button; //---------------------------------- // minimizeButton //---------------------------------- /** * The skin part that defines the Button control that corresponds to the minimize button. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var minimizeButton:Button; //---------------------------------- // titleIconImage //---------------------------------- /** * The title icon in the TitleBar. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var titleIconImage:BitmapImage; //---------------------------------- // titleTextField //---------------------------------- /** * The skin part that defines the UITextField control that displays the application title text. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var titleText:TextBase; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // title //---------------------------------- /** * Storage for the title property. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ private var _title:String = ""; /** * @private */ private var titleChanged:Boolean = false; /** * The title that appears in the window title bar and * the dock or taskbar. * * @default "" * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get title():String { return _title; } /** * @private */ public function set title(value:String):void { _title = value; titleChanged = true; invalidateProperties(); invalidateSize(); invalidateDisplayList(); } //---------------------------------- // titleIcon //---------------------------------- /** * @private * Storage for the titleIcon property. */ private var _titleIcon:Class; /** * @private */ private var titleIconChanged:Boolean = false; /** * The icon displayed in the title bar. * * @default null * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get titleIcon():Class { return _titleIcon; } /** * @private */ public function set titleIcon(value:Class):void { _titleIcon = value; titleIconChanged = true; invalidateProperties(); invalidateSize(); } //---------------------------------- // window //---------------------------------- /** * The IWindow that owns this TitleBar. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ private function get window():IWindow { var p:DisplayObject = parent; while (p && !(p is IWindow)) p = p.parent; return IWindow(p); } //-------------------------------------------------------------------------- // // Overridden methods: SkinnableComponent // //-------------------------------------------------------------------------- /** * @private * * When we are running on the mac, switch to the mac skin and continue the load. * */ override protected function attachSkin():void { if (isMac() && getStyle("skinClass") == TitleBarSkin) { setStyle("skinClass", MacTitleBarSkin); } super.attachSkin(); } //-------------------------------------------------------------------------- // // Overridden methods: SkinnableContainer // //-------------------------------------------------------------------------- /** * @private */ override protected function partAdded(partName:String, instance:Object):void { super.partAdded(partName, instance); if (instance == titleText) { titleText.text = title; } else if (instance == closeButton) { closeButton.focusEnabled = false; closeButton.addEventListener(MouseEvent.MOUSE_DOWN, button_mouseDownHandler); closeButton.addEventListener(MouseEvent.CLICK, closeButton_clickHandler); } else if (instance == minimizeButton) { minimizeButton.focusEnabled = false; minimizeButton.enabled = window.minimizable; minimizeButton.addEventListener(MouseEvent.MOUSE_DOWN, button_mouseDownHandler); minimizeButton.addEventListener(MouseEvent.CLICK, minimizeButton_clickHandler); } else if (instance == maximizeButton) { maximizeButton.focusEnabled = false; maximizeButton.enabled = window.maximizable; maximizeButton.addEventListener(MouseEvent.MOUSE_DOWN, button_mouseDownHandler); maximizeButton.addEventListener(MouseEvent.CLICK, maximizeButton_clickHandler); var targetWindow:DisplayObject = DisplayObject(window); targetWindow.addEventListener( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, window_displayStateChangeHandler, false, 0, true); // Add this listener so we can remove the display state change handler // if our window is reskinned. This fixes an RTE when the titleBar // display state handler ran without a window after being reskinned. targetWindow.addEventListener(SkinPartEvent.PART_REMOVED, partRemovedHandler, false, 0, true); } } /** * @private */ override protected function partRemoved(partName:String, instance:Object):void { super.partRemoved(partName, instance); if (instance == closeButton) { closeButton.removeEventListener(MouseEvent.CLICK, closeButton_clickHandler); } else if (instance == minimizeButton) { minimizeButton.removeEventListener(MouseEvent.MOUSE_DOWN, button_mouseDownHandler); minimizeButton.removeEventListener(MouseEvent.CLICK, minimizeButton_clickHandler); } else if (instance == maximizeButton) { maximizeButton.removeEventListener(MouseEvent.MOUSE_DOWN, button_mouseDownHandler); maximizeButton.removeEventListener(MouseEvent.CLICK, maximizeButton_clickHandler); var targetWindow:DisplayObject = DisplayObject(window); targetWindow.removeEventListener( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, window_displayStateChangeHandler); targetWindow.removeEventListener(SkinPartEvent.PART_REMOVED, partRemovedHandler); } } /** * @private */ override protected function commitProperties():void { super.commitProperties(); if (titleChanged) { titleText.text = _title; titleChanged = false; } if (titleIconChanged) { if (titleIconObject) { titleIconImage.source = null; titleIconObject = null; } if (_titleIcon && titleIconImage) { titleIconObject = new _titleIcon(); titleIconImage.source = titleIconObject; } titleIconChanged = false; } } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // // Skin states support // //-------------------------------------------------------------------------- /** * Returns the name of the state to be applied to the skin. For example, a * Button component could return the String "up", "down", "over", or "disabled" * to specify the state. * *
A subclass of SkinnableComponent must override this method to return a value.
* * @return A string specifying the name of the state to apply to the skin. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ override protected function getCurrentSkinState():String { if (!window.nativeWindow.closed && window.nativeWindow.displayState == NativeWindowDisplayState.MAXIMIZED) { return enabled ? "normalAndMaximized" : "disabledAndMaximized"; } return enabled ? "normal" : "disabled"; } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * @private */ private function mouseDownHandler(event:MouseEvent):void { window.nativeWindow.startMove(); event.stopPropagation(); } /** * The method that handles adoubleClick
event in a platform-appropriate manner.
*
* @param event The event object.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
protected function doubleClickHandler(event:MouseEvent):void
{
if (isMac())
{
window.minimize();
}
else
{
if (window.nativeWindow.displayState ==
NativeWindowDisplayState.MAXIMIZED)
{
window.restore();
}
else
{
window.maximize();
}
}
}
/**
* @private
* Used to swallow mousedown so bar is not draggable from buttons
*/
private function button_mouseDownHandler(event:MouseEvent):void
{
event.stopPropagation();
}
/**
* @private
*/
private function minimizeButton_clickHandler(event:Event):void
{
window.minimize();
}
/**
* @private
*/
private function maximizeButton_clickHandler(event:Event):void
{
if (window.nativeWindow.displayState ==
NativeWindowDisplayState.MAXIMIZED)
{
window.restore();
}
else
{
window.maximize();
}
// work around for bugs SDK-9547 & SDK-21190
maximizeButton.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
}
/**
* @private
*/
private function closeButton_clickHandler(event:Event):void
{
window.close();
}
/**
* @private
*/
private function window_displayStateChangeHandler(
event:NativeWindowDisplayStateEvent):void
{
// If we have been minimized or maximized then invalidate our skin state
// so the maximize and restore buttons will be updated.
if (event.afterDisplayState == NativeWindowDisplayState.MAXIMIZED ||
event.afterDisplayState == NativeWindowDisplayState.NORMAL)
{
invalidateSkinState();
}
}
/**
* @private
*/
private function partRemovedHandler(event:SkinPartEvent):void
{
if (event.instance == this)
{
var targetWindow:DisplayObject = DisplayObject(window);
targetWindow.removeEventListener(
NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE,
window_displayStateChangeHandler);
targetWindow.removeEventListener(SkinPartEvent.PART_REMOVED, partRemovedHandler);
}
}
}
}