Welcome!

Adobe Flex Authors: Matthew Lobas, PR.com Newswire, Shelly Palmer, Kevin Benedict

Related Topics: Adobe Flex, FlexSeminar.com

Adobe Flex: Article

Freely Available "SizeableTitleWindow" With Adobe's ColdFusion/Flex Connectivity

I found that Adobe includes a really nice resizeable closeable window

In playing around with the ColdFusion/Flex wizards, I found that Adobe includes a really nice resizeable closeable window.  When I get more time, I'll integrate this with my MaximizeRestorePanel class.


package com.adobe.ColdFusion.components
{
 import mx.containers.TitleWindow;
 import mx.managers.CursorManager;
 import mx.managers.ISystemManager;
 import mx.controls.Alert;
 import mx.logging.Log;
 import mx.utils.ObjectUtil;
 import mx.controls.Button;
 import flash.events.MouseEvent;
 import flash.events.Event;
 import flash.system.System;
 import flash.geom.Rectangle;
 
 public class SizeableTitleWindow extends TitleWindow
 {
   private const dragThreshold:int = 2;
   // sanity constraints. 
   private const minSizeWidth:int = 180; 
   private const minSizeHeight:int = 220;
   
   public const cursorSizeNone:int = -1;
   public const cursorSizeNE:int   = 0;
   public const cursorSizeN:int    = 1;
   public const cursorSizeNW:int   = 2;
   public const cursorSizeW:int    = 3;
   public const cursorSizeSW:int   = 4;
   public const cursorSizeS:int    = 5;
   public const cursorSizeSE:int   = 6;
   public const cursorSizeE:int    = 7;
   public const cursorSizeAll:int  = 8;
   
   [Embed(source="cursorImages/sizeNS.gif")]
   public static var sizeNSCursorSymbol:Class;

   [Embed(source="cursorImages/sizeNESW.gif")]
   public static var sizeNESWCursorSymbol:Class;
   
   [Embed(source="cursorImages/sizeWE.gif")]
   public static var sizeWECursorSymbol:Class;

   [Embed(source="cursorImages/sizeNWSE.gif")]
   public static var sizeNWSECursorSymbol:Class;
         
   [Embed(source="cursorImages/sizeAll.gif")]
   public static var sizeAllCursorSymbol:Class;

   private var downX:int;
   private var downY:int;
   private var startLeft:int;
   private var startTop:int;
   private var startHeight:int;
   private var startWidth:int;
   
   private var resizeCursor:int;
   private var currentCursorID:int;
   private var prevCursor:int;
   private var isResizing:Boolean;
   
   public function SizeableTitleWindow()
   {
    super();
    isResizing = false;
    currentCursorID = CursorManager.NO_CURSOR;
    prevCursor = cursorSizeNone;
   }
   
   override protected function createChildren():void
   {
    super.createChildren();

    // make the cursor change to the resize cursor
    this.titleBar.addEventListener(MouseEvent.MOUSE_MOVE, titleBar_resizeMoveListener);
    this.addEventListener(MouseEvent.MOUSE_MOVE, resizeMoveListener);
    
    this.addEventListener(MouseEvent.MOUSE_OUT, cursorMouseOutListener);
    
    // since the titlebar mousedown listener calls startDragging, but the listener is private
    // we will do our checking in the overridden startDragging event for the titlebar
    this.addEventListener(MouseEvent.MOUSE_DOWN, resizeDownListener);

   }
   
   protected function getCursorStyle(x:int, y:int, isTitleBar:Boolean):int
   {
    if (isResizing)
     return resizeCursor;
    
    // the NW corner has to be done in a seperate section because this
    // corner is twitchy and we add a 1 pix buffer
    if (x >= 0 && x <= dragThreshold + 1 && y >= 0 && y <= dragThreshold + 1)
    {
     return cursorSizeNW;
    } else if (x >= 0 && x <= dragThreshold)
    {
     if (y >= this.height - dragThreshold)
     {
      return cursorSizeSW;
     } else {
      return cursorSizeW;
     }
    } else if (x >= this.width - dragThreshold)
    {
     if (y >= 0 && y <= dragThreshold)
     {
      return cursorSizeNE;
     } else if (y >= this.height - dragThreshold)
     {
      return cursorSizeSE;
     } else {
      return cursorSizeE;
     }     
    } else if (y >= 0 && y <= dragThreshold)
    {
     return cursorSizeN;
    } else if (y >= this.height - dragThreshold)
    {
     return cursorSizeS;
// if you want to have the "move" style cursor when over the title bar, uncomment the next three lines     
//    } else if (isTitleBar)
//    {
//     return cursorSizeAll;
    }
    return cursorSizeNone;
   }
   
   protected function clearCursor():void
   {
    if (currentCursorID != CursorManager.NO_CURSOR)
    {
     CursorManager.removeCursor(currentCursorID);
     currentCursorID = CursorManager.NO_CURSOR;
    }
    prevCursor = cursorSizeNone;    
   }
   
   /**
    *  @protected
    *  Returns the height of the header.
    */
   protected function getHeaderHeight():Number
   {
    var headerHeight:Number = getStyle("headerHeight");
    
    if (isNaN(headerHeight))
     headerHeight = measureHeaderText().height + HEADER_PADDING;
    
    return headerHeight;
   }
   
   /**
    *  @protected. Returns a Rectangle containing the largest piece of header
    *  text (can be either the title or status, whichever is bigger).
    */
   protected function measureHeaderText():Rectangle
   {
    var textWidth:Number = 20;
    var textHeight:Number = 14;
    
    if (titleTextField && titleTextField.text)
    {
     titleTextField.validateNow();
     textWidth = titleTextField.textWidth;
     textHeight = titleTextField.textHeight;
    }
    
    if (statusTextField)
    {
     statusTextField.validateNow();
     textWidth = Math.max(textWidth, statusTextField.textWidth);
     textHeight = Math.max(textHeight, statusTextField.textHeight);
    }
    
    return new Rectangle(0, 0, textWidth, textHeight);
   }
         
   protected function adjustCursor(event:MouseEvent, isTitleBar:Boolean):void
   {
    var c:int;
    
    // we only want the move event from the title bar itself, not from it's children
    // otherwise you get weird cursor behavior in the middle of the titlebar
    if (isTitleBar && event.target != titleBar)
    {
     c = cursorSizeAll;
    } else {
     c = getCursorStyle(event.localX, event.localY, isTitleBar);
    }
    
    // don't switch stuff around if we don't have to
    if (c == prevCursor)
    {
     return;
    }
    
    prevCursor = c;
        
    clearCursor();
    
    switch (c)
    {
// if you want to have the "move" style cursor when over the title bar, uncomment the next three lines     
//     case cursorSizeAll:
//      currentCursorID = CursorManager.setCursor(sizeAllCursorSymbol, 2, -10, -10); 
//      break;
     case cursorSizeE:
     case cursorSizeW:
      currentCursorID = CursorManager.setCursor(sizeWECursorSymbol, 2, -10, -11);    
      break;
     case cursorSizeNW:
     case cursorSizeSE:
      currentCursorID = CursorManager.setCursor(sizeNWSECursorSymbol, 2, -11, -11);
      break;
     case cursorSizeNE:
     case cursorSizeSW:
      currentCursorID = CursorManager.setCursor(sizeNESWCursorSymbol, 2, -11, -10);
      break;
     case cursorSizeN:
     case cursorSizeS:
      currentCursorID = CursorManager.setCursor(sizeNSCursorSymbol, 2, -10, -10);
      break;
    }
   }
      
   protected function titleBar_resizeMoveListener(event:MouseEvent):void
   {
    if (event.target is Button)
    {
     //the base class doesn't give me access to "closeButton", so this
     //is the only way to check if we are over the button
     clearCursor();
     return;
    }

    adjustCursor(event, true);
   }
   
   protected function resizeMoveListener(event:MouseEvent):void
   {
    if (event.localY > getHeaderHeight())  //don't do it twice, the title bar takes care of it
    {
     adjustCursor(event, false);
    }
   }
   
   override protected function startDragging(event:MouseEvent):void
   {
    // check for the threshholds first, 
    // if we are within the threshold do our stuff, else call super
    var cursorStyle:int = getCursorStyle(event.localX, event.localY, true);
    if (cursorStyle != cursorSizeNone && cursorStyle != cursorSizeAll )
    {
     startSizing(cursorStyle, event.stageX, event.stageY);
    } else {
     super.startDragging(event);
    }
   }
   
   protected function resizeDownListener(event:MouseEvent):void
   {
    // check for the threshholds first,
    // if we are within the threshold do our stuff, else call super
    var cursorStyle:int = getCursorStyle(event.localX, event.localY, false);
    if (cursorStyle != cursorSizeNone && cursorStyle != cursorSizeAll)
    {
     startSizing(cursorStyle, event.stageX, event.stageY);
    }     
   }
   
   protected function startSizing(cursor:int, x:int, y:int):void
   {
    downX = x;
    downY = y;
    startHeight = this.height;
    startWidth = this.width;
    startLeft = this.x;
    startTop = this.y;
    resizeCursor = cursor;
    isResizing = true;        
        
    systemManager.addEventListener(
     MouseEvent.MOUSE_MOVE, systemManager_resizeMouseMoveHandler, true);
  
    systemManager.addEventListener(
     MouseEvent.MOUSE_UP, systemManager_resizeMouseUpHandler, true);
  
    stage.addEventListener(
     Event.MOUSE_LEAVE, stage_resizeMouseLeaveHandler);
   }   
 
   protected function stopSizing():void
   {
    isResizing = false;
    
    systemManager.removeEventListener(
     MouseEvent.MOUSE_MOVE, systemManager_resizeMouseMoveHandler, true);
  
    systemManager.removeEventListener(
     MouseEvent.MOUSE_UP, systemManager_resizeMouseUpHandler, true);
  
    stage.removeEventListener(
     Event.MOUSE_LEAVE, stage_resizeMouseLeaveHandler);

    clearCursor();
   }
   
   private function sizeWidth(event:MouseEvent):void
   {
    var tmp:int;
    tmp = startWidth + event.stageX - downX;
    if (tmp >= minSizeWidth)  
    {
     this.width = tmp;
    }    
   }

   private function sizeHeight(event:MouseEvent):void
   {
    var tmp:int;
    tmp = startHeight + event.stageY - downY;
    if (tmp >= minSizeHeight)  
    {
     this.height = tmp;
    }
   }
      
   private function sizeTop(event:MouseEvent):int
   {
    var tmp:int;
    var delta:int = downY - event.stageY;
    tmp = startHeight + delta;
    if (tmp < minSizeHeight)  
    {     
     delta = minSizeHeight - startHeight;
     tmp = startHeight + delta;     
    }
    
    this.height = tmp;
    return delta;
//    return 0;
   }

   private function sizeLeft(event:MouseEvent):int
   {
    var tmp:int;
    var delta:int = downX - event.stageX;
    tmp = startWidth + delta;
    if (tmp < minSizeWidth)  
    {
     delta = minSizeWidth - startWidth;
     tmp = startWidth + delta;
    }
    
    this.width = tmp;
    return delta;
//    return 0;
   }

   /**
    *  @private
    */
   private function systemManager_resizeMouseMoveHandler(event:MouseEvent):void
   {
    var leftDelta:int=0;
    var topDelta:int=0;    
    switch (resizeCursor)
    {
     case cursorSizeE:
      sizeWidth(event);
      break;
     case cursorSizeSE:
      sizeWidth(event);
      sizeHeight(event);
      break;      
     case cursorSizeS:
      sizeHeight(event);
      break;
     case cursorSizeSW:
      leftDelta = sizeLeft(event);
      sizeHeight(event);
      break;
     case cursorSizeW:
      leftDelta = sizeLeft(event);
      break;
     case cursorSizeNW:
      topDelta = sizeTop(event);
      leftDelta = sizeLeft(event);
      break;
     case cursorSizeN:
      topDelta = sizeTop(event);
      break;
     case cursorSizeNE:
      topDelta = sizeTop(event);
      sizeWidth(event);
      break;
    }
    
    // when sizing, we only want to do the move once (multiple moves cause ugly refresh problems)
    // a move happens when dragging involves the left or top side    
    if (leftDelta != 0 || topDelta != 0)
    {
     move(startLeft - leftDelta, startTop - topDelta);
    }
   }
       
   /**
    *  @private
    */
   private function systemManager_resizeMouseUpHandler(event:MouseEvent):void
   {
    stopSizing();
   }
  
   /**
    *  @private
    */
   private function stage_resizeMouseLeaveHandler(event:Event):void
   {
    stopSizing();
   }   
   
   private function cursorMouseOutListener(event:MouseEvent):void
   {
    if (!isResizing)
    {
     clearCursor();
    }
   }
  
 }
}

