Вход

Просмотр полной версии : Как правильно отслеживать drag картинки за предел окна


Korchy
25.11.2013, 15:32
Есть окно, в нем список, список состоит из объектов-картинок (контейнер с описанием, в нем спрайт). За картинку (спрайт) можно потащить startDrag/stopDrag. Если картинка вытаскивается за пределы окна, контейнер убирается из списка, в основной сцене генерится другой объект, на основании того, который перетащили. За конвертацией (убрать из списка, сгенерировать в сцене) следит менеджер. В принципе обычная библиотека элементов.
Вопрос, как правильно организовать отслеживание момента, когда картинка будет перетащена за пределы окна?
В классе контейнера, содержащего картинку я отслеживаю

private function OnMouseDown(e:MouseEvent):void {
lPict.startDrag();
}
private function OnMouseUp(e:MouseEvent):void {
lPict.stopDrag();
// Проверить, что вытащили за пределы окна (parent.parent - список.окно, смотрим по размерам окна)
var ParentCenter:Vector2 = VnObjectT(parent.parent).GetPosition();
var ParentW05:Number = VnObjectT(parent.parent).Width05;
var ParentH05:Number = VnObjectT(parent.parent).Height05;
if (e.stageX > ParentCenter.X + ParentW05 || e.stageX < ParentCenter.X - ParentW05 || e.stageY > ParentCenter.Y + ParentH05 || e.stageY < ParentCenter.Y - ParentH05) {
// За пределами окна - пробуем конвертировать картинку в объект
lConvObject.ConvertFromStorageToObject(new Vector2(e.stageX, e.stageY));
}
else {
// Осталась внутри окна - вернуть на место
lPict.MoveIntoParent(Width05, Height05, true);
}
}

Здесь не нравится обращение parent.parent к родителю. Из-за принципа потомок не знает о родителе, ну и в этом случае любая вставка промежуточного контейнера убивает правильность обращения к родителю.
Как должно быть?
Логика подсказывает, что картинка должна диспатчить эвент об окончании перетаскивания. Но кто должен слушать этот эвент и обрабатывать его? Окно? Оно относится к интерфейсу и не знает о менеджере конвертации. Надо ставить тогда в окно ссылку на менеджер, который вроде по логике окну ни к чему.

Вопрос - как организовать ситуацию правильно в общем принципе?

samana
26.11.2013, 02:46
Может в класс "объекта и картинки" который перетаскиваем, добавить свойство/ссылку на окно? Тогда с парентами не придётся возиться.

Wolsh
26.11.2013, 03:02
Не понял. У Менеджера есть ссылка на окно? Как-то же он собирается удалять из этого окна элемент списка. Если есть, то, получив событие от элемента списка, он имеет все, что нужно, чтобы определиться с положением дропа.

Добавлено через 8 минут
В такой схеме, как сейчас, Ваш контейнер-элементСписка действительно хочет знать о внешнем мире слишком много. С другой стороны, это можно понять — зачем Менеджеру конвертаций обрабатывать "холостые" дропы, он же занимается конвертацией. Может быть, элементам списка при добавлении в окно можно отдавать не ссылку на окно, а занимаемый окном Ректангл в глобальных координатах. Это было бы поуниверсальней.

Добавлено через 18 минут
Но я бы наверное предпочел написать DropManager, коль уж на то пошло)) Регистрировал в нем элементы списка и давал слепойРектангл или ссылку на окно. Он получал бы события дропа от итемов, просчитывал позицию и если надо, извещал Менеджер конвертации, а если нет — то вызывал у итема goHome().

Korchy
26.11.2013, 11:18
samana
Wolsh

Спасибо.
Значит получаются два пути. Попроще - втупую передавать контейнеру размеры окна, и поуниверсальнее - ввести еще один уровень обработки, который имеет доступ и к окну и к элементам списка и коррелирует их между собой. Хочется сделать как проще, но попробую сначала с дроп-менеджером обработки.