/* * Home3DAttributesController.java 25 juin 07 * * Sweet Home 3D, Copyright (c) 2007 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.PropertyChangeEvent; 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.Home; import com.eteks.sweethome3d.model.HomeEnvironment; import com.eteks.sweethome3d.model.HomeTexture; import com.eteks.sweethome3d.model.UserPreferences; /** * A MVC controller for home 3D attributes view. * @author Emmanuel Puybaret */ public class Home3DAttributesController implements Controller { /** * The properties that may be edited by the view associated to this controller. */ public enum Property {GROUND_COLOR, GROUND_PAINT, SKY_COLOR, SKY_PAINT, LIGHT_COLOR, WALLS_ALPHA, WALLS_TOP_COLOR} /** * The possible values for {@linkplain #getGroundPaint() ground paint type}. */ public enum EnvironmentPaint {COLORED, TEXTURED} private final Home home; private final UserPreferences preferences; private final ViewFactory viewFactory; private final ContentManager contentManager; private final UndoableEditSupport undoSupport; private TextureChoiceController groundTextureController; private TextureChoiceController skyTextureController; private final PropertyChangeSupport propertyChangeSupport; private DialogView home3DAttributesView; private int groundColor; private EnvironmentPaint groundPaint; private int skyColor; private EnvironmentPaint skyPaint; private int lightColor; private float wallsAlpha; /** * Creates the controller of 3D view with undo support. */ public Home3DAttributesController(Home home, UserPreferences preferences, ViewFactory viewFactory, ContentManager contentManager, UndoableEditSupport undoSupport) { this.home = home; this.preferences = preferences; this.viewFactory = viewFactory; this.contentManager = contentManager; this.undoSupport = undoSupport; this.propertyChangeSupport = new PropertyChangeSupport(this); updateProperties(); } /** * Returns the texture controller of the ground. */ public TextureChoiceController getGroundTextureController() { // Create sub controller lazily only once it's needed if (this.groundTextureController == null) { this.groundTextureController = new TextureChoiceController( this.preferences.getLocalizedString(Home3DAttributesController.class, "groundTextureTitle"), this.preferences, this.viewFactory, this.contentManager); this.groundTextureController.addPropertyChangeListener(TextureChoiceController.Property.TEXTURE, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { setGroundPaint(EnvironmentPaint.TEXTURED); } }); } return this.groundTextureController; } /** * Returns the texture controller of the sky. */ public TextureChoiceController getSkyTextureController() { // Create sub controller lazily only once it's needed if (this.skyTextureController == null) { this.skyTextureController = new TextureChoiceController( this.preferences.getLocalizedString(Home3DAttributesController.class, "skyTextureTitle"), this.preferences, this.viewFactory, this.contentManager); this.skyTextureController.addPropertyChangeListener(TextureChoiceController.Property.TEXTURE, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { setSkyPaint(EnvironmentPaint.TEXTURED); } }); } return this.skyTextureController; } /** * Returns the view associated with this controller. */ public DialogView getView() { // Create view lazily only once it's needed if (this.home3DAttributesView == null) { this.home3DAttributesView = this.viewFactory.createHome3DAttributesView( this.preferences, this); } return this.home3DAttributesView; } /** * 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 edited properties from the 3D attributes of the home edited by this controller. */ protected void updateProperties() { HomeEnvironment homeEnvironment = this.home.getEnvironment(); setGroundColor(homeEnvironment.getGroundColor()); HomeTexture groundTexture = homeEnvironment.getGroundTexture(); getGroundTextureController().setTexture(groundTexture); if (groundTexture != null) { setGroundPaint(EnvironmentPaint.TEXTURED); } else { setGroundPaint(EnvironmentPaint.COLORED); } setSkyColor(homeEnvironment.getSkyColor()); HomeTexture skyTexture = homeEnvironment.getSkyTexture(); getSkyTextureController().setTexture(skyTexture); if (skyTexture != null) { setSkyPaint(EnvironmentPaint.TEXTURED); } else { setSkyPaint(EnvironmentPaint.COLORED); } setLightColor(homeEnvironment.getLightColor()); setWallsAlpha(homeEnvironment.getWallsAlpha()); } /** * Sets the edited ground color. */ public void setGroundColor(int groundColor) { if (groundColor != this.groundColor) { int oldGroundColor = this.groundColor; this.groundColor = groundColor; this.propertyChangeSupport.firePropertyChange(Property.GROUND_COLOR.name(), oldGroundColor, groundColor); setGroundPaint(EnvironmentPaint.COLORED); } } /** * Returns the edited ground color. */ public int getGroundColor() { return this.groundColor; } /** * Sets whether the ground is colored or textured. */ public void setGroundPaint(EnvironmentPaint groundPaint) { if (groundPaint != this.groundPaint) { EnvironmentPaint oldGroundPaint = this.groundPaint; this.groundPaint = groundPaint; this.propertyChangeSupport.firePropertyChange(Property.GROUND_PAINT.name(), oldGroundPaint, groundPaint); } } /** * Returns whether the ground is colored or textured. */ public EnvironmentPaint getGroundPaint() { return this.groundPaint; } /** * Sets the edited sky color. */ public void setSkyColor(int skyColor) { if (skyColor != this.skyColor) { int oldSkyColor = this.skyColor; this.skyColor = skyColor; this.propertyChangeSupport.firePropertyChange(Property.SKY_COLOR.name(), oldSkyColor, skyColor); } } /** * Returns the edited sky color. */ public int getSkyColor() { return this.skyColor; } /** * Sets whether the sky is colored or textured. */ public void setSkyPaint(EnvironmentPaint skyPaint) { if (skyPaint != this.skyPaint) { EnvironmentPaint oldSkyPaint = this.skyPaint; this.skyPaint = skyPaint; this.propertyChangeSupport.firePropertyChange(Property.SKY_PAINT.name(), oldSkyPaint, skyPaint); } } /** * Returns whether the sky is colored or textured. */ public EnvironmentPaint getSkyPaint() { return this.skyPaint; } /** * Sets the edited light color. */ public void setLightColor(int lightColor) { if (lightColor != this.lightColor) { int oldLightColor = this.lightColor; this.lightColor = lightColor; this.propertyChangeSupport.firePropertyChange(Property.LIGHT_COLOR.name(), oldLightColor, lightColor); } } /** * Returns the edited light color. */ public int getLightColor() { return this.lightColor; } /** * Sets the edited walls transparency alpha. */ public void setWallsAlpha(float wallsAlpha) { if (wallsAlpha != this.wallsAlpha) { float oldWallsAlpha = this.wallsAlpha; this.wallsAlpha = wallsAlpha; this.propertyChangeSupport.firePropertyChange(Property.WALLS_ALPHA.name(), oldWallsAlpha, wallsAlpha); } } /** * Returns the edited walls transparency alpha. */ public float getWallsAlpha() { return this.wallsAlpha; } /** * Controls the modification of the 3D attributes of the edited home. */ public void modify3DAttributes() { int groundColor = getGroundColor(); HomeTexture groundTexture = getGroundPaint() == EnvironmentPaint.TEXTURED ? getGroundTextureController().getTexture() : null; int skyColor = getSkyColor(); HomeTexture skyTexture = getSkyPaint() == EnvironmentPaint.TEXTURED ? getSkyTextureController().getTexture() : null; int lightColor = getLightColor(); float wallsAlpha = getWallsAlpha(); HomeEnvironment homeEnvironment = this.home.getEnvironment(); int oldGroundColor = homeEnvironment.getGroundColor(); HomeTexture oldGroundTexture = homeEnvironment.getGroundTexture(); int oldSkyColor = homeEnvironment.getSkyColor(); HomeTexture oldSkyTexture = homeEnvironment.getSkyTexture(); int oldLightColor = homeEnvironment.getLightColor(); float oldWallsAlpha = homeEnvironment.getWallsAlpha(); // Apply modification doModify3DAttributes(home, groundColor, groundTexture, skyColor, skyTexture, lightColor, wallsAlpha); if (this.undoSupport != null) { UndoableEdit undoableEdit = new Home3DAttributesModificationUndoableEdit( this.home, this.preferences, oldGroundColor, oldGroundTexture, oldSkyColor, oldSkyTexture, oldLightColor, oldWallsAlpha, groundColor, groundTexture, skyColor, skyTexture, lightColor, wallsAlpha); this.undoSupport.postEdit(undoableEdit); } } /** * Undoable edit for 3D attributes modification. This class isn't anonymous to avoid * being bound to controller and its view. */ private static class Home3DAttributesModificationUndoableEdit extends AbstractUndoableEdit { private final Home home; private final UserPreferences preferences; private final int oldGroundColor; private final HomeTexture oldGroundTexture; private final int oldSkyColor; private final HomeTexture oldSkyTexture; private final int oldLightColor; private final float oldWallsAlpha; private final int groundColor; private final HomeTexture groundTexture; private final int skyColor; private final HomeTexture skyTexture; private final int lightColor; private final float wallsAlpha; private Home3DAttributesModificationUndoableEdit(Home home, UserPreferences preferences, int oldGroundColor, HomeTexture oldGroundTexture, int oldSkyColor, HomeTexture oldSkyTexture, int oldLightColor, float oldWallsAlpha, int groundColor, HomeTexture groundTexture, int skyColor, HomeTexture skyTexture, int lightColor, float wallsAlpha) { this.home = home; this.preferences = preferences; this.oldGroundColor = oldGroundColor; this.oldGroundTexture = oldGroundTexture; this.oldSkyColor = oldSkyColor; this.oldSkyTexture = oldSkyTexture; this.oldLightColor = oldLightColor; this.oldWallsAlpha = oldWallsAlpha; this.groundColor = groundColor; this.groundTexture = groundTexture; this.skyColor = skyColor; this.skyTexture = skyTexture; this.lightColor = lightColor; this.wallsAlpha = wallsAlpha; } @Override public void undo() throws CannotUndoException { super.undo(); doModify3DAttributes(this.home, this.oldGroundColor, this.oldGroundTexture, this.oldSkyColor, this.oldSkyTexture, this.oldLightColor, this.oldWallsAlpha); } @Override public void redo() throws CannotRedoException { super.redo(); doModify3DAttributes(this.home, this.groundColor, this.groundTexture, this.skyColor, this.skyTexture, this.lightColor, this.wallsAlpha); } @Override public String getPresentationName() { return this.preferences.getLocalizedString( Home3DAttributesController.class, "undoModify3DAttributesName"); } } /** * Modifies the 3D attributes of the given <code>home</code>. */ private static void doModify3DAttributes(Home home, int groundColor, HomeTexture groundTexture, int skyColor, HomeTexture skyTexture, int lightColor, float wallsAlpha) { HomeEnvironment homeEnvironment = home.getEnvironment(); homeEnvironment.setGroundColor(groundColor); homeEnvironment.setGroundTexture(groundTexture); homeEnvironment.setSkyColor(skyColor); homeEnvironment.setSkyTexture(skyTexture); homeEnvironment.setLightColor(lightColor); homeEnvironment.setWallsAlpha(wallsAlpha); } }