Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f848fa9
Merge TabControl into TabHeader
Glavo Oct 27, 2026
626ae08
Refactor TabHeaderSelectionModel to improve tab selection logic and r…
Glavo Oct 27, 2026
2d541cc
Simplify TabHeader skin layout and selection animation
Glavo Oct 27, 2026
c3fe934
Extract TabItem from TabHeader into a top-level class
Glavo Oct 27, 2026
7ac252b
Merge HeaderContainer into TabHeaderSkin
Glavo Oct 27, 2026
e23b959
Refactor TabItem initialization to remove unnecessary identifiers
Glavo Oct 27, 2026
7b2bef5
Refactor DownloadPage to improve tab initialization and structure
Glavo Oct 27, 2026
570e520
Refactor GameInstancePage and WorldManagePage to initialize TabItems …
Glavo Oct 27, 2026
cdb63e5
Refactor TabHeader to simplify onPageShown and onPageHidden methods
Glavo Oct 27, 2026
0071329
Refactor TabHeader to replace TabHeaderContainer with TabHeaderView f…
Glavo Oct 27, 2026
477d862
Refactor TabHeaderView to enhance tab representation and simplify sel…
Glavo Oct 27, 2026
c1ce879
Refactor TabHeader to initialize side property lazily and improve pro…
Glavo Oct 27, 2026
018c1c6
Refactor TabHeader to simplify getItemCount method by removing unnece…
Glavo Oct 27, 2026
26593e1
Merge remote-tracking branch 'upstream/main' into tab-header
Glavo Oct 27, 2026
0059efb
Separate tab presentation from selection and content control
Glavo Oct 27, 2026
f42cd33
Refactor CreateAccountPane to use IdentityHashMap for tab-to-factory …
Glavo Oct 27, 2026
d1fbd71
Centralize tab selection in TabController and remove per-tab selectio…
Glavo Oct 27, 2026
22a45c0
Simplify TabController and TabHeader constructors by removing nullabl…
Glavo Oct 27, 2026
53df841
Refactor TabController to replace ReadOnlyObjectWrapper with SimpleOb…
Glavo Oct 27, 2026
2ea9eaf
Refactor LauncherSettingsPage and TerracottaPage to initialize TabIte…
Glavo Oct 27, 2026
e9e6967
Refactor TabItem to simplify property management and lazy initialization
Glavo Oct 27, 2026
fe1685b
Rename select method to selectTab for consistency across tab management
Glavo Oct 27, 2026
f576ecf
Update TabHeader to access controller's tab list directly for improve…
Glavo Oct 27, 2026
d391cbd
Avoid initializing unvisited world tabs during refresh
Glavo Oct 27, 2026
5288562
Avoid initializing unvisited tabs during selection and lifecycle call…
Glavo Oct 27, 2026
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 @@ -133,27 +133,33 @@ public CreateAccountPane(AccountFactory<?> factory) {
}

