From 023776dbe8b5e73f5ddba0e1bb80391ceb45bd69 Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Tue, 22 Apr 2025 22:33:25 +0800
Subject: [PATCH 1/9] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DFluTableView?=
=?UTF-8?q?=E9=94=99=E4=BD=8D=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FluentUI/Controls/FluTableView.qml | 46 ++++++++-----------
.../FluentUI/Controls/FluTableView.qml | 46 ++++++++-----------
2 files changed, 36 insertions(+), 56 deletions(-)
diff --git a/src/Qt5/imports/FluentUI/Controls/FluTableView.qml b/src/Qt5/imports/FluentUI/Controls/FluTableView.qml
index 681200aa..6fb39b4f 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluTableView.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluTableView.qml
@@ -266,30 +266,18 @@ Rectangle {
d.rowHoverIndex = row
}
onWidthChanged: {
- if(editVisible){
- updateEditPosition()
- }
- if(isMainTable){
- updateTableItem()
- }
+ updatePosition()
}
onHeightChanged: {
- if(editVisible){
- updateEditPosition()
- }
- if(isMainTable){
- updateTableItem()
- }
+ updatePosition()
}
onXChanged: {
- if(editVisible){
- updateEditPosition()
- }
- if(isMainTable){
- updateTableItem()
- }
+ updatePosition()
}
onYChanged: {
+ updatePosition()
+ }
+ function updatePosition(){
if(editVisible){
updateEditPosition()
}
@@ -310,9 +298,11 @@ Rectangle {
}
function updateTableItem(){
var columnModel = control.columnSource[column]
- columnModel.x = item_table_mouse.x
- columnModel.y = item_table_mouse.y
- d.tableItemLayout(column)
+ if(columnModel.x !== item_table_mouse.x || columnModel.y !== item_table_mouse.y){
+ columnModel.x = item_table_mouse.x
+ columnModel.y = item_table_mouse.y
+ d.tableItemLayout(column)
+ }
}
Rectangle{
anchors.fill: parent
@@ -352,6 +342,7 @@ Rectangle {
}
FluLoader{
id: item_table_loader
+ property var tableView: control
property var model: item_table_mouse._model
property var display: rowModel[columnModel.dataIndex]
property var rowModel : model.rowModel
@@ -445,10 +436,6 @@ Rectangle {
}
}
- onWidthChanged:{
- table_view.forceLayout()
- }
-
MouseArea{
id:layout_mouse_table
hoverEnabled: true
@@ -479,6 +466,9 @@ Rectangle {
table_view.flick(0,1)
}
delegate: com_table_delegate
+ onWidthChanged: {
+ Qt.callLater(forceLayout)
+ }
}
}
@@ -955,18 +945,18 @@ Rectangle {
target: d
function onTableItemLayout(column){
if(item_layout_frozen._index === column){
- updateLayout()
+ Qt.callLater(updateLayout)
}
}
}
Connections{
target: table_view
function onContentXChanged(){
- updateLayout()
+ Qt.callLater(updateLayout)
}
}
function updateLayout(){
- width = table_view.columnWidthProvider(_index)
+ width = Qt.binding(() => table_view.columnWidthProvider(_index))
x = Qt.binding(function(){
var minX = 0
var maxX = table_view.width-width
diff --git a/src/Qt6/imports/FluentUI/Controls/FluTableView.qml b/src/Qt6/imports/FluentUI/Controls/FluTableView.qml
index 7efea849..100be1d9 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluTableView.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluTableView.qml
@@ -266,30 +266,18 @@ Rectangle {
d.rowHoverIndex = row
}
onWidthChanged: {
- if(editVisible){
- updateEditPosition()
- }
- if(isMainTable){
- updateTableItem()
- }
+ updatePosition()
}
onHeightChanged: {
- if(editVisible){
- updateEditPosition()
- }
- if(isMainTable){
- updateTableItem()
- }
+ updatePosition()
}
onXChanged: {
- if(editVisible){
- updateEditPosition()
- }
- if(isMainTable){
- updateTableItem()
- }
+ updatePosition()
}
onYChanged: {
+ updatePosition()
+ }
+ function updatePosition(){
if(editVisible){
updateEditPosition()
}
@@ -310,9 +298,11 @@ Rectangle {
}
function updateTableItem(){
var columnModel = control.columnSource[column]
- columnModel.x = item_table_mouse.x
- columnModel.y = item_table_mouse.y
- d.tableItemLayout(column)
+ if(columnModel.x !== item_table_mouse.x || columnModel.y !== item_table_mouse.y){
+ columnModel.x = item_table_mouse.x
+ columnModel.y = item_table_mouse.y
+ d.tableItemLayout(column)
+ }
}
Rectangle{
anchors.fill: parent
@@ -352,6 +342,7 @@ Rectangle {
}
FluLoader{
id: item_table_loader
+ property var tableView: control
property var model: item_table_mouse._model
property var display: rowModel[columnModel.dataIndex]
property var rowModel : model.rowModel
@@ -445,10 +436,6 @@ Rectangle {
}
}
- onWidthChanged:{
- table_view.forceLayout()
- }
-
MouseArea{
id:layout_mouse_table
hoverEnabled: true
@@ -479,6 +466,9 @@ Rectangle {
table_view.flick(0,1)
}
delegate: com_table_delegate
+ onWidthChanged: {
+ Qt.callLater(forceLayout)
+ }
}
}
@@ -955,18 +945,18 @@ Rectangle {
target: d
function onTableItemLayout(column){
if(item_layout_frozen._index === column){
- updateLayout()
+ Qt.callLater(updateLayout)
}
}
}
Connections{
target: table_view
function onContentXChanged(){
- updateLayout()
+ Qt.callLater(updateLayout)
}
}
function updateLayout(){
- width = table_view.columnWidthProvider(_index)
+ width = Qt.binding(() => table_view.columnWidthProvider(_index))
x = Qt.binding(function(){
var minX = 0
var maxX = table_view.width-width
From 5de9588b93e80813360b04e6bd02d4ef65627306 Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Wed, 7 May 2025 23:15:32 +0800
Subject: [PATCH 2/9] =?UTF-8?q?feat:=20FluAutoSuggestBox=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=BB=BA=E8=AE=AE=E8=A1=8C=E6=95=B0=E5=92=8C?=
=?UTF-8?q?=E8=A1=8C=E9=AB=98=E4=BB=A5=E5=8F=8Apressed=E6=97=B6=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=E5=BB=BA=E8=AE=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
example/example_en_US.ts | 9 ++++--
example/example_zh_CN.ts | 9 ++++--
example/qml/page/T_TextBox.qml | 17 +++++++++--
.../FluentUI/Controls/FluAutoSuggestBox.qml | 29 +++++++++++--------
.../FluentUI/Controls/FluAutoSuggestBox.qml | 29 +++++++++++--------
5 files changed, 62 insertions(+), 31 deletions(-)
diff --git a/example/example_en_US.ts b/example/example_en_US.ts
index 390f78c6..802e0585 100644
--- a/example/example_en_US.ts
+++ b/example/example_en_US.ts
@@ -2487,8 +2487,8 @@ Some contents...
-
-
+
+
Disabled
@@ -2507,6 +2507,11 @@ Some contents...
AutoSuggestBox
+
+
+ Show suggest when pressed
+
+
T_Theme
diff --git a/example/example_zh_CN.ts b/example/example_zh_CN.ts
index 6796d1c0..00981b6d 100644
--- a/example/example_zh_CN.ts
+++ b/example/example_zh_CN.ts
@@ -2676,8 +2676,8 @@ Some contents...
-
-
+
+
Disabled
禁用
@@ -2696,6 +2696,11 @@ Some contents...
AutoSuggestBox
自动建议框
+
+
+ Show suggest when pressed
+ 按下时显示建议
+
T_Theme
diff --git a/example/qml/page/T_TextBox.qml b/example/qml/page/T_TextBox.qml
index 357720d2..ab722ba5 100644
--- a/example/qml/page/T_TextBox.qml
+++ b/example/qml/page/T_TextBox.qml
@@ -114,18 +114,26 @@ FluScrollablePage{
placeholderText: qsTr("AutoSuggestBox")
items: generateRandomNames(100)
disabled: text_box_suggest_switch.checked
+ itemRows: 12
+ showSuggestWhenPressed: text_box_show_suggest_switch.checked
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
}
- FluToggleSwitch{
- id:text_box_suggest_switch
+ RowLayout{
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
}
- text: qsTr("Disabled")
+ FluToggleSwitch{
+ id:text_box_show_suggest_switch
+ text: qsTr("Show suggest when pressed")
+ }
+ FluToggleSwitch{
+ id:text_box_suggest_switch
+ text: qsTr("Disabled")
+ }
}
}
CodeExpander{
@@ -133,6 +141,9 @@ FluScrollablePage{
Layout.topMargin: -6
code:'FluAutoSuggestBox{
placeholderText: qsTr("AutoSuggestBox")
+ itemRows: 12
+ itemHeight: 38
+ showSuggestWhenPressed: false
}'
}
diff --git a/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml b/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml
index 4cf102ed..9f28175c 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml
@@ -7,9 +7,12 @@ FluTextBox{
property var items:[]
property string emptyText: qsTr("No results found")
property int autoSuggestBoxReplacement: FluentIcons.Search
+ property int itemHeight: 38
+ property int itemRows: 8
+ property bool showSuggestWhenPressed: false
property string textRole: "title"
property var filter: function(item){
- if(item.title.indexOf(control.text)!==-1){
+ if(item[textRole].indexOf(control.text)!==-1){
return true
}
return false
@@ -29,17 +32,11 @@ FluTextBox{
control.updateText(modelData[textRole])
}
function loadData(){
- var result = []
if(items==null){
- list_view.model = result
+ list_view.model = []
return
}
- items.map(function(item){
- if(control.filter(item)){
- result.push(item)
- }
- })
- list_view.model = result
+ list_view.model = items.filter(item => control.filter(item))
}
}
onActiveFocusChanged: {
@@ -69,7 +66,7 @@ FluTextBox{
ScrollBar.vertical: FluScrollBar {}
header: Item{
width: control.width
- height: visible ? 38 : 0
+ height: visible ? control.itemHeight : 0
visible: list_view.count === 0
FluText{
text: emptyText
@@ -82,7 +79,7 @@ FluTextBox{
}
delegate:FluControl{
id: item_control
- height: 38
+ height: control.itemHeight
width: control.width
onClicked: {
d.handleClick(modelData)
@@ -114,7 +111,7 @@ FluTextBox{
background:Rectangle{
id: rect_background
implicitWidth: control.width
- implicitHeight: 38*Math.min(Math.max(list_view.count,1),8)
+ implicitHeight: control.itemHeight*Math.min(Math.max(list_view.count,1),control.itemRows)
radius: 5
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
@@ -124,6 +121,14 @@ FluTextBox{
}
}
onTextChanged: {
+ control.showSuggest()
+ }
+ onPressed: {
+ if(control.showSuggestWhenPressed){
+ control.showSuggest()
+ }
+ }
+ function showSuggest(){
d.loadData()
if(d.flagVisible){
var pos = control.mapToItem(null, 0, 0)
diff --git a/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml b/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml
index 18119013..93697196 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml
@@ -6,9 +6,12 @@ FluTextBox{
property var items:[]
property string emptyText: qsTr("No results found")
property int autoSuggestBoxReplacement: FluentIcons.Search
+ property int itemHeight: 38
+ property int itemRows: 8
+ property bool showSuggestWhenPressed: false
property string textRole: "title"
property var filter: function(item){
- if(item.title.indexOf(control.text)!==-1){
+ if(item[textRole].indexOf(control.text)!==-1){
return true
}
return false
@@ -28,17 +31,11 @@ FluTextBox{
control.updateText(modelData[textRole])
}
function loadData(){
- var result = []
if(items==null){
- list_view.model = result
+ list_view.model = []
return
}
- items.map(function(item){
- if(control.filter(item)){
- result.push(item)
- }
- })
- list_view.model = result
+ list_view.model = items.filter(item => control.filter(item))
}
}
onActiveFocusChanged: {
@@ -68,7 +65,7 @@ FluTextBox{
ScrollBar.vertical: FluScrollBar {}
header: Item{
width: control.width
- height: visible ? 38 : 0
+ height: visible ? control.itemHeight : 0
visible: list_view.count === 0
FluText{
text: emptyText
@@ -81,7 +78,7 @@ FluTextBox{
}
delegate:FluControl{
id: item_control
- height: 38
+ height: control.itemHeight
width: control.width
onClicked: {
d.handleClick(modelData)
@@ -113,7 +110,7 @@ FluTextBox{
background:Rectangle{
id: rect_background
implicitWidth: control.width
- implicitHeight: 38*Math.min(Math.max(list_view.count,1),8)
+ implicitHeight: control.itemHeight*Math.min(Math.max(list_view.count,1),control.itemRows)
radius: 5
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
@@ -123,6 +120,14 @@ FluTextBox{
}
}
onTextChanged: {
+ control.showSuggest()
+ }
+ onPressed: {
+ if(control.showSuggestWhenPressed){
+ control.showSuggest()
+ }
+ }
+ function showSuggest(){
d.loadData()
if(d.flagVisible){
var pos = control.mapToItem(null, 0, 0)
From 99c77d2786629f632d8160ce5e0e10e6adcd1317 Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Fri, 9 May 2025 08:22:09 +0800
Subject: [PATCH 3/9] =?UTF-8?q?feat:=20FluBadge=E6=94=AF=E6=8C=81=E8=AE=BE?=
=?UTF-8?q?=E7=BD=AEmax=E5=92=8Cposition?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
example/qml/page/T_Badge.qml | 81 ++++++++++++++++--
.../imports/FluentUI/Controls/FluBadge.qml | 85 ++++++++++++-------
.../imports/FluentUI/Controls/FluBadge.qml | 85 ++++++++++++-------
3 files changed, 178 insertions(+), 73 deletions(-)
diff --git a/example/qml/page/T_Badge.qml b/example/qml/page/T_Badge.qml
index 6a2db9c5..941fc241 100644
--- a/example/qml/page/T_Badge.qml
+++ b/example/qml/page/T_Badge.qml
@@ -26,7 +26,8 @@ FluScrollablePage{
width: parent.width
text: qsTr("It usually appears in the upper right corner of the notification icon or avatar to display the number of messages that need to be processed")
}
- Row{
+ Flow{
+ width: parent.width
spacing: 20
Rectangle{
width: 40
@@ -34,7 +35,7 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
count:0
}
@@ -46,7 +47,7 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
count:5
}
@@ -57,7 +58,7 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
count:50
}
@@ -68,9 +69,10 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
- count:100
+ count:1000
+ max: 999
}
}
Rectangle{
@@ -79,7 +81,7 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
isDot:true
}
@@ -90,7 +92,7 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
count:99
color: Qt.rgba(250/255,173/255,20/255,1)
@@ -102,12 +104,71 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
- topRight: true
+ position: "topRight"
showZero: true
count:99
color: Qt.rgba(82/255,196/255,26/255,1)
}
}
+ Rectangle{
+ width: 40
+ height: 40
+ radius: 8
+ color: Qt.rgba(191/255,191/255,191/255,1)
+ FluBadge{
+ position: "topRight"
+ showZero: true
+ count:100
+ color: Qt.rgba(84/255,169/255,1,1)
+ }
+ }
+ Rectangle{
+ width: 40
+ height: 40
+ radius: 8
+ color: Qt.rgba(191/255,191/255,191/255,1)
+ FluBadge{
+ position: "bottomLeft"
+ showZero: true
+ count:100
+ color: Qt.rgba(84/255,169/255,1,1)
+ }
+ }
+ Rectangle{
+ width: 40
+ height: 40
+ radius: 8
+ color: Qt.rgba(191/255,191/255,191/255,1)
+ FluBadge{
+ position: "topLeft"
+ showZero: true
+ count:100
+ color: Qt.rgba(84/255,169/255,1,1)
+ }
+ }
+ Rectangle{
+ width: 40
+ height: 40
+ radius: 8
+ color: Qt.rgba(191/255,191/255,191/255,1)
+ FluBadge{
+ position: "bottomRight"
+ showZero: true
+ count:100
+ color: Qt.rgba(84/255,169/255,1,1)
+ }
+ }
+ Rectangle{
+ width: 40
+ height: 40
+ radius: 8
+ color: Qt.rgba(191/255,191/255,191/255,1)
+ FluBadge{
+ position: "topRight"
+ count: "NEW"
+ color: Qt.rgba(84/255,169/255,1,1)
+ }
+ }
}
}
}
@@ -120,7 +181,9 @@ FluScrollablePage{
radius: 8
color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{
+ position: "topRight"
count: 100
+ max: 99
isDot: false
color: Qt.rgba(82/255,196/255,26/255,1)
}
diff --git a/src/Qt5/imports/FluentUI/Controls/FluBadge.qml b/src/Qt5/imports/FluentUI/Controls/FluBadge.qml
index 32fe084c..22086a7d 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluBadge.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluBadge.qml
@@ -5,19 +5,15 @@ import FluentUI 1.0
Rectangle{
property bool isDot: false
property bool showZero: false
- property int count: 0
- property bool topRight: false
+ property var count: 0
+ property int max: 99
+ property string position: "" // topLeft, topRight, bottomLeft, bottomRight
id:control
color:Qt.rgba(255/255,77/255,79/255,1)
width: {
if(isDot)
return 10
- if(count<10){
- return 20
- }else if(count<100){
- return 30
- }
- return 40
+ return content_text.implicitWidth + 12
}
height: {
if(isDot)
@@ -31,49 +27,74 @@ Rectangle{
}
border.width: 1
border.color: Qt.rgba(1,1,1,1)
- anchors{
+ anchors {
+ left: {
+ if(!parent){
+ return undefined
+ }
+ return (position === "topLeft" || position === "bottomLeft") ? parent.left : undefined
+ }
right: {
- if(parent && topRight)
- return parent.right
- return undefined
+ if(!parent){
+ return undefined
+ }
+ return (position === "topRight" || position === "bottomRight") ? parent.right : undefined
}
top: {
- if(parent && topRight)
- return parent.top
- return undefined
+ if(!parent){
+ return undefined
+ }
+ return (position === "topLeft" || position === "topRight") ? parent.top : undefined
+ }
+ bottom: {
+ if(!parent){
+ return undefined
+ }
+ return (position === "bottomLeft" || position === "bottomRight") ? parent.bottom : undefined
+ }
+ leftMargin: {
+ if(!parent){
+ return 0
+ }
+ return (position === "topLeft" || position === "bottomLeft") ? (isDot ? -2.5 : -(width / 2)) : 0
}
rightMargin: {
- if(parent && topRight){
- if(isDot){
- return -2.5
- }
- return -(control.width/2)
+ if(!parent){
+ return 0
}
- return 0
+ return (position === "topRight" || position === "bottomRight") ? (isDot ? -2.5 : -(width / 2)) : 0
}
topMargin: {
- if(parent && topRight){
- if(isDot){
- return -2.5
- }
- return -10
+ if(!parent){
+ return 0
}
- return 0
+ return (position === "topLeft" || position === "topRight") ? (isDot ? -2.5 : -10) : 0
+ }
+ bottomMargin: {
+ if(!parent){
+ return 0
+ }
+ return (position === "bottomLeft" || position === "bottomRight") ? (isDot ? -2.5 : -10) : 0
}
}
visible: {
- if(showZero)
- return true
- return count!==0
+ if(typeof(count) === "number"){
+ return showZero ? true : count !== 0
+ }
+ return true
}
FluText{
+ id: content_text
anchors.centerIn: parent
color: Qt.rgba(1,1,1,1)
visible: !isDot
text:{
- if(count<100)
+ if(typeof(count) === "string"){
return count
- return "100+"
+ }else if(typeof(count) === "number"){
+ return count <= max ? count.toString() : "%1+".arg(max.toString())
+ }
+ return ""
}
}
}
diff --git a/src/Qt6/imports/FluentUI/Controls/FluBadge.qml b/src/Qt6/imports/FluentUI/Controls/FluBadge.qml
index 2e88c728..2c390c48 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluBadge.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluBadge.qml
@@ -5,19 +5,15 @@ import FluentUI
Rectangle{
property bool isDot: false
property bool showZero: false
- property int count: 0
- property bool topRight: false
+ property var count: 0
+ property int max: 99
+ property string position: "" // topLeft, topRight, bottomLeft, bottomRight
id:control
color:Qt.rgba(255/255,77/255,79/255,1)
width: {
if(isDot)
return 10
- if(count<10){
- return 20
- }else if(count<100){
- return 30
- }
- return 40
+ return content_text.implicitWidth + 12
}
height: {
if(isDot)
@@ -31,49 +27,74 @@ Rectangle{
}
border.width: 1
border.color: Qt.rgba(1,1,1,1)
- anchors{
+ anchors {
+ left: {
+ if(!parent){
+ return undefined
+ }
+ return (position === "topLeft" || position === "bottomLeft") ? parent.left : undefined
+ }
right: {
- if(parent && topRight)
- return parent.right
- return undefined
+ if(!parent){
+ return undefined
+ }
+ return (position === "topRight" || position === "bottomRight") ? parent.right : undefined
}
top: {
- if(parent && topRight)
- return parent.top
- return undefined
+ if(!parent){
+ return undefined
+ }
+ return (position === "topLeft" || position === "topRight") ? parent.top : undefined
+ }
+ bottom: {
+ if(!parent){
+ return undefined
+ }
+ return (position === "bottomLeft" || position === "bottomRight") ? parent.bottom : undefined
+ }
+ leftMargin: {
+ if(!parent){
+ return 0
+ }
+ return (position === "topLeft" || position === "bottomLeft") ? (isDot ? -2.5 : -(width / 2)) : 0
}
rightMargin: {
- if(parent && topRight){
- if(isDot){
- return -2.5
- }
- return -(control.width/2)
+ if(!parent){
+ return 0
}
- return 0
+ return (position === "topRight" || position === "bottomRight") ? (isDot ? -2.5 : -(width / 2)) : 0
}
topMargin: {
- if(parent && topRight){
- if(isDot){
- return -2.5
- }
- return -10
+ if(!parent){
+ return 0
}
- return 0
+ return (position === "topLeft" || position === "topRight") ? (isDot ? -2.5 : -10) : 0
+ }
+ bottomMargin: {
+ if(!parent){
+ return 0
+ }
+ return (position === "bottomLeft" || position === "bottomRight") ? (isDot ? -2.5 : -10) : 0
}
}
visible: {
- if(showZero)
- return true
- return count!==0
+ if(typeof(count) === "number"){
+ return showZero ? true : count !== 0
+ }
+ return true
}
FluText{
+ id: content_text
anchors.centerIn: parent
color: Qt.rgba(1,1,1,1)
visible: !isDot
text:{
- if(count<100)
+ if(typeof(count) === "string"){
return count
- return "100+"
+ }else if(typeof(count) === "number"){
+ return count <= max ? count.toString() : "%1+".arg(max.toString())
+ }
+ return ""
}
}
}
From 49e96b094b780c1b625af349bb5bc0107fa28d61 Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Sat, 10 May 2025 20:38:01 +0800
Subject: [PATCH 4/9] =?UTF-8?q?feat:=20FluRectangle=E6=94=AF=E6=8C=81borde?=
=?UTF-8?q?r=E7=BB=98=E5=88=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
example/qml/page/T_Rectangle.qml | 18 +++++++
src/FluRectangle.cpp | 62 ++++++++++++++++-------
src/FluRectangle.h | 4 ++
src/Qt5/imports/FluentUI/plugins.qmltypes | 17 +++++--
4 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/example/qml/page/T_Rectangle.qml b/example/qml/page/T_Rectangle.qml
index edd8d153..08a016ca 100644
--- a/example/qml/page/T_Rectangle.qml
+++ b/example/qml/page/T_Rectangle.qml
@@ -58,6 +58,22 @@ FluScrollablePage{
color:"#b4009e"
radius:[0,0,0,15]
}
+ FluRectangle{
+ width: 50
+ height: 50
+ color:"#a8d5ba"
+ radius:[15,15,15,15]
+ borderWidth: 3
+ borderColor: "#5b8a72"
+ }
+ FluRectangle{
+ width: 50
+ height: 50
+ color:"#dbe2ef"
+ radius:[15,0,0,0]
+ borderWidth: 2
+ borderColor: "#3f72af"
+ }
}
}
}
@@ -66,6 +82,8 @@ FluScrollablePage{
Layout.topMargin: -6
code:'FluRectangle{
radius: [25,25,25,25]
+ borderWidth: 2
+ borderColor: "#000000"
width: 50
height: 50
}'
diff --git a/src/FluRectangle.cpp b/src/FluRectangle.cpp
index 00890a76..fdd69d5f 100644
--- a/src/FluRectangle.cpp
+++ b/src/FluRectangle.cpp
@@ -2,33 +2,61 @@
#include
FluRectangle::FluRectangle(QQuickItem *parent) : QQuickPaintedItem(parent) {
- color(QColor(255, 255, 255, 255));
+ color(Qt::white);
radius({0, 0, 0, 0});
+ borderWidth(0);
+ borderColor(Qt::black);
connect(this, &FluRectangle::colorChanged, this, [=] { update(); });
connect(this, &FluRectangle::radiusChanged, this, [=] { update(); });
+ connect(this, &FluRectangle::borderWidthChanged, this, [=] { update(); });
+ connect(this, &FluRectangle::borderColorChanged, this, [=] { update(); });
}
+bool FluRectangle::borderValid() const {
+ return qRound(_borderWidth) >= 1 && _color.isValid() && _color.alpha() > 0;
+}
void FluRectangle::paint(QPainter *painter) {
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
- QPainterPath path;
+
QRectF rect = boundingRect();
- path.moveTo(rect.bottomRight() - QPointF(0, _radius[2]));
- path.lineTo(rect.topRight() + QPointF(0, _radius[1]));
- path.arcTo(QRectF(QPointF(rect.topRight() - QPointF(_radius[1] * 2, 0)),
- QSize(_radius[1] * 2, _radius[1] * 2)),
- 0, 90);
- path.lineTo(rect.topLeft() + QPointF(_radius[0], 0));
- path.arcTo(QRectF(QPointF(rect.topLeft()), QSize(_radius[0] * 2, _radius[0] * 2)), 90, 90);
- path.lineTo(rect.bottomLeft() - QPointF(0, _radius[3]));
- path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, _radius[3] * 2)),
- QSize(_radius[3] * 2, _radius[3] * 2)),
- 180, 90);
- path.lineTo(rect.bottomRight() - QPointF(_radius[2], 0));
- path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(_radius[2] * 2, _radius[2] * 2)),
- QSize(_radius[2] * 2, _radius[2] * 2)),
- 270, 90);
+ bool valid = borderValid();
+ if (valid) {
+ // 绘制边框时画笔的宽度从路径向两侧扩充
+ // 因此实际绘制的矩形应向内侧收缩边框宽度的一半,避免边框裁剪导致不完整
+ qreal halfBorderWidth = _borderWidth / 2.0;
+ rect.adjust(halfBorderWidth, halfBorderWidth, -halfBorderWidth, -halfBorderWidth);
+ }
+
+ QPainterPath path;
+ QList r = _radius;
+
+ while (r.size() < 4) {
+ r.append(0);
+ }
+
+ // 从右下角开始逆时针绘制圆角矩形路径
+ path.moveTo(rect.bottomRight() - QPointF(0, r[2]));
+ path.lineTo(rect.topRight() + QPointF(0, r[1]));
+ path.arcTo(QRectF(QPointF(rect.topRight() - QPointF(r[1] * 2, 0)), QSize(r[1] * 2, r[1] * 2)), 0, 90);
+
+ path.lineTo(rect.topLeft() + QPointF(r[0], 0));
+ path.arcTo(QRectF(QPointF(rect.topLeft()), QSize(r[0] * 2, r[0] * 2)), 90, 90);
+
+ path.lineTo(rect.bottomLeft() - QPointF(0, r[3]));
+ path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, r[3] * 2)), QSize(r[3] * 2, r[3] * 2)), 180, 90);
+
+ path.lineTo(rect.bottomRight() - QPointF(r[2], 0));
+ path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(r[2] * 2, r[2] * 2)), QSize(r[2] * 2, r[2] * 2)), 270, 90);
+
+ // 填充背景
painter->fillPath(path, _color);
+
+ // 绘制边框
+ if (valid) {
+ painter->strokePath(path, QPen(_borderColor, _borderWidth));
+ }
+
painter->restore();
}
diff --git a/src/FluRectangle.h b/src/FluRectangle.h
index 4690ff39..571af4f6 100644
--- a/src/FluRectangle.h
+++ b/src/FluRectangle.h
@@ -12,9 +12,13 @@ class FluRectangle : public QQuickPaintedItem {
Q_OBJECT
Q_PROPERTY_AUTO(QColor, color)
Q_PROPERTY_AUTO(QList, radius)
+ Q_PROPERTY_AUTO(qreal, borderWidth)
+ Q_PROPERTY_AUTO(QColor, borderColor)
QML_NAMED_ELEMENT(FluRectangle)
public:
explicit FluRectangle(QQuickItem *parent = nullptr);
+ bool borderValid() const;
+
void paint(QPainter *painter) override;
};
diff --git a/src/Qt5/imports/FluentUI/plugins.qmltypes b/src/Qt5/imports/FluentUI/plugins.qmltypes
index 26d694db..17e31c99 100644
--- a/src/Qt5/imports/FluentUI/plugins.qmltypes
+++ b/src/Qt5/imports/FluentUI/plugins.qmltypes
@@ -231,6 +231,8 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "color"; type: "QColor" }
Property { name: "radius"; type: "QList" }
+ Property { name: "borderWidth"; type: "double" }
+ Property { name: "borderColor"; type: "QColor" }
}
Component {
name: "FluSheetType"
@@ -2776,7 +2778,7 @@ Module {
}
Property {
name: "layoutMacosButtons"
- type: "FluLoader_QMLTYPE_14"
+ type: "FluLoader_QMLTYPE_11"
isReadonly: true
isPointer: true
}
@@ -2797,12 +2799,16 @@ Module {
Property { name: "items"; type: "QVariant" }
Property { name: "emptyText"; type: "string" }
Property { name: "autoSuggestBoxReplacement"; type: "int" }
+ Property { name: "itemHeight"; type: "int" }
+ Property { name: "itemRows"; type: "int" }
+ Property { name: "showSuggestWhenPressed"; type: "bool" }
Property { name: "textRole"; type: "string" }
Property { name: "filter"; type: "QVariant" }
Signal {
name: "itemClicked"
Parameter { name: "data"; type: "QVariant" }
}
+ Method { name: "showSuggest"; type: "QVariant" }
Method {
name: "updateText"
type: "QVariant"
@@ -2830,8 +2836,9 @@ Module {
defaultProperty: "data"
Property { name: "isDot"; type: "bool" }
Property { name: "showZero"; type: "bool" }
- Property { name: "count"; type: "int" }
- Property { name: "topRight"; type: "bool" }
+ Property { name: "count"; type: "QVariant" }
+ Property { name: "max"; type: "int" }
+ Property { name: "position"; type: "string" }
}
Component {
prototype: "QQuickItem"
@@ -3479,8 +3486,8 @@ Module {
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
Property { name: "topPadding"; type: "int" }
Property { name: "pageMode"; type: "int" }
- Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
- Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
+ Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_37"; isPointer: true }
+ Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_37"; isPointer: true }
Property { name: "navCompactWidth"; type: "int" }
Property { name: "navTopMargin"; type: "int" }
Property { name: "cellHeight"; type: "int" }
From b2fd3acda33c31cdd029eaa9b523a0ef75f9f31a Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Sun, 11 May 2025 22:18:37 +0800
Subject: [PATCH 5/9] =?UTF-8?q?feat:=20FluDatePicker=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E6=9C=88=E4=BB=BD=E6=97=B6=EF=BC=8C=E8=8B=A5=E5=BD=93=E5=89=8D?=
=?UTF-8?q?=E6=97=A5=E5=AD=98=E5=9C=A8=E4=BA=8E=E6=96=B0=E7=9A=84=E6=9C=88?=
=?UTF-8?q?=E4=BB=BD=E4=B8=AD=E5=88=99=E4=BF=9D=E6=8C=81=E6=97=A5=E4=B8=8D?=
=?UTF-8?q?=E5=8F=98=EF=BC=8C=E5=90=A6=E5=88=99=E4=BF=AE=E6=94=B9=E4=B8=BA?=
=?UTF-8?q?=E6=96=B0=E6=9C=88=E4=BB=BD=E7=9A=84=E6=9C=80=E5=90=8E=E4=B8=80?=
=?UTF-8?q?=E6=97=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Qt5/imports/FluentUI/Controls/FluDatePicker.qml | 5 +++++
src/Qt6/imports/FluentUI/Controls/FluDatePicker.qml | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/src/Qt5/imports/FluentUI/Controls/FluDatePicker.qml b/src/Qt5/imports/FluentUI/Controls/FluDatePicker.qml
index 1ba43afa..b2f4e96d 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluDatePicker.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluDatePicker.qml
@@ -178,7 +178,12 @@ FluButton {
}
if(type === 1){
text_month.text = model
+ let day = list_view_3.model[list_view_3.currentIndex]
list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex])
+ if(list_view_3.model.indexOf(day) === -1){
+ day = list_view_3.model[list_view_3.model.length - 1]
+ }
+ list_view_3.currentIndex = list_view_3.model.indexOf(day)
text_day.text = list_view_3.model[list_view_3.currentIndex]
}
diff --git a/src/Qt6/imports/FluentUI/Controls/FluDatePicker.qml b/src/Qt6/imports/FluentUI/Controls/FluDatePicker.qml
index 7afd1ca3..3c3a2ac5 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluDatePicker.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluDatePicker.qml
@@ -178,7 +178,12 @@ FluButton {
}
if(type === 1){
text_month.text = model
+ let day = list_view_3.model[list_view_3.currentIndex]
list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex])
+ if(list_view_3.model.indexOf(day) === -1){
+ day = list_view_3.model[list_view_3.model.length - 1]
+ }
+ list_view_3.currentIndex = list_view_3.model.indexOf(day)
text_day.text = list_view_3.model[list_view_3.currentIndex]
}
From a787a733c41e51aad89eedc1179649fd721be176 Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Sun, 11 May 2025 22:27:48 +0800
Subject: [PATCH 6/9] =?UTF-8?q?refactor:=20=E9=83=A8=E5=88=86=E6=8E=A7?=
=?UTF-8?q?=E4=BB=B6=E7=94=A8enabled=E6=9B=BF=E4=BB=A3disabled=E8=BF=9B?=
=?UTF-8?q?=E8=A1=8C=E9=80=BB=E8=BE=91=E5=88=A4=E6=96=AD=EF=BC=8C=E6=8F=90?=
=?UTF-8?q?=E5=8D=87=E4=BD=BF=E7=94=A8=E5=8E=9F=E7=94=9Fenabled=E5=B1=9E?=
=?UTF-8?q?=E6=80=A7=E6=97=B6=E7=9A=84=E5=85=BC=E5=AE=B9=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Qt5/imports/FluentUI/Controls/FluComboBox.qml | 4 ++--
src/Qt5/imports/FluentUI/Controls/FluMenuBarItem.qml | 4 ++--
src/Qt5/imports/FluentUI/Controls/FluSpinBox.qml | 4 ++--
src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml | 2 +-
src/Qt6/imports/FluentUI/Controls/FluComboBox.qml | 4 ++--
src/Qt6/imports/FluentUI/Controls/FluMenuBarItem.qml | 4 ++--
src/Qt6/imports/FluentUI/Controls/FluSpinBox.qml | 4 ++--
src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml | 2 +-
8 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/Qt5/imports/FluentUI/Controls/FluComboBox.qml b/src/Qt5/imports/FluentUI/Controls/FluComboBox.qml
index 3000cc7c..1792f911 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluComboBox.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluComboBox.qml
@@ -55,7 +55,7 @@ T.ComboBox {
font:control.font
readOnly: control.down
color: {
- if(control.disabled) {
+ if(!control.enabled) {
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
@@ -97,7 +97,7 @@ T.ComboBox {
anchors.margins: -2
}
color:{
- if(disabled){
+ if(!enabled){
return disableColor
}
return hovered ? hoverColor :normalColor
diff --git a/src/Qt5/imports/FluentUI/Controls/FluMenuBarItem.qml b/src/Qt5/imports/FluentUI/Controls/FluMenuBarItem.qml
index e772314f..4d366fcf 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluMenuBarItem.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluMenuBarItem.qml
@@ -6,7 +6,7 @@ T.MenuBarItem {
property bool disabled: false
property color textColor: {
if(FluTheme.dark){
- if(disabled){
+ if(!enabled){
return Qt.rgba(131/255,131/255,131/255,1)
}
if(pressed){
@@ -14,7 +14,7 @@ T.MenuBarItem {
}
return Qt.rgba(1,1,1,1)
}else{
- if(disabled){
+ if(!enabled){
return Qt.rgba(160/255,160/255,160/255,1)
}
if(pressed){
diff --git a/src/Qt5/imports/FluentUI/Controls/FluSpinBox.qml b/src/Qt5/imports/FluentUI/Controls/FluSpinBox.qml
index 2f562e35..bd3ab1aa 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluSpinBox.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluSpinBox.qml
@@ -139,13 +139,13 @@ T.SpinBox {
radius: 4
border.width: 1
border.color: {
- if(contentItem.disabled){
+ if(!contentItem.enabled){
return FluTheme.dark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(237/255,237/255,237/255,1)
}
return FluTheme.dark ? Qt.rgba(76/255,76/255,76/255,1) : Qt.rgba(240/255,240/255,240/255,1)
}
color: {
- if(contentItem.disabled){
+ if(!contentItem.enabled){
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
}
if(contentItem.activeFocus){
diff --git a/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml b/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml
index ef82bd13..3467a621 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml
@@ -6,7 +6,7 @@ FluControlBackground{
property Item inputItem
id:control
color: {
- if(inputItem && inputItem.disabled){
+ if(inputItem && !inputItem.enabled){
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
}
if(inputItem && inputItem.activeFocus){
diff --git a/src/Qt6/imports/FluentUI/Controls/FluComboBox.qml b/src/Qt6/imports/FluentUI/Controls/FluComboBox.qml
index 6dc161b1..6a8662c4 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluComboBox.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluComboBox.qml
@@ -55,7 +55,7 @@ T.ComboBox {
font:control.font
readOnly: control.down
color: {
- if(control.disabled) {
+ if(!control.enabled) {
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
@@ -97,7 +97,7 @@ T.ComboBox {
anchors.margins: -2
}
color:{
- if(disabled){
+ if(!enabled){
return disableColor
}
return hovered ? hoverColor :normalColor
diff --git a/src/Qt6/imports/FluentUI/Controls/FluMenuBarItem.qml b/src/Qt6/imports/FluentUI/Controls/FluMenuBarItem.qml
index 03e06cf0..9e0c6891 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluMenuBarItem.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluMenuBarItem.qml
@@ -7,7 +7,7 @@ T.MenuBarItem {
property bool disabled: false
property color textColor: {
if(FluTheme.dark){
- if(disabled){
+ if(!enabled){
return Qt.rgba(131/255,131/255,131/255,1)
}
if(pressed){
@@ -15,7 +15,7 @@ T.MenuBarItem {
}
return Qt.rgba(1,1,1,1)
}else{
- if(disabled){
+ if(!enabled){
return Qt.rgba(160/255,160/255,160/255,1)
}
if(pressed){
diff --git a/src/Qt6/imports/FluentUI/Controls/FluSpinBox.qml b/src/Qt6/imports/FluentUI/Controls/FluSpinBox.qml
index 7dcc6294..335d73eb 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluSpinBox.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluSpinBox.qml
@@ -140,13 +140,13 @@ T.SpinBox {
radius: 4
border.width: 1
border.color: {
- if(contentItem.disabled){
+ if(!contentItem.enabled){
return FluTheme.dark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(237/255,237/255,237/255,1)
}
return FluTheme.dark ? Qt.rgba(76/255,76/255,76/255,1) : Qt.rgba(240/255,240/255,240/255,1)
}
color: {
- if(contentItem.disabled){
+ if(!contentItem.enabled){
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
}
if(contentItem.activeFocus){
diff --git a/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml b/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml
index a57cff5a..44a4604e 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml
@@ -6,7 +6,7 @@ FluControlBackground{
property Item inputItem
id:control
color: {
- if(inputItem && inputItem.disabled){
+ if(inputItem && !inputItem.enabled){
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
}
if(inputItem && inputItem.activeFocus){
From f2c2beb90ac9d2ac1ec1cd919728a4d2980b4936 Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Sun, 11 May 2025 23:13:36 +0800
Subject: [PATCH 7/9] =?UTF-8?q?feat:=20FluTableView=E5=A2=9E=E5=8A=A0start?=
=?UTF-8?q?RowIndex=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=BB=A5=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E5=88=86=E9=A1=B5=E6=95=B0=E6=8D=AE=E5=9C=BA=E6=99=AF=E4=B8=8B?=
=?UTF-8?q?=E6=AD=A3=E7=A1=AE=E8=AE=A1=E7=AE=97=E8=A1=8C=E5=BA=8F=E5=8F=B7?=
=?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E4=BB=85=E4=BE=9D=E8=B5=96=E8=A1=A8?=
=?UTF-8?q?=E6=A0=BC=E6=95=B0=E6=8D=AE=E9=87=8F=E8=BF=9B=E8=A1=8C=E7=BC=96?=
=?UTF-8?q?=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
example/example_en_US.ts | 16 ++++++++--------
example/example_zh_CN.ts | 16 ++++++++--------
example/qml/page/T_TableView.qml | 1 +
.../imports/FluentUI/Controls/FluTableView.qml | 12 +++++++++++-
src/Qt5/imports/FluentUI/plugins.qmltypes | 7 ++++---
.../imports/FluentUI/Controls/FluTableView.qml | 12 +++++++++++-
6 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/example/example_en_US.ts b/example/example_en_US.ts
index 802e0585..a4886c29 100644
--- a/example/example_en_US.ts
+++ b/example/example_en_US.ts
@@ -2368,7 +2368,7 @@ Some contents...
-
+
Name
@@ -2418,37 +2418,37 @@ Some contents...
-
+
Avatar
-
+
Address
-
+
Nickname
-
+
Long String
-
+
Options
-
+
<Previous
-
+
Next>
diff --git a/example/example_zh_CN.ts b/example/example_zh_CN.ts
index 00981b6d..5d1d3c5d 100644
--- a/example/example_zh_CN.ts
+++ b/example/example_zh_CN.ts
@@ -2557,7 +2557,7 @@ Some contents...
-
+
Name
名称
@@ -2597,37 +2597,37 @@ Some contents...
焦点未获取:请点击表格中的任意一项,作为插入的靶点!
-
+
Avatar
头像
-
+
Address
地址
-
+
Nickname
昵称
-
+
Long String
长字符串
-
+
Options
操作
-
+
<Previous
<上一页
-
+
Next>
下一页>
diff --git a/example/qml/page/T_TableView.qml b/example/qml/page/T_TableView.qml
index 242fdb4b..e9681387 100644
--- a/example/qml/page/T_TableView.qml
+++ b/example/qml/page/T_TableView.qml
@@ -493,6 +493,7 @@ FluContentPage{
onRowsChanged: {
root.checkBoxChanged()
}
+ startRowIndex: (gagination.pageCurrent - 1) * gagination.__itemPerPage + 1
columnSource:[
{
title: table_view.customItem(com_column_checbox,{checked:true}),
diff --git a/src/Qt5/imports/FluentUI/Controls/FluTableView.qml b/src/Qt5/imports/FluentUI/Controls/FluTableView.qml
index 6fb39b4f..c1beabbe 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluTableView.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluTableView.qml
@@ -17,6 +17,7 @@ Rectangle {
property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1)
property bool horizonalHeaderVisible: true
property bool verticalHeaderVisible: true
+ property int startRowIndex: 1
property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
property alias view: table_view
@@ -841,7 +842,13 @@ Rectangle {
Connections{
target: table_view
function onRowsChanged(){
- header_row_model.rows = Array.from({length: table_view.rows}, (_, i) => ({rowIndex:i+1}))
+ header_vertical.updateRowIndex()
+ }
+ }
+ Connections {
+ target: control
+ function onStartRowIndexChanged(){
+ header_vertical.updateRowIndex()
}
}
Timer{
@@ -851,6 +858,9 @@ Rectangle {
header_vertical.forceLayout()
}
}
+ function updateRowIndex(){
+ header_row_model.rows = Array.from({length: table_view.rows}, (_, i) => ({rowIndex:i+control.startRowIndex}))
+ }
}
Item{
anchors{
diff --git a/src/Qt5/imports/FluentUI/plugins.qmltypes b/src/Qt5/imports/FluentUI/plugins.qmltypes
index 17e31c99..ffeabf87 100644
--- a/src/Qt5/imports/FluentUI/plugins.qmltypes
+++ b/src/Qt5/imports/FluentUI/plugins.qmltypes
@@ -2778,7 +2778,7 @@ Module {
}
Property {
name: "layoutMacosButtons"
- type: "FluLoader_QMLTYPE_11"
+ type: "FluLoader_QMLTYPE_12"
isReadonly: true
isPointer: true
}
@@ -3486,8 +3486,8 @@ Module {
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
Property { name: "topPadding"; type: "int" }
Property { name: "pageMode"; type: "int" }
- Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_37"; isPointer: true }
- Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_37"; isPointer: true }
+ Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_49"; isPointer: true }
+ Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_49"; isPointer: true }
Property { name: "navCompactWidth"; type: "int" }
Property { name: "navTopMargin"; type: "int" }
Property { name: "cellHeight"; type: "int" }
@@ -4092,6 +4092,7 @@ Module {
Property { name: "borderColor"; type: "QColor" }
Property { name: "horizonalHeaderVisible"; type: "bool" }
Property { name: "verticalHeaderVisible"; type: "bool" }
+ Property { name: "startRowIndex"; type: "int" }
Property { name: "selectedBorderColor"; type: "QColor" }
Property { name: "selectedColor"; type: "QColor" }
Property { name: "columnWidthProvider"; type: "QVariant" }
diff --git a/src/Qt6/imports/FluentUI/Controls/FluTableView.qml b/src/Qt6/imports/FluentUI/Controls/FluTableView.qml
index 100be1d9..ebb50392 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluTableView.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluTableView.qml
@@ -17,6 +17,7 @@ Rectangle {
property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1)
property bool horizonalHeaderVisible: true
property bool verticalHeaderVisible: true
+ property int startRowIndex: 1
property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
property alias view: table_view
@@ -841,7 +842,13 @@ Rectangle {
Connections{
target: table_view
function onRowsChanged(){
- header_row_model.rows = Array.from({length: table_view.rows}, (_, i) => ({rowIndex:i+1}))
+ header_vertical.updateRowIndex()
+ }
+ }
+ Connections {
+ target: control
+ function onStartRowIndexChanged(){
+ header_vertical.updateRowIndex()
}
}
Timer{
@@ -851,6 +858,9 @@ Rectangle {
header_vertical.forceLayout()
}
}
+ function updateRowIndex(){
+ header_row_model.rows = Array.from({length: table_view.rows}, (_, i) => ({rowIndex:i+control.startRowIndex}))
+ }
}
Item{
anchors{
From 97e88dbd6f96074fd5085064bca2b29e1b24bfaa Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Sat, 17 May 2025 08:25:17 +0800
Subject: [PATCH 8/9] =?UTF-8?q?feat:=20FluTour=E5=A2=9E=E5=8A=A0=E6=8C=87?=
=?UTF-8?q?=E7=A4=BA=E5=99=A8=E5=92=8C=E5=8A=A8=E7=94=BB=E6=95=88=E6=9E=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
example/example_en_US.ts | 23 +-
example/example_zh_CN.ts | 29 ++-
example/qml/page/T_Tour.qml | 30 ++-
src/Qt5/imports/FluentUI/Controls/FluTour.qml | 229 +++++++++++++++---
src/Qt5/imports/FluentUI/plugins.qmltypes | 2 +
src/Qt6/imports/FluentUI/Controls/FluTour.qml | 229 +++++++++++++++---
6 files changed, 449 insertions(+), 93 deletions(-)
diff --git a/example/example_en_US.ts b/example/example_en_US.ts
index a4886c29..15e18788 100644
--- a/example/example_en_US.ts
+++ b/example/example_en_US.ts
@@ -2737,49 +2737,60 @@ Some contents...
T_Tour
+
Upload File
+
Put your files here.
-
-
+
+
+
Save
+
Save your changes.
+
Other Actions
+
Click to see other actions.
-
+
Begin Tour
-
-
+
+ Begin Tour with custom indicator
+
+
+
+
+
Upload
-
+
More
diff --git a/example/example_zh_CN.ts b/example/example_zh_CN.ts
index 5d1d3c5d..f2be137d 100644
--- a/example/example_zh_CN.ts
+++ b/example/example_zh_CN.ts
@@ -552,7 +552,7 @@
Tour
- 游览
+ 漫游式引导
@@ -2938,56 +2938,67 @@ Some contents...
+
Upload File
上传文件
+
Put your files here.
把你的文件放在这里
-
-
+
+
+
Save
保存
+
Save your changes.
保存更改
+
Other Actions
其他操作
+
Click to see other actions.
点击查看其他操作
-
+
Begin Tour
- 开始游览
+ 开始导览
-
-
+
+ Begin Tour with custom indicator
+ 以自定义指示器开始导览
+
+
+
+
Upload
上传
-
+
More
更多
Tour
- 游览
+ 漫游式引导
diff --git a/example/qml/page/T_Tour.qml b/example/qml/page/T_Tour.qml
index e87e5827..f7ce16df 100644
--- a/example/qml/page/T_Tour.qml
+++ b/example/qml/page/T_Tour.qml
@@ -17,20 +17,42 @@ FluScrollablePage{
{title:qsTr("Other Actions"),description: qsTr("Click to see other actions."),target:()=>btn_more}
]
}
+ FluTour{
+ id:tour_custom_indicator
+ steps:[
+ {title:qsTr("Upload File"),description: qsTr("Put your files here."),target:()=>btn_upload},
+ {title:qsTr("Save"),description: qsTr("Save your changes."),target:()=>btn_save},
+ {title:qsTr("Other Actions"),description: qsTr("Click to see other actions."),target:()=>btn_more}
+ ]
+ indicator: Component{
+ FluText {
+ text: "%1 / %2".arg(current + 1).arg(total)
+ }
+ }
+ }
FluFrame{
Layout.fillWidth: true
Layout.preferredHeight: 130
padding: 10
- FluFilledButton{
+ Row{
anchors{
top: parent.top
topMargin: 14
}
- text: qsTr("Begin Tour")
- onClicked: {
- tour.open()
+ spacing: 20
+ FluFilledButton{
+ text: qsTr("Begin Tour")
+ onClicked: {
+ tour.open()
+ }
+ }
+ FluFilledButton{
+ text: qsTr("Begin Tour with custom indicator")
+ onClicked: {
+ tour_custom_indicator.open()
+ }
}
}
diff --git a/src/Qt5/imports/FluentUI/Controls/FluTour.qml b/src/Qt5/imports/FluentUI/Controls/FluTour.qml
index d8ff7027..b73b4853 100644
--- a/src/Qt5/imports/FluentUI/Controls/FluTour.qml
+++ b/src/Qt5/imports/FluentUI/Controls/FluTour.qml
@@ -7,8 +7,10 @@ import FluentUI 1.0
Popup{
property var steps : []
property int targetMargins: 5
+ property int targetRadius: 2
property Component nextButton: com_next_button
property Component prevButton: com_prev_button
+ property Component indicator: com_indicator
property int index : 0
property string finishText: qsTr("Finish")
property string nextText: qsTr("Next")
@@ -22,12 +24,12 @@ Popup{
contentItem: Item{}
onVisibleChanged: {
if(visible){
+ d.animationEnabled = false
control.index = 0
+ d.updatePos()
+ d.animationEnabled = true
}
}
- onIndexChanged: {
- canvas.requestPaint()
- }
Component{
id: com_next_button
FluFilledButton{
@@ -50,10 +52,32 @@ Popup{
}
}
}
+ Component{
+ id: com_indicator
+ Row{
+ spacing: 10
+ Repeater{
+ model: total
+ delegate: Rectangle{
+ width: 8
+ height: 8
+ radius: 4
+ scale: current === index ? 1.2 : 1
+ color:{
+ if(current === index){
+ return FluTheme.primaryColor
+ }
+ return FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
+ }
+ }
+ }
+ }
+ }
Item{
id:d
property var window: Window.window
property point pos: Qt.point(0,0)
+ property bool animationEnabled: true
property var step: steps[index]
property var target: {
if(steps[index]){
@@ -73,15 +97,22 @@ Popup{
}
return control.width
}
+ function updatePos(){
+ if(d.target && d.window){
+ d.pos = d.target.mapToGlobal(0,0)
+ d.pos = Qt.point(d.pos.x-d.window.x,d.pos.y-d.window.y)
+ }
+ }
+ onTargetChanged: {
+ updatePos()
+ }
}
Connections{
target: d.window
function onWidthChanged(){
- canvas.requestPaint()
timer_delay.restart()
}
function onHeightChanged(){
- canvas.requestPaint()
timer_delay.restart()
}
}
@@ -89,39 +120,128 @@ Popup{
id: timer_delay
interval: 200
onTriggered: {
- canvas.requestPaint()
+ d.updatePos()
}
}
- Canvas{
- id: canvas
- anchors.fill: parent
- onPaint: {
- d.pos = d.target.mapToGlobal(0,0)
- d.pos = Qt.point(d.pos.x-d.window.x,d.pos.y-d.window.y)
- var ctx = canvas.getContext("2d")
- ctx.clearRect(0, 0, canvasSize.width, canvasSize.height)
- ctx.save()
- ctx.fillStyle = "#88000000"
- ctx.fillRect(0, 0, canvasSize.width, canvasSize.height)
- ctx.globalCompositeOperation = 'destination-out'
- ctx.fillStyle = 'black'
- var rect = Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2)
- drawRoundedRect(rect,2,ctx)
- ctx.restore()
+ Item{
+ id: targetRect
+ x: d.pos.x - control.targetMargins
+ y: d.pos.y - control.targetMargins
+ width: d.target ? d.target.width + control.targetMargins * 2 : 0
+ height: d.target ? d.target.height + control.targetMargins * 2 : 0
+ Behavior on x {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
}
- function drawRoundedRect(rect, r, ctx) {
- ctx.beginPath();
- ctx.moveTo(rect.x + r, rect.y);
- ctx.lineTo(rect.x + rect.width - r, rect.y);
- ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r);
- ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r);
- ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r);
- ctx.lineTo(rect.x + r, rect.y + rect.height);
- ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r);
- ctx.lineTo(rect.x, rect.y + r);
- ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r);
- ctx.closePath();
- ctx.fill()
+ Behavior on y {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on width {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on height {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ }
+ Shape {
+ anchors.fill: parent
+ layer.enabled: true
+ layer.samples: 4
+ layer.smooth: true
+ ShapePath {
+ fillColor: "#88000000"
+ strokeWidth: 0
+ strokeColor: "transparent"
+
+ // draw background
+ PathMove {
+ x: 0
+ y: 0
+ }
+ PathLine {
+ x: control.width
+ y: 0
+ }
+ PathLine {
+ x: control.width
+ y: control.height
+ }
+ PathLine {
+ x: 0
+ y: control.height
+ }
+ PathLine {
+ x: 0
+ y: 0
+ }
+
+ // draw highlight
+ PathMove {
+ x: targetRect.x + control.targetRadius
+ y: targetRect.y
+ }
+ PathLine {
+ x: targetRect.x + targetRect.width - control.targetRadius
+ y: targetRect.y
+ }
+ PathArc {
+ x: targetRect.x + targetRect.width
+ y: targetRect.y + control.targetRadius
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
+
+ PathLine {
+ x: targetRect.x + targetRect.width
+ y: targetRect.y + targetRect.height - control.targetRadius
+ }
+ PathArc {
+ x: targetRect.x + targetRect.width - control.targetRadius
+ y: targetRect.y + targetRect.height
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
+
+ PathLine {
+ x: targetRect.x + control.targetRadius
+ y: targetRect.y + targetRect.height
+ }
+ PathArc {
+ x: targetRect.x
+ y: targetRect.y + targetRect.height - control.targetRadius
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
+
+ PathLine {
+ x: targetRect.x
+ y: targetRect.y + control.targetRadius
+ }
+ PathArc {
+ x: targetRect.x + control.targetRadius
+ y: targetRect.y
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
}
}
FluFrame{
@@ -151,6 +271,18 @@ Popup{
return 0
}
border.width: 0
+ Behavior on x {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on y {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
FluShadow{
radius: 5
}
@@ -193,10 +325,21 @@ Popup{
leftMargin: 15
}
}
+ FluLoader{
+ readonly property int total: steps.length
+ readonly property int current: control.index
+ sourceComponent: control.indicator
+ anchors{
+ bottom: parent.bottom
+ left: parent.left
+ bottomMargin: 15
+ leftMargin: 15
+ }
+ }
FluLoader{
id: loader_next
property bool isEnd: control.index === steps.length-1
- sourceComponent: com_next_button
+ sourceComponent: control.nextButton
anchors{
top: text_desc.bottom
topMargin: 10
@@ -207,7 +350,7 @@ Popup{
FluLoader{
id: loader_prev
visible: control.index !== 0
- sourceComponent: com_prev_button
+ sourceComponent: control.prevButton
anchors{
right: loader_next.left
top: loader_next.top
@@ -246,5 +389,17 @@ Popup{
}
return 0
}
+ Behavior on x {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on y {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
}
}
diff --git a/src/Qt5/imports/FluentUI/plugins.qmltypes b/src/Qt5/imports/FluentUI/plugins.qmltypes
index ffeabf87..17c84d82 100644
--- a/src/Qt5/imports/FluentUI/plugins.qmltypes
+++ b/src/Qt5/imports/FluentUI/plugins.qmltypes
@@ -4328,8 +4328,10 @@ Module {
defaultProperty: "contentData"
Property { name: "steps"; type: "QVariant" }
Property { name: "targetMargins"; type: "int" }
+ Property { name: "targetRadius"; type: "int" }
Property { name: "nextButton"; type: "QQmlComponent"; isPointer: true }
Property { name: "prevButton"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "indicator"; type: "QQmlComponent"; isPointer: true }
Property { name: "index"; type: "int" }
Property { name: "finishText"; type: "string" }
Property { name: "nextText"; type: "string" }
diff --git a/src/Qt6/imports/FluentUI/Controls/FluTour.qml b/src/Qt6/imports/FluentUI/Controls/FluTour.qml
index fea6368b..5049c9cc 100644
--- a/src/Qt6/imports/FluentUI/Controls/FluTour.qml
+++ b/src/Qt6/imports/FluentUI/Controls/FluTour.qml
@@ -7,8 +7,10 @@ import FluentUI
Popup{
property var steps : []
property int targetMargins: 5
+ property int targetRadius: 2
property Component nextButton: com_next_button
property Component prevButton: com_prev_button
+ property Component indicator: com_indicator
property int index : 0
property string finishText: qsTr("Finish")
property string nextText: qsTr("Next")
@@ -22,12 +24,12 @@ Popup{
contentItem: Item{}
onVisibleChanged: {
if(visible){
+ d.animationEnabled = false
control.index = 0
+ d.updatePos()
+ d.animationEnabled = true
}
}
- onIndexChanged: {
- canvas.requestPaint()
- }
Component{
id: com_next_button
FluFilledButton{
@@ -50,10 +52,32 @@ Popup{
}
}
}
+ Component{
+ id: com_indicator
+ Row{
+ spacing: 10
+ Repeater{
+ model: total
+ delegate: Rectangle{
+ width: 8
+ height: 8
+ radius: 4
+ scale: current === index ? 1.2 : 1
+ color:{
+ if(current === index){
+ return FluTheme.primaryColor
+ }
+ return FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
+ }
+ }
+ }
+ }
+ }
Item{
id:d
property var window: Window.window
property point pos: Qt.point(0,0)
+ property bool animationEnabled: true
property var step: steps[index]
property var target: {
if(steps[index]){
@@ -73,15 +97,22 @@ Popup{
}
return control.width
}
+ function updatePos(){
+ if(d.target && d.window){
+ d.pos = d.target.mapToGlobal(0,0)
+ d.pos = Qt.point(d.pos.x-d.window.x,d.pos.y-d.window.y)
+ }
+ }
+ onTargetChanged: {
+ updatePos()
+ }
}
Connections{
target: d.window
function onWidthChanged(){
- canvas.requestPaint()
timer_delay.restart()
}
function onHeightChanged(){
- canvas.requestPaint()
timer_delay.restart()
}
}
@@ -89,39 +120,128 @@ Popup{
id: timer_delay
interval: 200
onTriggered: {
- canvas.requestPaint()
+ d.updatePos()
}
}
- Canvas{
- id: canvas
- anchors.fill: parent
- onPaint: {
- d.pos = d.target.mapToGlobal(0,0)
- d.pos = Qt.point(d.pos.x-d.window.x,d.pos.y-d.window.y)
- var ctx = canvas.getContext("2d")
- ctx.clearRect(0, 0, canvasSize.width, canvasSize.height)
- ctx.save()
- ctx.fillStyle = "#88000000"
- ctx.fillRect(0, 0, canvasSize.width, canvasSize.height)
- ctx.globalCompositeOperation = 'destination-out'
- ctx.fillStyle = 'black'
- var rect = Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2)
- drawRoundedRect(rect,2,ctx)
- ctx.restore()
+ Item{
+ id: targetRect
+ x: d.pos.x - control.targetMargins
+ y: d.pos.y - control.targetMargins
+ width: d.target ? d.target.width + control.targetMargins * 2 : 0
+ height: d.target ? d.target.height + control.targetMargins * 2 : 0
+ Behavior on x {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
}
- function drawRoundedRect(rect, r, ctx) {
- ctx.beginPath();
- ctx.moveTo(rect.x + r, rect.y);
- ctx.lineTo(rect.x + rect.width - r, rect.y);
- ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r);
- ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r);
- ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r);
- ctx.lineTo(rect.x + r, rect.y + rect.height);
- ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r);
- ctx.lineTo(rect.x, rect.y + r);
- ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r);
- ctx.closePath();
- ctx.fill()
+ Behavior on y {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on width {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on height {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ }
+ Shape {
+ anchors.fill: parent
+ layer.enabled: true
+ layer.samples: 4
+ layer.smooth: true
+ ShapePath {
+ fillColor: "#88000000"
+ strokeWidth: 0
+ strokeColor: "transparent"
+
+ // draw background
+ PathMove {
+ x: 0
+ y: 0
+ }
+ PathLine {
+ x: control.width
+ y: 0
+ }
+ PathLine {
+ x: control.width
+ y: control.height
+ }
+ PathLine {
+ x: 0
+ y: control.height
+ }
+ PathLine {
+ x: 0
+ y: 0
+ }
+
+ // draw highlight
+ PathMove {
+ x: targetRect.x + control.targetRadius
+ y: targetRect.y
+ }
+ PathLine {
+ x: targetRect.x + targetRect.width - control.targetRadius
+ y: targetRect.y
+ }
+ PathArc {
+ x: targetRect.x + targetRect.width
+ y: targetRect.y + control.targetRadius
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
+
+ PathLine {
+ x: targetRect.x + targetRect.width
+ y: targetRect.y + targetRect.height - control.targetRadius
+ }
+ PathArc {
+ x: targetRect.x + targetRect.width - control.targetRadius
+ y: targetRect.y + targetRect.height
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
+
+ PathLine {
+ x: targetRect.x + control.targetRadius
+ y: targetRect.y + targetRect.height
+ }
+ PathArc {
+ x: targetRect.x
+ y: targetRect.y + targetRect.height - control.targetRadius
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
+
+ PathLine {
+ x: targetRect.x
+ y: targetRect.y + control.targetRadius
+ }
+ PathArc {
+ x: targetRect.x + control.targetRadius
+ y: targetRect.y
+ radiusX: control.targetRadius
+ radiusY: control.targetRadius
+ useLargeArc: false
+ direction: PathArc.Clockwise
+ }
}
}
FluFrame{
@@ -151,6 +271,18 @@ Popup{
return 0
}
border.width: 0
+ Behavior on x {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on y {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
FluShadow{
radius: 5
}
@@ -193,10 +325,21 @@ Popup{
leftMargin: 15
}
}
+ FluLoader{
+ readonly property int total: steps.length
+ readonly property int current: control.index
+ sourceComponent: control.indicator
+ anchors{
+ bottom: parent.bottom
+ left: parent.left
+ bottomMargin: 15
+ leftMargin: 15
+ }
+ }
FluLoader{
id: loader_next
property bool isEnd: control.index === steps.length-1
- sourceComponent: com_next_button
+ sourceComponent: control.nextButton
anchors{
top: text_desc.bottom
topMargin: 10
@@ -207,7 +350,7 @@ Popup{
FluLoader{
id: loader_prev
visible: control.index !== 0
- sourceComponent: com_prev_button
+ sourceComponent: control.prevButton
anchors{
right: loader_next.left
top: loader_next.top
@@ -246,5 +389,17 @@ Popup{
}
return 0
}
+ Behavior on x {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
+ Behavior on y {
+ enabled: d.animationEnabled && FluTheme.animationEnabled
+ NumberAnimation {
+ duration: 167
+ }
+ }
}
}
From ce4fb060845729b8ff34fc8f400948f57851313a Mon Sep 17 00:00:00 2001
From: Polaris-Night <158275221@qq.com>
Date: Sat, 17 May 2025 09:24:44 +0800
Subject: [PATCH 9/9] =?UTF-8?q?feat:=20FluRectangle=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BE=B9=E6=A1=86=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
example/example_en_US.ts | 6 +-
example/example_zh_CN.ts | 6 +-
example/qml/page/T_Rectangle.qml | 122 +++++++++++-----------
example/qml/window/CrashWindow.qml | 3 +
src/FluRectangle.cpp | 16 ++-
src/FluRectangle.h | 2 +
src/Qt5/imports/FluentUI/plugins.qmltypes | 2 +
7 files changed, 88 insertions(+), 69 deletions(-)
diff --git a/example/example_en_US.ts b/example/example_en_US.ts
index 15e18788..d3ae65e0 100644
--- a/example/example_en_US.ts
+++ b/example/example_en_US.ts
@@ -70,17 +70,17 @@
-
+
We apologize for the inconvenience caused by an unexpected error
-
+
Report Logs
-
+
Restart Program
diff --git a/example/example_zh_CN.ts b/example/example_zh_CN.ts
index f2be137d..8e55a866 100644
--- a/example/example_zh_CN.ts
+++ b/example/example_zh_CN.ts
@@ -70,17 +70,17 @@
友情提示
-
+
We apologize for the inconvenience caused by an unexpected error
对于意外错误给您带来的不便,我们深表歉意
-
+
Report Logs
上报日志
-
+
Restart Program
重启程序
diff --git a/example/qml/page/T_Rectangle.qml b/example/qml/page/T_Rectangle.qml
index 08a016ca..12cd429b 100644
--- a/example/qml/page/T_Rectangle.qml
+++ b/example/qml/page/T_Rectangle.qml
@@ -11,69 +11,71 @@ FluScrollablePage{
FluFrame{
Layout.fillWidth: true
- Layout.preferredHeight: 80
padding: 10
- Column{
+ Flow{
+ width: parent.width
spacing: 15
- anchors{
- left: parent.left
- verticalCenter: parent.verticalCenter
+ FluRectangle{
+ width: 50
+ height: 50
+ color:"#0078d4"
+ radius:[0,0,0,0]
}
- 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]
- }
- FluRectangle{
- width: 50
- height: 50
- color:"#a8d5ba"
- radius:[15,15,15,15]
- borderWidth: 3
- borderColor: "#5b8a72"
- }
- FluRectangle{
- width: 50
- height: 50
- color:"#dbe2ef"
- radius:[15,0,0,0]
- borderWidth: 2
- borderColor: "#3f72af"
- }
+ 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]
+ }
+ FluRectangle{
+ width: 50
+ height: 50
+ color:"#a8d5ba"
+ radius:[15,15,15,15]
+ borderWidth: 3
+ borderColor: "#5b8a72"
+ }
+ FluRectangle{
+ width: 50
+ height: 50
+ color:"#dbe2ef"
+ radius:[15,0,0,0]
+ borderWidth: 2
+ borderColor: "#3f72af"
+ }
+ FluRectangle{
+ width: 50
+ height: 50
+ color:"#dbe2ef"
+ borderWidth: 2
+ borderColor: "#3f72af"
+ borderStyle: Qt.DashLine
+ dashPattern: [4,2]
}
}
}
@@ -84,6 +86,8 @@ FluScrollablePage{
radius: [25,25,25,25]
borderWidth: 2
borderColor: "#000000"
+ borderStyle: Qt.DashLine
+ dashPattern: [4,2]
width: 50
height: 50
}'
diff --git a/example/qml/window/CrashWindow.qml b/example/qml/window/CrashWindow.qml
index b70fa0d5..4451816b 100644
--- a/example/qml/window/CrashWindow.qml
+++ b/example/qml/window/CrashWindow.qml
@@ -19,6 +19,9 @@ FluWindow {
Component.onCompleted: {
window.stayTop = true
}
+ Component.onDestruction: {
+ FluRouter.exit()
+ }
onInitArgument:
(argument)=>{
diff --git a/src/FluRectangle.cpp b/src/FluRectangle.cpp
index fdd69d5f..f682eae1 100644
--- a/src/FluRectangle.cpp
+++ b/src/FluRectangle.cpp
@@ -6,10 +6,14 @@ FluRectangle::FluRectangle(QQuickItem *parent) : QQuickPaintedItem(parent) {
radius({0, 0, 0, 0});
borderWidth(0);
borderColor(Qt::black);
+ borderStyle(Qt::SolidLine);
+ dashPattern({});
connect(this, &FluRectangle::colorChanged, this, [=] { update(); });
connect(this, &FluRectangle::radiusChanged, this, [=] { update(); });
connect(this, &FluRectangle::borderWidthChanged, this, [=] { update(); });
connect(this, &FluRectangle::borderColorChanged, this, [=] { update(); });
+ connect(this, &FluRectangle::borderStyleChanged, this, [=] { update(); });
+ connect(this, &FluRectangle::dashPatternChanged, this, [=] { update(); });
}
bool FluRectangle::borderValid() const {
@@ -21,8 +25,8 @@ void FluRectangle::paint(QPainter *painter) {
painter->setRenderHint(QPainter::Antialiasing);
QRectF rect = boundingRect();
- bool valid = borderValid();
- if (valid) {
+ bool drawBorder = borderValid();
+ if (drawBorder) {
// 绘制边框时画笔的宽度从路径向两侧扩充
// 因此实际绘制的矩形应向内侧收缩边框宽度的一半,避免边框裁剪导致不完整
qreal halfBorderWidth = _borderWidth / 2.0;
@@ -54,8 +58,12 @@ void FluRectangle::paint(QPainter *painter) {
painter->fillPath(path, _color);
// 绘制边框
- if (valid) {
- painter->strokePath(path, QPen(_borderColor, _borderWidth));
+ if (drawBorder) {
+ QPen pen(_borderColor, _borderWidth, _borderStyle);
+ if (_borderStyle == Qt::DashLine || _borderStyle == Qt::CustomDashLine) {
+ pen.setDashPattern(_dashPattern);
+ }
+ painter->strokePath(path, pen);
}
painter->restore();
diff --git a/src/FluRectangle.h b/src/FluRectangle.h
index 571af4f6..53556cc1 100644
--- a/src/FluRectangle.h
+++ b/src/FluRectangle.h
@@ -14,6 +14,8 @@ class FluRectangle : public QQuickPaintedItem {
Q_PROPERTY_AUTO(QList, radius)
Q_PROPERTY_AUTO(qreal, borderWidth)
Q_PROPERTY_AUTO(QColor, borderColor)
+ Q_PROPERTY_AUTO(Qt::PenStyle, borderStyle)
+ Q_PROPERTY_AUTO(QVector, dashPattern)
QML_NAMED_ELEMENT(FluRectangle)
public:
explicit FluRectangle(QQuickItem *parent = nullptr);
diff --git a/src/Qt5/imports/FluentUI/plugins.qmltypes b/src/Qt5/imports/FluentUI/plugins.qmltypes
index 17c84d82..5790dc12 100644
--- a/src/Qt5/imports/FluentUI/plugins.qmltypes
+++ b/src/Qt5/imports/FluentUI/plugins.qmltypes
@@ -233,6 +233,8 @@ Module {
Property { name: "radius"; type: "QList" }
Property { name: "borderWidth"; type: "double" }
Property { name: "borderColor"; type: "QColor" }
+ Property { name: "borderStyle"; type: "Qt::PenStyle" }
+ Property { name: "dashPattern"; type: "QVector" }
}
Component {
name: "FluSheetType"