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.panels;
19
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.List;
23
24 import org.vectomatic.dom.svg.OMCSSPrimitiveValue;
25 import org.vectomatic.svg.edit.client.AppConstants;
26 import org.vectomatic.svg.edit.client.SvgrealApp;
27 import org.vectomatic.svg.edit.client.gxt.widget.DashArrayCell;
28 import org.vectomatic.svg.edit.client.model.svg.CssContextModel;
29 import org.vectomatic.svg.edit.client.model.svg.DashArray;
30 import org.vectomatic.svg.edit.client.model.svg.DashArray.Dash;
31 import org.vectomatic.svg.edit.client.model.svg.DashArrayStore;
32
33 import com.extjs.gxt.ui.client.Style.Orientation;
34 import com.extjs.gxt.ui.client.data.ModelData;
35 import com.extjs.gxt.ui.client.event.ButtonEvent;
36 import com.extjs.gxt.ui.client.event.EventType;
37 import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
38 import com.extjs.gxt.ui.client.event.SelectionChangedListener;
39 import com.extjs.gxt.ui.client.event.SelectionListener;
40 import com.extjs.gxt.ui.client.store.ListStore;
41 import com.extjs.gxt.ui.client.store.Store;
42 import com.extjs.gxt.ui.client.store.StoreEvent;
43 import com.extjs.gxt.ui.client.store.StoreListener;
44 import com.extjs.gxt.ui.client.util.Margins;
45 import com.extjs.gxt.ui.client.util.Padding;
46 import com.extjs.gxt.ui.client.widget.Label;
47 import com.extjs.gxt.ui.client.widget.LayoutContainer;
48 import com.extjs.gxt.ui.client.widget.Window;
49 import com.extjs.gxt.ui.client.widget.button.Button;
50 import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
51 import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
52 import com.extjs.gxt.ui.client.widget.form.SpinnerField;
53 import com.extjs.gxt.ui.client.widget.grid.CellEditor;
54 import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
55 import com.extjs.gxt.ui.client.widget.grid.ColumnData;
56 import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
57 import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
58 import com.extjs.gxt.ui.client.widget.grid.EditorGrid.ClicksToEdit;
59 import com.extjs.gxt.ui.client.widget.grid.Grid;
60 import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
61 import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel;
62 import com.extjs.gxt.ui.client.widget.layout.RowData;
63 import com.extjs.gxt.ui.client.widget.layout.RowLayout;
64 import com.extjs.gxt.ui.client.widget.layout.VBoxLayout;
65 import com.extjs.gxt.ui.client.widget.layout.VBoxLayout.VBoxLayoutAlign;
66 import com.extjs.gxt.ui.client.widget.layout.VBoxLayoutData;
67 import com.google.gwt.core.client.GWT;
68 import com.google.gwt.dom.client.Style;
69 import com.google.gwt.event.logical.shared.CloseEvent;
70 import com.google.gwt.event.logical.shared.CloseHandler;
71 import com.google.gwt.event.logical.shared.HasCloseHandlers;
72 import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
73 import com.google.gwt.event.logical.shared.ValueChangeEvent;
74 import com.google.gwt.event.logical.shared.ValueChangeHandler;
75 import com.google.gwt.event.shared.GwtEvent;
76 import com.google.gwt.event.shared.HandlerRegistration;
77
78
79
80
81
82 public class DashArrayEditor extends Window implements HasCloseHandlers<DashArrayEditor>, HasValueChangeHandlers<DashArray> {
83
84
85
86 private DashArrayStore dashArrays;
87
88
89
90 private GridSelectionModel<DashArray> dashArraySelectionModel;
91
92
93
94 private StoreListener<Dash> storeListener;
95 private EditorGrid<Dash> dashGrid;
96 private GridSelectionModel<Dash> dashSelectionModel;
97 private Button removeDashArrayButton;
98 private Button addDashButton;
99 private Button removeDashButton;
100 private ColumnModel dashModel;
101 private SelectionChangedListener<Dash> dashSelectionListener;
102 private static final ListStore<Dash> NO_DASH = new ListStore<Dash>();
103
104 public DashArrayEditor() {
105 AppConstants appConstants = AppConstants.INSTANCE;
106 setPlain(true);
107 setModal(true);
108 setBlinkModal(true);
109 setMaximizable(true);
110 setSize(500, 300);
111 setMinWidth(500);
112 setMinHeight(300);
113 setHeading(appConstants.dashArrayEditor());
114
115
116
117
118 Label dashArraysLabel = new Label(appConstants.dashArraysLabel());
119
120 List<ColumnConfig> arrayConfigs = new ArrayList<ColumnConfig>();
121 ColumnConfig dashArrayColumn = new ColumnConfig();
122 dashArrayColumn.setSortable(false);
123 dashArrayColumn.setId(DashArray.STORE_PROPERTY);
124 dashArrayColumn.setWidth(220);
125 dashArrayColumn.setRenderer(new GridCellRenderer<DashArray>() {
126 @Override
127 public Object render(DashArray model, String property,
128 ColumnData config, int rowIndex, int colIndex,
129 ListStore<DashArray> store, Grid<DashArray> grid) {
130 DashArrayCell cell = new DashArrayCell();
131 cell.setDashArray(model);
132 return cell;
133 }
134 });
135 arrayConfigs.add(dashArrayColumn);
136 ColumnModel arrayModel = new ColumnModel(arrayConfigs);
137 dashArrays = new DashArrayStore();
138 dashArrays.add(CssContextModel.getDefaultDashArrays().getModels());
139 Grid<DashArray> dashArrayGrid = new Grid<DashArray>(dashArrays, arrayModel);
140 dashArrayGrid.setHideHeaders(true);
141 dashArrayGrid.setBorders(true);
142
143 dashArraySelectionModel = dashArrayGrid.getSelectionModel();
144 storeListener = new StoreListener<Dash>() {
145 public void handleEvent(StoreEvent<Dash> e) {
146 EventType type = e.getType();
147 if (type == Store.Add
148 || type == Store.Remove
149 || type == Store.Update) {
150 dashArrays.fireStoreUpdateEvent();
151 ValueChangeEvent.fire(DashArrayEditor.this, dashArraySelectionModel.getSelectedItem());
152 }
153 }
154 };
155 dashArraySelectionModel.addSelectionChangedListener(new SelectionChangedListener<DashArray>() {
156 @Override
157 public void selectionChanged(SelectionChangedEvent<DashArray> se) {
158
159 dashGrid.getStore().removeStoreListener(storeListener);
160 dashGrid.getSelectionModel().removeSelectionListener(dashSelectionListener);
161
162
163 DashArray dashArray = se.getSelectedItem();
164 ListStore<Dash> dashStore = NO_DASH;
165 if (dashArray != null) {
166 dashStore = dashArray.<ListStore<Dash>>get(DashArray.STORE_PROPERTY);
167 dashStore.addStoreListener(storeListener);
168 }
169 dashGrid.reconfigure(dashStore, dashModel);
170 dashSelectionModel = new GridSelectionModel<Dash>();
171 dashGrid.setSelectionModel(dashSelectionModel);
172 dashSelectionModel.addSelectionChangedListener(dashSelectionListener);
173 update();
174 ValueChangeEvent.fire(DashArrayEditor.this, dashArray);
175 }
176 });
177
178 Button addDashArrayButton = new Button(appConstants.addButton());
179 addDashArrayButton.setToolTip(appConstants.addDashArrayTip());
180 addDashArrayButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
181 @Override
182 public void componentSelected(ButtonEvent ce) {
183 addDashArray();
184 }
185 });
186
187 removeDashArrayButton = new Button(appConstants.removeButton());
188 removeDashArrayButton.setToolTip(appConstants.removeDashArrayTip());
189 removeDashArrayButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
190 @Override
191 public void componentSelected(ButtonEvent ce) {
192 removeDashArray();
193 }
194 });
195 LayoutContainer leftButtonContainer = new LayoutContainer();
196 leftButtonContainer.setLayout(new RowLayout(Orientation.HORIZONTAL));
197 RowData rowData = new RowData(.5, 1);
198 leftButtonContainer.add(addDashArrayButton, rowData);
199 leftButtonContainer.add(removeDashArrayButton, rowData);
200 leftButtonContainer.setHeight(30);
201 LayoutContainer leftContainer = new LayoutContainer();
202 VBoxLayout leftLayout = new VBoxLayout();
203 leftLayout.setPadding(new Padding(5));
204 leftLayout.setVBoxLayoutAlign(VBoxLayoutAlign.STRETCH);
205 VBoxLayoutData vbl1 = new VBoxLayoutData(new Margins(0, 0, 5, 0));
206 VBoxLayoutData vbl2 = new VBoxLayoutData(new Margins(0, 0, 5, 0));
207 vbl2.setFlex(1);
208 VBoxLayoutData vbl3 = new VBoxLayoutData(new Margins(0));
209 leftContainer.setLayout(leftLayout);
210 leftContainer.add(dashArraysLabel, vbl1);
211 leftContainer.add(dashArrayGrid, vbl2);
212 leftContainer.add(leftButtonContainer, vbl3);
213
214
215
216
217
218
219 Label dashArrayLabel = new Label(appConstants.dashArrayLabel());
220
221 List<ColumnConfig> dashConfigs = new ArrayList<ColumnConfig>();
222
223 SpinnerField valueField = new SpinnerField();
224 valueField.setFireChangeEventOnSetValue(true);
225 valueField.setAllowDecimals(false);
226 valueField.setAllowNegative(false);
227 ColumnConfig valueColumn = new ColumnConfig();
228 valueColumn.setSortable(false);
229 valueColumn.setId(Dash.VALUE_PROPERTY);
230 valueColumn.setHeader(appConstants.dashValue());
231 valueColumn.setWidth(160);
232 valueColumn.setEditor(new CellEditor(valueField));
233 dashConfigs.add(valueColumn);
234
235 final SimpleComboBox<Style.Unit> unitField = new SimpleComboBox<Style.Unit>();
236 unitField.setForceSelection(true);
237 unitField.setTriggerAction(TriggerAction.ALL);
238 unitField.add(Arrays.asList(Style.Unit.values()));
239
240 ColumnConfig unitColumn = new ColumnConfig();
241 unitColumn.setSortable(false);
242 unitColumn.setId(Dash.UNIT_PROPERTY);
243 unitColumn.setHeader(appConstants.dashUnit());
244 unitColumn.setWidth(60);
245 CellEditor unitEditor = new CellEditor(unitField) {
246 @Override
247 public Object preProcessValue(Object value) {
248 if (value == null) {
249 return value;
250 }
251 return unitField.findModel((Style.Unit)value);
252 }
253
254 @Override
255 public Object postProcessValue(Object value) {
256 if (value == null) {
257 return value;
258 }
259 return ((ModelData) value).get("value");
260 }
261 };
262 unitColumn.setEditor(unitEditor);
263 dashConfigs.add(unitColumn);
264
265 dashModel = new ColumnModel(dashConfigs);
266 dashGrid = new EditorGrid<Dash>(NO_DASH, dashModel);
267 dashGrid.setClicksToEdit(ClicksToEdit.TWO);
268 dashGrid.setAutoExpandColumn(Dash.VALUE_PROPERTY);
269 dashGrid.setBorders(true);
270 dashSelectionListener = new SelectionChangedListener<Dash>() {
271 @Override
272 public void selectionChanged(SelectionChangedEvent<Dash> se) {
273 GWT.log("dashSelectionModel.selectionChanged");
274 update();
275 }
276 };
277
278 addDashButton = new Button(appConstants.addButton());
279 addDashButton.setToolTip(appConstants.addDashTip());
280 addDashButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
281 @Override
282 public void componentSelected(ButtonEvent ce) {
283 addDash();
284 }
285 });
286
287 removeDashButton = new Button(appConstants.removeButton());
288 removeDashButton.setToolTip(appConstants.removeDashTip());
289 removeDashButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
290 @Override
291 public void componentSelected(ButtonEvent ce) {
292 removeDash();
293 }
294 });
295 LayoutContainer rightButtonContainer = new LayoutContainer();
296 rightButtonContainer.setLayout(new RowLayout(Orientation.HORIZONTAL));
297 rightButtonContainer.add(addDashButton, rowData);
298 rightButtonContainer.add(removeDashButton, rowData);
299 rightButtonContainer.setHeight(30);
300 LayoutContainer rightContainer = new LayoutContainer();
301 VBoxLayout rightLayout = new VBoxLayout();
302 rightLayout.setPadding(new Padding(5));
303 rightLayout.setVBoxLayoutAlign(VBoxLayoutAlign.STRETCH);
304 rightContainer.setLayout(rightLayout);
305 rightContainer.add(dashArrayLabel, vbl1);
306 rightContainer.add(dashGrid, vbl2);
307 rightContainer.add(rightButtonContainer, vbl3);
308
309
310
311
312
313 setLayout(new RowLayout(Orientation.HORIZONTAL));
314 rowData.setMargins(new Margins(5));
315
316 add(leftContainer, rowData);
317 add(rightContainer, rowData);
318
319 Button okButton = new Button(appConstants.commitButton());
320 okButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
321 @Override
322 public void componentSelected(ButtonEvent ce) {
323 GWT.log("DashArrayEditor.ok");
324 hide();
325 CloseEvent.<DashArrayEditor>fire(DashArrayEditor.this, DashArrayEditor.this, false);
326 }
327 });
328 addButton(okButton);
329 Button cancelButton = new Button(appConstants.cancelButton());
330 cancelButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
331 @Override
332 public void componentSelected(ButtonEvent ce) {
333 GWT.log("DashArrayEditor.cancel");
334 hide();
335 CloseEvent.<DashArrayEditor>fire(DashArrayEditor.this, DashArrayEditor.this, true);
336 }
337 });
338 addButton(cancelButton);
339 }
340
341 @Override
342 public void show() {
343 super.show();
344 layout(true);
345 }
346
347 public void addDashArray() {
348 GWT.log("DashArrayEditor.addDashArray");
349 dashArrays.add(DashArray.parse(""));
350 }
351
352 public void removeDashArray() {
353 GWT.log("DashArrayEditor.removeDashArray");
354 dashArrays.remove(dashArraySelectionModel.getSelectedItem());
355 }
356
357 public DashArrayStore getDashArrays() {
358 return dashArrays;
359 }
360
361 public void addDash() {
362 GWT.log("DashArrayEditor.addDash");
363 ListStore<Dash> dashStore = dashGrid.getStore();
364 dashStore.add(new Dash(new OMCSSPrimitiveValue(1, OMCSSPrimitiveValue.CSS_NUMBER)));
365 }
366
367 public void removeDash() {
368 GWT.log("DashArrayEditor.removeDash");
369 ListStore<Dash> dashStore = dashGrid.getStore();
370 for (Dash dash : dashSelectionModel.getSelectedItems()) {
371 dashStore.remove(dash);
372 }
373 update();
374 }
375
376 public void update() {
377 removeDashArrayButton.setEnabled(dashArraySelectionModel.getSelectedItem() != null);
378 ListStore<Dash> dashStore = dashGrid.getStore();
379 addDashButton.setEnabled(dashStore != NO_DASH);
380 removeDashButton.setEnabled(dashStore != NO_DASH && dashSelectionModel.getSelectedItem() != null);
381 }
382
383
384
385
386
387 @Override
388 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<DashArray> handler) {
389 return SvgrealApp.getApp().getEventBus().addHandlerToSource(ValueChangeEvent.getType(), this, handler);
390 }
391
392 @Override
393 public HandlerRegistration addCloseHandler(CloseHandler<DashArrayEditor> handler) {
394 return SvgrealApp.getApp().getEventBus().addHandlerToSource(CloseEvent.getType(), this, handler);
395 }
396
397 @Override
398 public void fireEvent(GwtEvent<?> event) {
399 SvgrealApp.getApp().getEventBus().fireEventFromSource(event, this);
400 }
401 }