/* Copyright (c) 2016 Jesper Öqvist <jesper@llbit.se> * * This file is part of Chunky. * * Chunky 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 3 of the License, or * (at your option) any later version. * * Chunky 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 Chunky. If not, see <http://www.gnu.org/licenses/>. */ package se.llbit.chunky.ui.render; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.value.ChangeListener; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Tab; import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.util.converter.NumberStringConverter; import se.llbit.chunky.PersistentSettings; import se.llbit.chunky.renderer.RenderController; import se.llbit.chunky.renderer.scene.Scene; import se.llbit.chunky.ui.DoubleAdjuster; import se.llbit.chunky.ui.RenderControlsFxController; import se.llbit.chunky.ui.SimpleColorPicker; import se.llbit.chunky.world.World; import se.llbit.math.ColorUtil; import se.llbit.math.Vector3; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; public class WaterTab extends Tab implements RenderControlsTab, Initializable { private Scene scene; @FXML private CheckBox stillWater; @FXML private DoubleAdjuster waterVisibility; @FXML private DoubleAdjuster waterOpacity; @FXML private CheckBox waterWorld; @FXML private TextField waterHeight; @FXML private Button applyWaterHeight; @FXML private CheckBox useCustomWaterColor; @FXML private SimpleColorPicker waterColor; @FXML private Button saveDefaults; private IntegerProperty waterHeightProp = new SimpleIntegerProperty(); private RenderController controller; private final ChangeListener<javafx.scene.paint.Color> waterColorListener = (observable, oldValue, newValue) -> { scene.setWaterColor(ColorUtil.fromFx(newValue)); useCustomWaterColor.setSelected(true); }; public WaterTab() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("WaterTab.fxml")); loader.setRoot(this); loader.setController(this); loader.load(); } @Override public void setController(RenderControlsFxController controller) { this.controller = controller.getRenderController(); scene = this.controller.getSceneManager().getScene(); } @Override public void update(Scene scene) { int waterHeight = scene.getWaterHeight(); if (waterHeight != 0) { waterHeightProp.set(scene.getWaterHeight()); } waterWorld.setSelected(scene.getWaterHeight() != 0); useCustomWaterColor.setSelected(scene.getUseCustomWaterColor()); stillWater.setSelected(scene.stillWaterEnabled()); waterVisibility.set(scene.getWaterVisibility()); waterOpacity.set(scene.getWaterOpacity()); // Update water color without modifying the useCustomColor value. waterColor.colorProperty().removeListener(waterColorListener); waterColor.setColor(ColorUtil.toFx(scene.getWaterColor())); waterColor.colorProperty().addListener(waterColorListener); } @Override public Tab getTab() { return this; } @Override public void initialize(URL location, ResourceBundle resources) { waterVisibility.setName("Water visibility"); waterVisibility.setTooltip("Visibility depth under water."); waterVisibility.setRange(0, 20); waterVisibility.clampMin(); waterVisibility.onValueChange(value -> scene.setWaterVisibility(value)); waterOpacity.setName("Water opacity"); waterOpacity.setTooltip("Sets how opaque the water surface appears."); waterOpacity.setRange(0, 1); waterOpacity.clampBoth(); waterOpacity.onValueChange(value -> scene.setWaterOpacity(value)); stillWater.selectedProperty() .addListener((observable, oldValue, newValue) -> scene.setStillWater(newValue)); int initialWaterHeight = PersistentSettings.getWaterHeight(); if (initialWaterHeight == 0) { initialWaterHeight = World.SEA_LEVEL; } waterHeight.textProperty().bindBidirectional(waterHeightProp, new NumberStringConverter()); waterHeightProp.set(initialWaterHeight); applyWaterHeight.setOnAction(e -> { if (!waterWorld.isSelected()) { // The check box event handler will update scene config. waterWorld.setSelected(true); } else { scene.setWaterHeight(waterHeightProp.get()); controller.getSceneManager().reloadChunks(); } }); waterWorld.selectedProperty().addListener((observable, oldValue, newValue) -> { boolean reload; if (newValue) { reload = scene.setWaterHeight(waterHeightProp.get()); } else { reload = scene.setWaterHeight(0); } if (reload) { controller.getSceneManager().reloadChunks(); } }); useCustomWaterColor.selectedProperty().addListener((observable, oldValue, newValue) -> { scene.setUseCustomWaterColor(newValue); }); waterColor.colorProperty().addListener(waterColorListener); saveDefaults.setTooltip(new Tooltip("Store the current water settings as new defaults.")); saveDefaults.setOnAction(e -> { PersistentSettings.setStillWater(scene.stillWaterEnabled()); PersistentSettings.setWaterOpacity(scene.getWaterOpacity()); PersistentSettings.setWaterVisibility(scene.getWaterVisibility()); PersistentSettings.setWaterHeight(scene.getWaterHeight()); boolean useCustomWaterColor = scene.getUseCustomWaterColor(); PersistentSettings.setUseCustomWaterColor(useCustomWaterColor); if (useCustomWaterColor) { Vector3 color = scene.getWaterColor(); PersistentSettings.setWaterColor(color.x, color.y, color.z); } }); } }