if (showMethodSwitcher) {
TabControl.Tab<?>[] tabs = new TabControl.Tab[Accounts.FACTORIES.size()];
TabControl.Tab<?> selected = null;
TabItem<?>[] tabs = new TabItem<?>[Accounts.FACTORIES.size()];
var tabToFactory = new IdentityHashMap<TabItem<?>, AccountFactory<?>>();

@Nullable TabItem<?> selected = null;
for (int i = 0; i < tabs.length; i++) {
AccountFactory<?> f = Accounts.FACTORIES.get(i);
tabs[i] = new TabControl.Tab<>(Accounts.getLoginType(f), Accounts.getLocalizedLoginTypeName(f));
tabs[i].setUserData(f);
TabItem<Node> tab = new TabItem<>();
tabs[i] = tab;

tab.setText(Accounts.getLocalizedLoginTypeName(f));
tabToFactory.put(tab, f);
if (factory == f) {
selected = tabs[i];
selected = tab;
}
}

TabHeader tabHeader = new TabHeader(tabs);
tabHeader.getStyleClass().add("add-account-tab-header");
tabHeader.setMinWidth(USE_PREF_SIZE);
tabHeader.setMaxWidth(USE_PREF_SIZE);
tabHeader.getSelectionModel().select(selected);
onChange(tabHeader.getSelectionModel().selectedItemProperty(),
if (selected != null)
tabHeader.getController().selectTab(selected);
onChange(tabHeader.getController().selectedTabProperty(),
newItem -> {
if (newItem == null)
return;
AccountFactory<?> newMethod = (AccountFactory<?>) newItem.getUserData();
AccountFactory<?> newMethod = tabToFactory.get(newItem);
settings().preferredLoginTypeProperty().set(Accounts.getLoginType(newMethod));
this.factory = newMethod;
initDetailsPane();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
@NotNullByDefault
public class TransitionPane extends StackPane {

/// The requested page, or `null` before content is assigned.
/// The requested page, or `null` when content is absent.
private @Nullable Node currentNode;

/// The pending or running transition, or `null` when content is settled.
Expand All @@ -44,6 +44,20 @@ public TransitionPane() {
return currentNode;
}

/// Stops any transition and removes displayed and prewarmed content without animation.
/// Resets [#getCurrentNode()] to null. Repeated calls on an empty pane have no effect.
/// Nodes are detached even if settling the transition throws an exception.
public final void clearContent() {
try {
if (activeTransition != null)
activeTransition.stop();
} finally {
disposePreloadPane();
currentNode = null;
getChildren().clear();
}
}

/// Attaches unowned content for hidden CSS and layout prewarming during scene pulses.
/// Replaces any previous candidate without changing the current content. The hidden
/// container uses a snapshot of this pane's content-area size and does not affect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.SVGContainer;
import org.jackhuang.hmcl.ui.animation.Motion;
import org.jetbrains.annotations.Nullable;

import java.util.function.Consumer;

Expand Down Expand Up @@ -77,18 +78,25 @@ public AdvancedListBox addNavigationDrawerItem(String title, SVG leftGraphic, Ru
return add(item);
}

public AdvancedListBox addNavigationDrawerTab(TabHeader tabHeader, TabControl.Tab<?> tab, String title, SVG leftGraphic) {
/// Adds an item that activates the tab through the controller and tracks its selection state.
///
/// @param leftGraphic the item icon, or null for no icon
/// @return this list box
public AdvancedListBox addNavigationDrawerTab(TabController controller, TabItem<?> tab, String title, @Nullable SVG leftGraphic) {
AdvancedListItem item = createNavigationDrawerItem(title, leftGraphic);
item.activeProperty().bind(tabHeader.getSelectionModel().selectedItemProperty().isEqualTo(tab));
item.setOnAction(e -> tabHeader.select(tab));
item.activeProperty().bind(controller.selectedTabProperty().isEqualTo(tab));
item.setOnAction(e -> controller.selectTab(tab));
return add(item);
}

public AdvancedListBox addNavigationDrawerTab(TabHeader tabHeader, TabControl.Tab<?> tab, String title,
/// Adds an item that activates the tab through the controller and switches icons with its selection state.
///
/// @return this list box
public AdvancedListBox addNavigationDrawerTab(TabController controller, TabItem<?> tab, String title,
SVG unselectedGraphic, SVG selectedGraphic) {
AdvancedListItem item = createNavigationDrawerItem(title, null);
item.activeProperty().bind(tabHeader.getSelectionModel().selectedItemProperty().isEqualTo(tab));
item.setOnAction(e -> tabHeader.select(tab));
item.activeProperty().bind(controller.selectedTabProperty().isEqualTo(tab));
item.setOnAction(e -> controller.selectTab(tab));

var leftGraphic = new SVGContainer(item.isActive() ? selectedGraphic : unselectedGraphic, AdvancedListItem.LEFT_ICON_SIZE);
leftGraphic.setMouseTransparent(true);
Expand Down
262 changes: 0 additions & 262 deletions HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TabControl.java

This file was deleted.

Loading
Loading