Compare commits

...

47 Commits

Author SHA1 Message Date
2367c6978a update 2024-05-11 22:21:11 +08:00
6b941697b0 update 2024-05-11 21:45:45 +08:00
4997b991db update 2024-05-10 19:23:30 +08:00
cd3abc01e9 fix bug 2024-05-10 19:20:01 +08:00
e6c4b79298 Merge branch 'main' into 1.7.6-dev
# Conflicts:
#	src/Qt5/imports/FluentUI/Controls/FluRadioButtons.qml
#	src/Qt6/imports/FluentUI/Controls/FluRadioButtons.qml
2024-05-10 12:26:14 +08:00
f830d5a9bf Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2024-05-09 19:41:15 +08:00
ed49e3f6af Merge pull request #499 from gao-xiangyang/main
info提示语支持主动调用函数关闭,支持关闭所有info框的函数
2024-05-09 17:10:34 +05:30
9aa6615189 FluRadioButtons 组件支持 disabled、manuallyDisabled选项
disabled: true // 禁用所有FluRadioButton子组件
        manuallyDisabled: true // 是否指定每个FluRadioButton上的disabled选项
2024-05-08 21:10:00 +08:00
c36515f19c info提示语支持主动调用函数关闭,支持关闭所有info框的函数 2024-05-08 20:35:31 +08:00
402579f32a update 2024-05-08 18:58:22 +08:00
655eff4f62 update 2024-05-07 22:16:42 +08:00
b916221d9f update 2024-05-07 21:47:40 +08:00
4cca680029 update 2024-05-05 22:05:18 +08:00
fe2543ab4d fix bug 2024-05-05 22:03:41 +08:00
394a42cb94 update 2024-05-05 21:33:47 +08:00
ac253a3de5 fix bug 2024-05-05 20:32:48 +08:00
0d61e33ef1 update 2024-05-05 15:52:46 +08:00
132ab12c32 update 2024-05-05 00:06:01 +08:00
af270951da update 2024-05-04 23:56:20 +08:00
18685b17ec update 2024-05-03 16:56:40 +08:00
0eb4d9f346 update 2024-05-03 01:54:38 +08:00
8015dcc2f1 update 2024-05-02 23:52:30 +08:00
0b1755e9eb update 2024-05-01 01:11:25 +08:00
e471d5a230 update 2024-04-30 19:38:05 +08:00
f922978338 update 2024-04-30 19:27:57 +08:00
91bda2a22c update 2024-04-30 13:07:46 +08:00
6638fe2e06 update 2024-04-30 13:06:27 +08:00
bf001d99d2 update 2024-04-30 12:59:09 +08:00
30531079b5 update 2024-04-29 10:12:34 +08:00
a746bc2684 update 2024-04-28 21:05:43 +08:00
96a6d0e7fa update 2024-04-28 20:22:05 +08:00
c733f3c60e update 2024-04-28 18:38:37 +08:00
effd9f3058 update 2024-04-28 18:19:21 +08:00
d93aac3518 update 2024-04-28 15:56:37 +08:00
5f6745b630 udpate 2024-04-28 13:03:20 +08:00
4f202831b8 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2024-04-28 10:51:29 +08:00
29cee84edd update 2024-04-28 10:51:13 +08:00
2d4e61445e Merge pull request #488 from yanhuacuo/path-for-insertRow
Add the functionality to insert new rows into the table
2024-04-28 10:47:28 +08:00
cc79854191 Merge pull request #489 from w-jt/main
FluPagination.qml 添加自定义控件,通过header和footer属性添加控件
2024-04-28 10:46:47 +08:00
500efa6298 添加自定义控件,通过header和footer属性添加控件
添加自定义控件,通过header和footer属性添加控件
2024-04-27 11:54:42 +08:00
355332da96 添加自定义控件,通过header和footer属性添加控件
添加自定义控件,通过header和footer属性添加控件
2024-04-27 11:53:57 +08:00
a0d662a8a5 添加自定义控件,通过header和footer属性添加控件
添加自定义控件,通过header和footer属性添加控件
2024-04-27 11:49:29 +08:00
aecc3fe3b4 添加自定义控件,通过header和footer属性添加控件
添加自定义控件,通过header和footer属性添加控件
2024-04-27 11:48:19 +08:00
3554fb99cd Add the functionality to insert new rows into the table 2024-04-27 09:40:37 +08:00
24fdff7e35 fix bug 2024-04-25 00:08:18 +08:00
d2fdd08604 update 2024-04-24 17:24:31 +08:00
1f5d6ce1aa update 2024-04-24 17:12:00 +08:00
49 changed files with 2140 additions and 960 deletions

View File

@ -1273,25 +1273,31 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="17"/> <location filename="qml/page/T_GroupBox.qml" line="17"/>
<location filename="qml/page/T_GroupBox.qml" line="27"/> <location filename="qml/page/T_GroupBox.qml" line="35"/>
<source>E-mail</source> <source>E-mail</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="18"/> <location filename="qml/page/T_GroupBox.qml" line="18"/>
<location filename="qml/page/T_GroupBox.qml" line="28"/> <location filename="qml/page/T_GroupBox.qml" line="36"/>
<source>Calendar</source> <source>Calendar</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="19"/> <location filename="qml/page/T_GroupBox.qml" line="19"/>
<location filename="qml/page/T_GroupBox.qml" line="29"/> <location filename="qml/page/T_GroupBox.qml" line="37"/>
<source>Contacts</source> <source>Contacts</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="24"/> <location filename="qml/page/T_GroupBox.qml" line="24"/>
<source>RadioButton Group</source> <source>RadioButton Group</source>
<oldsource>RadioButton Group111111111111111111111111</oldsource>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_GroupBox.qml" line="46"/>
<source>Disabled</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -1331,12 +1337,7 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Icons.qml" line="20"/> <location filename="qml/page/T_Icons.qml" line="51"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="60"/>
<source>You Copied </source> <source>You Copied </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1362,51 +1363,82 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="23"/> <location filename="qml/page/T_InfoBar.qml" line="27"/>
<source>Info</source> <source>Info</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="25"/> <location filename="qml/page/T_InfoBar.qml" line="29"/>
<location filename="qml/page/T_InfoBar.qml" line="49"/> <location filename="qml/page/T_InfoBar.qml" line="53"/>
<source>This is an InfoBar in the Info Style</source> <source>This is an InfoBar in the Info Style</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="29"/> <location filename="qml/page/T_InfoBar.qml" line="33"/>
<source>Warning</source> <source>Warning</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="31"/> <location filename="qml/page/T_InfoBar.qml" line="35"/>
<source>This is an InfoBar in the Warning Style</source> <source>This is an InfoBar in the Warning Style</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="37"/> <location filename="qml/page/T_InfoBar.qml" line="41"/>
<source>This is an InfoBar in the Error Style</source> <source>This is an InfoBar in the Error Style</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="43"/> <location filename="qml/page/T_InfoBar.qml" line="47"/>
<source>This is an InfoBar in the Success Style</source> <source>This is an InfoBar in the Success Style</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="47"/> <location filename="qml/page/T_InfoBar.qml" line="51"/>
<source>InfoBar that needs to be turned off manually</source> <source>InfoBar that needs to be turned off manually</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="49"/> <location filename="qml/page/T_InfoBar.qml" line="53"/>
<source>Manual shutdown is supported</source> <source>Manual shutdown is supported</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="59"/>
<source>Manually close the info message box</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="64"/>
<location filename="qml/page/T_InfoBar.qml" line="74"/>
<location filename="qml/page/T_InfoBar.qml" line="84"/>
<source>close &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="64"/>
<location filename="qml/page/T_InfoBar.qml" line="74"/>
<location filename="qml/page/T_InfoBar.qml" line="84"/>
<source>show &apos;%1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="70"/>
<location filename="qml/page/T_InfoBar.qml" line="80"/>
<location filename="qml/page/T_InfoBar.qml" line="90"/>
<source>This is an &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="94"/>
<source>clear all info</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>T_LineChart</name> <name>T_LineChart</name>
<message> <message>
<location filename="qml/chart/T_LineChart.qml" line="10"/> <location filename="qml/chart/T_LineChart.qml" line="11"/>
<source>Line Chart</source> <source>Line Chart</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1704,22 +1736,30 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="38"/> <location filename="qml/page/T_RadioButton.qml" line="38"/>
<location filename="qml/page/T_RadioButton.qml" line="80"/> <location filename="qml/page/T_RadioButton.qml" line="79"/>
<location filename="qml/page/T_RadioButton.qml" line="130"/>
<location filename="qml/page/T_RadioButton.qml" line="181"/>
<source>Disabled</source> <source>Disabled</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="63"/> <location filename="qml/page/T_RadioButton.qml" line="64"/>
<location filename="qml/page/T_RadioButton.qml" line="115"/>
<location filename="qml/page/T_RadioButton.qml" line="166"/>
<source>Radio Button_1</source> <source>Radio Button_1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="67"/> <location filename="qml/page/T_RadioButton.qml" line="67"/>
<location filename="qml/page/T_RadioButton.qml" line="118"/>
<location filename="qml/page/T_RadioButton.qml" line="169"/>
<source>Radio Button_2</source> <source>Radio Button_2</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="71"/> <location filename="qml/page/T_RadioButton.qml" line="70"/>
<location filename="qml/page/T_RadioButton.qml" line="121"/>
<location filename="qml/page/T_RadioButton.qml" line="172"/>
<source>Radio Button_3</source> <source>Radio Button_3</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1968,7 +2008,7 @@ Some contents...</source>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="177"/> <location filename="qml/page/T_TableView.qml" line="177"/>
<location filename="qml/page/T_TableView.qml" line="478"/> <location filename="qml/page/T_TableView.qml" line="509"/>
<source>Name</source> <source>Name</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1988,60 +2028,70 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="337"/> <location filename="qml/page/T_TableView.qml" line="365"/>
<source>Age</source> <source>Age</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="412"/> <location filename="qml/page/T_TableView.qml" line="440"/>
<source>Clear All</source> <source>Clear All</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="473"/> <location filename="qml/page/T_TableView.qml" line="447"/>
<source>Avatar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="491"/>
<source>Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="498"/>
<source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="505"/>
<source>Long String</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="513"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="532"/>
<source>&lt;Previous</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="533"/>
<source>Next&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="419"/>
<source>Delete Selection</source> <source>Delete Selection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="443"/> <location filename="qml/page/T_TableView.qml" line="470"/>
<source>Add a row of Data</source> <source>Add a row of Data</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/page/T_TableView.qml" line="476"/>
<source>Insert a Row</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="483"/>
<source>Focus not acquired: Please click any item in the form as the target for insertion!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="514"/>
<source>Avatar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="528"/>
<source>Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="536"/>
<source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="543"/>
<source>Long String</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="551"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="569"/>
<source>&lt;Previous</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="570"/>
<source>Next&gt;</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>T_Text</name> <name>T_Text</name>
@ -2193,12 +2243,12 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Timeline.qml" line="115"/> <location filename="qml/page/T_Timeline.qml" line="114"/>
<source>Append</source> <source>Append</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Timeline.qml" line="121"/> <location filename="qml/page/T_Timeline.qml" line="120"/>
<source>clear</source> <source>clear</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View File

@ -1359,27 +1359,33 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="17"/> <location filename="qml/page/T_GroupBox.qml" line="17"/>
<location filename="qml/page/T_GroupBox.qml" line="27"/> <location filename="qml/page/T_GroupBox.qml" line="35"/>
<source>E-mail</source> <source>E-mail</source>
<translation type="unfinished">邮箱</translation> <translation type="unfinished">邮箱</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="18"/> <location filename="qml/page/T_GroupBox.qml" line="18"/>
<location filename="qml/page/T_GroupBox.qml" line="28"/> <location filename="qml/page/T_GroupBox.qml" line="36"/>
<source>Calendar</source> <source>Calendar</source>
<translation type="unfinished">日历</translation> <translation type="unfinished">日历</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="19"/> <location filename="qml/page/T_GroupBox.qml" line="19"/>
<location filename="qml/page/T_GroupBox.qml" line="29"/> <location filename="qml/page/T_GroupBox.qml" line="37"/>
<source>Contacts</source> <source>Contacts</source>
<translation type="unfinished">联系人</translation> <translation type="unfinished">联系人</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_GroupBox.qml" line="24"/> <location filename="qml/page/T_GroupBox.qml" line="24"/>
<source>RadioButton Group</source> <source>RadioButton Group</source>
<oldsource>RadioButton Group111111111111111111111111</oldsource>
<translation type="unfinished">单选框分组</translation> <translation type="unfinished">单选框分组</translation>
</message> </message>
<message>
<location filename="qml/page/T_GroupBox.qml" line="46"/>
<source>Disabled</source>
<translation type="unfinished">禁用</translation>
</message>
</context> </context>
<context> <context>
<name>T_Home</name> <name>T_Home</name>
@ -1417,12 +1423,11 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<translation type="unfinished">请输入关键字</translation> <translation type="unfinished">请输入关键字</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Icons.qml" line="20"/>
<source>Search</source> <source>Search</source>
<translation type="unfinished">搜索</translation> <translation type="obsolete">搜索</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Icons.qml" line="60"/> <location filename="qml/page/T_Icons.qml" line="51"/>
<source>You Copied </source> <source>You Copied </source>
<translation type="unfinished">您复制</translation> <translation type="unfinished">您复制</translation>
</message> </message>
@ -1452,46 +1457,77 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<translation type="unfinished">信息栏</translation> <translation type="unfinished">信息栏</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="23"/> <location filename="qml/page/T_InfoBar.qml" line="27"/>
<source>Info</source> <source>Info</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="25"/> <location filename="qml/page/T_InfoBar.qml" line="29"/>
<location filename="qml/page/T_InfoBar.qml" line="49"/> <location filename="qml/page/T_InfoBar.qml" line="53"/>
<source>This is an InfoBar in the Info Style</source> <source>This is an InfoBar in the Info Style</source>
<translation type="unfinished">这是一个Info样式的信息栏</translation> <translation type="unfinished">这是一个Info样式的信息栏</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="29"/> <location filename="qml/page/T_InfoBar.qml" line="33"/>
<source>Warning</source> <source>Warning</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="31"/> <location filename="qml/page/T_InfoBar.qml" line="35"/>
<source>This is an InfoBar in the Warning Style</source> <source>This is an InfoBar in the Warning Style</source>
<translation type="unfinished">这是一个Warning样式的信息栏</translation> <translation type="unfinished">这是一个Warning样式的信息栏</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="37"/> <location filename="qml/page/T_InfoBar.qml" line="41"/>
<source>This is an InfoBar in the Error Style</source> <source>This is an InfoBar in the Error Style</source>
<translation type="unfinished">这是一个Error样式的信息栏</translation> <translation type="unfinished">这是一个Error样式的信息栏</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="43"/> <location filename="qml/page/T_InfoBar.qml" line="47"/>
<source>This is an InfoBar in the Success Style</source> <source>This is an InfoBar in the Success Style</source>
<translation type="unfinished">这是一个Success样式的信息栏</translation> <translation type="unfinished">这是一个Success样式的信息栏</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="47"/> <location filename="qml/page/T_InfoBar.qml" line="51"/>
<source>InfoBar that needs to be turned off manually</source> <source>InfoBar that needs to be turned off manually</source>
<translation type="unfinished">需要手动关闭的信息栏</translation> <translation type="unfinished">需要手动关闭的信息栏</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_InfoBar.qml" line="49"/> <location filename="qml/page/T_InfoBar.qml" line="53"/>
<source>Manual shutdown is supported</source> <source>Manual shutdown is supported</source>
<translation type="unfinished">支持手动关闭</translation> <translation type="unfinished">支持手动关闭</translation>
</message> </message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="59"/>
<source>Manually close the info message box</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="64"/>
<location filename="qml/page/T_InfoBar.qml" line="74"/>
<location filename="qml/page/T_InfoBar.qml" line="84"/>
<source>close &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="64"/>
<location filename="qml/page/T_InfoBar.qml" line="74"/>
<location filename="qml/page/T_InfoBar.qml" line="84"/>
<source>show &apos;%1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="70"/>
<location filename="qml/page/T_InfoBar.qml" line="80"/>
<location filename="qml/page/T_InfoBar.qml" line="90"/>
<source>This is an &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_InfoBar.qml" line="94"/>
<source>clear all info</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Loading...</source> <source>Loading...</source>
<translation type="obsolete">加载中...</translation> <translation type="obsolete">加载中...</translation>
@ -1500,7 +1536,7 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<context> <context>
<name>T_LineChart</name> <name>T_LineChart</name>
<message> <message>
<location filename="qml/chart/T_LineChart.qml" line="10"/> <location filename="qml/chart/T_LineChart.qml" line="11"/>
<source>Line Chart</source> <source>Line Chart</source>
<translation type="unfinished">线型图</translation> <translation type="unfinished">线型图</translation>
</message> </message>
@ -1808,22 +1844,30 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="38"/> <location filename="qml/page/T_RadioButton.qml" line="38"/>
<location filename="qml/page/T_RadioButton.qml" line="80"/> <location filename="qml/page/T_RadioButton.qml" line="79"/>
<location filename="qml/page/T_RadioButton.qml" line="130"/>
<location filename="qml/page/T_RadioButton.qml" line="181"/>
<source>Disabled</source> <source>Disabled</source>
<translation type="unfinished">禁用</translation> <translation type="unfinished">禁用</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="63"/> <location filename="qml/page/T_RadioButton.qml" line="64"/>
<location filename="qml/page/T_RadioButton.qml" line="115"/>
<location filename="qml/page/T_RadioButton.qml" line="166"/>
<source>Radio Button_1</source> <source>Radio Button_1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="67"/> <location filename="qml/page/T_RadioButton.qml" line="67"/>
<location filename="qml/page/T_RadioButton.qml" line="118"/>
<location filename="qml/page/T_RadioButton.qml" line="169"/>
<source>Radio Button_2</source> <source>Radio Button_2</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_RadioButton.qml" line="71"/> <location filename="qml/page/T_RadioButton.qml" line="70"/>
<location filename="qml/page/T_RadioButton.qml" line="121"/>
<location filename="qml/page/T_RadioButton.qml" line="172"/>
<source>Radio Button_3</source> <source>Radio Button_3</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2110,7 +2154,7 @@ Some contents...</source>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="177"/> <location filename="qml/page/T_TableView.qml" line="177"/>
<location filename="qml/page/T_TableView.qml" line="478"/> <location filename="qml/page/T_TableView.qml" line="509"/>
<source>Name</source> <source>Name</source>
<translation type="unfinished">名称</translation> <translation type="unfinished">名称</translation>
</message> </message>
@ -2130,57 +2174,67 @@ Some contents...</source>
<translation type="unfinished">全选</translation> <translation type="unfinished">全选</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="337"/> <location filename="qml/page/T_TableView.qml" line="365"/>
<source>Age</source> <source>Age</source>
<translation type="unfinished">年龄</translation> <translation type="unfinished">年龄</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="412"/> <location filename="qml/page/T_TableView.qml" line="440"/>
<source>Clear All</source> <source>Clear All</source>
<translation type="unfinished">清除所有</translation> <translation type="unfinished">清除所有</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="473"/> <location filename="qml/page/T_TableView.qml" line="476"/>
<source>Insert a Row</source>
<translation type="unfinished">插入一行</translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="483"/>
<source>Focus not acquired: Please click any item in the form as the target for insertion!</source>
<translation type="unfinished">焦点未获取:请点击表格中的任意一项,作为插入的靶点!</translation>
</message>
<message>
<location filename="qml/page/T_TableView.qml" line="514"/>
<source>Avatar</source> <source>Avatar</source>
<translation type="unfinished">头像</translation> <translation type="unfinished">头像</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="491"/> <location filename="qml/page/T_TableView.qml" line="528"/>
<source>Address</source> <source>Address</source>
<translation type="unfinished">地址</translation> <translation type="unfinished">地址</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="498"/> <location filename="qml/page/T_TableView.qml" line="536"/>
<source>Nickname</source> <source>Nickname</source>
<translation type="unfinished">昵称</translation> <translation type="unfinished">昵称</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="505"/> <location filename="qml/page/T_TableView.qml" line="543"/>
<source>Long String</source> <source>Long String</source>
<translation type="unfinished">长字符串</translation> <translation type="unfinished">长字符串</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="513"/> <location filename="qml/page/T_TableView.qml" line="551"/>
<source>Options</source> <source>Options</source>
<translation type="unfinished">操作</translation> <translation type="unfinished">操作</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="532"/> <location filename="qml/page/T_TableView.qml" line="569"/>
<source>&lt;Previous</source> <source>&lt;Previous</source>
<translation type="unfinished">&lt;上一页</translation> <translation type="unfinished">&lt;上一页</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="533"/> <location filename="qml/page/T_TableView.qml" line="570"/>
<source>Next&gt;</source> <source>Next&gt;</source>
<translation type="unfinished">下一页&gt;</translation> <translation type="unfinished">下一页&gt;</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="419"/> <location filename="qml/page/T_TableView.qml" line="447"/>
<source>Delete Selection</source> <source>Delete Selection</source>
<translation type="unfinished">删除选中</translation> <translation type="unfinished">删除选中</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="443"/> <location filename="qml/page/T_TableView.qml" line="470"/>
<source>Add a row of Data</source> <source>Add a row of Data</source>
<translation type="unfinished">添加一行数据</translation> <translation type="unfinished">添加一行数据</translation>
</message> </message>
@ -2335,12 +2389,12 @@ Some contents...</source>
<translation type="unfinished">时间轴</translation> <translation type="unfinished">时间轴</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Timeline.qml" line="115"/> <location filename="qml/page/T_Timeline.qml" line="114"/>
<source>Append</source> <source>Append</source>
<translation type="unfinished">追加</translation> <translation type="unfinished">追加</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Timeline.qml" line="121"/> <location filename="qml/page/T_Timeline.qml" line="120"/>
<source>clear</source> <source>clear</source>
<translation type="unfinished">清空</translation> <translation type="unfinished">清空</translation>
</message> </message>

