Changeset View
Changeset View
Standalone View
Standalone View
src/qml/FileBrowserDelegate.qml
Show All 12 Lines | |||||
13 | * Lesser General Public License for more details. | 13 | * Lesser General Public License for more details. | ||
14 | * | 14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public License | 15 | * You should have received a copy of the GNU Lesser General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | 17 | */ | ||
18 | 18 | | |||
19 | import QtQuick 2.7 | 19 | import QtQuick 2.7 | ||
20 | import QtQuick.Controls 2.2 | 20 | import QtQuick.Controls 2.2 | ||
21 | import QtQuick.Controls 1.4 as Controls1 | | |||
22 | import QtQuick.Layouts 1.2 | 21 | import QtQuick.Layouts 1.2 | ||
23 | 22 | | |||
24 | import org.kde.elisa 1.0 | 23 | import org.kde.elisa 1.0 | ||
25 | 24 | | |||
26 | FocusScope { | 25 | FocusScope { | ||
27 | id: fileDelegate | 26 | id: fileDelegate | ||
28 | 27 | | |||
29 | property var fileName | 28 | property var fileName | ||
30 | property var fileUrl | 29 | property var fileUrl | ||
31 | property var imageUrl | 30 | property var imageUrl | ||
32 | property var contentModel | 31 | property var contentModel | ||
33 | property bool isDirectory | 32 | property bool isDirectory | ||
34 | property bool isPlayList | 33 | property bool isPlayList | ||
35 | 34 | | |||
36 | signal enqueue(var data) | 35 | signal enqueue(var data) | ||
37 | signal replaceAndPlay(var data) | 36 | signal replaceAndPlay(var data) | ||
38 | signal loadPlayList(var data) | 37 | signal loadPlayList(var data) | ||
39 | signal open(var data) | 38 | signal open(var data) | ||
40 | signal selected() | 39 | signal selected() | ||
41 | 40 | | |||
42 | Controls1.Action { | | |||
43 | id: replaceAndPlayAction | | |||
44 | text: i18nc("Clear play list and enqueue current track", "Play Now and Replace Play List") | | |||
45 | iconName: "media-playback-start" | | |||
46 | onTriggered: replaceAndPlay(fileUrl) | | |||
47 | } | | |||
48 | | ||||
49 | Controls1.Action { | | |||
50 | id: enqueueAction | | |||
51 | text: i18nc("Enqueue current track", "Enqueue") | | |||
52 | iconName: "media-track-add-amarok" | | |||
53 | onTriggered: enqueue(fileUrl) | | |||
54 | } | | |||
55 | | ||||
56 | Controls1.Action { | | |||
57 | id: openAction | | |||
58 | text: i18nc("Enqueue current track", "Enqueue") | | |||
59 | iconName: 'document-open-folder' | | |||
60 | onTriggered: open(fileUrl) | | |||
61 | } | | |||
62 | | ||||
63 | Controls1.Action { | | |||
64 | id: viewDetailsAction | | |||
65 | text: i18nc("Show track metadata", "View Details") | | |||
66 | iconName: "help-about" | | |||
67 | onTriggered: { | | |||
68 | if (metadataLoader.active === false) { | | |||
69 | metadataLoader.active = true | | |||
70 | metadataLoader.item.trackDataHelper.trackData = contentModel.loadMetaDataFromUrl(fileUrl) | | |||
71 | } | | |||
72 | else { | | |||
73 | metadataLoader.item.close(); | | |||
74 | metadataLoader.active = false | | |||
75 | } | | |||
76 | } | | |||
77 | } | | |||
78 | | ||||
79 | Loader { | 41 | Loader { | ||
80 | id: metadataLoader | 42 | id: metadataLoader | ||
81 | active: false | 43 | active: false | ||
82 | onLoaded: item.show() | 44 | onLoaded: item.show() | ||
83 | 45 | | |||
84 | sourceComponent: MediaTrackMetadataView { | 46 | sourceComponent: MediaTrackMetadataView { | ||
85 | fileName: fileDelegate.fileUrl | 47 | fileName: fileDelegate.fileUrl | ||
86 | onRejected: metadataLoader.active = false; | 48 | onRejected: metadataLoader.active = false; | ||
Show All 15 Lines | 60 | MouseArea { | |||
102 | acceptedButtons: Qt.LeftButton | 64 | acceptedButtons: Qt.LeftButton | ||
103 | 65 | | |||
104 | Layout.preferredHeight: fileDelegate.width * 0.85 + elisaTheme.layoutVerticalMargin * 0.5 + | 66 | Layout.preferredHeight: fileDelegate.width * 0.85 + elisaTheme.layoutVerticalMargin * 0.5 + | ||
105 | (mainLabelSize.boundingRect.height - mainLabelSize.boundingRect.y) | 67 | (mainLabelSize.boundingRect.height - mainLabelSize.boundingRect.y) | ||
106 | Layout.fillWidth: true | 68 | Layout.fillWidth: true | ||
107 | 69 | | |||
108 | onClicked: fileDelegate.selected() | 70 | onClicked: fileDelegate.selected() | ||
109 | 71 | | |||
110 | onDoubleClicked: fileDelegate.enqueue(fileUrl) | 72 | onDoubleClicked: fileDelegate.open(fileUrl) | ||
111 | 73 | | |||
112 | TextMetrics { | 74 | TextMetrics { | ||
113 | id: mainLabelSize | 75 | id: mainLabelSize | ||
114 | font: mainLabel.font | 76 | font: mainLabel.font | ||
115 | text: mainLabel.text | 77 | text: mainLabel.text | ||
116 | } | 78 | } | ||
117 | 79 | | |||
118 | ColumnLayout { | 80 | ColumnLayout { | ||
119 | id: mainData | 81 | id: mainData | ||
120 | 82 | | |||
121 | spacing: 0 | 83 | spacing: 0 | ||
122 | anchors.fill: parent | 84 | anchors.fill: parent | ||
123 | 85 | | |||
124 | Item { | 86 | Item { | ||
125 | Layout.preferredHeight: fileDelegate.width * 0.85 | 87 | Layout.preferredHeight: fileDelegate.width * 0.85 | ||
126 | Layout.preferredWidth: fileDelegate.width * 0.85 | 88 | Layout.preferredWidth: fileDelegate.width * 0.85 | ||
127 | 89 | | |||
128 | Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter | 90 | Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter | ||
129 | 91 | | |||
130 | Loader { | 92 | Loader { | ||
131 | id: hoverLoader | 93 | id: hoverLoader | ||
132 | active: false | 94 | active: false | ||
133 | 95 | | |||
134 | anchors.centerIn: parent | 96 | anchors { | ||
97 | bottom: parent.bottom | ||||
98 | bottomMargin: 2 | ||||
99 | left: parent.left | ||||
100 | leftMargin: 2 | ||||
101 | } | ||||
102 | | ||||
135 | z: 1 | 103 | z: 1 | ||
136 | 104 | | |||
137 | opacity: 0 | 105 | opacity: 0 | ||
138 | 106 | | |||
139 | sourceComponent: Row { | 107 | sourceComponent: Row { | ||
108 | spacing: 2 | ||||
140 | 109 | | |||
141 | Controls1.ToolButton { | 110 | Button { | ||
142 | id: detailsButton | 111 | id: detailsButton | ||
143 | 112 | | |||
144 | Layout.preferredHeight: elisaTheme.delegateHeight | 113 | Layout.preferredHeight: elisaTheme.delegateHeight | ||
145 | Layout.preferredWidth: elisaTheme.delegateHeight | 114 | Layout.preferredWidth: elisaTheme.delegateHeight | ||
146 | 115 | | |||
147 | action: viewDetailsAction | | |||
148 | visible: !isDirectory && !isPlayList | 116 | visible: !isDirectory && !isPlayList | ||
117 | | ||||
118 | icon.name: "help-about" | ||||
119 | onClicked: { | ||||
120 | if (metadataLoader.active === false) { | ||||
121 | metadataLoader.active = true | ||||
122 | metadataLoader.item.trackDataHelper.trackData = contentModel.loadMetaDataFromUrl(fileUrl) | ||||
123 | } | ||||
124 | else { | ||||
125 | metadataLoader.item.close(); | ||||
126 | metadataLoader.active = false | ||||
127 | } | ||||
128 | } | ||||
129 | ToolTip { | ||||
130 | text: i18nc("Show track metadata", "View Details") | ||||
131 | } | ||||
149 | } | 132 | } | ||
150 | 133 | | |||
151 | Controls1.ToolButton { | 134 | Button { | ||
152 | id: enqueueOpenButton | 135 | id: enqueueOpenButton | ||
153 | 136 | | |||
154 | Layout.preferredHeight: elisaTheme.delegateHeight | 137 | Layout.preferredHeight: elisaTheme.delegateHeight | ||
155 | Layout.preferredWidth: elisaTheme.delegateHeight | 138 | Layout.preferredWidth: elisaTheme.delegateHeight | ||
156 | 139 | | |||
157 | action: isDirectory ? openAction : enqueueAction | | |||
158 | visible: !isPlayList | 140 | visible: !isPlayList | ||
141 | | ||||
142 | icon.name: isDirectory ? | ||||
143 | "go-next-view-page" : | ||||
144 | "media-track-add-amarok" | ||||
145 | onClicked: isDirectory ? | ||||
146 | open(fileUrl) : | ||||
147 | enqueue(fileUrl) | ||||
148 | ToolTip { | ||||
149 | text: isDirectory ? | ||||
150 | i18nc("Open view of the container", "Open") : | ||||
151 | i18nc("Enqueue current track", "Enqueue") | ||||
152 | } | ||||
159 | } | 153 | } | ||
160 | 154 | | |||
161 | Controls1.ToolButton { | 155 | Button { | ||
162 | id: replaceAndPlayButton | 156 | id: replaceAndPlayButton | ||
163 | 157 | | |||
164 | Layout.preferredHeight: elisaTheme.delegateHeight | 158 | Layout.preferredHeight: elisaTheme.delegateHeight | ||
165 | Layout.preferredWidth: elisaTheme.delegateHeight | 159 | Layout.preferredWidth: elisaTheme.delegateHeight | ||
166 | 160 | | |||
167 | scale: LayoutMirroring.enabled ? -1 : 1 | 161 | scale: LayoutMirroring.enabled ? -1 : 1 | ||
168 | action: replaceAndPlayAction | | |||
169 | visible: !isDirectory | 162 | visible: !isDirectory | ||
163 | | ||||
164 | icon.name: "media-playback-start" | ||||
165 | onClicked: replaceAndPlay(fileUrl) | ||||
166 | ToolTip { | ||||
167 | text: i18nc("Clear play list and enqueue current track", "Play Now and Replace Play List") | ||||
mgallien: In order to be able to have it in the bugfix branch, it is probably needed to put back the… | |||||
168 | } | ||||
170 | } | 169 | } | ||
171 | } | 170 | } | ||
172 | } | 171 | } | ||
173 | 172 | | |||
174 | Image { | 173 | Image { | ||
175 | id: icon | 174 | id: icon | ||
176 | anchors.fill: parent | 175 | anchors.fill: parent | ||
177 | 176 | | |||
Show All 9 Lines | |||||
187 | } | 186 | } | ||
188 | 187 | | |||
189 | LabelWithToolTip { | 188 | LabelWithToolTip { | ||
190 | id: mainLabel | 189 | id: mainLabel | ||
191 | 190 | | |||
192 | font.weight: Font.Bold | 191 | font.weight: Font.Bold | ||
193 | color: myPalette.text | 192 | color: myPalette.text | ||
194 | 193 | | |||
195 | horizontalAlignment: Text.AlignLeft | 194 | // FIXME: Center-aligned text looks better overall, but | ||
195 | // sometimes results in font kerning issues | ||||
196 | // See https://bugreports.qt.io/browse/QTBUG-49646 | ||||
197 | horizontalAlignment: Text.AlignHCenter | ||||
196 | 198 | | |||
197 | Layout.topMargin: elisaTheme.layoutVerticalMargin * 0.5 | 199 | Layout.topMargin: elisaTheme.layoutVerticalMargin * 0.5 | ||
198 | Layout.preferredWidth: fileDelegate.width * 0.85 | 200 | Layout.maximumWidth: fileDelegate.width * 0.9 | ||
201 | Layout.minimumWidth: Layout.maximumWidth | ||||
199 | Layout.maximumHeight: (mainLabelSize.boundingRect.height - mainLabelSize.boundingRect.y) * 2 | 202 | Layout.maximumHeight: (mainLabelSize.boundingRect.height - mainLabelSize.boundingRect.y) * 2 | ||
200 | Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom | 203 | Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom | ||
201 | 204 | | |||
202 | text: fileName | 205 | text: fileName | ||
203 | wrapMode: Label.Wrap | 206 | wrapMode: Label.Wrap | ||
204 | elide: Text.ElideRight | 207 | elide: Text.ElideRight | ||
205 | } | 208 | } | ||
206 | 209 | | |||
Show All 15 Lines | 222 | State { | |||
222 | PropertyChanges { | 225 | PropertyChanges { | ||
223 | target: hoverLoader | 226 | target: hoverLoader | ||
224 | active: false | 227 | active: false | ||
225 | } | 228 | } | ||
226 | PropertyChanges { | 229 | PropertyChanges { | ||
227 | target: hoverLoader | 230 | target: hoverLoader | ||
228 | opacity: 0.0 | 231 | opacity: 0.0 | ||
229 | } | 232 | } | ||
230 | PropertyChanges { | | |||
231 | target: icon | | |||
232 | opacity: 1 | | |||
233 | } | | |||
234 | }, | 233 | }, | ||
235 | State { | 234 | State { | ||
236 | name: 'hoveredOrSelected' | 235 | name: 'hoveredOrSelected' | ||
237 | when: fileDelegate.activeFocus || hoverArea.containsMouse | 236 | when: fileDelegate.activeFocus || hoverArea.containsMouse | ||
238 | PropertyChanges { | 237 | PropertyChanges { | ||
239 | target: hoverLoader | 238 | target: hoverLoader | ||
240 | active: true | 239 | active: true | ||
241 | } | 240 | } | ||
242 | PropertyChanges { | 241 | PropertyChanges { | ||
243 | target: hoverLoader | 242 | target: hoverLoader | ||
244 | opacity: 1.0 | 243 | opacity: 1.0 | ||
245 | } | 244 | } | ||
246 | PropertyChanges { | | |||
247 | target: icon | | |||
248 | opacity: 0.2 | | |||
249 | } | | |||
250 | } | 245 | } | ||
251 | ] | 246 | ] | ||
252 | 247 | | |||
253 | transitions: [ | 248 | transitions: [ | ||
254 | Transition { | 249 | Transition { | ||
255 | to: 'hoveredOrSelected' | 250 | to: 'hoveredOrSelected' | ||
256 | SequentialAnimation { | 251 | SequentialAnimation { | ||
257 | PropertyAction { | 252 | PropertyAction { | ||
Show All 25 Lines |
In order to be able to have it in the bugfix branch, it is probably needed to put back the comment.