forked from Shinonome/dots-hyprland
refractor secondary tab bar
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.models
|
||||||
|
|
||||||
|
TabBar {
|
||||||
|
id: root
|
||||||
|
property real indicatorPadding: 8
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
WheelHandler {
|
||||||
|
onWheel: (event) => {
|
||||||
|
if (event.angleDelta.y < 0) root.incrementCurrentIndex();
|
||||||
|
else if (event.angleDelta.y > 0) root.decrementCurrentIndex();
|
||||||
|
}
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: activeIndicator
|
||||||
|
z: 9999
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
topLeftRadius: height
|
||||||
|
topRightRadius: height
|
||||||
|
bottomLeftRadius: 0
|
||||||
|
bottomRightRadius: 0
|
||||||
|
color: Appearance.colors.colPrimary
|
||||||
|
// Animation
|
||||||
|
property real baseWidth: root.width / root.count
|
||||||
|
AnimatedTabIndexPair {
|
||||||
|
id: idxPair
|
||||||
|
index: root.currentIndex
|
||||||
|
}
|
||||||
|
height: 3
|
||||||
|
x: Math.min(idxPair.idx1, idxPair.idx2) * baseWidth + root.indicatorPadding
|
||||||
|
width: ((Math.max(idxPair.idx1, idxPair.idx2) + 1) * baseWidth - root.indicatorPadding) - x
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { // Tabbar bottom border
|
||||||
|
id: tabBarBottomBorder
|
||||||
|
z: 9998
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: 1
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
color: Appearance.colors.colOutlineVariant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
|
||||||
import qs.modules.common.functions
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.common.widgets
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
@@ -10,14 +10,12 @@ TabButton {
|
|||||||
id: root
|
id: root
|
||||||
property string buttonText
|
property string buttonText
|
||||||
property string buttonIcon
|
property string buttonIcon
|
||||||
property bool selected: false
|
|
||||||
property int rippleDuration: 1200
|
property int rippleDuration: 1200
|
||||||
height: buttonBackground.height
|
|
||||||
property int tabContentWidth: buttonBackground.width - buttonBackground.radius*2
|
property int tabContentWidth: buttonBackground.width - buttonBackground.radius*2
|
||||||
|
|
||||||
property color colBackground: ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
property color colBackground: ColorUtils.transparentize(Appearance.colors.colSurfaceContainer)
|
||||||
property color colBackgroundHover: Appearance.colors.colLayer1Hover
|
property color colBackgroundHover: ColorUtils.transparentize(Appearance.colors.colOnSurface, root.checked ? 1 : 0.95)
|
||||||
property color colRipple: Appearance.colors.colLayer1Active
|
property color colRipple: ColorUtils.transparentize(Appearance.colors.colOnSurface, 0.95)
|
||||||
|
|
||||||
PointingHandInteraction {}
|
PointingHandInteraction {}
|
||||||
|
|
||||||
@@ -91,8 +89,12 @@ TabButton {
|
|||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: buttonBackground
|
id: buttonBackground
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: 3
|
||||||
|
}
|
||||||
radius: Appearance?.rounding.normal
|
radius: Appearance?.rounding.normal
|
||||||
implicitHeight: 37
|
implicitHeight: 42
|
||||||
color: (root.hovered ? root.colBackgroundHover : root.colBackground)
|
color: (root.hovered ? root.colBackgroundHover : root.colBackground)
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: OpacityMask {
|
layer.effect: OpacityMask {
|
||||||
@@ -156,8 +158,8 @@ TabButton {
|
|||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
text: buttonIcon
|
text: buttonIcon
|
||||||
iconSize: Appearance.font.pixelSize.huge
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
fill: selected ? 1 : 0
|
fill: root.checked ? 1 : 0
|
||||||
color: selected ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1
|
color: root.checked ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||||
}
|
}
|
||||||
@@ -167,7 +169,7 @@ TabButton {
|
|||||||
id: buttonTextWidget
|
id: buttonTextWidget
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.pixelSize: Appearance.font.pixelSize.small
|
font.pixelSize: Appearance.font.pixelSize.small
|
||||||
color: selected ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1
|
color: root.checked ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1
|
||||||
text: buttonText
|
text: buttonText
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import QtQuick.Layouts
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property int currentTab: 0
|
|
||||||
property var tabButtonList: [
|
property var tabButtonList: [
|
||||||
{"name": Translation.tr("Pomodoro"), "icon": "search_activity"},
|
{"name": Translation.tr("Pomodoro"), "icon": "search_activity"},
|
||||||
{"name": Translation.tr("Stopwatch"), "icon": "timer"}
|
{"name": Translation.tr("Stopwatch"), "icon": "timer"}
|
||||||
@@ -17,20 +16,20 @@ Item {
|
|||||||
Keys.onPressed: (event) => {
|
Keys.onPressed: (event) => {
|
||||||
if ((event.key === Qt.Key_PageDown || event.key === Qt.Key_PageUp) && event.modifiers === Qt.NoModifier) { // Switch tabs
|
if ((event.key === Qt.Key_PageDown || event.key === Qt.Key_PageUp) && event.modifiers === Qt.NoModifier) { // Switch tabs
|
||||||
if (event.key === Qt.Key_PageDown) {
|
if (event.key === Qt.Key_PageDown) {
|
||||||
currentTab = Math.min(currentTab + 1, root.tabButtonList.length - 1)
|
tabBar.incrementCurrentIndex();
|
||||||
} else if (event.key === Qt.Key_PageUp) {
|
} else if (event.key === Qt.Key_PageUp) {
|
||||||
currentTab = Math.max(currentTab - 1, 0)
|
tabBar.decrementCurrentIndex();
|
||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key === Qt.Key_Space || event.key === Qt.Key_S) { // Pause/resume with Space or S
|
} else if (event.key === Qt.Key_Space || event.key === Qt.Key_S) { // Pause/resume with Space or S
|
||||||
if (currentTab === 0) {
|
if (tabBar.currentIndex === 0) {
|
||||||
TimerService.togglePomodoro()
|
TimerService.togglePomodoro()
|
||||||
} else {
|
} else {
|
||||||
TimerService.toggleStopwatch()
|
TimerService.toggleStopwatch()
|
||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key === Qt.Key_R) { // Reset with R
|
} else if (event.key === Qt.Key_R) { // Reset with R
|
||||||
if (currentTab === 0) {
|
if (tabBar.currentIndex === 0) {
|
||||||
TimerService.resetPomodoro()
|
TimerService.resetPomodoro()
|
||||||
} else {
|
} else {
|
||||||
TimerService.stopwatchReset()
|
TimerService.stopwatchReset()
|
||||||
@@ -46,82 +45,19 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
TabBar {
|
SecondaryTabBar {
|
||||||
id: tabBar
|
id: tabBar
|
||||||
Layout.fillWidth: true
|
currentIndex: swipeView.currentIndex
|
||||||
currentIndex: currentTab
|
|
||||||
onCurrentIndexChanged: currentTab = currentIndex
|
|
||||||
|
|
||||||
background: Item {
|
|
||||||
WheelHandler {
|
|
||||||
onWheel: (event) => {
|
|
||||||
if (event.angleDelta.y < 0)
|
|
||||||
tabBar.currentIndex = Math.min(tabBar.currentIndex + 1, root.tabButtonList.length - 1)
|
|
||||||
else if (event.angleDelta.y > 0)
|
|
||||||
tabBar.currentIndex = Math.max(tabBar.currentIndex - 1, 0)
|
|
||||||
}
|
|
||||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.tabButtonList
|
model: root.tabButtonList
|
||||||
delegate: SecondaryTabButton {
|
delegate: SecondaryTabButton {
|
||||||
selected: (index == currentTab)
|
|
||||||
buttonText: modelData.name
|
buttonText: modelData.name
|
||||||
buttonIcon: modelData.icon
|
buttonIcon: modelData.icon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { // Tab indicator
|
|
||||||
id: tabIndicator
|
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 3
|
|
||||||
property bool enableIndicatorAnimation: false
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onCurrentTabChanged() {
|
|
||||||
tabIndicator.enableIndicatorAnimation = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: indicator
|
|
||||||
property int tabCount: root.tabButtonList.length
|
|
||||||
property real fullTabSize: root.width / tabCount;
|
|
||||||
property real targetWidth: tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth
|
|
||||||
|
|
||||||
implicitWidth: targetWidth
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
x: tabBar.currentIndex * fullTabSize + (fullTabSize - targetWidth) / 2
|
|
||||||
|
|
||||||
color: Appearance.colors.colPrimary
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
|
|
||||||
Behavior on x {
|
|
||||||
enabled: tabIndicator.enableIndicatorAnimation
|
|
||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
|
||||||
enabled: tabIndicator.enableIndicatorAnimation
|
|
||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle { // Tabbar bottom border
|
|
||||||
id: tabBarBottomBorder
|
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 1
|
|
||||||
color: Appearance.colors.colOutlineVariant
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeView {
|
SwipeView {
|
||||||
id: swipeView
|
id: swipeView
|
||||||
Layout.topMargin: 10
|
Layout.topMargin: 10
|
||||||
@@ -129,11 +65,7 @@ Item {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
spacing: 10
|
spacing: 10
|
||||||
clip: true
|
clip: true
|
||||||
currentIndex: currentTab
|
currentIndex: tabBar.currentIndex
|
||||||
onCurrentIndexChanged: {
|
|
||||||
tabIndicator.enableIndicatorAnimation = true
|
|
||||||
currentTab = currentIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tabs
|
// Tabs
|
||||||
PomodoroTimer {}
|
PomodoroTimer {}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import QtQuick.Layouts
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property int currentTab: 0
|
|
||||||
property var tabButtonList: [{"icon": "checklist", "name": Translation.tr("Unfinished")}, {"name": Translation.tr("Done"), "icon": "check_circle"}]
|
property var tabButtonList: [{"icon": "checklist", "name": Translation.tr("Unfinished")}, {"name": Translation.tr("Done"), "icon": "check_circle"}]
|
||||||
property bool showAddDialog: false
|
property bool showAddDialog: false
|
||||||
property int dialogMargins: 20
|
property int dialogMargins: 20
|
||||||
@@ -17,9 +16,9 @@ Item {
|
|||||||
Keys.onPressed: (event) => {
|
Keys.onPressed: (event) => {
|
||||||
if ((event.key === Qt.Key_PageDown || event.key === Qt.Key_PageUp) && event.modifiers === Qt.NoModifier) {
|
if ((event.key === Qt.Key_PageDown || event.key === Qt.Key_PageUp) && event.modifiers === Qt.NoModifier) {
|
||||||
if (event.key === Qt.Key_PageDown) {
|
if (event.key === Qt.Key_PageDown) {
|
||||||
currentTab = Math.min(currentTab + 1, root.tabButtonList.length - 1)
|
tabBar.incrementCurrentIndex();
|
||||||
} else if (event.key === Qt.Key_PageUp) {
|
} else if (event.key === Qt.Key_PageUp) {
|
||||||
currentTab = Math.max(currentTab - 1, 0)
|
tabBar.decrementCurrentIndex();
|
||||||
}
|
}
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
@@ -39,82 +38,19 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
TabBar {
|
SecondaryTabBar {
|
||||||
id: tabBar
|
id: tabBar
|
||||||
Layout.fillWidth: true
|
currentIndex: swipeView.currentIndex
|
||||||
currentIndex: currentTab
|
|
||||||
onCurrentIndexChanged: currentTab = currentIndex
|
|
||||||
|
|
||||||
background: Item {
|
|
||||||
WheelHandler {
|
|
||||||
onWheel: (event) => {
|
|
||||||
if (event.angleDelta.y < 0)
|
|
||||||
tabBar.currentIndex = Math.min(tabBar.currentIndex + 1, root.tabButtonList.length - 1)
|
|
||||||
else if (event.angleDelta.y > 0)
|
|
||||||
tabBar.currentIndex = Math.max(tabBar.currentIndex - 1, 0)
|
|
||||||
}
|
|
||||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.tabButtonList
|
model: root.tabButtonList
|
||||||
delegate: SecondaryTabButton {
|
delegate: SecondaryTabButton {
|
||||||
selected: (index == currentTab)
|
|
||||||
buttonText: modelData.name
|
buttonText: modelData.name
|
||||||
buttonIcon: modelData.icon
|
buttonIcon: modelData.icon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { // Tab indicator
|
|
||||||
id: tabIndicator
|
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 3
|
|
||||||
property bool enableIndicatorAnimation: false
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onCurrentTabChanged() {
|
|
||||||
tabIndicator.enableIndicatorAnimation = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: indicator
|
|
||||||
property int tabCount: root.tabButtonList.length
|
|
||||||
property real fullTabSize: root.width / tabCount;
|
|
||||||
property real targetWidth: tabBar?.contentItem?.children[0]?.children[tabBar.currentIndex]?.tabContentWidth ?? 0
|
|
||||||
|
|
||||||
implicitWidth: targetWidth
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
x: tabBar.currentIndex * fullTabSize + (fullTabSize - targetWidth) / 2
|
|
||||||
|
|
||||||
color: Appearance.colors.colPrimary
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
|
|
||||||
Behavior on x {
|
|
||||||
enabled: tabIndicator.enableIndicatorAnimation
|
|
||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
|
||||||
enabled: tabIndicator.enableIndicatorAnimation
|
|
||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle { // Tabbar bottom border
|
|
||||||
id: tabBarBottomBorder
|
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 1
|
|
||||||
color: Appearance.colors.colOutlineVariant
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeView {
|
SwipeView {
|
||||||
id: swipeView
|
id: swipeView
|
||||||
Layout.topMargin: 10
|
Layout.topMargin: 10
|
||||||
@@ -122,11 +58,7 @@ Item {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
spacing: 10
|
spacing: 10
|
||||||
clip: true
|
clip: true
|
||||||
currentIndex: currentTab
|
currentIndex: tabBar.currentIndex
|
||||||
onCurrentIndexChanged: {
|
|
||||||
tabIndicator.enableIndicatorAnimation = true
|
|
||||||
currentTab = currentIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
// To Do tab
|
// To Do tab
|
||||||
TaskList {
|
TaskList {
|
||||||
@@ -215,7 +147,7 @@ Item {
|
|||||||
Todo.addTask(todoInput.text)
|
Todo.addTask(todoInput.text)
|
||||||
todoInput.text = ""
|
todoInput.text = ""
|
||||||
root.showAddDialog = false
|
root.showAddDialog = false
|
||||||
root.currentTab = 0 // Show unfinished tasks
|
tabBar.setCurrentIndex(0) // Show unfinished tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user