Files
QtPotato/src/qml/Header.qml
T
tri 0098641425 fix(ui): keep Space for playback after mouse clicks
Controls take focus only via Tab, so a click leaves Space for playback.
2026-11-11 20:12:06 +07:00

263 lines
8.3 KiB
QML

// SPDX-FileCopyrightText: 2020 George Florea Bănuș <georgefb899@gmail.com>
// SPDX-FileCopyrightText: 2026 Tri Vo Khac
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import org.kde.ki18n
import org.kde.kirigami as Kirigami
// Toolbar above the video: open buttons, track menus, translation progress, settings.
ToolBar {
id: root
// Space activates the focused control before the window's playback action. The
// controls take focus only from Tab, so a click leaves Space for playback.
Keys.onShortcutOverride: event => {
if (event.key === Qt.Key_Space && event.modifiers === Qt.NoModifier) {
event.accepted = true
}
}
required property Actions actions
required property MpvItem mpv
required property TranslationService translator
// False in full screen and when the user hides the toolbar.
property bool shown: true
property bool menuBarShown: true
readonly property bool isSmallSize: width < Kirigami.Units.gridUnit * 34
readonly property int buttonSize: isSmallSize ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
position: ToolBar.Header
state: shown ? "visible" : "hidden"
RowLayout {
width: parent.width
spacing: Kirigami.Units.mediumSpacing
HamburgerMenu {
actions: root.actions
mpv: root.mpv
visible: !root.menuBarShown
focusPolicy: Qt.TabFocus
icon.width: root.buttonSize
icon.height: root.buttonSize
}
ToolButton {
action: root.actions.openFile
focusPolicy: Qt.TabFocus
icon.width: root.buttonSize
icon.height: root.buttonSize
display: root.isSmallSize ? AbstractButton.IconOnly : AbstractButton.TextBesideIcon
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
}
ToolButton {
action: root.actions.openUrl
focusPolicy: Qt.TabFocus
icon.width: root.buttonSize
icon.height: root.buttonSize
display: root.isSmallSize ? AbstractButton.IconOnly : AbstractButton.TextBesideIcon
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
}
ToolSeparator {}
ToolButton {
id: subtitleButton
text: KI18n.i18nc("@action:intoolbar", "Subtitles")
icon.name: "add-subtitle"
icon.width: root.buttonSize
icon.height: root.buttonSize
focusPolicy: Qt.TabFocus
enabled: root.mpv.fileLoaded
opacity: enabled ? 1.0 : 0.6
display: root.isSmallSize ? AbstractButton.IconOnly : AbstractButton.TextBesideIcon
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
Accessible.role: Accessible.ButtonMenu
down: subtitleMenu.visible
onPressed: subtitleMenu.open()
SubtitleTracksMenu {
id: subtitleMenu
mpv: root.mpv
isPrimary: true
y: parent.height
modal: true
dim: false
// The track list is empty for files without subtitles, but a file can
// still be added.
enabled: true
MenuSeparator {}
AppMenuItem { action: root.actions.translateSubtitle }
AppMenuItem { action: root.actions.addSubtitle }
}
}
ToolButton {
text: KI18n.i18nc("@action:intoolbar", "Audio")
icon.name: "audio-volume-high"
icon.width: root.buttonSize
icon.height: root.buttonSize
focusPolicy: Qt.TabFocus
enabled: root.mpv.audioTracks.length > 0
opacity: enabled ? 1.0 : 0.6
display: root.isSmallSize ? AbstractButton.IconOnly : AbstractButton.TextBesideIcon
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
Accessible.role: Accessible.ButtonMenu
down: audioMenu.visible
onPressed: audioMenu.open()
AudioTracksMenu {
id: audioMenu
mpv: root.mpv
y: parent.height
modal: true
dim: false
}
}
// Translation progress, with a way to stop it.
RowLayout {
visible: root.translator.busy
spacing: Kirigami.Units.smallSpacing
Layout.leftMargin: Kirigami.Units.largeSpacing
Kirigami.Icon {
source: "translate"
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
}
ProgressBar {
from: 0
to: 1
value: root.translator.progress
indeterminate: root.translator.progress === 0
Layout.preferredWidth: Kirigami.Units.gridUnit * 6
}
Label {
text: root.translator.statusText
elide: Text.ElideRight
visible: !root.isSmallSize
Layout.maximumWidth: Kirigami.Units.gridUnit * 14
}
ToolButton {
action: root.actions.cancelTranslation
display: AbstractButton.IconOnly
focusPolicy: Qt.TabFocus
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
}
}
Item {
Layout.fillWidth: true
}
ToolButton {
action: root.actions.configure
focusPolicy: Qt.TabFocus
icon.width: root.buttonSize
icon.height: root.buttonSize
display: root.isSmallSize ? AbstractButton.IconOnly : AbstractButton.TextBesideIcon
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
}
}
states: [
State {
name: "hidden"
PropertyChanges {
root.height: 0
root.opacity: 0
root.visible: false
}
},
State {
name: "visible"
PropertyChanges {
root.height: root.implicitHeight
root.opacity: 1
root.visible: true
}
}
]
transitions: [
Transition {
from: "visible"
to: "hidden"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
target: root
property: "opacity"
duration: Kirigami.Units.veryShortDuration
easing.type: Easing.Linear
}
NumberAnimation {
target: root
property: "height"
duration: Kirigami.Units.veryShortDuration
easing.type: Easing.Linear
}
}
PropertyAction {
target: root
property: "visible"
value: false
}
}
},
Transition {
from: "hidden"
to: "visible"
SequentialAnimation {
PropertyAction {
target: root
property: "visible"
value: true
}
ParallelAnimation {
NumberAnimation {
target: root
property: "height"
duration: Kirigami.Units.veryShortDuration
easing.type: Easing.Linear
}
NumberAnimation {
target: root
property: "opacity"
duration: Kirigami.Units.veryShortDuration
easing.type: Easing.Linear
}
}
}
}
]
}