Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   Drag & drop реагирует на дочерних элементах (http://www.flasher.ru/forum/showthread.php?t=127196)

litebox 07.07.2009 20:12

Drag & drop реагирует на дочерних элементах
 
Есть экземпляр Panel, на нем размещены элементы управления. В приведенном ниже примере Drag & drop срабатывает всегда, даже когда юзер сделал клик на кнопке или текстовом поле. А хочется, чтобы панель перетаскивалась только за заголовок. Вариант добавить на все элементы событие mouseDown и душить его, чтобы оно не обрабатывалось панелью нравится не очень :) Наверное же есть способ по-красивее?

Код AS3:

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" >
        <mx:Script><![CDATA[
                import flash.net.URLLoader;
                import flash.net.URLRequest;
                import flash.net.URLVariables;
 
                import flash.events.Event;
                import flash.events.IOErrorEvent;
                import flash.events.MouseEvent;
 
 
 
                private function eventPanelStartDrag(e:MouseEvent):void
                {
                        if (e.currentTarget == panel)
                        {
                                panel.startDrag();
 
 
                        }
 
                        txtLog.text += "\n" + e.target.toString();
                        txtLog.text += "\n" + e.currentTarget.toString();
                }
 
                private function eventPanelStopDrag(e:MouseEvent):void
                {
                        panel.stopDrag();
 
                        txtLog.text += "\n" + "stop";
                }
 
        private function onSendData(e:MouseEvent):void
        {
 
        }   
    ]]></mx:Script>
        <mx:Panel id="panel" width="500" height="300" title="test" layout="vertical"
                horizontalAlign="center" paddingTop="8" paddingBottom="8" paddingLeft="8" paddingRight="8"
                mouseDown="eventPanelStartDrag(event)" mouseUp="eventPanelStopDrag(event)" >
                <mx:TextInput id="txtParams" width="100%" text="g_ind=2" />
                <mx:Button id="btnSendData" label="Send data" click="onSendData(event)" />
                <mx:TextArea id="txtLog" width="100%" height="100%" text="log:" editable="false" />
        </mx:Panel>
</mx:Application>


DeliMIter 09.07.2009 17:24

Свойство event.currentTarget для любого элемента внутри панели всегда будет указывать на саму панель, т.к. событие всплывающее, а подписан обработчик именно на событие панели. Следует использовать свойство event.target, указующее на оригинальный элемент, в котором произошло событие, т.е. определить, что приходит в event.target при нажатии на заголовок и стартовать перетаскивание только в этом случае.

litebox 09.07.2009 19:42

Приходит Main0.panel.UIComponent18.UITextField20, но делать такое сравнение:
Код AS3:

if (e.target.name == "UITextField20")
{
        panel.startDrag();
}

выглядит как-то не кошерно :( Тем более, что имя для заголовка дается автоматически, и нет гарантий, что при добавлении новых элементов управления оно не изменится, скажем, на UITextField21

DeliMIter 09.07.2009 20:09

У этого объекта наверняка есть десятка два характерных свойств. Родитель и позиция кажутся наиболее многообещающими.

litebox 10.07.2009 17:39

Добавил для Panel на событие creationComplete свойство hitArea:
Код AS3:

private function initHitArea(e:Event):void
{
        var hitTitle:Sprite = new Sprite();
 
        hitTitle.graphics.beginFill(0x00FF00);
        hitTitle.graphics.drawRect(0, 0, panel.width, 30);
 
        panel.hitArea = hitTitle;
        hitTitle.mouseEnabled = false;
 
        //panel.rawChildren.addChild(hitTitle);
}

по началу все казалось рабочим, но потом выяснилось, что если нажать на кнопке, или текстовом поле, которые лежат на панеле - все начинает тягаться снова :(
И еще, параллельный вопрос, почему использование FlexSprite приводит к ошибке:
Код AS3:

private function initHitArea(e:Event):void
{
        var hitTitle:FlexSprite = new FlexSprite();
 
        hitTitle.graphics.beginFill(0x00FF00);
        hitTitle.graphics.drawRect(0, 0, panel.width, 30);
 
        panel.hitArea = hitTitle;
        hitTitle.mouseEnabled = false;
 
        panel.addChild(hitTitle);
}

Ведь FlexSprite наследник UIComponent?

DeliMIter 10.07.2009 18:10

По прежнему не понимаю твоей проблемы. Я положил панель, написал ей заголовок, в неё кинул кнопку, на клик подписал событие, в котором выводил класс источника события и класс парента этого объекта, и вот что получил:
Код:

mx.containers::Panel BlackTest // клик по пустой панели
mx.controls::Button mx.containers::Panel // клик по кнопке
mx.core::UITextField mx.core::UIComponent // клик по заголовку

Если на имена объектов закладываться действительно не стоит, то пара "класс объекта" + "класс парента объекта" выглядит надёжно.

litebox 10.07.2009 18:37

Согласен, для моей небольшой задачки этого вполне достаточно. Просто я изучаю Flex и меня очень удивил этот момент, захотелось найти хорошее решение. Наиболее приличный вариант, как на мой взгляд, выглядит так:
Код AS3:

private function eventPanelStartDrag(e:MouseEvent):void
{
        var mousePoint:Point = panel.globalToLocal(new Point(e.stageX, e.stageY));
 
        if ((mousePoint.x > 0 && mousePoint.x < panel.width) && (mousePoint.y > 0 && mousePoint.y < 30))
        {
                panel.startDrag();
        }
}

но и тут не обошлось без неприятного момента :)
У панели есть свойство headerHeight, которое определяет высоту заголовка окна отлично задается через mxml. Однако, при обращении к этому свойству через AS, дабы определить область заголовка, возникает ошибка компиляции:
Код:

Error: Access of possibly undefined property headerHeight through a reference with static type mx.containers:Panel.
ах-ха, добрался таки до этого свойства через
Код AS3:

panel.getStyle("headerHeight")

уже что-то, жаль только, по умолчанию оно undefined :(


Часовой пояс GMT +4, время: 14:40.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.