MultiMenu ( horizontal ) ala 2advanced v.5
Оказалось довольно простой задачей на пару часов, зато выглядит шикарно...
package com.in4core.navigation { import com.greensock.TweenMax; import flash.display.DisplayObjectContainer; import flash.display.Graphics; import flash.display.Shape; import flash.events.EventDispatcher; import flash.events.MouseEvent; /** * ... * @author in4core lab */ public class MultiLevelMenu extends EventDispatcher { private var _container:DisplayObjectContainer; private var _levelsVector:Vector.<LevelContainer> = new Vector.<LevelContainer>; private namespace utils; private var _levels:int = -1; private var _xml:XML = null; private var _separatorW:int = 1; private var _separatorH:int = 1; private var _elementWidth:int = 220; private var _elementHeight:int = 20; private var _extra:String = '/'; private var _maskHeight:int = -1; public function MultiLevelMenu(container:DisplayObjectContainer , maskHeight:int) { this._maskHeight = maskHeight; this._container = container; } public function generateFromXML ( xml : XML , separatorW:int = 1, separatorH:int = 1 ) : void { this._separatorH = separatorH; this._separatorW = separatorW; this._xml = xml; this._levels = this.getOpenLevels(); const mask:Shape = new Shape(); mask.graphics.beginFill(0, 0); mask.graphics.drawRect(0, 0, _levels * ( _elementWidth + _separatorW ) , _maskHeight); mask.graphics.endFill(); mask.y = _container.y; this._container.mask = mask; this._container.parent.addChild(mask); trace('#MultiMenu openLevels : ' + _levels); this.createContainersToLevels(); this.prepareToOpenLevel(null); } private function createContainersToLevels():void { for (var i:int = 0; i < _levels ; i++ ) { const levelContainer:LevelContainer = new LevelContainer(); const g:Graphics = levelContainer.graphics; g.beginFill (0, 0); g.drawRect (0, 0, _elementWidth , _elementHeight); g.endFill (); levelContainer.x = ( _elementWidth + _separatorW ) * i; levelContainer.level = i + 1; levelContainer.addEventListener(MouseEvent.MOUSE_MOVE , onMove); this._container.addChild(levelContainer); this._levelsVector.push (levelContainer); } } private function onMove(e:MouseEvent):void { var t:LevelContainer = e.currentTarget as LevelContainer; var m:int = _maskHeight; var s:int = e.stageY; var y:int = _container.y; if (t.height > m ) t.y = int ( - ( ( t.height - m ) / m ) * (s - y ) ); } private function prepareToOpenLevel(e:MouseEvent):void { var lst:XMLList = null; var link:String = ''; var level:int = -1; var len:int = -1; if ( ! e ) { lst = _xml.children(); level = 0; } else { const curItem:Item = e.currentTarget as Item; const curCont:LevelContainer = curItem.parent as LevelContainer; level = curCont.level; lst = curItem.subLevels; link = curItem.link + _extra; this.clearNextLevels(e); } len = lst.length(); const l:LevelContainer = this._levelsVector[level]; if (lst == null || len == 0 ) return; for (var i:int = 0; i < len; i++) { const item:Item = new Item( _elementWidth , _elementHeight ); item.link = link + lst[i].@name; item.title = lst[i].@name; item.y = ( _elementHeight + _separatorH ) * i; if ( lst[i].hasComplexContent() ) { item.subLevels = lst[i].children(); item.addEventListener(MouseEvent.MOUSE_OVER , prepareToOpenLevel ); item.showIfSubMenu(); } else item.addEventListener(MouseEvent.MOUSE_OVER , clearNextLevels ); item.addEventListener(MouseEvent.CLICK , setLink); l.addChild ( item ); } if(level) TweenMax.fromTo ( l , 0.5 , { y: - l.height } , { y:0 } ); } private function setLink(e:MouseEvent):void { const tar:Item = e.currentTarget as Item; this.dispatchEvent( new MultiMenuEvent ( MultiMenuEvent.LINKED , tar.link ) ); } private function clearNextLevels(e:MouseEvent):void { var curItem:Item = e.currentTarget as Item; var curCont:LevelContainer = curItem.parent as LevelContainer; var level:int = curCont.level; for (var i:int = level; i < _levelsVector.length; i++) { this._levelsVector[i].y = 0; while ( this._levelsVector[i].numChildren ) this._levelsVector[i].removeChildAt(0); } } private function getOpenLevels():int { return _xml.@levels; } } } import com.greensock.TweenMax; import com.in4core.text.DisplayText; import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; internal class Item extends Sprite { private var _title:String; private var _link:String; private var _sh:Shape = new Shape(); private var _tf:TextField = DisplayText.addField('f_2', 8, true); private var _nx:TextField = DisplayText.addField('f_2', 8, true); private var _subLevel:XMLList; public function Item(w:int , h:int):void { _sh.graphics.beginFill(0); _sh.graphics.drawRect(0, 0, w, h); _sh.graphics.endFill(); _tf.textColor = 0xFFFFFF; _tf.text = 'test'; _tf.x = 10; _tf.width = w - 20; _tf.height = h; _nx.textColor = 0xFFFFFF; _nx.text = '>'; _nx.width = 10; _nx.height = h; _nx.x = w - _nx.width - 5; this.addChild(_sh); this.addChild(_tf); this.mouseChildren = false; this.buttonMode = true; this.addEventListener(MouseEvent.MOUSE_OVER , onOver); this.addEventListener(MouseEvent.MOUSE_OUT , onOut); _sh.alpha = 0.5; } private function onOut(e:MouseEvent):void { TweenMax.to(_sh , 0.5 , { alpha : 0.5 } ); } private function onOver(e:MouseEvent):void { TweenMax.to(_sh , 0.5 , { alpha : 0.7 } ); } public function showIfSubMenu():void { this.addChild(_nx); } public function set title(n:String):void { _title = n; _tf.text = _title; } public function set subLevels(xmlList:XMLList):void { _subLevel = xmlList; } public function get title():String { return _title; } public function get subLevels():XMLList{ return _subLevel; } public function get link():String { return _link; } public function set link(value:String):void { _link = value; } } internal class LevelContainer extends Sprite { private var _level:int; public function LevelContainer( ) { super(); } public function get level():int { return _level; } public function set level(value:int):void { _level = value; } }
Да, и нафига тут неймспейс... а для понта)
На самом деле, писать метод для просчета макс кол-ва нодов мне стало лень, поэтому вынес кол-во уровней в атрибут хмл.
Ну вот получилось под-копирку как у 2A, только на as3. Странно, что в сети, реализаций такого меню я не нашел, может конечно и есть где, хз.
Код:
<?xml version="1.0" encoding="utf-8" ?> <core levels="4"> <item name="item1"> <item name="subitem1"></item> <item name="subitem2"></item> <item name="subitem8"></item> <item name="subitem9"></item> <item name="subitem10"></item> <item name="subitem11"></item> <item name="subitem12"></item> <item name="subitem13"></item> </item> <item name="item2"></item> <item name="item3"></item> <item name="item4"></item> <item name="item5"> <item name="subitem1"> <item name="SSsubitem4"></item> <item name="SSsubitem5"></item> <item name="SSsubitem6"></item> </item> <item name="subitem2"> <item name="SSsubitem7"></item> <item name="SSsubitem8"></item> <item name="SSsubitem9"></item> </item> <item name="subitem3"> <item name="SSsubitem10"></item> <item name="SSsubitem11"></item> <item name="SSsubitem12"> <item name="level4"></item> <item name="level4"></item> <item name="level4"></item> <item name="level4"></item> <item name="level4"></item> <item name="level4"></item> <item name="level4"></item> </item> </item> </item> </core>
P.s. для скроллинга использую метод Wolsh всегда и везде, за что ему и огромное спасибо.
Всего комментариев 56
Комментарии
26.01.2012 15:07 | |
@Zebestov это делают 95% современных контролов и в 99% это оправданно. В свете stage3d и новых 2d движков (starling, nd2d и др.) вполне возможно появление контролов, которые не будут наследоваться от Sprite, но даже они не посмеют, чтото добавлять в родителя родитебя
@HardCoder ответ в комменте выше. Лишь добавлю. Вы правы. Я даже больше скажу, удаляться даже объекты с подписаными событиями, но удаляться далеко не сразу и его долго будут висеть в оперативке. А потом по интернету ходят скрины, как флеш банер отожрал всю оперативку и весь процессор. В juick.com точно была |
|
Обновил(-а) Dima_DPE 26.01.2012 в 15:11
|
26.01.2012 15:34 | |
Обновил(-а) Dima_DPE 26.01.2012 в 15:36
|
26.01.2012 16:25 | |
это другое, согласен, больше интересно конечно через e4x )
|
26.01.2012 16:53 | |
Да читаемость падает. Я все таки думал в одну строку можно уложить, жаль
|
Последние записи от in4core
- Система диалогов, создаем подобие old School типа Fallout. (07.05.2014)
- MVC в игорной индустрии (27.11.2012)
- Якорь мне .... ))) Или History API (06.11.2012)
- FSD - учим php/sql (28.06.2012)
- I4Logger - простой и компактный логгер (06.05.2012)