diff --git a/src/controls/swipenavigator/PrivateSwipeTab.qml b/src/controls/swipenavigator/PrivateSwipeTab.qml index baad5e71..3e0efc05 100644 --- a/src/controls/swipenavigator/PrivateSwipeTab.qml +++ b/src/controls/swipenavigator/PrivateSwipeTab.qml @@ -1,155 +1,160 @@ /* * SPDX-FileCopyrightText: 2020 Carson Black * * SPDX-License-Identifier: LGPL-2.0-or-later */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 import org.kde.kirigami 2.12 as Kirigami Rectangle { id: tabRoot property bool small: false - signal indexChanged(real xPos) + signal indexChanged(real xPos, real tabWidth) Keys.onPressed: { if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { columnView.currentIndex = index } } activeFocusOnTab: true implicitHeight: swipeNavigatorRoot.big ? small ? Kirigami.Units.gridUnit*5 : Kirigami.Units.gridUnit*4 : small ? Kirigami.Units.gridUnit*3 : Kirigami.Units.gridUnit*2 + onActiveFocusChanged: { + if (activeFocus) { + tabRoot.indexChanged(tabRoot.x, tabRoot.width) + } + } Connections { target: columnView function onCurrentIndexChanged() { if (index == columnView.currentIndex) { - tabRoot.indexChanged(tabRoot.x) + tabRoot.indexChanged(tabRoot.x, tabRoot.width) } } } Accessible.name: modelData.title Accessible.description: { if (!!modelData.progress) { if (index == columnView.currentIndex) { return i18nc("Accessibility text for a page tab. Keep the text as concise as possible and don't use a percent sign.", "Current page. Progress: %1 percent.", Math.round(modelData.progress*100)) } else { return i18nc("Accessibility text for a page tab. Keep the text as concise as possible.", "Navigate to %1. Progress: %1 percent.", modelData.title, Math.round(modelData.progress*100)) } } else { if (index == columnView.currentIndex) { return i18nc("Accessibility text for a page tab. Keep the text as concise as possible.", "Current page.") } else if (modelData.needsAttention) { return i18nc("Accessibility text for a page tab that's requesting the user's attention. Keep the text as concise as possible.", "Navigate to %1. Demanding attention.", modelData.title) } else { return i18nc("Accessibility text for a page tab that's requesting the user's attention. Keep the text as concise as possible.", "Navigate to %1.", modelData.title) } } } Accessible.role: Accessible.PageTab Accessible.focusable: true Accessible.onPressAction: columnView.currentIndex = index implicitWidth: small ? smallTitleRow.implicitWidth : largeTitleRow.implicitWidth border { width: activeFocus ? 2 : 0 color: Kirigami.Theme.textColor } color: { if (index == columnView.currentIndex) { return Kirigami.ColorUtils.adjustColor(Kirigami.Theme.activeTextColor, {"alpha": 0.2*255}) } else if (modelData.needsAttention) { return Kirigami.ColorUtils.adjustColor(Kirigami.Theme.negativeTextColor, {"alpha": 0.2*255}) } else { return "transparent" } } PrivateSwipeHighlight { states: [ State { name: "highlighted"; when: index == columnView.currentIndex }, State { name: "requestingAttention"; when: modelData.needsAttention } ] } PrivateSwipeProgress { anchors.fill: parent visible: modelData.progress != undefined progress: modelData.progress } RowLayout { id: smallTitleRow anchors.fill: parent Accessible.ignored: true visible: small ColumnLayout { Layout.margins: Kirigami.Settings.isMobile ? Kirigami.Units.smallSpacing : Kirigami.Units.largeSpacing Layout.alignment: Qt.AlignVCenter Kirigami.Icon { visible: !!modelData.icon.name source: modelData.icon.name Layout.preferredHeight: swipeNavigatorRoot.big ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.small Layout.preferredWidth: Layout.preferredHeight Layout.alignment: (Qt.AlignHCenter | Qt.AlignBottom) } Kirigami.Heading { level: swipeNavigatorRoot.big ? 2 : 5 text: modelData.title Layout.fillWidth: true Layout.alignment: (Qt.AlignLeft | Qt.AlignVCenter) } } } RowLayout { id: largeTitleRow anchors.fill: parent Accessible.ignored: true visible: !small RowLayout { Layout.margins: swipeNavigatorRoot.big ? Kirigami.Units.largeSpacing*2 : Kirigami.Units.largeSpacing Layout.alignment: Qt.AlignVCenter Kirigami.Icon { visible: !!modelData.icon.name source: modelData.icon.name Layout.preferredHeight: swipeNavigatorRoot.big ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.small Layout.preferredWidth: Layout.preferredHeight Layout.alignment: (Qt.AlignLeft | Qt.AlignVCenter) } Kirigami.Heading { level: swipeNavigatorRoot.big ? 1 : 2 text: modelData.title Layout.fillWidth: true Layout.alignment: (Qt.AlignLeft | Qt.AlignVCenter) } } } MouseArea { id: mouse anchors.fill: parent Accessible.ignored: true onClicked: { columnView.currentIndex = index } } Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter } \ No newline at end of file diff --git a/src/controls/swipenavigator/PrivateSwipeTabBar.qml b/src/controls/swipenavigator/PrivateSwipeTabBar.qml index 7da60637..bd05d9b0 100644 --- a/src/controls/swipenavigator/PrivateSwipeTabBar.qml +++ b/src/controls/swipenavigator/PrivateSwipeTabBar.qml @@ -1,36 +1,36 @@ /* * SPDX-FileCopyrightText: 2020 Carson Black * * SPDX-License-Identifier: LGPL-2.0-or-later */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 import org.kde.kirigami 2.12 as Kirigami RowLayout { id: swipeTabBarRoot spacing: 0 - signal indexChanged(real xPos) + signal indexChanged(real xPos, real tabWidth) property Item layouter: Item { Row { id: expandedLayouter Repeater { model: swipeNavigatorRoot.pages delegate: PrivateSwipeTab { small: false } } } } Repeater { model: swipeNavigatorRoot.pages delegate: PrivateSwipeTab { Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter small: expandedLayouter.width > swipeNavigatorRoot.width - onIndexChanged: swipeTabBarRoot.indexChanged(xPos) + onIndexChanged: swipeTabBarRoot.indexChanged(xPos, tabWidth) } } } diff --git a/src/controls/swipenavigator/PrivateSwipeTabBarLoader.qml b/src/controls/swipenavigator/PrivateSwipeTabBarLoader.qml index 183e383b..6a57c507 100644 --- a/src/controls/swipenavigator/PrivateSwipeTabBarLoader.qml +++ b/src/controls/swipenavigator/PrivateSwipeTabBarLoader.qml @@ -1,36 +1,62 @@ /* * SPDX-FileCopyrightText: 2020 Carson Black * * SPDX-License-Identifier: LGPL-2.0-or-later */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 import org.kde.kirigami 2.12 as Kirigami Loader { id: __loader readonly property bool shouldScroll: shrunkLayouter.width > swipeNavigatorRoot.width property Item layouter: Item { Row { id: shrunkLayouter Repeater { model: swipeNavigatorRoot.pages delegate: PrivateSwipeTab { small: true } } } } Component { id: nonScrollable PrivateSwipeTabBar {} } Component { id: scrollable ScrollView { + id: view ScrollBar.horizontal.visible: false - PrivateSwipeTabBar {} + Timer { + interval: 5000 + running: true + repeat: true + } + PrivateSwipeTabBar { + id: bar + property real targetDestination + NumberAnimation { + id: scrollAni + target: view.ScrollBar.horizontal + property: "position" + to: bar.targetDestination + duration: Kirigami.Units.smallDuration + easing.type: Easing.OutExpo + } + onIndexChanged: { + if (xPos > (bar.width)/2) { + bar.targetDestination = (1-view.ScrollBar.horizontal.size) * ((xPos+tabWidth) / bar.width) + scrollAni.restart() + } else { + bar.targetDestination = (1-view.ScrollBar.horizontal.size) * ((xPos) / bar.width) + scrollAni.restart() + } + } + } } } sourceComponent: shouldScroll ? scrollable : nonScrollable } \ No newline at end of file