mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-19 00:36:10 -04:00
theme selection
This commit is contained in:
parent
7fca697234
commit
0fb248e6be
@ -407,6 +407,31 @@ public class Settings {
|
|||||||
this.backgroundImageType.set(backgroundImageType);
|
this.backgroundImageType.set(backgroundImageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************
|
||||||
|
* THEME *
|
||||||
|
****************************************/
|
||||||
|
|
||||||
|
private final ImmediateObjectProperty<Theme> theme = new ImmediateObjectProperty<Theme>(this, "theme", Theme.getTheme(SETTINGS.getTheme()).orElse(Theme.BLUE)) {
|
||||||
|
@Override
|
||||||
|
public void invalidated() {
|
||||||
|
super.invalidated();
|
||||||
|
|
||||||
|
SETTINGS.setTheme(get().name().toLowerCase());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Theme getTheme() {
|
||||||
|
return theme.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTheme(Theme theme) {
|
||||||
|
this.theme.set(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmediateObjectProperty<Theme> themeProperty() {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* PROFILES *
|
* PROFILES *
|
||||||
****************************************/
|
****************************************/
|
||||||
|
45
HMCL/src/main/java/org/jackhuang/hmcl/setting/Theme.java
Normal file
45
HMCL/src/main/java/org/jackhuang/hmcl/setting/Theme.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.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 3 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, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.setting;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public enum Theme {
|
||||||
|
BLUE,
|
||||||
|
DARK_BLUE,
|
||||||
|
GREEN,
|
||||||
|
ORANGE,
|
||||||
|
PURPLE,
|
||||||
|
RED;
|
||||||
|
|
||||||
|
public String[] getStylesheets() {
|
||||||
|
return new String[]{
|
||||||
|
Theme.class.getResource("/css/jfoenix-fonts.css").toExternalForm(),
|
||||||
|
Theme.class.getResource("/css/jfoenix-design.css").toExternalForm(),
|
||||||
|
Theme.class.getResource("/assets/css/" + name().toLowerCase() + ".css").toExternalForm(),
|
||||||
|
Theme.class.getResource("/assets/css/root.css").toExternalForm()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Theme> getTheme(String name) {
|
||||||
|
for (Theme theme : values())
|
||||||
|
if (theme.name().equalsIgnoreCase(name))
|
||||||
|
return Optional.of(theme);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
@ -92,7 +92,7 @@ public final class Controllers {
|
|||||||
decorator.setCustomMaximize(false);
|
decorator.setCustomMaximize(false);
|
||||||
|
|
||||||
scene = new Scene(decorator, 804, 521);
|
scene = new Scene(decorator, 804, 521);
|
||||||
scene.getStylesheets().addAll(FXUtils.STYLESHEETS);
|
scene.getStylesheets().addAll(Settings.INSTANCE.getTheme().getStylesheets());
|
||||||
stage.setMinWidth(804);
|
stage.setMinWidth(804);
|
||||||
stage.setMaxWidth(804);
|
stage.setMaxWidth(804);
|
||||||
stage.setMinHeight(521);
|
stage.setMinHeight(521);
|
||||||
|
@ -132,12 +132,6 @@ public final class FXUtils {
|
|||||||
Lang.invoke(() -> loader.load());
|
Lang.invoke(() -> loader.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WritableImage takeSnapshot(Parent node, double width, double height) {
|
|
||||||
Scene scene = new Scene(node, width, height);
|
|
||||||
scene.getStylesheets().addAll(STYLESHEETS);
|
|
||||||
return scene.snapshot(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void resetChildren(JFXMasonryPane pane, List<Node> children) {
|
public static void resetChildren(JFXMasonryPane pane, List<Node> children) {
|
||||||
// Fixes mis-repositioning.
|
// Fixes mis-repositioning.
|
||||||
ReflectionHelper.setFieldContent(JFXMasonryPane.class, pane, "oldBoxes", null);
|
ReflectionHelper.setFieldContent(JFXMasonryPane.class, pane, "oldBoxes", null);
|
||||||
@ -325,12 +319,6 @@ public final class FXUtils {
|
|||||||
|
|
||||||
public static final Image DEFAULT_ICON = new Image("/assets/img/icon.png");
|
public static final Image DEFAULT_ICON = new Image("/assets/img/icon.png");
|
||||||
|
|
||||||
public static final String[] STYLESHEETS = new String[]{
|
|
||||||
FXUtils.class.getResource("/css/jfoenix-fonts.css").toExternalForm(),
|
|
||||||
FXUtils.class.getResource("/css/jfoenix-design.css").toExternalForm(),
|
|
||||||
FXUtils.class.getResource("/assets/css/jfoenix-main-demo.css").toExternalForm()
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final Interpolator SINE = new Interpolator() {
|
public static final Interpolator SINE = new Interpolator() {
|
||||||
@Override
|
@Override
|
||||||
protected double curve(double t) {
|
protected double curve(double t) {
|
||||||
|
@ -62,7 +62,7 @@ public final class LogWindow extends Stage {
|
|||||||
|
|
||||||
public LogWindow() {
|
public LogWindow() {
|
||||||
setScene(new Scene(impl, 800, 480));
|
setScene(new Scene(impl, 800, 480));
|
||||||
getScene().getStylesheets().addAll(FXUtils.STYLESHEETS);
|
getScene().getStylesheets().addAll(Settings.INSTANCE.getTheme().getStylesheets());
|
||||||
setTitle(Main.i18n("logwindow.title"));
|
setTitle(Main.i18n("logwindow.title"));
|
||||||
getIcons().add(new Image("/assets/img/icon.png"));
|
getIcons().add(new Image("/assets/img/icon.png"));
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui;
|
|||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import com.jfoenix.controls.JFXComboBox;
|
import com.jfoenix.controls.JFXComboBox;
|
||||||
import com.jfoenix.controls.JFXTextField;
|
import com.jfoenix.controls.JFXTextField;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
@ -77,6 +78,8 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
private ScrollPane scroll;
|
private ScrollPane scroll;
|
||||||
@FXML
|
@FXML
|
||||||
private MultiFileItem backgroundItem;
|
private MultiFileItem backgroundItem;
|
||||||
|
@FXML
|
||||||
|
private MultiFileItem themeItem;
|
||||||
|
|
||||||
{
|
{
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/setting.fxml");
|
FXUtils.loadFXML(this, "/assets/fxml/setting.fxml");
|
||||||
@ -152,6 +155,20 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
backgroundItem.setToggleSelectedListener(newValue -> {
|
backgroundItem.setToggleSelectedListener(newValue -> {
|
||||||
Settings.INSTANCE.setBackgroundImageType((EnumBackgroundImage) newValue.getUserData());
|
Settings.INSTANCE.setBackgroundImageType((EnumBackgroundImage) newValue.getUserData());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
themeItem.loadChildren(Arrays.asList(
|
||||||
|
themeItem.createChildren(Main.i18n("color.blue"), Theme.BLUE),
|
||||||
|
themeItem.createChildren(Main.i18n("color.dark_blue"), Theme.DARK_BLUE),
|
||||||
|
themeItem.createChildren(Main.i18n("color.green"), Theme.GREEN),
|
||||||
|
themeItem.createChildren(Main.i18n("color.orange"), Theme.ORANGE),
|
||||||
|
themeItem.createChildren(Main.i18n("color.purple"), Theme.PURPLE),
|
||||||
|
themeItem.createChildren(Main.i18n("color.red"), Theme.RED)
|
||||||
|
));
|
||||||
|
|
||||||
|
themeItem.getGroup().getToggles().stream().filter(it -> Settings.INSTANCE.getTheme() == it.getUserData()).findFirst().ifPresent(it -> it.setSelected(true));
|
||||||
|
themeItem.setToggleSelectedListener(newValue -> Settings.INSTANCE.setTheme((Theme) newValue.getUserData()));
|
||||||
|
Settings.INSTANCE.themeProperty().setChangedListenerAndOperate(it ->
|
||||||
|
themeItem.setSubtitle(Main.i18n("color." + it.name().toLowerCase())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initBackgroundItemSubtitle() {
|
private void initBackgroundItemSubtitle() {
|
||||||
|
@ -21,13 +21,14 @@ import javafx.scene.Scene;
|
|||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.web.WebView;
|
import javafx.scene.web.WebView;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import org.jackhuang.hmcl.setting.Settings;
|
||||||
|
|
||||||
public class WebStage extends Stage {
|
public class WebStage extends Stage {
|
||||||
private final WebView webView = new WebView();
|
private final WebView webView = new WebView();
|
||||||
|
|
||||||
public WebStage() {
|
public WebStage() {
|
||||||
setScene(new Scene(webView, 800, 480));
|
setScene(new Scene(webView, 800, 480));
|
||||||
getScene().getStylesheets().addAll(FXUtils.STYLESHEETS);
|
getScene().getStylesheets().addAll(Settings.INSTANCE.getTheme().getStylesheets());
|
||||||
getIcons().add(new Image("/assets/img/icon.png"));
|
getIcons().add(new Image("/assets/img/icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +134,8 @@ public class RipplerContainer extends StackPane {
|
|||||||
};
|
};
|
||||||
|
|
||||||
selectedProperty().addListener(listener);
|
selectedProperty().addListener(listener);
|
||||||
|
selectedProperty().addListener((a, b, newValue) ->
|
||||||
|
pseudoClassStateChanged(PseudoClass.getPseudoClass("selected"), newValue));
|
||||||
ripplerFillProperty().addListener(listener);
|
ripplerFillProperty().addListener(listener);
|
||||||
|
|
||||||
setShape(Lang.apply(new Rectangle(), rectangle -> {
|
setShape(Lang.apply(new Rectangle(), rectangle -> {
|
||||||
|
5
HMCL/src/main/resources/assets/css/blue.css
Normal file
5
HMCL/src/main/resources/assets/css/blue.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
-fx-base-color: #3F51B5;
|
||||||
|
-fx-base-check-color: derive(-fx-base-color, 30%);
|
||||||
|
-fx-base-text-fill: white;
|
||||||
|
}
|
5
HMCL/src/main/resources/assets/css/dark_blue.css
Normal file
5
HMCL/src/main/resources/assets/css/dark_blue.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
-fx-base-color: #283593;
|
||||||
|
-fx-base-check-color: derive(-fx-base-color, 30%);
|
||||||
|
-fx-base-text-fill: white;
|
||||||
|
}
|
5
HMCL/src/main/resources/assets/css/green.css
Normal file
5
HMCL/src/main/resources/assets/css/green.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
-fx-base-color: #43A047;
|
||||||
|
-fx-base-check-color: derive(-fx-base-color, 30%);
|
||||||
|
-fx-base-text-fill: black;
|
||||||
|
}
|
5
HMCL/src/main/resources/assets/css/orange.css
Normal file
5
HMCL/src/main/resources/assets/css/orange.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
-fx-base-color: #E67E22;
|
||||||
|
-fx-base-check-color: derive(-fx-base-color, 30%);
|
||||||
|
-fx-base-text-fill: black;
|
||||||
|
}
|
5
HMCL/src/main/resources/assets/css/purple.css
Normal file
5
HMCL/src/main/resources/assets/css/purple.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
-fx-base-color: #9C27B0;
|
||||||
|
-fx-base-check-color: derive(-fx-base-color, 30%);
|
||||||
|
-fx-base-text-fill: white;
|
||||||
|
}
|
5
HMCL/src/main/resources/assets/css/red.css
Normal file
5
HMCL/src/main/resources/assets/css/red.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
-fx-base-color: #F44336;
|
||||||
|
-fx-base-check-color: derive(-fx-base-color, 30%);
|
||||||
|
-fx-base-text-fill: black;
|
||||||
|
}
|
@ -4,8 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
-fx-base-color: #ec407a;
|
|
||||||
-fx-base-check-color: derive(-fx-base-color, 30%);/*#0F9D58;*/
|
|
||||||
-fx-font-family: "Roboto";
|
-fx-font-family: "Roboto";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +44,14 @@
|
|||||||
-fx-border-width: 1;
|
-fx-border-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rippler-container:selected .label {
|
||||||
|
-fx-text-fill: -fx-base-text-fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rippler-container= .label {
|
||||||
|
-fx-text-fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
.class-title {
|
.class-title {
|
||||||
-fx-font-size: 12px;
|
-fx-font-size: 12px;
|
||||||
-fx-padding: 0 16 0 16;
|
-fx-padding: 0 16 0 16;
|
@ -15,7 +15,7 @@
|
|||||||
</JFXMasonryPane>
|
</JFXMasonryPane>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
<AnchorPane pickOnBounds="false">
|
<AnchorPane pickOnBounds="false">
|
||||||
<JFXButton onMouseClicked="#addNewAccount" AnchorPane.bottomAnchor="16" AnchorPane.rightAnchor="16" buttonType="RAISED" prefWidth="40" prefHeight="40" style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;-fx-background-radius: 80px;">
|
<JFXButton onMouseClicked="#addNewAccount" AnchorPane.bottomAnchor="16" AnchorPane.rightAnchor="16" buttonType="RAISED" prefWidth="40" prefHeight="40" styleClass="jfx-button-raised-round">
|
||||||
<graphic>
|
<graphic>
|
||||||
<fx:include source="/assets/svg/plus.fxml" />
|
<fx:include source="/assets/svg/plus.fxml" />
|
||||||
</graphic>
|
</graphic>
|
||||||
|
@ -66,7 +66,9 @@
|
|||||||
<Label text="%settings.launcher.proxy.password" />
|
<Label text="%settings.launcher.proxy.password" />
|
||||||
<JFXTextField fx:id="txtProxyPassword" maxWidth="50" />
|
<JFXTextField fx:id="txtProxyPassword" maxWidth="50" />
|
||||||
</HBox></right></BorderPane>
|
</HBox></right></BorderPane>
|
||||||
<!--BorderPane><left><Label text="%launcher_settings.theme" /></left><right></right></BorderPane-->
|
|
||||||
|
<MultiFileItem fx:id="themeItem" title="%settings.launcher.theme" hasSubtitle="true" hasCustom="false" />
|
||||||
|
|
||||||
<VBox spacing="5">
|
<VBox spacing="5">
|
||||||
<BorderPane><left><Label text="%settings.launcher.log_font" BorderPane.alignment="CENTER_LEFT" /></left><right><HBox spacing="3"><FontComboBox fontSize="12" enableStyle="false" fx:id="cboFont" /><JFXTextField fx:id="txtFontSize" maxWidth="50" minWidth="50" /></HBox></right></BorderPane>
|
<BorderPane><left><Label text="%settings.launcher.log_font" BorderPane.alignment="CENTER_LEFT" /></left><right><HBox spacing="3"><FontComboBox fontSize="12" enableStyle="false" fx:id="cboFont" /><JFXTextField fx:id="txtFontSize" maxWidth="50" minWidth="50" /></HBox></right></BorderPane>
|
||||||
<Label fx:id="lblDisplay" text="[23:33:33] [Client Thread/INFO] [WaterPower]: Loaded mod WaterPower." />
|
<Label fx:id="lblDisplay" text="[23:33:33] [Client Thread/INFO] [WaterPower]: Loaded mod WaterPower." />
|
||||||
|
@ -55,6 +55,11 @@ public class ImmediateObjectProperty<T> extends SimpleObjectProperty<T> {
|
|||||||
this.listener = Objects.requireNonNull(listener);
|
this.listener = Objects.requireNonNull(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setChangedListenerAndOperate(Consumer<T> listener) {
|
||||||
|
this.listener = Objects.requireNonNull(listener);
|
||||||
|
listener.accept(get());
|
||||||
|
}
|
||||||
|
|
||||||
public ImmediateObjectProperty(Object bean, String name, T initialValue) {
|
public ImmediateObjectProperty(Object bean, String name, T initialValue) {
|
||||||
super(bean, name, initialValue);
|
super(bean, name, initialValue);
|
||||||
addListener(changeListener);
|
addListener(changeListener);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user