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

256 lines
9.1 KiB
QML
Raw Normal View History

// =========================================
// =============== 水平标签栏 ===============
// =========================================
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("锁定标签栏")
}
}
}
}