Skip to content

Instantly share code, notes, and snippets.

@newtriks
Created August 2, 2010 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save newtriks/505255 to your computer and use it in GitHub Desktop.
Save newtriks/505255 to your computer and use it in GitHub Desktop.
package
{
import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.ui.Keyboard;
import mx.controls.PopUpButton;
import mx.core.UIComponent;
import mx.core.UIComponentGlobals;
import mx.core.mx_internal;
import mx.effects.Tween;
import mx.events.InterManagerRequest;
import mx.managers.ISystemManager;
import mx.managers.PopUpManager;
use namespace mx_internal;
public class PopUpCombo extends PopUpButton
{
protected var _isOpen:Boolean = false;
protected var _inTween:Boolean = false;
protected var _tween:Tween;
private var _specificOpenDirection:String;
public static const OPEN_UP:String = "OPEN_UP";
public static const OPEN_DOWN:String = "OPEN_DOWN";
public function PopUpCombo()
{
super();
}
public function get specificOpenDirection():String
{
if(!_specificOpenDirection) _specificOpenDirection = PopUpCombo.OPEN_DOWN;
return _specificOpenDirection;
}
public function set specificOpenDirection(value:String):void
{
_specificOpenDirection = value;
}
override protected function clickHandler(event:MouseEvent):void
{
event.stopImmediatePropagation();
displayPopUp();
}
override protected function keyDownHandler(event:KeyboardEvent):void
{
super.keyDownHandler(event);
if (event.ctrlKey && event.keyCode == Keyboard.DOWN)
{
event.stopImmediatePropagation();
displayPopUp();
}
}
public function displayPopUp():void
{
var show:Boolean = !_isOpen;
var popUpGap:Number = getStyle("popUpGap");
var point:Point = new Point(0, unscaledHeight + popUpGap);
point = localToGlobal(point);
var initY:Number;
var endY:Number;
var easingFunction:Function;
var duration:Number;
if (popUp.parent == null)
{
PopUpManager.addPopUp(popUp, this, false);
popUp.owner = this;
}
else
PopUpManager.bringToFront(popUp);
if(show)
{
if(specificOpenDirection == PopUpCombo.OPEN_UP)
{
point.y -= (unscaledHeight + popUp.height + 2*popUpGap);
initY = -popUp.height;
}
else
{
initY = popUp.height;
}
point.x = Math.min( point.x, visibleScreen.right - popUp.getExplicitOrMeasuredWidth());
point.x = Math.max( point.x, 0);
point = popUp.parent.globalToLocal(point);
if (popUp.x != point.x || popUp.y != point.y)
popUp.move(point.x, point.y);
popUp.scrollRect = new Rectangle(0, initY,
popUp.width, popUp.height);
if (!popUp.visible)
popUp.visible = true;
endY = 0;
_isOpen = show;
duration = getStyle("openDuration");
easingFunction = getStyle("openEasingFunction") as Function;
}
else
{
_isOpen = show;
if (popUp.parent == null)
return;
point = popUp.parent.globalToLocal(point);
endY = (specificOpenDirection == PopUpCombo.OPEN_UP) ? -popUp.height - 2 : popUp.height + 2;
initY = 0;
duration = getStyle("closeDuration")
easingFunction = getStyle("closeEasingFunction") as Function;
}
_inTween = true;
UIComponentGlobals.layoutManager.validateNow();
// Block all layout, responses from web service, and other background
// processing until the tween finishes executing.
UIComponent.suspendBackgroundProcessing();
_tween = new Tween(this, initY, endY, duration);
if (easingFunction != null)
_tween.easingFunction = easingFunction;
}
protected function get visibleScreen():Rectangle
{
var sm:ISystemManager = systemManager.topLevelSystemManager;
var sbRoot:DisplayObject = sm.getSandboxRoot();
var _screen:Rectangle;
if (sm != sbRoot)
{
var request:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST,
false, false,
"getVisibleApplicationRect");
sbRoot.dispatchEvent(request);
_screen = Rectangle(request.value);
}
else
_screen = sm.getVisibleApplicationRect();
return _screen;
}
override mx_internal function onTweenUpdate(value:Number):void
{
popUp.scrollRect =
new Rectangle(0, value, popUp.width, popUp.height);
}
override mx_internal function onTweenEnd(value:Number):void
{
popUp.scrollRect =
new Rectangle(0, value, popUp.width, popUp.height);
_inTween = false;
UIComponent.resumeBackgroundProcessing();
if (!_isOpen)
{
popUp.visible = false;
popUp.scrollRect = null;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/02/11/determining-if-a-check-box-menu-item-is-toggled-in-a-flex-popupbutton-controls-pop-up-menu/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white"
xmlns:local="*">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.Menu;
import mx.events.DropdownEvent;
import mx.events.MenuEvent;
private var menu:Menu;
private function init():void {
menu = new Menu();
menu.variableRowHeight = true;
menu.dataProvider = arr;
menu.addEventListener(MenuEvent.CHANGE, menu_change);
popUpButton.popUp = menu;
}
private function menu_change(evt:MenuEvent):void {
popUpButton.displayPopUp();
}
]]>
</mx:Script>
<mx:Array id="arr">
<mx:Object label="Option 1"
type="label"/>
<mx:Object label="Option 2"
type="label"/>
</mx:Array>
<local:PopUpCombo id="popUpButton"
openAlways="true"
label="Click to open..."
specificOpenDirection="{PopUpCombo.OPEN_UP}"
initialize="init();" />
</mx:Application>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment