Newer
Older
/*****************************************************************************
* Copyright (C) 2019 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.
*****************************************************************************/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtQml.Models 2.2
import QtGraphicalEffects 1.0
import "qrc:///widgets/" as Widgets
import "qrc:///style/"
id: root
property alias image: picture.source
property alias title: titleLabel.text
property alias subtitle: subtitleTxt.text
property alias textHorizontalAlignment: subtitleTxt.horizontalAlignment
property alias playCoverBorder: picture.playCoverBorder
property alias playCoverOnlyBorders: picture.playCoverOnlyBorders
property alias playIconSize: picture.playIconSize
property alias pictureRadius: picture.radius
property alias pictureOverlay: picture.imageOverlay
property bool selected: false
property alias unselectedUnderlay: unselectedUnderlayLoader.sourceComponent
property alias selectedUnderlay: selectedUnderlayLoader.sourceComponent
property alias progress: picture.progress
property alias labels: picture.labels
property real pictureWidth: VLCStyle.colWidth(1)
property real pictureHeight: pictureWidth
property int titleMargin: VLCStyle.margin_xsmall
signal playClicked
signal addToPlaylistClicked
signal itemClicked(Item menuParent, int key, int modifier)
signal itemDoubleClicked(Item menuParent, int keys, int modifier)
signal contextMenuButtonClicked(Item menuParent, var globalMousePos)
Keys.onMenuPressed: root.contextMenuButtonClicked(picture, root.mapToGlobal(0,0))
Accessible.role: Accessible.Cell
Accessible.name: title
implicitWidth: mouseArea.implicitWidth
implicitHeight: mouseArea.implicitHeight
readonly property bool highlighted: mouseArea.containsMouse || root.activeFocus
readonly property int selectedBorderWidth: VLCStyle.gridItemSelectedBorder
property int _newIndicatorMedian: VLCStyle.margin_xsmall
property int _modifiersOnLastPress: Qt.NoModifier
state: highlighted ? "selected" : "unselected"
PropertyChanges {
target: selectedUnderlayLoader
opacity: 0
visible: false
}
PropertyChanges {
target: unselectedUnderlayLoader
opacity: 1
visible: true
}
PropertyChanges {
target: picture
playCoverOpacity: 0
playCoverVisible: false
_newIndicatorMedian: VLCStyle.margin_xsmall
PropertyChanges {
target: selectedUnderlayLoader
opacity: 1
visible: true
}
PropertyChanges {
target: unselectedUnderlayLoader
opacity: 0
visible: false
}
PropertyChanges {
target: picture
playCoverOpacity: 1
playCoverVisible: true
_newIndicatorMedian: VLCStyle.margin_small
transitions: [
Transition {
from: "unselected"
to: "selected"
// reversible: true // doesn't work
SequentialAnimation {
PropertyAction {
targets: [picture, selectedUnderlayLoader]
properties: "playCoverVisible,visible"
}
ParallelAnimation {
NumberAnimation {
properties: "opacity,playCoverOpacity"
duration: 240
easing.type: Easing.InSine
}
SmoothedAnimation {
target: root
property: "_newIndicatorMedian"
duration: 240
easing.type: Easing.InSine
}
}
PropertyAction {
target: unselectedUnderlayLoader
Transition {
from: "selected"
to: "unselected"
SequentialAnimation {
PropertyAction {
target: unselectedUnderlayLoader
property: "visible"
}
ParallelAnimation {
NumberAnimation {
properties: "opacity,playCoverOpacity"
duration: 200
easing.type: Easing.OutSine
}
SmoothedAnimation {
target: root
duration: 200
property: "_newIndicatorMedian"
easing.type: Easing.OutSine
}
}
PropertyAction {
targets: [picture, selectedUnderlayLoader]
properties: "playCoverVisible,visible"
}
implicitWidth: layout.implicitWidth
implicitHeight: layout.implicitHeight
drag.target: root.dragItem
drag.axis: Drag.XAndYAxis
drag.onActiveChanged: {
// 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
if (drag.active && !selected) {
root.itemClicked(picture, Qt.LeftButton, root._modifiersOnLastPress)
} else if (root.dragItem) {
root.dragItem.Drag.drop()
}
root.dragItem.Drag.active = drag.active
}
acceptedButtons: Qt.RightButton | Qt.LeftButton
Keys.onMenuPressed: root.contextMenuButtonClicked(picture, root.mapToGlobal(0,0))
onClicked: {
if (mouse.button === Qt.RightButton)
contextMenuButtonClicked(picture, mouseArea.mapToGlobal(mouse.x,mouse.y));
else {
root.itemClicked(picture, mouse.button, mouse.modifiers);
onDoubleClicked: {
if (mouse.button === Qt.LeftButton)
root.itemDoubleClicked(picture,mouse.buttons, mouse.modifiers)
}
onPressed: _modifiersOnLastPress = mouse.modifiers
onPositionChanged: {
if (drag.active) {
var pos = drag.target.parent.mapFromItem(mouseArea, mouseX, mouseY)
drag.target.x = pos.x + 12
drag.target.y = pos.y + 12
}
}
/* background visible when selected */
Rectangle {
id: selectionRect
x: - root.selectedBorderWidth
y: - root.selectedBorderWidth
width: root.width + ( root.selectedBorderWidth * 2 )
height: root.height + ( root.selectedBorderWidth * 2 )
color: VLCStyle.colors.bgHover
visible: root.selected || root.highlighted
Loader {
id: unselectedUnderlayLoader
Loader {
id: selectedUnderlayLoader
asynchronous: true
anchors.centerIn: parent
Widgets.MediaCover {
id: picture
width: pictureWidth
height: pictureHeight
playCoverVisible: root.highlighted
onPlayIconClicked: root.playClicked()
clip: true
radius: VLCStyle.gridCover_radius
/* new indicator (triangle at top-left of cover)*/
Rectangle {
id: newIndicator
// consider this Rectangle as a triangle, then following property is its median length
property alias median: root._newIndicatorMedian
x: parent.width - median
y: - median
width: 2 * median
height: 2 * median
color: VLCStyle.colors.accent
rotation: 45
visible: root.showNewIndicator && root.progress === 0
Widgets.ScrollingText {
id: titleTextRect
height: titleLabel.height
width: titleLabel.width
visible: root.title !== ""
Widgets.ListLabel {
id: titleLabel
elide: Text.ElideNone
width: pictureWidth
horizontalAlignment: root.textHorizontalAlignment
topPadding: root.titleMargin
color: selectionRect.visible ? VLCStyle.colors.bgHoverText : VLCStyle.colors.text
Widgets.MenuCaption {
id: subtitleTxt
visible: text !== ""
text: root.subtitle
width: pictureWidth
topPadding: VLCStyle.margin_xsmall
color: selectionRect.visible
? VLCStyle.colors.setColorAlpha(VLCStyle.colors.bgHoverText, .6)
: VLCStyle.colors.menuCaption
}
}