Drop area masking

I have created a group into which I would like to drop nodes that are dragged from other groups. The use-case I am trying to achieve is that I would like to show a “mask” on top of the “drop-area”. I am not sure how to show this “mask” which would be displayed over everything else in the group. The “mask” would also need to show a message to indicate that the nodes can be dropped into that group.

When do you want to show that “mask”?

If it is when the user starts doing any drag, then you need to override the DraggingTool.doActivate method by having it call its super method and then show those masks on all of the groups that you want. Override DraggingTool.doDeactivate to hide all of those masks.

If it is when the user is dragging something over a particular group, then you could implement Group.mouseDragEnter and Group.mouseDragLeave event handlers to show and hide a mask for that group.

I already have a definition for mouseDragEnter and mouseDragLeave which I am using to update the “storkewidth” to show and hide a dashed line around the drop area shape. What I am not able to figure out is how to superimpose another “shape” or some other type of graph object to act as the “mask”.

Yes, if the Group already had the Panel of whatever you want to show, you could make it visible then. That’s basically what your current mouseDragEnter/Leave event handlers are doing, except modifying some Shape.strokeWidth instead of modifying some Panel.visible.

Alternatively, if you don’t want to have that Panel in every Group, which might be undesirable overhead if you have a lot of Groups, you could create a single Part that had the appearance you wanted that you added to the Diagram and sized and positioned it the way you wanted. You’d want to set pickable to false on this, though. Otherwise the act of adding a Part exactly where the mouse is would cause the mouse to leave the Group and enter that new temporary Part.

So there are lots of ways of implementing what you want. I don’t know what your goals and requirements are, though.

The structure that I am going with is a bit complicated. I have essentially created a swimlane with the first column fixed (while scrolling horizontally). This fixed column has a set of groups that I am talking about earlier (one group for each row of the swimlane). In the template of these groups, I have a panel (“auto”) which I use to define the “drop-area” and this is the panel which has my “placeholder” for the dropped nodes. The requirement is to show a “mask” super-imposed on top of the group onto which the dragged node is being dropped. I am having trouble defining a panel that would act as a mask. Essentially, this panel would need to be the size of the group and not the “drop-area” and it would also need to be super-imposed on the group. The question is how do I define such a panel with the most important aspect being the super-imposition (that is what I am not able to achieve).

I’m wondering if my second alternative wouldn’t be easier to implement. Have a single predefined Part that your DraggingTool.doActivate override would add to the Diagram and position and size appropriately for the cell where the mouse is. Remove it in the override of DraggingTool.doDeactivate.

That way you don’t have to worry about this mask affecting or be affected by whatever Group it is in.

Unfortunately, that won’t work because the requirement is to only show the mask when the dragged node it one top of the group. My question though is “super-imposing” can you please suggest how I might do that?.

But that’s exactly what you would do – it would only be made visible in your Group.mouseDragEnter event handler, and not visible in the mouseDragLeave event handler.

The mouseDragEnter handler would also need to size and position that special mask Part.

Remember to set pickable to false on that Part.

What I am struggling with is making sure that the mask is the same size and width of as the group and also on-top of the group. “Shapes” don’t have zOrder I am hence stuck as to how I will make this “mask” render on-top of the group.

Are you suggesting that I add an independent “Part” to the diagram and then re-position and re-size it every time I want to show it on top of a group? Is there no other simpler way to achieve what I need?

By simpler, I mean a solution which will not require a lot of re-calculation of position and size.

Yes, and with a separate Part you can make sure it’s in the “Tool” Layer, which is in front of everything else.