View File

@ -7,7 +7,9 @@ import "../component"
FluScrollablePage{ FluScrollablePage{
id: root
title: qsTr("Line Chart") title: qsTr("Line Chart")
property var data : []
FluFrame{ FluFrame{
Layout.preferredWidth: 500 Layout.preferredWidth: 500
@ -15,13 +17,14 @@ FluScrollablePage{
padding: 10 padding: 10
Layout.topMargin: 20 Layout.topMargin: 20
FluChart{ FluChart{
id: chart
anchors.fill: parent anchors.fill: parent
chartType: 'line' chartType: 'line'
chartData: { return { chartData: { return {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{ datasets: [{
label: 'My First Dataset', label: 'My First Dataset',
data: [65, 59, 80, 81, 56, 55, 40], data: root.data,
fill: false, fill: false,
borderColor: 'rgb(75, 192, 192)', borderColor: 'rgb(75, 192, 192)',
tension: 0.1 tension: 0.1
@ -41,5 +44,20 @@ FluScrollablePage{
} }
} }
} }
Timer{
id: timer
interval: 300
repeat: true
onTriggered: {
root.data.push(Math.random()*100)
if(root.data.length>7){
root.data.shift()
}
chart.animateToNewData()
}
}
Component.onCompleted: {
timer.restart()
}
} }
} }

View File

@ -22,18 +22,37 @@ FluScrollablePage{
FluGroupBox { FluGroupBox {
title: qsTr("RadioButton Group") title: qsTr("RadioButton Group")
Layout.fillWidth: true
Layout.preferredHeight: 150
Layout.topMargin: 20
FluRadioButtons { FluRadioButtons {
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
spacing: 10 spacing: 10
disabled: radio_button_switch.checked
FluRadioButton { text: qsTr("E-mail") } FluRadioButton { text: qsTr("E-mail") }
FluRadioButton { text: qsTr("Calendar") } FluRadioButton { text: qsTr("Calendar") }
FluRadioButton { text: qsTr("Contacts") } FluRadioButton { text: qsTr("Contacts") }
} }
FluToggleSwitch{
id: radio_button_switch
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text: qsTr("Disabled")
}
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 4 Layout.topMargin: 4
code:'FluGroupBox { code:`
FluGroupBox {
title: qsTr("CheckBox Group") title: qsTr("CheckBox Group")
ColumnLayout { ColumnLayout {
spacing: 10 spacing: 10
@ -42,7 +61,20 @@ FluScrollablePage{
FluCheckBox { text: qsTr("Calendar") } FluCheckBox { text: qsTr("Calendar") }
FluCheckBox { text: qsTr("Contacts") } FluCheckBox { text: qsTr("Contacts") }
} }
}' }
FluGroupBox {
title: qsTr("RadioButton Group")
FluRadioButtons {
spacing: 10
disabled: true // 禁用所有FluRadioButton子组件
manuallyDisabled: true // 是否指定每个FluRadioButton上的disabled选项
FluRadioButton { text: qsTr("E-mail") }
FluRadioButton { text: qsTr("Calendar") }
FluRadioButton { text: qsTr("Contacts") }
}
}
`
} }
} }

View File

@ -14,17 +14,8 @@ FluContentPage {
anchors{ anchors{
top: parent.top top: parent.top
} }
} onTextChanged: {
grid_view.model = FluApp.iconData(text_box.text)
FluFilledButton{
text: qsTr("Search")
anchors{
left: text_box.right
verticalCenter: text_box.verticalCenter
leftMargin: 14
}
onClicked: {
grid_view.model = FluApp.iconDatas(text_box.text)
} }
} }
GridView{ GridView{
@ -33,7 +24,7 @@ FluContentPage {
cellHeight: 110 cellHeight: 110
clip: true clip: true
boundsBehavior: GridView.StopAtBounds boundsBehavior: GridView.StopAtBounds
model: FluApp.iconDatas() model: FluApp.iconData()
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
anchors{ anchors{
topMargin: 10 topMargin: 10

View File

@ -9,9 +9,13 @@ FluScrollablePage{
title: qsTr("InfoBar") title: qsTr("InfoBar")
property var info1
property var info2
property var info3
FluFrame{ FluFrame{
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 270 Layout.preferredHeight: 350
padding: 10 padding: 10
ColumnLayout{ ColumnLayout{
spacing: 14 spacing: 14
@ -49,6 +53,51 @@ FluScrollablePage{
showInfo(qsTr("This is an InfoBar in the Info Style"),0,qsTr("Manual shutdown is supported")) showInfo(qsTr("This is an InfoBar in the Info Style"),0,qsTr("Manual shutdown is supported"))
} }
} }
FluText{
wrapMode: Text.WrapAnywhere
width: parent.width
text: qsTr("Manually close the info message box")
}
Row{
spacing: 5
FluButton{
text: (info1 ? qsTr("close '%1'") : qsTr("show '%1")).arg("info1")
onClicked: {
if(info1) {
info1.close()
return
}
info1 = showInfo(qsTr("This is an '%1'").arg("info1"), 0)
}
}
FluButton{
text: (info2 ? qsTr("close '%1'") : qsTr("show '%1")).arg("info2")
onClicked: {
if(info2) {
info2.close()
return
}
info2 = showInfo(qsTr("This is an '%1'").arg("info2"), 0)
}
}
FluButton{
text: (info3 ? qsTr("close '%1'") : qsTr("show '%1")).arg("info3")
onClicked: {
if(info3) {
info3.close()
return
}
info3 = showInfo(qsTr("This is an '%1'").arg("info3"), 0)
}
}
FluButton{
text: qsTr("clear all info")
onClicked: {
clearAllInfo()
}
}
}
FluButton{ FluButton{
text:"Loading" text:"Loading"
onClicked: { onClicked: {
@ -60,12 +109,17 @@ FluScrollablePage{
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -6 Layout.topMargin: -6
code:'showInfo(qsTr("This is an InfoBar in the Info Style")) code:`
showInfo(qsTr("This is an InfoBar in the Info Style"))
showWarning(qsTr("This is an InfoBar in the Warning Style")) showWarning(qsTr("This is an InfoBar in the Warning Style"))
showError(qsTr("This is an InfoBar in the Error Style")) showError(qsTr("This is an InfoBar in the Error Style"))
showSuccess(qsTr("This is an InfoBar in the Success Style"))' showSuccess(qsTr("This is an InfoBar in the Success Style"))
var info1 = showInfo(qsTr("This is an 'Info1'"), 0)
info1.close()
`
} }
} }

View File

@ -53,21 +53,20 @@ FluScrollablePage{
Layout.topMargin: 20 Layout.topMargin: 20
FluRadioButtons{ FluRadioButtons{
spacing: 8 spacing: 8
disabled: radio_button_switch2.checked
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
} }
currentIndex: 1
FluRadioButton{ FluRadioButton{
disabled: radio_button_switch2.checked
text: qsTr("Radio Button_1") text: qsTr("Radio Button_1")
} }
FluRadioButton{ FluRadioButton{
disabled: radio_button_switch2.checked
text: qsTr("Radio Button_2") text: qsTr("Radio Button_2")
} }
FluRadioButton{ FluRadioButton{
disabled: radio_button_switch2.checked
text: qsTr("Radio Button_3") text: qsTr("Radio Button_3")
} }
} }
@ -97,4 +96,106 @@ FluScrollablePage{
}' }'
} }
FluFrame{
Layout.fillWidth: true
Layout.preferredHeight: 60
padding: 10
Layout.topMargin: 20
FluRadioButtons{
spacing: 8
anchors.verticalCenter: parent.verticalCenter
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
disabled: radio_button_switch3.checked
orientation: Qt.Horizontal
currentIndex: 1
FluRadioButton{
text: qsTr("Radio Button_1")
}
FluRadioButton{
text: qsTr("Radio Button_2")
}
FluRadioButton{
text: qsTr("Radio Button_3")
}
}
FluToggleSwitch{
id: radio_button_switch3
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text: qsTr("Disabled")
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -6
code:'FluRadioButtons{
spacing: 8
orientation: Qt.Horizontal
FluRadioButton{
text:"Radio Button_1"
}
FluRadioButton{
text:"Radio Button_2"
}
FluRadioButton{
text:"Radio Button_3"
}
}'
}
FluFrame{
Layout.fillWidth: true
Layout.preferredHeight: 100
padding: 10
Layout.topMargin: 20
FluRadioButtons{
spacing: 8
anchors.verticalCenter: parent.verticalCenter
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
disabled: radio_button_switch4.checked
currentIndex: -1
FluCheckBox{
text: qsTr("Radio Button_1")
}
FluCheckBox{
text: qsTr("Radio Button_2")
}
FluCheckBox{
text: qsTr("Radio Button_3")
}
}
FluToggleSwitch{
id: radio_button_switch4
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text: qsTr("Disabled")
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -6
code:'FluRadioButtons{
spacing: 8
FluCheckBox{
text:"Radio Button_1"
}
FluCheckBox{
text:"Radio Button_2"
}
FluCheckBox{
text:"Radio Button_3"
}
}'
}
} }

View File

@ -13,7 +13,7 @@ FluContentPage{
property var dataSource : [] property var dataSource : []
property int sortType: 0 property int sortType: 0
property bool seletedAll: true property bool selectedAll: true
property string nameKeyword: "" property string nameKeyword: ""
onNameKeywordChanged: { onNameKeywordChanged: {
@ -32,11 +32,11 @@ FluContentPage{
onCheckBoxChanged: { onCheckBoxChanged: {
for(var i =0;i< table_view.rows ;i++){ for(var i =0;i< table_view.rows ;i++){
if(false === table_view.getRow(i).checkbox.options.checked){ if(false === table_view.getRow(i).checkbox.options.checked){
root.seletedAll = false root.selectedAll = false
return return
} }
} }
root.seletedAll = true root.selectedAll = true
} }
onSortTypeChanged: { onSortTypeChanged: {
@ -238,13 +238,15 @@ FluContentPage{
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
} }
FluCheckBox{ FluCheckBox{
checked: true === root.seletedAll checked: true === root.selectedAll
animationEnabled: false animationEnabled: false
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
clickListener: function(){ clickListener: function(){
root.seletedAll = !root.seletedAll root.selectedAll = !root.selectedAll
var checked = root.seletedAll var checked = root.selectedAll
itemModel.display = table_view.customItem(com_column_checbox,{"checked":checked}) var columnModel = model.display
columnModel.title = table_view.customItem(com_column_checbox,{"checked":checked})
model.display = columnModel
for(var i =0;i< table_view.rows ;i++){ for(var i =0;i< table_view.rows ;i++){
var rowData = table_view.getRow(i) var rowData = table_view.getRow(i)
rowData.checkbox = table_view.customItem(com_checbox,{"checked":checked}) rowData.checkbox = table_view.customItem(com_checbox,{"checked":checked})
@ -271,7 +273,8 @@ FluContentPage{
} }
Component.onCompleted: { Component.onCompleted: {
currentIndex=["100","300","500","1000"].findIndex((element) => element === display) currentIndex=["100","300","500","1000"].findIndex((element) => element === display)
selectAll() textBox.forceActiveFocus()
textBox.selectAll()
} }
onCommit: { onCommit: {
editTextChaged(editText) editTextChaged(editText)
@ -280,6 +283,29 @@ FluContentPage{
} }
} }
Component{
id:com_auto_suggestbox
FluAutoSuggestBox {
id: textbox
anchors.fill: parent
focus: true
Component.onCompleted: {
var data = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
var result = data.map(function(item) {
return {title: item};
});
items = result
textbox.text= String(display)
forceActiveFocus()
selectAll()
}
onCommit: {
editTextChaged(textbox.text)
tableView.closeEditor()
}
}
}
Component{ Component{
id:com_avatar id:com_avatar
Item{ Item{
@ -323,7 +349,9 @@ FluContentPage{
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
custom_update_dialog.showDialog(options.title,function(text){ custom_update_dialog.showDialog(options.title,function(text){
itemModel.display = table_view.customItem(com_column_update_title,{"title":text}) var columnModel = model.display
columnModel.title = table_view.customItem(com_column_update_title,{"title":text})
model.display = columnModel
}) })
} }
} }
@ -421,15 +449,15 @@ FluContentPage{
var data = [] var data = []
var rows = [] var rows = []
for (var i = 0; i < table_view.rows; i++) { for (var i = 0; i < table_view.rows; i++) {
var item = table_view.getRow(i); var item = table_view.getRow(i)
rows.push(item) rows.push(item)
if (!item.checkbox.options.checked) { if (!item.checkbox.options.checked) {
data.push(item); data.push(item);
} }
} }
var sourceModel = table_view.sourceModel; var sourceModel = table_view.sourceModel
for (i = 0; i < sourceModel.rowCount; i++) { for (i = 0; i < sourceModel.rowCount; i++) {
var sourceItem = sourceModel.getRow(i); var sourceItem = sourceModel.getRow(i)
const foundItem = rows.find(item=> item._key === sourceItem._key) const foundItem = rows.find(item=> item._key === sourceItem._key)
if (!foundItem) { if (!foundItem) {
data.push(sourceItem); data.push(sourceItem);
@ -438,14 +466,24 @@ FluContentPage{
table_view.dataSource = data table_view.dataSource = data
} }
} }
FluButton{ FluButton{
text: qsTr("Add a row of Data") text: qsTr("Add a row of Data")
onClicked: { onClicked: {
table_view.appendRow(genTestObject()) table_view.appendRow(genTestObject())
} }
} }
FluButton{
text: qsTr("Insert a Row")
onClicked: {
var index = table_view.currentIndex()
if(index !== -1){
var testObj = genTestObject()
table_view.insertRow(index,testObj)
}else{
showWarning(qsTr("Focus not acquired: Please click any item in the form as the target for insertion!"))
}
}
}
} }
} }
@ -465,20 +503,19 @@ FluContentPage{
{ {
title: table_view.customItem(com_column_checbox,{checked:true}), title: table_view.customItem(com_column_checbox,{checked:true}),
dataIndex: 'checkbox', dataIndex: 'checkbox',
width:100, frozen: true
minimumWidth:100,
maximumWidth:100
},
{
title: table_view.customItem(com_column_update_title,{title:qsTr("Avatar")}),
dataIndex: 'avatar',
width:100
}, },
{ {
title: table_view.customItem(com_column_filter_name,{title:qsTr("Name")}), title: table_view.customItem(com_column_filter_name,{title:qsTr("Name")}),
dataIndex: 'name', dataIndex: 'name',
readOnly:true readOnly:true
}, },
{
title: table_view.customItem(com_column_update_title,{title:qsTr("Avatar")}),
dataIndex: 'avatar',
width:100,
frozen:true
},
{ {
title: table_view.customItem(com_column_sort_age,{sort:0}), title: table_view.customItem(com_column_sort_age,{sort:0}),
dataIndex: 'age', dataIndex: 'age',
@ -490,6 +527,7 @@ FluContentPage{
{ {
title: qsTr("Address"), title: qsTr("Address"),
dataIndex: 'address', dataIndex: 'address',
editDelegate: com_auto_suggestbox,
width:200, width:200,
minimumWidth:100, minimumWidth:100,
maximumWidth:250 maximumWidth:250
@ -513,8 +551,7 @@ FluContentPage{
title: qsTr("Options"), title: qsTr("Options"),
dataIndex: 'action', dataIndex: 'action',
width:160, width:160,
minimumWidth:160, frozen:true
maximumWidth:160
} }
] ]
} }
@ -566,7 +603,7 @@ FluContentPage{
return avatars[randomIndex]; return avatars[randomIndex];
} }
return { return {
checkbox: table_view.customItem(com_checbox,{checked:root.seletedAll}), checkbox: table_view.customItem(com_checbox,{checked:root.selectedAll}),
avatar:table_view.customItem(com_avatar,{avatar:getAvatar()}), avatar:table_view.customItem(com_avatar,{avatar:getAvatar()}),
name: getRandomName(), name: getRandomName(),
age:getRandomAge(), age:getRandomAge(),
@ -579,7 +616,7 @@ FluContentPage{
} }
} }
function loadData(page,count){ function loadData(page,count){
root.seletedAll = true root.selectedAll = true
const dataSource = [] const dataSource = []
for(var i=0;i<count;i++){ for(var i=0;i<count;i++){
dataSource.push(genTestObject()) dataSource.push(genTestObject())

View File

@ -44,7 +44,6 @@ FluScrollablePage{
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
text: modelData.text text: modelData.text
font.bold: true
linkColor: FluTheme.dark ? FluColors.Teal.lighter : FluColors.Teal.dark linkColor: FluTheme.dark ? FluColors.Teal.lighter : FluColors.Teal.dark
onLinkActivated: onLinkActivated:
(link)=> { (link)=> {

View File

@ -15,7 +15,7 @@ FluWindow {
title: "FluentUI" title: "FluentUI"
width: 1000 width: 1000
height: 680 height: 680
minimumWidth: 1000 minimumWidth: 800
minimumHeight: 200 minimumHeight: 200
launchMode: FluWindowType.SingleTask launchMode: FluWindowType.SingleTask
fitsAppBarWindows: true fitsAppBarWindows: true

View File

@ -180,5 +180,15 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
Qt${QT_VERSION_MAJOR}::Qml Qt${QT_VERSION_MAJOR}::Qml
) )
if ((${QT_VERSION_MAJOR} LESS_EQUAL 6) AND (CMAKE_BUILD_TYPE MATCHES "Release"))
find_program(QML_PLUGIN_DUMP NAMES qmlplugindump)
add_custom_target(Script-Generate-QmlTypes
COMMAND ${QML_PLUGIN_DUMP} -nonrelocatable FluentUI 1.0 ${CMAKE_CURRENT_BINARY_DIR} > ${CMAKE_CURRENT_SOURCE_DIR}/Qt5/imports/FluentUI/plugins.qmltypes
COMMENT "Generate qmltypes........."
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Qt5/imports/FluentUI/plugins.qmltypes
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
#安装 #安装
install(DIRECTORY ${FLUENTUI_QML_PLUGIN_DIRECTORY} DESTINATION ${CMAKE_INSTALL_PREFIX}/imports) install(DIRECTORY ${FLUENTUI_QML_PLUGIN_DIRECTORY} DESTINATION ${CMAKE_INSTALL_PREFIX}/imports)

View File

@ -1,6 +1,5 @@
#include "FluApp.h" #include "FluApp.h"
#include <QQmlEngine>
#include <QGuiApplication> #include <QGuiApplication>
#include <QQuickItem> #include <QQuickItem>
#include <QTimer> #include <QTimer>
@ -32,7 +31,7 @@ void FluApp::init(QObject *target, QLocale locale) {
} }
} }
[[maybe_unused]] QJsonArray FluApp::iconDatas(const QString &keyword) { [[maybe_unused]] QJsonArray FluApp::iconData(const QString &keyword) {
QJsonArray arr; QJsonArray arr;
QMetaEnum enumType = Fluent_Icons::staticMetaObject.enumerator(Fluent_Icons::staticMetaObject.indexOfEnumerator("Fluent_IconType")); QMetaEnum enumType = Fluent_Icons::staticMetaObject.enumerator(Fluent_Icons::staticMetaObject.indexOfEnumerator("Fluent_IconType"));
for (int i = 0; i <= enumType.keyCount() - 1; ++i) { for (int i = 0; i <= enumType.keyCount() - 1; ++i) {

View File

@ -36,7 +36,7 @@ SINGLETON(FluApp)
Q_INVOKABLE void init(QObject *target, QLocale locale = QLocale::system()); Q_INVOKABLE void init(QObject *target, QLocale locale = QLocale::system());
[[maybe_unused]] Q_INVOKABLE static QJsonArray iconDatas(const QString &keyword = ""); [[maybe_unused]] Q_INVOKABLE static QJsonArray iconData(const QString &keyword = "");
private: private:
QQmlEngine *_engine{}; QQmlEngine *_engine{};

View File

@ -7,6 +7,7 @@
#include "FluTools.h" #include "FluTools.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment (lib, "user32.lib") #pragma comment (lib, "user32.lib")
#pragma comment (lib, "dwmapi.lib") #pragma comment (lib, "dwmapi.lib")
@ -14,7 +15,6 @@
#include <windowsx.h> #include <windowsx.h>
#include <dwmapi.h> #include <dwmapi.h>
static inline QByteArray qtNativeEventType() { static inline QByteArray qtNativeEventType() {
static const auto result = "windows_generic_MSG"; static const auto result = "windows_generic_MSG";
return result; return result;
@ -35,15 +35,28 @@ static inline bool isCompositionEnabled() {
return false; return false;
} }
static inline void setShadow(HWND hwnd) {
const MARGINS shadow = {1, 0, 0, 0};
typedef HRESULT (WINAPI *DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset);
HMODULE module = LoadLibraryW(L"dwmapi.dll");
if (module) {
DwmExtendFrameIntoClientAreaPtr dwm_extendframe_into_client_area_;
dwm_extendframe_into_client_area_ = reinterpret_cast<DwmExtendFrameIntoClientAreaPtr>(GetProcAddress(module, "DwmExtendFrameIntoClientArea"));
if (dwm_extendframe_into_client_area_) {
dwm_extendframe_into_client_area_(hwnd, &shadow);
}
}
}
#endif #endif
bool containsCursorToItem(QQuickItem *item) { bool containsCursorToItem(QQuickItem *item) {
if (!item || !item->isVisible()) { if (!item || !item->isVisible()) {
return false; return false;
} }
auto point = QCursor::pos(); auto point = item->window()->mapFromGlobal(QCursor::pos());
auto rect = QRectF(item->mapToGlobal(QPoint(0, 0)), item->size()); auto rect = QRectF(item->mapToItem(item->window()->contentItem(), QPointF(0, 0)), item->size());
if (point.x() > rect.x() && point.x() < (rect.x() + rect.width()) && point.y() > rect.y() && point.y() < (rect.y() + rect.height())) { if (rect.contains(point)) {
return true; return true;
} }
return false; return false;
@ -74,11 +87,6 @@ void FluFrameless::componentComplete() {
int h = window()->height(); int h = window()->height();
_current = window()->winId(); _current = window()->winId();
window()->setFlags((window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint); window()->setFlags((window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (QQuickWindow::sceneGraphBackend() == "software") {
window()->setFlag(Qt::FramelessWindowHint, false);
}
#endif
if (!_fixSize) { if (!_fixSize) {
window()->setFlag(Qt::WindowMaximizeButtonHint); window()->setFlag(Qt::WindowMaximizeButtonHint);
} }
@ -97,20 +105,31 @@ void FluFrameless::componentComplete() {
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE); DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
if (_fixSize) { if (_fixSize) {
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME); #if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3) || QT_VERSION == QT_VERSION_CHECK(6, 6, 0))
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME);;
#else
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);
#endif
for (int i = 0; i <= QGuiApplication::screens().count() - 1; ++i) { for (int i = 0; i <= QGuiApplication::screens().count() - 1; ++i) {
connect(QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] { connect(QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] {
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED); SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
}); });
} }
} else { } else {
#if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3) || QT_VERSION == QT_VERSION_CHECK(6, 6, 0))
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME); ::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME);
#else
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
#endif
} }
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
connect(window(), &QQuickWindow::screenChanged, this, [hwnd] { connect(window(), &QQuickWindow::screenChanged, this, [hwnd] {
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER); ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); ::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
}); });
if (!window()->property("_hideShadow").toBool()) {
setShadow(hwnd);
}
#endif #endif
h = qRound(h + _appbar->height()); h = qRound(h + _appbar->height());
if (_fixSize) { if (_fixSize) {
@ -141,7 +160,6 @@ void FluFrameless::componentComplete() {
const auto uMsg = msg->message; const auto uMsg = msg->message;
const auto wParam = msg->wParam; const auto wParam = msg->wParam;
const auto lParam = msg->lParam; const auto lParam = msg->lParam;
static QPoint offsetXY;
if (uMsg == WM_WINDOWPOSCHANGING) { if (uMsg == WM_WINDOWPOSCHANGING) {
auto *wp = reinterpret_cast<WINDOWPOS *>(lParam); auto *wp = reinterpret_cast<WINDOWPOS *>(lParam);
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) { if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) {
@ -150,42 +168,37 @@ void FluFrameless::componentComplete() {
return true; return true;
} }
return false; return false;
} else if (uMsg == WM_NCCALCSIZE) { } else if (uMsg == WM_NCCALCSIZE && wParam == TRUE) {
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]); const auto clientRect = &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0];
const LONG originalTop = clientRect->top; const LONG originalTop = clientRect->top;
const LONG originalLeft = clientRect->left; const LONG originalLeft = clientRect->left;
const LONG originalRight = clientRect->right;
const LONG originalBottom = clientRect->bottom; const LONG originalBottom = clientRect->bottom;
const LONG originalRight = clientRect->right;
const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam); const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam);
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) { if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(hitTestResult); *result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(hitTestResult);
return true; return true;
} }
int offsetSize; #if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3) || QT_VERSION == QT_VERSION_CHECK(6, 6, 0))
bool isMaximum = ::IsZoomed(hwnd); clientRect->top = originalTop;
auto _offsetXY = QPoint(abs(clientRect->left - originalLeft), abs(clientRect->top - originalTop)); clientRect->bottom = originalBottom;
if (_offsetXY.x() != 0) { clientRect->left = originalLeft;
offsetXY = _offsetXY; clientRect->right = originalRight;
}
if (isMaximum || _isFullScreen()) {
offsetSize = 0;
} else {
offsetSize = 1;
}
if (!isCompositionEnabled()) {
offsetSize = 0;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
clientRect->top = originalTop + offsetSize;
clientRect->bottom = originalBottom - offsetSize;
clientRect->left = originalLeft + offsetSize;
clientRect->right = originalRight - offsetSize;
#else #else
if (!isMaximum) { bool isMaximum = ::IsZoomed(hwnd);
clientRect->top = originalTop + offsetSize; if (isMaximum) {
clientRect->bottom = originalBottom - offsetSize; auto geometry = window()->screen()->geometry();
clientRect->left = originalLeft + offsetSize; auto offsetX = qAbs(geometry.left()-originalLeft);
clientRect->right = originalRight - offsetSize; auto offsetY = qAbs(geometry.top()-originalTop);
clientRect->top = originalTop + offsetY;
clientRect->bottom = originalBottom - offsetY;
clientRect->left = originalLeft + offsetX;
clientRect->right = originalRight - offsetX;
} else {
clientRect->top = originalTop;
clientRect->bottom = originalBottom;
clientRect->left = originalLeft;
clientRect->right = originalRight;
} }
#endif #endif
_setMaximizeHovered(false); _setMaximizeHovered(false);
@ -244,6 +257,41 @@ void FluFrameless::componentComplete() {
} }
*result = HTCLIENT; *result = HTCLIENT;
return true; return true;
} else if (uMsg == WM_NCPAINT) {
#if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3) || QT_VERSION == QT_VERSION_CHECK(6, 6, 0))
*result = FALSE;
return true;
#else
if (isCompositionEnabled()) {
return false;
}
*result = FALSE;
return true;
#endif
} else if (uMsg == WM_NCACTIVATE) {
#if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3) || QT_VERSION == QT_VERSION_CHECK(6, 6, 0))
*result = TRUE;
return true;
#else
if (isCompositionEnabled()) {
return false;
}
*result = TRUE;
return true;
#endif
} else if (uMsg == WM_GETMINMAXINFO) {
#if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3) || QT_VERSION == QT_VERSION_CHECK(6, 6, 0))
auto *minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
auto pixelRatio = window()->devicePixelRatio();
auto geometry = window()->screen()->availableGeometry();
RECT rect;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
minmaxInfo->ptMaxPosition.x = rect.left;
minmaxInfo->ptMaxPosition.y = rect.top;
minmaxInfo->ptMaxSize.x = qRound(geometry.width() * pixelRatio);
minmaxInfo->ptMaxSize.y = qRound(geometry.height() * pixelRatio);
#endif
return false;
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN)) { } else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN)) {
if (_hitMaximizeButton()) { if (_hitMaximizeButton()) {
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
@ -258,38 +306,11 @@ void FluFrameless::componentComplete() {
_setMaximizePressed(false); _setMaximizePressed(false);
return true; return true;
} }
} else if (uMsg == WM_NCPAINT) {
*result = FALSE;
return true;
} else if (uMsg == WM_NCACTIVATE) {
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1));
return true;
} else if (uMsg == WM_GETMINMAXINFO) {
auto *minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
minmaxInfo->ptMaxPosition.x = 0;
minmaxInfo->ptMaxPosition.y = 0;
minmaxInfo->ptMaxSize.x = 0;
minmaxInfo->ptMaxSize.y = 0;
return false;
#else
auto pixelRatio = window()->devicePixelRatio();
auto geometry = window()->screen()->availableGeometry();
RECT rect;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
if (!_fixSize) {
minmaxInfo->ptMinTrackSize.x = qRound(window()->minimumWidth() * pixelRatio + offsetXY.x());
minmaxInfo->ptMinTrackSize.y = qRound(window()->minimumHeight() * pixelRatio + offsetXY.y() + _appbar->height() * pixelRatio);
}
minmaxInfo->ptMaxPosition.x = rect.left - offsetXY.x();
minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x();
minmaxInfo->ptMaxSize.x = qRound(geometry.width() * pixelRatio) + offsetXY.x() * 2;
minmaxInfo->ptMaxSize.y = qRound(geometry.height() * pixelRatio) + offsetXY.y() * 2;
return true;
#endif
} else if (uMsg == WM_NCRBUTTONDOWN) { } else if (uMsg == WM_NCRBUTTONDOWN) {
if (wParam == HTCAPTION) { if (wParam == HTCAPTION) {
_showSystemMenu(QCursor::pos()); auto pos = window()->position();
auto offset = window()->mapFromGlobal(QCursor::pos());
_showSystemMenu(QPoint(pos.x() + offset.x(), pos.y() + offset.y()));
} }
} else if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN) { } else if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN) {
const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0)); const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0));
@ -327,9 +348,16 @@ bool FluFrameless::_isFullScreen() {
void FluFrameless::_showSystemMenu(QPoint point) { void FluFrameless::_showSystemMenu(QPoint point) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QScreen *screen = window()->screen();
if (!screen) {
screen = QGuiApplication::primaryScreen();
}
if (!screen) {
return;
}
const QPoint origin = screen->geometry().topLeft();
auto nativePos = QPointF(QPointF(point - origin) * window()->devicePixelRatio()).toPoint() + origin;
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU);
auto hMenu = ::GetSystemMenu(hwnd, FALSE); auto hMenu = ::GetSystemMenu(hwnd, FALSE);
if (_isMaximized() || _isFullScreen()) { if (_isMaximized() || _isFullScreen()) {
::EnableMenuItem(hMenu, SC_MOVE, MFS_DISABLED); ::EnableMenuItem(hMenu, SC_MOVE, MFS_DISABLED);
@ -345,12 +373,11 @@ void FluFrameless::_showSystemMenu(QPoint point) {
::EnableMenuItem(hMenu, SC_SIZE, MFS_DISABLED); ::EnableMenuItem(hMenu, SC_SIZE, MFS_DISABLED);
::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_DISABLED); ::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_DISABLED);
} }
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), qRound(point.x() * window()->devicePixelRatio()), const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), nativePos.x(),
qRound(point.y() * window()->devicePixelRatio()), 0, hwnd, nullptr); nativePos.y(), 0, hwnd, nullptr);
if (result != FALSE) { if (result) {
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0); ::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
} }
::SetWindowLongPtr(hwnd, GWL_STYLE, style & ~WS_SYSMENU);
#endif #endif
} }
@ -375,11 +402,15 @@ bool FluFrameless::_hitMaximizeButton() {
} }
void FluFrameless::_setMaximizePressed(bool val) { void FluFrameless::_setMaximizePressed(bool val) {
_maximizeButton->setProperty("down", val); if(_maximizeButton){
_maximizeButton->setProperty("down", val);
}
} }
void FluFrameless::_setMaximizeHovered(bool val) { void FluFrameless::_setMaximizeHovered(bool val) {
_maximizeButton->setProperty("hover", val); if(_maximizeButton){
_maximizeButton->setProperty("hover", val);
}
} }
void FluFrameless::_updateCursor(int edges) { void FluFrameless::_updateCursor(int edges) {

63
src/FluTableModel.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "FluTableModel.h"
FluTableModel::FluTableModel(QObject *parent) : QAbstractTableModel{parent} {
}
int FluTableModel::rowCount(const QModelIndex &parent) const {
return _rows.count();
}
int FluTableModel::columnCount(const QModelIndex &parent) const {
return this->_columnSource.size();
}
QVariant FluTableModel::data(const QModelIndex &index, int role) const {
switch (role) {
case FluTableModel::RowModel:
return QVariant::fromValue(_rows.at(index.row()));
case FluTableModel::ColumnModel:
return QVariant::fromValue(_columnSource.at(index.column()));
default:
break;
}
return {};
}
QHash<int, QByteArray> FluTableModel::roleNames() const {
return {
{FluTableModel::RowModel, "rowModel"},
{FluTableModel::ColumnModel, "columnModel"}
};
}
void FluTableModel::clear() {
beginResetModel();
this->_rows.clear();
endResetModel();
}
QVariant FluTableModel::getRow(int rowIndex) {
return _rows.at(rowIndex);
}
void FluTableModel::setRow(int rowIndex, QVariant row) {
_rows.replace(rowIndex, row.toMap());
Q_EMIT dataChanged(index(rowIndex, 0), index(rowIndex, columnCount() - 1));
}
void FluTableModel::insertRow(int rowIndex, QVariant row) {
beginInsertRows(QModelIndex(), rowIndex, rowIndex);
_rows.insert(rowIndex, row.toMap());
endInsertRows();
}
void FluTableModel::removeRow(int rowIndex, int rows) {
beginRemoveRows(QModelIndex(), rowIndex, rowIndex + rows - 1);
_rows = _rows.mid(0, rowIndex) + _rows.mid(rowIndex + rows);
endRemoveRows();
}
void FluTableModel::appendRow(QVariant row) {
insertRow(rowCount(), row);
}

46
src/FluTableModel.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef FLUTABLEMODEL_H
#define FLUTABLEMODEL_H
#include <QObject>
#include <QAbstractItemModel>
#include <QtQml/qqml.h>
#include "stdafx.h"
class FluTableModel : public QAbstractTableModel {
Q_OBJECT
Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource)
Q_PROPERTY_AUTO(QList<QVariantMap>, rows)
Q_PROPERTY(int rowCount READ rowCount CONSTANT)
QML_NAMED_ELEMENT(FluTableModel)
public:
enum TableModelRoles {
RowModel = 0x0101,
ColumnModel = 0x0102
};
explicit FluTableModel(QObject *parent = nullptr);
[[nodiscard]] int rowCount(const QModelIndex &parent = {}) const override;
[[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void clear();
Q_INVOKABLE QVariant getRow(int rowIndex);
Q_INVOKABLE void setRow(int rowIndex, QVariant row);
Q_INVOKABLE void insertRow(int rowIndex, QVariant row);
Q_INVOKABLE void removeRow(int rowIndex, int rows = 1);
Q_INVOKABLE void appendRow(QVariant row);
};
#endif // FLUTABLEMODEL_H

View File

@ -3,9 +3,8 @@
#include <QJSValueList> #include <QJSValueList>
FluTableSortProxyModel::FluTableSortProxyModel(QSortFilterProxyModel *parent) : QSortFilterProxyModel{parent} { FluTableSortProxyModel::FluTableSortProxyModel(QSortFilterProxyModel *parent) : QSortFilterProxyModel{parent} {
_model = nullptr;
connect(this, &FluTableSortProxyModel::modelChanged, this, [=] { connect(this, &FluTableSortProxyModel::modelChanged, this, [=] {
setSourceModel(this->model()); setSourceModel(this->model().value<QAbstractTableModel *>());
}); });
} }
@ -59,15 +58,18 @@ bool FluTableSortProxyModel::lessThan(const QModelIndex &source_left, const QMod
[[maybe_unused]] QVariant FluTableSortProxyModel::getRow(int rowIndex) { [[maybe_unused]] QVariant FluTableSortProxyModel::getRow(int rowIndex) {
QVariant result; QVariant result;
QMetaObject::invokeMethod(_model, "getRow", Q_RETURN_ARG(QVariant, result), Q_ARG(int, mapToSource(index(rowIndex, 0)).row())); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "getRow", Q_RETURN_ARG(QVariant, result), Q_ARG(int, mapToSource(index(rowIndex, 0)).row()));
return result; return result;
} }
[[maybe_unused]] void FluTableSortProxyModel::setRow(int rowIndex, const QVariant &val) { [[maybe_unused]] void FluTableSortProxyModel::setRow(int rowIndex, const QVariant &val) {
QMetaObject::invokeMethod(_model, "setRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(QVariant, val)); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "setRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(QVariant, val));
}
[[maybe_unused]] void FluTableSortProxyModel::insertRow(int rowIndex, const QVariant &val) {
QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "insertRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(QVariant, val));
} }
[[maybe_unused]] void FluTableSortProxyModel::removeRow(int rowIndex, int rows) { [[maybe_unused]] void FluTableSortProxyModel::removeRow(int rowIndex, int rows) {
QMetaObject::invokeMethod(_model, "removeRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(int, rows)); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "removeRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(int, rows));
} }

View File

@ -8,7 +8,7 @@
class FluTableSortProxyModel : public QSortFilterProxyModel { class FluTableSortProxyModel : public QSortFilterProxyModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO_P(QAbstractTableModel*, model) Q_PROPERTY_AUTO_P(QVariant, model)
QML_NAMED_ELEMENT(FluTableSortProxyModel) QML_NAMED_ELEMENT(FluTableSortProxyModel)
public: public:
explicit FluTableSortProxyModel(QSortFilterProxyModel *parent = nullptr); explicit FluTableSortProxyModel(QSortFilterProxyModel *parent = nullptr);
@ -23,6 +23,8 @@ public:
[[maybe_unused]] Q_INVOKABLE void setRow(int rowIndex, const QVariant &val); [[maybe_unused]] Q_INVOKABLE void setRow(int rowIndex, const QVariant &val);
[[maybe_unused]] Q_INVOKABLE void insertRow(int rowIndex, const QVariant &val);
[[maybe_unused]] Q_INVOKABLE void removeRow(int rowIndex, int rows); [[maybe_unused]] Q_INVOKABLE void removeRow(int rowIndex, int rows);
[[maybe_unused]] Q_INVOKABLE void setComparator(const QJSValue &comparator); [[maybe_unused]] Q_INVOKABLE void setComparator(const QJSValue &comparator);

View File

@ -95,5 +95,5 @@ SINGLETON(FluTools)
Q_INVOKABLE QString getWallpaperFilePath(); Q_INVOKABLE QString getWallpaperFilePath();
Q_INVOKABLE QColor imageMainColor(const QImage& image, double bright = 1); Q_INVOKABLE QColor imageMainColor(const QImage &image, double bright = 1);
}; };

View File

@ -1,25 +1,14 @@
#include "FluTreeModel.h" #include "FluTreeModel.h"
#include <QMetaEnum> #include <QMetaEnum>
#include <utility>
FluTreeNode::FluTreeNode(QObject *parent) : QObject{parent} { FluTreeNode::FluTreeNode(QObject *parent) : QObject{parent} {
} }
FluTreeModel::FluTreeModel(QObject *parent) : QAbstractItemModel{parent} { FluTreeModel::FluTreeModel(QObject *parent) : QAbstractTableModel{parent} {
_dataSourceSize = 0; _dataSourceSize = 0;
} }
QModelIndex FluTreeModel::parent(const QModelIndex &child) const {
return {};
}
QModelIndex FluTreeModel::index(int row, int column, const QModelIndex &parent) const {
if (!hasIndex(row, column, parent) || parent.isValid())
return {};
return createIndex(row, column, _rows.at(row));
}
int FluTreeModel::rowCount(const QModelIndex &parent) const { int FluTreeModel::rowCount(const QModelIndex &parent) const {
return _rows.count(); return _rows.count();
} }
@ -265,12 +254,12 @@ void FluTreeModel::allCollapse() {
endResetModel(); endResetModel();
} }
QVariant FluTreeModel::selectionModel(){ QVariant FluTreeModel::selectionModel() {
QList<FluTreeNode *> data; QList<FluTreeNode *> data;
foreach (auto item, _dataSource) { foreach (auto item, _dataSource) {
if (item->checked()) { if (item->checked()) {
data.append(item); data.append(item);
}
} }
}
return QVariant::fromValue(data); return QVariant::fromValue(data);
} }

View File

@ -50,7 +50,7 @@ public:
} }
return true; return true;
}; };
Q_INVOKABLE bool hideLineFooter() { Q_INVOKABLE bool hideLineFooter() {
if (_parent) { if (_parent) {
auto childIndex = _parent->_children.indexOf(this); auto childIndex = _parent->_children.indexOf(this);
@ -86,12 +86,11 @@ public:
FluTreeNode *_parent = nullptr; FluTreeNode *_parent = nullptr;
}; };
class FluTreeModel : public QAbstractItemModel { class FluTreeModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(int, dataSourceSize) Q_PROPERTY_AUTO(int, dataSourceSize)
Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource) Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource)
QML_NAMED_ELEMENT(FluTreeModel) QML_NAMED_ELEMENT(FluTreeModel)
QML_ADDED_IN_MINOR_VERSION(1)
public: public:
enum TreeModelRoles { enum TreeModelRoles {
RowModel = 0x0101, RowModel = 0x0101,
@ -108,10 +107,6 @@ public:
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QModelIndex parent(const QModelIndex &child) const override;
[[nodiscard]] QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
Q_INVOKABLE void removeRows(int row, int count); Q_INVOKABLE void removeRows(int row, int count);
Q_INVOKABLE void insertRows(int row, const QList<FluTreeNode *> &data); Q_INVOKABLE void insertRows(int row, const QList<FluTreeNode *> &data);

View File

@ -15,6 +15,7 @@
#include "FluQrCodeItem.h" #include "FluQrCodeItem.h"
#include "FluTableSortProxyModel.h" #include "FluTableSortProxyModel.h"
#include "FluFrameless.h" #include "FluFrameless.h"
#include "FluTableModel.h"
void FluentUI::registerTypes(QQmlEngine *engine) { void FluentUI::registerTypes(QQmlEngine *engine) {
initializeEngine(engine, _uri); initializeEngine(engine, _uri);
@ -32,6 +33,7 @@ void FluentUI::registerTypes(const char *uri) const {
qmlRegisterType<FluWatermark>(uri, major, minor, "FluWatermark"); qmlRegisterType<FluWatermark>(uri, major, minor, "FluWatermark");
qmlRegisterType<FluAccentColor>(uri, major, minor, "FluAccentColor"); qmlRegisterType<FluAccentColor>(uri, major, minor, "FluAccentColor");
qmlRegisterType<FluTreeModel>(uri, major, minor, "FluTreeModel"); qmlRegisterType<FluTreeModel>(uri, major, minor, "FluTreeModel");
qmlRegisterType<FluTableModel>(uri, major, minor, "FluTableModel");
qmlRegisterType<FluRectangle>(uri, major, minor, "FluRectangle"); qmlRegisterType<FluRectangle>(uri, major, minor, "FluRectangle");
qmlRegisterType<FluFrameless>(uri, major, minor, "FluFrameless"); qmlRegisterType<FluFrameless>(uri, major, minor, "FluFrameless");
qmlRegisterType<FluTableSortProxyModel>(uri, major, minor, "FluTableSortProxyModel"); qmlRegisterType<FluTableSortProxyModel>(uri, major, minor, "FluTableSortProxyModel");
@ -146,6 +148,12 @@ void FluentUI::registerTypes(const char *uri) const {
qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri, major, minor, "FluTimelineType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri, major, minor, "FluTimelineType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluSheetType::staticMetaObject, uri, major, minor, "FluSheetType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluSheetType::staticMetaObject, uri, major, minor, "FluSheetType", "Access to enums & flags only");
// qmlRegisterSingletonInstance(uri, major, minor, "FluApp", FluApp::getInstance());
// qmlRegisterSingletonInstance(uri, major, minor, "FluColors", FluColors::getInstance());
// qmlRegisterSingletonInstance(uri, major, minor, "FluTheme", FluTheme::getInstance());
// qmlRegisterSingletonInstance(uri, major, minor, "FluTools", FluTools::getInstance());
// qmlRegisterSingletonInstance(uri, major, minor, "FluTextStyle", FluTextStyle::getInstance());
qmlRegisterModule(uri, major, minor); qmlRegisterModule(uri, major, minor);
#endif #endif
} }

View File

@ -7,6 +7,7 @@ FluTextBox{
property var items:[] property var items:[]
property string emptyText: qsTr("No results found") property string emptyText: qsTr("No results found")
property int autoSuggestBoxReplacement: FluentIcons.Search property int autoSuggestBoxReplacement: FluentIcons.Search
property string textRole: "title"
property var filter: function(item){ property var filter: function(item){
if(item.title.indexOf(control.text)!==-1){ if(item.title.indexOf(control.text)!==-1){
return true return true
@ -25,7 +26,7 @@ FluTextBox{
function handleClick(modelData){ function handleClick(modelData){
control_popup.visible = false control_popup.visible = false
control.itemClicked(modelData) control.itemClicked(modelData)
control.updateText(modelData.title) control.updateText(modelData[textRole])
} }
function loadData(){ function loadData(){
var result = [] var result = []
@ -48,7 +49,6 @@ FluTextBox{
} }
Popup{ Popup{
id:control_popup id:control_popup
y:control.height
focus: false focus: false
padding: 0 padding: 0
enter: Transition { enter: Transition {
@ -62,7 +62,7 @@ FluTextBox{
contentItem: FluClip{ contentItem: FluClip{
radius: [5,5,5,5] radius: [5,5,5,5]
ListView{ ListView{
id:list_view id: list_view
anchors.fill: parent anchors.fill: parent
clip: true clip: true
boundsBehavior: ListView.StopAtBounds boundsBehavior: ListView.StopAtBounds
@ -72,7 +72,7 @@ FluTextBox{
height: visible ? 38 : 0 height: visible ? 38 : 0
visible: list_view.count === 0 visible: list_view.count === 0
FluText{ FluText{
text:emptyText text: emptyText
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
@ -81,10 +81,10 @@ FluTextBox{
} }
} }
delegate:FluControl{ delegate:FluControl{
id:item_control id: item_control
height: 38 height: 38
width: control.width width: control.width
onClicked:{ onClicked: {
d.handleClick(modelData) d.handleClick(modelData)
} }
background: Rectangle{ background: Rectangle{
@ -103,7 +103,7 @@ FluTextBox{
} }
} }
contentItem: FluText{ contentItem: FluText{
text:modelData.title text: modelData[textRole]
leftPadding: 10 leftPadding: 10
rightPadding: 10 rightPadding: 10
verticalAlignment : Qt.AlignVCenter verticalAlignment : Qt.AlignVCenter
@ -128,7 +128,7 @@ FluTextBox{
if(d.flagVisible){ if(d.flagVisible){
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(d.window.height>pos.y+control.height+rect_background.implicitHeight){ if(d.window.height>pos.y+control.height+rect_background.implicitHeight){
control_popup.y = control.height control_popup.y = Qt.binding(function(){return control.height})
} else if(pos.y>rect_background.implicitHeight){ } else if(pos.y>rect_background.implicitHeight){
control_popup.y = -rect_background.implicitHeight control_popup.y = -rect_background.implicitHeight
} else { } else {

View File

@ -11,6 +11,7 @@ T.ComboBox {
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1) property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
property alias textBox: text_field
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding) implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
@ -39,6 +40,7 @@ T.ComboBox {
opacity: enabled ? 1 : 0.3 opacity: enabled ? 1 : 0.3
} }
contentItem: T.TextField { contentItem: T.TextField {
id: text_field
property bool disabled: !control.editable property bool disabled: !control.editable
leftPadding: !control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1 leftPadding: !control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1
rightPadding: control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1 rightPadding: control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1

View File

@ -18,22 +18,23 @@ FluObject {
if(screenLayout){ if(screenLayout){
var last = screenLayout.getLastloader(); var last = screenLayout.getLastloader();
if(last.type === type && last.text === text && moremsg === last.moremsg){ if(last.type === type && last.text === text && moremsg === last.moremsg){
last.restart(); last.duration = duration
return; if (duration > 0) last.restart();
return last;
} }
} }
initScreenLayout(); initScreenLayout();
contentComponent.createObject(screenLayout,{ return contentComponent.createObject(screenLayout,{
type:type, type:type,
text:text, text:text,
duration:duration, duration:duration,
moremsg:moremsg, moremsg:moremsg,
}); });
} }
function createCustom(itemcomponent,duration){ function createCustom(itemcomponent,duration){
initScreenLayout(); initScreenLayout();
if(itemcomponent){ if(itemcomponent){
contentComponent.createObject(screenLayout,{itemcomponent:itemcomponent,duration:duration}); return contentComponent.createObject(screenLayout,{itemcomponent:itemcomponent,duration:duration});
} }
} }
function initScreenLayout(){ function initScreenLayout(){
@ -85,7 +86,9 @@ FluObject {
} }
Timer { Timer {
id:delayTimer id:delayTimer
interval: duration; running: duration > 0; repeat: duration > 0 interval: duration;
running: duration > 0;
repeat: duration > 0
onTriggered: content.close(); onTriggered: content.close();
} }
FluLoader{ FluLoader{
@ -235,18 +238,26 @@ FluObject {
} }
} }
function showSuccess(text,duration=1000,moremsg){ function showSuccess(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_success,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_success,text,duration,moremsg ? moremsg : "");
} }
function showInfo(text,duration=1000,moremsg){ function showInfo(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_info,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_info,text,duration,moremsg ? moremsg : "");
} }
function showWarning(text,duration=1000,moremsg){ function showWarning(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_warning,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_warning,text,duration,moremsg ? moremsg : "");
} }
function showError(text,duration=1000,moremsg){ function showError(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_error,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_error,text,duration,moremsg ? moremsg : "");
} }
function showCustom(itemcomponent,duration=1000){ function showCustom(itemcomponent,duration=1000){
mcontrol.createCustom(itemcomponent,duration); return mcontrol.createCustom(itemcomponent,duration);
}
function clearAllInfo(){
if(mcontrol.screenLayout != null) {
mcontrol.screenLayout.destroy()
mcontrol.screenLayout = null
}
return true
} }
} }

View File

@ -48,9 +48,6 @@ T.MenuBarItem {
radius: 3 radius: 3
color: { color: {
if(control.highlighted){ if(control.highlighted){
return FluTheme.itemCheckColor
}
if(control.hovered){
return FluTheme.itemHoverColor return FluTheme.itemHoverColor
} }
return FluTheme.itemNormalColor return FluTheme.itemNormalColor

View File

@ -99,9 +99,9 @@ T.MenuItem {
anchors.fill: parent anchors.fill: parent
anchors.margins: 3 anchors.margins: 3
radius: 4 radius: 4
color:{ color: {
if(control.highlighted){ if(control.highlighted){
return FluTheme.itemCheckColor return FluTheme.itemHoverColor
} }
return FluTheme.itemNormalColor return FluTheme.itemNormalColor
} }

View File

@ -1,100 +1,109 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import FluentUI 1.0 import FluentUI 1.0
Item {
signal requestPage(int page,int count) Item {
property string previousText: qsTr("<Previous") signal requestPage(int page, int count)
property string nextText: qsTr("Next>")
property int pageCurrent: 0 property string previousText: qsTr("<Previous")
property int itemCount: 0 property string nextText: qsTr("Next>")
property int pageButtonCount: 5 property int pageCurrent: 0
property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0 property int itemCount: 0
property int __itemPerPage: 10 property int pageButtonCount: 5
property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1 property int pageCount: itemCount > 0 ? Math.ceil(itemCount / __itemPerPage) : 0
id: control property int __itemPerPage: 10
implicitHeight: 40 property int __pageButtonHalf: Math.floor(pageButtonCount / 2) + 1
implicitWidth: content.width property Component header: null
Row{ property Component footer: null
id: content id: control
height: control.height implicitHeight: 40
spacing: 10 implicitWidth: content.width
padding: 10 Row {
FluToggleButton{ id: content
visible: control.pageCount>1 height: control.height
disabled: control.pageCurrent<=1 spacing: 10
text:control.previousText padding: 10
clickListener:function() { Loader {
control.calcNewPage(control.pageCurrent-1); sourceComponent: header
} }
} FluToggleButton {
Row{ visible: control.pageCount > 1
spacing: 5 disabled: control.pageCurrent <= 1
FluToggleButton{ text: control.previousText
property int pageNumber:1 clickListener: function () {
visible: control.pageCount>0 control.calcNewPage(control.pageCurrent - 1);
checked: pageNumber === control.pageCurrent }
text:String(pageNumber) }
clickListener:function() { Row {
control.calcNewPage(pageNumber); spacing: 5
} FluToggleButton {
} property int pageNumber: 1
FluText{ visible: control.pageCount > 0
visible: (control.pageCount>control.pageButtonCount&& checked: pageNumber === control.pageCurrent
control.pageCurrent>control.__pageButtonHalf) text: String(pageNumber)
text: "..." clickListener: function () {
} control.calcNewPage(pageNumber);
Repeater{ }
id: button_repeator }
model: (control.pageCount<2)?0:(control.pageCount>=control.pageButtonCount)?(control.pageButtonCount-2):(control.pageCount-2) FluText {
delegate:FluToggleButton{ visible: (control.pageCount > control.pageButtonCount &&
property int pageNumber: { control.pageCurrent > control.__pageButtonHalf)
return (control.pageCurrent<=control.__pageButtonHalf) text: "..."
?(2+index) }
:(control.pageCount-control.pageCurrent<=control.pageButtonCount-control.__pageButtonHalf) Repeater {
?(control.pageCount-button_repeator.count+index) id: button_repeator
:(control.pageCurrent+2+index-control.__pageButtonHalf) model: (control.pageCount < 2) ? 0 : (control.pageCount >= control.pageButtonCount) ? (control.pageButtonCount - 2) : (control.pageCount - 2)
} delegate: FluToggleButton {
text:String(pageNumber) property int pageNumber: {
checked: pageNumber === control.pageCurrent return (control.pageCurrent <= control.__pageButtonHalf)
clickListener:function(){ ? (2 + index)
control.calcNewPage(pageNumber); : (control.pageCount - control.pageCurrent <= control.pageButtonCount - control.__pageButtonHalf)
} ? (control.pageCount - button_repeator.count + index)
} : (control.pageCurrent + 2 + index - control.__pageButtonHalf)
} }
FluText{ text: String(pageNumber)
visible: (control.pageCount>control.pageButtonCount&& checked: pageNumber === control.pageCurrent
control.pageCount-control.pageCurrent>control.pageButtonCount-control.__pageButtonHalf) clickListener: function () {
text: "..." control.calcNewPage(pageNumber);
} }
FluToggleButton{ }
property int pageNumber:control.pageCount }
visible: control.pageCount>1 FluText {
checked: pageNumber === control.pageCurrent visible: (control.pageCount > control.pageButtonCount &&
text:String(pageNumber) control.pageCount - control.pageCurrent > control.pageButtonCount - control.__pageButtonHalf)
clickListener:function(){ text: "..."
control.calcNewPage(pageNumber); }
} FluToggleButton {
} property int pageNumber: control.pageCount
} visible: control.pageCount > 1
FluToggleButton{ checked: pageNumber === control.pageCurrent
visible: control.pageCount>1 text: String(pageNumber)
disabled: control.pageCurrent>=control.pageCount clickListener: function () {
text:control.nextText control.calcNewPage(pageNumber);
clickListener:function() { }
control.calcNewPage(control.pageCurrent+1); }
} }
} FluToggleButton {
} visible: control.pageCount > 1
function calcNewPage(page) disabled: control.pageCurrent >= control.pageCount
{ text: control.nextText
if(!page) clickListener: function () {
return control.calcNewPage(control.pageCurrent + 1);
let page_num=Number(page) }
if(page_num<1||page_num>control.pageCount||page_num===control.pageCurrent) }
return Loader {
control.pageCurrent=page_num sourceComponent: footer
control.requestPage(page_num,control.__itemPerPage) }
} }
} function calcNewPage(page) {
if (!page)
return
let page_num = Number(page)
if (page_num < 1 || page_num > control.pageCount || page_num === control.pageCurrent)
return
control.pageCurrent = page_num
control.requestPage(page_num, control.__itemPerPage)
}
}

View File

@ -3,30 +3,87 @@ import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import FluentUI 1.0 import FluentUI 1.0
ColumnLayout { Item{
default property alias buttons: control.data
property int currentIndex : -1
id:control id:control
onCurrentIndexChanged: { default property list<QtObject> buttons
for(var i = 0;i<buttons.length;i++){ property int currentIndex : -1
buttons[i].checked = false property int spacing: 8
} property int orientation: Qt.Vertical
var button = buttons[currentIndex] property bool disabled: false
if(button){ property bool manuallyDisabled: false
button.checked = true QtObject{
} id: d
} function updateChecked(){
Component.onCompleted: { if(buttons.length === 0){
for(var i = 0;i<buttons.length;i++){ return
buttons[i].clickListener = function(){ }
for(var i = 0;i<buttons.length;i++){ for(var i = 0;i<buttons.length;i++){
var button = buttons[i] buttons[i].checked = false
if(this === button){ }
currentIndex = i if(currentIndex>=0 && currentIndex<buttons.length){
} buttons[currentIndex].checked = true
}
} }
} }
currentIndex = 0 function refreshButtonStatus() {
for(var i = 0;i<buttons.length;i++){
if(!manuallyDisabled) buttons[i].enabled = !disabled
}
}
}
implicitWidth: childrenRect.width
implicitHeight: childrenRect.height
onCurrentIndexChanged: {
d.updateChecked()
}
onDisabledChanged: {
d.refreshButtonStatus()
}
onManuallyDisabledChanged: {
d.refreshButtonStatus()
}
Component{
id:com_vertical
ColumnLayout {
data: control.buttons
spacing: control.spacing
Component.onCompleted: {
for(var i = 0;i<control.buttons.length;i++){
control.buttons[i].clickListener = function(){
for(var i = 0;i<control.buttons.length;i++){
var button = control.buttons[i]
if(this === button){
control.currentIndex = i
}
}
}
}
d.updateChecked()
d.refreshButtonStatus()
}
}
}
Component{
id:com_horizontal
RowLayout {
data: control.buttons
spacing: control.spacing
Component.onCompleted: {
for(var i = 0;i<control.buttons.length;i++){
control.buttons[i].clickListener = function(){
for(var i = 0;i<control.buttons.length;i++){
var button = control.buttons[i]
if(this === button){
control.currentIndex = i
}
}
}
}
d.updateChecked()
d.refreshButtonStatus()
}
}
}
FluLoader{
sourceComponent: control.orientation === Qt.Vertical ? com_vertical : com_horizontal
} }
} }

View File

@ -171,7 +171,7 @@ T.ScrollBar {
,Transition { ,Transition {
to: "show" to: "show"
SequentialAnimation { SequentialAnimation {
PauseAnimation { duration: 450 } PauseAnimation { duration: 150 }
NumberAnimation { NumberAnimation {
target: rect_bar target: rect_bar
properties: vertical ? "width" : "height" properties: vertical ? "width" : "height"

View File

@ -4,7 +4,7 @@ import FluentUI 1.0
Item { Item {
//高性能阴影比DropShadow阴影性能高出数倍 //高性能阴影比DropShadow阴影性能高出数倍
property color color: FluTheme.dark ? "#AAAAAA" : "#999999" property color color: FluTheme.dark ? "#000000" : "#999999"
property int elevation: 5 property int elevation: 5
property int radius: 4 property int radius: 4
id:control id:control

View File

@ -9,14 +9,41 @@ Rectangle {
readonly property alias rows: table_view.rows readonly property alias rows: table_view.rows
readonly property alias columns: table_view.columns readonly property alias columns: table_view.columns
readonly property alias current: d.current readonly property alias current: d.current
readonly property alias sourceModel: table_model property var sourceModel:FluTableModel {
property var columnSource columnSource: control.columnSource
}
property var columnSource: []
property var dataSource property var dataSource
property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1) 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 horizonalHeaderVisible: true
property bool verticalHeaderVisible: true property bool verticalHeaderVisible: true
property color selectedBorderColor: FluTheme.primaryColor property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3) property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
property alias view: table_view
property var columnWidthProvider: function(column) {
var columnModel = control.columnSource[column]
var width = columnModel.width
if(width){
return width
}
var minimumWidth = columnModel.minimumWidth
if(minimumWidth){
return minimumWidth
}
return d.defaultItemWidth
}
property var rowHeightProvider: function(row) {
var rowModel = control.getRow(row)
var height = rowModel.height
if(height){
return height
}
var minimumHeight = rowModel._minimumHeight
if(minimumHeight){
return minimumHeight
}
return d.defaultItemHeight
}
id:control id:control
color: { color: {
if(Window.active){ if(Window.active){
@ -27,67 +54,69 @@ Rectangle {
onColumnSourceChanged: { onColumnSourceChanged: {
if(columnSource.length!==0){ if(columnSource.length!==0){
var columns= [] var columns= []
var columnsData = []
var headerRow = {} var headerRow = {}
columnSource.forEach(function(item){ var offsetX = 0
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model); for(var i=0;i<=columnSource.length-1;i++){
var item = columnSource[i]
if(!item.width){
item.width = d.defaultItemWidth
}
item.x = offsetX
offsetX = offsetX + item.width
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',sourceModel);
column.display = item.dataIndex column.display = item.dataIndex
columnsData.push(item)
columns.push(column) columns.push(column)
headerRow[item.dataIndex] = item.title headerRow[item.dataIndex] = item
}) }
d.columns_data = columnsData
table_model.columns = columns
header_column_model.columns = columns header_column_model.columns = columns
header_column_model.rows = [headerRow] header_column_model.rows = [headerRow]
} }
} }
Component.onDestruction: {
table_view.contentY = 0
}
QtObject{ QtObject{
id:d id:d
property var current property var current
property int rowHoverIndex: -1 property int rowHoverIndex: -1
property int defaultItemWidth: 100 property int defaultItemWidth: 100
property int defaultItemHeight: 42 property int defaultItemHeight: 42
property var columns_data: []
property var editDelegate property var editDelegate
property var editPosition property var editPosition
signal tableItemLayout(int column)
function getEditDelegate(column){ function getEditDelegate(column){
var obj =d.columns_data[column].editDelegate var obj =control.columnSource[column].editDelegate
if(obj){ if(obj){
return obj return obj
} }
if(d.columns_data[column].editMultiline === true){ if(control.columnSource[column].editMultiline === true){
return com_edit_multiline return com_edit_multiline
} }
return com_edit return com_edit
} }
} }
onDataSourceChanged: { onDataSourceChanged: {
table_model.clear() sourceModel.clear()
table_model.rows = dataSource sourceModel.rows = dataSource
}
TableModel {
id:table_model
TableModelColumn {}
} }
TableModel{ TableModel{
id:header_column_model id: header_column_model
TableModelColumn {} TableModelColumn { display : "title"}
} }
TableModel{ TableModel{
id:header_row_model id: header_row_model
TableModelColumn { display: "rowIndex" } TableModelColumn { display: "rowIndex" }
} }
FluTableSortProxyModel{ FluTableSortProxyModel{
id:table_sort_model id: table_sort_model
model: table_model model: control.sourceModel
} }
Component{ Component{
id:com_edit id:com_edit
FluTextBox{ FluTextBox{
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
Component.onCompleted: { Component.onCompleted: {
forceActiveFocus() forceActiveFocus()
selectAll() selectAll()
@ -113,7 +142,7 @@ Rectangle {
TextArea.flickable: FluMultilineTextBox { TextArea.flickable: FluMultilineTextBox {
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
isCtrlEnterForNewline: true isCtrlEnterForNewline: true
Component.onCompleted: { Component.onCompleted: {
@ -196,14 +225,42 @@ Rectangle {
id:com_table_delegate id:com_table_delegate
MouseArea{ MouseArea{
id:item_table_mouse id:item_table_mouse
property var rowObject : control.getRow(row) property var _model: model
property var itemModel: model property bool isMainTable: TableView.view == table_view
property var currentTableView: TableView.view
property bool isHide: {
if(isMainTable && columnModel.frozen){
return true
}
if(!isMainTable){
if(currentTableView.dataIndex !== columnModel.dataIndex)
return true
}
return false
}
property bool isRowSelected: {
if(!rowModel)
return false
if(d.current){
return rowModel._key === d.current._key
}
return false
}
property bool editVisible: { property bool editVisible: {
if(rowObject && d.editPosition && d.editPosition._key === rowObject._key && d.editPosition.column === column){ if(!rowModel)
return false
if(d.editPosition && d.editPosition._key === rowModel._key && d.editPosition.column === column){
return true return true
} }
return false return false
} }
implicitWidth: isHide ? Number.MIN_VALUE : TableView.view.width
visible: !isHide
TableView.onPooled: {
if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){
control.closeEditor()
}
}
hoverEnabled: true hoverEnabled: true
onEntered: { onEntered: {
d.rowHoverIndex = row d.rowHoverIndex = row
@ -212,25 +269,37 @@ Rectangle {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
onHeightChanged: { onHeightChanged: {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
onXChanged: { onXChanged: {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
onYChanged: { onYChanged: {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
function updateEditPosition(){ function updateEditPosition(){
var obj = {} var obj = {}
obj._key = rowObject._key obj._key = rowModel._key
obj.column = column obj.column = column
obj.row = row obj.row = row
obj.x = item_table_mouse.x obj.x = item_table_mouse.x
@ -239,26 +308,22 @@ Rectangle {
obj.height = item_table_mouse.height - 2 obj.height = item_table_mouse.height - 2
d.editPosition = obj d.editPosition = obj
} }
function updateTableItem(){
var columnModel = control.columnSource[column]
columnModel.x = item_table_mouse.x
columnModel.y = item_table_mouse.y
d.tableItemLayout(column)
}
Rectangle{ Rectangle{
id:item_table
anchors.fill: parent anchors.fill: parent
property point position: Qt.point(column,row)
property bool isRowSelected: {
if(rowObject === null)
return false
if(d.current){
return rowObject._key === d.current._key
}
return false
}
color:{ color:{
if(item_table.isRowSelected){ if(item_table_mouse.isRowSelected){
return control.selectedColor return control.selectedColor
} }
if(d.rowHoverIndex === row || item_table.isRowSelected){ if(d.rowHoverIndex === row || item_table_mouse.isRowSelected){
return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
} }
return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.015) : Qt.rgba(0,0,0,0.015)) return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03))
} }
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
@ -271,25 +336,28 @@ Rectangle {
onReleased: { onReleased: {
} }
onDoubleClicked:{ onDoubleClicked:{
if(typeof(display) == "object"){ if(item_table_loader.isObject){
return return
} }
loader_edit.display = item_table_loader.display
d.editDelegate = d.getEditDelegate(column) d.editDelegate = d.getEditDelegate(column)
updateEditPosition() item_table_mouse.updateEditPosition()
loader_edit.display = display
} }
onClicked: onClicked:
(event)=>{ (event)=>{
d.current = rowObject d.current = rowModel
control.closeEditor() control.closeEditor()
event.accepted = true event.accepted = true
} }
} }
FluLoader{ FluLoader{
property var model: itemModel id: item_table_loader
property var display: itemModel.display property var model: item_table_mouse._model
property int row: item_table.position.y property var display: rowModel[columnModel.dataIndex]
property int column: item_table.position.x property var rowModel : model.rowModel
property var columnModel : model.columnModel
property int row : model.row
property int column: model.column
property bool isObject: typeof(display) == "object" property bool isObject: typeof(display) == "object"
property var options: { property var options: {
if(isObject){ if(isObject){
@ -299,15 +367,53 @@ Rectangle {
} }
anchors.fill: parent anchors.fill: parent
sourceComponent: { sourceComponent: {
if(isObject){ if(item_table_mouse.visible){
return display.comId if(isObject){
return display.comId
}
return com_text
} }
return com_text return undefined
} }
} }
FluLoader{
id: loader_edit
property var tableView: control
property var display
property int column: {
if(d.editPosition){
return d.editPosition.column
}
return 0
}
property int row: {
if(d.editPosition){
return d.editPosition.row
}
return 0
}
anchors{
fill: parent
margins: 1
}
signal editTextChaged(string text)
sourceComponent: {
if(item_table_mouse.visible && d.editPosition && d.editPosition.column === model.column && d.editPosition.row === model.row){
return d.editDelegate
}
return undefined
}
onEditTextChaged:
(text)=>{
var obj = control.getRow(row)
obj[control.columnSource[column].dataIndex] = text
control.setRow(row,obj)
}
z:999
}
Item{ Item{
anchors.fill: parent anchors.fill: parent
visible: item_table.isRowSelected visible: item_table_mouse.isRowSelected
Rectangle{ Rectangle{
width: 1 width: 1
height: parent.height height: parent.height
@ -338,6 +444,11 @@ Rectangle {
} }
} }
} }
onWidthChanged:{
table_view.forceLayout()
}
MouseArea{ MouseArea{
id:layout_mouse_table id:layout_mouse_table
hoverEnabled: true hoverEnabled: true
@ -359,30 +470,8 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
ScrollBar.horizontal:scroll_bar_h ScrollBar.horizontal:scroll_bar_h
ScrollBar.vertical:scroll_bar_v ScrollBar.vertical:scroll_bar_v
columnWidthProvider: function(column) { columnWidthProvider: control.columnWidthProvider
var columnObject = d.columns_data[column] rowHeightProvider: control.rowHeightProvider
var width = columnObject.width
if(width){
return width
}
var minimumWidth = columnObject.minimumWidth
if(minimumWidth){
return minimumWidth
}
return d.defaultItemWidth
}
rowHeightProvider: function(row) {
var rowObject = control.getRow(row)
var height = rowObject.height
if(height){
return height
}
var minimumHeight = rowObject._minimumHeight
if(minimumHeight){
return minimumHeight
}
return d.defaultItemHeight
}
model: table_sort_model model: table_sort_model
clip: true clip: true
onRowsChanged: { onRowsChanged: {
@ -390,70 +479,51 @@ Rectangle {
table_view.flick(0,1) table_view.flick(0,1)
} }
delegate: com_table_delegate delegate: com_table_delegate
FluLoader{
id:loader_edit
property var tableView: control
property var display
property int column: {
if(d.editPosition){
return d.editPosition.column
}
return 0
}
property int row: {
if(d.editPosition){
return d.editPosition.row
}
return 0
}
signal editTextChaged(string text)
sourceComponent: d.editPosition ? d.editDelegate : undefined
onEditTextChaged:
(text)=>{
var obj = control.getRow(row)
obj[d.columns_data[column].dataIndex] = text
control.setRow(row,obj)
}
width: {
if(d.editPosition){
return d.editPosition.width
}
return 0
}
height: {
if(d.editPosition){
return d.editPosition.height
}
return 0
}
x:{
if(d.editPosition){
return d.editPosition.x
}
return 0
}
y:{
if(d.editPosition){
return d.editPosition.y
}
return 0
}
z:999
}
} }
} }
Component{ Component{
id:com_column_header_delegate id: com_column_header_delegate
Rectangle{ Rectangle{
id:column_item_control id: column_item_control
property var currentTableView : TableView.view
readonly property real cellPadding: 8 readonly property real cellPadding: 8
property bool canceled: false property bool canceled: false
property int columnIndex: column property var _model: model
readonly property var columnObject : d.columns_data[column] readonly property var columnModel : control.columnSource[_index]
implicitWidth: { readonly property int _index : {
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2) const isDataIndex = (element) => {
return element.dataIndex === display.dataIndex
}
return control.columnSource.findIndex(isDataIndex)
}
readonly property bool isHeaderHorizontal: TableView.view == header_horizontal
readonly property bool isHide: {
if(isHeaderHorizontal && columnModel.frozen){
return true
}
if(!isHeaderHorizontal){
if(currentTableView.dataIndex !== columnModel.dataIndex)
return true
}
return false
}
visible: !isHide
implicitWidth: {
if(isHide){
return Number.MIN_VALUE
}
if(column_item_control.isHeaderHorizontal){
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2)
}
return Math.max(TableView.view.width,Number.MIN_VALUE)
}
implicitHeight: {
if(column_item_control.isHeaderHorizontal){
return Math.max(36, (item_column_loader.item&&item_column_loader.item.implicitHeight) + (cellPadding * 2))
}
return Math.max(TableView.view.height,Number.MIN_VALUE)
} }
implicitHeight: Math.max(36, (item_column_loader.item&&item_column_loader.item.implicitHeight) + (cellPadding * 2))
color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1) color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1)
Rectangle{ Rectangle{
border.color: control.borderColor border.color: control.borderColor
@ -474,7 +544,7 @@ Rectangle {
width: 1 width: 1
height: parent.height height: parent.height
anchors.left: parent.left anchors.left: parent.left
visible: column !== 0 visible: column_item_control._index !== 0
color:"#00000000" color:"#00000000"
} }
Rectangle{ Rectangle{
@ -483,7 +553,7 @@ Rectangle {
height: parent.height height: parent.height
anchors.right: parent.right anchors.right: parent.right
color:"#00000000" color:"#00000000"
visible: column === table_view.columns - 1 visible: column_item_control._index === table_view.columns - 1
} }
MouseArea{ MouseArea{
id:column_item_control_mouse id:column_item_control_mouse
@ -505,22 +575,23 @@ Rectangle {
} }
FluLoader{ FluLoader{
id:item_column_loader id:item_column_loader
property var itemModel: model property var model: column_item_control._model
property var modelData: model.display property var display: model.display.title
property var tableView: table_view property var tableView: table_view
property var tableModel: table_model property var sourceModel: control.sourceModel
property bool isObject: typeof(display) == "object"
property var options:{ property var options:{
if(typeof(modelData) == "object"){ if(isObject){
return modelData.options return display.options
} }
return {} return {}
} }
property int column: column_item_control.columnIndex property int column: column_item_control._index
width: parent.width width: parent.width
height: parent.height height: parent.height
sourceComponent: { sourceComponent: {
if(typeof(modelData) == "object"){ if(isObject){
return modelData.comId return display.comId
} }
return com_column_text return com_column_text
} }
@ -532,7 +603,7 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
hoverEnabled: true hoverEnabled: true
visible: !(columnObject.width === columnObject.minimumWidth && columnObject.width === columnObject.maximumWidth && columnObject.width) visible: !columnModel.frozen && !(columnModel.width === columnModel.minimumWidth && columnModel.width === columnModel.maximumWidth && columnModel.width)
cursorShape: Qt.SplitHCursor cursorShape: Qt.SplitHCursor
preventStealing: true preventStealing: true
onPressed : onPressed :
@ -552,9 +623,9 @@ Rectangle {
return return
} }
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
var minimumWidth = columnObject.minimumWidth var minimumWidth = columnModel.minimumWidth
var maximumWidth = columnObject.maximumWidth var maximumWidth = columnModel.maximumWidth
var w = columnObject.width var w = columnModel.width
if(!w){ if(!w){
w = d.defaultItemWidth w = d.defaultItemWidth
} }
@ -564,7 +635,7 @@ Rectangle {
if(!maximumWidth){ if(!maximumWidth){
maximumWidth = 65535 maximumWidth = 65535
} }
columnObject.width = Math.min(Math.max(minimumWidth, w + delta.x),maximumWidth) columnModel.width = Math.min(Math.max(minimumWidth, w + delta.x),maximumWidth)
table_view.forceLayout() table_view.forceLayout()
header_horizontal.forceLayout() header_horizontal.forceLayout()
} }
@ -577,7 +648,7 @@ Rectangle {
id:item_control id:item_control
readonly property real cellPadding: 8 readonly property real cellPadding: 8
property bool canceled: false property bool canceled: false
property var rowObject: control.getRow(row) property var rowModel: control.getRow(row)
implicitWidth: Math.max(30, row_text.implicitWidth + (cellPadding * 2)) implicitWidth: Math.max(30, row_text.implicitWidth + (cellPadding * 2))
implicitHeight: row_text.implicitHeight + (cellPadding * 2) implicitHeight: row_text.implicitHeight + (cellPadding * 2)
color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1) color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1)
@ -643,9 +714,9 @@ Rectangle {
cursorShape: Qt.SplitVCursor cursorShape: Qt.SplitVCursor
preventStealing: true preventStealing: true
visible: { visible: {
if(rowObject === null) if(rowModel === null)
return false return false
return !(rowObject.height === rowObject._minimumHeight && rowObject.height === rowObject._maximumHeight && rowObject.height) return !(rowModel.height === rowModel._minimumHeight && rowModel.height === rowModel._maximumHeight && rowModel.height)
} }
onPressed : onPressed :
(mouse)=>{ (mouse)=>{
@ -663,11 +734,11 @@ Rectangle {
if(!pressed){ if(!pressed){
return return
} }
var rowObject = control.getRow(row) var rowModel = control.getRow(row)
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
var minimumHeight = rowObject._minimumHeight var minimumHeight = rowModel._minimumHeight
var maximumHeight = rowObject._maximumHeight var maximumHeight = rowModel._maximumHeight
var h = rowObject.height var h = rowModel.height
if(!h){ if(!h){
h = d.defaultItemHeight h = d.defaultItemHeight
} }
@ -677,8 +748,8 @@ Rectangle {
if(!maximumHeight){ if(!maximumHeight){
maximumHeight = 65535 maximumHeight = 65535
} }
rowObject.height = Math.min(Math.max(minimumHeight, h + delta.y),maximumHeight) rowModel.height = Math.min(Math.max(minimumHeight, h + delta.y),maximumHeight)
control.setRow(row,rowObject) control.setRow(row,rowModel)
table_view.forceLayout() table_view.forceLayout()
} }
} }
@ -688,7 +759,7 @@ Rectangle {
id:com_column_text id:com_column_text
FluText { FluText {
id: column_text id: column_text
text: modelData text: String(display)
anchors.fill: parent anchors.fill: parent
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -791,6 +862,138 @@ Rectangle {
} }
} }
} }
Item{
anchors{
left: header_vertical.right
top: parent.top
bottom: parent.bottom
right: parent.right
}
Component{
id: com_table_frozen
Rectangle{
id: item_layout_frozen
anchors.fill: parent
color: {
if(Window.active){
return FluTheme.dark ? Qt.rgba(48/255,48/255,48/255,1) :Qt.rgba(1,1,1,1)
}
return FluTheme.dark ? Qt.rgba(56/255,56/255,56/255,1) :Qt.rgba(243/255,243/255,243/255,1)
}
visible: table_view.rows !== 0
Rectangle{
z:99
anchors.fill: parent
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,0.6) : Qt.rgba(191/255,191/255,191/255,0.3)
FluShadow{
radius: 0
anchors.fill: parent
}
color: "#00000000"
}
TableView{
property string dataIndex: columnModel.dataIndex
id: item_table_frozen
interactive: false
clip: true
anchors{
left: parent.left
right: parent.right
}
contentWidth: width
height: table_view.height
y: header_horizontal.height
boundsBehavior: TableView.StopAtBounds
model: table_view.model
delegate: table_view.delegate
syncDirection: Qt.Vertical
syncView: table_view
}
TableView {
property string dataIndex: columnModel.dataIndex
id:item_table_frozen_header
model: header_column_model
boundsBehavior: Flickable.StopAtBounds
interactive: false
clip: true
contentWidth: width
anchors{
left: parent.left
right: parent.right
top: parent.top
bottom: item_table_frozen.top
}
delegate: com_column_header_delegate
Component.onCompleted: {
item_table_frozen_header.forceLayout()
}
}
Connections{
target: table_view
function onWidthChanged() {
item_table_frozen_header.forceLayout()
}
}
}
}
Repeater{
Component.onCompleted: {
model = control.columnSource
}
delegate: FluLoader{
id: item_layout_frozen
readonly property int _index : model.index
readonly property var columnModel : control.columnSource[_index]
readonly property bool isHide:{
if(columnModel.frozen){
return false
}
return true
}
Connections{
target: d
function onTableItemLayout(column){
if(item_layout_frozen._index === column){
updateLayout()
}
}
}
Connections{
target: table_view
function onContentXChanged(){
updateLayout()
}
}
function updateLayout(){
width = table_view.columnWidthProvider(_index)
x = Qt.binding(function(){
var minX = 0
var maxX = table_view.width-width
for(var i=0;i<_index;i++){
var item = control.columnSource[i]
if(item.frozen){
minX = minX + table_view.columnWidthProvider(i)
}
}
for(i=_index+1;i<control.columnSource.length;i++){
item = control.columnSource[i]
if(item.frozen){
maxX = maxX - table_view.columnWidthProvider(i)
}
}
return Math.min(Math.max(columnModel.x - table_view.contentX,minX),maxX)}
)
}
Component.onCompleted: {
updateLayout()
}
height: control.height
visible: !item_layout_frozen.isHide
sourceComponent: item_layout_frozen.isHide ? undefined : com_table_frozen
}
}
}
FluScrollBar { FluScrollBar {
id: scroll_bar_h id: scroll_bar_h
anchors{ anchors{
@ -837,7 +1040,7 @@ Rectangle {
function sort(callback=undefined){ function sort(callback=undefined){
if(callback){ if(callback){
table_sort_model.setComparator(function(left,right){ table_sort_model.setComparator(function(left,right){
return callback(table_model.getRow(left),table_model.getRow(right)) return callback(sourceModel.getRow(left),sourceModel.getRow(right))
}) })
}else{ }else{
table_sort_model.setComparator(undefined) table_sort_model.setComparator(undefined)
@ -846,7 +1049,7 @@ Rectangle {
function filter(callback=undefined){ function filter(callback=undefined){
if(callback){ if(callback){
table_sort_model.setFilter(function(index){ table_sort_model.setFilter(function(index){
return callback(table_model.getRow(index)) return callback(sourceModel.getRow(index))
}) })
}else{ }else{
table_sort_model.setFilter(undefined) table_sort_model.setFilter(undefined)
@ -868,7 +1071,26 @@ Rectangle {
table_view.model.removeRow(rowIndex,rows) table_view.model.removeRow(rowIndex,rows)
} }
} }
function insertRow(rowIndex,obj){
if(rowIndex>=0 && rowIndex<table_view.rows){
sourceModel.insertRow(rowIndex,obj)
}
}
function currentIndex(){
var index = -1
if(!d.current){
return index
}
for (var i = 0; i <= sourceModel.rowCount-1; i++) {
var sourceItem = sourceModel.getRow(i);
if(sourceItem._key === d.current._key){
index = i
break
}
}
return index
}
function appendRow(obj){ function appendRow(obj){
table_model.appendRow(obj) sourceModel.appendRow(obj)
} }
} }

View File

@ -17,6 +17,7 @@ Rectangle {
property color selectedBorderColor: FluTheme.primaryColor property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3) property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
readonly property alias current: d.current readonly property alias current: d.current
property alias view: table_view
id:control id:control
color: { color: {
if(Window.active){ if(Window.active){
@ -45,6 +46,9 @@ Rectangle {
id:tree_model id:tree_model
columnSource: control.columnSource columnSource: control.columnSource
} }
Component.onDestruction: {
table_view.contentY = 0
}
onDepthPaddingChanged: { onDepthPaddingChanged: {
table_view.forceLayout() table_view.forceLayout()
} }

View File

@ -60,8 +60,9 @@ Window {
signal lazyLoad() signal lazyLoad()
property var _windowRegister property var _windowRegister
property string _route property string _route
id:window property bool _hideShadow: false
color:"transparent" id: window
color: FluTools.isSoftware() ? window.backgroundColor : "transparent"
Component.onCompleted: { Component.onCompleted: {
FluRouter.addWindow(window) FluRouter.addWindow(window)
useSystemAppBar = FluApp.useSystemAppBar useSystemAppBar = FluApp.useSystemAppBar
@ -121,12 +122,21 @@ Window {
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
asynchronous: true asynchronous: true
Component.onCompleted: { Component.onCompleted: {
var geometry = FluTools.desktopAvailableGeometry(window) img_back.updateLayout()
width = geometry.width
height = geometry.height
sourceSize = Qt.size(width,height)
source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath) source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
} }
Connections{
target: window
function onScreenChanged(){
img_back.updateLayout()
}
}
function updateLayout(){
var geometry = FluTools.desktopAvailableGeometry(window)
img_back.width = geometry.width
img_back.height = geometry.height
img_back.sourceSize = Qt.size(img_back.width,img_back.height)
}
Connections{ Connections{
target: FluTheme target: FluTheme
function onDesktopImagePathChanged(){ function onDesktopImagePathChanged(){
@ -142,7 +152,7 @@ Window {
} }
Timer{ Timer{
id:timer_update_image id:timer_update_image
interval: 500 interval: 150
onTriggered: { onTriggered: {
img_back.source = "" img_back.source = ""
img_back.source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath) img_back.source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
@ -156,7 +166,7 @@ Window {
blurRadius: 64 blurRadius: 64
visible: window.active && FluTheme.blurBehindWindowEnabled visible: window.active && FluTheme.blurBehindWindowEnabled
tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1) tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1)
targetRect: Qt.rect(window.x,window.y,window.width,window.height) targetRect: Qt.rect(window.x-window.screen.virtualX,window.y-window.screen.virtualY,window.width,window.height)
} }
} }
} }
@ -279,13 +289,7 @@ Window {
id:loader_border id:loader_border
anchors.fill: parent anchors.fill: parent
sourceComponent: { sourceComponent: {
if(window.useSystemAppBar){ if(window.useSystemAppBar || FluTools.isWin() || window.visibility === Window.Maximized || window.visibility === Window.FullScreen){
return undefined
}
if(FluTools.isWindows10OrGreater()){
return undefined
}
if(window.visibility === Window.Maximized || window.visibility === Window.FullScreen){
return undefined return undefined
} }
return com_border return com_border
@ -295,19 +299,21 @@ Window {
loader_loading.sourceComponent = undefined loader_loading.sourceComponent = undefined
} }
function showSuccess(text,duration,moremsg){ function showSuccess(text,duration,moremsg){
info_bar.showSuccess(text,duration,moremsg) return info_bar.showSuccess(text,duration,moremsg)
} }
function showInfo(text,duration,moremsg){ function showInfo(text,duration,moremsg){
info_bar.showInfo(text,duration,moremsg) return info_bar.showInfo(text,duration,moremsg)
} }
function showWarning(text,duration,moremsg){ function showWarning(text,duration,moremsg){
info_bar.showWarning(text,duration,moremsg) return info_bar.showWarning(text,duration,moremsg)
} }
function showError(text,duration,moremsg){ function showError(text,duration,moremsg){
info_bar.showError(text,duration,moremsg) return info_bar.showError(text,duration,moremsg)
}
function clearAllInfo(){
return info_bar.clearAllInfo()
} }
function moveWindowToDesktopCenter(){ function moveWindowToDesktopCenter(){
screen = Qt.application.screens[FluTools.cursorScreenIndex()]
var availableGeometry = FluTools.desktopAvailableGeometry(window) var availableGeometry = FluTools.desktopAvailableGeometry(window)
window.setGeometry((availableGeometry.width-window.width)/2+Screen.virtualX,(availableGeometry.height-window.height)/2+Screen.virtualY,window.width,window.height) window.setGeometry((availableGeometry.width-window.width)/2+Screen.virtualX,(availableGeometry.height-window.height)/2+Screen.virtualY,window.width,window.height)
} }

View File

@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only. // It is used for QML tooling purposes only.
// //
// This file was auto-generated by: // This file was auto-generated by:
// 'qmlplugindump -nonrelocatable FluentUI 1.0 D:\QtProjects\build-FluentUI-Desktop_Qt_5_15_2_MSVC2019_64bit-Release\src' // 'qmlplugindump -nonrelocatable FluentUI 1.0 D:/QtProjects/build-FluentUI-Desktop_Qt_5_15_2_MSVC2019_64bit-Release/src'
Module { Module {
dependencies: ["QtQuick 2.0"] dependencies: ["QtQuick 2.0"]
@ -25,6 +25,8 @@ Module {
name: "FluApp" name: "FluApp"
prototype: "QObject" prototype: "QObject"
exports: ["FluentUI/FluApp 1.0"] exports: ["FluentUI/FluApp 1.0"]
isCreatable: false
isSingleton: true
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Property { name: "useSystemAppBar"; type: "bool" } Property { name: "useSystemAppBar"; type: "bool" }
Property { name: "windowIcon"; type: "string" } Property { name: "windowIcon"; type: "string" }
@ -39,11 +41,11 @@ Module {
Parameter { name: "target"; type: "QObject"; isPointer: true } Parameter { name: "target"; type: "QObject"; isPointer: true }
} }
Method { Method {
name: "iconDatas" name: "iconData"
type: "QJsonArray" type: "QJsonArray"
Parameter { name: "keyword"; type: "string" } Parameter { name: "keyword"; type: "string" }
} }
Method { name: "iconDatas"; type: "QJsonArray" } Method { name: "iconData"; type: "QJsonArray" }
} }
Component { Component {
name: "FluCalendarViewType" name: "FluCalendarViewType"
@ -78,6 +80,8 @@ Module {
name: "FluColors" name: "FluColors"
prototype: "QObject" prototype: "QObject"
exports: ["FluentUI/FluColors 1.0"] exports: ["FluentUI/FluColors 1.0"]
isCreatable: false
isSingleton: true
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Property { name: "Transparent"; type: "QColor" } Property { name: "Transparent"; type: "QColor" }
Property { name: "Black"; type: "QColor" } Property { name: "Black"; type: "QColor" }
@ -265,11 +269,15 @@ Module {
} }
} }
Component { Component {
name: "FluTableSortProxyModel" name: "FluTableModel"
prototype: "QSortFilterProxyModel" prototype: "QAbstractTableModel"
exports: ["FluentUI/FluTableSortProxyModel 1.0"] exports: ["FluentUI/FluTableModel 1.0"]
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Property { name: "model"; type: "QAbstractTableModel"; isPointer: true } Property { name: "dataSourceSize"; type: "int" }
Property { name: "columnSource"; type: "QList<QVariantMap>" }
Property { name: "rows"; type: "QList<QVariantMap>" }
Property { name: "rowCount"; type: "int"; isReadonly: true }
Method { name: "clear" }
Method { Method {
name: "getRow" name: "getRow"
type: "QVariant" type: "QVariant"
@ -278,6 +286,46 @@ Module {
Method { Method {
name: "setRow" name: "setRow"
Parameter { name: "rowIndex"; type: "int" } Parameter { name: "rowIndex"; type: "int" }
Parameter { name: "row"; type: "QVariant" }
}
Method {
name: "insertRow"
Parameter { name: "rowIndex"; type: "int" }
Parameter { name: "row"; type: "QVariant" }
}
Method {
name: "removeRow"
Parameter { name: "rowIndex"; type: "int" }
Parameter { name: "rows"; type: "int" }
}
Method {
name: "removeRow"
Parameter { name: "rowIndex"; type: "int" }
}
Method {
name: "appendRow"
Parameter { name: "row"; type: "QVariant" }
}
}
Component {
name: "FluTableSortProxyModel"
prototype: "QSortFilterProxyModel"
exports: ["FluentUI/FluTableSortProxyModel 1.0"]
exportMetaObjectRevisions: [0]
Property { name: "model"; type: "QVariant" }
Method {
name: "getRow"
type: "QVariant"
Parameter { name: "rowIndex"; type: "int" }
}
Method {
name: "setRow"
Parameter { name: "rowIndex"; type: "int" }
Parameter { name: "val"; type: "QVariant" }
}
Method {
name: "insertRow"
Parameter { name: "rowIndex"; type: "int" }
Parameter { name: "val"; type: "QVariant" } Parameter { name: "val"; type: "QVariant" }
} }
Method { Method {
@ -298,6 +346,8 @@ Module {
name: "FluTextStyle" name: "FluTextStyle"
prototype: "QObject" prototype: "QObject"
exports: ["FluentUI/FluTextStyle 1.0"] exports: ["FluentUI/FluTextStyle 1.0"]
isCreatable: false
isSingleton: true
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Property { name: "family"; type: "string" } Property { name: "family"; type: "string" }
Property { name: "Caption"; type: "QFont" } Property { name: "Caption"; type: "QFont" }
@ -312,6 +362,8 @@ Module {
name: "FluTheme" name: "FluTheme"
prototype: "QObject" prototype: "QObject"
exports: ["FluentUI/FluTheme 1.0"] exports: ["FluentUI/FluTheme 1.0"]
isCreatable: false
isSingleton: true
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Property { name: "dark"; type: "bool"; isReadonly: true } Property { name: "dark"; type: "bool"; isReadonly: true }
Property { name: "accentColor"; type: "FluAccentColor"; isPointer: true } Property { name: "accentColor"; type: "FluAccentColor"; isPointer: true }
@ -380,6 +432,8 @@ Module {
name: "FluTools" name: "FluTools"
prototype: "QObject" prototype: "QObject"
exports: ["FluentUI/FluTools 1.0"] exports: ["FluentUI/FluTools 1.0"]
isCreatable: false
isSingleton: true
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Method { name: "qtMajor"; type: "int" } Method { name: "qtMajor"; type: "int" }
Method { name: "qtMinor"; type: "int" } Method { name: "qtMinor"; type: "int" }
@ -499,7 +553,7 @@ Module {
} }
Component { Component {
name: "FluTreeModel" name: "FluTreeModel"
prototype: "QAbstractItemModel" prototype: "QAbstractTableModel"
exports: ["FluentUI/FluTreeModel 1.0"] exports: ["FluentUI/FluTreeModel 1.0"]
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
Property { name: "dataSourceSize"; type: "int" } Property { name: "dataSourceSize"; type: "int" }
@ -2316,6 +2370,7 @@ Module {
Parameter { name: "selection"; type: "QItemSelection" } Parameter { name: "selection"; type: "QItemSelection" }
} }
} }
Component { name: "QAbstractTableModel"; prototype: "QAbstractItemModel" }
Component { Component {
name: "QSortFilterProxyModel" name: "QSortFilterProxyModel"
prototype: "QAbstractProxyModel" prototype: "QAbstractProxyModel"
@ -2472,7 +2527,7 @@ Module {
} }
Property { Property {
name: "layoutMacosButtons" name: "layoutMacosButtons"
type: "FluLoader_QMLTYPE_14" type: "FluLoader_QMLTYPE_13"
isReadonly: true isReadonly: true
isPointer: true isPointer: true
} }
@ -2493,6 +2548,7 @@ Module {
Property { name: "items"; type: "QVariant" } Property { name: "items"; type: "QVariant" }
Property { name: "emptyText"; type: "string" } Property { name: "emptyText"; type: "string" }
Property { name: "autoSuggestBoxReplacement"; type: "int" } Property { name: "autoSuggestBoxReplacement"; type: "int" }
Property { name: "textRole"; type: "string" }
Property { name: "filter"; type: "QVariant" } Property { name: "filter"; type: "QVariant" }
Signal { Signal {
name: "itemClicked" name: "itemClicked"
@ -2695,6 +2751,7 @@ Module {
Property { name: "normalColor"; type: "QColor" } Property { name: "normalColor"; type: "QColor" }
Property { name: "hoverColor"; type: "QColor" } Property { name: "hoverColor"; type: "QColor" }
Property { name: "disableColor"; type: "QColor" } Property { name: "disableColor"; type: "QColor" }
Property { name: "textBox"; type: "QQuickTextField"; isReadonly: true; isPointer: true }
Signal { Signal {
name: "commit" name: "commit"
Parameter { name: "text"; type: "string" } Parameter { name: "text"; type: "string" }
@ -3162,15 +3219,15 @@ Module {
defaultProperty: "data" defaultProperty: "data"
Property { name: "logo"; type: "QUrl" } Property { name: "logo"; type: "QUrl" }
Property { name: "title"; type: "string" } Property { name: "title"; type: "string" }
Property { name: "items"; type: "FluObject_QMLTYPE_172"; isPointer: true } Property { name: "items"; type: "FluObject_QMLTYPE_173"; isPointer: true }
Property { name: "footerItems"; type: "FluObject_QMLTYPE_172"; isPointer: true } Property { name: "footerItems"; type: "FluObject_QMLTYPE_173"; isPointer: true }
Property { name: "displayMode"; type: "int" } Property { name: "displayMode"; type: "int" }
Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true } Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true }
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true } Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
Property { name: "topPadding"; type: "int" } Property { name: "topPadding"; type: "int" }
Property { name: "pageMode"; type: "int" } Property { name: "pageMode"; type: "int" }
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_33"; isPointer: true } Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_49"; isPointer: true }
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_33"; isPointer: true } Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_49"; isPointer: true }
Property { name: "navCompactWidth"; type: "int" } Property { name: "navCompactWidth"; type: "int" }
Property { name: "navTopMargin"; type: "int" } Property { name: "navTopMargin"; type: "int" }
Property { name: "cellHeight"; type: "int" } Property { name: "cellHeight"; type: "int" }
@ -3246,6 +3303,8 @@ Module {
Property { name: "pageCount"; type: "int" } Property { name: "pageCount"; type: "int" }
Property { name: "__itemPerPage"; type: "int" } Property { name: "__itemPerPage"; type: "int" }
Property { name: "__pageButtonHalf"; type: "int" } Property { name: "__pageButtonHalf"; type: "int" }
Property { name: "header"; type: "QQmlComponent"; isPointer: true }
Property { name: "footer"; type: "QQmlComponent"; isPointer: true }
Signal { Signal {
name: "requestPage" name: "requestPage"
Parameter { name: "page"; type: "int" } Parameter { name: "page"; type: "int" }
@ -3470,14 +3529,16 @@ Module {
Property { name: "textColor"; type: "QColor" } Property { name: "textColor"; type: "QColor" }
} }
Component { Component {
prototype: "QQuickColumnLayout" prototype: "QQuickItem"
name: "FluentUI/FluRadioButtons 1.0" name: "FluentUI/FluRadioButtons 1.0"
exports: ["FluentUI/FluRadioButtons 1.0"] exports: ["FluentUI/FluRadioButtons 1.0"]
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
isComposite: true isComposite: true
defaultProperty: "buttons" defaultProperty: "buttons"
Property { name: "currentIndex"; type: "int" }
Property { name: "buttons"; type: "QObject"; isList: true; isReadonly: true } Property { name: "buttons"; type: "QObject"; isList: true; isReadonly: true }
Property { name: "currentIndex"; type: "int" }
Property { name: "spacing"; type: "int" }
Property { name: "orientation"; type: "int" }
} }
Component { Component {
prototype: "QQuickRangeSlider" prototype: "QQuickRangeSlider"
@ -3757,6 +3818,7 @@ Module {
exportMetaObjectRevisions: [0] exportMetaObjectRevisions: [0]
isComposite: true isComposite: true
defaultProperty: "data" defaultProperty: "data"
Property { name: "sourceModel"; type: "QVariant" }
Property { name: "columnSource"; type: "QVariant" } Property { name: "columnSource"; type: "QVariant" }
Property { name: "dataSource"; type: "QVariant" } Property { name: "dataSource"; type: "QVariant" }
Property { name: "borderColor"; type: "QColor" } Property { name: "borderColor"; type: "QColor" }
@ -3767,7 +3829,6 @@ Module {
Property { name: "rows"; type: "int"; isReadonly: true } Property { name: "rows"; type: "int"; isReadonly: true }
Property { name: "columns"; type: "int"; isReadonly: true } Property { name: "columns"; type: "int"; isReadonly: true }
Property { name: "current"; type: "QVariant"; isReadonly: true } Property { name: "current"; type: "QVariant"; isReadonly: true }
Property { name: "sourceModel"; type: "QQmlTableModel"; isReadonly: true; isPointer: true }
Method { name: "closeEditor"; type: "QVariant" } Method { name: "closeEditor"; type: "QVariant" }
Method { name: "resetPosition"; type: "QVariant" } Method { name: "resetPosition"; type: "QVariant" }
Method { Method {
@ -3803,6 +3864,13 @@ Module {
Parameter { name: "rowIndex"; type: "QVariant" } Parameter { name: "rowIndex"; type: "QVariant" }
Parameter { name: "rows"; type: "QVariant" } Parameter { name: "rows"; type: "QVariant" }
} }
Method {
name: "insertRow"
type: "QVariant"
Parameter { name: "rowIndex"; type: "QVariant" }
Parameter { name: "obj"; type: "QVariant" }
}
Method { name: "currentIndex"; type: "QVariant" }
Method { Method {
name: "appendRow" name: "appendRow"
type: "QVariant" type: "QVariant"
@ -4068,6 +4136,7 @@ Module {
Property { name: "closeListener"; type: "QVariant" } Property { name: "closeListener"; type: "QVariant" }
Property { name: "_windowRegister"; type: "QVariant" } Property { name: "_windowRegister"; type: "QVariant" }
Property { name: "_route"; type: "string" } Property { name: "_route"; type: "string" }
Property { name: "_hideShadow"; type: "bool" }
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
Signal { Signal {
name: "initArgument" name: "initArgument"
@ -4116,6 +4185,8 @@ Module {
Parameter { name: "data"; type: "QVariant" } Parameter { name: "data"; type: "QVariant" }
} }
Method { name: "showMaximized"; type: "QVariant" } Method { name: "showMaximized"; type: "QVariant" }
Method { name: "showMinimized"; type: "QVariant" }
Method { name: "showNormal"; type: "QVariant" }
Method { Method {
name: "showLoading" name: "showLoading"
type: "QVariant" type: "QVariant"
@ -4136,7 +4207,12 @@ Module {
isComposite: true isComposite: true
defaultProperty: "contentData" defaultProperty: "contentData"
Property { name: "contentDelegate"; type: "QQmlComponent"; isPointer: true } Property { name: "contentDelegate"; type: "QQmlComponent"; isPointer: true }
Method { name: "showDialog"; type: "QVariant" } Method {
name: "showDialog"
type: "QVariant"
Parameter { name: "offsetX"; type: "QVariant" }
Parameter { name: "offsetY"; type: "QVariant" }
}
Property { name: "windowIcon"; type: "string" } Property { name: "windowIcon"; type: "string" }
Property { name: "launchMode"; type: "int" } Property { name: "launchMode"; type: "int" }
Property { name: "argument"; type: "QVariant" } Property { name: "argument"; type: "QVariant" }
@ -4162,6 +4238,7 @@ Module {
Property { name: "closeListener"; type: "QVariant" } Property { name: "closeListener"; type: "QVariant" }
Property { name: "_windowRegister"; type: "QVariant" } Property { name: "_windowRegister"; type: "QVariant" }
Property { name: "_route"; type: "string" } Property { name: "_route"; type: "string" }
Property { name: "_hideShadow"; type: "bool" }
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
Signal { Signal {
name: "initArgument" name: "initArgument"
@ -4210,6 +4287,8 @@ Module {
Parameter { name: "data"; type: "QVariant" } Parameter { name: "data"; type: "QVariant" }
} }
Method { name: "showMaximized"; type: "QVariant" } Method { name: "showMaximized"; type: "QVariant" }
Method { name: "showMinimized"; type: "QVariant" }
Method { name: "showNormal"; type: "QVariant" }
Method { Method {
name: "showLoading" name: "showLoading"
type: "QVariant" type: "QVariant"

View File

@ -6,6 +6,7 @@ FluTextBox{
property var items:[] property var items:[]
property string emptyText: qsTr("No results found") property string emptyText: qsTr("No results found")
property int autoSuggestBoxReplacement: FluentIcons.Search property int autoSuggestBoxReplacement: FluentIcons.Search
property string textRole: "title"
property var filter: function(item){ property var filter: function(item){
if(item.title.indexOf(control.text)!==-1){ if(item.title.indexOf(control.text)!==-1){
return true return true
@ -24,7 +25,7 @@ FluTextBox{
function handleClick(modelData){ function handleClick(modelData){
control_popup.visible = false control_popup.visible = false
control.itemClicked(modelData) control.itemClicked(modelData)
control.updateText(modelData.title) control.updateText(modelData[textRole])
} }
function loadData(){ function loadData(){
var result = [] var result = []
@ -47,7 +48,6 @@ FluTextBox{
} }
Popup{ Popup{
id:control_popup id:control_popup
y:control.height
focus: false focus: false
padding: 0 padding: 0
enter: Transition { enter: Transition {
@ -61,7 +61,7 @@ FluTextBox{
contentItem: FluClip{ contentItem: FluClip{
radius: [5,5,5,5] radius: [5,5,5,5]
ListView{ ListView{
id:list_view id: list_view
anchors.fill: parent anchors.fill: parent
clip: true clip: true
boundsBehavior: ListView.StopAtBounds boundsBehavior: ListView.StopAtBounds
@ -71,7 +71,7 @@ FluTextBox{
height: visible ? 38 : 0 height: visible ? 38 : 0
visible: list_view.count === 0 visible: list_view.count === 0
FluText{ FluText{
text:emptyText text: emptyText
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
@ -80,10 +80,10 @@ FluTextBox{
} }
} }
delegate:FluControl{ delegate:FluControl{
id:item_control id: item_control
height: 38 height: 38
width: control.width width: control.width
onClicked:{ onClicked: {
d.handleClick(modelData) d.handleClick(modelData)
} }
background: Rectangle{ background: Rectangle{
@ -102,7 +102,7 @@ FluTextBox{
} }
} }
contentItem: FluText{ contentItem: FluText{
text:modelData.title text: modelData[textRole]
leftPadding: 10 leftPadding: 10
rightPadding: 10 rightPadding: 10
verticalAlignment : Qt.AlignVCenter verticalAlignment : Qt.AlignVCenter
@ -127,7 +127,7 @@ FluTextBox{
if(d.flagVisible){ if(d.flagVisible){
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(d.window.height>pos.y+control.height+rect_background.implicitHeight){ if(d.window.height>pos.y+control.height+rect_background.implicitHeight){
control_popup.y = control.height control_popup.y = Qt.binding(function(){return control.height})
} else if(pos.y>rect_background.implicitHeight){ } else if(pos.y>rect_background.implicitHeight){
control_popup.y = -rect_background.implicitHeight control_popup.y = -rect_background.implicitHeight
} else { } else {

View File

@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import FluentUI import FluentUI

View File

@ -11,6 +11,7 @@ T.ComboBox {
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1) property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
property alias textBox: text_field
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding) implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
@ -39,6 +40,7 @@ T.ComboBox {
opacity: enabled ? 1 : 0.3 opacity: enabled ? 1 : 0.3
} }
contentItem: T.TextField { contentItem: T.TextField {
id: text_field
property bool disabled: !control.editable property bool disabled: !control.editable
leftPadding: !control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1 leftPadding: !control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1
rightPadding: control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1 rightPadding: control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1

View File

@ -1,6 +1,6 @@
import QtQuick import QtQuick 2.15
import QtQuick.Controls import QtQuick.Controls 2.15
import FluentUI import FluentUI 1.0
FluObject { FluObject {
property var root; property var root;
@ -18,22 +18,23 @@ FluObject {
if(screenLayout){ if(screenLayout){
var last = screenLayout.getLastloader(); var last = screenLayout.getLastloader();
if(last.type === type && last.text === text && moremsg === last.moremsg){ if(last.type === type && last.text === text && moremsg === last.moremsg){
last.restart(); last.duration = duration
return; if (duration > 0) last.restart();
return last;
} }
} }
initScreenLayout(); initScreenLayout();
contentComponent.createObject(screenLayout,{ return contentComponent.createObject(screenLayout,{
type:type, type:type,
text:text, text:text,
duration:duration, duration:duration,
moremsg:moremsg, moremsg:moremsg,
}); });
} }
function createCustom(itemcomponent,duration){ function createCustom(itemcomponent,duration){
initScreenLayout(); initScreenLayout();
if(itemcomponent){ if(itemcomponent){
contentComponent.createObject(screenLayout,{itemcomponent:itemcomponent,duration:duration}); return contentComponent.createObject(screenLayout,{itemcomponent:itemcomponent,duration:duration});
} }
} }
function initScreenLayout(){ function initScreenLayout(){
@ -85,7 +86,9 @@ FluObject {
} }
Timer { Timer {
id:delayTimer id:delayTimer
interval: duration; running: duration > 0; repeat: duration > 0 interval: duration;
running: duration > 0;
repeat: duration > 0
onTriggered: content.close(); onTriggered: content.close();
} }
FluLoader{ FluLoader{
@ -235,18 +238,26 @@ FluObject {
} }
} }
function showSuccess(text,duration=1000,moremsg){ function showSuccess(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_success,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_success,text,duration,moremsg ? moremsg : "");
} }
function showInfo(text,duration=1000,moremsg){ function showInfo(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_info,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_info,text,duration,moremsg ? moremsg : "");
} }
function showWarning(text,duration=1000,moremsg){ function showWarning(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_warning,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_warning,text,duration,moremsg ? moremsg : "");
} }
function showError(text,duration=1000,moremsg){ function showError(text,duration=1000,moremsg){
mcontrol.create(mcontrol.const_error,text,duration,moremsg ? moremsg : ""); return mcontrol.create(mcontrol.const_error,text,duration,moremsg ? moremsg : "");
} }
function showCustom(itemcomponent,duration=1000){ function showCustom(itemcomponent,duration=1000){
mcontrol.createCustom(itemcomponent,duration); return mcontrol.createCustom(itemcomponent,duration);
}
function clearAllInfo(){
if(mcontrol.screenLayout != null) {
mcontrol.screenLayout.destroy()
mcontrol.screenLayout = null
}
return true
} }
} }

View File

@ -49,9 +49,6 @@ T.MenuBarItem {
radius: 3 radius: 3
color: { color: {
if(control.highlighted){ if(control.highlighted){
return FluTheme.itemCheckColor
}
if(control.hovered){
return FluTheme.itemHoverColor return FluTheme.itemHoverColor
} }
return FluTheme.itemNormalColor return FluTheme.itemNormalColor

View File

@ -100,9 +100,9 @@ T.MenuItem {
anchors.fill: parent anchors.fill: parent
anchors.margins: 3 anchors.margins: 3
radius: 4 radius: 4
color:{ color: {
if(control.highlighted){ if(control.highlighted){
return FluTheme.itemCheckColor return FluTheme.itemHoverColor
} }
return FluTheme.itemNormalColor return FluTheme.itemNormalColor
} }

View File

@ -1,100 +1,108 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import FluentUI import FluentUI
Item { Item {
signal requestPage(int page,int count) signal requestPage(int page, int count)
property string previousText: qsTr("<Previous")
property string nextText: qsTr("Next>") property string previousText: qsTr("<Previous")
property int pageCurrent: 0 property string nextText: qsTr("Next>")
property int itemCount: 0 property int pageCurrent: 0
property int pageButtonCount: 5 property int itemCount: 0
property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0 property int pageButtonCount: 5
property int __itemPerPage: 10 property int pageCount: itemCount > 0 ? Math.ceil(itemCount / __itemPerPage) : 0
property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1 property int __itemPerPage: 10
id: control property int __pageButtonHalf: Math.floor(pageButtonCount / 2) + 1
implicitHeight: 40 property Component header: null
implicitWidth: content.width property Component footer: null
Row{ id: control
id: content implicitHeight: 40
height: control.height implicitWidth: content.width
spacing: 10 Row {
padding: 10 id: content
FluToggleButton{ height: control.height
visible: control.pageCount>1 spacing: 10
disabled: control.pageCurrent<=1 padding: 10
text:control.previousText Loader {
clickListener:function() { sourceComponent: header
control.calcNewPage(control.pageCurrent-1); }
} FluToggleButton {
} visible: control.pageCount > 1
Row{ disabled: control.pageCurrent <= 1
spacing: 5 text: control.previousText
FluToggleButton{ clickListener: function () {
property int pageNumber:1 control.calcNewPage(control.pageCurrent - 1);
visible: control.pageCount>0 }
checked: pageNumber === control.pageCurrent }
text:String(pageNumber) Row {
clickListener:function() { spacing: 5
control.calcNewPage(pageNumber); FluToggleButton {
} property int pageNumber: 1
} visible: control.pageCount > 0
FluText{ checked: pageNumber === control.pageCurrent
visible: (control.pageCount>control.pageButtonCount&& text: String(pageNumber)
control.pageCurrent>control.__pageButtonHalf) clickListener: function () {
text: "..." control.calcNewPage(pageNumber);
} }
Repeater{ }
id: button_repeator FluText {
model: (control.pageCount<2)?0:(control.pageCount>=control.pageButtonCount)?(control.pageButtonCount-2):(control.pageCount-2) visible: (control.pageCount > control.pageButtonCount &&
delegate:FluToggleButton{ control.pageCurrent > control.__pageButtonHalf)
property int pageNumber: { text: "..."
return (control.pageCurrent<=control.__pageButtonHalf) }
?(2+index) Repeater {
:(control.pageCount-control.pageCurrent<=control.pageButtonCount-control.__pageButtonHalf) id: button_repeator
?(control.pageCount-button_repeator.count+index) model: (control.pageCount < 2) ? 0 : (control.pageCount >= control.pageButtonCount) ? (control.pageButtonCount - 2) : (control.pageCount - 2)
:(control.pageCurrent+2+index-control.__pageButtonHalf) delegate: FluToggleButton {
} property int pageNumber: {
text:String(pageNumber) return (control.pageCurrent <= control.__pageButtonHalf)
checked: pageNumber === control.pageCurrent ? (2 + index)
clickListener:function(){ : (control.pageCount - control.pageCurrent <= control.pageButtonCount - control.__pageButtonHalf)
control.calcNewPage(pageNumber); ? (control.pageCount - button_repeator.count + index)
} : (control.pageCurrent + 2 + index - control.__pageButtonHalf)
} }
} text: String(pageNumber)
FluText{ checked: pageNumber === control.pageCurrent
visible: (control.pageCount>control.pageButtonCount&& clickListener: function () {
control.pageCount-control.pageCurrent>control.pageButtonCount-control.__pageButtonHalf) control.calcNewPage(pageNumber);
text: "..." }
} }
FluToggleButton{ }
property int pageNumber:control.pageCount FluText {
visible: control.pageCount>1 visible: (control.pageCount > control.pageButtonCount &&
checked: pageNumber === control.pageCurrent control.pageCount - control.pageCurrent > control.pageButtonCount - control.__pageButtonHalf)
text:String(pageNumber) text: "..."
clickListener:function(){ }
control.calcNewPage(pageNumber); FluToggleButton {
} property int pageNumber: control.pageCount
} visible: control.pageCount > 1
} checked: pageNumber === control.pageCurrent
FluToggleButton{ text: String(pageNumber)
visible: control.pageCount>1 clickListener: function () {
disabled: control.pageCurrent>=control.pageCount control.calcNewPage(pageNumber);
text:control.nextText }
clickListener:function() { }
control.calcNewPage(control.pageCurrent+1); }
} FluToggleButton {
} visible: control.pageCount > 1
} disabled: control.pageCurrent >= control.pageCount
function calcNewPage(page) text: control.nextText
{ clickListener: function () {
if(!page) control.calcNewPage(control.pageCurrent + 1);
return }
let page_num=Number(page) }
if(page_num<1||page_num>control.pageCount||page_num===control.pageCurrent) Loader {
return sourceComponent: footer
control.pageCurrent=page_num }
control.requestPage(page_num,control.__itemPerPage) }
} function calcNewPage(page) {
} if (!page)
return
let page_num = Number(page)
if (page_num < 1 || page_num > control.pageCount || page_num === control.pageCurrent)
return
control.pageCurrent = page_num
control.requestPage(page_num, control.__itemPerPage)
}
}

View File

@ -4,30 +4,87 @@ import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import FluentUI import FluentUI
ColumnLayout { Item{
default property alias buttons: control.data
property int currentIndex : -1
id:control id:control
onCurrentIndexChanged: { default property list<QtObject> buttons
for(var i = 0;i<buttons.length;i++){ property int currentIndex : -1
buttons[i].checked = false property int spacing: 8
} property int orientation: Qt.Vertical
var button = buttons[currentIndex] property bool disabled: false
if(button){ property bool manuallyDisabled: false
button.checked = true QtObject{
} id: d
} function updateChecked(){
Component.onCompleted: { if(buttons.length === 0){
for(var i = 0;i<buttons.length;i++){ return
buttons[i].clickListener = function(){ }
for(var i = 0;i<buttons.length;i++){ for(var i = 0;i<buttons.length;i++){
var button = buttons[i] buttons[i].checked = false
if(this === button){ }
currentIndex = i if(currentIndex>=0 && currentIndex<buttons.length){
} buttons[currentIndex].checked = true
}
} }
} }
currentIndex = 0 function refreshButtonStatus() {
for(var i = 0;i<buttons.length;i++){
if(!manuallyDisabled) buttons[i].enabled = !disabled
}
}
}
implicitWidth: childrenRect.width
implicitHeight: childrenRect.height
onCurrentIndexChanged: {
d.updateChecked()
}
onDisabledChanged: {
d.refreshButtonStatus()
}
onManuallyDisabledChanged: {
d.refreshButtonStatus()
}
Component{
id:com_vertical
ColumnLayout {
data: control.buttons
spacing: control.spacing
Component.onCompleted: {
for(var i = 0;i<control.buttons.length;i++){
control.buttons[i].clickListener = function(){
for(var i = 0;i<control.buttons.length;i++){
var button = control.buttons[i]
if(this === button){
control.currentIndex = i
}
}
}
}
d.updateChecked()
d.refreshButtonStatus()
}
}
}
Component{
id:com_horizontal
RowLayout {
data: control.buttons
spacing: control.spacing
Component.onCompleted: {
for(var i = 0;i<control.buttons.length;i++){
control.buttons[i].clickListener = function(){
for(var i = 0;i<control.buttons.length;i++){
var button = control.buttons[i]
if(this === button){
control.currentIndex = i
}
}
}
}
d.updateChecked()
d.refreshButtonStatus()
}
}
}
FluLoader{
sourceComponent: control.orientation === Qt.Vertical ? com_vertical : com_horizontal
} }
} }

View File

@ -56,7 +56,9 @@ QtObject {
var launchMode = win.launchMode var launchMode = win.launchMode
if(launchMode === 1){ if(launchMode === 1){
win.argument = argument win.argument = argument
win.show() if(!win.visible){
win.visible = true
}
win.raise() win.raise()
win.requestActivate() win.requestActivate()
return return

View File

@ -173,7 +173,7 @@ T.ScrollBar {
,Transition { ,Transition {
to: "show" to: "show"
SequentialAnimation { SequentialAnimation {
PauseAnimation { duration: 450 } PauseAnimation { duration: 150 }
NumberAnimation { NumberAnimation {
target: rect_bar target: rect_bar
properties: vertical ? "width" : "height" properties: vertical ? "width" : "height"

View File

@ -4,7 +4,7 @@ import FluentUI
Item { Item {
//高性能阴影比DropShadow阴影性能高出数倍 //高性能阴影比DropShadow阴影性能高出数倍
property color color: FluTheme.dark ? "#AAAAAA" : "#999999" property color color: FluTheme.dark ? "#000000" : "#999999"
property int elevation: 5 property int elevation: 5
property int radius: 4 property int radius: 4
id:control id:control

View File

@ -9,14 +9,41 @@ Rectangle {
readonly property alias rows: table_view.rows readonly property alias rows: table_view.rows
readonly property alias columns: table_view.columns readonly property alias columns: table_view.columns
readonly property alias current: d.current readonly property alias current: d.current
readonly property alias sourceModel: table_model property var sourceModel:FluTableModel {
property var columnSource columnSource: control.columnSource
}
property var columnSource: []
property var dataSource property var dataSource
property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1) 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 horizonalHeaderVisible: true
property bool verticalHeaderVisible: true property bool verticalHeaderVisible: true
property color selectedBorderColor: FluTheme.primaryColor property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3) property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
property alias view: table_view
property var columnWidthProvider: function(column) {
var columnModel = control.columnSource[column]
var width = columnModel.width
if(width){
return width
}
var minimumWidth = columnModel.minimumWidth
if(minimumWidth){
return minimumWidth
}
return d.defaultItemWidth
}
property var rowHeightProvider: function(row) {
var rowModel = control.getRow(row)
var height = rowModel.height
if(height){
return height
}
var minimumHeight = rowModel._minimumHeight
if(minimumHeight){
return minimumHeight
}
return d.defaultItemHeight
}
id:control id:control
color: { color: {
if(Window.active){ if(Window.active){
@ -27,67 +54,69 @@ Rectangle {
onColumnSourceChanged: { onColumnSourceChanged: {
if(columnSource.length!==0){ if(columnSource.length!==0){
var columns= [] var columns= []
var columnsData = []
var headerRow = {} var headerRow = {}
columnSource.forEach(function(item){ var offsetX = 0
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model); for(var i=0;i<=columnSource.length-1;i++){
var item = columnSource[i]
if(!item.width){
item.width = d.defaultItemWidth
}
item.x = offsetX
offsetX = offsetX + item.width
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',sourceModel);
column.display = item.dataIndex column.display = item.dataIndex
columnsData.push(item)
columns.push(column) columns.push(column)
headerRow[item.dataIndex] = item.title headerRow[item.dataIndex] = item
}) }
d.columns_data = columnsData
table_model.columns = columns
header_column_model.columns = columns header_column_model.columns = columns
header_column_model.rows = [headerRow] header_column_model.rows = [headerRow]
} }
} }
Component.onDestruction: {
table_view.contentY = 0
}
QtObject{ QtObject{
id:d id:d
property var current property var current
property int rowHoverIndex: -1 property int rowHoverIndex: -1
property int defaultItemWidth: 100 property int defaultItemWidth: 100
property int defaultItemHeight: 42 property int defaultItemHeight: 42
property var columns_data: []
property var editDelegate property var editDelegate
property var editPosition property var editPosition
signal tableItemLayout(int column)
function getEditDelegate(column){ function getEditDelegate(column){
var obj =d.columns_data[column].editDelegate var obj =control.columnSource[column].editDelegate
if(obj){ if(obj){
return obj return obj
} }
if(d.columns_data[column].editMultiline === true){ if(control.columnSource[column].editMultiline === true){
return com_edit_multiline return com_edit_multiline
} }
return com_edit return com_edit
} }
} }
onDataSourceChanged: { onDataSourceChanged: {
table_model.clear() sourceModel.clear()
table_model.rows = dataSource sourceModel.rows = dataSource
}
TableModel {
id:table_model
TableModelColumn {}
} }
TableModel{ TableModel{
id:header_column_model id: header_column_model
TableModelColumn {} TableModelColumn { display : "title"}
} }
TableModel{ TableModel{
id:header_row_model id: header_row_model
TableModelColumn { display: "rowIndex" } TableModelColumn { display: "rowIndex" }
} }
FluTableSortProxyModel{ FluTableSortProxyModel{
id:table_sort_model id: table_sort_model
model: table_model model: control.sourceModel
} }
Component{ Component{
id:com_edit id:com_edit
FluTextBox{ FluTextBox{
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
Component.onCompleted: { Component.onCompleted: {
forceActiveFocus() forceActiveFocus()
selectAll() selectAll()
@ -113,7 +142,7 @@ Rectangle {
TextArea.flickable: FluMultilineTextBox { TextArea.flickable: FluMultilineTextBox {
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
isCtrlEnterForNewline: true isCtrlEnterForNewline: true
Component.onCompleted: { Component.onCompleted: {
@ -196,14 +225,42 @@ Rectangle {
id:com_table_delegate id:com_table_delegate
MouseArea{ MouseArea{
id:item_table_mouse id:item_table_mouse
property var rowObject : control.getRow(row) property var _model: model
property var itemModel: model property bool isMainTable: TableView.view == table_view
property var currentTableView: TableView.view
property bool isHide: {
if(isMainTable && columnModel.frozen){
return true
}
if(!isMainTable){
if(currentTableView.dataIndex !== columnModel.dataIndex)
return true
}
return false
}
property bool isRowSelected: {
if(!rowModel)
return false
if(d.current){
return rowModel._key === d.current._key
}
return false
}
property bool editVisible: { property bool editVisible: {
if(rowObject && d.editPosition && d.editPosition._key === rowObject._key && d.editPosition.column === column){ if(!rowModel)
return false
if(d.editPosition && d.editPosition._key === rowModel._key && d.editPosition.column === column){
return true return true
} }
return false return false
} }
implicitWidth: isHide ? Number.MIN_VALUE : TableView.view.width
visible: !isHide
TableView.onPooled: {
if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){
control.closeEditor()
}
}
hoverEnabled: true hoverEnabled: true
onEntered: { onEntered: {
d.rowHoverIndex = row d.rowHoverIndex = row
@ -212,25 +269,37 @@ Rectangle {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
onHeightChanged: { onHeightChanged: {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
onXChanged: { onXChanged: {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
onYChanged: { onYChanged: {
if(editVisible){ if(editVisible){
updateEditPosition() updateEditPosition()
} }
if(isMainTable){
updateTableItem()
}
} }
function updateEditPosition(){ function updateEditPosition(){
var obj = {} var obj = {}
obj._key = rowObject._key obj._key = rowModel._key
obj.column = column obj.column = column
obj.row = row obj.row = row
obj.x = item_table_mouse.x obj.x = item_table_mouse.x
@ -239,26 +308,22 @@ Rectangle {
obj.height = item_table_mouse.height - 2 obj.height = item_table_mouse.height - 2
d.editPosition = obj d.editPosition = obj
} }
function updateTableItem(){
var columnModel = control.columnSource[column]
columnModel.x = item_table_mouse.x
columnModel.y = item_table_mouse.y
d.tableItemLayout(column)
}
Rectangle{ Rectangle{
id:item_table
anchors.fill: parent anchors.fill: parent
property point position: Qt.point(column,row)
property bool isRowSelected: {
if(rowObject === null)
return false
if(d.current){
return rowObject._key === d.current._key
}
return false
}
color:{ color:{
if(item_table.isRowSelected){ if(item_table_mouse.isRowSelected){
return control.selectedColor return control.selectedColor
} }
if(d.rowHoverIndex === row || item_table.isRowSelected){ if(d.rowHoverIndex === row || item_table_mouse.isRowSelected){
return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
} }
return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.015) : Qt.rgba(0,0,0,0.015)) return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03))
} }
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
@ -271,25 +336,28 @@ Rectangle {
onReleased: { onReleased: {
} }
onDoubleClicked:{ onDoubleClicked:{
if(typeof(display) == "object"){ if(item_table_loader.isObject){
return return
} }
loader_edit.display = item_table_loader.display
d.editDelegate = d.getEditDelegate(column) d.editDelegate = d.getEditDelegate(column)
updateEditPosition() item_table_mouse.updateEditPosition()
loader_edit.display = display
} }
onClicked: onClicked:
(event)=>{ (event)=>{
d.current = rowObject d.current = rowModel
control.closeEditor() control.closeEditor()
event.accepted = true event.accepted = true
} }
} }
FluLoader{ FluLoader{
property var model: itemModel id: item_table_loader
property var display: itemModel.display property var model: item_table_mouse._model
property int row: item_table.position.y property var display: rowModel[columnModel.dataIndex]
property int column: item_table.position.x property var rowModel : model.rowModel
property var columnModel : model.columnModel
property int row : model.row
property int column: model.column
property bool isObject: typeof(display) == "object" property bool isObject: typeof(display) == "object"
property var options: { property var options: {
if(isObject){ if(isObject){
@ -299,15 +367,53 @@ Rectangle {
} }
anchors.fill: parent anchors.fill: parent
sourceComponent: { sourceComponent: {
if(isObject){ if(item_table_mouse.visible){
return display.comId if(isObject){
return display.comId
}
return com_text
} }
return com_text return undefined
} }
} }
FluLoader{
id: loader_edit
property var tableView: control
property var display
property int column: {
if(d.editPosition){
return d.editPosition.column
}
return 0
}
property int row: {
if(d.editPosition){
return d.editPosition.row
}
return 0
}
anchors{
fill: parent
margins: 1
}
signal editTextChaged(string text)
sourceComponent: {
if(item_table_mouse.visible && d.editPosition && d.editPosition.column === model.column && d.editPosition.row === model.row){
return d.editDelegate
}
return undefined
}
onEditTextChaged:
(text)=>{
var obj = control.getRow(row)
obj[control.columnSource[column].dataIndex] = text
control.setRow(row,obj)
}
z:999
}
Item{ Item{
anchors.fill: parent anchors.fill: parent
visible: item_table.isRowSelected visible: item_table_mouse.isRowSelected
Rectangle{ Rectangle{
width: 1 width: 1
height: parent.height height: parent.height
@ -338,6 +444,11 @@ Rectangle {
} }
} }
} }
onWidthChanged:{
table_view.forceLayout()
}
MouseArea{ MouseArea{
id:layout_mouse_table id:layout_mouse_table
hoverEnabled: true hoverEnabled: true
@ -359,30 +470,8 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
ScrollBar.horizontal:scroll_bar_h ScrollBar.horizontal:scroll_bar_h
ScrollBar.vertical:scroll_bar_v ScrollBar.vertical:scroll_bar_v
columnWidthProvider: function(column) { columnWidthProvider: control.columnWidthProvider
var columnObject = d.columns_data[column] rowHeightProvider: control.rowHeightProvider
var width = columnObject.width
if(width){
return width
}
var minimumWidth = columnObject.minimumWidth
if(minimumWidth){
return minimumWidth
}
return d.defaultItemWidth
}
rowHeightProvider: function(row) {
var rowObject = control.getRow(row)
var height = rowObject.height
if(height){
return height
}
var minimumHeight = rowObject._minimumHeight
if(minimumHeight){
return minimumHeight
}
return d.defaultItemHeight
}
model: table_sort_model model: table_sort_model
clip: true clip: true
onRowsChanged: { onRowsChanged: {
@ -390,70 +479,51 @@ Rectangle {
table_view.flick(0,1) table_view.flick(0,1)
} }
delegate: com_table_delegate delegate: com_table_delegate
FluLoader{
id:loader_edit
property var tableView: control
property var display
property int column: {
if(d.editPosition){
return d.editPosition.column
}
return 0
}
property int row: {
if(d.editPosition){
return d.editPosition.row
}
return 0
}
signal editTextChaged(string text)
sourceComponent: d.editPosition ? d.editDelegate : undefined
onEditTextChaged:
(text)=>{
var obj = control.getRow(row)
obj[d.columns_data[column].dataIndex] = text
control.setRow(row,obj)
}
width: {
if(d.editPosition){
return d.editPosition.width
}
return 0
}
height: {
if(d.editPosition){
return d.editPosition.height
}
return 0
}
x:{
if(d.editPosition){
return d.editPosition.x
}
return 0
}
y:{
if(d.editPosition){
return d.editPosition.y
}
return 0
}
z:999
}
} }
} }
Component{ Component{
id:com_column_header_delegate id: com_column_header_delegate
Rectangle{ Rectangle{
id:column_item_control id: column_item_control
property var currentTableView : TableView.view
readonly property real cellPadding: 8 readonly property real cellPadding: 8
property bool canceled: false property bool canceled: false
property int columnIndex: column property var _model: model
readonly property var columnObject : d.columns_data[column] readonly property var columnModel : control.columnSource[_index]
implicitWidth: { readonly property int _index : {
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2) const isDataIndex = (element) => {
return element.dataIndex === display.dataIndex
}
return control.columnSource.findIndex(isDataIndex)
}
readonly property bool isHeaderHorizontal: TableView.view == header_horizontal
readonly property bool isHide: {
if(isHeaderHorizontal && columnModel.frozen){
return true
}
if(!isHeaderHorizontal){
if(currentTableView.dataIndex !== columnModel.dataIndex)
return true
}
return false
}
visible: !isHide
implicitWidth: {
if(isHide){
return Number.MIN_VALUE
}
if(column_item_control.isHeaderHorizontal){
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2)
}
return Math.max(TableView.view.width,Number.MIN_VALUE)
}
implicitHeight: {
if(column_item_control.isHeaderHorizontal){
return Math.max(36, (item_column_loader.item&&item_column_loader.item.implicitHeight) + (cellPadding * 2))
}
return Math.max(TableView.view.height,Number.MIN_VALUE)
} }
implicitHeight: Math.max(36, (item_column_loader.item&&item_column_loader.item.implicitHeight) + (cellPadding * 2))
color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1) color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1)
Rectangle{ Rectangle{
border.color: control.borderColor border.color: control.borderColor
@ -474,7 +544,7 @@ Rectangle {
width: 1 width: 1
height: parent.height height: parent.height
anchors.left: parent.left anchors.left: parent.left
visible: column !== 0 visible: column_item_control._index !== 0
color:"#00000000" color:"#00000000"
} }
Rectangle{ Rectangle{
@ -483,7 +553,7 @@ Rectangle {
height: parent.height height: parent.height
anchors.right: parent.right anchors.right: parent.right
color:"#00000000" color:"#00000000"
visible: column === table_view.columns - 1 visible: column_item_control._index === table_view.columns - 1
} }
MouseArea{ MouseArea{
id:column_item_control_mouse id:column_item_control_mouse
@ -505,22 +575,23 @@ Rectangle {
} }
FluLoader{ FluLoader{
id:item_column_loader id:item_column_loader
property var itemModel: model property var model: column_item_control._model
property var modelData: model.display property var display: model.display.title
property var tableView: table_view property var tableView: table_view
property var tableModel: table_model property var sourceModel: control.sourceModel
property bool isObject: typeof(display) == "object"
property var options:{ property var options:{
if(typeof(modelData) == "object"){ if(isObject){
return modelData.options return display.options
} }
return {} return {}
} }
property int column: column_item_control.columnIndex property int column: column_item_control._index
width: parent.width width: parent.width
height: parent.height height: parent.height
sourceComponent: { sourceComponent: {
if(typeof(modelData) == "object"){ if(isObject){
return modelData.comId return display.comId
} }
return com_column_text return com_column_text
} }
@ -532,7 +603,7 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
hoverEnabled: true hoverEnabled: true
visible: !(columnObject.width === columnObject.minimumWidth && columnObject.width === columnObject.maximumWidth && columnObject.width) visible: !columnModel.frozen && !(columnModel.width === columnModel.minimumWidth && columnModel.width === columnModel.maximumWidth && columnModel.width)
cursorShape: Qt.SplitHCursor cursorShape: Qt.SplitHCursor
preventStealing: true preventStealing: true
onPressed : onPressed :
@ -552,9 +623,9 @@ Rectangle {
return return
} }
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
var minimumWidth = columnObject.minimumWidth var minimumWidth = columnModel.minimumWidth
var maximumWidth = columnObject.maximumWidth var maximumWidth = columnModel.maximumWidth
var w = columnObject.width var w = columnModel.width
if(!w){ if(!w){
w = d.defaultItemWidth w = d.defaultItemWidth
} }
@ -564,7 +635,7 @@ Rectangle {
if(!maximumWidth){ if(!maximumWidth){
maximumWidth = 65535 maximumWidth = 65535
} }
columnObject.width = Math.min(Math.max(minimumWidth, w + delta.x),maximumWidth) columnModel.width = Math.min(Math.max(minimumWidth, w + delta.x),maximumWidth)
table_view.forceLayout() table_view.forceLayout()
header_horizontal.forceLayout() header_horizontal.forceLayout()
} }
@ -577,7 +648,7 @@ Rectangle {
id:item_control id:item_control
readonly property real cellPadding: 8 readonly property real cellPadding: 8
property bool canceled: false property bool canceled: false
property var rowObject: control.getRow(row) property var rowModel: control.getRow(row)
implicitWidth: Math.max(30, row_text.implicitWidth + (cellPadding * 2)) implicitWidth: Math.max(30, row_text.implicitWidth + (cellPadding * 2))
implicitHeight: row_text.implicitHeight + (cellPadding * 2) implicitHeight: row_text.implicitHeight + (cellPadding * 2)
color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1) color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1)
@ -643,9 +714,9 @@ Rectangle {
cursorShape: Qt.SplitVCursor cursorShape: Qt.SplitVCursor
preventStealing: true preventStealing: true
visible: { visible: {
if(rowObject === null) if(rowModel === null)
return false return false
return !(rowObject.height === rowObject._minimumHeight && rowObject.height === rowObject._maximumHeight && rowObject.height) return !(rowModel.height === rowModel._minimumHeight && rowModel.height === rowModel._maximumHeight && rowModel.height)
} }
onPressed : onPressed :
(mouse)=>{ (mouse)=>{
@ -663,11 +734,11 @@ Rectangle {
if(!pressed){ if(!pressed){
return return
} }
var rowObject = control.getRow(row) var rowModel = control.getRow(row)
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
var minimumHeight = rowObject._minimumHeight var minimumHeight = rowModel._minimumHeight
var maximumHeight = rowObject._maximumHeight var maximumHeight = rowModel._maximumHeight
var h = rowObject.height var h = rowModel.height
if(!h){ if(!h){
h = d.defaultItemHeight h = d.defaultItemHeight
} }
@ -677,8 +748,8 @@ Rectangle {
if(!maximumHeight){ if(!maximumHeight){
maximumHeight = 65535 maximumHeight = 65535
} }
rowObject.height = Math.min(Math.max(minimumHeight, h + delta.y),maximumHeight) rowModel.height = Math.min(Math.max(minimumHeight, h + delta.y),maximumHeight)
control.setRow(row,rowObject) control.setRow(row,rowModel)
table_view.forceLayout() table_view.forceLayout()
} }
} }
@ -688,7 +759,7 @@ Rectangle {
id:com_column_text id:com_column_text
FluText { FluText {
id: column_text id: column_text
text: modelData text: String(display)
anchors.fill: parent anchors.fill: parent
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -791,6 +862,138 @@ Rectangle {
} }
} }
} }
Item{
anchors{
left: header_vertical.right
top: parent.top
bottom: parent.bottom
right: parent.right
}
Component{
id: com_table_frozen
Rectangle{
id: item_layout_frozen
anchors.fill: parent
color: {
if(Window.active){
return FluTheme.dark ? Qt.rgba(48/255,48/255,48/255,1) :Qt.rgba(1,1,1,1)
}
return FluTheme.dark ? Qt.rgba(56/255,56/255,56/255,1) :Qt.rgba(243/255,243/255,243/255,1)
}
visible: table_view.rows !== 0
Rectangle{
z:99
anchors.fill: parent
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,0.6) : Qt.rgba(191/255,191/255,191/255,0.3)
FluShadow{
radius: 0
anchors.fill: parent
}
color: "#00000000"
}
TableView{
property string dataIndex: columnModel.dataIndex
id: item_table_frozen
interactive: false
clip: true
anchors{
left: parent.left
right: parent.right
}
contentWidth: width
height: table_view.height
y: header_horizontal.height
boundsBehavior: TableView.StopAtBounds
model: table_view.model
delegate: table_view.delegate
syncDirection: Qt.Vertical
syncView: table_view
}
TableView {
property string dataIndex: columnModel.dataIndex
id:item_table_frozen_header
model: header_column_model
boundsBehavior: Flickable.StopAtBounds
interactive: false
clip: true
contentWidth: width
anchors{
left: parent.left
right: parent.right
top: parent.top
bottom: item_table_frozen.top
}
delegate: com_column_header_delegate
Component.onCompleted: {
item_table_frozen_header.forceLayout()
}
}
Connections{
target: table_view
function onWidthChanged() {
item_table_frozen_header.forceLayout()
}
}
}
}
Repeater{
Component.onCompleted: {
model = control.columnSource
}
delegate: FluLoader{
id: item_layout_frozen
readonly property int _index : model.index
readonly property var columnModel : control.columnSource[_index]
readonly property bool isHide:{
if(columnModel.frozen){
return false
}
return true
}
Connections{
target: d
function onTableItemLayout(column){
if(item_layout_frozen._index === column){
updateLayout()
}
}
}
Connections{
target: table_view
function onContentXChanged(){
updateLayout()
}
}
function updateLayout(){
width = table_view.columnWidthProvider(_index)
x = Qt.binding(function(){
var minX = 0
var maxX = table_view.width-width
for(var i=0;i<_index;i++){
var item = control.columnSource[i]
if(item.frozen){
minX = minX + table_view.columnWidthProvider(i)
}
}
for(i=_index+1;i<control.columnSource.length;i++){
item = control.columnSource[i]
if(item.frozen){
maxX = maxX - table_view.columnWidthProvider(i)
}
}
return Math.min(Math.max(columnModel.x - table_view.contentX,minX),maxX)}
)
}
Component.onCompleted: {
updateLayout()
}
height: control.height
visible: !item_layout_frozen.isHide
sourceComponent: item_layout_frozen.isHide ? undefined : com_table_frozen
}
}
}
FluScrollBar { FluScrollBar {
id: scroll_bar_h id: scroll_bar_h
anchors{ anchors{
@ -837,7 +1040,7 @@ Rectangle {
function sort(callback=undefined){ function sort(callback=undefined){
if(callback){ if(callback){
table_sort_model.setComparator(function(left,right){ table_sort_model.setComparator(function(left,right){
return callback(table_model.getRow(left),table_model.getRow(right)) return callback(sourceModel.getRow(left),sourceModel.getRow(right))
}) })
}else{ }else{
table_sort_model.setComparator(undefined) table_sort_model.setComparator(undefined)
@ -846,7 +1049,7 @@ Rectangle {
function filter(callback=undefined){ function filter(callback=undefined){
if(callback){ if(callback){
table_sort_model.setFilter(function(index){ table_sort_model.setFilter(function(index){
return callback(table_model.getRow(index)) return callback(sourceModel.getRow(index))
}) })
}else{ }else{
table_sort_model.setFilter(undefined) table_sort_model.setFilter(undefined)
@ -868,7 +1071,26 @@ Rectangle {
table_view.model.removeRow(rowIndex,rows) table_view.model.removeRow(rowIndex,rows)
} }
} }
function insertRow(rowIndex,obj){
if(rowIndex>=0 && rowIndex<table_view.rows){
sourceModel.insertRow(rowIndex,obj)
}
}
function currentIndex(){
var index = -1
if(!d.current){
return index
}
for (var i = 0; i <= sourceModel.rowCount-1; i++) {
var sourceItem = sourceModel.getRow(i);
if(sourceItem._key === d.current._key){
index = i
break
}
}
return index
}
function appendRow(obj){ function appendRow(obj){
table_model.appendRow(obj) sourceModel.appendRow(obj)
} }
} }

View File

@ -17,6 +17,7 @@ Rectangle {
property color selectedBorderColor: FluTheme.primaryColor property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3) property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
readonly property alias current: d.current readonly property alias current: d.current
property alias view: table_view
id:control id:control
color: { color: {
if(Window.active){ if(Window.active){
@ -28,21 +29,26 @@ Rectangle {
tree_model.setDataSource(dataSource) tree_model.setDataSource(dataSource)
} }
onColumnSourceChanged: { onColumnSourceChanged: {
var columns= [] if(columnSource.length !== 0){
var headerRow = {} var columns= []
columnSource.forEach(function(item){ var headerRow = {}
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',control); columnSource.forEach(function(item){
column.display = item.dataIndex var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',control);
columns.push(column) column.display = item.dataIndex
headerRow[item.dataIndex] = item.title columns.push(column)
}) headerRow[item.dataIndex] = item.title
header_column_model.columns = columns })
header_column_model.rows = [headerRow] header_column_model.columns = columns
header_column_model.rows = [headerRow]
}
} }
FluTreeModel{ FluTreeModel{
id:tree_model id:tree_model
columnSource: control.columnSource columnSource: control.columnSource
} }
Component.onDestruction: {
table_view.contentY = 0
}
onDepthPaddingChanged: { onDepthPaddingChanged: {
table_view.forceLayout() table_view.forceLayout()
} }

View File

@ -59,8 +59,9 @@ Window {
signal lazyLoad() signal lazyLoad()
property var _windowRegister property var _windowRegister
property string _route property string _route
id:window property bool _hideShadow: false
color:"transparent" id: window
color: FluTools.isSoftware() ? window.backgroundColor : "transparent"
Component.onCompleted: { Component.onCompleted: {
FluRouter.addWindow(window) FluRouter.addWindow(window)
useSystemAppBar = FluApp.useSystemAppBar useSystemAppBar = FluApp.useSystemAppBar
@ -120,12 +121,21 @@ Window {
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
asynchronous: true asynchronous: true
Component.onCompleted: { Component.onCompleted: {
var geometry = FluTools.desktopAvailableGeometry(window) img_back.updateLayout()
width = geometry.width
height = geometry.height
sourceSize = Qt.size(width,height)
source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath) source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
} }
Connections{
target: window
function onScreenChanged(){
img_back.updateLayout()
}
}
function updateLayout(){
var geometry = FluTools.desktopAvailableGeometry(window)
img_back.width = geometry.width
img_back.height = geometry.height
img_back.sourceSize = Qt.size(img_back.width,img_back.height)
}
Connections{ Connections{
target: FluTheme target: FluTheme
function onDesktopImagePathChanged(){ function onDesktopImagePathChanged(){
@ -141,7 +151,7 @@ Window {
} }
Timer{ Timer{
id:timer_update_image id:timer_update_image
interval: 500 interval: 150
onTriggered: { onTriggered: {
img_back.source = "" img_back.source = ""
img_back.source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath) img_back.source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
@ -155,7 +165,7 @@ Window {
blurRadius: 64 blurRadius: 64
visible: window.active && FluTheme.blurBehindWindowEnabled visible: window.active && FluTheme.blurBehindWindowEnabled
tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1) tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1)
targetRect: Qt.rect(window.x,window.y,window.width,window.height) targetRect: Qt.rect(window.x-window.screen.virtualX,window.y-window.screen.virtualY,window.width,window.height)
} }
} }
} }
@ -278,13 +288,7 @@ Window {
id:loader_border id:loader_border
anchors.fill: parent anchors.fill: parent
sourceComponent: { sourceComponent: {
if(window.useSystemAppBar){ if(window.useSystemAppBar || FluTools.isWin() || window.visibility === Window.Maximized || window.visibility === Window.FullScreen){
return undefined
}
if(FluTools.isWindows10OrGreater()){
return undefined
}
if(window.visibility === Window.Maximized || window.visibility === Window.FullScreen){
return undefined return undefined
} }
return com_border return com_border
@ -294,19 +298,21 @@ Window {
loader_loading.sourceComponent = undefined loader_loading.sourceComponent = undefined
} }
function showSuccess(text,duration,moremsg){ function showSuccess(text,duration,moremsg){
info_bar.showSuccess(text,duration,moremsg) return info_bar.showSuccess(text,duration,moremsg)
} }
function showInfo(text,duration,moremsg){ function showInfo(text,duration,moremsg){
info_bar.showInfo(text,duration,moremsg) return info_bar.showInfo(text,duration,moremsg)
} }
function showWarning(text,duration,moremsg){ function showWarning(text,duration,moremsg){
info_bar.showWarning(text,duration,moremsg) return info_bar.showWarning(text,duration,moremsg)
} }
function showError(text,duration,moremsg){ function showError(text,duration,moremsg){
info_bar.showError(text,duration,moremsg) return info_bar.showError(text,duration,moremsg)
}
function clearAllInfo(){
return info_bar.clearAllInfo()
} }
function moveWindowToDesktopCenter(){ function moveWindowToDesktopCenter(){
screen = Qt.application.screens[FluTools.cursorScreenIndex()]
var availableGeometry = FluTools.desktopAvailableGeometry(window) var availableGeometry = FluTools.desktopAvailableGeometry(window)
window.setGeometry((availableGeometry.width-window.width)/2+Screen.virtualX,(availableGeometry.height-window.height)/2+Screen.virtualY,window.width,window.height) window.setGeometry((availableGeometry.width-window.width)/2+Screen.virtualX,(availableGeometry.height-window.height)/2+Screen.virtualY,window.width,window.height)
} }