View Javadoc

1   /**********************************************
2    * Copyright (C) 2011 Lukas Laag
3    * This file is part of svgreal.
4    * 
5    * svgreal is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * svgreal is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with svgreal.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  package org.vectomatic.svg.edit.client.gxt.form;
19  
20  import org.vectomatic.dom.svg.OMNode;
21  import org.vectomatic.dom.svg.OMSVGLinearGradientElement;
22  import org.vectomatic.dom.svg.OMSVGPaint;
23  import org.vectomatic.dom.svg.OMSVGPatternElement;
24  import org.vectomatic.dom.svg.OMSVGRadialGradientElement;
25  import org.vectomatic.dom.svg.impl.SVGPaintParser;
26  import org.vectomatic.dom.svg.utils.OMSVGParser;
27  import org.vectomatic.dom.svg.utils.SVGConstants;
28  import org.vectomatic.svg.edit.client.AppBundle;
29  import org.vectomatic.svg.edit.client.AppConstants;
30  import org.vectomatic.svg.edit.client.gxt.panels.ColorEditor;
31  import org.vectomatic.svg.edit.client.gxt.widget.PaintCell;
32  
33  import com.extjs.gxt.ui.client.Style.IconAlign;
34  import com.extjs.gxt.ui.client.Style.Orientation;
35  import com.extjs.gxt.ui.client.event.ButtonEvent;
36  import com.extjs.gxt.ui.client.event.Events;
37  import com.extjs.gxt.ui.client.event.FieldEvent;
38  import com.extjs.gxt.ui.client.event.SelectionListener;
39  import com.extjs.gxt.ui.client.util.Margins;
40  import com.extjs.gxt.ui.client.widget.LayoutContainer;
41  import com.extjs.gxt.ui.client.widget.button.ToggleButton;
42  import com.extjs.gxt.ui.client.widget.form.AdapterField;
43  import com.extjs.gxt.ui.client.widget.layout.FillData;
44  import com.extjs.gxt.ui.client.widget.layout.FillLayout;
45  import com.extjs.gxt.ui.client.widget.layout.RowData;
46  import com.extjs.gxt.ui.client.widget.layout.RowLayout;
47  import com.google.gwt.core.client.GWT;
48  import com.google.gwt.event.logical.shared.CloseEvent;
49  import com.google.gwt.event.logical.shared.CloseHandler;
50  import com.google.gwt.event.logical.shared.ValueChangeEvent;
51  import com.google.gwt.event.logical.shared.ValueChangeHandler;
52  import com.google.gwt.event.shared.HandlerRegistration;
53  import com.google.gwt.user.client.ui.AbstractImagePrototype;
54  
55  /**
56   * Field subclass to edit SVGPaint values
57   * @author laaglu
58   */
59  public class PaintField extends AdapterField {
60  	private class PaintFieldPanel extends LayoutContainer {
61  		private PaintCell paintCell;
62  		private ToggleButton[] toggleButtons;
63  
64  		public PaintFieldPanel() {
65  			AppBundle bundle = AppBundle.INSTANCE;
66  			AppConstants constants = AppConstants.INSTANCE;
67  			String toggleGroup = "paintGroup";
68  			String[] tooltips = {
69  				constants.paintNone(),
70  				constants.paintCurrent(),
71  				constants.paintPlain(),
72  				constants.paintLinearGradient(),
73  				constants.paintRadialGradient(),
74  				constants.paintPattern()
75  			};
76  			AbstractImagePrototype icons[] = {
77  					AbstractImagePrototype.create(bundle.paintNone()),
78  					AbstractImagePrototype.create(bundle.paintCurrent()),
79  					AbstractImagePrototype.create(bundle.paintPlain()),
80  					AbstractImagePrototype.create(bundle.paintLinear()),
81  					AbstractImagePrototype.create(bundle.paintRadial()),
82  					AbstractImagePrototype.create(bundle.paintPattern())
83  			};
84  			SelectionListener[] listeners = {
85  				new SelectionListener<ButtonEvent>() {
86  					@Override
87  					public void componentSelected(ButtonEvent ce) {
88  						setValue(SVGPaintParser.NONE);
89  						PaintField.this.fireEvent(Events.AfterEdit, new FieldEvent(PaintField.this));
90  					}
91  				},
92  				new SelectionListener<ButtonEvent>() {
93  					@Override
94  					public void componentSelected(ButtonEvent ce) {
95  						// TODO Auto-generated method stub
96  					}
97  				},
98  				new SelectionListener<ButtonEvent>() {
99  					private HandlerRegistration changeReg;
100 					private HandlerRegistration closeReg;
101 					@Override
102 					public void componentSelected(ButtonEvent ce) {
103 						ColorEditor editor = ColorEditor.getInstance();
104 						OMSVGPaint paint = (OMSVGPaint) PaintField.this.value;
105 						// If the paint is already rgb, use it, otherwise, start from black
106 						editor.setPaint(paint.getPaintType() == OMSVGPaint.SVG_PAINTTYPE_RGBCOLOR ? paint : OMSVGParser.parsePaint(SVGConstants.CSS_BLACK_VALUE));
107 						changeReg = editor.addValueChangeHandler(new ValueChangeHandler<OMSVGPaint>() {
108 							@Override
109 							public void onValueChange(ValueChangeEvent<OMSVGPaint> event) {
110 								setValue(event.getValue());
111 							}					
112 						});
113 						closeReg = editor.addCloseHandler(new CloseHandler<ColorEditor>() {
114 							@Override
115 							public void onClose(CloseEvent<ColorEditor> event) {
116 								GWT.log("PaintField.onClose()");
117 								changeReg.removeHandler();
118 								closeReg.removeHandler();
119 								PaintField.this.fireEvent(Events.AfterEdit, new FieldEvent(PaintField.this));
120 							}
121 						});
122 						editor.show();
123 					}
124 				},
125 				new SelectionListener<ButtonEvent>() {
126 					@Override
127 					public void componentSelected(ButtonEvent ce) {
128 						// TODO Auto-generated method stub
129 					}
130 				},
131 				new SelectionListener<ButtonEvent>() {
132 					@Override
133 					public void componentSelected(ButtonEvent ce) {
134 						// TODO Auto-generated method stub
135 					}
136 				},
137 				new SelectionListener<ButtonEvent>() {
138 					@Override
139 					public void componentSelected(ButtonEvent ce) {
140 						// TODO Auto-generated method stub
141 					}
142 				}
143 			};
144 			
145 			LayoutContainer toggleContainer = new LayoutContainer();
146 			toggleContainer.setLayout(new FillLayout(Orientation.HORIZONTAL));
147 
148 			toggleButtons = new ToggleButton[6];
149 			for (int i = 0; i < toggleButtons.length;i++) {
150 				toggleButtons[i] = new ToggleButton();
151 				toggleButtons[i].setToggleGroup(toggleGroup);
152 				toggleButtons[i].setToolTip(tooltips[i]);
153 				toggleButtons[i].setIconAlign(IconAlign.TOP);
154 				toggleButtons[i].setIcon(icons[i]);
155 				toggleButtons[i].addSelectionListener(listeners[i]);
156 				toggleContainer.add(toggleButtons[i], i < toggleButtons.length -1 ? new FillData(0, 2, 0, 0) : new FillData(0));
157 			}
158 
159 			paintCell = new PaintCell();
160 			RowLayout rowLayout = new RowLayout(Orientation.HORIZONTAL);
161 			setLayout(rowLayout);
162 			add(paintCell, new RowData(1,1, new Margins(0, 5, 0, 0)));
163 			add(toggleContainer, new RowData(156, 1, new Margins(0)));
164 			setHeight(26);
165 		}
166 		
167 		private ToggleButton getPaintButton(OMSVGPaint paint) {
168 			switch(paint.getPaintType()) {
169 				case OMSVGPaint.SVG_PAINTTYPE_NONE:
170 					return toggleButtons[0];
171 				case OMSVGPaint.SVG_PAINTTYPE_CURRENTCOLOR:
172 					return toggleButtons[1];
173 				case OMSVGPaint.SVG_PAINTTYPE_RGBCOLOR:
174 				case OMSVGPaint.SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
175 					// Ignore ICC colors for the moment as they are not implemented
176 					// by browsers
177 					return toggleButtons[2];
178 				case OMSVGPaint.SVG_PAINTTYPE_URI:
179 				case OMSVGPaint.SVG_PAINTTYPE_URI_NONE:
180 				case OMSVGPaint.SVG_PAINTTYPE_URI_CURRENTCOLOR:
181 				case OMSVGPaint.SVG_PAINTTYPE_URI_RGBCOLOR:
182 				case OMSVGPaint.SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
183 					String id = paint.getUri();
184 					if (id != null && id.startsWith("#")) {
185 						id = id.substring(1);
186 					}
187 					if (id != null) {
188 						OMNode node = OMNode.convert(OMSVGParser.currentDocument().getDocument().getElementById(id));
189 						if (node instanceof OMSVGLinearGradientElement) {
190 							return toggleButtons[3];
191 						} else if (node instanceof OMSVGRadialGradientElement) {
192 							return toggleButtons[4];
193 						} else if (node instanceof OMSVGPatternElement) {
194 							return toggleButtons[5];
195 						}
196 					}
197 					switch(paint.getPaintType()) {
198 						case OMSVGPaint.SVG_PAINTTYPE_URI_CURRENTCOLOR:
199 							return toggleButtons[1];
200 						case OMSVGPaint.SVG_PAINTTYPE_URI_RGBCOLOR:
201 						case OMSVGPaint.SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
202 							return toggleButtons[2];
203 						case OMSVGPaint.SVG_PAINTTYPE_URI:
204 						case OMSVGPaint.SVG_PAINTTYPE_URI_NONE:
205 							return toggleButtons[0];
206 					}
207 
208 				default:
209 					assert false;
210 					return null;
211 			}
212 		}
213 		
214 		public void update(OMSVGPaint paint) {
215 			if (paint != null) {
216 				getPaintButton(paint).toggle(true);
217 				paintCell.setPaint(paint);
218 			}
219 		}
220 
221 	}
222 	public PaintField() {
223 		super(null);
224 		widget = new PaintFieldPanel();
225 		setResizeWidget(true);
226 		setFireChangeEventOnSetValue(true);
227 	}
228 	
229 	@Override
230 	public void setValue(Object value) {
231 		((PaintFieldPanel)widget).update((OMSVGPaint)value);
232 		super.setValue(value);
233 	}
234 	
235 	@Override
236 	public Object getValue() {
237 		return value;
238 	}
239 
240 }