mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-14 09:42:10 -04:00
Add adaptive media width setting. (#2165)
This commit is contained in:
@@ -301,6 +301,7 @@ Singleton {
|
|||||||
property var workspaceNameIcons: ({})
|
property var workspaceNameIcons: ({})
|
||||||
property bool waveProgressEnabled: true
|
property bool waveProgressEnabled: true
|
||||||
property bool scrollTitleEnabled: true
|
property bool scrollTitleEnabled: true
|
||||||
|
property bool mediaAdaptiveWidthEnabled: true
|
||||||
property bool audioVisualizerEnabled: true
|
property bool audioVisualizerEnabled: true
|
||||||
property string audioScrollMode: "volume"
|
property string audioScrollMode: "volume"
|
||||||
property int audioWheelScrollAmount: 5
|
property int audioWheelScrollAmount: 5
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ var SPEC = {
|
|||||||
workspaceNameIcons: { def: {} },
|
workspaceNameIcons: { def: {} },
|
||||||
waveProgressEnabled: { def: true },
|
waveProgressEnabled: { def: true },
|
||||||
scrollTitleEnabled: { def: true },
|
scrollTitleEnabled: { def: true },
|
||||||
|
mediaAdaptiveWidthEnabled: { def: true },
|
||||||
audioVisualizerEnabled: { def: true },
|
audioVisualizerEnabled: { def: true },
|
||||||
audioScrollMode: { def: "volume" },
|
audioScrollMode: { def: "volume" },
|
||||||
audioWheelScrollAmount: { def: 5 },
|
audioWheelScrollAmount: { def: 5 },
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ BasePill {
|
|||||||
readonly property bool usePlayerVolume: activePlayer && activePlayer.volumeSupported && !__isChromeBrowser
|
readonly property bool usePlayerVolume: activePlayer && activePlayer.volumeSupported && !__isChromeBrowser
|
||||||
property bool compactMode: false
|
property bool compactMode: false
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
readonly property int textWidth: {
|
readonly property bool adaptiveWidthEnabled: SettingsData.mediaAdaptiveWidthEnabled
|
||||||
|
readonly property int maxTextWidth: {
|
||||||
const size = widgetData?.mediaSize !== undefined ? widgetData.mediaSize : SettingsData.mediaSize;
|
const size = widgetData?.mediaSize !== undefined ? widgetData.mediaSize : SettingsData.mediaSize;
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -36,10 +37,7 @@ BasePill {
|
|||||||
if (isVerticalOrientation) {
|
if (isVerticalOrientation) {
|
||||||
return widgetThickness - horizontalPadding * 2;
|
return widgetThickness - horizontalPadding * 2;
|
||||||
}
|
}
|
||||||
const controlsWidth = 20 + Theme.spacingXS + 24 + Theme.spacingXS + 20;
|
return 0;
|
||||||
const audioVizWidth = 20;
|
|
||||||
const contentWidth = audioVizWidth + Theme.spacingXS + controlsWidth;
|
|
||||||
return contentWidth + (textWidth > 0 ? textWidth + Theme.spacingXS : 0);
|
|
||||||
}
|
}
|
||||||
readonly property int currentContentHeight: {
|
readonly property int currentContentHeight: {
|
||||||
if (!isVerticalOrientation) {
|
if (!isVerticalOrientation) {
|
||||||
@@ -119,7 +117,28 @@ BasePill {
|
|||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
Item {
|
Item {
|
||||||
implicitWidth: root.playerAvailable ? root.currentContentWidth : 0
|
id: contentRoot
|
||||||
|
readonly property real measuredTextWidth: {
|
||||||
|
if (!root.playerAvailable || root.maxTextWidth <= 0 || !textContainer.visible)
|
||||||
|
return 0;
|
||||||
|
// Preserve the fixed-width text slot even if metadata is briefly empty.
|
||||||
|
if (!root.adaptiveWidthEnabled)
|
||||||
|
return root.maxTextWidth;
|
||||||
|
if (textContainer.displayText.length === 0)
|
||||||
|
return 0;
|
||||||
|
const rawWidth = mediaText.contentWidth;
|
||||||
|
if (!isFinite(rawWidth) || rawWidth <= 0)
|
||||||
|
return 0;
|
||||||
|
return Math.min(root.maxTextWidth, Math.ceil(rawWidth));
|
||||||
|
}
|
||||||
|
readonly property int horizontalContentWidth: {
|
||||||
|
const controlsWidth = 20 + Theme.spacingXS + 24 + Theme.spacingXS + 20;
|
||||||
|
const audioVizWidth = 20;
|
||||||
|
const baseWidth = audioVizWidth + Theme.spacingXS + controlsWidth;
|
||||||
|
return baseWidth + (measuredTextWidth > 0 ? measuredTextWidth + Theme.spacingXS : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: root.playerAvailable ? (root.isVerticalOrientation ? root.currentContentWidth : horizontalContentWidth) : 0
|
||||||
implicitHeight: root.playerAvailable ? root.currentContentHeight : 0
|
implicitHeight: root.playerAvailable ? root.currentContentHeight : 0
|
||||||
opacity: root.playerAvailable ? 1 : 0
|
opacity: root.playerAvailable ? 1 : 0
|
||||||
|
|
||||||
@@ -132,8 +151,9 @@ BasePill {
|
|||||||
|
|
||||||
Behavior on implicitWidth {
|
Behavior on implicitWidth {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +289,7 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: textWidth
|
width: contentRoot.measuredTextWidth
|
||||||
height: root.widgetThickness
|
height: root.widgetThickness
|
||||||
visible: {
|
visible: {
|
||||||
const size = widgetData?.mediaSize !== undefined ? widgetData.mediaSize : SettingsData.mediaSize;
|
const size = widgetData?.mediaSize !== undefined ? widgetData.mediaSize : SettingsData.mediaSize;
|
||||||
@@ -278,50 +298,95 @@ BasePill {
|
|||||||
clip: true
|
clip: true
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
StyledText {
|
Behavior on width {
|
||||||
id: mediaText
|
NumberAnimation {
|
||||||
property bool needsScrolling: implicitWidth > textContainer.width && SettingsData.scrollTitleEnabled
|
duration: Theme.mediumDuration
|
||||||
property real scrollOffset: 0
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: textContainer.displayText
|
|
||||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
|
||||||
color: Theme.widgetTextColor
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
x: needsScrolling ? -scrollOffset : 0
|
|
||||||
onTextChanged: {
|
|
||||||
scrollOffset = 0;
|
|
||||||
scrollAnimation.restart();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SequentialAnimation {
|
Item {
|
||||||
id: scrollAnimation
|
id: textClip
|
||||||
running: mediaText.needsScrolling && textContainer.visible
|
anchors.fill: parent
|
||||||
loops: Animation.Infinite
|
clip: true
|
||||||
|
|
||||||
PauseAnimation {
|
StyledText {
|
||||||
duration: 2000
|
id: mediaText
|
||||||
|
property bool needsScrolling: implicitWidth > textContainer.width && SettingsData.scrollTitleEnabled
|
||||||
|
property real scrollOffset: 0
|
||||||
|
property real textShift: 0
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: textContainer.displayText
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
x: (needsScrolling ? -scrollOffset : 0) + textShift
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
scrollOffset = 0;
|
||||||
|
textShift = 0;
|
||||||
|
scrollAnimation.restart();
|
||||||
|
textChangeAnimation.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
SequentialAnimation {
|
||||||
target: mediaText
|
id: scrollAnimation
|
||||||
property: "scrollOffset"
|
running: mediaText.needsScrolling && textContainer.visible
|
||||||
from: 0
|
loops: Animation.Infinite
|
||||||
to: mediaText.implicitWidth - textContainer.width + 5
|
|
||||||
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
PauseAnimation {
|
||||||
easing.type: Easing.Linear
|
duration: 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: mediaText
|
||||||
|
property: "scrollOffset"
|
||||||
|
from: 0
|
||||||
|
to: mediaText.implicitWidth - textContainer.width + 5
|
||||||
|
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
}
|
||||||
|
|
||||||
|
PauseAnimation {
|
||||||
|
duration: 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: mediaText
|
||||||
|
property: "scrollOffset"
|
||||||
|
to: 0
|
||||||
|
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PauseAnimation {
|
SequentialAnimation {
|
||||||
duration: 2000
|
id: textChangeAnimation
|
||||||
}
|
|
||||||
|
|
||||||
NumberAnimation {
|
ParallelAnimation {
|
||||||
target: mediaText
|
NumberAnimation {
|
||||||
property: "scrollOffset"
|
target: mediaText
|
||||||
to: 0
|
property: "opacity"
|
||||||
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
from: 0.7
|
||||||
easing.type: Easing.Linear
|
to: 1
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: mediaText
|
||||||
|
property: "textShift"
|
||||||
|
from: 4
|
||||||
|
to: 0
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,13 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("audioVisualizerEnabled", checked)
|
onToggled: checked => SettingsData.set("audioVisualizerEnabled", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
text: I18n.tr("Adaptive Media Width")
|
||||||
|
description: I18n.tr("Shrink the media widget to fit shorter song titles while still respecting the configured maximum size")
|
||||||
|
checked: SettingsData.mediaAdaptiveWidthEnabled
|
||||||
|
onToggled: checked => SettingsData.set("mediaAdaptiveWidthEnabled", checked)
|
||||||
|
}
|
||||||
|
|
||||||
SettingsDropdownRow {
|
SettingsDropdownRow {
|
||||||
property var scrollOptsInternal: ["volume", "song", "nothing"]
|
property var scrollOptsInternal: ["volume", "song", "nothing"]
|
||||||
property var scrollOptsDisplay: [I18n.tr("Change Volume", "media scroll wheel option"), I18n.tr("Change Song", "media scroll wheel option"), I18n.tr("Nothing", "media scroll wheel option")]
|
property var scrollOptsDisplay: [I18n.tr("Change Volume", "media scroll wheel option"), I18n.tr("Change Song", "media scroll wheel option"), I18n.tr("Nothing", "media scroll wheel option")]
|
||||||
|
|||||||
Reference in New Issue
Block a user