====== Drag-n-drop support in h-smile core engine ====== Drag-n-drop is a mechanism that allows to drag DOM element from source container to destination [container]. Engine supports drag-n-drop by providing D&D specific CSS attributes, state flags and events. Dragging implemented as an internal modal loop that starts on MOUSE_MOVE(while mouse button is "on") and ends when MOUSE_UP or KEY_DOWN(VK_ESCAPE) is received. For dragging engine creates a copy of element that user have chosen to drag. That copy gets either '':moving'' or '':copying'' flags and is moving synchronously with mouse pointer. Original element gets :drag-source state flag (and correspondent CSS pseudo-class). {{ http://www.terrainformatica.com/sciter/screenshots/the-map.png?331x361 }} (Screen shot above shows drop of last element from pallete (left table) to the map field (table on the right)) ===== Style attributes ===== ==== accept-drag ==== accept-drop: selector( some-selector ); This attribute declares applied element as a drop target for all elements that match //some-selector//. ==== draggable ==== draggable**: none | copy-move | only-copy | only-move; The attribute defines that this element can be dragged and how. Default value is ''none'' - element is not draggable. Other values are: * ''copy-move'' - element can be moved or copied. Current state of CTRL keyboard button defines current drag mode; * ''only-copy'' - element can be only copied; * ''only-move'' - element can be only moved - transfered from one container to another. ==== drop==== drop: insert | append | prepend | recycle; Is used together with ''accept-drag'' to define where or how element will be dropped on this drop-target: * ''insert'' - dragged element will be inserted between children of this container, insertion position is marked by special marker drawn by ''outline-color''; * ''append'' - dragged element will become last child after the drop; * ''prepend'' - dragged element will become first child after the drop; * ''replace'' - dragged element will replace current content of the target after the drop; * ''recycle'' - defines "black hole", dragged element will be removed after the drop of dragged element on this one. ===== State flags (CSS pseudo-classes) ===== Following state flags are related to D&D support: ==== '':moving'' and '':copying'' ==== These flags are set in element that is being draged. Either one of this flag is active at any given moment of time. Use them for styling moving and copying state of the element. Example: option:moving { background:red; opacity:0.5; } . In code these flags are represented by state constants: ''STATE_MOVING'' and ''STATE_COPYING''. ==== '':drop-target'' ==== This flag is set in all elements that can accept current dragged element. Engine will set this flag when dragging starts and will reset when dragging will end. Use this selector to give user visual clue of where dragging element can be dropped. In code this flag is declared as ''STATE_DROP_TARGET'' constant. ==== '':drag-over'' ==== The flag is set in current drop-target element that is under the mouse pointer at the moment. Only one element (if any) may have this flag set at any given moment of time. In code it is declared as ''STATE_DRAG_OVER''. ==== '':drag-source'' ==== The flag is set in original dragged element. Only one element (if any) may have this flag set at any given moment of time. Use this flag if you need for example hide original element while in drag moving mode. option:drag-source { visibility:hidden; } In code it is declared as ''STATE_DRAG_SOURCE''. ==== '':drop-marker'' ==== The flag is set on synthetic element that is created to mark drop position at the destination. Only one element (if any) may have this flag set at any given moment of time. Use this flag if you need to show to the user what would be new position of dragged element. option:drop-marker { visibility:visible; opacity:.5; } ===== D&D Events ===== While dragging some DOM element engine generates "primary" (or physical) and "secondary" (or logical) events from MOUSE_EVENTS group. Primary events are: * ''DRAGGING | MOUSE_ENTER'' * ''DRAGGING | MOUSE_LEAVE'' * ''DRAGGING | MOUSE_MOVE'' * ''DRAGGING | MOUSE_UP'' * ''DRAGGING | MOUSE_DOWN'' These are normal mouse event codes but "ORed" with DRAGGING flag. In most cases you will need to handle only secondary, resulting events: * ''DRAG_REQUEST'' - Drag operation is about to start. Target element is the one that is requested to drag. To cancel drag request simply return ''true'' value from the event handler. * ''DROP'' - the element is just dropped onto //drop-target// element. event is being sent in sinking/bubbling manner to the //drop-target// element. ''MOUSE_PARAMS.target'' is the //drop-target// element and ''MOUSE_PARAMS.dragging'' is that dropped element. * ''DRAG_ENTER'' and ''DRAG_LEAVE'' events are being sent to the //drop-target// element when mouse pointer arrives or leaves such //drop-target// element (''MOUSE_PARAMS.target''). In all these events ''MOUSE_PARAMS.dragging'' contains reference to element that is being dragged. ''MOUSE_PARAMS.dragging'' is a copy of original element that user selected to drag. ''MOUSE_PARAMS.dragging'' is a read/write field. In principle it can be replaced by some other element "on the fly".