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
Комментарии
25.01.2012 16:19 | |
25.01.2012 16:26 | |
Я вообще то всегда так пишу, когда final ( конечно если сравнить с кодом рулеточные столы... - но там суть была не в коде, а в реализации вообщем то) , пример AdvancedMovieClip - такой же чистый код. Ну скобки так генеририует FD я обычно на это уже внимания не обращаю, может есть какая то настройка, чтобы скобки делал нормально? И кстати в новом FD бесит автогенератор приватов this.private = private , вместо того как было раньше _private = private
|
|
Обновил(-а) in4core 25.01.2012 в 16:37
|
25.01.2012 16:43 | |
25.01.2012 16:51 | |
люди неглупые приват и напишут, а не будут вспенивать мозг читателям
|
25.01.2012 16:53 | |
Подменю всегда открываются сверху (на уровне первого элемента), перейти с нижнего пункта меню на подменю практически нереально.
|
25.01.2012 16:55 | |
Цитата:
Ну скобки так генеририует FD
|
25.01.2012 16:57 | |
25.01.2012 17:05 | |
Котяра, это мой стиль и все. Котяра, нет наверное не пользуюсь, я никаких плагов в фд не ставил, вообщем то всегда хватало и того функционала , что есть. Что посоветуешь?
|
25.01.2012 17:06 | |
alatar не понял где и что нереально, по мне все очень удобно, так как и должно быть.
Сменил на приват. alatar только , что проверил у 2А точно так же. А если они для Вас, не являются эталоном того как надо делать навигацию, то для меня - да |
|
Обновил(-а) in4core 25.01.2012 в 17:10
|
25.01.2012 17:11 | |
Мнение программиста очень часто расходится с мнением конечного пользователя. Я про понятность и удобство. Ваш вариант меню имеет право на жизнь, но скролы подменю не интуитивные, нет визуального прогрессбара, а значит не понятно сколько там еще. И не говорите мне, что положение курсора по оси ординат и есть этот визуальный прогресс. Это понимают программисты, но не юзеры.
Всплывающие подменю всегда на уровне первого элемента - это тоже ваше право, но в 95% подменю вырастает на уровне пункта меню (win, mac, linux проверено). Все выше сказанно не в коем случае не говорит, что ваше меню плохое. Оно прекрасно, но для некоторых людей оно не интуитивно, на что я и попытался указать. |
|
Обновил(-а) Dima_DPE 25.01.2012 в 17:16
|
25.01.2012 17:14 | |
Dima_DPE , собственно я ответил на этот вопрос выше. Если же делать визуальные скроллы будет выглядеть не кашерно, но проблем добавить видимый скролл 2 строчками кода, я не вижу.
Dima_DPE собственно я вас и понял, никаких вопросов не имею, у каждого просто свое мнение, кому как удобно. И опять же повторюсь сделать так, как на мак и вин ( проверено ) сложности никакой нет, допилить под себя дело 10 минут |
|
Обновил(-а) in4core 25.01.2012 в 17:23
|
25.01.2012 17:24 | |
А мне понравилось - все интуитивно понятно и без глюков. Неожиданно.
|
25.01.2012 17:26 | |
Цитата:
alatar не понял где и что нереально, по мне все очень удобно, так как и должно быть.
|
25.01.2012 17:37 | |
Вот еще бы магические константы в именованные вынести.
|
25.01.2012 17:40 | |
alatar имеет в виду http://dl.************/u/6132064/menu.png - обычно в меню пункты выпадают на уровне родителя, а тут сверху. Когда начинаешь двигать мышку к ним, пересекаешь другие, и подменю тютю. А так неожиданно красиво сделано.
|
25.01.2012 17:41 | |
Цитата:
Вот еще бы магические константы в именованные вынести.
|
25.01.2012 17:42 | |
Волгоградец , GBee - спасибо.
Насчет неожиданно тока обидно, я навигационных элементов много написал в своей жизни, это так скажем мой хлеб, тоесть на as у меня вообщем то и специализация создание программно-визуальных интерфейсов клиентских приложений. С другой стороны, я просто не выкладываю их суда, дабы каждый для себя пишет подобные штуки, а вот с меню, ссылок в нете не нашел, поэтому выложил. |
|
Обновил(-а) in4core 25.01.2012 в 17:48
|
25.01.2012 20:16 | |
Самое интересное "ala advanced v.5" - это наверное, чтобы новичков заманить. А так - прогресс на лицо. Ещё год и можешь браться за свой собственный MMORPG! =)
|
25.01.2012 20:31 | |
А можно пример стратегий для которых не надо года?)
|
25.01.2012 22:00 | |
Оч круто! in4core, если так дальше дело пойдет, то вам нужно блатоваться в могучую кучку flex-team. Подвиньте их там хорошенько, а то делают как на АвтоВАЗе, — тормоза какие-то.
|
25.01.2012 22:08 | |
fish_r - пруф давно висит ) читайте внимательнее
|
25.01.2012 22:52 | |
Дык я о том же. Щаз поднаторишь — и в путь!
|
25.01.2012 23:00 | |
еще бы уметь собирать это все во фреймворк типа флекса, чтобы к FD подключать например, swc - не кашерно )
|
25.01.2012 23:31 | |
Цитата:
если не нравится как выглядит - напишите свой
|
|
Обновил(-а) fish_r 25.01.2012 в 23:35
|
26.01.2012 00:50 | |
Почему вместо замечаний о том, что хотелось бы добавить вот этого у тебя всегда ответы в стиле — добавь сам, напиши свой и вообще так задумано?
|
26.01.2012 00:56 | |
Меня больше интересует вопрос - почему ты суешь свой нос все время в мою сторону по поводу холивара в 95% и только в 5% по коду ? Может тебе мальчики нравятся , а мой смазливый аватар тебя просто возбуждает ?
P.s. если тебе вдруг не нравится такое общение, то подумай сам, как ты общаешься в таком же ключе тогда, когда к тебе разговор отношения не имеет во первых, во вторых когда разговор идет безобидный и никого не обижающий, а ты лезешь со своими комментариями с оскарблениями. Пример : вот щас ты написал вполне нормальный вопрос, но получил вполне нормальный пинок |
|
Обновил(-а) in4core 26.01.2012 в 01:01
|
26.01.2012 01:35 | |
Досадно, меня раскусили.
Оскорблениями. Через "о". |
26.01.2012 13:45 | |
По коду, так по коду (далее то, что бросилось в глаза при чтении кода):
Далее, более мелкие замечания:
Смертные грехи по моему мнению:
Заключиние: Есть мнение, что люди, которые не разобрались как работает flex и его контролы, очень часто называют его всякими обидными словами, а ведь flex не так плох. В конце концов на его примере можно было научиться как контролы писать нельзя. |
|
Обновил(-а) Dima_DPE 26.01.2012 в 13:55
|
26.01.2012 13:46 | |
Mur4ik Есть такой косяк, но в мат я не силен, и как модифцировать Wolsh формулу я не знаю. Если подскажите, буду признателен
|
26.01.2012 14:36 | |
Фразы "мой подход", "мой стиль", "мой личный подход" особенно бесят, в ответ из цензуры на ум приходит только фраза "не сработаемся". Это не аргумент, это отмазка: "от#6ii3сь и не трогайте тут меня, каждый дрочит как хочет и я по своему". Вы просили по коду, я указал.
Цитата:
А кто вам сказал, что нельзя? Писать можно, что угодно, однако, в статье я пояснил, что написал так,чтобы просто сварить все в одном котелке, логичнее же было создавать маску отдельно от меню вообще, а в меню дергать только геттер маски контейнера для опознавания высоты. - это было бы правильно.
Цитата:
Глубину меню можно было бы легко вычеслить по самому xml и не лениться, там работы 3 строки кода
Покажите мне такую реализацию в 3 строчки? оооочень интересно. Цитата:
...безупречный алмаз, таких классов не бывает) или это утопия
Цитата:
Читая сверху вниз, я все больше удивляюсь, сначала про мышиные события, затем addChild - никакой ощутимой нагрузки на проц и память добавление текстового поля с 1 символом - не несет. Успокойтесь уже со своей экономией, 21 век на дворе, а вы все fireFox не ставите - жрет видите ли много, а касперский? - это ваще смерть)
Вы будете сильно удивлены, но сборщик мусора до сих пор не всегда убирает такие вещи Извиняюсь, что так много написал. Не знал, что статья на хабре у вас в непоколебимых истинах, я ж по старинке книжки читаю, вот дурак. Удачи вам. |
|
Обновил(-а) Dima_DPE 26.01.2012 в 14:40
|
26.01.2012 14:49 | |
Цитата:
а потенциальные дыры в утечке памяти
|
26.01.2012 14:53 | |
100% удалится тогда, когда обьем доступной памяти будет слишком низким. Если памяти более чем достаточно, может удалить, может не удалить - это не скажется на производительности.
|
26.01.2012 14:58 | |
Цитата:
я то прочитал ) но, фраза шла от вас насчет того, что вы в 3 строчки напишите. Так вот, чтобы не быть голословным покажите уж, как это так, хотя бы в 5 строчек. посмотреть хочется просто и убедится в своем нубизме
var len:int = 0; var nod:XMLList = xml.item; while (nod.hasComplexContent()) { len++; nod = nod.children(); } И не смейте орать что тут не 3 строки, работы с xml тут ровно 3 строки |
|
Обновил(-а) Dima_DPE 26.01.2012 в 15:02
|
26.01.2012 15:01 | |
Цитата:
у меня меню ничего не жрет
|
|
Обновил(-а) Dima_DPE 26.01.2012 в 15:17
|
Последние записи от 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)