1 Reply Latest reply on Jun 2, 2011 12:27 AM by EricJ32

    Drag and Drop in list with DragIndicator

    EricJ32 Level 1

      I have a list with a custom layout, which works a little like the FlowLayout.

      I need to be able to drag-and-drop to reorder items in this list and have the dragIndicator show a slightly transparent version of the renderer.

      The list is populated with other display objects, like this:

       

      <s:ArrayCollection id="listItems">

           <local:MyCustomComponent title="Component 1" />

           <local:MyCustomComponent title="Component 2" />

           <local:MyCustomComponent title="Component 3" />

      </s:ArrayCollection>

       

      I use a custom item renderer for the list which contains nothing but the following method:

      public override function set data(value:Object):void

      {

          super.data = value;

       

          if(value is IVisualElement)

              this.addElement(value as IVisualElement);

      }

       

      ie, it adds whatever container has been included in the dataProvider into the ItemRenderer.

      This works fine and I get, for the above data, three instances of my MyCustomComponent rendered.

       

      What I now need is to have the dragIndicator be a copy of the selected renderer. This is where I'm getting unstuck.  When I drag one of the components, I don't get an indicator at all. If I add a rect with includeIn="dragging" into the ItemRenderer, then that displays, but the actual component doesn't.

       

      Any ideas at this point?

       

      The next thing I tried was to use an extended List which overrides two of the functions:

       

      protected override function dragStartHandler(event:DragEvent):void

      {

          if (event.isDefaultPrevented())

              return;

       

          var dragSource:DragSource = new DragSource();

          addDragData(dragSource);

       

          var indicator:IFlexDisplayObject = createDragIndicator();

       

       

          DragManager.doDrag(this,

              dragSource,

              event,

              indicator,

              0, //xOffset

              0, //yOffset

              0.5, //imageAlpha

              dragMoveEnabled);

      }

       

       

      public override function createDragIndicator():IFlexDisplayObject

      {

          var dragItem:IVisualElement = selectedItem;

       

          var dragImage : UIBitmap = new UIBitmap( dragItem, PixelSnapping.NEVER );

       

          if (dragImage is IVisualElement)

              IVisualElement(dragImage).owner = this;

       

          return dragImage;

      }

       

      So, createDragIndicator basically creates a bitmap copy of the component, which it does very successfully. My problem is that when it is displayed, it always shows up at 0,0 on the list, rather than over the top of the renderer, which is where I want it to start. I can't find a way to make it overlay the renderer's position.

       

      So, would you have any ideas as to how I create a solution by either of the methods I've tried above, or by another?

       

      Thanks

        • 1. Re: Drag and Drop in list with DragIndicator
          EricJ32 Level 1

          OK, I've fixed this in the following way.

          In the createDragIndicator() function, I've grabbed the element from the layout and set the dragImage's x and y to the same:

           

          public override function createDragIndicator():IFlexDisplayObject

          {

               var dragItem:IVisualElement = selectedItem;

           

               var dragImage : UIBitmap = new UIBitmap( dragItem, PixelSnapping.NEVER );

           

              

               if (dragImage is IVisualElement)

                    IVisualElement(dragImage).owner = this;

           

           

               var element:ILayoutElement;

           

              

               if (layout.useVirtualLayout)

                    element = layout.target.getVirtualElementAt(selectedIndex);

               else

                    element = layout.target.getElementAt(selectedIndex);

           

           

               dragImage.x = element.getLayoutBoundsX();

               dragImage.y = element.getLayoutBoundsY();

           

               return dragImage;

          }