diff --git a/src/contents/config/config.qml b/src/contents/config/config.qml index 11f2f35..405c6bf 100644 --- a/src/contents/config/config.qml +++ b/src/contents/config/config.qml @@ -5,6 +5,6 @@ ConfigModel { ConfigCategory { name: i18n("General") icon: "configure" - source: "ConfigGeneral.qml" + source: "config/General.qml" } } diff --git a/src/contents/ui/Compact.qml b/src/contents/ui/Compact.qml new file mode 100644 index 0000000..f57a42b --- /dev/null +++ b/src/contents/ui/Compact.qml @@ -0,0 +1,317 @@ +import "./components" +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.kirigami as Kirigami +import org.kde.plasma.private.mpris as Mpris + + +Item { + id: compact + readonly property bool horizontal: widget.formFactor === PlasmaCore.Types.Horizontal + readonly property bool fillAvailableSpace: plasmoid.configuration.fillAvailableSpace + readonly property bool colorsFromAlbumCover: plasmoid.configuration.colorsFromAlbumCover + readonly property int backgroundRadius: plasmoid.configuration.panelBackgroundRadius + readonly property string panelIcon: plasmoid.configuration.panelIcon + readonly property int albumCoverRadius: plasmoid.configuration.albumCoverRadius + readonly property bool fallbackToIconWhenArtNotAvailable: plasmoid.configuration.fallbackToIconWhenArtNotAvailable + readonly property bool useAlbumCoverAsPanelIcon: plasmoid.configuration.useAlbumCoverAsPanelIcon + readonly property int songTextMaxWidth: plasmoid.configuration.maxSongWidthInPanel + readonly property int songTextAlignment: plasmoid.configuration.songTextAlignment + readonly property bool splitSongAndArtists: plasmoid.configuration.separateText + readonly property int songTextScrollingBehaviour: plasmoid.configuration.textScrollingBehaviour + readonly property int songTextScrollingSpeed: plasmoid.configuration.textScrollingSpeed + readonly property bool songTextScrollingResetOnPause: plasmoid.configuration.textScrollingResetOnPause + readonly property bool songTextScrollingEnabled: plasmoid.configuration.textScrollingEnabled + readonly property font songTextFont: textFont + readonly property font songTextBoldFont: boldTextFont + readonly property bool showCommands: plasmoid.configuration.commandsInPanel + readonly property real volumeStep: plasmoid.configuration.volumeStep + + property color imageColor: Kirigami.Theme.textColor + property bool imageReady: false + property string backgroundColor: imageReady && colorsFromAlbumCover ? Kirigami.ColorUtils.tintWithAlpha(imageColor, "#000000", 0.5) : "transparent" + property string foregroundColor: imageReady && colorsFromAlbumCover ? Kirigami.ColorUtils.tintWithAlpha(imageColor, contrastColor, .6) : Kirigami.Theme.textColor + property string contrastColor: Kirigami.ColorUtils.brightnessForColor(backgroundColor) === Kirigami.ColorUtils.Dark ? "#ffffff" : "#000000" + + readonly property int widgetThickness: Math.min(height, width) + readonly property int controlsSize: Math.round(widgetThickness * 0.75) + readonly property int lengthMargin: Math.round((widgetThickness - controlsSize)) + + Layout.preferredWidth: grid.implicitWidth + Layout.preferredHeight: grid.implicitHeight + Layout.fillHeight: horizontal || fillAvailableSpace + Layout.fillWidth: !horizontal || fillAvailableSpace + + Behavior on backgroundColor { + ColorAnimation { + duration: Kirigami.Units.longDuration + } + } + + Behavior on foregroundColor { + ColorAnimation { + duration: Kirigami.Units.longDuration + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + widget.expanded = !widget.expanded; + } + } + + MouseAreaWithWheelHandler { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton + propagateComposedEvents: true + property int wheelDelta: 0 + onClicked: (mouse) => { + switch (mouse.button) { + case Qt.MiddleButton: + player.playPause() + break + case Qt.BackButton: + if (player.canGoPrevious) { + player.previous(); + } + break + case Qt.ForwardButton: + if (player.canGoNext) { + player.next(); + } + break + default: + if (mouse.modifiers & Qt.ControlModifier) { + if (player.canRaise) player.raise() + } else { + mouse.accepted = false + } + } + } + onWheelUp: { + player.changeVolume(volumeStep / 100, true); + } + onWheelDown: { + player.changeVolume(-volumeStep / 100, true); + } + z: 999 + } + + Rectangle { + anchors.fill: parent + color: backgroundColor + radius: backgroundRadius + } + + GridLayout { + id: grid + columnSpacing: Kirigami.Units.smallSpacing + rowSpacing: Kirigami.Units.smallSpacing + columns: horizontal ? grid.children.length : 1 + rows: horizontal ? 1 : grid.children.length + anchors.fill: parent + + PanelIcon { + Layout.leftMargin: horizontal ? lengthMargin / 2: 0 + Layout.topMargin: horizontal ? 0 : lengthMargin / 2 + Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter + + size: compact.controlsSize + icon: panelIcon + imageUrl: player.artUrl + imageRadius: albumCoverRadius + fallbackToIconWhenImageNotAvailable: fallbackToIconWhenArtNotAvailable + type: { + if (!useAlbumCoverAsPanelIcon) { + return PanelIcon.Type.Icon; + } + return PanelIcon.Type.Image; + } + onTypeChanged: { + compact.imageReady = type === PanelIcon.Type.Image && imageReady + } + onImageColorChanged: (color) => { + compact.imageColor = color + } + onImageReadyChanged: { + if (type === PanelIcon.Type.Image) + compact.imageReady = imageReady + } + } + + Item { + id: middleSpace + implicitWidth: horizontal ? panelScrollingText.implicitWidth : panelScrollingText.implicitHeight + implicitHeight: horizontal ? panelScrollingText.implicitHeight : panelScrollingText.implicitWidth + Layout.fillHeight: horizontal || fillAvailableSpace + Layout.fillWidth: !horizontal || fillAvailableSpace + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.rightMargin: horizontal ? Kirigami.Units.smallSpacing : 0 + Layout.leftMargin: horizontal ? Kirigami.Units.smallSpacing : 0 + Layout.topMargin: horizontal ? 0 : Kirigami.Units.smallSpacing + Layout.bottomMargin: horizontal ? 0: Kirigami.Units.smallSpacings + readonly property int length: horizontal ? width : height + + ColumnLayout { + id: panelScrollingText + + // The components are anchored before they are rotated. This means that when the widget is placed on a vertical panel + // and the state is `vertical-top` or `vertical-bottom`, the song text may overlap with the PanelIcon or the ToolButtons. + // As a workaround, the component's height is set equal to its width. + height: width + visible: songTextMaxWidth !== 0 + rotation: { + if (horizontal) return 0 + if (widget.location === PlasmaCore.Types.LeftEdge) return -90 + if (widget.location === PlasmaCore.Types.RightEdge) return 90 + } + + state: { + if (songTextAlignment == Qt.AlignCenter || !fillAvailableSpace) { + return 'centered' + } + if (horizontal && songTextAlignment == Qt.AlignLeft) { + return 'horizontal-left' + } + if (horizontal && songTextAlignment == Qt.AlignRight) { + return 'horizontal-right' + } + if (!horizontal && songTextAlignment == Qt.AlignLeft) { + return 'vertical-top' + } + if (!horizontal && songTextAlignment == Qt.AlignRight) { + return 'vertical-bottom' + } + } + + states: [ + State { + name: "centered" + AnchorChanges { + target: panelScrollingText + anchors.horizontalCenter: middleSpace.horizontalCenter + anchors.verticalCenter: middleSpace.verticalCenter + } + }, + State { + name: "horizontal-left" + AnchorChanges { + target: panelScrollingText + anchors.left: middleSpace.left + anchors.verticalCenter: middleSpace.verticalCenter + } + }, + State { + name: "horizontal-right" + AnchorChanges { + target: panelScrollingText + anchors.right: middleSpace.right + anchors.verticalCenter: middleSpace.verticalCenter + } + }, + State { + name: "vertical-top" + AnchorChanges { + target: panelScrollingText + anchors.top: middleSpace.top + anchors.horizontalCenter: middleSpace.horizontalCenter + } + }, + State { + name: "vertical-bottom" + AnchorChanges { + target: panelScrollingText + anchors.bottom: middleSpace.bottom + anchors.horizontalCenter: middleSpace.horizontalCenter + } + } + ] + + ColumnLayout { + id: songAndArtistText + spacing: 0 + anchors.centerIn: parent + + ScrollingText { + visible: splitSongAndArtists + overflowBehaviour: songTextScrollingBehaviour + font: songTextBoldFont + speed: songTextScrollingSpeed + maxWidth: fillAvailableSpace ? middleSpace.length : songTextMaxWidth + text: player.title + scrollingEnabled: songTextScrollingEnabled + scrollResetOnPause: songTextScrollingResetOnPause + textColor: foregroundColor + } + ScrollingText { + overflowBehaviour: songTextScrollingBehaviour + font: songTextFont + speed: songTextScrollingSpeed + maxWidth: fillAvailableSpace ? middleSpace.length : songTextMaxWidth + text: splitSongAndArtists ? player.artists : [player.artists, player.title].filter((x) => x).join(" - ") + scrollingEnabled: songTextScrollingEnabled + scrollResetOnPause: songTextScrollingResetOnPause + visible: text.length !== 0 + textColor: foregroundColor + } + } + } + } + + GridLayout { + Layout.rightMargin: horizontal ? lengthMargin / 2 : 0 + Layout.bottomMargin: horizontal ? 0: lengthMargin / 2 + columns: horizontal ? grid.children.length : 1 + rows: horizontal ? 1 : grid.children.length + Layout.fillHeight: horizontal + Layout.fillWidth: !horizontal + Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter + + PlasmaComponents3.ToolButton { + visible: showCommands + enabled: player.canGoPrevious + icon.name: "media-skip-backward" + icon.color: foregroundColor + implicitWidth: compact.controlsSize + implicitHeight: compact.controlsSize + MouseArea { + anchors.fill: parent + onClicked: player.previous() + } + Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter + } + + PlasmaComponents3.ToolButton { + visible: showCommands + enabled: player.playbackStatus === Mpris.PlaybackStatus.Playing ? player.canPause : player.canPlay + implicitWidth: compact.controlsSize + implicitHeight: compact.controlsSize + icon.name: player.playbackStatus === Mpris.PlaybackStatus.Playing ? "media-playback-pause" : "media-playback-start" + icon.color: foregroundColor + MouseArea { + anchors.fill: parent + onClicked: player.playPause() + } + Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter + } + + PlasmaComponents3.ToolButton { + visible: showCommands + enabled: player.canGoNext + implicitWidth: compact.controlsSize + implicitHeight: compact.controlsSize + icon.name: "media-skip-forward" + icon.color: foregroundColor + MouseArea { + anchors.fill: parent + onClicked: player.next() + } + Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter + } + } + } +} \ No newline at end of file diff --git a/src/contents/ui/Full.qml b/src/contents/ui/Full.qml new file mode 100644 index 0000000..27c3959 --- /dev/null +++ b/src/contents/ui/Full.qml @@ -0,0 +1,167 @@ +import "./components" +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.kirigami as Kirigami +import org.kde.plasma.private.mpris as Mpris + + +Item { + property string albumPlaceholder: plasmoid.configuration.albumPlaceholder + property font songTextFont: textFont + property font songTextBoldFont: boldTextFont + property int songTextScrollingSpeed: plasmoid.configuration.textScrollingSpeed + property real volumeStep: plasmoid.configuration.volumeStep + + Layout.preferredHeight: column.implicitHeight + Layout.preferredWidth: column.implicitWidth + Layout.minimumWidth: column.implicitWidth + Layout.minimumHeight: column.implicitHeight + + ColumnLayout { + id: column + + spacing: 0 + anchors.fill: parent + + Rectangle { + Layout.alignment: Qt.AlignHCenter + Layout.margins: 10 + width: 300 + height: width + + Image { + anchors.fill: parent + source: player.artUrl || albumPlaceholder + fillMode: Image.PreserveAspectFit + MouseArea { + id: coverMouseArea + anchors.fill: parent + cursorShape: player.canRaise ? Qt.PointingHandCursor : Qt.ArrowCursor + onClicked: { + if (player.canRaise) player.raise() + } + hoverEnabled: true + } + PlasmaComponents3.ToolTip { + id: raisePlayerTooltip + anchors.centerIn: parent + text: player.canRaise ? i18n("Bring player to the front") : i18n("This player can't be raised") + visible: coverMouseArea.containsMouse + } + } + } + + TrackPositionSlider { + Layout.leftMargin: 20 + Layout.rightMargin: 20 + songPosition: player.songPosition + songLength: player.songLength + playing: player.playbackStatus === Mpris.PlaybackStatus.Playing + enableChangePosition: player.canSeek + onRequireChangePosition: (position) => { + player.setPosition(position) + } + onRequireUpdatePosition: () => { + player.updatePosition() + } + } + + ScrollingText { + speed: songTextScrollingSpeed + font: songTextBoldFont + maxWidth: 250 + text: player.title + } + + ScrollingText { + speed: songTextScrollingSpeed + font: songTextFont + maxWidth: 250 + text: player.artists + } + + VolumeBar { + Layout.leftMargin: 40 + Layout.rightMargin: 40 + Layout.topMargin: 10 + volume: player.volume + onSetVolume: (vol) => { + player.setVolume(vol) + } + onVolumeUp: { + player.changeVolume(volumeStep / 100, false) + } + onVolumeDown: { + player.changeVolume(-volumeStep / 100, false) + } + } + + Item { + Layout.leftMargin: 20 + Layout.rightMargin: 20 + Layout.bottomMargin: 10 + Layout.fillWidth: true + Layout.preferredHeight: row.implicitHeight + RowLayout { + id: row + + anchors.fill: parent + + CommandIcon { + enabled: player.canChangeShuffle + Layout.alignment: Qt.AlignHCenter + size: Kirigami.Units.iconSizes.medium + source: "media-playlist-shuffle" + onClicked: player.setShuffle(player.shuffle === Mpris.ShuffleStatus.Off ? Mpris.ShuffleStatus.On : Mpris.ShuffleStatus.Off) + active: player.shuffle === Mpris.ShuffleStatus.On + } + + CommandIcon { + enabled: player.canGoPrevious + Layout.alignment: Qt.AlignHCenter + size: Kirigami.Units.iconSizes.medium + source: "media-skip-backward" + onClicked: player.previous() + } + + CommandIcon { + enabled: player.playbackStatus === Mpris.PlaybackStatus.Playing ? player.canPause : player.canPlay + Layout.alignment: Qt.AlignHCenter + size: Kirigami.Units.iconSizes.large + source: player.playbackStatus === Mpris.PlaybackStatus.Playing ? "media-playback-pause" : "media-playback-start" + onClicked: player.playPause() + } + + CommandIcon { + enabled: player.canGoNext + Layout.alignment: Qt.AlignHCenter + size: Kirigami.Units.iconSizes.medium + source: "media-skip-forward" + onClicked: player.next() + } + + CommandIcon { + enabled: player.canChangeLoopStatus + Layout.alignment: Qt.AlignHCenter + size: Kirigami.Units.iconSizes.medium + source: player.loopStatus === Mpris.LoopStatus.Track ? "media-playlist-repeat-song" : "media-playlist-repeat" + active: player.loopStatus != Mpris.LoopStatus.None + onClicked: () => { + let status = Mpris.LoopStatus.None; + if (player.loopStatus == Mpris.LoopStatus.None) + status = Mpris.LoopStatus.Track; + else if (player.loopStatus === Mpris.LoopStatus.Track) + status = Mpris.LoopStatus.Playlist; + player.setLoopStatus(status); + } + } + + } + + } + + } +} \ No newline at end of file diff --git a/src/contents/ui/CommandIcon.qml b/src/contents/ui/components/CommandIcon.qml similarity index 100% rename from src/contents/ui/CommandIcon.qml rename to src/contents/ui/components/CommandIcon.qml diff --git a/src/contents/ui/MouseAreaWithWheelHandler.qml b/src/contents/ui/components/MouseAreaWithWheelHandler.qml similarity index 100% rename from src/contents/ui/MouseAreaWithWheelHandler.qml rename to src/contents/ui/components/MouseAreaWithWheelHandler.qml diff --git a/src/contents/ui/PanelIcon.qml b/src/contents/ui/components/PanelIcon.qml similarity index 100% rename from src/contents/ui/PanelIcon.qml rename to src/contents/ui/components/PanelIcon.qml diff --git a/src/contents/ui/ScrollingText.qml b/src/contents/ui/components/ScrollingText.qml similarity index 100% rename from src/contents/ui/ScrollingText.qml rename to src/contents/ui/components/ScrollingText.qml diff --git a/src/contents/ui/TrackPositionSlider.qml b/src/contents/ui/components/TrackPositionSlider.qml similarity index 100% rename from src/contents/ui/TrackPositionSlider.qml rename to src/contents/ui/components/TrackPositionSlider.qml diff --git a/src/contents/ui/VolumeBar.qml b/src/contents/ui/components/VolumeBar.qml similarity index 100% rename from src/contents/ui/VolumeBar.qml rename to src/contents/ui/components/VolumeBar.qml diff --git a/src/contents/ui/ConfigIcon.qml b/src/contents/ui/config/ConfigIcon.qml similarity index 100% rename from src/contents/ui/ConfigIcon.qml rename to src/contents/ui/config/ConfigIcon.qml diff --git a/src/contents/ui/ConfigGeneral.qml b/src/contents/ui/config/General.qml similarity index 99% rename from src/contents/ui/ConfigGeneral.qml rename to src/contents/ui/config/General.qml index ffd51ca..d88960c 100644 --- a/src/contents/ui/ConfigGeneral.qml +++ b/src/contents/ui/config/General.qml @@ -1,3 +1,4 @@ +import "../components" import QtQuick import QtQuick.Controls import QtQuick.Layouts diff --git a/src/contents/ui/main.qml b/src/contents/ui/main.qml index ea7dd47..d1280ce 100644 --- a/src/contents/ui/main.qml +++ b/src/contents/ui/main.qml @@ -6,20 +6,18 @@ import org.kde.plasma.components as PlasmaComponents3 import org.kde.kirigami as Kirigami import org.kde.plasma.private.mpris as Mpris + PlasmoidItem { id: widget Plasmoid.status: PlasmaCore.Types.HiddenStatus Plasmoid.backgroundHints: plasmoid.configuration.desktopWidgetBg - readonly property bool horizontal: Plasmoid.formFactor === PlasmaCore.Types.Horizontal - readonly property font textFont: { - return plasmoid.configuration.useCustomFont ? plasmoid.configuration.customFont : Kirigami.Theme.defaultFont - } + readonly property int formFactor: Plasmoid.formFactor + readonly property int location: Plasmoid.location + + readonly property font textFont: plasmoid.configuration.useCustomFont ? plasmoid.configuration.customFont : Kirigami.Theme.defaultFont readonly property font boldTextFont: Qt.font(Object.assign({}, textFont, {weight: Font.Bold})) - readonly property bool textScrollingEnabled: plasmoid.configuration.textScrollingEnabled - readonly property bool textScrollingResetOnPause: plasmoid.configuration.textScrollingResetOnPause - readonly property int volumeStep: plasmoid.configuration.volumeStep toolTipTextFormat: Text.PlainText toolTipMainText: player.playbackStatus > Mpris.PlaybackStatus.Stopped ? player.title : i18n("No media playing") @@ -45,445 +43,6 @@ PlasmoidItem { } } - compactRepresentation: Item { - id: compact - - Layout.preferredWidth: grid.implicitWidth - Layout.preferredHeight: grid.implicitHeight - Layout.fillHeight: horizontal || plasmoid.configuration.fillAvailableSpace - Layout.fillWidth: !horizontal || plasmoid.configuration.fillAvailableSpace - readonly property bool colorsFromAlbumCover: plasmoid.configuration.colorsFromAlbumCover - property color imageColor: Kirigami.Theme.textColor - property bool imageReady: false - property string backgroundColor: imageReady && colorsFromAlbumCover ? Kirigami.ColorUtils.tintWithAlpha(imageColor, "#000000", 0.5) : "transparent" - property string foregroundColor: imageReady && colorsFromAlbumCover ? Kirigami.ColorUtils.tintWithAlpha(imageColor, contrastColor, .6) : Kirigami.Theme.textColor - property string contrastColor: Kirigami.ColorUtils.brightnessForColor(backgroundColor) === Kirigami.ColorUtils.Dark ? "#ffffff" : "#000000" - - readonly property int widgetThickness: Math.min(height, width) - readonly property int controlsSize: Math.round(widgetThickness * 0.75) - readonly property int lengthMargin: Math.round((widgetThickness - controlsSize)) - - Behavior on backgroundColor { - ColorAnimation { - duration: Kirigami.Units.longDuration - } - } - - Behavior on foregroundColor { - ColorAnimation { - duration: Kirigami.Units.longDuration - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - widget.expanded = !widget.expanded; - } - } - - MouseAreaWithWheelHandler { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton - propagateComposedEvents: true - property int wheelDelta: 0 - onClicked: (mouse) => { - switch (mouse.button) { - case Qt.MiddleButton: - player.playPause() - break - case Qt.BackButton: - if (player.canGoPrevious) { - player.previous(); - } - break - case Qt.ForwardButton: - if (player.canGoNext) { - player.next(); - } - break - default: - if (mouse.modifiers & Qt.ControlModifier) { - if (player.canRaise) player.raise() - } else { - mouse.accepted = false - } - } - } - onWheelUp: { - player.changeVolume(volumeStep / 100, true); - } - onWheelDown: { - player.changeVolume(-volumeStep / 100, true); - } - z: 999 - } - - Rectangle { - anchors.fill: parent - color: backgroundColor - radius: plasmoid.configuration.panelBackgroundRadius - } - - GridLayout { - id: grid - columnSpacing: Kirigami.Units.smallSpacing - rowSpacing: Kirigami.Units.smallSpacing - columns: horizontal ? grid.children.length : 1 - rows: horizontal ? 1 : grid.children.length - anchors.fill: parent - - PanelIcon { - Layout.leftMargin: horizontal ? lengthMargin / 2: 0 - Layout.topMargin: horizontal ? 0 : lengthMargin / 2 - size: compact.controlsSize - icon: plasmoid.configuration.panelIcon - imageUrl: player.artUrl - imageRadius: plasmoid.configuration.albumCoverRadius - fallbackToIconWhenImageNotAvailable: plasmoid.configuration.fallbackToIconWhenArtNotAvailable - type: { - if (!plasmoid.configuration.useAlbumCoverAsPanelIcon) { - return PanelIcon.Type.Icon; - } - return PanelIcon.Type.Image; - } - Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter - onTypeChanged: { - compact.imageReady = type === PanelIcon.Type.Image && imageReady - } - onImageColorChanged: (color) => { - compact.imageColor = color - } - onImageReadyChanged: { - if (type === PanelIcon.Type.Image) - compact.imageReady = imageReady - } - } - - Item { - id: panelScrollingText - implicitWidth: horizontal ? column.implicitWidth : column.implicitHeight - implicitHeight: horizontal ? column.implicitHeight : column.implicitWidth - Layout.fillHeight: horizontal || plasmoid.configuration.fillAvailableSpace - Layout.fillWidth: !horizontal || plasmoid.configuration.fillAvailableSpace - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.rightMargin: horizontal ? Kirigami.Units.smallSpacing : 0 - Layout.leftMargin: horizontal ? Kirigami.Units.smallSpacing : 0 - Layout.topMargin: horizontal ? 0 : Kirigami.Units.smallSpacing - Layout.bottomMargin: horizontal ? 0: Kirigami.Units.smallSpacings - readonly property int length: horizontal ? width : height - - ColumnLayout { - id: column - spacing: 0 - - // The components are anchored before they are rotated. This means that when the widget is placed on a vertical panel - // and the state is `vertical-top` or `vertical-bottom`, the song text may overlap with the PanelIcon or the ToolButtons. - // As a workaround, the component's height is set equal to its width. - height: width - visible: plasmoid.configuration.maxSongWidthInPanel !== 0 - rotation: { - if (horizontal) return 0 - if (plasmoid.location === PlasmaCore.Types.LeftEdge) return -90 - if (plasmoid.location === PlasmaCore.Types.RightEdge) return 90 - } - - readonly property int songTextAlignment: plasmoid.configuration.songTextAlignment - state: { - if (songTextAlignment == Qt.AlignCenter || !plasmoid.configuration.fillAvailableSpace) { - return 'centered' - } - if (horizontal && songTextAlignment == Qt.AlignLeft) { - return 'horizontal-left' - } - if (horizontal && songTextAlignment == Qt.AlignRight) { - return 'horizontal-right' - } - if (!horizontal && songTextAlignment == Qt.AlignLeft) { - return 'vertical-top' - } - if (!horizontal && songTextAlignment == Qt.AlignRight) { - return 'vertical-bottom' - } - } - - states: [ - State { - name: "centered" - AnchorChanges { - target: column - anchors.horizontalCenter: panelScrollingText.horizontalCenter - anchors.verticalCenter: panelScrollingText.verticalCenter - } - }, - State { - name: "horizontal-left" - AnchorChanges { - target: column - anchors.left: panelScrollingText.left - anchors.verticalCenter: panelScrollingText.verticalCenter - } - }, - State { - name: "horizontal-right" - AnchorChanges { - target: column - anchors.right: panelScrollingText.right - anchors.verticalCenter: panelScrollingText.verticalCenter - } - }, - State { - name: "vertical-top" - AnchorChanges { - target: column - anchors.top: panelScrollingText.top - anchors.horizontalCenter: panelScrollingText.horizontalCenter - } - }, - State { - name: "vertical-bottom" - AnchorChanges { - target: column - anchors.bottom: panelScrollingText.bottom - anchors.horizontalCenter: panelScrollingText.horizontalCenter - } - } - ] - - ColumnLayout { - spacing: 0 - anchors.centerIn: parent - - ScrollingText { - visible: plasmoid.configuration.separateText - overflowBehaviour: plasmoid.configuration.textScrollingBehaviour - font: widget.boldTextFont - speed: plasmoid.configuration.textScrollingSpeed - maxWidth: plasmoid.configuration.fillAvailableSpace ? panelScrollingText.length : plasmoid.configuration.maxSongWidthInPanel - text: player.title - scrollingEnabled: textScrollingEnabled - scrollResetOnPause: textScrollingResetOnPause - textColor: foregroundColor - } - ScrollingText { - overflowBehaviour: plasmoid.configuration.textScrollingBehaviour - font: widget.textFont - speed: plasmoid.configuration.textScrollingSpeed - maxWidth: plasmoid.configuration.fillAvailableSpace ? panelScrollingText.length : plasmoid.configuration.maxSongWidthInPanel - text: plasmoid.configuration.separateText ? player.artists : [player.artists, player.title].filter((x) => x).join(" - ") - scrollingEnabled: textScrollingEnabled - scrollResetOnPause: textScrollingResetOnPause - visible: text.length !== 0 - textColor: foregroundColor - } - } - } - } - - - GridLayout { - Layout.rightMargin: horizontal ? lengthMargin / 2 : 0 - Layout.bottomMargin: horizontal ? 0: lengthMargin / 2 - columns: horizontal ? grid.children.length : 1 - rows: horizontal ? 1 : grid.children.length - Layout.fillHeight: horizontal - Layout.fillWidth: !horizontal - Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter - - PlasmaComponents3.ToolButton { - visible: plasmoid.configuration.commandsInPanel - enabled: player.canGoPrevious - icon.name: "media-skip-backward" - icon.color: foregroundColor - implicitWidth: compact.controlsSize - implicitHeight: compact.controlsSize - MouseArea { - anchors.fill: parent - onClicked: player.previous() - } - Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter - } - - PlasmaComponents3.ToolButton { - visible: plasmoid.configuration.commandsInPanel - enabled: player.playbackStatus === Mpris.PlaybackStatus.Playing ? player.canPause : player.canPlay - implicitWidth: compact.controlsSize - implicitHeight: compact.controlsSize - icon.name: player.playbackStatus === Mpris.PlaybackStatus.Playing ? "media-playback-pause" : "media-playback-start" - icon.color: foregroundColor - MouseArea { - anchors.fill: parent - onClicked: player.playPause() - } - Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter - } - - PlasmaComponents3.ToolButton { - visible: plasmoid.configuration.commandsInPanel - enabled: player.canGoNext - implicitWidth: compact.controlsSize - implicitHeight: compact.controlsSize - icon.name: "media-skip-forward" - icon.color: foregroundColor - MouseArea { - anchors.fill: parent - onClicked: player.next() - } - Layout.alignment : Qt.AlignVCenter | Qt.AlignHCenter - } - } - } - } - - fullRepresentation: Item { - Layout.preferredHeight: column.implicitHeight - Layout.preferredWidth: column.implicitWidth - Layout.minimumWidth: column.implicitWidth - Layout.minimumHeight: column.implicitHeight - - ColumnLayout { - id: column - - spacing: 0 - anchors.fill: parent - - Rectangle { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 10 - width: 300 - height: width - - Image { - anchors.fill: parent - source: player.artUrl || plasmoid.configuration.albumPlaceholder - fillMode: Image.PreserveAspectFit - MouseArea { - id: coverMouseArea - anchors.fill: parent - cursorShape: player.canRaise ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: { - if (player.canRaise) player.raise() - } - hoverEnabled: true - } - PlasmaComponents3.ToolTip { - id: raisePlayerTooltip - anchors.centerIn: parent - text: player.canRaise ? i18n("Bring player to the front") : i18n("This player can't be raised") - visible: coverMouseArea.containsMouse - } - } - } - - TrackPositionSlider { - Layout.leftMargin: 20 - Layout.rightMargin: 20 - songPosition: player.songPosition - songLength: player.songLength - playing: player.playbackStatus === Mpris.PlaybackStatus.Playing - enableChangePosition: player.canSeek - onRequireChangePosition: (position) => { - player.setPosition(position) - } - onRequireUpdatePosition: () => { - player.updatePosition() - } - } - - ScrollingText { - speed: plasmoid.configuration.textScrollingSpeed - font: widget.boldTextFont - maxWidth: 250 - text: player.title - } - - ScrollingText { - speed: plasmoid.configuration.textScrollingSpeed - font: widget.textFont - maxWidth: 250 - text: player.artists - } - - VolumeBar { - Layout.leftMargin: 40 - Layout.rightMargin: 40 - Layout.topMargin: 10 - volume: player.volume - onSetVolume: (vol) => { - player.setVolume(vol) - } - onVolumeUp: { - player.changeVolume(volumeStep / 100, false) - } - onVolumeDown: { - player.changeVolume(-volumeStep / 100, false) - } - } - - Item { - Layout.leftMargin: 20 - Layout.rightMargin: 20 - Layout.bottomMargin: 10 - Layout.fillWidth: true - Layout.preferredHeight: row.implicitHeight - RowLayout { - id: row - - anchors.fill: parent - - CommandIcon { - enabled: player.canChangeShuffle - Layout.alignment: Qt.AlignHCenter - size: Kirigami.Units.iconSizes.medium - source: "media-playlist-shuffle" - onClicked: player.setShuffle(player.shuffle === Mpris.ShuffleStatus.Off ? Mpris.ShuffleStatus.On : Mpris.ShuffleStatus.Off) - active: player.shuffle === Mpris.ShuffleStatus.On - } - - CommandIcon { - enabled: player.canGoPrevious - Layout.alignment: Qt.AlignHCenter - size: Kirigami.Units.iconSizes.medium - source: "media-skip-backward" - onClicked: player.previous() - } - - CommandIcon { - enabled: player.playbackStatus === Mpris.PlaybackStatus.Playing ? player.canPause : player.canPlay - Layout.alignment: Qt.AlignHCenter - size: Kirigami.Units.iconSizes.large - source: player.playbackStatus === Mpris.PlaybackStatus.Playing ? "media-playback-pause" : "media-playback-start" - onClicked: player.playPause() - } - - CommandIcon { - enabled: player.canGoNext - Layout.alignment: Qt.AlignHCenter - size: Kirigami.Units.iconSizes.medium - source: "media-skip-forward" - onClicked: player.next() - } - - CommandIcon { - enabled: player.canChangeLoopStatus - Layout.alignment: Qt.AlignHCenter - size: Kirigami.Units.iconSizes.medium - source: player.loopStatus === Mpris.LoopStatus.Track ? "media-playlist-repeat-song" : "media-playlist-repeat" - active: player.loopStatus != Mpris.LoopStatus.None - onClicked: () => { - let status = Mpris.LoopStatus.None; - if (player.loopStatus == Mpris.LoopStatus.None) - status = Mpris.LoopStatus.Track; - else if (player.loopStatus === Mpris.LoopStatus.Track) - status = Mpris.LoopStatus.Playlist; - player.setLoopStatus(status); - } - } - - } - - } - - } - } + compactRepresentation: Compact {} + fullRepresentation: Full {} }