Here are some thoughts on how to handle FLUID-187, allowing portlets to be dropped into an empty column: http://issues.fluidproject.org/browse/FLUID-187
Apologies for the length. The terminology uses a short cut in that it refers to the things that are dragged and dropped in the context of the Reorderer and portlets. That is, I'm going to refer to "portlets", "columns", and so on, and not something more abstract, partly to make the discussion concrete. Once the problem is better understood, then more abstract terminology can be used. dnd: drag-and-drop. movable: a portlet that can move. Some portlets are locked or fixed and cannot move. draggable, dragged: the portlet that is being moved via a dnd. avatar: the semi-transparent clone of the dragged portlet that moves with the mouse during the drag. Note that the draggable itself stays in its current location until the drop is performed. It is the avatar that moves with the mouse during dnd. drop target, droppable: the thing that detects mouse movement over it and signals that it is a drop location. Currently, only the movable portlets are drop targets (and are implemented as jQuery droppables). drop target permissions: data that is consulted to determine if a draggable can be dropped relative to the drop target. The permissions are based on a combination of whether a droppable portlet is fixed (hence, nothing can be dropped above it), and a portlet's precedence (dragged portlets with lower precedence cannot be dropped above droppable portlets with higher precedence). The fixed nature and precedence of a portlet is captured by the drop target permissions data. drop marker: the thing that is displayed to indicate a drop point, either above or below a droppable portlet. In terms of the DOM, it is an element that is the same type of tag as the draggable. It is styled to be a "thin" coloured bar. drop point: the location to display the drop marker. column: a vertical container of portlets. interstitial space: the white space in a column between the portlets therein. Overall Problem ------- ------- At present, the Reorderer consider only the movable portlets as drop targets. The initial problem is that when all portlets are moved out of a column, and that column is empty, then it contains no drop targets. Any attempt to drag a portlet to the empty column fails because there is no drop target to signal that the mouse is over it. A corollary is that if the column contains a single portlet at the top, users expect to be able to drag a portlet anywhere below that single portlet. But, they cannot. They have to drag over the single portlet in order to drop below it. Similar behaviour occurs even when dragging in a full column, where users have to place the mouse over a portlet in order to drop. They cannot drop on the white space between portlets. This is easily seen in the current implementation where the drop marker vanishes when the mouse is over these interstitial spaces. What is needed is the ability to detect the mouse position: - between droppable portlets, - below a single portlet in a column, - in an empty column. Two Problems: --- -------- Part of the solution is to make the columns drop targets as well. That results in the mouse movement being detected in a column even when the mouse is not over a portlet. Also, making a column a target is a restriction of sorts: not just any white space will detect mouse movement over it; only white space within the column under the mouse. Making columns drop targets leads to two main new problems. 1. Determining where one is in a column when not over a droppable portlet. A preliminary coding experiment was done to see what would happen if one simply added the columns as drop targets. The result was that the column did signal that the mouse was over it. However, given the permissions data structure, when the mouse is over interstitial space and not over a droppable portlet, then the permissions indicate that there is no drop point available. No drop marker was displayed, and releasing the mouse resulted in no movement of the dragged portlet. Also, as the mouse moved over a droppable portlet during the drag, the system reverted to its normal behaviour: drop markers showed up as appropriate. (This is a good thing). The issue then becomes how to use the current mouse coordinates during a drag over interstitial space in a column to determine the nearest drop target portlet or pair of drop target portlets. Once the droppable portlet(s) are discovered, one can check against their drop target permissions, and display the drop marker at the drop point as appropriate. Currently, I am looking into how jQuery captures and defines mouse coordinates. For example: http://docs.jquery.com/Tutorials:Mouse_Position 2. What is the drop marker in DOM-speak? Or, how to decide on the right tag? Currently, when a portlet is marked as draggable, a drop marker is created such that it is of the same type of tag as the draggable. In the case of uPortal, that is a <div> element. One might suspect that if columns are added as drop targets, then the drop marker would be of the wrong type of tag. First, it is undesirable to create a drop marker whose tag is the same as the column's. (In the case of uPortal, that is a <td> element). Fortunately, that can't happen if the drop marker is instantiated in the context of the draggable, and is of the same type as the draggable. Secondly, it is potentially illegal html to place the drop marker outside of the column (before or after), and the current code might well do that. But, this is a problem in another way: The drop marker should never be placed between *columns*, but (1) only between portlets, (2) after the last portlet in a column, or (3) in place of the first portlet in an empty column. Overall, if the first problem of finding the permissble location of the drop point is solved (see, Determining where one is in a column when not over a droppable portlet above), then configuring the drop target as the draggable tag type should be sufficient. Final thought ----- ------- If (when) this works, why not make the columns the only drop targets? Why have columns *and* portlets as drop targets? Is there any need to have portlets as drop targets any more? One other idea --- ----- ---- Can the event horizon of the portlets be expanded to "fill" the interstitial space? That is, what if there is no white space between porlets? It may look like there is white space, but actually the portlets are separated by no more than a pixel. In that case, the mouse will always be over some portlet, and never over the column underneath. This probably won't work since it's the css content box that the mouse is sensitive to. That is, once you reach the element's margins, or even its padding, the mouse is no longer considered to be over the element. And, filling the column does not address the empty column issue. -- ;;;;joseph 'This is not war -- this is pest control!' - "Doomsday", Dalek Leader - _______________________________________________ fluid-work mailing list [email protected] http://fluidproject.org/mailman/listinfo/fluid-work
