1 /* 2 * Home3DAttributesController.java 25 juin 07 3 * 4 * Sweet Home 3D, Copyright (c) 2007 Emmanuel PUYBARET / eTeks <info@eteks.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 package com.eteks.sweethome3d.viewcontroller; 21 22 import java.beans.PropertyChangeEvent; 23 import java.beans.PropertyChangeListener; 24 import java.beans.PropertyChangeSupport; 25 26 import javax.swing.undo.CannotRedoException; 27 import javax.swing.undo.CannotUndoException; 28 import javax.swing.undo.UndoableEditSupport; 29 30 import com.eteks.sweethome3d.model.Home; 31 import com.eteks.sweethome3d.model.HomeEnvironment; 32 import com.eteks.sweethome3d.model.HomeTexture; 33 import com.eteks.sweethome3d.model.UserPreferences; 34 35 /** 36 * A MVC controller for home 3D attributes view. 37 * @author Emmanuel Puybaret 38 */ 39 public class Home3DAttributesController implements Controller { 40 /** 41 * The properties that may be edited by the view associated to this controller. 42 */ 43 public enum Property {GROUND_COLOR, GROUND_PAINT, BACKGROUND_IMAGE_VISIBLE_ON_GROUND_3D, SKY_COLOR, SKY_PAINT, LIGHT_COLOR, WALLS_ALPHA, WALLS_TOP_COLOR} 44 /** 45 * The possible values for {@linkplain #getGroundPaint() ground paint type}. 46 */ 47 public enum EnvironmentPaint {COLORED, TEXTURED} 48 49 private final Home home; 50 private final UserPreferences preferences; 51 private final ViewFactory viewFactory; 52 private final ContentManager contentManager; 53 private final UndoableEditSupport undoSupport; 54 private TextureChoiceController groundTextureController; 55 private TextureChoiceController skyTextureController; 56 private final PropertyChangeSupport propertyChangeSupport; 57 private DialogView home3DAttributesView; 58 59 private int groundColor; 60 private EnvironmentPaint groundPaint; 61 private boolean backgroundImageVisibleOnGround3D; 62 private int skyColor; 63 private EnvironmentPaint skyPaint; 64 private int lightColor; 65 private float wallsAlpha; 66 67 /** 68 * Creates the controller of 3D view with undo support. 69 */ Home3DAttributesController(Home home, UserPreferences preferences, ViewFactory viewFactory, ContentManager contentManager, UndoableEditSupport undoSupport)70 public Home3DAttributesController(Home home, 71 UserPreferences preferences, 72 ViewFactory viewFactory, 73 ContentManager contentManager, 74 UndoableEditSupport undoSupport) { 75 this.home = home; 76 this.preferences = preferences; 77 this.viewFactory = viewFactory; 78 this.contentManager = contentManager; 79 this.undoSupport = undoSupport; 80 this.propertyChangeSupport = new PropertyChangeSupport(this); 81 82 updateProperties(); 83 } 84 85 /** 86 * Returns the texture controller of the ground. 87 */ getGroundTextureController()88 public TextureChoiceController getGroundTextureController() { 89 // Create sub controller lazily only once it's needed 90 if (this.groundTextureController == null) { 91 this.groundTextureController = new TextureChoiceController( 92 this.preferences.getLocalizedString(Home3DAttributesController.class, "groundTextureTitle"), 93 this.preferences, this.viewFactory, this.contentManager); 94 this.groundTextureController.addPropertyChangeListener(TextureChoiceController.Property.TEXTURE, 95 new PropertyChangeListener() { 96 public void propertyChange(PropertyChangeEvent ev) { 97 setGroundPaint(EnvironmentPaint.TEXTURED); 98 } 99 }); 100 } 101 return this.groundTextureController; 102 } 103 104 /** 105 * Returns the texture controller of the sky. 106 */ getSkyTextureController()107 public TextureChoiceController getSkyTextureController() { 108 // Create sub controller lazily only once it's needed 109 if (this.skyTextureController == null) { 110 this.skyTextureController = new TextureChoiceController( 111 this.preferences.getLocalizedString(Home3DAttributesController.class, "skyTextureTitle"), 112 false, 113 this.preferences, this.viewFactory, this.contentManager); 114 this.skyTextureController.addPropertyChangeListener(TextureChoiceController.Property.TEXTURE, 115 new PropertyChangeListener() { 116 public void propertyChange(PropertyChangeEvent ev) { 117 setSkyPaint(EnvironmentPaint.TEXTURED); 118 } 119 }); 120 } 121 return this.skyTextureController; 122 } 123 124 /** 125 * Returns the view associated with this controller. 126 */ getView()127 public DialogView getView() { 128 // Create view lazily only once it's needed 129 if (this.home3DAttributesView == null) { 130 this.home3DAttributesView = this.viewFactory.createHome3DAttributesView( 131 this.preferences, this); 132 } 133 return this.home3DAttributesView; 134 } 135 136 /** 137 * Displays the view controlled by this controller. 138 */ displayView(View parentView)139 public void displayView(View parentView) { 140 getView().displayView(parentView); 141 } 142 143 /** 144 * Adds the property change <code>listener</code> in parameter to this controller. 145 */ addPropertyChangeListener(Property property, PropertyChangeListener listener)146 public void addPropertyChangeListener(Property property, PropertyChangeListener listener) { 147 this.propertyChangeSupport.addPropertyChangeListener(property.name(), listener); 148 } 149 150 /** 151 * Removes the property change <code>listener</code> in parameter from this controller. 152 */ removePropertyChangeListener(Property property, PropertyChangeListener listener)153 public void removePropertyChangeListener(Property property, PropertyChangeListener listener) { 154 this.propertyChangeSupport.removePropertyChangeListener(property.name(), listener); 155 } 156 157 /** 158 * Updates edited properties from the 3D attributes of the home edited by this controller. 159 */ updateProperties()160 protected void updateProperties() { 161 HomeEnvironment homeEnvironment = this.home.getEnvironment(); 162 setGroundColor(homeEnvironment.getGroundColor()); 163 HomeTexture groundTexture = homeEnvironment.getGroundTexture(); 164 getGroundTextureController().setTexture(groundTexture); 165 if (groundTexture != null) { 166 setGroundPaint(EnvironmentPaint.TEXTURED); 167 } else { 168 setGroundPaint(EnvironmentPaint.COLORED); 169 } 170 setBackgroundImageVisibleOnGround3D(homeEnvironment.isBackgroundImageVisibleOnGround3D()); 171 setSkyColor(homeEnvironment.getSkyColor()); 172 HomeTexture skyTexture = homeEnvironment.getSkyTexture(); 173 getSkyTextureController().setTexture(skyTexture); 174 if (skyTexture != null) { 175 setSkyPaint(EnvironmentPaint.TEXTURED); 176 } else { 177 setSkyPaint(EnvironmentPaint.COLORED); 178 } 179 setLightColor(homeEnvironment.getLightColor()); 180 setWallsAlpha(homeEnvironment.getWallsAlpha()); 181 } 182 183 /** 184 * Sets the edited ground color. 185 */ setGroundColor(int groundColor)186 public void setGroundColor(int groundColor) { 187 if (groundColor != this.groundColor) { 188 int oldGroundColor = this.groundColor; 189 this.groundColor = groundColor; 190 this.propertyChangeSupport.firePropertyChange(Property.GROUND_COLOR.name(), oldGroundColor, groundColor); 191 192 setGroundPaint(EnvironmentPaint.COLORED); 193 } 194 } 195 196 /** 197 * Returns the edited ground color. 198 */ getGroundColor()199 public int getGroundColor() { 200 return this.groundColor; 201 } 202 203 /** 204 * Sets whether the ground is colored or textured. 205 */ setGroundPaint(EnvironmentPaint groundPaint)206 public void setGroundPaint(EnvironmentPaint groundPaint) { 207 if (groundPaint != this.groundPaint) { 208 EnvironmentPaint oldGroundPaint = this.groundPaint; 209 this.groundPaint = groundPaint; 210 this.propertyChangeSupport.firePropertyChange(Property.GROUND_PAINT.name(), oldGroundPaint, groundPaint); 211 } 212 } 213 214 /** 215 * Returns whether the ground is colored or textured. 216 */ getGroundPaint()217 public EnvironmentPaint getGroundPaint() { 218 return this.groundPaint; 219 } 220 221 /** 222 * Returns <code>true</code> if the background image should be displayed on the ground in 3D. 223 * @since 6.0 224 */ isBackgroundImageVisibleOnGround3D()225 public boolean isBackgroundImageVisibleOnGround3D() { 226 return this.backgroundImageVisibleOnGround3D; 227 } 228 229 /** 230 * Sets whether the background image should be displayed on the ground in 3D. 231 * @since 6.0 232 */ setBackgroundImageVisibleOnGround3D(boolean backgroundImageVisibleOnGround3D)233 public void setBackgroundImageVisibleOnGround3D(boolean backgroundImageVisibleOnGround3D) { 234 if (this.backgroundImageVisibleOnGround3D != backgroundImageVisibleOnGround3D) { 235 this.backgroundImageVisibleOnGround3D = backgroundImageVisibleOnGround3D; 236 this.propertyChangeSupport.firePropertyChange(Property.BACKGROUND_IMAGE_VISIBLE_ON_GROUND_3D.name(), 237 !backgroundImageVisibleOnGround3D, backgroundImageVisibleOnGround3D); 238 } 239 } 240 241 /** 242 * Sets the edited sky color. 243 */ setSkyColor(int skyColor)244 public void setSkyColor(int skyColor) { 245 if (skyColor != this.skyColor) { 246 int oldSkyColor = this.skyColor; 247 this.skyColor = skyColor; 248 this.propertyChangeSupport.firePropertyChange(Property.SKY_COLOR.name(), oldSkyColor, skyColor); 249 } 250 } 251 252 /** 253 * Returns the edited sky color. 254 */ getSkyColor()255 public int getSkyColor() { 256 return this.skyColor; 257 } 258 259 /** 260 * Sets whether the sky is colored or textured. 261 */ setSkyPaint(EnvironmentPaint skyPaint)262 public void setSkyPaint(EnvironmentPaint skyPaint) { 263 if (skyPaint != this.skyPaint) { 264 EnvironmentPaint oldSkyPaint = this.skyPaint; 265 this.skyPaint = skyPaint; 266 this.propertyChangeSupport.firePropertyChange(Property.SKY_PAINT.name(), oldSkyPaint, skyPaint); 267 } 268 } 269 270 /** 271 * Returns whether the sky is colored or textured. 272 */ getSkyPaint()273 public EnvironmentPaint getSkyPaint() { 274 return this.skyPaint; 275 } 276 277 /** 278 * Sets the edited light color. 279 */ setLightColor(int lightColor)280 public void setLightColor(int lightColor) { 281 if (lightColor != this.lightColor) { 282 int oldLightColor = this.lightColor; 283 this.lightColor = lightColor; 284 this.propertyChangeSupport.firePropertyChange(Property.LIGHT_COLOR.name(), oldLightColor, lightColor); 285 } 286 } 287 288 /** 289 * Returns the edited light color. 290 */ getLightColor()291 public int getLightColor() { 292 return this.lightColor; 293 } 294 295 /** 296 * Sets the edited walls transparency alpha. 297 */ setWallsAlpha(float wallsAlpha)298 public void setWallsAlpha(float wallsAlpha) { 299 if (wallsAlpha != this.wallsAlpha) { 300 float oldWallsAlpha = this.wallsAlpha; 301 this.wallsAlpha = wallsAlpha; 302 this.propertyChangeSupport.firePropertyChange(Property.WALLS_ALPHA.name(), oldWallsAlpha, wallsAlpha); 303 } 304 } 305 306 /** 307 * Returns the edited walls transparency alpha. 308 */ getWallsAlpha()309 public float getWallsAlpha() { 310 return this.wallsAlpha; 311 } 312 313 /** 314 * Controls the modification of the 3D attributes of the edited home. 315 */ modify3DAttributes()316 public void modify3DAttributes() { 317 int groundColor = getGroundColor(); 318 HomeTexture groundTexture = getGroundPaint() == EnvironmentPaint.TEXTURED 319 ? getGroundTextureController().getTexture() 320 : null; 321 boolean backgroundImageVisibleOnGround3D = isBackgroundImageVisibleOnGround3D(); 322 int skyColor = getSkyColor(); 323 HomeTexture skyTexture = getSkyPaint() == EnvironmentPaint.TEXTURED 324 ? getSkyTextureController().getTexture() 325 : null; 326 int lightColor = getLightColor(); 327 float wallsAlpha = getWallsAlpha(); 328 329 HomeEnvironment homeEnvironment = this.home.getEnvironment(); 330 int oldGroundColor = homeEnvironment.getGroundColor(); 331 boolean oldBackgroundImageVisibleOnGround3D = homeEnvironment.isBackgroundImageVisibleOnGround3D(); 332 HomeTexture oldGroundTexture = homeEnvironment.getGroundTexture(); 333 int oldSkyColor = homeEnvironment.getSkyColor(); 334 HomeTexture oldSkyTexture = homeEnvironment.getSkyTexture(); 335 int oldLightColor = homeEnvironment.getLightColor(); 336 float oldWallsAlpha = homeEnvironment.getWallsAlpha(); 337 338 // Apply modification 339 doModify3DAttributes(home, groundColor, groundTexture, backgroundImageVisibleOnGround3D, skyColor, 340 skyTexture, lightColor, wallsAlpha); 341 if (this.undoSupport != null) { 342 this.undoSupport.postEdit(new Home3DAttributesModificationUndoableEdit( 343 this.home, this.preferences, 344 oldGroundColor, oldGroundTexture, 345 oldBackgroundImageVisibleOnGround3D, oldSkyColor, 346 oldSkyTexture, oldLightColor, oldWallsAlpha, 347 groundColor, groundTexture, 348 backgroundImageVisibleOnGround3D, skyColor, 349 skyTexture, lightColor, wallsAlpha)); 350 } 351 } 352 353 /** 354 * Undoable edit for 3D attributes modification. This class isn't anonymous to avoid 355 * being bound to controller and its view. 356 */ 357 private static class Home3DAttributesModificationUndoableEdit extends LocalizedUndoableEdit { 358 private final Home home; 359 private final int oldGroundColor; 360 private final HomeTexture oldGroundTexture; 361 private final boolean oldBackgroundImageVisibleOnGround3D; 362 private final int oldSkyColor; 363 private final HomeTexture oldSkyTexture; 364 private final int oldLightColor; 365 private final float oldWallsAlpha; 366 private final int groundColor; 367 private final HomeTexture groundTexture; 368 private final boolean backgroundImageVisibleOnGround3D; 369 private final int skyColor; 370 private final HomeTexture skyTexture; 371 private final int lightColor; 372 private final float wallsAlpha; 373 Home3DAttributesModificationUndoableEdit(Home home, UserPreferences preferences, int oldGroundColor, HomeTexture oldGroundTexture, boolean oldBackgroundImageVisibleOnGround3D, int oldSkyColor, HomeTexture oldSkyTexture, int oldLightColor, float oldWallsAlpha, int groundColor, HomeTexture groundTexture, boolean backgroundImageVisibleOnGround3D, int skyColor, HomeTexture skyTexture, int lightColor, float wallsAlpha)374 private Home3DAttributesModificationUndoableEdit(Home home, 375 UserPreferences preferences, 376 int oldGroundColor, 377 HomeTexture oldGroundTexture, 378 boolean oldBackgroundImageVisibleOnGround3D, 379 int oldSkyColor, 380 HomeTexture oldSkyTexture, 381 int oldLightColor, 382 float oldWallsAlpha, 383 int groundColor, 384 HomeTexture groundTexture, 385 boolean backgroundImageVisibleOnGround3D, 386 int skyColor, 387 HomeTexture skyTexture, 388 int lightColor, 389 float wallsAlpha) { 390 super(preferences, Home3DAttributesController.class, "undoModify3DAttributesName"); 391 this.home = home; 392 this.oldGroundColor = oldGroundColor; 393 this.oldGroundTexture = oldGroundTexture; 394 this.oldBackgroundImageVisibleOnGround3D = oldBackgroundImageVisibleOnGround3D; 395 this.oldSkyColor = oldSkyColor; 396 this.oldSkyTexture = oldSkyTexture; 397 this.oldLightColor = oldLightColor; 398 this.oldWallsAlpha = oldWallsAlpha; 399 this.groundColor = groundColor; 400 this.groundTexture = groundTexture; 401 this.backgroundImageVisibleOnGround3D = backgroundImageVisibleOnGround3D; 402 this.skyColor = skyColor; 403 this.skyTexture = skyTexture; 404 this.lightColor = lightColor; 405 this.wallsAlpha = wallsAlpha; 406 } 407 408 @Override undo()409 public void undo() throws CannotUndoException { 410 super.undo(); 411 doModify3DAttributes(this.home, this.oldGroundColor, this.oldGroundTexture, this.oldBackgroundImageVisibleOnGround3D, 412 this.oldSkyColor, this.oldSkyTexture, this.oldLightColor, this.oldWallsAlpha); 413 } 414 415 @Override redo()416 public void redo() throws CannotRedoException { 417 super.redo(); 418 doModify3DAttributes(this.home, this.groundColor, this.groundTexture, this.backgroundImageVisibleOnGround3D, 419 this.skyColor, this.skyTexture, this.lightColor, this.wallsAlpha); 420 } 421 } 422 423 /** 424 * Modifies the 3D attributes of the given <code>home</code>. 425 */ doModify3DAttributes(Home home, int groundColor, HomeTexture groundTexture, boolean backgroundImageVisibleOnGround3D, int skyColor, HomeTexture skyTexture, int lightColor, float wallsAlpha)426 private static void doModify3DAttributes(Home home, 427 int groundColor, HomeTexture groundTexture, 428 boolean backgroundImageVisibleOnGround3D, 429 int skyColor, HomeTexture skyTexture, 430 int lightColor, 431 float wallsAlpha) { 432 HomeEnvironment homeEnvironment = home.getEnvironment(); 433 homeEnvironment.setGroundColor(groundColor); 434 homeEnvironment.setGroundTexture(groundTexture); 435 homeEnvironment.setBackgroundImageVisibleOnGround3D(backgroundImageVisibleOnGround3D); 436 homeEnvironment.setSkyColor(skyColor); 437 homeEnvironment.setSkyTexture(skyTexture); 438 homeEnvironment.setLightColor(lightColor); 439 homeEnvironment.setWallsAlpha(wallsAlpha); 440 } 441 } 442