Drag and Drop Skinning in Spark
Customize the ItemRenderer‘s “dragging” state. The drag indicator is the image that the user sees when they select and item and drag it away from the source container. By default the Spark List creates a drag indicator by duplicating all the ItemRenderers for the items being dragged. Therefore a natural way to customize the drag indicator is by customizing the ItemRenderer skin. Spark makes that easy by introducing the optional “dragging” state.
Customize the List‘s optional “dropIndicator” skin part. The drop indicator is the image that the user sees as an indicator of where the dragged items are going to be inserted in the destination container. By default, the Spark List displays a horizontal/vertical line along the gap between the at the insertion point. Spark makes that easy by automatically managing the “dropIndicator” optional dynamic skin part.
Customize the Drag Indicator
I’ll set up a custom ItemRenderer and I’ll flesh out the optional “dragging” state.
CustomDraggingItemRenderer.mxml:
<?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer focusEnabled="false" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"> <s:states> <s:State name="normal" /> <s:State name="hovered" /> <s:State name="selected" /> <s:State name="normalAndShowsCaret"/> <s:State name="hoveredAndShowsCaret"/> <s:State name="selectedAndShowsCaret"/> <s:State name="dragging"/> </s:states> <s:Rect left="0" right="0" top="0" bottom="-1" includeIn="dragging"> <s:stroke> <s:SolidColorStroke color="0xDDBBCC" weight="1"/> </s:stroke> <s:fill> <s:SolidColor color="0x5010CC" alpha="0.3"/> </s:fill> </s:Rect> <s:Label id="labelDisplay" verticalCenter="0" left="3" right="3" top="6" bottom="4" fontWeight.dragging="bold"/> </s:ItemRenderer> |
When the Spark List creates the duplicate ItemRenderes for the drag indicator, it will set them to their “dragging” state. Note that at that point the List’s data item will be rendered by two ItemRender instances – one to display the item in the List itself and one to display the item in the drag indicator.
Customize the Drop Indicator
I’ll set up a custom List skin. I’ll replace the “dropIndicator” skin part. Note that since the part is a dynamic part (created only during drag-and-drop operation) it’s placed inside the <fx:Declarations/> tag.
CustomDropIndicatorListSkin.mxml:
<fx:Declarations> <!--- Defines the appearance of the the List's drop indicator. To customize the drop indicator appearance, create a custom ListSkin class. The List's layout takes care to size and position the dropIndicator. The size of the <code>dropIndicator</code> is typically set to the size of the gaps between the items. The minimum and maximum settings are typically respected only in the direction along the major axis (the gap axis). For example a VerticalLayout ignores the <code>minWidth</code> and <code>maxWidth</code> settings, but respect <code>minHeight</code> and <code>maxHeight</code>. @copy spark.components.List#dropIndicator --> <fx:Component id="dropIndicator"> <s:Group minWidth="3" minHeight="3" maxWidth="3" maxHeight="3"> <s:Line width="20" left="3" verticalCenter="2"> <s:stroke> <s:SolidColorStroke color="0xFF0000"/> </s:stroke> </s:Line> <s:Path left="50" verticalCenter="-2" scaleX="-1" data="M 0 5 L 30 5 26 0 40 8 26 16 30 11 0 11 Z"> <s:stroke> <s:LinearGradientStroke rotation="5" weight="1"> <s:GradientEntry color="0xD8D8D8"/> <s:GradientEntry color="0x000000"/> </s:LinearGradientStroke> </s:stroke> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xD8D8D8" /> <s:GradientEntry color="0x888888" /> </s:LinearGradient> </s:fill> </s:Path> </s:Group> </fx:Component> </fx:Declarations> |
Click on the image at the top of the page to see the example in action. The sources are available here. The example was compiled with the Gumbo Flex SDK build 13553.
Hi Evtim,
Thanks for the nice example!
How did you create the “M 0 5 L 30 5 26 0 40 8 26 16 30 11 0 11 Z” path data?
Looks like something Catalyst generates…
Kind regards,
Jochen
Jochen – It looks like Catalyst data (and could well be) but it also looks like SVG data, like what you could extract from Fireworks or Illustrator file exports. So even without Catalyst you can still generate the shape data – draw the shape in Illustrator / Fireworks, export as an SVG file, and copy the path data from that file!
Hey Guys,
I actually created the data by hand, just plotted some line coordinates to outline an arrow (that took some tweaking). But yeah, definitely exporting from some of the CS apps or Catalyst makes more sense 🙂
-Evtim
Aha. That indeed makes a lot of sense.
Will download this example and try to replace the path data with some other SVG data.
Thanks for sharing this info James!
@Evtim: I think you accidently typed “dragIndicator” instead of “dropIndicator” in the sentence: “I’ll set up a custom List skin. I’ll replace the “dragIndicator” skin part.”
Thanks Jochen,
Yep good catch about the mistype, I corrected it now.
-Evtim
Could you share the source code? View Source is enabled but I get a 404.
Thanks.
Markus
Hi Markus,
Sorry about that, I’ll have it fixed when I get a little bit of extra time. In the mean time you can use the source code link at the bottom of the post – you should be able to download the zipped sources. Let me know if that doesn’t work for you.
-Evtim
I’ve been trying this with the Tree control and it seems to work a bit differently… the dragging state for example isn’t set by the tree control from what I understand… though its certainly possible to do so from the tree’s dragStarted event.
Thanks for that! It’s so easy as I see..
I can’t get the dragging states of custom spark ItemRenderers to display in my application. I even tried using the ItemRenderer above and it does not work for me. Yes, drag and drop is working, but the display of the drag image is not.
In my project, the display hierarchy for my component is something like s:TitleWindow > mx:Accordion > s:NavigatorContent > s:List > s:ItemRenderer.
@Stephen
Problem solved. This was being caused by setting the enabled property of another component based upon mx:VBox to true, which for some reason would subsequently disallow any dragImage from displaying anywhere in the application. I suppose I should change that component over to spark.
Now if I could only get Image children in custom a spark ItemRender to display in the dragging state.
Hi Stephen,
Image children don’t display in the dragging state? What does your ItemRenderer look like?
An intriguing discussion is worth comment. I think that you
need to write more on this subject, it might not be a taboo subject but typically folks don’t talk about these topics.
To the next! All the best!!