/* uDig - User Friendly Desktop Internet GIS client * http://udig.refractions.net * (C) 2004, Refractions Research Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.swt.styling.simple; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.geotools.swt.utils.Messages; /** * Allows editing/viewing of a scale. Used to build the min/max scale editors for a rule. * <p> * Here is the pretty picture: <pre><code> * +-+ +-------------+ * Scale:|x| | 90% \/| * +-+ +-------------+ * </code></pre> * </p> * <p> * Workflow: * <ol> * <li>createControl( parent ) - set up controls * <li>setFill( stroke, mode ) - provide content from SimpleStyleConfigurator/SimpleRasterConfigurator * <ol> * <li> scale values got from rules * <li> values copied into controls * <li> controls enabled based on mode & fields * </ol> * <li>Listener.widgetSelected/modifyText - User performs an "edit" * <li>Listener.sync( SelectionEvent ) - update fields with values of controls * <li>fire( SelectionSevent ) - notify SimpleStyleConfigurator/SimpleRasterConfigurator of change * <li>getScale( ) - returns the specified scale * </ul> * </p> * @author Andrea Aime * @since 1.1 * * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/swt/src/main/java/org/geotools/swt/styling/simple/ScaleViewer.java $ */ public class ScaleViewer { public static final int MIN = 0; public static final int MAX = 1; boolean enabled; double scale; int type; Button on; Combo scaleEditor; private class Listener implements SelectionListener, ModifyListener { public void widgetSelected( SelectionEvent e ) { sync(e); }; public void widgetDefaultSelected( SelectionEvent e ) { sync(e); }; public void modifyText( ModifyEvent e ) { sync(AbstractSimpleConfigurator.selectionEvent(e)); }; private void sync( SelectionEvent selectionEvent ) { try { ScaleViewer.this.enabled = ScaleViewer.this.on.getSelection(); String ptext = ScaleViewer.this.scaleEditor.getText(); ScaleViewer.this.scale = Double.parseDouble(ptext); fire(selectionEvent); // everything worked } catch (Throwable t) { t.printStackTrace(); } finally { ScaleViewer.this.scaleEditor.setEnabled(ScaleViewer.this.enabled); } } }; Listener sync = new Listener(); private SelectionListener listener; public ScaleViewer( int type ) { if (type != MIN && type != MAX) throw new IllegalArgumentException("Type should be either MIN or MAX"); //$NON-NLS-1$ this.type = type; this.scale = type == MIN ? 0 : Double.MAX_VALUE; } /** * Accepts a listener that will be notified when content changes. * @param listener1 */ public void addListener( SelectionListener listener1 ) { this.listener = listener1; } /** * Remove listener. * @param listener1 */ public void removeListener( SelectionListener listener1 ) { if (this.listener == listener1) this.listener = null; } /** * TODO summary sentence for fire ... * * @param event */ protected void fire( SelectionEvent event ) { if (this.listener == null) return; this.listener.widgetSelected(event); } /** * TODO summary sentence for createControl ... * * @param parent * @param kListener * @return Generated composite */ public Composite createControl( Composite parent, KeyListener kListener ) { String labelId = type == MIN ? Messages.getString("SimpleStyleConfigurator_minscaleden_label") : Messages .getString("SimpleStyleConfigurator_maxscaleden_label"); Composite part = AbstractSimpleConfigurator.subpart(parent, labelId); this.on = new Button(part, SWT.CHECK); this.on.addSelectionListener(this.sync); this.scaleEditor = new Combo(part, SWT.DROP_DOWN); this.scaleEditor.setItems(new String[]{"100", "1000", "10000", "100000", "1000000", "10000000"}); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ this.scaleEditor.setTextLimit(10); this.scaleEditor.addKeyListener(kListener); String tooltip = type == MIN ? Messages.getString("ScaleViewer_minscaleden_tooltip") : Messages .getString("ScaleViewer_maxscaleden_tooltip"); this.scaleEditor.setToolTipText(tooltip); return part; } /** * Gets the scale denominator chosen by the user, or the default value for this type if none was selected. * Default values are 0 for MIN type, {@linkplain Double#MAX_VALUE} for the MAX type * @param build * * @return Fill defined by this model */ public double getScale() { if (!this.enabled) return type == MIN ? 0 : Double.MAX_VALUE; else return scale; } /** * Sets the scale denominator, or disables the component if the provided scale is not a positive number * @param scale */ public void setScale( double scale2, long defaultScale ) { listen(false); this.scale = scale2; this.enabled = true; if (Double.isNaN(scale) || Double.isInfinite(scale) || scale <= Double.MIN_VALUE || scale >= Double.MAX_VALUE) { this.scale = defaultScale; this.enabled = false; } scaleEditor.setText(Double.toString(scale)); this.on.setSelection(this.enabled); this.scaleEditor.setEnabled(this.enabled); listen(true); } void listen( boolean listen ) { if (listen) { this.on.addSelectionListener(this.sync); this.scaleEditor.addSelectionListener(this.sync); this.scaleEditor.addModifyListener(this.sync); } else { this.on.removeSelectionListener(this.sync); this.scaleEditor.removeSelectionListener(this.sync); this.scaleEditor.removeModifyListener(this.sync); } } public boolean isEnabled() { return enabled; } }