1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.edit.client.gxt.widget;
19
20 import org.vectomatic.svg.edit.client.SVGWindow;
21 import org.vectomatic.svg.edit.client.command.CommandFactories;
22 import org.vectomatic.svg.edit.client.command.DndCommandFactory;
23 import org.vectomatic.svg.edit.client.command.DndCommandFactory.DropGesture;
24 import org.vectomatic.svg.edit.client.engine.SVGModel;
25 import org.vectomatic.svg.edit.client.engine.SVGProcessor;
26 import org.vectomatic.svg.edit.client.model.svg.SVGElementModel;
27
28 import com.extjs.gxt.ui.client.core.El;
29 import com.extjs.gxt.ui.client.dnd.DropTarget;
30 import com.extjs.gxt.ui.client.dnd.Insert;
31 import com.extjs.gxt.ui.client.dnd.ScrollSupport;
32 import com.extjs.gxt.ui.client.event.DNDEvent;
33 import com.extjs.gxt.ui.client.util.Rectangle;
34 import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.TreeNode;
35 import com.google.gwt.core.client.GWT;
36 import com.google.gwt.user.client.Element;
37 import com.google.gwt.user.client.Timer;
38
39
40
41
42
43 public class SVGTreePanelDropTarget extends DropTarget {
44 protected DndCommandFactory dndCommandFactory;
45 protected TreePanelExt<SVGElementModel> tree;
46 protected TreeNode activeItem, appendItem;
47 protected DropGesture dropGesture;
48
49 private boolean restoreTrackMouse;
50 private ScrollSupport scrollSupport;
51
52 protected SVGModel svgModel;
53 public SVGTreePanelDropTarget(SVGWindow window) {
54 super(window.getTree());
55 this.tree = window.getTree();
56 svgModel = window.getSvgModel();
57 dndCommandFactory = CommandFactories.getDndCommandFactory();
58 }
59
60 protected void clearStyles(DNDEvent event) {
61 Insert.get().hide();
62 event.getStatus().setStatus(false);
63 if (activeItem != null) {
64 tree.getView().onDropChange(activeItem, false);
65 }
66 }
67
68 @Override
69 protected void onDragDrop(DNDEvent event) {
70 GWT.log("SVGTreePanelDropTarget.onDragDrop");
71 super.onDragDrop(event);
72 if (event.getData() == null)
73 return;
74
75 tree.getView().onDropChange(activeItem, false);
76 dndCommandFactory.processDragAndDrop(dropGesture);
77 tree.setTrackMouseOver(restoreTrackMouse);
78 activeItem = null;
79 appendItem = null;
80 scrollSupport.stop();
81 }
82
83 @Override
84 protected void onDragEnter(DNDEvent e) {
85 super.onDragEnter(e);
86 e.getStatus().setStatus(false);
87 restoreTrackMouse = tree.isTrackMouseOver();
88 tree.setTrackMouseOver(false);
89
90 if (scrollSupport == null) {
91 scrollSupport = new ScrollSupport(tree.el());
92 }
93 scrollSupport.start();
94 }
95
96 @Override
97 protected void onDragFail(DNDEvent event) {
98 super.onDragFail(event);
99 scrollSupport.stop();
100 }
101
102 @Override
103 protected void onDragLeave(DNDEvent e) {
104 super.onDragLeave(e);
105 if (activeItem != null) {
106 tree.getView().onDropChange(activeItem, false);
107 activeItem = null;
108 }
109 tree.setTrackMouseOver(restoreTrackMouse);
110 scrollSupport.stop();
111 }
112
113 @Override
114 protected void onDragMove(DNDEvent event) {
115 event.setCancelled(false);
116 }
117
118 @Override
119 protected void showFeedback(DNDEvent event) {
120
121
122 final TreeNode overItem = tree.findNode(event.getTarget());
123 if (!dndCommandFactory.isValidDropTarget(getModel(overItem))) {
124
125 clearStyles(event);
126 return;
127 }
128 handleInsert(event, overItem);
129 }
130
131
132 protected void handleInsert(DNDEvent event, final TreeNode item) {
133
134
135
136 int height = item.getElement().getOffsetHeight();
137 int mid = height / 2;
138 int top = item.getElement().getAbsoluteTop();
139 mid += top;
140 int y = event.getClientY();
141 boolean before = y < mid;
142
143 if ((!item.isLeaf() || SVGProcessor.isGroupElement(getModel(item).getElement()))
144 && ((before && y > top + 4) || (!before && y < top + height - 4))) {
145 handleAppend(event, item);
146 return;
147 }
148 dropGesture = before ? DropGesture.BeforeNode : DropGesture.AfterNode;
149
150
151 if (activeItem != null) {
152 tree.getView().onDropChange(activeItem, false);
153 }
154 appendItem = null;
155 activeItem = item;
156
157 int idx = -1;
158 if (activeItem.getParent() == null) {
159 idx = tree.getStore().getRootItems().indexOf(activeItem);
160 } else {
161 idx = activeItem.getParent().indexOf(item);
162 }
163
164 event.getStatus().setStatus(true);
165
166 showInsert(event, item.getElement(), before);
167 }
168
169 protected void handleAppend(DNDEvent event, final TreeNode item) {
170 dropGesture = DropGesture.OnNode;
171 Insert.get().hide();
172 event.getStatus().setStatus(true);
173
174 if (activeItem != null) {
175 tree.getView().onDropChange(activeItem, false);
176 }
177
178 if (item != null && item != appendItem && !item.isExpanded()) {
179 Timer t = new Timer() {
180 @Override
181 public void run() {
182 if (item == appendItem) {
183
184 item.setExpanded(true);
185 } else {
186 }
187 }
188 };
189
190 t.schedule(800);
191 }
192 appendItem = item;
193 activeItem = item;
194 if (activeItem != null) {
195 tree.getView().onDropChange(activeItem, true);
196 }
197 }
198
199
200
201 private void showInsert(DNDEvent event, Element elem, boolean before) {
202 Insert insert = Insert.get();
203 insert.show(elem);
204 Rectangle rect = El.fly(elem).getBounds();
205 int y = before ? rect.y - 2 : (rect.y + rect.height - 4);
206 insert.setBounds(rect.x, y, rect.width, 6);
207 }
208
209
210 public SVGElementModel getActiveItem() {
211 return getModel(activeItem);
212 }
213 public SVGElementModel getModel(TreeNode treeNode) {
214 if (treeNode != null) {
215 return (SVGElementModel)treeNode.getModel();
216 }
217 return null;
218 }
219 public SVGModel getSvgModel() {
220 return svgModel;
221 }
222 }