/* * Copyright (c) 2016, 2018 Gluon * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Gluon, any associated website, nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL GLUON BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.gluonhq.notesapp.views; import com.gluonhq.charm.glisten.afterburner.GluonPresenter; import com.gluonhq.charm.glisten.animation.BounceInUpTransition; import com.gluonhq.charm.glisten.control.AppBar; import com.gluonhq.charm.glisten.control.SettingsPane; import com.gluonhq.charm.glisten.control.settings.DefaultOption; import com.gluonhq.charm.glisten.control.settings.Option; import com.gluonhq.charm.glisten.control.settings.OptionBase; import com.gluonhq.charm.glisten.control.settings.OptionEditor; import com.gluonhq.charm.glisten.mvc.View; import com.gluonhq.charm.glisten.visual.MaterialDesignIcon; import com.gluonhq.notesapp.NotesApp; import com.gluonhq.notesapp.model.Settings; import com.gluonhq.notesapp.model.Settings.SORTING; import com.gluonhq.notesapp.service.Service; import javafx.beans.property.BooleanProperty; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Slider; import javax.inject.Inject; import java.util.Optional; import java.util.function.Function; public class SettingsPresenter extends GluonPresenter<NotesApp> { @Inject private Service service; private Settings config; @FXML private View settings; @FXML private SettingsPane settingsPane; public void initialize() { settings.setShowTransitionFactory(BounceInUpTransition::new); settings.showingProperty().addListener((obs, oldValue, newValue) -> { if (newValue) { AppBar appBar = getApp().getAppBar(); appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> getApp().getDrawer().open())); appBar.setTitleText("Settings"); appBar.getActionItems().add(MaterialDesignIcon.CLOSE.button(e -> getApp().goHome())); } }); config = new Settings(); updateSettings(service.settingsProperty().get()); service.settingsProperty().addListener((obs, ov, nv) -> updateSettings(nv)); config.showDateProperty().addListener((obs, ov, nv) -> updateService()); config.sortingProperty().addListener((obs, ov, nv) -> updateService()); config.ascendingProperty().addListener((obs, ov, nv) -> updateService()); config.fontSizeProperty().addListener((obs, ov, nv) -> updateService()); final Option<BooleanProperty> dateOption = new DefaultOption<>(MaterialDesignIcon.DATE_RANGE.graphic(), "Show Date", "Show the note's date", null, config.showDateProperty(), true); final DefaultOption<ObjectProperty<SORTING>> sortOption = new DefaultOption<>(MaterialDesignIcon.SORT_BY_ALPHA.graphic(), "Sort Notes", "Sort the notes by", null, config.sortingProperty(), true); final DefaultOption<BooleanProperty> ascendingOption = new DefaultOption<>(MaterialDesignIcon.SORT.graphic(), "Asc./Des.", "Sort in ascending or descending order", null, config.ascendingProperty(), true); final Option<Number> fontOption = new SliderOption(MaterialDesignIcon.NETWORK_CELL.graphic(), "Size of Text", "Set the text size", null, config.fontSizeProperty(), true, 8, 12); settingsPane.getOptions().addAll(dateOption, sortOption, ascendingOption, fontOption); settingsPane.setSearchBoxVisible(false); } private void updateSettings(Settings settings) { this.config.setShowDate(settings.isShowDate()); this.config.setSorting(settings.getSorting()); this.config.setAscending(settings.isAscending()); this.config.setFontSize(settings.getFontSize()); } private void updateService() { Settings newConfig = new Settings(); newConfig.setShowDate(this.config.isShowDate()); newConfig.setFontSize(this.config.getFontSize()); newConfig.setSorting(this.config.getSorting()); newConfig.setAscending(this.config.isAscending()); service.settingsProperty().set(newConfig); service.storeSettings(); } private class SliderOption extends OptionBase<Number> { private final int min; private final int max; public SliderOption(Node graphic, String caption, String description, String category, IntegerProperty value, boolean isEditable, int min, int max) { super(graphic, caption, description, category, (Property<Number>) value, isEditable); this.min = min; this.max = max; } @Override public Property<Number> valueProperty() { return value; } @Override public Optional<Function<Option<Number>, OptionEditor<Number>>> editorFactoryProperty() { return Optional.of(option -> new SliderEditor(option, min, max)); } } private class SliderEditor implements OptionEditor<Number> { private final Slider slider; public SliderEditor(Option<Number> option, int min, int max) { slider = new Slider(min, max, option.valueProperty().getValue().doubleValue()); slider.setSnapToTicks(true); slider.setMajorTickUnit(1); slider.setMinorTickCount(0); valueProperty().bindBidirectional(option.valueProperty()); } @Override public Node getEditor() { return slider; } @Override public Number getValue() { return slider.getValue(); } @Override public void setValue(Number value) { slider.setValue(value.doubleValue()); } @Override public final Property<Number> valueProperty() { return (Property<Number>) slider.valueProperty(); } } }