Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

clluiz

[Resolvido] Como fazer um menu com abas

Recommended Posts

Olá a todos, sou novo no fórum e também com a tecnologia Flex, já que comecei a trabalhar com ela em janeiro deste ano.

 

Meu problema é o seguinte: eu quero fazer um menu retrátil e que tenha uma aba para que o usuário possa clicar para mostrá-lo. Como na figura (mal feita abaixo) fiz apenas para mostrar o que pretendo.

 

De início apenas aba irá aparecer e quando o usuário clicar nela o menu se expande.

 

Imagem Postada

 

A lógica para fazer o menu se movimentar eu sei.

 

Mas não estou conseguindo achar um modo de colocar aquela "aba" no menu.

Minha idéia inicial para tentar conseguir este formato foi herdar um HBox e dentro dele colocar dois VBox, um iria representar a parte em que apareceriam as opções do menu e o outro seria a aba.

 

Mas essa idéia não funcionou muito. Então pergunto:

 

É possível colocar essa aba no menu usando flex? Ou alguma sugestão para conseguir um efeito semelhante?

 

Obrigado pela atenção.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não sei se é possível, só que se for você tera que trabalhar com States e transitions, para o efeito que quer, mas acredito que de pra fazer sim.

Abs

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegui fazer. Para alcançar este objetivo eu criei um componente que extende um TabNavigator e coloquei a aba centralizada. Os efeitos para movimentas foram mais fáceis de fazer.

 

Ps. se alguem quiser ver o código é só pedir.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Seria bom se compartilhasse a solução

Compartilhar este post


Link para o post
Compartilhar em outros sites

Este é o código do componente:

 

