clluiz 0 Denunciar post Postado Fevereiro 13, 2010 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. 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
Matheus Brito 12 Denunciar post Postado Fevereiro 17, 2010 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
clluiz 0 Denunciar post Postado Fevereiro 18, 2010 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
Mário Monteiro 179 Denunciar post Postado Fevereiro 20, 2010 Seria bom se compartilhasse a solução Compartilhar este post Link para o post Compartilhar em outros sites
clluiz 0 Denunciar post Postado Fevereiro 20, 2010 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