Files
work-secretfile-selfcheck/UmiOCR-data/qt_res/qml/TabBar_/HTabBar.qml

256 lines
9.1 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// =========================================
// =============== 水平标签栏 ===============
// =========================================
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import "../Widgets"
RowLayout {
id: hTabBarLayout
anchors.fill: parent
spacing: 0
// 标签栏控制(左,置顶按钮)
Item {
width: size_.hTabBarHeight
Layout.fillHeight: true
// 图钉按钮
Button {
checkable: true
checked: mainWindowRoot.isMainWindowTop
onCheckedChanged: { // 双向绑定锁定标记
mainWindowRoot.isMainWindowTop = checked
qmlapp.globalConfigs.setValue("window.isMainWindowTop", checked, true)
}
anchors.fill: parent
anchors.margins: 4
contentItem: Icon_ {
icon: "pin"
anchors.fill: parent
color: parent.checked ? theme.bgColor : theme.textColor
}
background: Rectangle {
anchors.fill: parent
radius: size_.btnRadius
color: parent.checked ? theme.coverColor4 : (
parent.hovered ? theme.coverColor2 : "#00000000"
)
}
ToolTip_ {
visible: parent.hovered
text: qsTr("窗口置顶")
}
}
}
// 标签栏本体(中)
Rectangle {
id: hTabBarMain
Layout.fillWidth: true
Layout.fillHeight: true
color: "#00000000"
property int tabWidth: 200 // 标签当前宽度
// 方法:重设标签按钮宽度
function resetTabBtnWidth() {
let w = hTabBarMain.width
if(!qmlapp.tab.barIsLock) w -= tabBarControl.width // 无锁定时,减去+按钮宽度
w = w / barManager.model.count
tabWidth = Math.min(w, size_.line * 8)
}
onWidthChanged: resetTabBtnWidth() // 监听标签栏总宽度变化
// 监听改变锁定,重设宽度
property bool isLock: qmlapp.tab.barIsLock
onIsLockChanged: {
hTabBarMain.resetTabBtnWidth()
}
MouseArea { // 点击标签栏空余位置,都是添加新标签
anchors.fill: parent
onClicked: {
if(!qmlapp.tab.barIsLock)
qmlapp.tab.addNavi() // 添加导航页
}
}
// Rectangle { // 标签按钮下方的阴影
// anchors.bottom: parent.bottom
// width: parent.width
// height: size_.hTabBarHeight * 0.5
// gradient: Gradient {
// GradientStop { position: 0.0; color: "#00000000" }
// GradientStop { position: 1.0; color: theme.coverColor2 }
// }
// }
Rectangle { // 拖拽时的位置指示器
id: dragIndicator
visible: false
width: parent.tabWidth
height: size_.hTabBarHeight
gradient: Gradient { // 水平渐变
orientation: Gradient.Horizontal
GradientStop { position: 1.0; color: "#00000000" }
GradientStop { position: 0.0; color: theme.coverColor3 }
}
}
// 水平标签栏行布局
Row {
id: hTabBarMainRow
spacing: -1 // 给负的间隔,是为了让选中标签能覆盖左右两边标签的竖线
// ===== 标签按钮组 =====
BarManager {
id: barManager
// 标签元素模板
delegate: TabButton_ {
title: title_ // 标题
checked: checked_ // 初始时是否选中
index: index_ // 初始位置
width: hTabBarMain.tabWidth
}
// 事件:创建新标签时(与父类的槽同时生效)
onItemAdded: {
// 链接表现相关的槽函数
item.dragStart.connect(dragStart)
item.dragFinish.connect(dragFinish)
item.dragMoving.connect(dragMoving)
}
// 事件:按钮数量变化
onCountChanged: hTabBarMain.resetTabBtnWidth()
// ========================= 【拖拽相关】 =========================
property var intervalList: [] // 记录按钮位置区间的列表
property var originalPosList: [] // 记录按钮初始位置的列表
property int originalX // 记录本轮拖拽前,被拖拽按钮原本的位置
function dragStart(index){ // 方法:开始拖拽
// 重新记录当前所有按钮的位置
originalX = itemAt(index).x
intervalList = [-Infinity] // 下限:负无穷
originalPosList = [itemAt(0).x]
for(let i=1, c=model.count; i < c; i++){ // 按钮位置区间
const it = itemAt(i)
intervalList.push(it.x)
originalPosList.push(it.x)
}
intervalList.push(Infinity) // 上限:负无穷
dragIndicator.visible = true
}
function btnDragIndex(index){ // 函数返回当前index应该所处的序号
const dragItem = itemAt(index)
const x = dragItem.x + Math.round(dragItem.width/2) // 被拖动按钮的中心位置
let go = 0 // 应该拖放到的位置
for(const c=intervalList.length-1; go < c; go++){
if(x >= intervalList[go] && x <= intervalList[go+1]){
break;
}
}
return go;
}
function dragMoving(index, x){ // 方法:拖拽移动
let go = btnDragIndex(index) // 应该拖放到的序号
dragIndicator.x = originalPosList[go]
}
function dragFinish(index){ // 方法:结束拖拽
dragIndicator.visible = false
let go = btnDragIndex(index) // 应该拖放到的序号
if(index !== go){ // 需要移动
// model.move(index, go, 1)
qmlapp.tab.moveTabPage(index, go)
} else { // 无需移动,则回到原位
itemAt(index).x = originalX
}
resetIndex()
}
}
// 元素:控制按钮
Rectangle{
id: tabBarControl
color: "#00000000"
width: size_.hTabBarHeight
height: size_.hTabBarHeight
visible: !qmlapp.tab.barIsLock
// 添加“+”按钮
IconButton {
anchors.fill: parent
anchors.margins: 4
icon_: "add"
color: theme.textColor
onClicked: {
qmlapp.tab.addNavi() // 添加导航页
}
}
}
// 动画
add: Transition { // 添加子项
enabled: qmlapp.enabledEffect
NumberAnimation {
properties: "opacity, scale" // 透明度和大小从小到大
from: 0; to: 1.0
easing.type: Easing.OutBack // 缓动:超出反弹
duration: 300
}
}
move: Transition { // 移动子项
enabled: qmlapp.enabledEffect
NumberAnimation {
properties: "x,y"
easing.type: Easing.OutBack
duration: 300
}
}
}
}
// 标签栏控制(右,锁定按钮)
Item{
width: size_.hTabBarHeight
Layout.fillHeight: true
// 锁定“🔒︎”按钮
Button {
checkable: true
checked: qmlapp.tab.barIsLock
onCheckedChanged: { // 双向绑定锁定标记
qmlapp.tab.barIsLock = checked
qmlapp.globalConfigs.setValue("window.barIsLock", checked, true)
}
anchors.fill: parent
anchors.margins: 4
contentItem: Icon_ {
icon: "lock"
anchors.fill: parent
color: parent.checked ? theme.bgColor : theme.textColor
}
background: Rectangle {
anchors.fill: parent
radius: size_.btnRadius
color: parent.checked ? theme.coverColor4 : (
parent.hovered ? theme.coverColor2 : "#00000000"
)
}
ToolTip_ {
visible: parent.hovered
text: qsTr("锁定标签栏")
}
}
}
}