package br.ufla.lemaf.ref.utils
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;

	import mx.core.Container;
	import mx.core.EdgeMetrics;
	import mx.core.IFlexDisplayObject;
	import mx.core.IInvalidating;
	import mx.core.mx_internal;
	
	import mx.effects.Effect;
	import mx.effects.Move;
	
	import mx.events.FlexEvent;
	import mx.events.ResizeEvent;
	
	import mx.managers.PopUpManager;
	import mx.skins.ProgrammaticSkin;
	import mx.effects.easing.Sine;
	import mx.containers.TabNavigator;
	import mx.controls.Button;

	use namespace mx_internal;
	
	[Style(name="verticalAlign", type="String", enumeration="top,middle,bottom", inherit="no")]
	public class DockTab extends TabNavigator
	{
		
		// Constantes
		private static const MIN_TAB_WIDTH:Number = 30;
		private static const TAB_HEIGHT:Number = 100;
		private static const TAB_WIDTH:Number = 30;
		
        private var showing:Boolean;
		
		private var realParent:Container;
		
		private var moveEffect:Move;
		
		private var useEasingFunction:Boolean = true;
		
		/// devido à rotação da aba foi preciso usar um artifício para 
		/// que os botões tivessem o comportamento desejado
		[Embed(source="assets/arrow-up-double.png")]
		[Bindable]
		private var hiddenIcon:Class;
				
		[Embed(source="assets/arrow-down-double.png")]
		[Bindable]
		private var showingIcon:Class;
		
		[Inspectable]
		public var initiallyShowing:Boolean = false;
			
		public function DockTab()
		{
			super();
			this.styleName = "MyTabNavigator";
			this.addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
		}
		
		
		// ------- Tratamento de eventos -------------------------------------------------- //
		private function creationCompleteHandler(ev:FlexEvent):void
		{
			
			this.removeEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
			
			realParent = parent as Container;
			
			// remove da lista de filhos
			realParent.removeChild(this);
			
			this.initialized = true;
			
			// adiciona como Popup
			PopUpManager.addPopUp(this, realParent);
			
			// Adiciona os eventos 
			this.addEventListener(MouseEvent.CLICK, onClick);
			var button:Button; 
			button = this.getTabAt(0) as Button;
			button.addEventListener(MouseEvent.MOUSE_DOWN, onClick);
			 
			realParent.addEventListener(ResizeEvent.RESIZE, onParentResize);
			 
			this.visible = false;
			onParentVisibilityChange(null);
			onParentResize(null);
			 
			showing = initiallyShowing;
			
			// Seta os ícones
			if(initiallyShowing) button.setStyle("icon", showingIcon);
			else button.setStyle("icon", hiddenIcon);
		}
		
		public function onClick(event:MouseEvent):void {
			
			var button:Button = this.getTabAt(0) as Button;
			
			if(showing) { 
				
				showing = false; 
				button.setStyle("icon", hiddenIcon);
				animate(showing);
			
			} else { 
				
				showing = true; 
				button.setStyle("icon", showingIcon);
				animate(showing);
			}
		}

		// ------- Métodos para fazer o TabNavigator Vertical ----------------------------- //
		
		protected function get tabBarHeight():Number {
			return tabBar.getExplicitOrMeasuredWidth();
		}
		
		protected function get tabBarWidth():Number {
			var tabWidth:Number = getStyle("tabHeight");
			
			if (isNaN(tabWidth))
				tabWidth = tabBar.getExplicitOrMeasuredHeight();
			
			return tabWidth - 1;
		}

		override protected function createChildren() : void {
			
			super.createChildren();
			if (tabBar) {
				tabBar.setStyle("paddingLeft", 0);
				tabBar.setStyle("paddingRight", 0);
				tabBar.toolTip = "Menu";
			}
		}		
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void {
			
			super.updateDisplayList(unscaledWidth, unscaledHeight);

			// determina o tamanho do TabBar 
			var vm:EdgeMetrics = viewMetrics;

			tabBar.setActualSize(TAB_HEIGHT,TAB_WIDTH);
			
			var vAlign:String = getStyle("verticalAlign");
			var allowedVerticalAlignValues:Array = ["top", "bottom", "middle"];
			if (allowedVerticalAlignValues.indexOf(vAlign) == (-1)) vAlign="top";
			
			tabBar.rotation = 90;
			
			if (vAlign == "top") tabBar.move(unscaledWidth,0);
			else if (vAlign == "middle") tabBar.move(unscaledWidth,(unscaledHeight/2-tabBar.width/2));
			else if (vAlign == "bottom") tabBar.move(unscaledWidth,unscaledHeight-tabBar.width);
		}
		
		override protected function measure() : void {
			
			super.measure();
			
			// remove o acréscimo de algura feito pela superclasse 
			// as abas agora estão ao lado não no topo
			var removedHeight:Number = tabBarWidth;
			measuredMinHeight -= removedHeight;
			measuredHeight -= removedHeight;
			
			// adiciona largura pela mesma razão acima
			var addedWidth:Number = tabBarWidth;
			measuredMinWidth += addedWidth;
			measuredWidth += addedWidth;
			
			// assegurar que existe espaço suficiente 
			// para desenhar todas as abas em seu tamanho mínimo
			var tabWidth:Number = getStyle("tabWidth");
			if (isNaN(tabWidth)) tabWidth = 0;
			
			var minTabBarWidth:Number = numChildren * Math.max(tabWidth, MIN_TAB_WIDTH);
			
			// acrescenta métricas de visão
			var vm:EdgeMetrics = viewMetrics;
			minTabBarWidth += (vm.top + vm.bottom);
			
			// acrescenta gaps horizontais
			if (numChildren > 1) 
				minTabBarWidth += (getStyle("horizontalGap") * (numChildren - 1));
			
			if (measuredHeight < minTabBarWidth) measuredHeight = minTabBarWidth+tabBarWidth;
		}
		
		override protected function get contentHeight():Number {

			// desfaz o ajuste de altura de conteúdo feito pela superclasse
			return super.contentHeight + tabBarWidth;
		}
		
		override protected function get contentWidth():Number {

			// ajusta a largura do conteudo para acomodar o TabBar
			var vm:EdgeMetrics = viewMetricsAndPadding;
			
			var vmLeft:Number = vm.left;
			var vmRight:Number = vm.right;
			
			if (isNaN(vmLeft))
				vmLeft = 0;
			if (isNaN(vmRight))
				vmRight = 0;
			
			return unscaledWidth - tabBarWidth - vmLeft - vmRight;
		}
		
		override protected function get contentX():Number {
			
			// ajusta a posição do conteudo para acomodar o TabBar
			var paddingLeft:Number = getStyle("paddingLeft");
			
			if (isNaN(paddingLeft))
				paddingLeft = 0;
			
			return paddingLeft;
		}
		
		override protected function get contentY():Number {
			
			// desfaz o ajuste da posição do conteudo feito pela superclasse
			return super.contentY - tabBarWidth;
		}
		
		override protected function adjustFocusRect(object:DisplayObject = null):void {
			super.adjustFocusRect(object);
			
			// desfaz mudanças feitas pela superclasse
			// Ajusta o foco para ficar abaixo das abas
			// e faz a mesma coisa com a largura ao inves da altura
			var focusObj:IFlexDisplayObject = IFlexDisplayObject(getFocusObject());
			
			if (focusObj)
			{
				focusObj.setActualSize(focusObj.width - tabBarWidth, focusObj.height + tabBarWidth);
				
				focusObj.move(focusObj.x, focusObj.y - tabBarWidth);
				
				if (focusObj is IInvalidating)
					IInvalidating(focusObj).validateNow();
					
				else if (focusObj is ProgrammaticSkin)
					ProgrammaticSkin(focusObj).validateNow();
			}
		}
		
		override protected function layoutChrome(unscaledWidth:Number, unscaledHeight:Number):void {
			super.layoutChrome(unscaledWidth, unscaledHeight);
			
			// desfaz mudanças feitas pela superclasse
			// Move a borda para deixar espaço para as abas
			// e faz a mesma coisa com a largura ao inves da altura
			if (border)
			{
				var borderOffset:Number = tabBarWidth;
				border.setActualSize(unscaledWidth - borderOffset, unscaledHeight);
				border.move (0, 0);
			}
		}
		
		// -------------------------------------------------------------------------------- //
		
		// -------------------- Métodos para posicionamento e Animação -------------------- //
		private function onParentResize(event: ResizeEvent):void {
			
							
			// altera as medidas para serem as mesma do componente pai
				if (height != realParent.height)
					height = realParent.height;

			// Pega a nova posição 
			var shouldShow:Boolean;
			
			if(initiallyShowing) shouldShow = true;
			else shouldShow = showing;
						
			var point:Point = getPosition(shouldShow);
			setPosition(point);
		}
		
		private function onParentVisibilityChange(event:Event):void {
			
			if (this.visible != realParent.visible) {
				this.visible = realParent.visible;
			}
		}
		
		private function fitToBounds():void {
			
			// Pega as coordenadas máximas da Doca
			var actualXEnd:Number = this.x + this.width;
			var actualYEnd:Number = this.y + this.height;
			
			// Pega as coordenadas atuais
			var newPoint:Point = new Point(this.x, this.y);
			
			// Modificada as coordenadas somente onde é necessário
			if (realParent.width < actualXEnd)
				newPoint.x = Math.max(0, realParent.width - this.width - 10);
			
			if (realParent.height < actualYEnd)
				newPoint.y = Math.max(0, realParent.height - this.height - 10);
			
			// Ajusta a posição
			setPosition(newPoint);
		}
		
		private function getPosition(visible:Boolean):Point {
			
			var point:Point;
			
			if (visible)
				point = new Point(0,0);
			else
				point = new Point(-width + 31, 0);
			
			point = realParent.localToGlobal(point);
			return point;
		}
		
		private function setPosition(point:Point):void {
			x = point.x;
			y = point.y;
		}
		
		private function animate(shouldShow: Boolean):Effect
		{
			var moveTo:Point;
			
			if (moveEffect != null) {
				moveEffect.pause();
				moveEffect = null;
			}
			
			moveEffect = new Move(this);
			
			moveTo = getPosition(shouldShow);
			
			moveEffect.xTo = moveTo.x;
			moveEffect.yTo = moveTo.y;
			
			if (useEasingFunction) {
				
				if (moveTo.y < 0) {
					moveEffect.duration = 500;
					moveEffect.easingFunction = Sine.easeIn;
				} else {
					moveEffect.duration = 1000;
					moveEffect.easingFunction = Sine.easeOut;
				}
				
			}
			
			moveEffect.play();
			return moveEffect;
		}
		
	}
}