You can find the associated images for this class in the zip file here.

posted Friday, 9 June 2006

More Stories By Flex News Desk

Flex News Desk provides the very latest news on the cross-platform Flex development framework for creating rich Internet applications, and on Adobe's AIR/Flex/Flash product combination.

Comments (3)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
In an age of borderless networks, security for the cloud and security for the corporate network can no longer be separated. Security teams are now presented with the challenge of monitoring and controlling access to these cloud environments, at the same time that developers quickly spin up new cloud instances and executives push forwards new initiatives. The vulnerabilities created by migration to the cloud, such as misconfigurations and compromised credentials, require that security teams t...
AI and machine learning disruption for Enterprises started happening in the areas such as IT operations management (ITOPs) and Cloud management and SaaS apps. In 2019 CIOs will see disruptive solutions for Cloud & Devops, AI/ML driven IT Ops and Cloud Ops. Customers want AI-driven multi-cloud operations for monitoring, detection, prevention of disruptions. Disruptions cause revenue loss, unhappy users, impacts brand reputation etc.
Today's workforce is trading their cubicles and corporate desktops in favor of an any-location, any-device work style. And as digital natives make up more and more of the modern workforce, the appetite for user-friendly, cloud-based services grows. The center of work is shifting to the user and to the cloud. But managing a proliferation of SaaS, web, and mobile apps running on any number of clouds and devices is unwieldy and increases security risks. Steve Wilson, Citrix Vice President of Cloud,...
As the fourth industrial revolution continues to march forward, key questions remain related to the protection of software, cloud, AI, and automation intellectual property. Recent developments in Supreme Court and lower court case law will be reviewed to explain the intricacies of what inventions are eligible for patent protection, how copyright law may be used to protect application programming interfaces (APIs), and the extent to which trademark and trade secret law may have expanded relev...
Cloud computing, big data and AI provide a new impetus and urgency to traditional enterprises to become digitally transformed businesses as they face disruption from new players who leverage technology to foster new business models. Traditionally, enterprises focused on digitizing processes and transactions. The incumbents can also be disruptors by leveraging AI for data-driven insights and innovate at scale on Cloud platform. They need to uncover the power of ERP/SAP using Cloud, AI and Big dat...
When Enterprises started adopting Hadoop-based Big Data environments over the last ten years, they were mainly on-premise deployments. Organizations would spin up and manage large Hadoop clusters, where they would funnel exabytes or petabytes of unstructured data.However, over the last few years the economics of maintaining this enormous infrastructure compared with the elastic scalability of viable cloud options has changed this equation. The growth of cloud storage, cloud-managed big data e...
Your applications have evolved, your computing needs are changing, and your servers have become more and more dense. But your data center hasn't changed so you can't get the benefits of cheaper, better, smaller, faster... until now. Colovore is Silicon Valley's premier provider of high-density colocation solutions that are a perfect fit for companies operating modern, high-performance hardware. No other Bay Area colo provider can match our density, operating efficiency, and ease of scalability.
The Japan External Trade Organization (JETRO) is a non-profit organization that provides business support services to companies expanding to Japan. With the support of JETRO's dedicated staff, clients can incorporate their business; receive visa, immigration, and HR support; find dedicated office space; identify local government subsidies; get tailored market studies; and more.
The graph represents a network of 1,329 Twitter users whose recent tweets contained "#DevOps", or who were replied to or mentioned in those tweets, taken from a data set limited to a maximum of 18,000 tweets. The network was obtained from Twitter on Thursday, 10 January 2019 at 23:50 UTC. The tweets in the network were tweeted over the 7-hour, 6-minute period from Thursday, 10 January 2019 at 16:29 UTC to Thursday, 10 January 2019 at 23:36 UTC. Additional tweets that were mentioned in this...
Artificial intelligence, machine learning, neural networks. We're in the midst of a wave of excitement around AI such as hasn't been seen for a few decades. But those previous periods of inflated expectations led to troughs of disappointment. This time is (mostly) different. Applications of AI such as predictive analytics are already decreasing costs and improving reliability of industrial machinery. Pattern recognition can equal or exceed the ability of human experts in some domains. It's devel...