From bcc5d433a911568de9ba7d8ceaf5070173d7a3b1 Mon Sep 17 00:00:00 2001 From: zhuzihcu Date: Fri, 10 Mar 2023 18:08:32 +0800 Subject: [PATCH] update --- example/AboutPage.qml | 2 +- example/MainPage.qml | 286 ++++++++++----------- example/T_Awesome.qml | 13 +- example/T_Buttons.qml | 290 ++++++++++++---------- example/T_Dialog.qml | 33 +-- example/T_Expander.qml | 104 ++++---- example/T_InfoBar.qml | 72 +++--- example/T_Progress.qml | 65 ++--- example/T_Rectangle.qml | 221 ++++++++--------- example/T_Slider.qml | 40 +-- example/T_TextBox.qml | 80 +++--- example/T_Theme.qml | 110 ++++----- example/T_ToggleSwitch.qml | 25 +- example/T_TreeView.qml | 12 +- example/T_Typography.qml | 15 +- example/qml.qrc | 2 +- src/Fluent.cpp | 9 + src/controls/FluAppBar.qml | 17 +- src/controls/FluArea.qml | 28 +++ src/controls/FluContentPage.qml | 29 +++ src/controls/FluExpander.qml | 2 + src/controls/FluIconButton.qml | 6 +- src/controls/FluNavigationView.qml | 341 ++++++++++++++++++++++++++ src/controls/FluPaneItem.qml | 7 + src/controls/FluPaneItemHeader.qml | 5 + src/controls/FluPaneItemSeparator.qml | 5 + src/controls/FluScrollablePage.qml | 34 +++ src/controls/FluTreeView.qml | 9 +- src/controls/FluWindow.qml | 1 + src/res.qrc | 7 + 30 files changed, 1095 insertions(+), 775 deletions(-) create mode 100644 src/controls/FluArea.qml create mode 100644 src/controls/FluContentPage.qml create mode 100644 src/controls/FluNavigationView.qml create mode 100644 src/controls/FluPaneItem.qml create mode 100644 src/controls/FluPaneItemHeader.qml create mode 100644 src/controls/FluPaneItemSeparator.qml create mode 100644 src/controls/FluScrollablePage.qml diff --git a/example/AboutPage.qml b/example/AboutPage.qml index 62e4045e..ab55b286 100644 --- a/example/AboutPage.qml +++ b/example/AboutPage.qml @@ -34,7 +34,7 @@ FluWindow { fontStyle: FluText.Title } FluText{ - text:"v1.0.2" + text:"v1.0.3" fontStyle: FluText.Body Layout.alignment: Qt.AlignBottom } diff --git a/example/MainPage.qml b/example/MainPage.qml index 92e36d46..5f51a660 100644 --- a/example/MainPage.qml +++ b/example/MainPage.qml @@ -17,184 +17,164 @@ FluWindow { FluAppBar{ id:appbar title: "FluentUI" - showDark: true } - ListModel{ - id:nav_items - ListElement{ - text:"Buttons" - page:"qrc:/T_Buttons.qml" + + FluObject{ + id:original_items + + FluPaneItemHeader{ + title:"Inputs" } - ListElement{ - text:"TextBox" - page:"qrc:/T_TextBox.qml" + + FluPaneItem{ + title:"Buttons" + onTap:{ + nav_view.push("qrc:/T_Buttons.qml") + } } - ListElement{ - text:"ToggleSwitch" - page:"qrc:/T_ToggleSwitch.qml" + + FluPaneItem{ + title:"Slider" + onTap:{ + nav_view.push("qrc:/T_Slider.qml") + } } - ListElement{ - text:"Slider" - page:"qrc:/T_Slider.qml" + + FluPaneItem{ + title:"ToggleSwitch" + onTap:{ + nav_view.push("qrc:/T_ToggleSwitch.qml") + } } - ListElement{ - text:"InfoBar" - page:"qrc:/T_InfoBar.qml" + + FluPaneItemHeader{ + title:"Form" } - ListElement{ - text:"Dialog" - page:"qrc:/T_Dialog.qml" + + FluPaneItem{ + title:"TextBox" + onTap:{ + nav_view.push("qrc:/T_TextBox.qml") + } } - ListElement{ - text:"Progress" - page:"qrc:/T_Progress.qml" + + FluPaneItemHeader{ + title:"Surface" } - ListElement{ - text:"Rectangle" - page:"qrc:/T_Rectangle.qml" + + FluPaneItem{ + title:"InfoBar" + onTap:{ + nav_view.push("qrc:/T_InfoBar.qml") + } } - ListElement{ - text:"Expander" - page:"qrc:/T_Expander.qml" + + FluPaneItem{ + title:"Progress" + onTap:{ + nav_view.push("qrc:/T_Progress.qml") + } } - ListElement{ - text:"TreeView" - page:"qrc:/T_TreeView.qml" + FluPaneItem{ + title:"Rectangle" + onTap:{ + nav_view.push("qrc:/T_Rectangle.qml") + } } - ListElement{ - text:"Theme" - page:"qrc:/T_Theme.qml" + FluPaneItem{ + title:"Expander" + onTap:{ + nav_view.push("qrc:/T_Expander.qml") + } } - ListElement{ - text:"Awesome" - page:"qrc:/T_Awesome.qml" + + FluPaneItemHeader{ + title:"Popus" } - ListElement{ - text:"Typography" - page:"qrc:/T_Typography.qml" + + + FluPaneItem{ + title:"Dialog" + onTap:{ + nav_view.push("qrc:/T_Dialog.qml") + } + } + + FluPaneItemHeader{ + title:"Navigation" + } + + FluPaneItem{ + title:"TreeView" + onTap:{ + nav_view.push("qrc:/T_TreeView.qml") + } + } + + FluPaneItemHeader{ + title:"Theming" + } + + + FluPaneItem{ + title:"Theme" + onTap:{ + nav_view.push("qrc:/T_Theme.qml") + } + } + + FluPaneItem{ + title:"Awesome" + onTap:{ + nav_view.push("qrc:/T_Awesome.qml") + } + } + FluPaneItem{ + title:"Typography" + onTap:{ + nav_view.push("qrc:/T_Typography.qml") + } + } + + } + + FluObject{ + id:footer_items + FluPaneItemSeparator{} + FluPaneItem{ + title:"意见反馈" + onTap:{ + Qt.openUrlExternally("https://github.com/zhuzichu520/FluentUI/issues/new") + } + } + FluPaneItem{ + title:"关于" + onTap:{ + FluApp.navigate("/About") + } } } - FluIconButton{ - icon:FluentIcons.FA_navicon + + FluNavigationView{ + id:nav_view anchors{ + top: appbar.bottom left: parent.left - bottom: parent.bottom - leftMargin: 12 - bottomMargin: 12 - } - FluMenu{ - id:menu - x:40 - margins:4 - FluMenuItem{ - text:"意见反馈" - onClicked:{ - Qt.openUrlExternally("https://github.com/zhuzichu520/FluentUI/issues/new") - } - } - FluMenuItem{ - text:"关于" - onClicked:{ - FluApp.navigate("/About") - } - } - } - onClicked:{ - menu.open() - } - } - - ListView{ - id:nav_list - anchors{ - top: appbar.bottom - bottom: parent.bottom - topMargin: 20 - bottomMargin: 52 - } - ScrollBar.vertical: ScrollBar { } - boundsBehavior: Flickable.StopAtBounds - clip: true - width: 160 - model: nav_items - delegate: Item{ - height: 38 - width: nav_list.width - - Rectangle{ - radius: 4 - anchors{ - top: parent.top - bottom: parent.bottom - left: parent.left - right: parent.right - topMargin: 2 - bottomMargin: 2 - leftMargin: 6 - rightMargin: 6 - } - MouseArea{ - id:item_mouse - hoverEnabled: true - anchors.fill: parent - onClicked: { - nav_list.currentIndex = index - } - } - color: { - if(FluTheme.isDark){ - if(nav_list.currentIndex === index){ - return "#2D2D2D" - } - if(item_mouse.containsMouse){ - return "#292929" - } - return "#202020" - }else{ - if(item_mouse.containsMouse){ - return Qt.rgba(0,0,0,0.03) - } - if(nav_list.currentIndex === index){ - return Qt.rgba(0,0,0,0.06) - } - return Qt.rgba(0,0,0,0) - } - } - - FluText{ - text:model.text - anchors.centerIn: parent - } - - } - } - } - - Rectangle{ - color: FluTheme.isDark ? "#323232" : "#FFFFFF" - radius: 10 - clip: true - anchors{ - left: nav_list.right - leftMargin: 2 - top: appbar.bottom - topMargin: 20 right: parent.right - rightMargin: 10 bottom: parent.bottom - bottomMargin: 20 } - border.width: 1 - border.color: FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(238/255,238/255,238/255,1) + items:original_items + footerItems:footer_items - Loader{ - anchors.fill: parent - anchors.margins:20 - source: nav_items.get(nav_list.currentIndex).page + Component.onCompleted: { + nav_view.setCurrentIndex(1) + nav_view.push("qrc:/T_Buttons.qml") } + } + } diff --git a/example/T_Awesome.qml b/example/T_Awesome.qml index 2490cc65..0f5a94ce 100644 --- a/example/T_Awesome.qml +++ b/example/T_Awesome.qml @@ -4,20 +4,19 @@ import QtQuick.Layouts 1.15 import QtQuick.Window 2.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"Awesome" - fontStyle: FluText.TitleLarge - } +FluContentPage { + + title:"Awesome" + FluTextBox{ id:text_box placeholderText: "请输入关键字" anchors{ topMargin: 20 - top:title.bottom + top:parent.top } } + FluFilledButton{ text:"搜索" anchors{ diff --git a/example/T_Buttons.qml b/example/T_Buttons.qml index 48ab8400..b6d11cb9 100644 --- a/example/T_Buttons.qml +++ b/example/T_Buttons.qml @@ -2,154 +2,182 @@ import QtQuick.Layouts 1.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 -import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - width: parent.width - FluText{ - id:title - text:"Buttons" - fontStyle: FluText.TitleLarge - } - ScrollView{ - clip: true +FluScrollablePage{ + title:"Buttons" + + spacing: 20 + + FluArea{ + Layout.topMargin: 20 width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom + height: 68 + paddings: 10 + + FluButton{ + disabled:button_switch.checked + onClicked: { + showInfo("点击StandardButton") + } + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + } } - ColumnLayout{ + + Row{ spacing: 5 - width: parent.width - RowLayout{ - Layout.topMargin: 20 - width: parent.width - FluButton{ - disabled:button_switch.checked - onClicked: { - showInfo("点击StandardButton") - } - } - Item{ - height: 1 - Layout.fillWidth: true - } - FluToggleSwitch{ - id:button_switch - Layout.alignment: Qt.AlignRight - } - FluText{ - text:"Disabled" - } + anchors{ + verticalCenter: parent.verticalCenter + right: parent.right } - FluDivider{ - Layout.fillWidth: true ; height:1; + FluToggleSwitch{ + id:button_switch + Layout.alignment: Qt.AlignRight } - RowLayout{ - Layout.topMargin: 20 - width: parent.width - FluFilledButton{ - disabled:filled_button_switch.checked + FluText{ + text:"Disabled" + } + } + } + + FluArea{ + width: parent.width + height: 68 + paddings: 10 + + FluFilledButton{ + disabled:filled_button_switch.checked + onClicked: { + showWarning("点击FilledButton") + } + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + } + } + + Row{ + spacing: 5 + anchors{ + verticalCenter: parent.verticalCenter + right: parent.right + } + FluToggleSwitch{ + id:filled_button_switch + Layout.alignment: Qt.AlignRight + } + FluText{ + text:"Disabled" + } + } + } + + + FluArea{ + width: parent.width + height: 68 + paddings: 10 + + FluIconButton{ + icon:FluentIcons.FA_close + disabled:icon_button_switch.checked + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + } + onClicked:{ + showSuccess("点击IconButton") + } + } + + Row{ + spacing: 5 + anchors{ + verticalCenter: parent.verticalCenter + right: parent.right + } + FluToggleSwitch{ + id:icon_button_switch + Layout.alignment: Qt.AlignRight + } + FluText{ + text:"Disabled" + } + } + } + + FluArea{ + width: parent.width + height: 100 + paddings: 10 + + ColumnLayout{ + spacing: 8 + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + } + Repeater{ + id:repeater + property int selecIndex : 0 + model: 3 + delegate: FluRadioButton{ + checked : repeater.selecIndex===index + disabled:radio_button_switch.checked + text:"Radio Button_"+index onClicked:{ - showWarning("点击FilledButton") + repeater.selecIndex = index } } - Item{ - height: 1 - Layout.fillWidth: true - } - FluToggleSwitch{ - id:filled_button_switch - Layout.alignment: Qt.AlignRight - } - FluText{ - text:"Disabled" - } } - FluDivider{ - Layout.fillWidth: true ; height:1 + } + + + Row{ + spacing: 5 + anchors{ + verticalCenter: parent.verticalCenter + right: parent.right } - RowLayout{ - Layout.topMargin: 20 - width: parent.width - FluIconButton{ - icon:FluentIcons.FA_close - disabled:icon_button_switch.checked - onClicked:{ - showSuccess("点击IconButton") - } - } - Item{ - height: 1 - Layout.fillWidth: true - } - FluToggleSwitch{ - id:icon_button_switch - Layout.alignment: Qt.AlignRight - } - FluText{ - text:"Disabled" - } + FluToggleSwitch{ + id:radio_button_switch + Layout.alignment: Qt.AlignRight } - FluDivider{ - Layout.fillWidth: true ; height:1 + FluText{ + text:"Disabled" } - RowLayout{ - Layout.topMargin: 20 - width: parent.width - ColumnLayout{ - spacing: 8 - Repeater{ - id:repeater - property int selecIndex : 0 - model: 3 - delegate: FluRadioButton{ - checked : repeater.selecIndex===index - disabled:radio_button_switch.checked - text:"Radio Button_"+index - onClicked:{ - repeater.selecIndex = index - } - } - } - } - Item{ - height: 1 - Layout.fillWidth: true - } - FluToggleSwitch{ - id:radio_button_switch - Layout.alignment: Qt.AlignRight - } - FluText{ - text:"Disabled" - } + } + } + + + FluArea{ + width: parent.width + height: 68 + paddings: 10 + + FluCheckBox{ + disabled:icon_button_check.checked + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left } - FluDivider{ - Layout.fillWidth: true ; height:1 + } + + + Row{ + spacing: 5 + anchors{ + verticalCenter: parent.verticalCenter + right: parent.right } - RowLayout{ - Layout.topMargin: 20 - width: parent.width - FluCheckBox{ - disabled:icon_button_check.checked - } - Item{ - height: 1 - Layout.fillWidth: true - } - FluToggleSwitch{ - id:icon_button_check - Layout.alignment: Qt.AlignRight - } - FluText{ - text:"Disabled" - } + FluToggleSwitch{ + id:icon_button_check + Layout.alignment: Qt.AlignRight } - FluDivider{ - Layout.fillWidth: true ; height:1 + FluText{ + text:"Disabled" } } } diff --git a/example/T_Dialog.qml b/example/T_Dialog.qml index 98e25a9a..d28ad3f5 100644 --- a/example/T_Dialog.qml +++ b/example/T_Dialog.qml @@ -5,13 +5,8 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - - FluText{ - id:title - text:"Dialog" - fontStyle: FluText.TitleLarge - } +FluScrollablePage{ + title:"Dialog" FluContentDialog{ id:dialog @@ -27,25 +22,11 @@ Item { } } - - - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - FluButton{ - Layout.topMargin: 20 - text:"Show Dialog" - onClicked: { - dialog.open() - } - } + FluButton{ + Layout.topMargin: 20 + text:"Show Dialog" + onClicked: { + dialog.open() } } } diff --git a/example/T_Expander.qml b/example/T_Expander.qml index 239dff2b..cb39e476 100644 --- a/example/T_Expander.qml +++ b/example/T_Expander.qml @@ -5,72 +5,54 @@ import QtQuick.Window 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"Expander" - fontStyle: FluText.TitleLarge - } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - Column{ - spacing: 5 - Item{ - width: 1 - height: 20 - } - FluExpander{ - headerText:"打开一个单选框" - Item{ - anchors.fill: parent - ColumnLayout{ - spacing: 8 - anchors{ - top: parent.top - left: parent.left - topMargin: 15 - leftMargin: 15 - } - Repeater{ - id:repeater - property int selecIndex : 0 - model: 3 - delegate: FluRadioButton{ - checked : repeater.selecIndex===index - text:"Radio Button_"+index - onClicked:{ - repeater.selecIndex = index - } - } +FluScrollablePage{ + title:"Expander" + + FluExpander{ + headerText:"打开一个单选框" + Layout.topMargin: 20 + Item{ + anchors.fill: parent + ColumnLayout{ + spacing: 8 + anchors{ + top: parent.top + left: parent.left + topMargin: 15 + leftMargin: 15 + } + Repeater{ + id:repeater + property int selecIndex : 0 + model: 3 + delegate: FluRadioButton{ + checked : repeater.selecIndex===index + text:"Radio Button_"+index + onClicked:{ + repeater.selecIndex = index } } } } + } + } - FluExpander{ - Layout.topMargin: 20 - headerText:"打开一个滑动文本框" - Item{ - anchors.fill: parent - ScrollView{ - id:scrollview - width: parent.width - height: parent.height - contentWidth: parent.width - FluText{ - id:test - width: scrollview.width - wrapMode: Text.WrapAnywhere - padding: 14 - text:"先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。宫中府中,俱为一体;陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明;故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏。臣不胜受恩感激。今当远离,临表涕零,不知所言。" - } - } + FluExpander{ + Layout.topMargin: 20 + headerText:"打开一个滑动文本框" + Item{ + anchors.fill: parent + ScrollView{ + id:scrollview + width: parent.width + height: parent.height + contentWidth: parent.width + FluText{ + id:test + width: scrollview.width + wrapMode: Text.WrapAnywhere + padding: 14 + text:"先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。宫中府中,俱为一体;陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明;故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏。臣不胜受恩感激。今当远离,临表涕零,不知所言。" } } } diff --git a/example/T_InfoBar.qml b/example/T_InfoBar.qml index 51904949..eb5c306f 100644 --- a/example/T_InfoBar.qml +++ b/example/T_InfoBar.qml @@ -5,51 +5,35 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"InfoBar" - fontStyle: FluText.TitleLarge - } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 +FluScrollablePage{ + title:"InfoBar" - FluButton{ - text:"Info" - Layout.topMargin: 20 - onClicked: { - showInfo("这是一个Info样式的InfoBar") - } - } - FluButton{ - text:"Warning" - Layout.topMargin: 20 - onClicked: { - showWarning("这是一个Warning样式的InfoBar") - } - } - FluButton{ - text:"Error" - Layout.topMargin: 20 - onClicked: { - showError("这是一个Error样式的InfoBar") - } - } - FluButton{ - text:"Success" - Layout.topMargin: 20 - onClicked: { - showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar") - } - } + FluButton{ + text:"Info" + Layout.topMargin: 20 + onClicked: { + showInfo("这是一个Info样式的InfoBar") + } + } + FluButton{ + text:"Warning" + Layout.topMargin: 20 + onClicked: { + showWarning("这是一个Warning样式的InfoBar") + } + } + FluButton{ + text:"Error" + Layout.topMargin: 20 + onClicked: { + showError("这是一个Error样式的InfoBar") + } + } + FluButton{ + text:"Success" + Layout.topMargin: 20 + onClicked: { + showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar") } } } diff --git a/example/T_Progress.qml b/example/T_Progress.qml index 36cd07f5..08d7cc9c 100644 --- a/example/T_Progress.qml +++ b/example/T_Progress.qml @@ -5,47 +5,32 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"Progress" - fontStyle: FluText.TitleLarge +FluScrollablePage{ + title:"Progress" + + FluProgressBar{ + Layout.topMargin: 20 } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - FluProgressBar{ - Layout.topMargin: 20 - } - FluProgressRing{ - Layout.topMargin: 10 - } - FluProgressBar{ - id:progress_bar - Layout.topMargin: 20 - indeterminate: false - } - FluProgressRing{ - id:progress_ring - Layout.topMargin: 10 - indeterminate: false - } - FluSlider{ - Layout.topMargin: 30 - value:50 - onValueChanged:{ - progress_bar.progress = value/100 - progress_ring.progress = value/100 - } - Layout.bottomMargin: 30 - } + FluProgressRing{ + Layout.topMargin: 10 + } + FluProgressBar{ + id:progress_bar + Layout.topMargin: 20 + indeterminate: false + } + FluProgressRing{ + id:progress_ring + Layout.topMargin: 10 + indeterminate: false + } + FluSlider{ + Layout.topMargin: 30 + value:50 + onValueChanged:{ + progress_bar.progress = value/100 + progress_ring.progress = value/100 } + Layout.bottomMargin: 30 } } diff --git a/example/T_Rectangle.qml b/example/T_Rectangle.qml index 35a258d0..af9feb5b 100644 --- a/example/T_Rectangle.qml +++ b/example/T_Rectangle.qml @@ -5,127 +5,110 @@ import QtQuick.Window 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"Rectangle" - fontStyle: FluText.TitleLarge +FluScrollablePage{ + title:"Rectangle" + + RowLayout{ + Layout.topMargin: 20 + FluRectangle{ + width: 50 + height: 50 + color:"#0078d4" + radius:[0,0,0,0] + } + FluRectangle{ + width: 50 + height: 50 + color:"#744da9" + radius:[15,15,15,15] + } + FluRectangle{ + width: 50 + height: 50 + color:"#ffeb3b" + radius:[15,0,0,0] + } + FluRectangle{ + width: 50 + height: 50 + color:"#f7630c" + radius:[0,15,0,0] + } + FluRectangle{ + width: 50 + height: 50 + color:"#e71123" + radius:[0,0,15,0] + } + FluRectangle{ + width: 50 + height: 50 + color:"#b4009e" + radius:[0,0,0,15] + } } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - width: parent.width - height: parent.height - RowLayout{ - Layout.topMargin: 20 - FluRectangle{ - width: 50 - height: 50 - color:"#0078d4" - radius:[0,0,0,0] - } - FluRectangle{ - width: 50 - height: 50 - color:"#744da9" - radius:[15,15,15,15] - } - FluRectangle{ - width: 50 - height: 50 - color:"#ffeb3b" - radius:[15,0,0,0] - } - FluRectangle{ - width: 50 - height: 50 - color:"#f7630c" - radius:[0,15,0,0] - } - FluRectangle{ - width: 50 - height: 50 - color:"#e71123" - radius:[0,0,15,0] - } - FluRectangle{ - width: 50 - height: 50 - color:"#b4009e" - radius:[0,0,0,15] - } - } - FluText{ - text:"配合图片使用" - fontStyle: FluText.Subtitle - Layout.topMargin: 20 - } - RowLayout{ - spacing: 14 - FluRectangle{ - width: 50 - height: 50 - radius:[25,0,25,25] - Image { - asynchronous: true - anchors.fill: parent - source: "qrc:/res/svg/avatar_1.svg" - sourceSize: Qt.size(width,height) - } - } - FluRectangle{ - width: 50 - height: 50 - radius:[10,10,10,10] - Image { - asynchronous: true - anchors.fill: parent - sourceSize: Qt.size(width,height) - source: "qrc:/res/svg/avatar_2.svg" - } - } - FluRectangle{ - width: 50 - height: 50 - radius:[25,25,25,25] - Image { - asynchronous: true - anchors.fill: parent - sourceSize: Qt.size(width,height) - source: "qrc:/res/svg/avatar_3.svg" - } - } - FluRectangle{ - width: 50 - height: 50 - radius:[0,25,25,25] - Image { - asynchronous: true - anchors.fill: parent - sourceSize: Qt.size(width,height) - source: "qrc:/res/svg/avatar_4.svg" - } - } - } - FluRectangle{ - width: 1080/5 - height: 1439/5 - radius:[25,25,25,25] - Image { - asynchronous: true - source: "qrc:/res/image/image_huoyin.webp" - anchors.fill: parent - sourceSize: Qt.size(width,height) - } - Layout.topMargin: 10 + FluText{ + text:"配合图片使用" + fontStyle: FluText.Subtitle + Layout.topMargin: 20 + } + RowLayout{ + spacing: 14 + FluRectangle{ + width: 50 + height: 50 + radius:[25,0,25,25] + Image { + asynchronous: true + anchors.fill: parent + source: "qrc:/res/svg/avatar_1.svg" + sourceSize: Qt.size(width,height) } } + FluRectangle{ + width: 50 + height: 50 + radius:[10,10,10,10] + Image { + asynchronous: true + anchors.fill: parent + sourceSize: Qt.size(width,height) + source: "qrc:/res/svg/avatar_2.svg" + } + } + FluRectangle{ + width: 50 + height: 50 + radius:[25,25,25,25] + Image { + asynchronous: true + anchors.fill: parent + sourceSize: Qt.size(width,height) + source: "qrc:/res/svg/avatar_3.svg" + } + } + FluRectangle{ + width: 50 + height: 50 + radius:[0,25,25,25] + Image { + asynchronous: true + anchors.fill: parent + sourceSize: Qt.size(width,height) + source: "qrc:/res/svg/avatar_4.svg" + } + } + } + FluRectangle{ + width: 1080/5 + height: 1439/5 + radius:[25,25,25,25] + Image { + asynchronous: true + source: "qrc:/res/image/image_huoyin.webp" + anchors.fill: parent + sourceSize: Qt.size(width,height) + } + Layout.topMargin: 10 } } diff --git a/example/T_Slider.qml b/example/T_Slider.qml index 1fedbc0d..05b5c716 100644 --- a/example/T_Slider.qml +++ b/example/T_Slider.qml @@ -5,33 +5,19 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"Slider" - fontStyle: FluText.TitleLarge +FluScrollablePage{ + + title:"Slider" + + FluSlider{ + Layout.topMargin: 20 + Layout.leftMargin: 15 + value: 50 } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - FluSlider{ - Layout.topMargin: 20 - Layout.leftMargin: 15 - value: 50 - } - FluSlider{ - orientation:FluSlider.Vertical - Layout.topMargin: 20 - Layout.leftMargin: 15 - value: 50 - } - } + FluSlider{ + orientation:FluSlider.Vertical + Layout.topMargin: 20 + Layout.leftMargin: 15 + value: 50 } } diff --git a/example/T_TextBox.qml b/example/T_TextBox.qml index 4245bb12..78305710 100644 --- a/example/T_TextBox.qml +++ b/example/T_TextBox.qml @@ -5,58 +5,44 @@ import QtQuick.Window 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"TextBox" - fontStyle: FluText.TitleLarge +FluScrollablePage{ + + title:"TextBox" + + FluTextBox{ + Layout.topMargin: 20 + placeholderText: "单行输入框" + Layout.preferredWidth: 300 } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - FluTextBox{ - Layout.topMargin: 20 - placeholderText: "单行输入框" - Layout.preferredWidth: 300 - } - FluMultiLineTextBox{ - Layout.topMargin: 20 - Layout.preferredWidth: 300 - placeholderText: "多行输入框" - } - FluAutoSuggestBox{ - Layout.topMargin: 20 - values:generateRandomNames(100) - placeholderText: "AutoSuggestBox" - Layout.preferredWidth: 300 - } - } + FluMultiLineTextBox{ + Layout.topMargin: 20 + Layout.preferredWidth: 300 + placeholderText: "多行输入框" + } + FluAutoSuggestBox{ + Layout.topMargin: 20 + values:generateRandomNames(100) + placeholderText: "AutoSuggestBox" + Layout.preferredWidth: 300 } function generateRandomNames(numNames) { - const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - const names = []; - function generateRandomName() { - const nameLength = Math.floor(Math.random() * 5) + 4; - let name = ''; - for (let i = 0; i < nameLength; i++) { - const letterIndex = Math.floor(Math.random() * 26); - name += alphabet.charAt(letterIndex); + const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + const names = []; + function generateRandomName() { + const nameLength = Math.floor(Math.random() * 5) + 4; + let name = ''; + for (let i = 0; i < nameLength; i++) { + const letterIndex = Math.floor(Math.random() * 26); + name += alphabet.charAt(letterIndex); + } + return name; } - return name; - } - for (let i = 0; i < numNames; i++) { - const name = generateRandomName(); - names.push(name); - } - return names; + for (let i = 0; i < numNames; i++) { + const name = generateRandomName(); + names.push(name); + } + return names; } diff --git a/example/T_Theme.qml b/example/T_Theme.qml index 970c051d..2c2a9b29 100644 --- a/example/T_Theme.qml +++ b/example/T_Theme.qml @@ -5,71 +5,57 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"Theme" - fontStyle: FluText.TitleLarge - } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - RowLayout{ - Layout.topMargin: 20 - Repeater{ - model: [FluColors.Yellow,FluColors.Orange,FluColors.Red,FluColors.Magenta,FluColors.Purple,FluColors.Blue,FluColors.Teal,FluColors.Green] - delegate: Rectangle{ - width: 42 - height: 42 - radius: 4 - color: mouse_item.containsMouse ? Qt.lighter(modelData.normal,1.1) : modelData.normal - FluIcon { - anchors.centerIn: parent - icon: FluentIcons.FA_check - iconSize: 15 - visible: modelData === FluTheme.primaryColor - color: FluTheme.isDark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1) - } - MouseArea{ - id:mouse_item - anchors.fill: parent - hoverEnabled: true - onClicked: { - FluTheme.primaryColor = modelData - } - } +FluScrollablePage{ + + title:"Theme" + + RowLayout{ + Layout.topMargin: 20 + Repeater{ + model: [FluColors.Yellow,FluColors.Orange,FluColors.Red,FluColors.Magenta,FluColors.Purple,FluColors.Blue,FluColors.Teal,FluColors.Green] + delegate: Rectangle{ + width: 42 + height: 42 + radius: 4 + color: mouse_item.containsMouse ? Qt.lighter(modelData.normal,1.1) : modelData.normal + FluIcon { + anchors.centerIn: parent + icon: FluentIcons.FA_check + iconSize: 15 + visible: modelData === FluTheme.primaryColor + color: FluTheme.isDark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1) + } + MouseArea{ + id:mouse_item + anchors.fill: parent + hoverEnabled: true + onClicked: { + FluTheme.primaryColor = modelData } } } - FluText{ - text:"夜间模式" - fontStyle: FluText.Subtitle - Layout.topMargin: 20 - } - FluToggleSwitch{ - checked: FluTheme.isDark - onClickFunc:function(){ - FluTheme.isDark = !FluTheme.isDark - } - } - FluText{ - text:"无边框" - fontStyle: FluText.Subtitle - Layout.topMargin: 20 - } - FluToggleSwitch{ - checked: FluTheme.isFrameless - onClickFunc:function(){ - FluTheme.isFrameless = !FluTheme.isFrameless - } - } + } + } + FluText{ + text:"夜间模式" + fontStyle: FluText.Subtitle + Layout.topMargin: 20 + } + FluToggleSwitch{ + checked: FluTheme.isDark + onClickFunc:function(){ + FluTheme.isDark = !FluTheme.isDark + } + } + FluText{ + text:"无边框" + fontStyle: FluText.Subtitle + Layout.topMargin: 20 + } + FluToggleSwitch{ + checked: FluTheme.isFrameless + onClickFunc:function(){ + FluTheme.isFrameless = !FluTheme.isFrameless } } } diff --git a/example/T_ToggleSwitch.qml b/example/T_ToggleSwitch.qml index d2bcab86..8523cde9 100644 --- a/example/T_ToggleSwitch.qml +++ b/example/T_ToggleSwitch.qml @@ -5,26 +5,11 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"ToggleSwitch" - fontStyle: FluText.TitleLarge - } - ScrollView{ - clip: true - width: parent.width - contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } - ColumnLayout{ - spacing: 5 - FluToggleSwitch{ - Layout.topMargin: 20 - } - } +FluScrollablePage{ + title:"ToggleSwitch" + + FluToggleSwitch{ + Layout.topMargin: 20 } } diff --git a/example/T_TreeView.qml b/example/T_TreeView.qml index 8bfdba4c..d39f0c73 100644 --- a/example/T_TreeView.qml +++ b/example/T_TreeView.qml @@ -2,15 +2,11 @@ import QtQuick.Layouts 1.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 -import QtGraphicalEffects 1.15 import FluentUI 1.0 -Item { - FluText{ - id:title - text:"TreeView" - fontStyle: FluText.TitleLarge - } +FluContentPage { + + title:"TreeView" function randomName() { var names = ["张三", "李四", "王五", "赵六", "钱七", "孙八", "周九", "吴十"] @@ -56,7 +52,7 @@ Item { id:tree_view width:240 anchors{ - top:title.bottom + top:parent.top left:parent.left bottom:parent.bottom } diff --git a/example/T_Typography.qml b/example/T_Typography.qml index 2d35bcc0..d602fd1e 100644 --- a/example/T_Typography.qml +++ b/example/T_Typography.qml @@ -3,24 +3,15 @@ import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import FluentUI 1.0 -Item { +FluContentPage { + title: "Typography" property int textSize: 13 - FluText{ - id:title - text:"Typography" - fontStyle: FluText.TitleLarge - } - ScrollView{ clip: true width: parent.width contentWidth: parent.width - anchors{ - top: title.bottom - bottom: parent.bottom - } ColumnLayout{ spacing: 0 FluText{ @@ -85,7 +76,7 @@ Item { topMargin: 30 } onValueChanged:{ - textSize = value/100*16+8 + textSize = value/100*16+8 } value: 31 } diff --git a/example/qml.qrc b/example/qml.qrc index cdbdf275..a985b5c3 100644 --- a/example/qml.qrc +++ b/example/qml.qrc @@ -3,7 +3,6 @@ T_ToggleSwitch.qml T_Typography.qml App.qml - MainPage.qml SettingPage.qml AboutPage.qml T_Buttons.qml @@ -30,5 +29,6 @@ T_Dialog.qml T_TreeView.qml T_Expander.qml + MainPage.qml diff --git a/src/Fluent.cpp b/src/Fluent.cpp index a92557f4..d58ca339 100644 --- a/src/Fluent.cpp +++ b/src/Fluent.cpp @@ -33,6 +33,15 @@ void Fluent::registerTypes(const char *uri){ qmlRegisterType(uri,major,minor,"WindowHelper"); qmlRegisterType(uri,major,minor,"FluColorSet"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluArea.qml"),uri,major,minor,"FluArea"); + + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentPage.qml"),uri,major,minor,"FluContentPage"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollablePage.qml"),uri,major,minor,"FluScrollablePage"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemHeader.qml"),uri,major,minor,"FluPaneItemHeader"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItem.qml"),uri,major,minor,"FluPaneItem"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemSeparator.qml"),uri,major,minor,"FluPaneItemSeparator"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluNavigationView.qml"),uri,major,minor,"FluNavigationView"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluAutoSuggestBox.qml"),uri,major,minor,"FluAutoSuggestBox"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluExpander.qml"),uri,major,minor,"FluExpander"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTreeView.qml"),uri,major,minor,"FluTreeView"); diff --git a/src/controls/FluAppBar.qml b/src/controls/FluAppBar.qml index 6e140e5b..8d6bc45d 100644 --- a/src/controls/FluAppBar.qml +++ b/src/controls/FluAppBar.qml @@ -14,7 +14,8 @@ Rectangle{ return Window.window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1) } visible: FluTheme.isFrameless - height: visible ? 50 : 0 + height: visible ? 34 : 0 + width: { if(parent==null) return 200 @@ -60,7 +61,7 @@ Rectangle{ anchors{ verticalCenter: parent.verticalCenter left: parent.left - leftMargin: 14 + leftMargin: 10 } color:root.textColor fontStyle: FluText.Title @@ -69,14 +70,13 @@ Rectangle{ } RowLayout{ - anchors.right: parent.right; - anchors.rightMargin: 10 - height: parent.height - spacing: 5 + anchors.right: parent.right + height: 30 + spacing: 0 TFpsMonitor{ Layout.alignment: Qt.AlignVCenter - Layout.rightMargin: 12 + Layout.rightMargin: 20 Layout.topMargin: 5 color:root.textColor visible: showFps @@ -84,8 +84,9 @@ Rectangle{ RowLayout{ Layout.alignment: Qt.AlignVCenter - spacing: 5 + Layout.rightMargin: 14 visible: showDark + spacing: 5 FluText{ text:"夜间模式" color:root.textColor diff --git a/src/controls/FluArea.qml b/src/controls/FluArea.qml new file mode 100644 index 00000000..4b4a066b --- /dev/null +++ b/src/controls/FluArea.qml @@ -0,0 +1,28 @@ +import QtQuick 2.15 +import FluentUI 1.0 + +Rectangle { + radius: 4 + color: FluTheme.isDark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1) + border.color: FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1) + border.width: 1 + implicitHeight: height + implicitWidth: width + + default property alias content: container.data + property int paddings : 0 + property int leftPadding : 0 + property int rightPadding : 0 + property int topPadding : 0 + property int bottomPadding : 0 + + Item { + id: container + anchors.fill: parent + anchors.leftMargin: Math.max(paddings,leftPadding) + anchors.rightMargin: Math.max(paddings,rightPadding) + anchors.topMargin: Math.max(paddings,topPadding) + anchors.bottomMargin: Math.max(paddings,bottomPadding) + } + +} diff --git a/src/controls/FluContentPage.qml b/src/controls/FluContentPage.qml new file mode 100644 index 00000000..aa6051f5 --- /dev/null +++ b/src/controls/FluContentPage.qml @@ -0,0 +1,29 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import FluentUI 1.0 + +Item { + + id:root + + property alias title: text_title.text + default property alias content: container.data + + FluText{ + id:text_title + fontStyle: FluText.TitleLarge + } + + Item{ + clip: true + id:container + anchors{ + top: text_title.bottom + bottom: parent.bottom + } + width: parent.width + } + +} diff --git a/src/controls/FluExpander.qml b/src/controls/FluExpander.qml index 0b4c8ea6..bde00d54 100644 --- a/src/controls/FluExpander.qml +++ b/src/controls/FluExpander.qml @@ -10,6 +10,8 @@ Item { id:root height: layout_header.height + container.height width: 400 + implicitWidth: width + implicitHeight: height property int contentHeight : 300 diff --git a/src/controls/FluIconButton.qml b/src/controls/FluIconButton.qml index 48da6e30..36deb1ac 100644 --- a/src/controls/FluIconButton.qml +++ b/src/controls/FluIconButton.qml @@ -14,9 +14,9 @@ Rectangle { property bool disabled: false property bool hovered: button_mouse.containsMouse - property color hoverColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(244/255,244/255,244/255,1) - property color normalColor: FluTheme.isDark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) - property color disableColor: FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(1,1,1,1) + property color hoverColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(0,0,0,0.03) + property color normalColor: FluTheme.isDark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) + property color disableColor: FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(0,0,0,0) property color textColor: { if(FluTheme.isDark){ diff --git a/src/controls/FluNavigationView.qml b/src/controls/FluNavigationView.qml new file mode 100644 index 00000000..f734a273 --- /dev/null +++ b/src/controls/FluNavigationView.qml @@ -0,0 +1,341 @@ +import QtQuick 2.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import FluentUI 1.0 + +Item { + + id:root + + property FluObject items + property FluObject footerItems + + property int displayMode: width<=700 ? FluNavigationView.Minimal : FluNavigationView.Open + + property bool displaMinimalNav : false + + onDisplayModeChanged: { + if(displayMode === FluNavigationView.Minimal){ + anim_navi.enabled = false + displaMinimalNav = false + timer_anim_enable.restart() + } + } + + Timer{ + id:timer_anim_enable + interval: 150 + onTriggered: { + anim_navi.enabled = true + } + } + + enum DisplayMode { + Minimal, + Open, + Auto + } + + property var window : { + if(Window.window == null) + return null + return Window.window + } + + Component{ + id:com_panel_item_separatorr + FluDivider{ + width: nav_list.width + height: 1 + } + } + + Component{ + id:com_panel_item_header + Item{ + height: 30 + width: nav_list.width + FluText{ + text:model.title + fontStyle: FluText.BodyStrong + anchors{ + bottom: parent.bottom + left:parent.left + leftMargin: 10 + } + } + } + } + + Component{ + id:com_panel_item + Item{ + height: 38 + width: nav_list.width + + Rectangle{ + radius: 4 + anchors{ + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + topMargin: 2 + bottomMargin: 2 + leftMargin: 6 + rightMargin: 6 + } + MouseArea{ + id:item_mouse + hoverEnabled: true + anchors.fill: parent + onClicked: { + if(type===0){ + model.repTap() + if(nav_list.currentIndex !== position){ + nav_list.currentIndex = position + model.tap() + } + }else{ + model.tap() + } + } + } + color: { + if(FluTheme.isDark){ + if((nav_list.currentIndex === position)&&type===0){ + return "#2D2D2D" + } + if(item_mouse.containsMouse){ + return "#292929" + } + return Qt.rgba(0,0,0,0) + }else{ + if(item_mouse.containsMouse){ + return Qt.rgba(0,0,0,0.03) + } + if(nav_list.currentIndex === position&&type===0){ + return Qt.rgba(0,0,0,0.06) + } + return Qt.rgba(0,0,0,0) + } + } + + FluText{ + text:model.title + anchors{ + verticalCenter: parent.verticalCenter + left:parent.left + leftMargin: 14 + } + } + } + } + } + + + Item { + id:nav_app_bar + width: parent.width + height: 38 + + RowLayout{ + height:parent.height + spacing: 0 + FluIconButton{ + icon: FluentIcons.FA_arrow_left + Layout.leftMargin: 5 + Layout.alignment: Qt.AlignVCenter + disabled: nav_swipe.depth === 1 + onClicked: { + nav_swipe.pop() + nav_list.stackIndex.pop() + var index = nav_list.stackIndex[nav_list.stackIndex.length-1] + nav_list.enableStack = false + nav_list.currentIndex = index + nav_list.enableStack = true + } + } + FluIconButton{ + icon: FluentIcons.FA_navicon + Layout.leftMargin: 5 + visible: displayMode === FluNavigationView.Minimal + Layout.alignment: Qt.AlignVCenter + onClicked: { + displaMinimalNav = !displaMinimalNav + } + } + } + + + RowLayout{ + anchors{ + right: parent.right + rightMargin: 14 + verticalCenter: parent.verticalCenter + } + spacing: 5 + FluText{ + text:"夜间模式" + fontStyle: FluText.Body + } + FluToggleSwitch{ + checked: FluTheme.isDark + onClickFunc:function(){ + FluTheme.isDark = !FluTheme.isDark + } + } + } + } + + Item{ + anchors{ + left: displayMode === FluNavigationView.Minimal ? parent.left : layout_list.right + leftMargin: 2 + top: nav_app_bar.bottom + right: parent.right + rightMargin: 10 + bottom: parent.bottom + bottomMargin: 20 + } + + StackView{ + id:nav_swipe + anchors.fill: parent + clip: true + anchors.margins: 10 + popEnter : Transition{} + popExit : Transition{} + pushEnter : Transition{} + pushExit : Transition{} + replaceEnter : Transition{} + replaceExit : Transition{} + } + } + + MouseArea{ + anchors.fill: parent + enabled: (displayMode === FluNavigationView.Minimal && displaMinimalNav) + onClicked: { + displaMinimalNav = false + } + } + + Rectangle{ + id:layout_list + width: 300 + anchors{ + top: nav_app_bar.bottom + bottom: parent.bottom + } + x: { + if(displayMode !== FluNavigationView.Minimal) + return 0 + return (displayMode === FluNavigationView.Minimal && displaMinimalNav) ? 0 : -width + } + Behavior on x{ + id:anim_navi + NumberAnimation{ + duration: 150 + } + } + color: { + if(displayMode === FluNavigationView.Minimal){ + return FluTheme.isDark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(243/255,243/255,243/255,1) + } + if(window && window.active){ + return FluTheme.isDark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(238/255,244/255,249/255,1) + } + return FluTheme.isDark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1) + } + Behavior on color{ + ColorAnimation { + duration: 300 + } + } + ListView{ + id:nav_list + property bool enableStack: true + property var stackIndex: [] + clip: true + anchors{ + top: parent.top + left: parent.left + right: parent.right + bottom: layout_footer.top + } + currentIndex: -1 + onCurrentIndexChanged: { + if(enableStack){ + stackIndex.push(currentIndex) + } + } + model:{ + if(items){ + return items.children + } + } + boundsBehavior: ListView.StopAtBounds + delegate: Loader{ + property var model: modelData + property var position: index + property int type: 0 + sourceComponent: { + if(modelData instanceof FluPaneItem){ + return com_panel_item + } + if(modelData instanceof FluPaneItemHeader){ + return com_panel_item_header + } + if(modelData instanceof FluPaneItemSeparator){ + return com_panel_item_separatorr + } + } + } + } + + ListView{ + id:layout_footer + width: layout_list.width + height: childrenRect.height + anchors.bottom: parent.bottom + boundsBehavior: ListView.StopAtBounds + model: { + if(footerItems){ + return footerItems.children + } + } + currentIndex: -1 + delegate: Loader{ + property var model: modelData + property var position: index + property int type: 1 + sourceComponent: { + if(modelData instanceof FluPaneItem){ + return com_panel_item + } + if(modelData instanceof FluPaneItemHeader){ + return com_panel_item_header + } + if(modelData instanceof FluPaneItemSeparator){ + return com_panel_item_separatorr + } + } + } + } + + } + + + + function push(url){ + nav_swipe.push(url) + } + + function setCurrentIndex(index){ + nav_list.currentIndex = index + } + +} diff --git a/src/controls/FluPaneItem.qml b/src/controls/FluPaneItem.qml new file mode 100644 index 00000000..374bc072 --- /dev/null +++ b/src/controls/FluPaneItem.qml @@ -0,0 +1,7 @@ +import QtQuick 2.15 + +QtObject { + property string title + signal tap + signal repTap +} diff --git a/src/controls/FluPaneItemHeader.qml b/src/controls/FluPaneItemHeader.qml new file mode 100644 index 00000000..63d47894 --- /dev/null +++ b/src/controls/FluPaneItemHeader.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +QtObject { + property string title +} diff --git a/src/controls/FluPaneItemSeparator.qml b/src/controls/FluPaneItemSeparator.qml new file mode 100644 index 00000000..9dfda865 --- /dev/null +++ b/src/controls/FluPaneItemSeparator.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +QtObject { + +} diff --git a/src/controls/FluScrollablePage.qml b/src/controls/FluScrollablePage.qml new file mode 100644 index 00000000..a3aa02d8 --- /dev/null +++ b/src/controls/FluScrollablePage.qml @@ -0,0 +1,34 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import FluentUI 1.0 + +Item { + + id:root + + property alias title: text_title.text + default property alias content: container.data + property int spacing : 5 + + FluText{ + id:text_title + fontStyle: FluText.TitleLarge + } + + ScrollView{ + clip: true + width: parent.width + contentWidth: parent.width + anchors{ + top: text_title.bottom + bottom: parent.bottom + } + ColumnLayout{ + id:container + spacing: root.spacing + width: parent.width + } + } +} diff --git a/src/controls/FluTreeView.qml b/src/controls/FluTreeView.qml index 277d942c..251f7bb9 100644 --- a/src/controls/FluTreeView.qml +++ b/src/controls/FluTreeView.qml @@ -5,9 +5,8 @@ import QtQuick.Controls 2.15 import FluentUI 1.0 import QtGraphicalEffects 1.15 -Rectangle { +Item { id:root - color: FluTheme.isDark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1) enum TreeViewSelectionMode { None, @@ -101,12 +100,12 @@ Rectangle { if(item_layout.singleSelected && selectionMode === FluTreeView.Single){ return Qt.rgba(62/255,62/255,62/255,1) } - return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(62/255,62/255,62/255,1):Qt.rgba(50/255,50/255,50/255,1) + return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(62/255,62/255,62/255,1):Qt.rgba(0,0,0,0) }else{ if(item_layout.singleSelected && selectionMode === FluTreeView.Single){ - return Qt.rgba(244/255,244/255,244/255,1) + return Qt.rgba(0,0,0,0.06) } - return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(244/255,244/255,244/255,1):Qt.rgba(253/255,253/255,253/255,1) + return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(0,0,0,0.03):Qt.rgba(0,0,0,0) } } diff --git a/src/controls/FluWindow.qml b/src/controls/FluWindow.qml index 10509c3d..3d046c4d 100644 --- a/src/controls/FluWindow.qml +++ b/src/controls/FluWindow.qml @@ -60,6 +60,7 @@ Item { color:root.color anchors.fill: parent anchors.margins: borderless + clip: true Behavior on color{ ColorAnimation { duration: 300 diff --git a/src/res.qrc b/src/res.qrc index d530b183..8eb51068 100644 --- a/src/res.qrc +++ b/src/res.qrc @@ -36,5 +36,12 @@ controls/FluTreeView.qml controls/FluExpander.qml controls/FluAutoSuggestBox.qml + controls/FluNavigationView.qml + controls/FluPaneItem.qml + controls/FluPaneItemHeader.qml + controls/FluPaneItemSeparator.qml + controls/FluScrollablePage.qml + controls/FluContentPage.qml + controls/FluArea.qml