Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,16 @@ public BooleanProperty windowTransparentProperty() {
return windowTransparent;
}

/// The position of the launcher navigation sidebar drawer.
@SerializedName("sidebarPosition")
private final ObjectProperty<SidebarPosition> sidebarPosition =
new RawPreservingObjectProperty<>(SidebarPosition.LEFT);

/// Returns the sidebar position property.
public ObjectProperty<SidebarPosition> sidebarPositionProperty() {
return sidebarPosition;
}

// Background source

/// The launcher background source type.
Expand Down
42 changes: 42 additions & 0 deletions HMCL/src/main/java/org/jackhuang/hmcl/setting/SidebarPosition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2026 huangyuhui <huanghongxun2008@126.com> and contributors
*
* 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 <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.setting;

import org.jetbrains.annotations.NotNullByDefault;

/// Represents the placement position of the launcher navigation sidebar drawer.
@NotNullByDefault
public enum SidebarPosition {

/// Sidebar positioned on the left side of the window (default).
LEFT("left"),

/// Sidebar positioned on the right side of the window.
RIGHT("right");

private final String name;

SidebarPosition(String name) {
this.name = name;
}

/// Returns the internal string name of this position.
public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import org.jackhuang.hmcl.setting.SidebarPosition;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.Lang;

import static org.jackhuang.hmcl.setting.SettingsManager.settings;

public class DecoratorAnimatedPage extends Control {

Expand Down Expand Up @@ -62,10 +66,20 @@ protected DecoratorAnimatedPageSkin(T control) {
super(control);

BorderPane pane = new BorderPane();
pane.setLeft(control.left);
FXUtils.setLimitWidth(control.left, 200);
pane.setCenter(control.center);
getChildren().setAll(pane);

FXUtils.onChangeAndOperate(settings().sidebarPositionProperty(), position -> {
SidebarPosition pos = Lang.requireNonNullElse(position, SidebarPosition.LEFT);
if (pos == SidebarPosition.RIGHT) {
pane.setLeft(null);
pane.setRight(control.left);
} else {
pane.setRight(null);
pane.setLeft(control.left);
}
});
}

protected void setLeft(Node... children) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,15 @@ public PersonalizationPage() {
themeAppearanceList.getContent().add(brightnessPane);
}

{
LineSelectButton<SidebarPosition> sidebarPositionPane = new LineSelectButton<>();
sidebarPositionPane.setTitle(i18n("settings.launcher.sidebar_position"));
sidebarPositionPane.setNullSafeConverter(pos -> i18n("settings.launcher.sidebar_position." + pos.getName()));
sidebarPositionPane.setItems(Arrays.asList(SidebarPosition.LEFT, SidebarPosition.RIGHT));
sidebarPositionPane.valueProperty().bindBidirectional(settings().sidebarPositionProperty());
themeAppearanceList.getContent().add(sidebarPositionPane);
}

{
ComponentSublist themeColorSublist = new ComponentSublist();
themeColorSublist.setTitle(i18n("settings.launcher.theme_color"));
Expand Down
20 changes: 16 additions & 4 deletions HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import org.jackhuang.hmcl.setting.Accounts;
import org.jackhuang.hmcl.setting.GameDirectory;
import org.jackhuang.hmcl.setting.GameDirectoryManager;
import org.jackhuang.hmcl.setting.SidebarPosition;
import static org.jackhuang.hmcl.setting.SettingsManager.settings;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.terracotta.TerracottaMetadata;
Expand Down Expand Up @@ -149,7 +151,13 @@ protected Skin(RootPage control) {
// first item in left sidebar
AccountAdvancedListItem accountListItem = new AccountAdvancedListItem();
accountListItem.setOnAction(e -> Controllers.navigate(Controllers.getAccountListPage()));
FXUtils.onSecondaryButtonClicked(accountListItem, () -> AccountListPopupMenu.show(accountListItem, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, accountListItem.getWidth(), 0));
FXUtils.onSecondaryButtonClicked(accountListItem, () -> {
SidebarPosition pos = settings().sidebarPositionProperty().get();
JFXPopup.PopupHPosition hPos = (pos == SidebarPosition.RIGHT)
? JFXPopup.PopupHPosition.RIGHT
: JFXPopup.PopupHPosition.LEFT;
AccountListPopupMenu.show(accountListItem, JFXPopup.PopupVPosition.TOP, hPos, accountListItem.getWidth(), 0);
});
accountListItem.accountProperty().bind(Accounts.selectedAccountProperty());

// second item in left sidebar
Expand Down Expand Up @@ -225,7 +233,7 @@ else if (Platform.SYSTEM_PLATFORM.equals(OperatingSystem.LINUX, Architecture.LOO
}
});

// the left sidebar
// the sidebar
AdvancedListBox sideBar = new AdvancedListBox()
.startCategory(i18n("account").toUpperCase(Locale.ROOT))
.add(accountListItem)
Expand All @@ -241,15 +249,19 @@ else if (Platform.SYSTEM_PLATFORM.equals(OperatingSystem.LINUX, Architecture.LOO
Controllers.navigate(Controllers.getSettingsPage());
});

// the root page, with the sidebar in left, navigator in center.
// the root page, with the sidebar in left or right, navigator in center.
setLeft(sideBar);
setCenter(getSkinnable().getMainPage());
}

public void showGameListPopupMenu(Region gameListItem) {
SidebarPosition pos = settings().sidebarPositionProperty().get();
JFXPopup.PopupHPosition hPos = (pos == SidebarPosition.RIGHT)
? JFXPopup.PopupHPosition.RIGHT
: JFXPopup.PopupHPosition.LEFT;
GameListPopupMenu.show(gameListItem,
JFXPopup.PopupVPosition.TOP,
JFXPopup.PopupHPosition.LEFT,
hPos,
gameListItem.getWidth(),
0,
getSkinnable().getMainPage().getRepository(),
Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,9 @@ settings.launcher.proxy.port=Port
settings.launcher.proxy.socks=SOCKS
settings.launcher.proxy.username=Username
settings.launcher.theme=Theme
settings.launcher.sidebar_position=Sidebar Position
settings.launcher.sidebar_position.left=Left
settings.launcher.sidebar_position.right=Right
settings.launcher.theme_color=Theme Color
settings.launcher.theme_color_style=Color Style
settings.launcher.theme_color_style.content=Content
Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_uk.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,9 @@ settings.launcher.proxy.port=Порт
settings.launcher.proxy.socks=SOCKS
settings.launcher.proxy.username=Ім'я користувача
settings.launcher.theme=Тема
settings.launcher.sidebar_position=Розміщення бічної панелі
settings.launcher.sidebar_position.left=Зліва
settings.launcher.sidebar_position.right=Справа
settings.launcher.theme_color=Колір теми
settings.launcher.theme_color_style=Стиль кольору
settings.launcher.theme_color_style.content=Контент
Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,9 @@ settings.launcher.proxy.port=連線埠
settings.launcher.proxy.socks=SOCKS
settings.launcher.proxy.username=帳戶
settings.launcher.theme=主題色
settings.launcher.sidebar_position=側邊欄位置
settings.launcher.sidebar_position.left=左側
settings.launcher.sidebar_position.right=右側
settings.launcher.theme_color=主題色
settings.launcher.theme_color_style=色彩模式
settings.launcher.theme_color_style.content=內容
Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,9 @@ settings.launcher.proxy.port=端口
settings.launcher.proxy.socks=SOCKS
settings.launcher.proxy.username=账户
settings.launcher.theme=主题
settings.launcher.sidebar_position=侧边栏位置
settings.launcher.sidebar_position.left=左侧
settings.launcher.sidebar_position.right=右侧
settings.launcher.theme_color=主题色
settings.launcher.theme_color_style=色彩模式
settings.launcher.theme_color_style.content=内容
Expand Down