Tags

, , , , , , , , , , , , , , , , ,


Bookmark and Share var addthis_pub = ‘prosenjit23’;

Recently I have been working with Adobe Flex 3 for a project of mine. Flex offers a lot of UI components out-of-the-box that can be used as is. One of them is the Panel control. The Panel is essentially a container to house other components like data grids, etc. Panels are useful when creating dashboard applications. Unfortunately Flex does not offer inbuilt maximize or restore functions on the Panel controls. Rather it is left to the developers to devise their own  mechanisms. Long story short, I had a need for it and Flex did not offer it. And so I started scouring the net for samples. There were loads of good ones but their implementations were much too complicated for my needs. Reluctantly I started working on my own prototype.

<pre style="text-align:justify;"><?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	width="598" height="620">
	<mx:Script>
		<!&#91;CDATA&#91;
			import mx.core.UIComponent;
			import mx.managers.SystemManager;
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
			import mx.managers.PopUpManager;
			import mx.containers.TitleWindow;
			import mx.core.IFlexDisplayObject;
			import mx.containers.Panel;

			// Button constants
			private static const _RESTORE_LABEL_:String = "Restore";
			private static const _MAXIMIZE_LABEL_:String = "Maximize";

			&#91;Bindable&#93;
			private var currWidth:int; // Stores the current width of the panel to be resized
			&#91;Bindable&#93;
			private var currHeight:int; // Stores the current height of the panel to be resized
			&#91;Bindable&#93;
			private var currTop:int; // Stores the current y coordinate of the panel to be resized
			&#91;Bindable&#93;
			private var currLeft:int; // Stores the current x coordinate of the panel to be resized
			&#91;Bindable&#93;
			private var isMaximized:Boolean = false; // Stores the current state of the panel as a boolean
			&#91;Bindable&#93;
			private var currIndex:int; // Stores the current index of the panel to be maximized

			/**
			 * This function orchestrates what method
			 * is called on the button click event depending on
			 * its label value.
			 */
			private function maxRestore(thePanel:Panel, minRestorBtn:Button):void
			{
				if(minRestorBtn.label == _RESTORE_LABEL_)
					restore(thePanel, minRestorBtn);
				else if(minRestorBtn.label == _MAXIMIZE_LABEL_)
					maximize(thePanel, minRestorBtn);
			}

			/**
			 * This method maximizes the specified panel to occupy the
			 * whole displayed screen area. This method can be tuned to
			 * occupy the area of its parent component rather than the parent
			 * application.
			 */
			private function maximize(thePanel:Panel, minRestorBtn:Button):void
			{
				if(!isMaximized)
				{
					// Save previous position info
					currWidth = thePanel.width;
					currHeight = thePanel.height;
					currTop = thePanel.y;
					currLeft = thePanel.x;
					currIndex = thePanel.parentApplication.getChildIndex(thePanel);

					// Set the maximized flag to true
					isMaximized = true;

					// Set current info
					thePanel.width=this.width;
					thePanel.height = this.height;
					thePanel.x = 0;
					thePanel.y = 0;

					var parentApp:UIComponent = thePanel.parentApplication as UIComponent;
					parentApp.removeChildAt(currIndex);
					parentApp.addChild(thePanel);

					// Set the button properties
					minRestorBtn.label = _RESTORE_LABEL_;
				}
			}

			/**
			 * This method restores the panel to its original location
			 * and size on the screen.
			 */
			private function restore(thePanel:Panel,minRestorBtn:Button):void
			{
				if(isMaximized)
				{
					var parentApp:UIComponent = thePanel.parentApplication as UIComponent;
					// Set the maximized flag to false
					isMaximized = false;

					// Set the button properties
					minRestorBtn.label = _MAXIMIZE_LABEL_;

					// Restore the original size and location information
					thePanel.width = currWidth;
					thePanel.height = currHeight;
					thePanel.x = currLeft;
					thePanel.y = currTop;

					// Now relocate the panel to its original position
					// in the child stack.
					parentApp.setChildIndex(thePanel,currIndex);
				}
			}
		&#93;&#93;>
	</mx:Script>

    <mx:Resize id="resize" /> <!-- This helps in the resize effect -->
    <mx:Move id="moveEffect" /> <!-- This helps in the move effect -->

	<mx:Panel id="upperPanel" x="47.5" y="35" width="500" height="142" layout="absolute"
		resizeEffect="{resize}"
		moveEffect="{moveEffect}" backgroundAlpha="1.0"
		borderAlpha="1.0" title="Top Panel">
		<mx:TextInput x="136" y="19"/>
		<mx:Button x="304" y="19" label="Button"/>
		<mx:ControlBar width="100%" alpha="1.0">
            <mx:Spacer width="100%" alpha="1.0"/>
            <mx:Button id="upperPanelMaxBtn" label="{_MAXIMIZE_LABEL_}" click="maxRestore(upperPanel, upperPanelMaxBtn)"/>
        </mx:ControlBar>
	</mx:Panel>
	<!-- This panel has the capability to maximize and restore -->
	<mx:Panel id="maxminPanel" name="maxminPanel" x="47.5" y="195" width="500" height="184"
		layout="absolute" resizeEffect="{resize}"
		moveEffect="{moveEffect}" backgroundAlpha="1.0"
		borderAlpha="1.0">
		 <mx:title>Middle Panel</mx:title>
		 <mx:DataGrid top="10" right="10" bottom="10" left="10">
		 	 <mx:columns>
		 	 	 <mx:DataGridColumn headerText="Column 1" dataField="col1"/>
		 	 	 <mx:DataGridColumn headerText="Column 2" dataField="col2"/>
		 	 	 <mx:DataGridColumn headerText="Column 3" dataField="col3"/>
		 	 </mx:columns>
		 </mx:DataGrid>
		 <mx:ControlBar width="100%" alpha="1.0">
            <mx:Spacer width="100%" alpha="1.0"/>
            <mx:Button id="maxminPanelMaxBtn" label="{_MAXIMIZE_LABEL_}" click="maxRestore(maxminPanel, maxminPanelMaxBtn)"/>
        </mx:ControlBar>
	</mx:Panel>
	<mx:Panel id="lowerPanel" x="47.5" y="403" width="500" height="197" layout="absolute"
		resizeEffect="{resize}"
		moveEffect="{moveEffect}" backgroundAlpha="1.0"
		borderAlpha="1.0" title="Bottom Panel">
		<mx:TextInput x="104" y="35"/>
		<mx:ControlBar width="100%" alpha="1.0">
            <mx:Spacer width="100%" alpha="1.0"/>
            <mx:Button id="lowerPanelMaxBtn" label="{_MAXIMIZE_LABEL_}" click="maxRestore(lowerPanel, lowerPanelMaxBtn)"/>
        </mx:ControlBar>
	</mx:Panel>
</mx:Application></pre>

This is, like I said, just a prototype. The MXML file contains a couple of methods that take in the Panel controls as parameters and work their magic. For production use, I would surely extend the Panel control to create a custom one and wire it up with the necessary behavior. I would have loved to upload my SWF file to this blog but unfortunately WordPress does not permit that (for some ridiculous reason).

The moment a UI library offers widgets like panels and windows it becomes quite obvious that people would want to have minimize, maximize, restore and resize capabilities on them (and no the resize and move effects do not help much since they do not manipulate the z-ordering of components).Unfortunately Adobe does not think it is necessary. Personally I think the guys at Adobe are being extremely lazy about this. Of course there is always an excuse of being busy doing bigger and better things. Well so much for making lives easier for developers.


Bookmark and Share var addthis_pub = ‘prosenjit23’;

Advertisements