E o CSS:

 

/* CSS file */

/* fonte embutida */
@font-face {
	src:url("Charrington.ttf");
	fontFamily: myFont;
	advancedAntiAliasing: true;
}

/* fonte embutida, negrito */
@font-face {
	src:url("CharringtonBold.ttf");
	fontFamily: myFont;
	advancedAntiAliasing: true;
	fontWeight: bold;
}

.MyTabNavigator {
	backgroundColor: #808080;
	backgroundAlpha: 0.5;
	cornerRadius: 10;
	tabStyleName: "MyTabs";
	firstTabStyleName: "MyFirstTab";
	lastTabStyleName: "MyLastTab";
	selectedTabTextStyleName: "MySelectedTab";
	paddingLeft: 10;
	paddingRight: 100;
	borderColor: #808080;
}

.MyTabs {
	backgroundColor: #808080;
	cornerRadius: 0;
	color: black;
}

.MyFirstTab,
.MyLastTab {
	backgroundColor: #808080;
	backgroundAlpha: 0.5;
	cornerRadius: 10;
	color: black;
	fontSize: 20;
	borderColor: #808080;
}

.MySelectedTab {
	backgroundColor: haloBlue;
	color: black;
	textRollOverColor: black;
}

Basicamente é isso, mas tem que mudar os icones do menu e a fonte tb vai ter que ser baixada. Qualquer sugestão de algo que eu possa fazer melhor será bem vinda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.