This commit is contained in:
朱子楚\zhuzi 2023-07-04 22:38:56 +08:00
parent e625b91b08
commit 887fd2c02b
12 changed files with 329 additions and 138 deletions

View File

@ -7,7 +7,7 @@ import FluentUI
FluScrollablePage{ FluScrollablePage{
pageMode: FluNavigationView.SingleTask launchMode: FluPage.SingleTask
animDisabled: true animDisabled: true
ListModel{ ListModel{

View File

@ -6,7 +6,7 @@ import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
FluPage{ FluPage{
pageMode: FluNavigationView.SingleTop launchMode: FluPage.SingleTop
FluRemoteLoader{ FluRemoteLoader{
anchors.fill: parent anchors.fill: parent
source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml" source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml"

View File

@ -7,7 +7,7 @@ import "qrc:///example/qml/component"
FluScrollablePage{ FluScrollablePage{
pageMode: FluNavigationView.SingleInstance launchMode: FluPage.SingleInstance
title:"TextBox" title:"TextBox"
FluArea{ FluArea{

View File

@ -0,0 +1,142 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
import "qrc:///example/qml/component"
Item {
ColumnLayout{
anchors{
top: parent.top
left: parent.left
right: parent.right
}
RowLayout{
Layout.topMargin: 20
Layout.leftMargin: 15
spacing: 14
FluText{
text:"FluentUI"
font: FluTextStyle.Title
MouseArea{
anchors.fill: parent
onClicked: {
FluApp.navigate("/")
}
}
}
FluText{
text:"v%1".arg(appInfo.version)
font: FluTextStyle.Body
Layout.alignment: Qt.AlignBottom
}
}
RowLayout{
spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15
FluText{
text:"作者:"
}
FluText{
text:"朱子楚"
Layout.alignment: Qt.AlignBottom
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
FluText{
text:"GitHub"
}
FluTextButton{
id:text_hublink
topPadding:0
bottomPadding:0
text:"https://github.com/zhuzichu520/FluentUI"
Layout.alignment: Qt.AlignBottom
onClicked: {
Qt.openUrlExternally(text_hublink.text)
}
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
FluText{
text:"B站"
}
FluTextButton{
topPadding:0
bottomPadding:0
text:"https://www.bilibili.com/video/BV1mg4y1M71w/"
Layout.alignment: Qt.AlignBottom
onClicked: {
Qt.openUrlExternally(text)
}
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
FluText{
id:text_info
text:"如果该项目对你有作用就请点击上方链接给一个免费的star或者一键三连谢谢"
ColorAnimation {
id: animation
target: text_info
property: "color"
from: "red"
to: "blue"
duration: 1000
running: true
loops: Animation.Infinite
easing.type: Easing.InOutQuad
}
}
}
RowLayout{
spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15
FluText{
text:"捐赠:"
}
}
Item{
Layout.preferredWidth: parent.width
Layout.preferredHeight: 252
Row{
anchors.horizontalCenter: parent.horizontalCenter
spacing: 30
Image{
width: 250
height: 250
source: "qrc:/example/res/image/qrcode_wx.jpg"
}
Image{
width: 250
height: 250
source: "qrc:/example/res/image/qrcode_zfb.jpg"
}
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
Layout.topMargin: 20
FluText{
id:text_desc
text:"个人开发,维护不易,你们的捐赠就是我继续更新的动力!\n有什么问题提Issues只要时间充足我就会解决的"
}
}
}
}

View File

@ -168,6 +168,7 @@ CustomWindow {
width: parent.width width: parent.width
height: parent.height height: parent.height
z:999 z:999
// pageMode: FluNavigationView.NoStack
items: ItemsOriginal items: ItemsOriginal
footerItems:ItemsFooter footerItems:ItemsFooter
topPadding:FluTools.isMacos() ? 20 : 5 topPadding:FluTools.isMacos() ? 20 : 5

View File

@ -12,21 +12,19 @@ Item {
Minimal = 2, Minimal = 2,
Auto = 3 Auto = 3
} }
enum PageModeFlag{ enum PageMode {
Standard = 0, Stack = 0,
SingleTask = 1, NoStack = 1
SingleTop = 2,
SingleInstance = 3
} }
property url logo property url logo
property string title: "" property string title: ""
property FluObject items property FluObject items
property FluObject footerItems property FluObject footerItems
property bool dontPageAnimation: false
property int displayMode: FluNavigationView.Auto property int displayMode: FluNavigationView.Auto
property Component autoSuggestBox property Component autoSuggestBox
property Component actionItem property Component actionItem
property int topPadding: 0 property int topPadding: 0
property int pageMode: FluNavigationView.Stack
signal logoClicked signal logoClicked
id:control id:control
QtObject{ QtObject{
@ -43,21 +41,21 @@ Item {
collapseAll() collapseAll()
} }
function handleItems(){ function handleItems(){
var idx = 0 var _idx = 0
var data = [] var data = []
if(items){ if(items){
for(var i=0;i<items.children.length;i++){ for(var i=0;i<items.children.length;i++){
var item = items.children[i] var item = items.children[i]
item.idx = idx item._idx = _idx
data.push(item) data.push(item)
idx++ _idx++
if(item instanceof FluPaneItemExpander){ if(item instanceof FluPaneItemExpander){
for(var j=0;j<item.children.length;j++){ for(var j=0;j<item.children.length;j++){
var itemChild = item.children[j] var itemChild = item.children[j]
itemChild.parent = item itemChild.parent = item
itemChild.idx = idx itemChild._idx = _idx
data.push(itemChild) data.push(itemChild)
idx++ _idx++
} }
} }
} }
@ -66,10 +64,10 @@ Item {
for(var k=0;k<footerItems.children.length;k++){ for(var k=0;k<footerItems.children.length;k++){
var itemFooter = footerItems.children[k] var itemFooter = footerItems.children[k]
if (comEmpty.status === Component.Ready) { if (comEmpty.status === Component.Ready) {
var objEmpty = comEmpty.createObject(items,{idx:idx}); var objEmpty = comEmpty.createObject(items,{_idx:_idx});
itemFooter.idx = idx; itemFooter._idx = _idx;
data.push(objEmpty) data.push(objEmpty)
idx++ _idx++
} }
} }
} }
@ -196,7 +194,6 @@ Item {
return false return false
} }
} }
Rectangle{ Rectangle{
radius: 4 radius: 4
anchors.fill: parent anchors.fill: parent
@ -208,7 +205,7 @@ Item {
visible: { visible: {
for(var i=0;i<model.children.length;i++){ for(var i=0;i<model.children.length;i++){
var item = model.children[i] var item = model.children[i]
if(item.idx === nav_list.currentIndex && !model.isExpand){ if(item._idx === nav_list.currentIndex && !model.isExpand){
return true return true
} }
} }
@ -218,7 +215,6 @@ Item {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
} }
FluIcon{ FluIcon{
id:item_icon_expand id:item_icon_expand
rotation: model.isExpand?0:180 rotation: model.isExpand?0:180
@ -244,7 +240,7 @@ Item {
} }
color: { color: {
if(FluTheme.dark){ if(FluTheme.dark){
if((nav_list.currentIndex === idx)&&type===0){ if((nav_list.currentIndex === _idx)&&type===0){
return Qt.rgba(1,1,1,0.06) return Qt.rgba(1,1,1,0.06)
} }
if(item_control.hovered){ if(item_control.hovered){
@ -252,7 +248,7 @@ Item {
} }
return Qt.rgba(0,0,0,0) return Qt.rgba(0,0,0,0)
}else{ }else{
if(nav_list.currentIndex === idx&&type===0){ if(nav_list.currentIndex === _idx&&type===0){
return Qt.rgba(0,0,0,0.06) return Qt.rgba(0,0,0,0.06)
} }
if(item_control.hovered){ if(item_control.hovered){
@ -357,7 +353,7 @@ Item {
if(model.tapFunc){ if(model.tapFunc){
model.tapFunc() model.tapFunc()
}else{ }else{
nav_list.currentIndex = idx nav_list.currentIndex = _idx
layout_footer.currentIndex = -1 layout_footer.currentIndex = -1
model.tap() model.tap()
if(d.isMinimal || d.isCompact){ if(d.isMinimal || d.isCompact){
@ -368,8 +364,8 @@ Item {
if(model.tapFunc){ if(model.tapFunc){
model.tapFunc() model.tapFunc()
}else{ }else{
nav_list.currentIndex = nav_list.count-layout_footer.count+idx nav_list.currentIndex = nav_list.count-layout_footer.count+_idx
layout_footer.currentIndex = idx layout_footer.currentIndex = _idx
model.tap() model.tap()
if(d.isMinimal || d.isCompact){ if(d.isMinimal || d.isCompact){
d.enableNavigationPanel = false d.enableNavigationPanel = false
@ -383,11 +379,11 @@ Item {
color: { color: {
if(FluTheme.dark){ if(FluTheme.dark){
if(type===0){ if(type===0){
if(nav_list.currentIndex === idx){ if(nav_list.currentIndex === _idx){
return Qt.rgba(1,1,1,0.06) return Qt.rgba(1,1,1,0.06)
} }
}else{ }else{
if(nav_list.currentIndex === (nav_list.count-layout_footer.count+idx)){ if(nav_list.currentIndex === (nav_list.count-layout_footer.count+_idx)){
return Qt.rgba(1,1,1,0.06) return Qt.rgba(1,1,1,0.06)
} }
} }
@ -397,11 +393,11 @@ Item {
return Qt.rgba(0,0,0,0) return Qt.rgba(0,0,0,0)
}else{ }else{
if(type===0){ if(type===0){
if(nav_list.currentIndex === idx){ if(nav_list.currentIndex === _idx){
return Qt.rgba(0,0,0,0.06) return Qt.rgba(0,0,0,0.06)
} }
}else{ }else{
if(nav_list.currentIndex === (nav_list.count-layout_footer.count+idx)){ if(nav_list.currentIndex === (nav_list.count-layout_footer.count+_idx)){
return Qt.rgba(0,0,0,0.06) return Qt.rgba(0,0,0,0.06)
} }
} }
@ -511,32 +507,40 @@ Item {
Layout.preferredWidth: 30 Layout.preferredWidth: 30
Layout.preferredHeight: 30 Layout.preferredHeight: 30
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
disabled: nav_swipe.depth <= 1 disabled: {
return d.stackItems.length <= 1
}
iconSize: 13 iconSize: 13
onClicked: { onClicked: {
FluTools.deleteItem(nav_swipe.pop()) d.stackItems = d.stackItems.slice(0, -1)
d.stackItems.pop()
var item = d.stackItems[d.stackItems.length-1] var item = d.stackItems[d.stackItems.length-1]
if(item.idx<(nav_list.count - layout_footer.count)){ if(item._idx<(nav_list.count - layout_footer.count)){
layout_footer.currentIndex = -1 layout_footer.currentIndex = -1
}else{ }else{
layout_footer.currentIndex = item.idx-(nav_list.count-layout_footer.count) layout_footer.currentIndex = item._idx-(nav_list.count-layout_footer.count)
} }
nav_list.currentIndex = item.idx nav_list.currentIndex = item._idx
if(nav_swipe.currentItem.pageMode === FluNavigationView.SingleInstance){ if(pageMode === FluNavigationView.Stack){
var url = nav_swipe.currentItem.url var nav_stack = loader_content.item.navStack()
var nav_stack2 = loader_content.item.navStack()
nav_stack.pop()
if(nav_stack.currentItem.launchMode === FluPage.SingleInstance){
var url = nav_stack.currentItem.url
var pageIndex = -1 var pageIndex = -1
for(var i=0;i<nav_swipe2.children.length;i++){ for(var i=0;i<nav_stack2.children.length;i++){
var obj = nav_swipe2.children[i] var obj = nav_stack2.children[i]
if(obj.url === url){ if(obj.url === url){
pageIndex = i pageIndex = i
break break
} }
} }
if(pageIndex !== -1){ if(pageIndex !== -1){
nav_swipe2.currentIndex = pageIndex nav_stack2.currentIndex = pageIndex
} }
} }
}else if(pageMode === FluNavigationView.NoStack){
loader_content.setSource(item._ext.url,item._ext.argument)
}
} }
} }
FluIconButton{ FluIconButton{
@ -607,7 +611,39 @@ Item {
} }
} }
} }
Component{
id:com_stack_content
Item{ Item{
StackView{
id:nav_stack
anchors.fill: parent
clip: true
visible: !nav_stack2.visible
popEnter : Transition{}
popExit : Transition {}
pushEnter: Transition {}
pushExit : Transition{}
replaceEnter : Transition{}
replaceExit : Transition{}
}
StackLayout{
id:nav_stack2
anchors.fill: nav_stack
clip: true
visible: nav_stack.currentItem?.launchMode === FluPage.SingleInstance
}
function navStack(){
return nav_stack
}
function navStack2(){
return nav_stack2
}
}
}
Loader{
id:loader_content
anchors{ anchors{
left: parent.left left: parent.left
top: nav_app_bar.bottom top: nav_app_bar.bottom
@ -629,24 +665,7 @@ Item {
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
} }
StackView{ sourceComponent: com_stack_content
id:nav_swipe
anchors.fill: parent
clip: true
visible: !nav_swipe2.visible
popEnter : Transition{}
popExit : Transition {}
pushEnter: Transition {}
pushExit : Transition{}
replaceEnter : Transition{}
replaceExit : Transition{}
}
StackLayout{
id:nav_swipe2
anchors.fill: nav_swipe
clip: true
visible: nav_swipe.currentItem.pageMode === FluNavigationView.SingleInstance
}
} }
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
@ -696,7 +715,7 @@ Item {
return d.isMinimalAndPanel ? true : false return d.isMinimalAndPanel ? true : false
} }
FluAcrylic { FluAcrylic {
sourceItem:nav_swipe sourceItem:loader_content
anchors.fill: layout_list anchors.fill: layout_list
color: { color: {
if(d.isMinimalAndPanel || d.isCompactAndPanel){ if(d.isMinimalAndPanel || d.isCompactAndPanel){
@ -785,7 +804,7 @@ Item {
delegate: Loader{ delegate: Loader{
property var model: modelData property var model: modelData
property var idx: index property var _idx: index
property int type: 0 property int type: 0
sourceComponent: { sourceComponent: {
if(modelData instanceof FluPaneItem){ if(modelData instanceof FluPaneItem){
@ -839,7 +858,7 @@ Item {
} }
delegate: Loader{ delegate: Loader{
property var model: modelData property var model: modelData
property var idx: index property var _idx: index
property int type: 1 property int type: 1
sourceComponent: { sourceComponent: {
if(modelData instanceof FluPaneItem){ if(modelData instanceof FluPaneItem){
@ -938,7 +957,7 @@ Item {
modelData.tapFunc() modelData.tapFunc()
}else{ }else{
modelData.tap() modelData.tap()
nav_list.currentIndex = idx nav_list.currentIndex = _idx
layout_footer.currentIndex = -1 layout_footer.currentIndex = -1
if(d.isMinimal || d.isCompact){ if(d.isMinimal || d.isCompact){
d.enableNavigationPanel = false d.enableNavigationPanel = false
@ -968,7 +987,7 @@ Item {
Component{ Component{
id:com_placeholder id:com_placeholder
Item{ Item{
property int pageMode: FluNavigationView.SingleInstance property int launchMode: FluPage.SingleInstance
property string url property string url
} }
} }
@ -990,33 +1009,49 @@ Item {
function getItems(){ function getItems(){
return nav_list.model return nav_list.model
} }
function getCurrentIndex(){
return nav_list.currentIndex
}
function getCurrentUrl(){
if(pageMode === FluNavigationView.Stack){
var nav_stack = loader_content.item.navStack()
if(nav_stack.currentItem){
return nav_stack.currentItem.url
}
}else if(pageMode === FluNavigationView.NoStack){
return loader_content.source.toString()
}
return undefined
}
function push(url,argument={}){ function push(url,argument={}){
var page = nav_swipe.find(function(item) { function stackPush(){
var nav_stack = loader_content.item.navStack()
var nav_stack2 = loader_content.item.navStack2()
var page = nav_stack.find(function(item) {
return item.url === url; return item.url === url;
}) })
if(page){ if(page){
switch(page.pageMode) switch(page.launchMode)
{ {
case FluNavigationView.SingleTask: case FluPage.SingleTask:
while(nav_swipe.currentItem !== page) while(nav_stack.currentItem !== page)
{ {
FluTools.deleteItem(nav_swipe.pop()) nav_stack.pop()
d.stackItems.pop() d.stackItems = d.stackItems.slice(0, -1)
} }
return return
case FluNavigationView.SingleTop: case FluPage.SingleTop:
if (nav_swipe.currentItem.url === url){ if (nav_stack.currentItem.url === url){
return return
} }
break break
case FluNavigationView.Standard: case FluPage.Standard:
default: default:
} }
} }
var pageIndex = -1 var pageIndex = -1
for(var i=0;i<nav_swipe2.children.length;i++){ for(var i=0;i<nav_stack2.children.length;i++){
var item = nav_swipe2.children[i] var item = nav_stack2.children[i]
if(item.url === url){ if(item.url === url){
pageIndex = i pageIndex = i
break break
@ -1024,39 +1059,45 @@ Item {
} }
var options = Object.assign(argument,{url:url}) var options = Object.assign(argument,{url:url})
if(pageIndex!==-1){ if(pageIndex!==-1){
nav_swipe2.currentIndex = pageIndex nav_stack2.currentIndex = pageIndex
nav_swipe.push(com_placeholder,options) nav_stack.push(com_placeholder,options)
}else{ }else{
var comp = Qt.createComponent(url) var comp = Qt.createComponent(url)
if (comp.status === Component.Ready) { if (comp.status === Component.Ready) {
var obj = comp.createObject(nav_swipe,options) var obj = comp.createObject(nav_stack,options)
if(obj.pageMode === FluNavigationView.SingleInstance){ if(obj.launchMode === FluPage.SingleInstance){
nav_swipe.push(com_placeholder,options) nav_stack.push(com_placeholder,options)
nav_swipe2.children.push(obj) nav_stack2.children.push(obj)
nav_swipe2.currentIndex = nav_swipe2.count - 1 nav_stack2.currentIndex = nav_stack2.count - 1
}else{ }else{
nav_swipe.push(obj) nav_stack.push(obj)
} }
}else{ }else{
console.error(comp.errorString()) console.error(comp.errorString())
} }
} }
d.stackItems.push(nav_list.model[nav_list.currentIndex]) d.stackItems = d.stackItems.concat(nav_list.model[nav_list.currentIndex])
} }
function getCurrentIndex(){ function noStackPush(){
return nav_list.currentIndex if(loader_content.source.toString() === url){
return
} }
function getCurrentUrl(){ loader_content.setSource(url,argument)
if(nav_swipe.currentItem){ var obj = nav_list.model[nav_list.currentIndex]
return nav_swipe.currentItem.url obj._ext = {url:url,argument:argument}
d.stackItems = d.stackItems.concat(obj)
}
if(pageMode === FluNavigationView.Stack){
stackPush()
}else if(pageMode === FluNavigationView.NoStack){
noStackPush()
} }
return undefined
} }
function startPageByItem(data){ function startPageByItem(data){
var items = getItems() var items = getItems()
for(var i=0;i<items.length;i++){ for(var i=0;i<items.length;i++){
var item = items[i] var item = items[i]
if(item.key === data.key){ if(item._key === data._key){
if(getCurrentIndex() === i){ if(getCurrentIndex() === i){
return return
} }

View File

@ -5,12 +5,19 @@ import QtQuick.Window
import FluentUI import FluentUI
Item { Item {
property int pageMode: FluNavigationView.SingleTop enum LaunchMode{
Standard = 0,
SingleTask = 1,
SingleTop = 2,
SingleInstance = 3
}
property int launchMode: FluPage.SingleTop
property bool animDisabled: false property bool animDisabled: false
property string url : "" property string url : ""
id: control id: control
opacity: visible opacity: visible
visible: false visible: false
StackView.onRemoved: destroy()
Behavior on opacity{ Behavior on opacity{
enabled: !animDisabled enabled: !animDisabled
NumberAnimation{ NumberAnimation{

View File

@ -3,8 +3,9 @@ import QtQuick.Controls
import FluentUI import FluentUI
QtObject { QtObject {
readonly property string key : FluTools.uuid() readonly property string _key : FluTools.uuid()
readonly property int flag : 0 property int _idx
property var _ext
property string title property string title
property int order : 0 property int order : 0
property int icon property int icon
@ -15,7 +16,6 @@ QtObject {
property string desc property string desc
property var image property var image
property var parent property var parent
property int idx
property int count: 0 property int count: 0
signal tap signal tap
property var tapFunc property var tapFunc

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import FluentUI import FluentUI
QtObject { QtObject {
readonly property string key : FluTools.uuid() readonly property string _key : FluTools.uuid()
property int _idx
property var parent property var parent
property int idx
} }

View File

@ -3,11 +3,11 @@ import QtQuick.Controls
import FluentUI import FluentUI
FluObject { FluObject {
readonly property string key : FluTools.uuid() readonly property string _key : FluTools.uuid()
property int _idx
property string title property string title
property var icon property var icon
property Component cusIcon property Component cusIcon
property bool isExpand: false property bool isExpand: false
property var parent property var parent
property int idx
} }

View File

@ -3,8 +3,8 @@ import QtQuick.Controls
import FluentUI import FluentUI
QtObject { QtObject {
readonly property string key : FluTools.uuid() readonly property string _key : FluTools.uuid()
property int _idx
property string title property string title
property var parent property var parent
property int idx
} }

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import FluentUI import FluentUI
QtObject { QtObject {
readonly property string key : FluTools.uuid() readonly property string _key : FluTools.uuid()
property int _idx
property var parent property var parent
property int idx
} }