2021-03-11 10:16:54 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* Copyright (C) 2021 VLC authors and VideoLAN
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* ( at your option ) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2023-05-09 13:19:15 +02:00
|
|
|
import QtQuick 2.12
|
|
|
|
import QtQuick.Templates 2.12 as T
|
|
|
|
import QtQuick.Layouts 1.12
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-02 11:52:10 +01:00
|
|
|
import org.videolan.vlc 0.1
|
2022-12-12 15:41:41 +01:00
|
|
|
|
2021-03-11 10:16:54 +01:00
|
|
|
import "qrc:///widgets/" as Widgets
|
|
|
|
import "qrc:///style/"
|
|
|
|
|
2021-11-05 17:05:08 +01:00
|
|
|
T.Control {
|
2021-03-11 10:16:54 +01:00
|
|
|
id: delegate
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
|
2022-07-07 14:38:55 +02:00
|
|
|
property var rowModel
|
|
|
|
property var sortModel
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-07-07 14:18:54 +02:00
|
|
|
property bool selected: false
|
2021-03-11 10:16:54 +01:00
|
|
|
|
|
|
|
readonly property int _index: index
|
|
|
|
|
|
|
|
property int _modifiersOnLastPress: Qt.NoModifier
|
|
|
|
|
2021-12-13 18:44:25 +01:00
|
|
|
readonly property bool dragActive: hoverArea.drag.active
|
|
|
|
|
2022-07-07 13:44:27 +02:00
|
|
|
property var dragItem
|
|
|
|
|
2022-07-11 10:18:38 +02:00
|
|
|
property bool acceptDrop: false
|
|
|
|
|
2022-07-07 10:17:54 +02:00
|
|
|
signal contextMenuButtonClicked(Item menuParent, var menuModel, point globalMousePos)
|
|
|
|
signal rightClick(Item menuParent, var menuModel, point globalMousePos)
|
|
|
|
signal itemDoubleClicked(var index, var model)
|
|
|
|
|
2022-07-07 14:18:54 +02:00
|
|
|
signal selectAndFocus(int modifiers, int focusReason)
|
|
|
|
|
2022-07-11 10:18:38 +02:00
|
|
|
signal dropEntered(var drag, bool before)
|
|
|
|
signal dropUpdatePosition(var drag, bool before)
|
|
|
|
signal dropExited(var drag, bool before)
|
|
|
|
signal dropEvent(var drag, var drop, bool before)
|
|
|
|
|
2022-07-07 12:08:32 +02:00
|
|
|
property Component defaultDelegate: Widgets.ScrollingText {
|
|
|
|
id: defaultDelId
|
|
|
|
property var rowModel: parent.rowModel
|
2022-07-07 14:38:55 +02:00
|
|
|
property var colModel: parent.colModel
|
2022-12-02 11:52:10 +01:00
|
|
|
readonly property ColorContext colorContext: parent.colorContext
|
|
|
|
readonly property bool selected: parent.selected
|
2022-07-07 12:08:32 +02:00
|
|
|
|
|
|
|
label: text
|
|
|
|
forceScroll: parent.currentlyFocused
|
|
|
|
width: parent.width
|
|
|
|
clip: scrolling
|
|
|
|
|
|
|
|
Widgets.ListLabel {
|
|
|
|
id: text
|
|
|
|
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
text: defaultDelId.rowModel
|
|
|
|
? (defaultDelId.rowModel[defaultDelId.colModel.criteria] || "")
|
|
|
|
: ""
|
2022-12-02 11:52:10 +01:00
|
|
|
|
|
|
|
color: defaultDelId.selected
|
|
|
|
? defaultDelId.colorContext.fg.highlight
|
|
|
|
: defaultDelId.colorContext.fg.primary
|
2022-07-07 12:08:32 +02:00
|
|
|
}
|
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
// Settings
|
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
hoverEnabled: true
|
2022-12-02 11:52:10 +01:00
|
|
|
|
2021-12-13 18:44:25 +01:00
|
|
|
ListView.delayRemove: dragActive
|
|
|
|
|
2022-10-17 17:50:03 +02:00
|
|
|
Component.onCompleted: {
|
|
|
|
Keys.menuPressed.connect(contextButton.clicked)
|
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
|
|
|
|
// Childs
|
|
|
|
|
2022-12-02 11:52:10 +01:00
|
|
|
readonly property ColorContext colorContext: ColorContext {
|
|
|
|
id: theme
|
|
|
|
colorSet: ColorContext.Item
|
|
|
|
|
|
|
|
focused: delegate.visualFocus
|
|
|
|
hovered: delegate.hovered
|
|
|
|
}
|
|
|
|
|
2021-07-22 16:40:08 +02:00
|
|
|
background: AnimatedBackground {
|
2022-06-01 11:40:25 +02:00
|
|
|
animationDuration: VLCStyle.duration_short
|
2023-11-14 14:40:35 +01:00
|
|
|
enabled: theme.initialized
|
|
|
|
color: delegate.selected ? theme.bg.highlight : theme.bg.primary
|
|
|
|
border.color: visualFocus ? theme.visualFocus : "transparent"
|
2021-07-22 16:40:08 +02:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
MouseArea {
|
|
|
|
id: hoverArea
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
// Settings
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
anchors.fill: parent
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
hoverEnabled: false
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
acceptedButtons: Qt.RightButton | Qt.LeftButton
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-07-07 13:44:27 +02:00
|
|
|
drag.target: delegate.dragItem
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
drag.axis: Drag.XAndYAxis
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2023-04-26 15:51:57 +02:00
|
|
|
drag.smoothed: false
|
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
// Events
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2024-01-22 16:08:22 +01:00
|
|
|
onPressed: (mouse) => {
|
2023-04-26 15:51:57 +02:00
|
|
|
_modifiersOnLastPress = mouse.modifiers
|
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2024-01-22 16:08:22 +01:00
|
|
|
onClicked: (mouse) => {
|
2022-06-16 13:40:17 +02:00
|
|
|
if ((mouse.button === Qt.LeftButton) || !delegate.selected) {
|
2022-03-04 11:00:31 +01:00
|
|
|
delegate.selectAndFocus(mouse.modifiers, Qt.MouseFocusReason)
|
2021-12-13 12:35:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mouse.button === Qt.RightButton)
|
2022-07-07 14:38:55 +02:00
|
|
|
delegate.rightClick(delegate, delegate.rowModel, hoverArea.mapToGlobal(mouse.x, mouse.y))
|
2021-03-11 10:16:54 +01:00
|
|
|
}
|
|
|
|
|
2024-01-22 16:08:22 +01:00
|
|
|
onDoubleClicked: (mouse) => {
|
2021-12-13 12:35:51 +01:00
|
|
|
if (mouse.button === Qt.LeftButton)
|
2022-07-07 14:38:55 +02:00
|
|
|
delegate.itemDoubleClicked(delegate._index, delegate.rowModel)
|
2021-12-13 12:35:51 +01:00
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
drag.onActiveChanged: {
|
|
|
|
// NOTE: Perform the "click" action because the click action is only executed on mouse
|
|
|
|
// release (we are in the pressed state) but we will need the updated list on drop.
|
2022-06-16 13:40:17 +02:00
|
|
|
if (drag.active && !delegate.selected) {
|
2022-07-07 14:18:54 +02:00
|
|
|
delegate.selectAndFocus(_modifiersOnLastPress, index)
|
2022-07-07 13:44:27 +02:00
|
|
|
} else if (delegate.dragItem) {
|
|
|
|
delegate.dragItem.Drag.drop()
|
2021-12-13 12:35:51 +01:00
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-07-07 13:44:27 +02:00
|
|
|
delegate.dragItem.Drag.active = drag.active
|
2021-03-11 10:16:54 +01:00
|
|
|
}
|
2022-12-12 15:41:41 +01:00
|
|
|
|
2023-05-09 13:27:17 +02:00
|
|
|
TapHandler {
|
|
|
|
acceptedDevices: PointerDevice.TouchScreen
|
|
|
|
|
2022-12-12 15:41:41 +01:00
|
|
|
onTapped: {
|
|
|
|
delegate.selectAndFocus(Qt.NoModifier, Qt.MouseFocusReason)
|
|
|
|
delegate.itemDoubleClicked(delegate._index, delegate.rowModel)
|
|
|
|
}
|
2023-01-23 14:28:37 +01:00
|
|
|
|
|
|
|
onLongPressed: {
|
|
|
|
delegate.rightClick(delegate, delegate.rowModel, point.scenePosition)
|
|
|
|
}
|
2022-12-12 15:41:41 +01:00
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
}
|
2021-12-13 12:35:51 +01:00
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
contentItem: Row {
|
2022-12-12 15:48:36 +01:00
|
|
|
leftPadding: VLCStyle.margin_xxxsmall
|
|
|
|
rightPadding: VLCStyle.margin_xxxsmall
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-08 19:15:43 +01:00
|
|
|
spacing: VLCStyle.column_spacing
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
Repeater {
|
2022-07-07 14:38:55 +02:00
|
|
|
model: delegate.sortModel
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
Loader{
|
|
|
|
property var rowModel: delegate.rowModel
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-13 16:20:12 +01:00
|
|
|
property var colModel: modelData.model
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
readonly property int index: delegate._index
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
readonly property bool currentlyFocused: delegate.activeFocus
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-02 11:52:10 +01:00
|
|
|
readonly property bool selected: delegate.selected
|
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
readonly property bool containsMouse: hoverArea.containsMouse
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-02 11:52:10 +01:00
|
|
|
readonly property ColorContext colorContext: theme
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-15 11:25:13 +01:00
|
|
|
width: (modelData.size) ? VLCStyle.colWidth(modelData.size) : 0
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
height: parent.height
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2024-01-12 02:57:16 +01:00
|
|
|
sourceComponent: colModel.colDelegate || delegate.defaultDelegate
|
2021-03-11 10:16:54 +01:00
|
|
|
}
|
2021-12-13 12:35:51 +01:00
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
Item {
|
2022-07-07 11:45:42 +02:00
|
|
|
width: VLCStyle.icon_normal
|
2021-12-13 09:54:43 +01:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
height: parent.height
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2021-12-22 10:35:17 +01:00
|
|
|
Widgets.IconToolButton {
|
2021-12-13 12:35:51 +01:00
|
|
|
id: contextButton
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-12-08 19:08:04 +01:00
|
|
|
anchors.left: parent.left
|
|
|
|
|
|
|
|
// NOTE: We want the contextButton to be contained inside the trailing
|
2022-12-08 19:15:43 +01:00
|
|
|
// column_spacing.
|
2022-12-08 19:08:04 +01:00
|
|
|
anchors.leftMargin: -width
|
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2023-11-10 17:39:10 +01:00
|
|
|
text: VLCIcons.ellipsis
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2023-11-10 15:22:23 +01:00
|
|
|
font.pixelSize: VLCStyle.icon_normal
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2023-11-10 17:39:10 +01:00
|
|
|
description: I18n.qtr("Menu")
|
2023-06-14 19:31:54 +02:00
|
|
|
|
2021-12-13 12:35:51 +01:00
|
|
|
visible: delegate.hovered
|
2021-03-11 10:16:54 +01:00
|
|
|
|
2022-03-04 11:00:31 +01:00
|
|
|
onClicked: {
|
2022-06-16 13:35:47 +02:00
|
|
|
if (!delegate.selected)
|
|
|
|
delegate.selectAndFocus(Qt.NoModifier, Qt.MouseFocusReason)
|
2022-03-04 11:00:31 +01:00
|
|
|
|
2023-05-09 12:22:47 +02:00
|
|
|
const pos = contextButton.mapToGlobal(VLCStyle.margin_xsmall, contextButton.height / 2 + VLCStyle.fontHeight_normal)
|
2022-07-07 10:17:54 +02:00
|
|
|
delegate.contextMenuButtonClicked(this, delegate.rowModel, pos)
|
2022-03-04 11:00:31 +01:00
|
|
|
}
|
2022-12-21 19:34:29 +01:00
|
|
|
|
|
|
|
activeFocusOnTab: false
|
2021-12-13 09:54:43 +01:00
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
}
|
|
|
|
}
|
2022-07-11 10:18:38 +02:00
|
|
|
|
|
|
|
DropArea {
|
|
|
|
enabled: delegate.acceptDrop
|
|
|
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
|
|
|
function isBefore(drag) {
|
|
|
|
return drag.y < height/2
|
|
|
|
}
|
|
|
|
|
2024-01-22 17:03:43 +01:00
|
|
|
onEntered: (drag) => { delegate.dropEntered(drag, isBefore(drag)) }
|
2022-07-11 10:18:38 +02:00
|
|
|
|
2024-01-22 17:03:43 +01:00
|
|
|
onPositionChanged: (drag) => { delegate.dropUpdatePosition(drag, isBefore(drag)) }
|
2022-07-11 10:18:38 +02:00
|
|
|
|
|
|
|
onExited:delegate.dropExited(drag, isBefore(drag))
|
|
|
|
|
2024-01-22 17:03:43 +01:00
|
|
|
onDropped: (drop) => { delegate.dropEvent(drag, drop, isBefore(drag)) }
|
2022-07-11 10:18:38 +02:00
|
|
|
|
|
|
|
}
|
2021-03-11 10:16:54 +01:00
|
|
|
}
|