In case it’s helpful, here’s a quick breakdown of how all of this works:
EDIT: Now that i’m done, this isn’t necessarily quick
Circle/Square Drag/Drop Widgets -
onDragStart - set variable values to determine where in the widget the user clicked when the drag was started (MousedownX and MousedownY). You’ll notice i’m setting these values based on the current cursor position in relation to the x,y coordinates of the widget. I’m using the mouse coordinates on drop to tell the repeater where to position the new item. By default it’s going to be the top left corner at those coordinates, so i’m using these variables to make sure that if they grabbed any place besides the top left, the widget is positioned in the right place.
onDrag - move This with Drag - hopefully fairly straightforward, move the widget with the drag
OnDragDrop - Two cases here:
If area of widget is over the area of the Rectangle - Add a row to the corresponding repeater. IF you dig into the add row logic, you’ll notice i’m using the following formulas to set the coordinates:
X:
[[Cursor.x-LVAR1.x - MousedownX]]
y:
[[Cursor.y-LVAR1.y - MousedownY]]
LVAR1 is the Canvas widget. To simplify some logic I left both of the repeaters inside of a dynamic panel. It’s important to remember that dynamic panels have their own set of coordinates. However, the cursor position axure gets is for the overall window. So to position something inside of the dynamic panel based on the window coordinates I need to subtract the x and y of the dynamic panel. For example, position 0,0 in the CanvasDP widget is actually 318, 165 in the window. Finally I subtract the the offset values I recording when the drag started.
Then the second case If True (essentially meaning it always fires):
Move this to x,y before drag. Puts the widget back where it started.
Repeater Elements
Inside of the dynamic panel are two repeater widgets. They start with no rows of data, so even though in RP you see them, they won’t show up in the generated html until rows are added.
OnItemLoad, we move the widgets to the coordinates stored on drop above. I have the repeaters set up to be vertical grids - so the x value is straightforward. However, y is a little tricky. By default a vertical repeater will automatically offset each item by the width of the row. SO when setting the position I need to first “0 out” the y using this logic: -((Item.index - 1) * LVAR1.height) where LVAR1 is the shape being copied. This setts the y coordinate so that it is 0. Then I add in whatever y coordinate was recorded on drop to place the item.
Inside of the repeaters, each has a dynamic panel with the shape. The dynamic panel is set with the following events:
OnDrag - move This with Drag
OnDrop - update the rows with the new coordinates. This is actually pretty straightforward. Take the existing x,y values and add in the TotalDragX and the TotalyDragY respectively. Then update “This” row in the repeater.