001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.style.sld;
018:
019: import net.refractions.udig.project.internal.Layer;
020: import net.refractions.udig.style.IStyleConfigurator;
021:
022: import org.eclipse.jface.dialogs.Dialog;
023: import org.eclipse.swt.SWT;
024: import org.eclipse.swt.events.ModifyEvent;
025: import org.eclipse.swt.events.SelectionEvent;
026: import org.eclipse.swt.graphics.FontMetrics;
027: import org.eclipse.swt.graphics.GC;
028: import org.eclipse.swt.layout.RowData;
029: import org.eclipse.swt.layout.RowLayout;
030: import org.eclipse.swt.widgets.Composite;
031: import org.eclipse.swt.widgets.Event;
032: import org.eclipse.swt.widgets.Label;
033: import org.geotools.styling.Style;
034: import org.geotools.styling.StyleBuilder;
035:
036: /**
037: * This is here to save me some typing and ensure that the simple raster and
038: * feature configurators look similar.
039: * @author mleslie
040: * @since 0.6.0
041: */
042: public abstract class AbstractSimpleConfigurator extends
043: IStyleConfigurator {
044: /** <code>build</code> field */
045: protected StyleBuilder build = new StyleBuilder();
046:
047: /**
048: * Construct <code>AbstractSimpleConfigurator</code>.
049: *
050: */
051: public AbstractSimpleConfigurator() {
052: super ();
053: }
054:
055: @Override
056: public abstract boolean canStyle(Layer aLayer);
057:
058: @Override
059: protected abstract void refresh();
060:
061: @Override
062: public abstract void createControl(Composite parent);
063:
064: /**
065: * TODO summary sentence for synchronize ...
066: *
067: */
068: public abstract void synchronize();
069:
070: /**
071: * TODO summary sentence for setLayout ...
072: *
073: * @param parent
074: */
075: protected void setLayout(Composite parent) {
076: RowLayout layout = new RowLayout();
077: layout.pack = false;
078: layout.wrap = true;
079: layout.type = SWT.HORIZONTAL;
080: layout.fill = true;
081: layout.marginLeft = 0;
082: layout.marginRight = 0;
083: layout.marginTop = 0;
084: layout.marginBottom = 0;
085: layout.spacing = 0;
086: parent.setLayout(layout);
087: }
088:
089: /**
090: * Retrieves the style object from the style blackboard.
091: *
092: * @return Style
093: */
094: protected Style getStyle() {
095: Layer layer = getLayer();
096: assert (canStyle(layer));
097: // TODO: Ensure framework does not show me when I can't handle this
098: // layer
099: // TODO: Stop commenting in the first person, as though I am the
100: // class. It's creepy.
101: Style style = (Style) getStyleBlackboard().get(SLDContent.ID);
102:
103: // if no style information, create default
104: if (style == null) {
105: // TODO: Why do "I" have to do this, can't the framework deal?
106: // (It could if I advertise that I deal with SLDContentID type?)
107: style = SLDContent.createDefaultStyle();
108: getStyleBlackboard().put(SLDContent.ID, style);
109: // XXX: This may throw out an event and cause some debugging grief?
110: }
111: return style;
112: }
113:
114: /**
115: * Construct a subpart labeled with the provided tag.
116: * <p>
117: * Creates a composite with a grid layout of the specifed columns,
118: * and a label with text from label.
119: * </p>
120: * @param parent
121: * @param label
122: * @return Composite with one label
123: */
124: public static Composite subpart(Composite parent, String label) {
125: Composite subpart = new Composite(parent, SWT.NONE);
126: RowLayout across = new RowLayout();
127: across.type = SWT.HORIZONTAL;
128: across.wrap = true;
129: across.pack = true;
130: across.fill = true;
131: across.marginBottom = 1;
132: across.marginRight = 2;
133:
134: subpart.setLayout(across);
135:
136: Label labell = new Label(subpart, SWT.RIGHT);
137: labell.setText(label);
138:
139: RowData data = new RowData();
140: data.width = 40;
141: //check to see if width is not enough space
142: GC gc = new GC(parent.getParent());
143: gc.setFont(parent.getParent().getFont());
144: FontMetrics fontMetrics = gc.getFontMetrics();
145: gc.dispose();
146: int labelWidth = Dialog.convertWidthInCharsToPixels(
147: fontMetrics, labell.getText().length() + 1);
148: if (labelWidth > data.width) {
149: data.width = labelWidth;
150: }
151: // TODO: adjust the methods that call this one to keep a consistent
152: // width (otherwise they're misaligned)
153: data.height = 10;
154: labell.setLayoutData(data);
155:
156: return subpart;
157: }
158:
159: /**
160: * Morph a text ModifyEvent into a SelectionEvent as best we can.
161: * <p>
162: * This may be a bad abuse of the event system, it appears to be in
163: * use because we are too lazy to specify a new event type for style
164: * modification.
165: * </p>
166: * <p>
167: * However this does seem to be in keeping with the purpose of SelectionEvent
168: * it already isolates out code from TypedEvents by providing a summary of what
169: * changed in which widet.
170: * </p>
171: * @param e
172: * @return A SelectionEvent based on the provided modify event
173: */
174: public static SelectionEvent selectionEvent(final ModifyEvent e) {
175: Event event = new Event();
176: event.widget = e.widget;
177: event.data = e.data;
178: event.display = e.display;
179: event.time = e.time;
180: return new SelectionEvent(event) {
181: /** <code>serialVersionUID</code> field */
182: private static final long serialVersionUID = 6544345585295778029L;
183:
184: @Override
185: public Object getSource() {
186: return e.getSource();
187: }
188: };
189: };
190: }
|