fuzbal/Sidebar.qml

246 lines
7.4 KiB
QML
Raw Normal View History

// SPDX-License-Identifier: Unlicense
import QtQuick 2.12
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.6
import Qt.labs.platform 1.1
Page {
id: control
property bool modified: false
property Video video
function clear() {
description.clear()
events.clear()
}
function save() {
modified = false
return {
meta: {
version: Qt.application.version,
video: video.source.toString(),
description: description.text
},
tags: tags.model,
events: events.save()
}
}
function load(data) {
if (data.meta.description !== undefined)
description.text = data.meta.description
if (data.tags !== undefined)
tags.model = data.tags
events.load(data.events)
modified = false
}
FileDialog {
id: videoDialog
title: qsTr('Open video')
onAccepted: {
clear()
video.source = currentFile
const events = io.read(video.source+'.events')
if (events)
load(JSON.parse(events))
}
}
FileDialog {
id: tagsDialog
title: qsTr('Load tags')
nameFilters: [qsTr('JSON files (*.json)'), qsTr('All files (*)')]
onAccepted: tags.model = JSON.parse(io.read(currentFile))
}
Keys.forwardTo: [tags, video]
header: ToolBar {
horizontalPadding: 0
RowLayout {
anchors.fill: parent
ToolButton {
action: Action {
icon.name: 'document-open'
shortcut: StandardKey.Open
onTriggered: videoDialog.open()
}
focusPolicy: Qt.NoFocus
}
Label {
text: video.loaded ? video.source : ''
elide: Text.ElideLeft
Layout.fillWidth: true
}
ToolButton {
action: Action {
onTriggered: io.write(video.source+'.events', JSON.stringify(save()))
shortcut: StandardKey.Save
icon.name: 'document-save'
enabled: video.loaded && control.modified
}
visible: video.loaded
opacity: enabled ? 1 : 0.25
focusPolicy: Qt.NoFocus
}
}
}
ColumnLayout {
anchors.fill: parent
// Description box.
ColumnLayout {
spacing: 0
RowLayout {
Label {
text: qsTr('Description')
Layout.fillWidth: true
}
Label { text: description.enabled ? qsTr('') : qsTr('+') }
TapHandler { onTapped: description.enabled = !description.enabled }
}
ScrollView {
Layout.fillWidth: true
Layout.preferredHeight: 100
contentWidth: parent.availableWidth
padding: 1
visible: description.enabled
background: Frame { }
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
TextArea {
id: description
background: Rectangle { color: palette.base }
leftPadding: padding
selectByMouse: true
wrapMode: Text.Wrap
onTextChanged: modified = true
KeyNavigation.priority: KeyNavigation.BeforeItem
KeyNavigation.tab: events
}
}
}
// Events list.
ColumnLayout {
spacing: 0
Label { text: qsTr('Events') }
Frame {
padding: 1
Layout.fillWidth: true
Layout.fillHeight: true
Events {
id: events
anchors.fill: parent
focus: true
tags: tags.model
onEditingChanged: video.pause(editing)
onChanged: modified = true
MouseArea {
anchors.fill: parent
enabled: !parent.editing
onPressed: {
const index = events.indexAt(mouse.x, mouse.y)
if (index !== -1) {
events.currentIndex = index
video.seek(events.itemAtIndex(index).time)
}
forceActiveFocus()
}
}
}
}
}
Page {
Layout.fillWidth: true
Layout.fillHeight: false
StackLayout {
currentIndex: bar.currentIndex
implicitHeight: children[currentIndex].implicitHeight
width: parent.width
Frame {
padding: 5
enabled: visible
Layout.fillWidth: true
ColumnLayout {
width: parent.width
spacing: 0
RowLayout {
Label {
text: qsTr('Tags')
Layout.fillWidth: true
}
ToolButton {
icon.name: 'document-open'
Layout.alignment: Qt.AlignTop
onClicked: tagsDialog.open()
focusPolicy:Qt.NoFocus
}
}
Tags {
id: tags
model: JSON.parse(io.read('qrc:/tags.json'))
enabled: video.loaded && !events.editing
onClicked: events.create(video.time, tag, fields)
Layout.fillWidth: true
}
}
}
Frame {
padding: 5
enabled: visible
Layout.fillWidth: true
Filter {
id: filter
tags: tags.model
width: parent.width
onChanged: print('filter changed')
}
}
}
footer: TabBar {
id: bar
Layout.fillWidth: true
ActionGroup { id: tabActions }
Repeater {
model: [
{ text: qsTr('&Annotate'), shortcut: qsTr('Alt+A') },
{ text: qsTr('&Filter'), shortcut: qsTr('Alt+F') }
]
delegate: TabButton {
action: Action {
ActionGroup.group: tabActions
shortcut: modelData.shortcut
}
text: modelData.text
focusPolicy: Qt.NoFocus
padding: 5
onClicked: TabBar.tabBar.setCurrentIndex(index)
}
}
}
}
}
}