Skip to content

qml: Introduce adaptive sidebar/tab-bar shell driven by size class#690

Open
pseudoramdom wants to merge 2 commits into
bitcoin-core:qt6from
pseudoramdom:sidebar-sizeclass
Open

qml: Introduce adaptive sidebar/tab-bar shell driven by size class#690
pseudoramdom wants to merge 2 commits into
bitcoin-core:qt6from
pseudoramdom:sidebar-sizeclass

Conversation

@pseudoramdom
Copy link
Copy Markdown
Contributor

@pseudoramdom pseudoramdom commented May 11, 2026

Summary

Introduces an adaptive navigation shell - a single declarative tree of tabs that renders as a persistent sidebar at regular widths and a bottom tab bar at compact widths, swapping automatically at runtime based on the window size.

Gated behind the -DENABLE_TABVIEW_SHELL=ON CMake flag

Related to #689

Details

  • SizeClass - a small singleton that turns the live window dimensions into one of two coarse buckets: compact (narrow) and regular (wide).
  • Tab - represents a single navigation destination. Each tab carries a title, an icon
  • TabSection - groups related tabs together. In the sidebar, sections render with a header above their tabs to provide visual grouping
  • TabView - the adaptive shell. It accepts a tree of tabs (and sections of tabs) and decides at runtime whether to render them as a left sidebar or a bottom tab bar based on the window's size class

TabView API at a glance

TabView {
    TabSection {
        title: qsTr("Node")
        Tab { title: "Node";    iconSource: "..."; contentComponent: Component { NodeRunner {} } }
        Tab { title: "Peers";   displayModes: TabView.Sidebar; ... }
        Tab { title: "Network"; displayModes: TabView.Sidebar; ... }
    }
    TabSection {
        title: qsTr("Wallet")
        displayModes: TabView.Sidebar
        model: walletListModel
        delegate: Tab {
            required property string name
            title: name
            onSelected: walletController.setSelectedWallet(name)
            contentComponent: Component { WalletContainer {} }
        }
        Tab { title: "Add Wallet"; iconSource: "..."; actionOnly: true; onTriggered: addWalletPopup.open() }
    }
    Tab { title: qsTr("Settings"); pinToBottom: true; contentComponent: Component { NodeSettings {} } }
}

Screenshots

Sidebar

Screenshot 2026-05-11 at 10 39 11 AM Screenshot 2026-05-11 at 10 39 15 AM Screenshot 2026-05-11 at 10 39 18 AM Screenshot 2026-05-11 at 10 39 25 AM Screenshot 2026-05-11 at 10 39 29 AM

Tabbar

Screenshot 2026-05-11 at 10 39 36 AM Screenshot 2026-05-11 at 10 39 35 AM Screenshot 2026-05-11 at 10 39 32 AM

@pseudoramdom
Copy link
Copy Markdown
Contributor Author

pseudoramdom commented May 11, 2026

Work towards #689

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants