allow changing of user interface orientation via settings

This commit is contained in:
Sebastian Stenzel
2019-10-18 12:51:41 +02:00
parent 7a1e20d732
commit aa61ab2b6e
6 changed files with 76 additions and 5 deletions

View File

@@ -17,6 +17,7 @@ import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.NodeOrientation;
import java.util.function.Consumer;
@@ -30,9 +31,10 @@ public class Settings {
public static final int DEFAULT_PORT = 42427;
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final WebDavUrlScheme DEFAULT_GVFS_SCHEME = WebDavUrlScheme.DAV;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
public static final boolean DEFAULT_DEBUG_MODE = false;
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = System.getProperty("os.name").toLowerCase().contains("windows") ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
public static final NodeOrientation DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT;
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
@@ -44,6 +46,7 @@ public class Settings {
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
private final ObjectProperty<VolumeImpl> preferredVolumeImpl = new SimpleObjectProperty<>(DEFAULT_PREFERRED_VOLUME_IMPL);
private final ObjectProperty<UiTheme> theme = new SimpleObjectProperty<>(DEFAULT_THEME);
private final ObjectProperty<NodeOrientation> userInterfaceOrientation = new SimpleObjectProperty<>(DEFAULT_USER_INTERFACE_ORIENTATION);
private Consumer<Settings> saveCmd;
@@ -61,6 +64,7 @@ public class Settings {
debugMode.addListener(this::somethingChanged);
preferredVolumeImpl.addListener(this::somethingChanged);
theme.addListener(this::somethingChanged);
userInterfaceOrientation.addListener(this::somethingChanged);
}
void setSaveCmd(Consumer<Settings> saveCmd) {
@@ -118,4 +122,8 @@ public class Settings {
public ObjectProperty<UiTheme> theme() {
return theme;
}
public ObjectProperty<NodeOrientation> userInterfaceOrientation() {
return userInterfaceOrientation;
}
}

View File

@@ -9,6 +9,7 @@ import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import javafx.geometry.NodeOrientation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,6 +37,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
out.name("debugMode").value(value.debugMode().get());
out.name("preferredVolumeImpl").value(value.preferredVolumeImpl().get().name());
out.name("theme").value(value.theme().get().name());
out.name("uiOrientation").value(value.userInterfaceOrientation().get().name());
out.endObject();
}
@@ -85,6 +87,9 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
case "theme":
settings.theme().set(parseUiTheme(in.nextString()));
break;
case "uiOrientation":
settings.userInterfaceOrientation().set(parseUiOrientation(in.nextString()));
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
@@ -109,7 +114,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
try {
return WebDavUrlScheme.valueOf(webDavUrlSchemeName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid volume type {}. Defaulting to {}.", webDavUrlSchemeName, Settings.DEFAULT_GVFS_SCHEME);
LOG.warn("Invalid WebDAV url scheme {}. Defaulting to {}.", webDavUrlSchemeName, Settings.DEFAULT_GVFS_SCHEME);
return Settings.DEFAULT_GVFS_SCHEME;
}
}
@@ -118,11 +123,20 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
try {
return UiTheme.valueOf(uiThemeName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid volume type {}. Defaulting to {}.", uiThemeName, Settings.DEFAULT_THEME);
LOG.warn("Invalid ui theme {}. Defaulting to {}.", uiThemeName, Settings.DEFAULT_THEME);
return Settings.DEFAULT_THEME;
}
}
private NodeOrientation parseUiOrientation(String uiOrientationName) {
try {
return NodeOrientation.valueOf(uiOrientationName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid ui orientation {}. Defaulting to {}.", uiOrientationName, Settings.DEFAULT_USER_INTERFACE_ORIENTATION);
return Settings.DEFAULT_USER_INTERFACE_ORIENTATION;
}
}
private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException {
List<VaultSettings> result = new ArrayList<>();
in.beginArray();

View File

@@ -8,6 +8,7 @@ import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.fxapp.FxApplicationScoped;
import javax.inject.Inject;
@@ -19,16 +20,25 @@ public class DefaultSceneFactory implements Function<Parent, Scene> {
protected static final KeyCodeCombination ALT_F4 = new KeyCodeCombination(KeyCode.F4, KeyCombination.ALT_DOWN);
protected static final KeyCodeCombination SHORTCUT_W = new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN);
protected final Settings settings;
@Inject
public DefaultSceneFactory() {}
public DefaultSceneFactory(Settings settings) {
this.settings = settings;
}
@Override
public Scene apply(Parent root) {
Scene scene = new Scene(root);
configureRoot(root);
configureScene(scene);
return scene;
}
protected void configureRoot(Parent root) {
root.nodeOrientationProperty().bind(settings.userInterfaceOrientation());
}
protected void configureScene(Scene scene) {
scene.windowProperty().addListener(observable -> {
Window window = scene.getWindow();

View File

@@ -7,6 +7,7 @@ import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.DefaultSceneFactory;
import javax.inject.Inject;
@@ -20,7 +21,8 @@ public class MainWindowSceneFactory extends DefaultSceneFactory {
private final Lazy<VaultListController> vaultListController;
@Inject
public MainWindowSceneFactory(Lazy<MainWindowController> mainWindowController, Lazy<VaultListController> vaultListController) {
public MainWindowSceneFactory(Settings settings, Lazy<MainWindowController> mainWindowController, Lazy<VaultListController> vaultListController) {
super(settings);
this.mainWindowController = mainWindowController;
this.vaultListController = vaultListController;
}

View File

@@ -1,21 +1,33 @@
package org.cryptomator.ui.preferences;
import javafx.beans.value.ObservableValue;
import javafx.geometry.NodeOrientation;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.util.StringConverter;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.ui.common.FxController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
@PreferencesScoped
public class GeneralPreferencesController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(GeneralPreferencesController.class);
private final Settings settings;
public ChoiceBox<UiTheme> themeChoiceBox;
public CheckBox startHiddenCheckbox;
public CheckBox debugModeCheckbox;
public ToggleGroup nodeOrientation;
public RadioButton nodeOrientationLtr;
public RadioButton nodeOrientationRtl;
@Inject
GeneralPreferencesController(Settings settings) {
@@ -30,6 +42,20 @@ public class GeneralPreferencesController implements FxController {
startHiddenCheckbox.selectedProperty().bindBidirectional(settings.startHidden());
debugModeCheckbox.selectedProperty().bindBidirectional(settings.debugMode());
nodeOrientation.selectedToggleProperty().addListener(this::toggleNodeOrientation);
nodeOrientationLtr.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.LEFT_TO_RIGHT);
nodeOrientationRtl.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.RIGHT_TO_LEFT);
}
private void toggleNodeOrientation(@SuppressWarnings("unused") ObservableValue<? extends Toggle> observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) {
if (nodeOrientationLtr.equals(newValue)) {
settings.userInterfaceOrientation().set(NodeOrientation.LEFT_TO_RIGHT);
} else if (nodeOrientationRtl.equals(newValue)) {
settings.userInterfaceOrientation().set(NodeOrientation.RIGHT_TO_LEFT);
} else {
LOG.warn("Unexpected toggle option {}", newValue);
}
}
/* Helper classes */

View File

@@ -6,10 +6,15 @@
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.ToggleGroup?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.preferences.GeneralPreferencesController"
spacing="6">
<fx:define>
<ToggleGroup fx:id="nodeOrientation"/>
</fx:define>
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
@@ -18,6 +23,12 @@
<Label text="%preferences.general.theme"/>
<ChoiceBox fx:id="themeChoiceBox"/>
</HBox>
<HBox spacing="6" alignment="CENTER_LEFT">
<Label text="Interface Orientation" HBox.hgrow="NEVER"/>
<RadioButton fx:id="nodeOrientationLtr" text="Left to Right" alignment="CENTER_LEFT" toggleGroup="${nodeOrientation}"/>
<RadioButton fx:id="nodeOrientationRtl" text="Right to Left" alignment="CENTER_RIGHT" toggleGroup="${nodeOrientation}"/>
</HBox>
<CheckBox fx:id="startHiddenCheckbox" text="%preferences.general.startHidden"/>