mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(media): tighten MediaMini panel layout for album art and height
This commit is contained in:
@@ -14,7 +14,8 @@ SmartPanel {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
preferredWidth: Math.round((root.isSideBySide ? 480 : 360) * Style.uiScaleRatio)
|
preferredWidth: Math.round((root.isSideBySide ? 480 : 360) * Style.uiScaleRatio)
|
||||||
preferredHeight: Math.round((root.compactMode ? 240 : (root.showAlbumArt ? 560 : 300)) * Style.uiScaleRatio)
|
// Fallback only; SmartPanel uses panelContent.contentPreferredHeight when set.
|
||||||
|
preferredHeight: Math.round((root.compactMode ? 240 : 400) * Style.uiScaleRatio)
|
||||||
|
|
||||||
property var mediaMiniSettings: {
|
property var mediaMiniSettings: {
|
||||||
const widget = BarService.lookupWidget("MediaMini", screen?.name);
|
const widget = BarService.lookupWidget("MediaMini", screen?.name);
|
||||||
@@ -73,9 +74,16 @@ SmartPanel {
|
|||||||
id: playerContent
|
id: playerContent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
readonly property real contentPreferredHeight: (root.compactMode ? 240 : (root.showAlbumArt ? 560 : 300)) * Style.uiScaleRatio
|
// implicitHeight + mainLayout vertical anchors.margins (each Style.marginL).
|
||||||
|
readonly property real contentPreferredHeight: {
|
||||||
// Old loader removed from here
|
const m = mainLayout.implicitHeight + 2 * Style.marginL;
|
||||||
|
const scale = Style.uiScaleRatio;
|
||||||
|
if (root.compactMode)
|
||||||
|
return Math.max(m, 240 * scale);
|
||||||
|
if (!root.showAlbumArt)
|
||||||
|
return Math.max(m, 300 * scale);
|
||||||
|
return Math.max(m, 260 * scale);
|
||||||
|
}
|
||||||
|
|
||||||
property Component visualizerSource: {
|
property Component visualizerSource: {
|
||||||
switch (root.visualizerType) {
|
switch (root.visualizerType) {
|
||||||
@@ -90,7 +98,6 @@ SmartPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -229,10 +236,9 @@ SmartPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adaptive Content Area
|
|
||||||
NBox {
|
NBox {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.preferredHeight: mediaContentGrid.implicitHeight + Style.marginM + Style.marginM
|
||||||
|
|
||||||
// Visualizer background for content area
|
// Visualizer background for content area
|
||||||
Loader {
|
Loader {
|
||||||
@@ -243,7 +249,10 @@ SmartPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
anchors.fill: parent
|
id: mediaContentGrid
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
anchors.leftMargin: root.compactMode ? Style.marginL : Style.marginM
|
anchors.leftMargin: root.compactMode ? Style.marginL : Style.marginM
|
||||||
anchors.rightMargin: root.compactMode ? Style.marginL : Style.marginM
|
anchors.rightMargin: root.compactMode ? Style.marginL : Style.marginM
|
||||||
anchors.topMargin: Style.marginM
|
anchors.topMargin: Style.marginM
|
||||||
@@ -255,21 +264,35 @@ SmartPanel {
|
|||||||
// Album Art (Vertical in normal, Horizontal in compact)
|
// Album Art (Vertical in normal, Horizontal in compact)
|
||||||
Item {
|
Item {
|
||||||
id: albumArtItem
|
id: albumArtItem
|
||||||
Layout.preferredWidth: {
|
readonly property real compactArtSize: Math.round(110 * Style.uiScaleRatio)
|
||||||
if (root.compactMode)
|
readonly property bool artSizeKnown: artSizeProbe.status === Image.Ready && artSizeProbe.sourceSize.width > 0 && artSizeProbe.sourceSize.height > 0
|
||||||
return Math.round(110 * Style.uiScaleRatio);
|
readonly property real artAspectRatio: artSizeKnown ? artSizeProbe.sourceSize.width / artSizeProbe.sourceSize.height : 1
|
||||||
return Math.min(parent.width, parent.height - controlsLayout.implicitHeight - parent.rowSpacing);
|
// Non-compact: height from width÷aspect so grid implicit height does not depend on panel height (no layout loop).
|
||||||
}
|
readonly property real artBoxW: root.compactMode ? compactArtSize : Math.max(parent.width, 1)
|
||||||
Layout.preferredHeight: Layout.preferredWidth
|
readonly property real artBoxH: root.compactMode ? compactArtSize : (artBoxW / Math.max(artAspectRatio, 0.001))
|
||||||
|
readonly property real fitArtW: artBoxW / artBoxH > artAspectRatio ? artBoxH * artAspectRatio : artBoxW
|
||||||
|
readonly property real fitArtH: artBoxW / artBoxH > artAspectRatio ? artBoxH : artBoxW / artAspectRatio
|
||||||
|
|
||||||
|
Layout.preferredWidth: fitArtW
|
||||||
|
Layout.preferredHeight: fitArtH
|
||||||
|
Layout.minimumWidth: fitArtW
|
||||||
|
Layout.maximumWidth: fitArtW
|
||||||
|
Layout.minimumHeight: fitArtH
|
||||||
|
Layout.maximumHeight: fitArtH
|
||||||
Layout.fillWidth: false
|
Layout.fillWidth: false
|
||||||
Layout.fillHeight: false
|
Layout.fillHeight: false
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
visible: root.showAlbumArt
|
visible: root.showAlbumArt
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: artSizeProbe
|
||||||
|
visible: false
|
||||||
|
asynchronous: true
|
||||||
|
source: MediaService.trackArtUrl
|
||||||
|
}
|
||||||
|
|
||||||
NImageRounded {
|
NImageRounded {
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
width: Math.min(parent.width, parent.height)
|
|
||||||
height: width
|
|
||||||
radius: root.compactMode ? Style.radiusM : Style.radiusL
|
radius: root.compactMode ? Style.radiusM : Style.radiusL
|
||||||
imagePath: MediaService.trackArtUrl
|
imagePath: MediaService.trackArtUrl
|
||||||
imageFillMode: Image.PreserveAspectCrop
|
imageFillMode: Image.PreserveAspectCrop
|
||||||
@@ -279,9 +302,7 @@ SmartPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
width: Math.min(parent.width, parent.height)
|
|
||||||
height: width
|
|
||||||
anchors.margins: Style.marginS
|
anchors.margins: Style.marginS
|
||||||
z: 2
|
z: 2
|
||||||
active: !!(root.needsSpectrum && root.showAlbumArt)
|
active: !!(root.needsSpectrum && root.showAlbumArt)
|
||||||
@@ -367,7 +388,7 @@ SmartPanel {
|
|||||||
id: progressWrapper
|
id: progressWrapper
|
||||||
visible: (MediaService.currentPlayer && MediaService.trackLength > 0)
|
visible: (MediaService.currentPlayer && MediaService.trackLength > 0)
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: root.compactMode ? (Style.baseWidgetSize * 0.4) : (Style.baseWidgetSize * 0.5)
|
Layout.preferredHeight: progressColumn.implicitHeight
|
||||||
|
|
||||||
property real localSeekRatio: -1
|
property real localSeekRatio: -1
|
||||||
property real lastSentSeekRatio: -1
|
property real lastSentSeekRatio: -1
|
||||||
@@ -396,55 +417,74 @@ SmartPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSlider {
|
ColumnLayout {
|
||||||
id: progressSlider
|
id: progressColumn
|
||||||
anchors.fill: parent
|
anchors.left: parent.left
|
||||||
from: 0
|
anchors.right: parent.right
|
||||||
to: 1
|
anchors.top: parent.top
|
||||||
stepSize: 0
|
spacing: 2
|
||||||
snapAlways: false
|
|
||||||
enabled: MediaService.trackLength > 0 && MediaService.canSeek
|
|
||||||
heightRatio: 0.4
|
|
||||||
|
|
||||||
value: (!MediaService.isSeeking) ? progressWrapper.progressRatio : (progressWrapper.localSeekRatio >= 0 ? progressWrapper.localSeekRatio : 0)
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: root.compactMode ? (Style.baseWidgetSize * 0.4) : (Style.baseWidgetSize * 0.5)
|
||||||
|
|
||||||
onMoved: {
|
NSlider {
|
||||||
progressWrapper.localSeekRatio = value;
|
id: progressSlider
|
||||||
seekDebounce.restart();
|
anchors.fill: parent
|
||||||
}
|
from: 0
|
||||||
onPressedChanged: {
|
to: 1
|
||||||
if (pressed) {
|
stepSize: 0
|
||||||
MediaService.isSeeking = true;
|
snapAlways: false
|
||||||
progressWrapper.localSeekRatio = value;
|
enabled: MediaService.trackLength > 0 && MediaService.canSeek
|
||||||
MediaService.seekByRatio(value);
|
heightRatio: 0.4
|
||||||
progressWrapper.lastSentSeekRatio = value;
|
|
||||||
} else {
|
value: (!MediaService.isSeeking) ? progressWrapper.progressRatio : (progressWrapper.localSeekRatio >= 0 ? progressWrapper.localSeekRatio : 0)
|
||||||
seekDebounce.stop();
|
|
||||||
MediaService.seekByRatio(value);
|
onMoved: {
|
||||||
MediaService.isSeeking = false;
|
progressWrapper.localSeekRatio = value;
|
||||||
progressWrapper.localSeekRatio = -1;
|
seekDebounce.restart();
|
||||||
progressWrapper.lastSentSeekRatio = -1;
|
}
|
||||||
|
onPressedChanged: {
|
||||||
|
if (pressed) {
|
||||||
|
MediaService.isSeeking = true;
|
||||||
|
progressWrapper.localSeekRatio = value;
|
||||||
|
MediaService.seekByRatio(value);
|
||||||
|
progressWrapper.lastSentSeekRatio = value;
|
||||||
|
} else {
|
||||||
|
seekDebounce.stop();
|
||||||
|
MediaService.seekByRatio(value);
|
||||||
|
MediaService.isSeeking = false;
|
||||||
|
progressWrapper.localSeekRatio = -1;
|
||||||
|
progressWrapper.lastSentSeekRatio = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
RowLayout {
|
||||||
anchors.left: parent.left
|
Layout.fillWidth: true
|
||||||
anchors.top: parent.bottom
|
spacing: 0
|
||||||
anchors.topMargin: 2 // Small gap for side-by-side mode
|
|
||||||
text: MediaService.positionString || "0:00"
|
NText {
|
||||||
pointSize: Style.fontSizeXS
|
text: MediaService.positionString || "0:00"
|
||||||
color: Color.mOnSurfaceVariant
|
pointSize: Style.fontSizeXS
|
||||||
visible: parent.visible
|
color: Color.mOnSurfaceVariant
|
||||||
}
|
visible: progressWrapper.visible
|
||||||
NText {
|
}
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.bottom
|
Item {
|
||||||
anchors.topMargin: 2
|
Layout.fillWidth: true
|
||||||
text: MediaService.lengthString || "0:00"
|
Layout.minimumWidth: 0
|
||||||
pointSize: Style.fontSizeXS
|
}
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
visible: parent.visible
|
NText {
|
||||||
|
text: MediaService.lengthString || "0:00"
|
||||||
|
pointSize: Style.fontSizeXS
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
visible: progressWrapper.visible
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user