yxdy ff15075c79
Some checks are pending
Gallery App Build / macOS (push) Waiting to run
Gallery App Build / Windows (push) Waiting to run
Gallery App Build / Ubuntu (push) Waiting to run
修改样式
2025-03-07 16:23:09 +08:00

287 lines
10 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI.Controls
import FluentUI.impl
Item {
FluentUI.theme: Theme.of(control)
property int tabWidthBehavior : TabViewType.Equal
property int closeButtonVisibility : TabViewType.Always
property int itemWidth: 146
property bool addButtonVisibility: true
property var parentD;
signal newPressed
signal closeTabed(var item)
signal closeTabOk()
signal clickNav(var item)
id:control
implicitHeight: height
implicitWidth: width
anchors.fill: {
if(parent)
return parent
return undefined
}
QtObject {
id: d
property int dragIndex: -1
property bool dragBehavior: false
property bool itemPress: false
property int maxEqualWidth: 240
}
MouseArea{
anchors.fill: parent
preventStealing: true
}
ListModel{
id:tab_model
}
IconButton{
id:btn_new
visible: addButtonVisibility
width: 34
height: 34
x:Math.min(tab_nav.contentWidth,tab_nav.width)
anchors.top: parent.top
icon.name: FluentIcons.graph_Add
icon.width: 14
icon.height: 14
onClicked: {
newPressed()
}
}
ListView{
id:tab_nav
height: 34
orientation: ListView.Horizontal
anchors{
top: parent.top
left: parent.left
right: parent.right
rightMargin: 34
}
interactive: false
model: tab_model
move: Transition {
NumberAnimation { properties: "x"; duration: 100; easing.type: Easing.OutCubic }
NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic }
}
moveDisplaced: Transition {
NumberAnimation { properties: "x"; duration: 300; easing.type: Easing.OutCubic}
NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic }
}
clip: true
ScrollBar.horizontal: ScrollBar{
id: scroll_nav
policy: ScrollBar.AlwaysOff
}
delegate: Item{
width: item_container.width
height: item_container.height
DropArea{
anchors.fill: parent
onEntered:
(drag)=>{
tab_model.move(drag.source.visualIndex, item_container.visualIndex,1)
}
}
Control{
id:item_container
property int visualIndex: model.index
readonly property bool isCurrent: model.index === tab_nav.currentIndex
readonly property bool isNext: model.index-1 === tab_nav.currentIndex
readonly property bool isPrevious: model.index+1 === tab_nav.currentIndex
height: tab_nav.height
Drag.active: mouse_tab_item.drag.active
Drag.source: item_container
Drag.hotSpot.x: width/2
width: {
if(tabWidthBehavior === TabViewType.Equal){
return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width)
}
if(tabWidthBehavior === TabViewType.SizeToContent){
return itemWidth
}
if(tabWidthBehavior === TabViewType.Compact){
return hover_handler.hovered || item_btn_close.hovered || tab_nav.currentIndex === index ? itemWidth : 41 + item_btn_close.width
}
return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width)
}
states: [
State {
when: mouse_tab_item.drag.active
ParentChange {
target: item_container
parent: tab_nav
}
AnchorChanges {
target: item_container
anchors {
horizontalCenter: undefined
verticalCenter: undefined
}
}
}
]
MouseArea {
id: mouse_tab_item
anchors.fill: parent
drag.target: item_container
drag.axis: Drag.XAxis
onClicked: {
tab_nav.currentIndex = model.index
clickNav(model)
}
}
Rectangle{
width: parent.width - 5
height: parent.height
radius: 6
color: Theme.uncheckedInputColor(item_container,true,true,control.FluentUI.dark)
}
// TabBackgroundImpl{
// width: item_container.width + 6*2
// height: item_container.height
// x: -6
// visible: item_container.isCurrent
// radius: 6
// color: control.FluentUI.theme.res.solidBackgroundFillColorQuarternary
// strokeColor: control.FluentUI.theme.res.dividerStrokeColorDefault
// }
Rectangle{
radius: 6
width: item_container.width - 5
height: item_container.height
visible: true//item_container.isCurrent
color: item_container.isCurrent ? Qt.rgba(0/255,0/255,0/255, 0.5) : Qt.rgba(255/255,255/255,255/255, 0.05)
}
RowLayout{
spacing: 0
height: parent.height
Image{
source: model.icon
Layout.leftMargin: 10
Layout.preferredWidth: 15
Layout.preferredHeight: 15
Layout.alignment: Qt.AlignVCenter
}
Label{
id:item_text
text: model.text
Layout.leftMargin: 10
visible: {
if(tabWidthBehavior === TabViewType.Equal){
return true
}
if(tabWidthBehavior === TabViewType.SizeToContent){
return true
}
if(tabWidthBehavior === TabViewType.Compact){
return hover_handler.hovered || item_btn_close.hovered || tab_nav.currentIndex === index
}
return false
}
Layout.preferredWidth: visible?item_container.width - 41 - item_btn_close.width:0
elide: Text.ElideRight
Layout.alignment: Qt.AlignVCenter
}
}
IconButton{
id:item_btn_close
icon.name: FluentIcons.graph_ChromeClose
icon.width: 10
icon.height: 10
width: visible ? 24 : 0
height: 24
visible: {
if(closeButtonVisibility === TabViewType.Never)
return false
if(closeButtonVisibility === TabViewType.OnHover)
return hover_handler.hovered || item_btn_close.hovered
return true
}
anchors{
right: parent.right
rightMargin: 10
verticalCenter: parent.verticalCenter
}
onClicked: {
closeTabed(model)
tab_model.remove(index)
closeTabOk()
}
}
// Rectangle{
// width: 1
// height: 16
// anchors{
// verticalCenter: parent.verticalCenter
// right: parent.right
// }
// visible: !item_container.isCurrent && !item_container.isPrevious
// color: control.FluentUI.theme.res.dividerStrokeColorDefault
// }
HoverHandler{
id: hover_handler
}
}
Component.onCompleted: {
parentD.setHitTestVisible(this)
}
}
WheelHandler{
onWheel:
(wheel)=>{
if (wheel.angleDelta.y > 0) scroll_nav.decrease()
else scroll_nav.increase()
}
}
}
//
Item{
id:container
anchors{
top: tab_nav.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
Repeater{
model:tab_model
AutoLoader{
property var argument: model.argument
anchors.fill: parent
sourceComponent: model.page
visible: tab_nav.currentIndex === index
}
}
}
function createTab(icon,text,page,argument={}){
return {icon:icon,text:text,page:page,argument:argument}
}
function appendTab(icon,text,page,argument){
tab_model.append(createTab(icon,text,page,argument))
}
function setTabList(list){
tab_model.clear()
tab_model.append(list)
}
function count(){
return tab_nav.count
}
function choose(index) {
tab_nav.currentIndex = index
}
function get_cur_tab() {
return tab_model.get(tab_nav.currentIndex)
}
function get_list() {
return tab_nav
}
}