main
朱子楚\zhuzi 2023-03-27 22:58:33 +08:00
parent 3a32d66d6a
commit f0f58ca2dd
2 changed files with 113 additions and 25 deletions

View File

@ -8,6 +8,20 @@ FluScrollablePage{
title:"TabView" title:"TabView"
Component{
id:com_page
Rectangle{
anchors.fill: parent
color: argument
}
}
Component.onCompleted: {
var colors = [FluColors.Yellow,FluColors.Orange,FluColors.Red,FluColors.Magenta,FluColors.Purple,FluColors.Blue,FluColors.Teal,FluColors.Green]
for(var i =0;i<colors.length;i++){
tab_view.appendTab("","Document "+i,com_page,colors[i].dark)
}
}
FluArea{ FluArea{
width: parent.width width: parent.width
@ -17,7 +31,7 @@ FluScrollablePage{
FluTabView{ FluTabView{
id:tab_view
} }

View File

@ -28,28 +28,17 @@ Item {
property int tabWidthBehavior : FluTabView.Equal property int tabWidthBehavior : FluTabView.Equal
property int closeButtonVisibility : FluTabView.Always property int closeButtonVisibility : FluTabView.Always
property int itemWidth: 146
QtObject { QtObject {
id: d id: d
property int dragIndex: -1 property int dragIndex: -1
property bool dragBehavior: false property bool dragBehavior: false
property bool itemPress: false
} }
ListModel{ ListModel{
id:tab_model id:tab_model
ListElement{
icon:""
text:"Document0"
}
ListElement{
icon:""
text:"Document1"
}
ListElement{
icon:""
text:"Document2"
}
} }
ListView{ ListView{
@ -57,6 +46,8 @@ Item {
height: 34 height: 34
orientation: ListView.Horizontal orientation: ListView.Horizontal
width: parent.width width: parent.width
interactive: false
boundsBehavior: ListView.StopAtBounds
model: tab_model model: tab_model
move: Transition { move: Transition {
NumberAnimation { properties: "x"; duration: 100; easing.type: Easing.OutCubic } NumberAnimation { properties: "x"; duration: 100; easing.type: Easing.OutCubic }
@ -66,16 +57,20 @@ Item {
NumberAnimation { properties: "x"; duration: 300; easing.type: Easing.OutCubic} NumberAnimation { properties: "x"; duration: 300; easing.type: Easing.OutCubic}
NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic } NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic }
} }
clip: true clip: false
ScrollBar.horizontal: ScrollBar{
id: scroll_nav
policy: ScrollBar.AlwaysOff
}
delegate: Item{ delegate: Item{
width: item_container.width width: itemWidth
height: item_container.height height: item_container.height
z: item_mouse_drag.pressed ? 1000 : 1 z: item_mouse_drag.pressed ? 1000 : 1
Item{ Item{
id:item_layout id:item_layout
width: item_container.width width: itemWidth
height: item_container.height height: item_container.height
FluItem{ FluItem{
@ -84,7 +79,7 @@ Item {
property real timestamp: new Date().getTime() property real timestamp: new Date().getTime()
height: tab_nav.height height: tab_nav.height
width: item_text.width+30 width: itemWidth
radius: [5,5,0,0] radius: [5,5,0,0]
Behavior on x { enabled: d.dragBehavior; NumberAnimation { duration: 200 } } Behavior on x { enabled: d.dragBehavior; NumberAnimation { duration: 200 } }
Behavior on y { enabled: d.dragBehavior; NumberAnimation { duration: 200 } } Behavior on y { enabled: d.dragBehavior; NumberAnimation { duration: 200 } }
@ -101,7 +96,13 @@ Item {
drag.target: item_container drag.target: item_container
drag.axis: Drag.XAxis drag.axis: Drag.XAxis
onWheel: {
if (wheel.angleDelta.y > 0) scroll_nav.decrease()
else scroll_nav.increase()
}
onPressed: { onPressed: {
d.itemPress = true
item_container.timestamp = new Date().getTime(); item_container.timestamp = new Date().getTime();
d.dragBehavior = false; d.dragBehavior = false;
var pos = tab_nav.mapFromItem(item_container, 0, 0) var pos = tab_nav.mapFromItem(item_container, 0, 0)
@ -112,9 +113,10 @@ Item {
} }
onReleased: { onReleased: {
d.itemPress = false
timer.stop()
var timeDiff = new Date().getTime() - item_container.timestamp var timeDiff = new Date().getTime() - item_container.timestamp
console.debug(timeDiff) if (timeDiff < 300) {
if (timeDiff < 150) {
tab_nav.currentIndex = index tab_nav.currentIndex = index
} }
d.dragIndex = -1; d.dragIndex = -1;
@ -128,9 +130,41 @@ Item {
} }
onPositionChanged: { onPositionChanged: {
var pos = tab_nav.mapFromItem(item_container, 0, 0); var pos = tab_nav.mapFromItem(item_container, 0, 0)
var idx = tab_nav.indexAt(pos.x, pos.y); updatePosition(pos)
if (idx > -1 && idx < tab_nav.count) { if(pos.x<0){
timer.isIncrease = false
timer.restart()
}else if(pos.x>tab_nav.width-itemWidth){
timer.isIncrease = true
timer.restart()
}
}
Timer{
id:timer
property bool isIncrease: true
interval: 10
repeat: true
onTriggered: {
if(isIncrease){
if(tab_nav.contentX>=tab_nav.contentWidth-tab_nav.width){
return
}
tab_nav.contentX = tab_nav.contentX+1
}else{
if(tab_nav.contentX<=0){
return
}
tab_nav.contentX = tab_nav.contentX-1
}
item_mouse_drag.updatePosition(tab_nav.mapFromItem(item_container, 0, 0))
}
}
function updatePosition(pos){
var idx = tab_nav.indexAt(pos.x+tab_nav.contentX, pos.y)
var firstIdx = tab_nav.indexAt(tab_nav.contentX+1, pos.y)
var lastIdx = tab_nav.indexAt(tab_nav.width+tab_nav.contentX-1, pos.y)
if (idx >= firstIdx && idx <= lastIdx && d.dragIndex !== idx) {
tab_model.move(d.dragIndex, idx, 1) tab_model.move(d.dragIndex, idx, 1)
d.dragIndex = idx; d.dragIndex = idx;
} }
@ -141,7 +175,7 @@ Item {
anchors.fill: parent anchors.fill: parent
color: { color: {
if(FluTheme.isDark){ if(FluTheme.isDark){
if(item_mouse_hove.containsMouse){ if(item_mouse_hove.containsMouse || item_btn_close.hovered){
return Qt.rgba(1,1,1,0.03) return Qt.rgba(1,1,1,0.03)
} }
if(tab_nav.currentIndex === index){ if(tab_nav.currentIndex === index){
@ -149,7 +183,7 @@ Item {
} }
return Qt.rgba(0,0,0,0) return Qt.rgba(0,0,0,0)
}else{ }else{
if(item_mouse_hove.containsMouse){ if(item_mouse_hove.containsMouse || item_btn_close.hovered){
return Qt.rgba(0,0,0,0.03) return Qt.rgba(0,0,0,0.03)
} }
if(tab_nav.currentIndex === index){ if(tab_nav.currentIndex === index){
@ -168,6 +202,7 @@ Item {
} }
FluIconButton{ FluIconButton{
id:item_btn_close
iconSource: FluentIcons.ChromeClose iconSource: FluentIcons.ChromeClose
iconSize: 10 iconSize: 10
width: 24 width: 24
@ -177,9 +212,48 @@ Item {
rightMargin: 5 rightMargin: 5
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
onClicked: {
tab_model.remove(index)
}
} }
} }
} }
} }
} }
Item{
id:container
anchors{
top: tab_nav.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
Repeater{
model:tab_model
Loader{
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)
}
} }