![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|
|
|||||
|
Регистрация: Sep 2006
Сообщений: 89
|
Всем доброго времени суток
возник вопрос, можно ли повесить листенер на мувик и слушать что-то типа onResize? Т.е. если ресайзится мувик, чтобы что-то выполнялось. Хочется такое делать из классов, например, скроллера, которые должен ресайциться под маску. Или скроллер слушал размер текста и отключался, елси высота текста меньше маски... В хелпе addListener вроде можно повесить на любой объект, но если делать movieClip.addListener(Object), то onResize у Object'a не вызывается... Можно конечно прописать руками setInterval и смотреть что высота/ширина не изменилась, но как-то кажется это решение не очень оптимальным... Спасибо за совет. |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Вы простите конечно, но разве мувик может ресайзится сам? Его ресайзит программа, написанная Вами. Кому как не ей знать, КАК она его ресайзит?
__________________
Reality.getBounds(this); |
|
|||||
|
Регистрация: Sep 2006
Сообщений: 89
|
Это то понятно, просто проще нацепить "слушателя" и не думать в каких ситуациях может заресайзиться мувик. У меня сильное общущение что так правильнее, ибо в моем случае ресайзить может при изменении текста и ресайзе сцены...
Да и с точки зрения ООП, думаю, для написания отдельного класса это правильно. Ибо если класс принемает ссылку на мувик и должен подстраиваться под размеры мувика, то он не может и не должен знать почему мувик изменился снаружи, он просто должен на это отреагировать... Иначе код класса уже не будет достаточным, придется где-то вызывать дополнительно его методы myOnResize и т.д. Последний раз редактировалось Denis Davidov; 01.06.2008 в 03:48. |
|
|||||
|
Регистрация: Sep 2006
Сообщений: 89
|
Ок, с addListener понятно, работает только со Stage.
все-таки возвращаясь к изначальному вопросу, можно как-то слушать изменение размера мувика из класса? |
|
|||||
|
2 варианта:
1) ты пишешь программу сам, которая ресайзит мувик (встроенных нету). Там уже нужно действовать руками и писать все самому. 2) если у тебя showAll=true, тогда мувик будет ресайзиться при ресайзе флэшки, то есть как писал iNils:
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Вы могли бы привести примеры стандартных событий, происходящих в программе, а не в плеере (как события мыши, окна, загрузки данных и т.д.) ? Я сходу не могу, но у меня и знаний маловато. По-моему всё что происходит в программе, контролируется программой. У любого ресайза есть причина. Изменение текстового поля происходит при загрузке в него текста, добавлении символов руками (для отслеживания этого есть стандартное событие) или изменение текста в результате действия программы. Т.е. Вы всегда знаете, в какой момент текстовое поле изменилось, и можете устроить проверку его размеров. А создавать интервал опроса размеров или запрашивать их на onEnterFrame - совершенно неоправданная нагрузка на проц. Вы можете предусмотреть в своем классе метод, производящий изменения в зависимости от размеров, и вызывать этот метод извне тогда же, когда меняете его размер. Я вижу только одну альтернативу - опрос с интервалом. Но я бы никогда так не стал делать.
__________________
Reality.getBounds(this); |
|
|||||
|
Modus ponens
|
/**
* ...
* @author wvxvw
*/
class SomeClass extends MovieClip
{
public var broadcastMessage:Function;
public var addListener:Function;
public var removeListener:Function;
public function SomeClass()
{
_global.AsBroadcaster.initialize(this);
super();
}
public function get x():Number {
return _x;
}
public function set x(n:Number):Void {
_x = n;
broadcastMessage("onResize", "x", _x);
}
// this won't move the clip to new _y position, super._y points nowhere... :(
public function get _y():Number {
return super._y;
}
public function set _y(n:Number):Void {
super._y = n;
broadcastMessage("onResize", "_y", super._y);
}
}
*bbb - инстанс SomeClass'а (клипа в библиотеке с линкейджем к этому самому классу) выложеный на сцену* import SomeClass;
var abc:SomeClass = SomeClass(bbb);
abc.addListener(this);
onResize = function(prop:String, newVal:Number):Void {
trace("Instance of SomeClass changed property: "+prop+" to "+newVal);
}
abc.x = 100;
Но, вообще, удобнее пользоваться EventDispatcher'ом =) Хреново то, что оверрайда нету для свойств типа _х/_у и т.п... т.е. можно создать классу свойства с такими же именами, но тогда до "родных мувиклиповых" _х/_у уже будет недостучаться... Есть еще вариант: можно не линковать класс к клипу в библиотеке, а аттачить клип, ну, скажем, в конструкторе, тогда в гет/сет можно будет обращаться не к super, а к этому приаттаченому клипу (я обычно именно так и делаю), тогда и гет/сет можно будет назвать _х/_у и т.п. Но дальше проблема может возникнуть в том, что по-настоящему приватных переменных в АС2 нету, и какой-нибудь другой класс сможет обратиться напрямую к клипу (а не через гет/сет) и события не воникнет...
__________________
Hell is the possibility of sanity Последний раз редактировалось wvxvw; 01.06.2008 в 12:45. |
|
|||||
|
Регистрация: Sep 2006
Сообщений: 89
|
Спасибо все за участие в теме.
Что-бы немного придать конкретики, речь идет о текстовом поле под маской с рускопысным скролл-баром (от Wolsh'а). есть 2 вещи, кот. я в данном конкретном случае хочу решить: 1) маска слушает сцену и ресайцится. скрол бар должен ресайзится после маски (под ее новый размер), т.е. просто слушать onResize Stag'а не выход. Тем более если ресайзить независимо, то придется дублировать код для маски и скрола (одна и та-же зависимость например высоты от высоты Stage'a, что неприемлемо). навешивать на onResize у маски callBack чтобы ресайзить скролл -- думаю лишний гемор. Хотя можно и последовательность ресайзов будет правильная... 2)при изменении текстового поля, бегунок скрола должен реагировать (увеличиваться/уменьшаться/или совсем блокироваться). С этим проще, ибо изменение поля происходит при нажатии на меню, т.е. туда теоретически можно засунуть вызов функции scroll'а, это не сложно... Но мне как-то ближе вариант описанный wvxvw. Попробую с этим поэкспериментировать... 2wvxvw: посмотрел EventDispatcher, что-то там мало примеров, я так понял надо примерно так: Как то так? чем EventDispatcher лучше чем то, что Вы описали? |
|
|||||
|
Modus ponens
|
EventDispatcher лучше тем, что не диктует как называть функцию слушателя, т.е. на событие можно подписать сколько угодно разных функций, пусть они даже являются методами одного и того же объекта. А события в свою очередь можно унифицировать, и не путаться в их названиях (т.е. пример, я хочу, чтобы клип А слушал онРесайз от клипа Б, в случае с АсБроадкастером мне нужно будет разослать всем подписчикам сообщение и это сообщение будет именем вызываемого метода т.е. если у меня в клипе А уже есть функция онРесайз, то ее все равно вызовут (а я могу даже не знать/не помнить, что клип Б будет высылать клипу А это событие или случайно назвать свою функцию так же, как и высылаемое событие - более вероятная ситуация).
Конечно, есть флешевский EventDispatcher (mх.utils.EventDispatcher), но я пользуюсь своим. Вот, мб пригодиться =) Я не претендую на непогрешимость, и возможно мое творение не лучее решение, но, пока что работает и я доволен: /**
* ...
* @author wvxvw
*/
import events.Event;
class events.EventDispatcher
{
private var _eventListeners:Array;
public function EventDispatcher()
{
_eventListeners = [];
}
public function addEventListener(evt:String, fn:Function, ob:Object):Void
{
_eventListeners.push( { e:evt, f:fn, o:ob } );
}
public function removeEventListener(evt:String, fn:Function, ob:Object):Function
{
var i:Number = 0;
var l:Number = _eventListeners.length;
var obj:Object;
for (i = 0; i < l; i++)
{
obj = _eventListeners[i];
if (obj.e != _eventListeners[i].e) continue;
if (obj.f != _eventListeners[i].f) continue;
if (obj.o != _eventListeners[i].o) continue;
return _eventListeners.splice(i, 1)[0].f;
}
}
public function dispatchEvent(evt:Event):Void
{
var i:Number = 0;
var l:Number = _eventListeners.length;
var obj:Object;
for (i = 0; i < l; i++)
{
if (evt.type != _eventListeners[i].e) continue;
evt.target = this;
_eventListeners[i].f.apply(_eventListeners[i].o, [evt.clone()]);
}
delete evt;
}
}
/**
* ...
* @author wvxvw
*/
import utils.Utils
class events.Event
{
private var _target:Object = null;
private var _type:String = 'default';
public var className:String = 'Event';
public function Event(s:String)
{
if (s) _type = s;
}
public function clone():Event
{
var evt:Event = new Event(_type);
evt.target = _target;
return evt;
}
//------- get/set ------------//
public function set target(o:Object):Void
{
if (_target == null) _target = o;
}
public function get target():Object
{
return _target;
}
public function set type(s:String):Void
{
return;
}
public function get type():String
{
return _type;
}
public function toString():String
{
return Utils.formatToString(this, 'target', 'type');
}
}
/**
* ...
* @author wvxvw
*/
class utils.Utils
{
private static var CLASS_NAME:String = 'className';
public static function formatToString(o:Object):String
{
var i:Number = 1;
var l:Number = arguments.length;
var r_str:String = '[' + o[CLASS_NAME] + ' ';
for (i = 1; i < l; i++)
{
r_str += arguments[i] + '=' + o[arguments[i]] + ' ';
}
return r_str + ']';
}
public static function formatToStyle(o:Object):String
{
var skip:Array = arguments.slice(1, arguments.length);
var i:Number = skip.length;
var needSkip:Boolean = false;
var s:String;
var r_str:String = o[CLASS_NAME] + ' {';
for (s in o)
{
if (o[s] instanceof Function) continue;
if (s == CLASS_NAME) continue;
while (i--)
{
if (s == skip[i])
{
needSkip = true;
break;
}
}
i = skip.length;
if (needSkip) continue;
r_str += s + ':' + o[s] + '; ';
}
return r_str + '}';
}
}
__________________
Hell is the possibility of sanity Последний раз редактировалось wvxvw; 02.06.2008 в 14:11. |
![]() |
![]() |
Часовой пояс GMT +4, время: 01:18. |
|
|
« Предыдущая тема | Следующая тема » |
|
|