Skip to content

[GSoC] LateNightQML: Deck Layouts - #17014

Open
xARSENICx wants to merge 1 commit into
mixxxdj:mainfrom
xARSENICx:LateNightQML/layouts
Open

[GSoC] LateNightQML: Deck Layouts #17014
xARSENICx wants to merge 1 commit into
mixxxdj:mainfrom
xARSENICx:LateNightQML/layouts

Conversation

@xARSENICx

@xARSENICx xARSENICx commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This PR continues the LateNightQML skin work by completing the responsive deck layouts with feature and visual parity for the Classic and PaleMoon color schemes.

Testing the Experimental Skin

Since this is an experimental milestone, first run Mixxx with the developer flag:

./build/mixxx --developer

Once Mixxx is open, switch to:

Preferences -> Interface -> LateNight QML (Experimental)

You can dynamically toggle between the Classic and PaleMoon color schemes under preferences.

Previews

Classic

  • Full:
    image
  • Compact:
    image
  • Mini
    image

PaleMoon

  • Full:
    image
  • Compact:
    image
  • Mini:
    image

Scope of Changes

New Styling

The menus now get resized with available options according to the selected state:

  • Full
    image
  • Compact
    image
  • Mini
    image

Implemented in this PR

  • Adds Mini, Compact, and Full deck layouts.
  • Centralizes responsive layout state across mixer visibility, Big Library mode, deck count, and saved deck size.
  • Integrates the layouts with the responsive library and mixer arrangement.
  • Preserves a minimum usable deck height when resizing the library splitter.
  • Integrates deck transport, cue, loop, beatjump, key, sync, rate, vinyl, and FX controls according to the Deck Layout

Tracking

GSoC: LateNightQML PR-14

@xARSENICx

Copy link
Copy Markdown
Contributor Author

There are some stray changes in Toolbar and Waveforms solving visual regression which were overlooked. Since, the scope of the changes are very small and should not cause a burden to review, I did not open a separate PR for them.

@JoergAtGithub JoergAtGithub added the LateNight QML Affects the QML implementation of the LateNight skin label Sep 6, 2026

@JoergAtGithub JoergAtGithub left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is far to big to review! Furthermore it contains several unrelated changes.

Please move the commits for:

  • Waverform changes
  • Toolbar indicators
  • Key indicators

each into an seperate PR!

@xARSENICx

Copy link
Copy Markdown
Contributor Author

Will do so.

@xARSENICx
xARSENICx force-pushed the LateNightQML/layouts branch from 83781ee to 206e643 Compare September 7, 2026 15:18
Comment on lines +13 to +27
// The derived controls choose the slot size, but the two source toggles
// remain the authority for whether a slot exists at all. This prevents a
// stale derived value from leaving an empty layout gap.
readonly property bool showSpinnyOrCover: (showSpinniesProxy.value > 0 || showCoverArtProxy.value > 0)
&& (!showSpinnyOrCoverProxy.initialized || showSpinnyOrCoverProxy.value > 0)
readonly property bool showSmallSpinnyOrCover: root.showSpinnyOrCover
&& (!showSmallSpinnyOrCoverProxy.initialized
? selectBigSpinnyProxy.value <= 0
: showSmallSpinnyOrCoverProxy.value > 0)
readonly property bool showBigSpinnyOrCover: root.showSpinnyOrCover
&& (!showBigSpinnyOrCoverProxy.initialized
? selectBigSpinnyProxy.value > 0
: showBigSpinnyOrCoverProxy.value > 0)
readonly property bool showCover: root.showSpinnyOrCover && showCoverArtProxy.value > 0
readonly property bool showSpinny: root.showSpinnyOrCover && showSpinniesProxy.value > 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    // The derived controls choose the slot size, but the two source toggles
    // remain the authority for whether a slot exists at all. This prevents a
    // stale derived value from leaving an empty layout gap.
    readonly property bool showSpinnyOrCover: (showSpinniesProxy.value > 0 || showCoverArtProxy.value > 0)
            && (!showSpinnyOrCoverProxy.initialized || showSpinnyOrCoverProxy.value > 0)
    readonly property bool showSmallSpinnyOrCover: root.showSpinnyOrCover
            && (!showSmallSpinnyOrCoverProxy.initialized
                    ? selectBigSpinnyProxy.value <= 0
                    : showSmallSpinnyOrCoverProxy.value > 0)
    readonly property bool showBigSpinnyOrCover: root.showSpinnyOrCover
            && (!showBigSpinnyOrCoverProxy.initialized
                    ? selectBigSpinnyProxy.value > 0
                    : showBigSpinnyOrCoverProxy.value > 0)
    readonly property bool showCover: root.showSpinnyOrCover && showCoverArtProxy.value > 0
    readonly property bool showSpinny: root.showSpinnyOrCover && showSpinniesProxy.value > 0

Wouldn't it make sense to move this code into a singleton and reuse it in CompactDeck.qml, and FullDeck.qml.
It's always good to have a single point where the decision is taken.

Comment on lines +17 to +20
function formatTime(seconds) {
const value = Math.max(0, Math.floor(seconds));
return Math.floor(value / 60).toString() + ":" + (value % 60).toString().padStart(2, "0");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to move this to DurationFormatter.qml and share it?

@@ -0,0 +1,94 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import QtQuick
pragma ComponentBehavior: Bound
import QtQuick

@@ -1 +1 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pragma ComponentBehavior: Bound
import QtQuick

@@ -0,0 +1,223 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import QtQuick
pragma ComponentBehavior: Bound
import QtQuick

@@ -0,0 +1,161 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import QtQuick
pragma ComponentBehavior: Bound
import QtQuick

@@ -1 +1 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pragma ComponentBehavior: Bound
import QtQuick

@@ -0,0 +1,176 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import QtQuick
pragma ComponentBehavior: Bound
import QtQuick

@@ -0,0 +1,52 @@
import QtQuick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import QtQuick
pragma ComponentBehavior: Bound
import QtQuick

visible: false
readonly property bool ready: true

// All controls used by the layout are declared here before Toolbar and

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we had the Skin controls declared already?

@github-project-automation github-project-automation Bot moved this to In progress in QML GUI Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build code quality LateNight QML Affects the QML implementation of the LateNight skin qml skins waveform

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

2 participants