feat: title bar with color

This commit is contained in:
huanghongxun 2021-08-28 01:24:36 +08:00
parent e9bc1524f1
commit a560eff153
15 changed files with 38 additions and 44 deletions

View File

@ -30,7 +30,7 @@ public final class Metadata {
private Metadata() {} private Metadata() {}
public static final String VERSION = System.getProperty("hmcl.version.override", JarUtils.thisJar().flatMap(JarUtils::getImplementationVersion).orElse("@develop@")); public static final String VERSION = System.getProperty("hmcl.version.override", JarUtils.thisJar().flatMap(JarUtils::getImplementationVersion).orElse("@develop@"));
public static final String NAME = "HMCL"; public static final String NAME = "Hello Minecraft! Launcher";
public static final String TITLE = NAME + " " + VERSION; public static final String TITLE = NAME + " " + VERSION;
public static final String UPDATE_URL = System.getProperty("hmcl.update_source.override", "https://hmcl.huangyuhui.net/api/update_link"); public static final String UPDATE_URL = System.getProperty("hmcl.update_source.override", "https://hmcl.huangyuhui.net/api/update_link");

View File

@ -41,7 +41,7 @@ public class Theme {
public static final Theme BLUE = new Theme("blue", "#5C6BC0"); public static final Theme BLUE = new Theme("blue", "#5C6BC0");
public static final Color BLACK = Color.web("#292929"); public static final Color BLACK = Color.web("#292929");
public static final Color[] SUGGESTED_COLORS = new Color[]{ public static final Color[] SUGGESTED_COLORS = new Color[]{
Color.web("#5C6BC0"), // blue Color.web("#3D6DA3"), // blue
Color.web("#283593"), // dark blue Color.web("#283593"), // dark blue
Color.web("#43A047"), // green Color.web("#43A047"), // green
Color.web("#E67E22"), // orange Color.web("#E67E22"), // orange

View File

@ -172,8 +172,8 @@ public final class Controllers {
scene = new Scene(decorator.getDecorator()); scene = new Scene(decorator.getDecorator());
scene.setFill(Color.TRANSPARENT); scene.setFill(Color.TRANSPARENT);
stage.setMinHeight(482 + 32); stage.setMinHeight(450 + 2 + 40 + 16); // bg height + border width*2 + toolbar height + shadow width*2
stage.setMinWidth(802 + 32); stage.setMinWidth(800 + 2 + 16); // bg width + border width*2 + shadow width*2
decorator.getDecorator().prefWidthProperty().bind(scene.widthProperty()); decorator.getDecorator().prefWidthProperty().bind(scene.widthProperty());
decorator.getDecorator().prefHeightProperty().bind(scene.heightProperty()); decorator.getDecorator().prefHeightProperty().bind(scene.heightProperty());
scene.getStylesheets().setAll(config().getTheme().getStylesheets()); scene.getStylesheets().setAll(config().getTheme().getStylesheets());

View File

@ -50,20 +50,18 @@ public interface DecoratorPage extends Refreshable {
private final boolean backable; private final boolean backable;
private final boolean refreshable; private final boolean refreshable;
private final boolean animate; private final boolean animate;
private final boolean titleBarTransparent;
private final double leftPaneWidth; private final double leftPaneWidth;
public State(String title, Node titleNode, boolean backable, boolean refreshable, boolean animate) { public State(String title, Node titleNode, boolean backable, boolean refreshable, boolean animate) {
this(title, titleNode, backable, refreshable, animate, false, 0); this(title, titleNode, backable, refreshable, animate, 0);
} }
public State(String title, Node titleNode, boolean backable, boolean refreshable, boolean animate, boolean titleBarTransparent, double leftPaneWidth) { public State(String title, Node titleNode, boolean backable, boolean refreshable, boolean animate, double leftPaneWidth) {
this.title = title; this.title = title;
this.titleNode = titleNode; this.titleNode = titleNode;
this.backable = backable; this.backable = backable;
this.refreshable = refreshable; this.refreshable = refreshable;
this.animate = animate; this.animate = animate;
this.titleBarTransparent = titleBarTransparent;
this.leftPaneWidth = leftPaneWidth; this.leftPaneWidth = leftPaneWidth;
} }
@ -95,10 +93,6 @@ public interface DecoratorPage extends Refreshable {
return animate; return animate;
} }
public boolean isTitleBarTransparent() {
return titleBarTransparent;
}
public double getLeftPaneWidth() { public double getLeftPaneWidth() {
return leftPaneWidth; return leftPaneWidth;
} }

View File

@ -31,7 +31,6 @@ import org.jackhuang.hmcl.ui.wizard.Refreshable;
public abstract class DecoratorTransitionPage extends Control implements DecoratorPage { public abstract class DecoratorTransitionPage extends Control implements DecoratorPage {
protected final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle("")); protected final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle(""));
private final DoubleProperty leftPaneWidth = new SimpleDoubleProperty(); private final DoubleProperty leftPaneWidth = new SimpleDoubleProperty();
private final BooleanProperty titleBarTransparent = new SimpleBooleanProperty(false);
private final BooleanProperty backable = new SimpleBooleanProperty(false); private final BooleanProperty backable = new SimpleBooleanProperty(false);
private final BooleanProperty refreshable = new SimpleBooleanProperty(false); private final BooleanProperty refreshable = new SimpleBooleanProperty(false);
private Node currentPage; private Node currentPage;
@ -57,11 +56,11 @@ public abstract class DecoratorTransitionPage extends Control implements Decorat
if (to instanceof DecoratorPage) { if (to instanceof DecoratorPage) {
state.bind(Bindings.createObjectBinding(() -> { state.bind(Bindings.createObjectBinding(() -> {
State state = ((DecoratorPage) to).stateProperty().get(); State state = ((DecoratorPage) to).stateProperty().get();
return new State(state.getTitle(), state.getTitleNode(), backable.get(), state.isRefreshable(), true, titleBarTransparent.get(), leftPaneWidth.get()); return new State(state.getTitle(), state.getTitleNode(), backable.get(), state.isRefreshable(), true, leftPaneWidth.get());
}, ((DecoratorPage) to).stateProperty())); }, ((DecoratorPage) to).stateProperty()));
} else { } else {
state.unbind(); state.unbind();
state.set(new State("", null, backable.get(), false, true, titleBarTransparent.get(), leftPaneWidth.get())); state.set(new State("", null, backable.get(), false, true, leftPaneWidth.get()));
} }
if (to instanceof Region) { if (to instanceof Region) {
@ -121,16 +120,4 @@ public abstract class DecoratorTransitionPage extends Control implements Decorat
public void setLeftPaneWidth(double leftPaneWidth) { public void setLeftPaneWidth(double leftPaneWidth) {
this.leftPaneWidth.set(leftPaneWidth); this.leftPaneWidth.set(leftPaneWidth);
} }
public boolean isTitleBarTransparent() {
return titleBarTransparent.get();
}
public BooleanProperty titleBarTransparentProperty() {
return titleBarTransparent;
}
public void setTitleBarTransparent(boolean titleBarTransparent) {
this.titleBarTransparent.set(titleBarTransparent);
}
} }

View File

@ -63,11 +63,10 @@ public class AboutPage extends StackPane {
bangbang93.setSubtitle(i18n("about.thanks_to.bangbang93.statement")); bangbang93.setSubtitle(i18n("about.thanks_to.bangbang93.statement"));
bangbang93.setExternalLink("https://bmclapi2.bangbang93.com/"); bangbang93.setExternalLink("https://bmclapi2.bangbang93.com/");
IconedTwoLineListItem gamerteam = new IconedTwoLineListItem(); IconedTwoLineListItem redLnn = new IconedTwoLineListItem();
gamerteam.setTitle("gamerteam"); redLnn.setTitle("Red_lnn");
gamerteam.setImage(new Image("/assets/img/gamerteam.jpg", 32, 32, false, true)); redLnn.setImage(new Image("/assets/img/red_lnn.jpg", 32, 32, false, true));
gamerteam.setSubtitle(i18n("about.thanks_to.gamerteam.statement")); redLnn.setSubtitle(i18n("about.thanks_to.gamerteam.statement"));
gamerteam.setExternalLink("http://www.zhaisoul.com/");
IconedTwoLineListItem mcbbs = new IconedTwoLineListItem(); IconedTwoLineListItem mcbbs = new IconedTwoLineListItem();
mcbbs.setImage(new Image("/assets/img/chest.png", 32, 32, false, true)); mcbbs.setImage(new Image("/assets/img/chest.png", 32, 32, false, true));
@ -80,14 +79,14 @@ public class AboutPage extends StackPane {
contributors.setTitle(i18n("about.thanks_to.contributors")); contributors.setTitle(i18n("about.thanks_to.contributors"));
contributors.setSubtitle(i18n("about.thanks_to.contributors.statement")); contributors.setSubtitle(i18n("about.thanks_to.contributors.statement"));
contributors.setExternalLink("https://github.com/huanghongxun/HMCL/graphs/contributors"); contributors.setExternalLink("https://github.com/huanghongxun/HMCL/graphs/contributors");
contributors.setExternalLink("https://hmcl.huangyuhui.net/api/redirect/sponsor");
IconedTwoLineListItem users = new IconedTwoLineListItem(); IconedTwoLineListItem users = new IconedTwoLineListItem();
users.setImage(new Image("/assets/img/craft_table.png", 32, 32, false, true)); users.setImage(new Image("/assets/img/craft_table.png", 32, 32, false, true));
users.setTitle(i18n("about.thanks_to.users")); users.setTitle(i18n("about.thanks_to.users"));
users.setSubtitle(i18n("about.thanks_to.users.statement")); users.setSubtitle(i18n("about.thanks_to.users.statement"));
users.setExternalLink("https://hmcl.huangyuhui.net/api/redirect/sponsor");
thanks.getContent().setAll(yushijinhun, bangbang93, gamerteam, mcbbs, users, contributors); thanks.getContent().setAll(yushijinhun, bangbang93, mcbbs, redLnn, users, contributors);
} }
ComponentList dep = new ComponentList(); ComponentList dep = new ComponentList();

View File

@ -33,7 +33,7 @@ import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class LauncherSettingsPage extends BorderPane implements DecoratorPage { public class LauncherSettingsPage extends BorderPane implements DecoratorPage {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(new State(i18n("settings.launcher"), null, true, false, true, false, 200)); private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(new State(i18n("settings.launcher"), null, true, false, true, 200));
private final TabHeader tab; private final TabHeader tab;
private final TabHeader.Tab<SettingsPage> settingsTab = new TabHeader.Tab<>("settingsPage"); private final TabHeader.Tab<SettingsPage> settingsTab = new TabHeader.Tab<>("settingsPage");
private final TabHeader.Tab<HelpPage> helpTab = new TabHeader.Tab<>("helpPage"); private final TabHeader.Tab<HelpPage> helpTab = new TabHeader.Tab<>("helpPage");

View File

@ -30,6 +30,8 @@ import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
@ -59,7 +61,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.SINE;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class MainPage extends StackPane implements DecoratorPage { public final class MainPage extends StackPane implements DecoratorPage {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle("HMCL " + Metadata.VERSION)); private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>();
private final PopupMenu menu = new PopupMenu(); private final PopupMenu menu = new PopupMenu();
private final JFXPopup popup = new JFXPopup(menu); private final JFXPopup popup = new JFXPopup(menu);
@ -75,6 +77,19 @@ public final class MainPage extends StackPane implements DecoratorPage {
private JFXButton menuButton; private JFXButton menuButton;
{ {
HBox titleNode = new HBox(8);
titleNode.setPadding(new Insets(0, 0, 0, 2));
titleNode.setAlignment(Pos.CENTER_LEFT);
ImageView titleIcon = new ImageView();
titleIcon.setImage(new Image("/assets/img/icon.png", 20, 20, false, false));
Label titleLabel = new Label(Metadata.TITLE);
titleLabel.getStyleClass().add("jfx-decorator-title");
titleNode.getChildren().setAll(titleIcon, titleLabel);
state.setValue(State.fromTitleNode(titleNode));
setPadding(new Insets(20)); setPadding(new Insets(20));
updatePane = new StackPane(); updatePane = new StackPane();

View File

@ -93,7 +93,6 @@ public class RootPage extends DecoratorTabPage {
@Override @Override
protected void onNavigated(Node to) { protected void onNavigated(Node to) {
backableProperty().set(!(to instanceof MainPage)); backableProperty().set(!(to instanceof MainPage));
setTitleBarTransparent(to instanceof MainPage);
super.onNavigated(to); super.onNavigated(to);
} }

View File

@ -244,7 +244,7 @@ public class GameListPage extends ListPageBase<GameListItem> implements Decorato
public GameListSkin() { public GameListSkin() {
super(GameList.this); super(GameList.this);
state.set(new State(i18n("version.manage"), null, true, false, true, false, 200)); state.set(new State(i18n("version.manage"), null, true, false, true, 200));
} }
@Override @Override

View File

@ -388,7 +388,7 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
} }
control.state.bind(Bindings.createObjectBinding(() -> control.state.bind(Bindings.createObjectBinding(() ->
new State(i18n("version.manage.manage.title", getSkinnable().getVersion()), null, true, false, true, false, 200), new State(i18n("version.manage.manage.title", getSkinnable().getVersion()), null, true, false, true, 200),
getSkinnable().version)); getSkinnable().version));
//control.transitionPane.getStyleClass().add("gray-background"); //control.transitionPane.getStyleClass().add("gray-background");

View File

@ -398,7 +398,7 @@
-fx-font-weight: BOLD; -fx-font-weight: BOLD;
} }
.jfx-tool-bar .background { .jfx-tool-bar.background {
-fx-background-color: -fx-base-color; -fx-background-color: -fx-base-color;
} }
@ -1140,12 +1140,12 @@
.window { .window {
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-padding: 16; -fx-padding: 8;
} }
.body { .body {
-fx-border-radius: 5; -fx-border-radius: 5;
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.4), 20, 0.3, 0.0, 0.0); -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.4), 10, 0.3, 0.0, 0.0);
} }
.debug-border { .debug-border {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -29,7 +29,7 @@ about.legal=Legal Acknowledgement
about.thanks_to=Thanks to about.thanks_to=Thanks to
about.thanks_to.bangbang93.statement=BMCLAPI about.thanks_to.bangbang93.statement=BMCLAPI
about.thanks_to.contributors=All contributors who participated in this project via issues, pull requests, etc. about.thanks_to.contributors=All contributors who participated in this project via issues, pull requests, etc.
about.thanks_to.gamerteam.statement=gamerteam (Default background image) about.thanks_to.gamerteam.statement=Default background image
about.thanks_to.mcbbs=MCBBS about.thanks_to.mcbbs=MCBBS
about.thanks_to.mcbbs.statement=Provide MCBBS download source about.thanks_to.mcbbs.statement=Provide MCBBS download source
about.thanks_to.users=Members of HMCL User Group about.thanks_to.users=Members of HMCL User Group

View File

@ -30,7 +30,7 @@ about.thanks_to=鸣谢
about.thanks_to.bangbang93.statement=提供 BMCLAPI 下载源,请赞助支持 BMCLAPI about.thanks_to.bangbang93.statement=提供 BMCLAPI 下载源,请赞助支持 BMCLAPI
about.thanks_to.contributors=所有通过 Issues、Pull Requests 等方式参与本项目的贡献者 about.thanks_to.contributors=所有通过 Issues、Pull Requests 等方式参与本项目的贡献者
about.thanks_to.contributors.statement=没有开源社区的支持Hello Minecraft! Launcher 无法走到今天 about.thanks_to.contributors.statement=没有开源社区的支持Hello Minecraft! Launcher 无法走到今天
about.thanks_to.gamerteam.statement=提供默认背景图与 HMCL 官方网站 CDN about.thanks_to.gamerteam.statement=提供默认背景图
about.thanks_to.mcbbs=MCBBS 我的世界中文论坛 about.thanks_to.mcbbs=MCBBS 我的世界中文论坛
about.thanks_to.mcbbs.statement=提供 MCBBS 下载源 about.thanks_to.mcbbs.statement=提供 MCBBS 下载源
about.thanks_to.users=HMCL 用户群成员 about.thanks_to.users=HMCL 用户群成员