Warning, /multimedia/elisa/src/qml/MediaPlayerControl.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 SPDX-FileCopyrightText: 2020 (c) Carson Black <uhhadd@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-3.0-or-later 0006 */ 0007 0008 import QtQuick 2.7 0009 import QtQuick.Layouts 1.2 0010 import QtQuick.Controls 2.7 0011 import org.kde.kirigami 2.5 as Kirigami 0012 import org.kde.elisa 1.0 0013 0014 import "shared" 0015 0016 BasePlayerControl { 0017 id: musicWidget 0018 0019 property alias volume: volumeSlider.value 0020 property bool isMaximized 0021 property bool isTranslucent 0022 property bool isNearCollapse 0023 0024 signal maximize() 0025 signal minimize() 0026 /* 0027 Emmited when User uses the Item as a handle to resize the layout. 0028 y: difference to previous position 0029 offset: cursor offset (y coordinate relative to this Item, where dragging begun) 0030 */ 0031 signal handlePositionChanged(int y, int offset) 0032 0033 onIsMaximizedChanged: isMaximized ? maximize() : minimize() 0034 0035 SystemPalette { 0036 id: myPalette 0037 colorGroup: SystemPalette.Active 0038 } 0039 0040 Theme { 0041 id: elisaTheme 0042 } 0043 0044 Rectangle { 0045 anchors.fill: parent 0046 0047 Kirigami.Theme.colorSet: Kirigami.Theme.Header 0048 Kirigami.Theme.inherit: false 0049 0050 color: isTranslucent ? myPalette.midlight : Kirigami.Theme.backgroundColor 0051 opacity: isTranslucent ? elisaTheme.mediaPlayerControlOpacity : 1.0 0052 0053 Kirigami.Separator { 0054 anchors { 0055 left: parent.left 0056 right: parent.right 0057 bottom: parent.bottom 0058 } 0059 visible: !isTranslucent 0060 } 0061 0062 MouseArea { 0063 property int dragStartOffset: 0 0064 0065 anchors.fill: parent 0066 cursorShape: isMaximized ? Qt.ArrowCursor : Qt.SizeVerCursor 0067 0068 onPressed: mouse => { 0069 dragStartOffset = mouse.y 0070 } 0071 0072 onPositionChanged: mouse => musicWidget.handlePositionChanged(mouse.y, dragStartOffset) 0073 0074 drag.axis: Drag.YAxis 0075 drag.threshold: 1 0076 } 0077 } 0078 0079 RowLayout { 0080 anchors.fill: parent 0081 spacing: 0 0082 0083 Item { implicitWidth: Math.floor(Kirigami.Units.smallSpacing / 2) } 0084 0085 FlatButtonWithToolTip { 0086 id: minimizeMaximizeButton 0087 text: i18nc("@action:button", "Toggle Party Mode") 0088 icon.name: musicWidget.isMaximized ? "draw-arrow-up" : "draw-arrow-down" 0089 onClicked: musicWidget.isMaximized = !musicWidget.isMaximized 0090 } 0091 0092 FlatButtonWithToolTip { 0093 id: skipBackwardButton 0094 enabled: skipBackwardEnabled 0095 text: i18nc("@action:button", "Skip Backward") 0096 icon.name: musicWidget.LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward" 0097 onClicked: musicWidget.playPrevious() 0098 } 0099 0100 FlatButtonWithToolTip { 0101 id: playPauseButton 0102 enabled: musicWidget.playEnabled 0103 text: musicWidget.isPlaying ? i18nc("@action:button Pause any media that is playing", "Pause") : i18nc("@action:button Start playing media", "Play") 0104 icon.name: musicWidget.isPlaying ? "media-playback-pause" : "media-playback-start" 0105 onClicked: musicWidget.isPlaying ? musicWidget.pause() : musicWidget.play() 0106 } 0107 0108 FlatButtonWithToolTip { 0109 id: skipForwardButton 0110 enabled: skipForwardEnabled 0111 text: i18nc("@action:button skip forward in playlists", "Skip Forward") 0112 icon.name: musicWidget.LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward" 0113 onClicked: musicWidget.playNext() 0114 } 0115 0116 DurationSlider { 0117 Layout.fillWidth: true 0118 Layout.fillHeight: true 0119 position: musicWidget.position 0120 duration: musicWidget.duration 0121 seekable: musicWidget.seekable 0122 playEnabled: musicWidget.playEnabled 0123 onSeek: position => musicWidget.seek(position) 0124 0125 labelColor: myPalette.text 0126 } 0127 0128 FlatButtonWithToolTip { 0129 id: muteButton 0130 text: i18nc("@action:button", "Toggle Mute") 0131 icon.name: musicWidget.muted ? "player-volume-muted" : "player-volume" 0132 onClicked: musicWidget.muted = !musicWidget.muted 0133 } 0134 0135 VolumeSlider { 0136 id: volumeSlider 0137 Layout.preferredWidth: elisaTheme.volumeSliderWidth 0138 Layout.maximumWidth: elisaTheme.volumeSliderWidth 0139 Layout.minimumWidth: elisaTheme.volumeSliderWidth 0140 Layout.fillHeight: true 0141 0142 muted: musicWidget.muted 0143 } 0144 0145 Item { implicitWidth: Kirigami.Units.largeSpacing } 0146 0147 FlatButtonWithToolTip { 0148 id: shuffleButton 0149 text: i18nc("@action:button", "Toggle Shuffle") 0150 icon.name: "media-playlist-shuffle" 0151 checkable: true 0152 checked: ElisaApplication.mediaPlayListProxyModel.shufflePlayList 0153 onClicked: ElisaApplication.mediaPlayListProxyModel.shufflePlayList = !ElisaApplication.mediaPlayListProxyModel.shufflePlayList 0154 } 0155 0156 FlatButtonWithToolTip { 0157 id: repeatButton 0158 text: { 0159 const map = { 0160 [MediaPlayListProxyModel.None]: i18nc("@info:tooltip", "Current: Don't repeat tracks"), 0161 [MediaPlayListProxyModel.One]: i18nc("@info:tooltip", "Current: Repeat current track"), 0162 [MediaPlayListProxyModel.Playlist]: i18nc("@info:tooltip", "Current: Repeat all tracks in playlist"), 0163 } 0164 return map[ElisaApplication.mediaPlayListProxyModel.repeatMode] 0165 } 0166 icon.name: { 0167 const map = { 0168 [MediaPlayListProxyModel.None]: "media-repeat-none", 0169 [MediaPlayListProxyModel.One]: "media-repeat-single", 0170 [MediaPlayListProxyModel.Playlist]: "media-repeat-all", 0171 } 0172 return map[ElisaApplication.mediaPlayListProxyModel.repeatMode] 0173 } 0174 0175 down: pressed || menu.visible 0176 Accessible.role: Accessible.ButtonMenu 0177 0178 checkable: true 0179 checked: ElisaApplication.mediaPlayListProxyModel.repeatMode !== 0 0180 onClicked: { 0181 ElisaApplication.mediaPlayListProxyModel.repeatMode = (ElisaApplication.mediaPlayListProxyModel.repeatMode + 1) % 3 0182 } 0183 onPressAndHold: { 0184 menu.popup() 0185 } 0186 0187 menu: Menu { 0188 PlaylistModeItem { 0189 text: i18nc("@action:inmenu", "Playlist") 0190 mode: MediaPlayListProxyModel.Playlist 0191 } 0192 PlaylistModeItem { 0193 text: i18nc("@action:inmenu", "One") 0194 mode: MediaPlayListProxyModel.One 0195 } 0196 PlaylistModeItem { 0197 text: i18nc("@action:inmenu", "None") 0198 mode: MediaPlayListProxyModel.None 0199 } 0200 } 0201 0202 Kirigami.Icon { 0203 anchors { 0204 right: parent.right 0205 bottom: parent.bottom 0206 margins: Kirigami.Units.smallSpacing 0207 } 0208 width: Math.round(Kirigami.Units.iconSizes.small / 2) 0209 height: Math.round(Kirigami.Units.iconSizes.small / 2) 0210 source: "arrow-down" 0211 } 0212 } 0213 0214 FlatButtonWithToolTip { 0215 // normally toggles the playlist in contentView, but when the headerbar is too narrow to 0216 // show the playlistDrawer handle, this opens the drawer instead 0217 0218 id: showHidePlaylistAction 0219 property bool _togglesDrawer: mainWindow.width < elisaTheme.viewSelectorSmallSizeThreshold 0220 0221 action: Action { 0222 checkable: true 0223 shortcut: ElisaApplication.actionShortcut(ElisaApplication.action("toggle_playlist")) 0224 onTriggered: { 0225 if (showHidePlaylistAction._togglesDrawer) { 0226 playlistDrawer.visible = !playlistDrawer.visible 0227 } else { 0228 contentView.showPlaylist = !contentView.showPlaylist 0229 } 0230 } 0231 } 0232 0233 visible: !musicWidget.isMaximized && (!_togglesDrawer || musicWidget.isNearCollapse) 0234 0235 display: _togglesDrawer ? AbstractButton.IconOnly : AbstractButton.TextBesideIcon 0236 text: i18nc("@action:button", "Show Playlist") 0237 icon.name: "view-media-playlist" 0238 0239 checked: _togglesDrawer ? playlistDrawer.visible : contentView.showPlaylist 0240 } 0241 0242 FlatButtonWithToolTip { 0243 id: menuButton 0244 0245 function openMenu() { 0246 if (!menu.visible) { 0247 menu.open() 0248 } else { 0249 menu.dismiss() 0250 } 0251 } 0252 0253 text: i18nc("@action:button", "Application Menu") 0254 icon.name: "open-menu-symbolic" 0255 0256 down: pressed || menu.visible 0257 Accessible.role: Accessible.ButtonMenu 0258 0259 onPressed: openMenu() 0260 // Need this too because the base control sends onClicked for return/enter 0261 onClicked: openMenu() 0262 0263 menu: ApplicationMenu { 0264 y: menuButton.height 0265 // without modal, clicking on menuButton will not close the menu 0266 modal: true 0267 dim: false 0268 } 0269 } 0270 0271 Item { 0272 implicitWidth: Math.floor(Kirigami.Units.smallSpacing / 2) 0273 } 0274 } 0275 0276 Component.onCompleted: { 0277 for (const element of [ 0278 menuButton, 0279 repeatButton, 0280 shuffleButton, 0281 muteButton, 0282 skipForwardButton, 0283 skipBackwardButton, 0284 playPauseButton, 0285 minimizeMaximizeButton, 0286 ]) { 0287 ElisaApplication.installKeyEventFilter(element) 0288 } 0289 } 0290 }