/* * CompassController.java 22 sept. 2010 * * Sweet Home 3D, Copyright (c) 2010 Emmanuel PUYBARET / eTeks <info@eteks.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.eteks.sweethome3d.viewcontroller; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoableEdit; import javax.swing.undo.UndoableEditSupport; import com.eteks.sweethome3d.model.Compass; import com.eteks.sweethome3d.model.Home; import com.eteks.sweethome3d.model.UserPreferences; /** * A MVC controller for the compass view. * @author Emmanuel Puybaret */ public class CompassController implements Controller { /** * The properties that may be edited by the view associated to this controller. */ public enum Property {X, Y, DIAMETER, VISIBLE, NORTH_DIRECTION_IN_DEGREES, LATITUDE_IN_DEGREES, LONGITUDE_IN_DEGREES, TIME_ZONE} private final Home home; private final UserPreferences preferences; private final ViewFactory viewFactory; private final UndoableEditSupport undoSupport; private final PropertyChangeSupport propertyChangeSupport; private DialogView compassView; private float x; private float y; private float diameter; private boolean visible; private float northDirectionInDegrees; private float latitudeInDegrees; private float longitudeInDegrees; private String timeZone; public CompassController(Home home, UserPreferences preferences, ViewFactory viewFactory, UndoableEditSupport undoSupport) { this.home = home; this.preferences = preferences; this.viewFactory = viewFactory; this.undoSupport = undoSupport; this.propertyChangeSupport = new PropertyChangeSupport(this); updateProperties(); } /** * Returns the view associated with this controller. */ public DialogView getView() { // Create view lazily only once it's needed if (this.compassView == null) { this.compassView = this.viewFactory.createCompassView( this.preferences, this); } return this.compassView; } /** * Displays the view controlled by this controller. */ public void displayView(View parentView) { getView().displayView(parentView); } /** * Adds the property change <code>listener</code> in parameter to this controller. */ public void addPropertyChangeListener(Property property, PropertyChangeListener listener) { this.propertyChangeSupport.addPropertyChangeListener(property.name(), listener); } /** * Removes the property change <code>listener</code> in parameter from this controller. */ public void removePropertyChangeListener(Property property, PropertyChangeListener listener) { this.propertyChangeSupport.removePropertyChangeListener(property.name(), listener); } /** * Updates compass properties edited by this controller. */ protected void updateProperties() { Compass compass = this.home.getCompass(); setX(compass.getX()); setY(compass.getY()); setDiameter(compass.getDiameter()); setVisible(compass.isVisible()); setNorthDirectionInDegrees((float)Math.toDegrees(compass.getNorthDirection())); setLatitudeInDegrees((float)Math.toDegrees(compass.getLatitude())); setLongitudeInDegrees((float)Math.toDegrees(compass.getLongitude())); setTimeZone(compass.getTimeZone()); } /** * Returns the edited abscissa of the center. */ public float getX() { return this.x; } /** * Sets the edited abscissa of the center. */ public void setX(float x) { if (x != this.x) { float oldX = this.x; this.x = x; this.propertyChangeSupport.firePropertyChange(Property.X.name(), oldX, x); } } /** * Returns the edited ordinate of the center. */ public float getY() { return this.y; } /** * Sets the edited ordinate of the center. */ public void setY(float y) { if (y != this.y) { float oldY = this.y; this.y = y; this.propertyChangeSupport.firePropertyChange(Property.Y.name(), oldY, y); } } /** * Returns the edited diameter. */ public float getDiameter() { return this.diameter; } /** * Sets the edited diameter. */ public void setDiameter(float diameter) { if (diameter != this.diameter) { float oldDiameter = this.diameter; this.diameter = diameter; this.propertyChangeSupport.firePropertyChange(Property.DIAMETER.name(), oldDiameter, diameter); } } /** * Returns whether compass is visible or not. */ public boolean isVisible() { return this.visible; } /** * Sets whether this compass is visible or not. */ public void setVisible(boolean visible) { if (visible != this.visible) { this.visible = visible; this.propertyChangeSupport.firePropertyChange(Property.VISIBLE.name(), !visible, visible); } } /** * Returns the edited North direction angle in degrees. */ public float getNorthDirectionInDegrees() { return this.northDirectionInDegrees; } /** * Sets the edited North direction angle. */ public void setNorthDirectionInDegrees(float northDirectionInDegrees) { if (northDirectionInDegrees != this.northDirectionInDegrees) { float oldNorthDirectionInDegrees = this.northDirectionInDegrees; this.northDirectionInDegrees = northDirectionInDegrees; this.propertyChangeSupport.firePropertyChange(Property.NORTH_DIRECTION_IN_DEGREES.name(), oldNorthDirectionInDegrees, northDirectionInDegrees); } } /** * Returns the edited latitude in degrees. */ public final float getLatitudeInDegrees() { return this.latitudeInDegrees; } /** * Sets the edited latitude in degrees. */ public void setLatitudeInDegrees(float latitudeInDegrees) { if (latitudeInDegrees != this.latitudeInDegrees) { float oldLatitudeInDegrees = this.latitudeInDegrees; this.latitudeInDegrees = latitudeInDegrees; this.propertyChangeSupport.firePropertyChange(Property.LATITUDE_IN_DEGREES.name(), oldLatitudeInDegrees, latitudeInDegrees); } } /** * Returns the edited longitude in degrees. */ public final float getLongitudeInDegrees() { return this.longitudeInDegrees; } /** * Sets the edited longitude of the center. */ public void setLongitudeInDegrees(float longitudeInDegrees) { if (longitudeInDegrees != this.longitudeInDegrees) { float oldLongitudeInDegrees = this.longitudeInDegrees; this.longitudeInDegrees = longitudeInDegrees; this.propertyChangeSupport.firePropertyChange(Property.LONGITUDE_IN_DEGREES.name(), oldLongitudeInDegrees, longitudeInDegrees); } } /** * Returns the edited time zone identifier. */ public String getTimeZone() { return this.timeZone; } /** * Sets the edited time zone identifier. */ public void setTimeZone(String timeZone) { if (!timeZone.equals(this.timeZone)) { String oldTimeZone = this.timeZone; this.timeZone = timeZone; this.propertyChangeSupport.firePropertyChange(Property.TIME_ZONE.name(), oldTimeZone, timeZone); } } /** * Modifies home compass from the values stored in this controller. */ public void modifyCompass() { float x = getX(); float y = getY(); float diameter = getDiameter(); boolean visible = isVisible(); float northDirection = (float)Math.toRadians(getNorthDirectionInDegrees()); float latitude = (float)Math.toRadians(getLatitudeInDegrees()); float longitude = (float)Math.toRadians(getLongitudeInDegrees()); String timeZone = getTimeZone(); UndoableEdit undoableEdit = new CompassUndoableEdit(this.home.getCompass(), this.preferences, x, y, diameter, visible, northDirection, latitude, longitude, timeZone); doModifyCompass(this.home.getCompass(), x, y, diameter, visible, northDirection, latitude, longitude, timeZone); this.undoSupport.postEdit(undoableEdit); } /** * Undoable edit for compass. This class isn't anonymous to avoid * being bound to controller and its view. */ private static class CompassUndoableEdit extends AbstractUndoableEdit { private final Compass compass; private final UserPreferences preferences; private final float oldX; private final float oldY; private final float oldDiameter; private final float oldNorthDirection; private final float oldLatitude; private final float oldLongitude; private final String oldTimeZone; private final boolean oldVisible; private final float newX; private final float newY; private final float newDiameter; private final float newNorthDirection; private final float newLatitude; private final float newLongitude; private final String newTimeZone; private final boolean newVisible; public CompassUndoableEdit(Compass compass, UserPreferences preferences, float newX, float newY, float newDiameter, boolean newVisible, float newNorthDirection, float newLatitude, float newLongitude, String newTimeZone) { this.compass = compass; this.preferences = preferences; this.oldX = compass.getX(); this.oldY = compass.getY(); this.oldDiameter = compass.getDiameter(); this.oldVisible = compass.isVisible(); this.oldNorthDirection = compass.getNorthDirection(); this.oldLatitude = compass.getLatitude(); this.oldLongitude = compass.getLongitude(); this.oldTimeZone = compass.getTimeZone(); this.newX = newX; this.newY = newY; this.newDiameter = newDiameter; this.newVisible = newVisible; this.newNorthDirection = newNorthDirection; this.newLatitude = newLatitude; this.newLongitude = newLongitude; this.newTimeZone = newTimeZone; } @Override public void undo() throws CannotUndoException { super.undo(); doModifyCompass(this.compass, this.oldX, this.oldY, this.oldDiameter, this.oldVisible, this.oldNorthDirection, this.oldLatitude, this.oldLongitude, this.oldTimeZone); } @Override public void redo() throws CannotRedoException { super.redo(); doModifyCompass(this.compass, this.newX, this.newY, this.newDiameter, this.newVisible, this.newNorthDirection, this.newLatitude, this.newLongitude, this.newTimeZone); } @Override public String getPresentationName() { return this.preferences.getLocalizedString(CompassController.class, "undoModifyCompassName"); } } private static void doModifyCompass(Compass compass, float x, float y, float diameter, boolean visible, float northDirection, float latitude, float longitude, String timeZone) { compass.setX(x); compass.setY(y); compass.setDiameter(diameter); compass.setVisible(visible); compass.setNorthDirection(northDirection); compass.setLatitude(latitude); compass.setLongitude(longitude); compass.setTimeZone(timeZone); } }