| 115 | |
---|
| 116 | Success! |
---|
| 117 | |
---|
| 118 | == Step 4: Sorting == |
---|
| 119 | |
---|
| 120 | Currently, regardless of where you drag an item to it will end up as the last item in the window. It would be great if you could sort the items within a window by dragging them on top of each other. To do this, the ProcessEvent() function will need to determine both the container and the item within that container an element was dragged onto. |
---|
| 121 | |
---|
| 122 | Easy! We've attached as a 'dragdrop' listener to the item containers. This means we'll be notified whenever the 'dragdrop' event is sent to the containers or any of their children (i.e., their items). Each event has a ''target'' element and a ''current'' element. The target element is the element the event was actually targetted at; in the case of 'dragdrop', the element that was dropped on. The current element is the element the processing listener is observing; in our case, the container. |
---|
| 123 | |
---|
| 124 | So we can find the destination item and container with the following: |
---|
| 125 | |
---|
| 126 | {{{ |
---|
| 127 | void DragListener::ProcessEvent(Rocket::Core::Event& event) |
---|
| 128 | { |
---|
| 129 | if (event == "dragdrop") |
---|
| 130 | { |
---|
| 131 | Rocket::Core::Element* dest_container = event.GetCurrentElement(); |
---|
| 132 | Rocket::Core::Element* dest_element = event.GetTargetElement(); |
---|
| 133 | Rocket::Core::Element* drag_element = static_cast< Rocket::Core::Element* >(event.GetParameter< void* >("drag_element", NULL)); |
---|
| 134 | }}} |
---|
| 135 | |
---|
| 136 | If the dragged item is dropped directly onto a container, then the current and target elements will be the same. In this case, we want to keep the old processing: |
---|
| 137 | |
---|
| 138 | {{{ |
---|
| 139 | if (dest_container == dest_element) |
---|
| 140 | { |
---|
| 141 | // The dragged element was dragged directly onto a container. |
---|
| 142 | drag_element->GetParentNode()->RemoveChild(drag_element); |
---|
| 143 | dest_container->AppendChild(drag_element); |
---|
| 144 | } |
---|
| 145 | }}} |
---|
| 146 | |
---|
| 147 | Otherwise, we want to insert the item into its new container ''before'' the item it was dragged onto. |
---|
| 148 | |
---|
| 149 | {{{ |
---|
| 150 | else |
---|
| 151 | { |
---|
| 152 | // The dragged element was dragged onto an item inside a container. In order to get the |
---|
| 153 | // element in the right place, it will be inserted into the container before the item |
---|
| 154 | // it was dragged on top of. |
---|
| 155 | Rocket::Core::Element* insert_before = dest_element; |
---|
| 156 | |
---|
| 157 | drag_element->GetParentNode()->RemoveChild(drag_element); |
---|
| 158 | dest_container->InsertBefore(drag_element, insert_before); |
---|
| 159 | } |
---|
| 160 | }}} |
---|
| 161 | |
---|
| 162 | Run the app again and try it out. All good, except try dragging an item onto another item within the same window; in this case, it should be inserted ''after'' the element it is dragged onto, not before. So, just fix that up in the event handler and you're done! |
---|
| 163 | |
---|
| 164 | You can find the fully-completed source in the drag sample. |