Compare commits

..

83 Commits

Author SHA1 Message Date
74940665ae update 2023-06-30 22:55:03 +08:00
21ddc79f3f update 2023-06-30 22:50:44 +08:00
64bbae9266 update 2023-06-30 18:47:25 +08:00
bbb6fe9329 update 2023-06-30 17:39:58 +08:00
c42f3ef70f update 2023-06-30 17:22:27 +08:00
f13f1727af update 2023-06-30 12:08:57 +08:00
9f9e48659b update 2023-06-29 23:36:36 +08:00
294606d019 update 2023-06-29 22:30:15 +08:00
bfa5c93d40 update 2023-06-29 18:47:10 +08:00
9656b3dd95 update 2023-06-29 17:48:48 +08:00
8a52f143d7 update 2023-06-29 10:07:02 +08:00
dc3b1acaa5 update 2023-06-29 10:03:24 +08:00
1a8d06331f update 2023-06-28 18:12:33 +08:00
d09414db1b update 2023-06-28 18:07:39 +08:00
bf3006415b update 2023-06-28 13:16:21 +08:00
cdba8b7921 update 2023-06-28 13:15:33 +08:00
192c65a510 update 2023-06-28 13:13:39 +08:00
90943674b3 update 2023-06-28 12:12:15 +08:00
157dc9166b update 2023-06-28 09:45:47 +08:00
a7e8a5e4cf update 2023-06-28 02:28:34 +08:00
96071ac8d7 update 2023-06-27 22:14:27 +08:00
e25b944704 update 2023-06-27 21:14:20 +08:00
1566e3934e update 2023-06-27 21:02:57 +08:00
16e71f01b1 Merge pull request #172 from mentalfl0w/dev
Make the FluTableView readonly text copiable.
2023-06-27 20:47:21 +08:00
e54c161aa6 Make the FluTableView readonly text copiable. 2023-06-27 20:39:57 +08:00
2147965b00 update 2023-06-27 00:17:01 +08:00
3a940466d5 update 2023-06-27 00:00:41 +08:00
564b27cd02 update 2023-06-26 23:57:50 +08:00
4be2ad6ba0 Merge pull request #171 from mentalfl0w/dev
FluTableView bug fixed.
2023-06-26 23:41:14 +08:00
1d9f6f5eff FluTableView bug fixed. 2023-06-26 23:21:15 +08:00
0610f63f26 update 2023-06-26 19:59:28 +08:00
d741b3eb4f update 2023-06-26 18:20:01 +08:00
cb7d2097f2 update 2023-06-26 18:12:58 +08:00
dff77d3d4f update 2023-06-26 11:43:49 +08:00
6d0834c653 update 2023-06-25 23:39:23 +08:00
059a1b17cc update 2023-06-25 23:17:44 +08:00
e1096b8e22 update 2023-06-25 19:01:22 +08:00
cd577c5599 update 2023-06-25 11:44:13 +08:00
d43532986a update 2023-06-25 11:30:25 +08:00
4c9e576072 update 2023-06-25 10:13:50 +08:00
b254064e26 Merge pull request #168 from mentalfl0w/dev
Fix qt_standard_project_setup for Qt 6.2 and below.
2023-06-25 09:03:12 +08:00
ffd8072826 Fix qt_standard_project_setup for Qt 6.2 and below. 2023-06-24 21:57:00 +08:00
9a1db0b230 update 2023-06-24 11:56:32 +08:00
9786e69fc2 update 2023-06-24 10:27:28 +08:00
82be3b12e3 update 2023-06-21 17:17:25 +08:00
1c0f5acaf8 update 2023-06-21 16:12:07 +08:00
243f8aa248 update 2023-06-21 11:47:05 +08:00
cbb8c3122b update 2023-06-21 00:43:05 +08:00
9f2c58306c update 2023-06-20 19:18:18 +08:00
adc3558e02 update .gitignore 2023-06-20 19:02:18 +08:00
98d73eb6cb update 2023-06-20 18:32:10 +08:00
b442696f92 update 2023-06-20 18:02:15 +08:00
82f606dd65 update 2023-06-20 12:53:32 +08:00
4efb91084a update 2023-06-19 18:08:49 +08:00
103dbe9d56 update 2023-06-19 17:50:54 +08:00
b829fa572f update 2023-06-19 09:52:19 +08:00
d2c5cc779b update 2023-06-19 09:50:11 +08:00
5acf664492 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-06-19 09:12:59 +08:00
75d226947f update 2023-06-18 23:54:39 +08:00
752ff3c4f2 update 2023-06-18 13:56:30 +08:00
e591c483d5 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-06-16 17:17:25 +08:00
fdff068752 update 2023-06-16 17:17:21 +08:00
24f28d8945 update 2023-06-16 12:45:57 +08:00
ed51143e9b update 2023-06-16 12:25:50 +08:00
9d94bc65d5 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-06-16 09:30:33 +08:00
7bfa9f0191 update 2023-06-16 09:30:21 +08:00
6db144c751 Update README.md 2023-06-15 15:58:56 +08:00
a574cd9230 update 2023-06-15 15:01:33 +08:00
8c45c125e6 update 2023-06-15 14:46:32 +08:00
aab4802d7e update 2023-06-15 07:39:45 +08:00
441c1ab03c update 2023-06-15 00:42:07 +08:00
91f4f508cc update 2023-06-15 00:21:54 +08:00
94f8047508 update 2023-06-14 19:29:23 +08:00
d926a84f72 update 2023-06-14 00:04:37 +08:00
c07011408c update 2023-06-13 23:57:52 +08:00
4f9ec6abf2 update 2023-06-13 22:24:22 +08:00
c3b3dc904e update 2023-06-13 22:00:15 +08:00
2a5acb45a1 update 2023-06-13 20:13:49 +08:00
d29580f8f2 update 2023-06-13 18:17:40 +08:00
fd0ddbf5aa update 2023-06-13 11:48:29 +08:00
ac602c5afa update 2023-06-13 10:26:14 +08:00
8dbfcfd994 Merge pull request #157 from mentalfl0w/dev
Fix FluNavigationView push function in Standard mode.
2023-06-13 09:20:58 +08:00
c5ce34cbc3 Fix FluNavigationView push function in Standard mode. 2023-06-12 22:41:58 +08:00
208 changed files with 2634 additions and 1866 deletions

View File

@ -2,9 +2,21 @@ cmake_minimum_required(VERSION 3.20)
project(FluentUI VERSION 0.1 LANGUAGES CXX) project(FluentUI VERSION 0.1 LANGUAGES CXX)
add_subdirectory(src) option(FLUENTUI_BUILD_EXAMPLES "Build FluentUI demo applications." ON)
add_subdirectory(example) option(FLUENTUI_BUILD_FRAMELESSHEPLER "Build FramelessHelper." ON)
add_subdirectory(src)
if (FLUENTUI_BUILD_EXAMPLES)
add_subdirectory(example)
endif ()
if (FLUENTUI_BUILD_FRAMELESSHEPLER)
add_definitions(-DFRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT) add_definitions(-DFRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT)
add_definitions(-DFRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT) add_definitions(-DFRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT)
add_subdirectory(framelesshelper) add_subdirectory(framelesshelper)
endif ()
message("------------------------ FluentUI ------------------------")
message("Build FluentUI demo applications.: ${FLUENTUI_BUILD_EXAMPLES}")
message("Build FramelessHelper.: ${FLUENTUI_BUILD_FRAMELESSHEPLER}")

View File

@ -115,5 +115,9 @@ View more [`here`](doc/md/all_components.md)!
This FluentUI library currently licensed under [MIT License](./License) This FluentUI library currently licensed under [MIT License](./License)
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=zhuzichu520/FluentUI&type=Date)](https://star-history.com/#zhuzichu520/FluentUI&Date)
## ⚡ Visitor count ## ⚡ Visitor count
![](https://profile-counter.glitch.me/zhuzichu520-FluentUI/count.svg) ![](https://profile-counter.glitch.me/zhuzichu520-FluentUI/count.svg)

0
doc/preview/demo_content_dialog.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
doc/preview/demo_filledbtn.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

0
doc/preview/demo_icon.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

0
doc/preview/demo_infobar.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

0
doc/preview/demo_large.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 192 KiB

0
doc/preview/demo_multiline_textbox.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

0
doc/preview/demo_progress_bar_ring.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
doc/preview/demo_radiobtn.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

0
doc/preview/demo_rectangle.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

0
doc/preview/demo_slider.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 997 B

After

Width:  |  Height:  |  Size: 997 B

0
doc/preview/demo_standardbtn.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

0
doc/preview/demo_textbox.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
doc/preview/demo_textbtn.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

0
doc/preview/demo_toggle_switch.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

0
doc/preview/demo_tooltip.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
doc/preview/demo_tree_view.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
doc/preview/qt_creator_project.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.20)
project(example VERSION 0.1 LANGUAGES CXX) project(example VERSION 0.1 LANGUAGES CXX)
#配置通用编译 #配置通用编译
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE) if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
@ -20,9 +19,17 @@ endif()
file(TO_CMAKE_PATH "/" PATH_SEPARATOR) file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
#设置版本号 #设置版本号
add_definitions(-DVERSION=1,3,3,0) add_definitions(-DVERSION=1,3,7,1)
find_package(Qt6 REQUIRED COMPONENTS Quick REQUIRED) find_package(Qt6 REQUIRED COMPONENTS Quick)
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
qt_standard_project_setup()
else()
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
endif()
#遍历所有Cpp文件 #遍历所有Cpp文件
file(GLOB_RECURSE CPP_FILES *.cpp *.h) file(GLOB_RECURSE CPP_FILES *.cpp *.h)
@ -101,4 +108,6 @@ target_link_libraries(example PRIVATE
#安装 #安装
install(TARGETS example install(TARGETS example
BUNDLE DESTINATION . BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View File

@ -6,6 +6,7 @@ import FluentUI
Window { Window {
id: app id: app
flags: Qt.SplashScreen
Component.onCompleted: { Component.onCompleted: {
FluApp.init(app) FluApp.init(app)
FluTheme.darkMode = FluDarkMode.System FluTheme.darkMode = FluDarkMode.System
@ -13,7 +14,6 @@ Window {
"/":"qrc:/example/qml/window/MainWindow.qml", "/":"qrc:/example/qml/window/MainWindow.qml",
"/about":"qrc:/example/qml/window/AboutWindow.qml", "/about":"qrc:/example/qml/window/AboutWindow.qml",
"/login":"qrc:/example/qml/window/LoginWindow.qml", "/login":"qrc:/example/qml/window/LoginWindow.qml",
"/media":"qrc:/example/qml/window/MediaWindow.qml",
"/singleTaskWindow":"qrc:/example/qml/window/SingleTaskWindow.qml", "/singleTaskWindow":"qrc:/example/qml/window/SingleTaskWindow.qml",
"/standardWindow":"qrc:/example/qml/window/StandardWindow.qml", "/standardWindow":"qrc:/example/qml/window/StandardWindow.qml",
"/singleInstanceWindow":"qrc:/example/qml/window/SingleInstanceWindow.qml" "/singleInstanceWindow":"qrc:/example/qml/window/SingleInstanceWindow.qml"

View File

@ -130,13 +130,15 @@ FluExpander{
"FluBreadcrumbBar", "FluBreadcrumbBar",
"FluCopyableText", "FluCopyableText",
"FluAcrylic", "FluAcrylic",
"FluRemoteLoader" "FluRemoteLoader",
"FluMenuBar",
"FluPagination",
"FluRadioButtons",
"FluImage",
"FluSpinBox"
]; ];
code = code.replace(/\n/g, "<br>"); code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;"); code = code.replace(/ /g, "&nbsp;");
return code.replace(RegExp("\\b(" + qmlKeywords.join("|") + ")\\b", "g"), "<span style='color: #c23a80'>$1</span>"); return code.replace(RegExp("\\b(" + qmlKeywords.join("|") + ")\\b", "g"), "<span style='color: #c23a80'>$1</span>");
} }
} }

View File

@ -8,16 +8,17 @@ FluObject{
property var navigationView property var navigationView
FluPaneItem{ FluPaneItem{
id:item_home
count: 9
title:lang.home title:lang.home
infoBadge:FluBadge{
count: item_home.count
}
icon:FluentIcons.Home icon:FluentIcons.Home
// cusIcon: Image{
// anchors.centerIn: parent
// source: FluTheme.dark ? "qrc:/example/res/svg/home_dark.svg" : "qrc:/example/res/svg/home.svg"
// sourceSize: Qt.size(30,30)
// width: 18
// height: 18
// }
onTap:{ onTap:{
if(navigationView.getCurrentUrl()){
item_home.count = 0
}
navigationView.push("qrc:/example/qml/page/T_Home.qml") navigationView.push("qrc:/example/qml/page/T_Home.qml")
} }
} }
@ -26,20 +27,39 @@ FluObject{
title:lang.basic_input title:lang.basic_input
icon:FluentIcons.CheckboxComposite icon:FluentIcons.CheckboxComposite
FluPaneItem{ FluPaneItem{
id:item_buttons
count: 99
infoBadge:FluBadge{
count: item_buttons.count
}
title:"Buttons" title:"Buttons"
image:"qrc:/example/res/image/control/Button.png" image:"qrc:/example/res/image/control/Button.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event." desc:"A control that responds to user input and raisesa Click event."
onTap:{ onTap:{
item_buttons.count = 0
navigationView.push("qrc:/example/qml/page/T_Buttons.qml") navigationView.push("qrc:/example/qml/page/T_Buttons.qml")
} }
} }
FluPaneItem{ FluPaneItem{
id:item_text
title:"Text" title:"Text"
count: 5
infoBadge:FluBadge{
count: item_text.count
color: Qt.rgba(82/255,196/255,26/255,1)
}
onTap:{ onTap:{
item_text.count = 0
navigationView.push("qrc:/example/qml/page/T_Text.qml") navigationView.push("qrc:/example/qml/page/T_Text.qml")
} }
} }
FluPaneItem{
title:"Image"
onTap:{
navigationView.push("qrc:/example/qml/page/T_Image.qml")
}
}
FluPaneItem{ FluPaneItem{
title:"Slider" title:"Slider"
image:"qrc:/example/res/image/control/Slider.png" image:"qrc:/example/res/image/control/Slider.png"
@ -58,6 +78,12 @@ FluObject{
navigationView.push("qrc:/example/qml/page/T_CheckBox.qml") navigationView.push("qrc:/example/qml/page/T_CheckBox.qml")
} }
} }
FluPaneItem{
title:"RadioButton"
onTap:{
navigationView.push("qrc:/example/qml/page/T_RadioButton.qml")
}
}
FluPaneItem{ FluPaneItem{
title:"ToggleSwitch" title:"ToggleSwitch"
onTap:{ onTap:{
@ -167,8 +193,15 @@ FluObject{
} }
} }
FluPaneItem{ FluPaneItem{
id:item_combobox
title:"ComboBox" title:"ComboBox"
count: 9
infoBadge:FluBadge{
count: item_combobox.count
color: Qt.rgba(250/255,173/255,20/255,1)
}
onTap:{ onTap:{
item_combobox.count = 0
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml") navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
} }
} }
@ -231,6 +264,12 @@ FluObject{
navigationView.push("qrc:/example/qml/page/T_TableView.qml") navigationView.push("qrc:/example/qml/page/T_TableView.qml")
} }
} }
FluPaneItem{
title:"Pagination"
onTap:{
navigationView.push("qrc:/example/qml/page/T_Pagination.qml")
}
}
FluPaneItem{ FluPaneItem{
title:"MultiWindow" title:"MultiWindow"
onTap:{ onTap:{
@ -278,28 +317,19 @@ FluObject{
} }
} }
FluPaneItemExpander{
title:lang.media
icon:FluentIcons.Media
FluPaneItem{
title:"MediaPlayer"
image:"qrc:/example/res/image/control/MediaPlayerElement.png"
recentlyAdded:true
order:0
desc:"A control to display video and image content."
onTap:{
navigationView.push("qrc:/example/qml/page/T_MediaPlayer.qml")
}
}
}
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.other title:lang.other
icon:FluentIcons.Shop icon:FluentIcons.Shop
FluPaneItem{ FluPaneItem{
id:item_other
title:"RemoteLoader" title:"RemoteLoader"
count: 99
infoBadge:FluBadge{
count: item_other.count
color: Qt.rgba(82/255,196/255,26/255,1)
}
onTap:{ onTap:{
item_other.count = 0
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml") navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
} }
} }

View File

@ -58,6 +58,7 @@ FluScrollablePage{
width: 100 width: 100
height: 100 height: 100
anchors.centerIn: parent anchors.centerIn: parent
}
}' }'
} }

View File

@ -33,6 +33,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
count:0 count:0
} }
} }
@ -43,6 +45,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
count:5 count:5
} }
} }
@ -52,6 +56,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
count:50 count:50
} }
} }
@ -61,6 +67,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
count:100 count:100
} }
} }
@ -70,6 +78,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
isDot:true isDot:true
} }
} }
@ -79,6 +89,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
count:99 count:99
color: Qt.rgba(250/255,173/255,20/255,1) color: Qt.rgba(250/255,173/255,20/255,1)
} }
@ -89,6 +101,8 @@ FluScrollablePage{
radius: 8 radius: 8
color: Qt.rgba(191/255,191/255,191/255,1) color: Qt.rgba(191/255,191/255,191/255,1)
FluBadge{ FluBadge{
topRight: true
showZero: true
count:99 count:99
color: Qt.rgba(82/255,196/255,26/255,1) color: Qt.rgba(82/255,196/255,26/255,1)
} }

View File

@ -210,20 +210,21 @@ FluScrollablePage{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
} }
items:[
FluMenuItem{ FluMenuItem{
text:"Menu_1" text:"Menu_1"
}, }
FluMenuItem{ FluMenuItem{
text:"Menu_2" text:"Menu_2"
}, }
FluMenuItem{ FluMenuItem{
text:"Menu_3" text:"Menu_3"
}, }
FluMenuItem{ FluMenuItem{
text:"Menu_4" text:"Menu_4"
onClicked: {
console.debug(parent.height)
}
} }
]
} }
FluToggleSwitch{ FluToggleSwitch{
id:drop_down_button_switch id:drop_down_button_switch
@ -261,24 +262,23 @@ FluScrollablePage{
height: 100 height: 100
paddings: 10 paddings: 10
Layout.topMargin: 20 Layout.topMargin: 20
ColumnLayout{ FluRadioButtons{
spacing: 8 spacing: 8
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
} }
Repeater{ FluRadioButton{
id:repeater
property int selecIndex : 0
model: 3
delegate: FluRadioButton{
checked : repeater.selecIndex===index
disabled:radio_button_switch.checked disabled:radio_button_switch.checked
text:"Radio Button_"+index text:"Radio Button_1"
clickListener:function(){
repeater.selecIndex = index
} }
FluRadioButton{
disabled:radio_button_switch.checked
text:"Radio Button_2"
} }
FluRadioButton{
disabled:radio_button_switch.checked
text:"Radio Button_3"
} }
} }
FluToggleSwitch{ FluToggleSwitch{

View File

@ -22,7 +22,12 @@ FluScrollablePage{
} }
FluCheckBox{ FluCheckBox{
disabled: check_box_switch.checked disabled: check_box_switch.checked
text:"Text" text:"Right"
}
FluCheckBox{
disabled: check_box_switch.checked
text:"Left"
textRight: false
} }
} }
FluToggleSwitch{ FluToggleSwitch{

View File

@ -28,10 +28,6 @@ FluScrollablePage{
ListElement { text: "Apple" } ListElement { text: "Apple" }
ListElement { text: "Coconut" } ListElement { text: "Coconut" }
} }
onAccepted: {
if (find(editText) === -1)
model_1.append({text: editText})
}
} }
} }
} }

View File

@ -23,6 +23,9 @@ FluScrollablePage{
text:"showYear=true" text:"showYear=true"
} }
FluDatePicker{ FluDatePicker{
onCurrentChanged: {
showSuccess(current.toLocaleDateString())
}
} }
} }
} }
@ -50,7 +53,9 @@ FluScrollablePage{
FluDatePicker{ FluDatePicker{
showYear:false showYear:false
onCurrentChanged: {
showSuccess(current.toLocaleDateString())
}
} }
} }
} }

View File

@ -27,7 +27,7 @@ FluScrollablePage{
Layout.topMargin: 20 Layout.topMargin: 20
Item{ Item{
anchors.fill: parent anchors.fill: parent
ColumnLayout{ FluRadioButtons{
spacing: 8 spacing: 8
anchors{ anchors{
top: parent.top top: parent.top
@ -35,17 +35,14 @@ FluScrollablePage{
topMargin: 15 topMargin: 15
leftMargin: 15 leftMargin: 15
} }
Repeater{ FluRadioButton{
id:repeater text:"Radio Button_1"
property int selecIndex : 0
model: 3
delegate: FluRadioButton{
checked : repeater.selecIndex===index
text:"Radio Button_"+index
clickListener:function() {
repeater.selecIndex = index
} }
FluRadioButton{
text:"Radio Button_2"
} }
FluRadioButton{
text:"Radio Button_3"
} }
} }
} }

View File

@ -17,7 +17,6 @@ FluScrollablePage{
desc:"The latest FluentUI controls and styles for your applications." desc:"The latest FluentUI controls and styles for your applications."
url:"https://github.com/zhuzichu520/FluentUI" url:"https://github.com/zhuzichu520/FluentUI"
} }
} }
Item{ Item{

View File

@ -0,0 +1,48 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "qrc:///example/qml/component"
FluScrollablePage{
title:"Image"
FluArea{
Layout.fillWidth: true
height: 300
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left:parent.left
}
FluImage{
width: 384
height: 240
source: "https://gitee.com/zhu-zichu/zhu-zichu/raw/74f075efe2f8d3c3bb7ba3c2259e403450e4050b/image/banner_4.jpg"
onStatusChanged:{
if(status === Image.Error){
showError("图片加载失败,请重新加载")
}
}
clickErrorListener: function(){
source = "https://gitee.com/zhu-zichu/zhu-zichu/raw/74f075efe2f8d3c3bb7ba3c2259e403450e4050b/image/banner_1.jpg"
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluImage{
width: 400
height: 300
source: "https://gitee.com/zhu-zichu/zhu-zichu/raw/74f075efe2f8d3c3bb7ba3c2259e403450e4050b/image/banner_1.jpg"
}'
}
}

View File

@ -1,62 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "qrc:///example/qml/component"
FluScrollablePage{
title:"MediaPlayer"
onVisibleChanged: {
if(visible){
player.play()
}else{
player.pause()
}
}
FluArea{
Layout.fillWidth: true
height: 320
Layout.topMargin: 20
paddings: 10
ColumnLayout{
anchors{
verticalCenter: parent.verticalCenter
left:parent.left
}
FluMediaPlayer{
id:player
source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMediaPlayer{
id:player
source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
}
'
}
FluArea{
Layout.fillWidth: true
height: 68
Layout.topMargin: 20
paddings: 10
FluButton{
text:"跳转到视频播放器窗口"
anchors.verticalCenter: parent.verticalCenter
onClicked:{
FluApp.navigate("/media",{source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"})
}
}
}
}

View File

@ -9,6 +9,36 @@ FluScrollablePage{
title:"Menu" title:"Menu"
FluMenu {
id:menu
title: qsTr("File")
Action { text: qsTr("New...")}
Action { text: qsTr("Open...") }
Action { text: qsTr("Save") }
FluMenuSeparator { }
Action {
text: qsTr("Quit")
onTriggered: {
showError("Quit")
}
}
Action {
text: qsTr("Disable")
enabled:false
onTriggered: {
showError("Disable")
}
}
FluMenuSeparator { }
Action { text: qsTr("Check");checkable: true;checked: true}
FluMenu{
title: "Save As..."
Action { text: qsTr("Doc") }
Action { text: qsTr("PDF") }
}
}
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
height: 100 height: 100
@ -22,28 +52,19 @@ FluScrollablePage{
left:parent.left left:parent.left
} }
FluText{
text:"Menu"
}
FluButton{ FluButton{
text:"左击菜单" text:"Show Menu Popup"
Layout.topMargin: 20 Layout.topMargin: 20
onClicked:{ onClicked:{
menu.popup() menu.popup()
} }
} }
FluButton{
text:"右击菜单"
Layout.topMargin: 20
onClicked: {
showSuccess("请按鼠标右击")
}
MouseArea{
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
menu.popup()
}
}
}
} }
} }
@ -69,20 +90,78 @@ menu.popup()
' '
} }
FluArea{
Layout.fillWidth: true
height: 100
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left:parent.left
}
FluText{
text:"MenuBar"
}
FluMenuBar {
id:menu_bar
FluMenu { FluMenu {
id:menu title: qsTr("File")
FluMenuItem{ Action { text: qsTr("New...") }
text:"删除" Action { text: qsTr("Open...") }
onClicked: { Action { text: qsTr("Save") }
showError("删除") FluMenuSeparator { }
Action { text: qsTr("Quit") }
Action {
text: qsTr("Disable")
enabled:false
}
FluMenu{
title: "Save As..."
Action { text: qsTr("Doc") }
Action { text: qsTr("PDF") }
} }
} }
FluMenuItem{ FluMenu {
text:"修改" title: qsTr("Edit")
onClicked: { Action { text: qsTr("Cut") }
showInfo("修改") Action { text: qsTr("Copy") }
Action { text: qsTr("Paste") }
} }
FluMenu {
title: qsTr("Help")
Action { text: qsTr("About") }
} }
} }
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMenuBar{
id:menu
FluMenu:{
title:"File"
Action { text: qsTr("New...") }
}
FluMenu:{
title:"Edit"
Action { text: qsTr("Cut") }
Action { text: qsTr("Copy") }
Action { text: qsTr("Paste") }
}
}
menu.popup()
'
}
} }

View File

@ -0,0 +1,49 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import "qrc:///example/qml/component"
import FluentUI
FluScrollablePage{
title:"Pagination"
FluArea{
Layout.fillWidth: true
height: 200
paddings: 10
Layout.topMargin: 20
ColumnLayout{
spacing: 20
anchors.verticalCenter: parent.verticalCenter
FluPagination{
pageCurrent: 1
pageButtonCount: 5
itemCount: 5000
}
FluPagination{
pageCurrent: 2
itemCount: 5000
pageButtonCount: 7
}
FluPagination{
pageCurrent: 3
itemCount: 5000
pageButtonCount: 9
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluPagination{
pageCurrent: 1
itemCount: 1000
pageButtonCount: 9
}'
}
}

View File

@ -76,5 +76,4 @@ FluScrollablePage{
} }
' '
} }
} }

View File

@ -33,10 +33,13 @@ FluScrollablePage{
indeterminate: false indeterminate: false
} }
FluSlider{ FluSlider{
value:50
onValueChanged:{ onValueChanged:{
progress_bar.progress = value/100 var progress = value/100
progress_ring.progress = value/100 progress_bar.progress = progress
progress_ring.progress = progress
}
Component.onCompleted: {
value = 50
} }
} }
} }

View File

@ -0,0 +1,101 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "qrc:///example/qml/component"
FluScrollablePage{
title:"RadioButton"
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
Row{
spacing: 30
anchors.verticalCenter: parent.verticalCenter
FluRadioButton{
disabled: radio_button_switch.checked
}
FluRadioButton{
disabled: radio_button_switch.checked
text:"Right"
}
FluRadioButton{
disabled: radio_button_switch.checked
text:"Left"
textRight: false
}
}
FluToggleSwitch{
id:radio_button_switch
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text:"Disabled"
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRadioButton{
text:"Text"
}'
}
FluArea{
Layout.fillWidth: true
height: 100
paddings: 10
Layout.topMargin: 20
FluRadioButtons{
spacing: 8
anchors.verticalCenter: parent.verticalCenter
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluRadioButton{
disabled: radio_button_switch2.checked
text:"Radio Button_1"
}
FluRadioButton{
disabled: radio_button_switch2.checked
text:"Radio Button_2"
}
FluRadioButton{
disabled: radio_button_switch2.checked
text:"Radio Button_3"
}
}
FluToggleSwitch{
id:radio_button_switch2
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text:"Disabled"
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRadioButtons{
spacing: 8
FluRadioButton{
text:"Radio Button_1"
}
FluRadioButton{
text:"Radio Button_2"
}
FluRadioButton{
text:"Radio Button_3"
}
}'
}
}

View File

@ -5,8 +5,10 @@ import QtQuick.Controls
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
FluPage{
pageMode: FluNavigationView.SingleTop
FluRemoteLoader{ FluRemoteLoader{
property int pageMode: FluNavigationView.Standard anchors.fill: parent
property string url: ''
source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml" source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml"
} }
}

View File

@ -13,11 +13,11 @@ FluScrollablePage{
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 20 Layout.topMargin: 20
height: 136 height: 128
paddings: 10 paddings: 10
ColumnLayout{ ColumnLayout{
spacing: 10 spacing: 5
anchors{ anchors{
top: parent.top top: parent.top
left: parent.left left: parent.left
@ -43,16 +43,15 @@ FluScrollablePage{
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 20 Layout.topMargin: 20
height: 168 height: 160
paddings: 10 paddings: 10
ColumnLayout{ ColumnLayout{
spacing: 10 spacing: 5
anchors{ anchors{
top: parent.top top: parent.top
left: parent.left left: parent.left
} }
FluText{ FluText{
text:lang.navigation_view_display_mode text:lang.navigation_view_display_mode
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong

View File

@ -15,7 +15,6 @@ FluScrollablePage{
paddings: 10 paddings: 10
Layout.topMargin: 20 Layout.topMargin: 20
FluSlider{ FluSlider{
value: 50
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
@ -27,17 +26,14 @@ FluScrollablePage{
}' }'
} }
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
height: 200 height: 200
paddings: 10 paddings: 10
Layout.topMargin: 20 Layout.topMargin: 20
FluSlider{ FluSlider{
value: 50 orientation: Qt.Vertical
vertical:true
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 20
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
@ -45,7 +41,7 @@ FluScrollablePage{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1 Layout.topMargin: -1
code:'FluSlider{ code:'FluSlider{
vertical:true orientation: Qt.Vertical
value:50 value:50
}' }'
} }

View File

@ -21,28 +21,27 @@ FluScrollablePage{
id:btn_status_mode id:btn_status_mode
Layout.preferredWidth: 140 Layout.preferredWidth: 140
text:"Loading" text:"Loading"
items:[
FluMenuItem{ FluMenuItem{
text:"Loading" text:"Loading"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Loading status_view.statusMode = FluStatusView.Loading
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Empty" text:"Empty"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Empty status_view.statusMode = FluStatusView.Empty
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Error" text:"Error"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Error status_view.statusMode = FluStatusView.Error
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Success" text:"Success"
onClicked: { onClicked: {
@ -50,7 +49,6 @@ FluScrollablePage{
status_view.statusMode = FluStatusView.Success status_view.statusMode = FluStatusView.Success
} }
} }
]
} }
} }
} }

View File

@ -40,21 +40,20 @@ FluScrollablePage{
id:btn_tab_width_behavior id:btn_tab_width_behavior
Layout.preferredWidth: 140 Layout.preferredWidth: 140
text:"Equal" text:"Equal"
items:[
FluMenuItem{ FluMenuItem{
text:"Equal" text:"Equal"
onClicked: { onClicked: {
btn_tab_width_behavior.text = text btn_tab_width_behavior.text = text
tab_view.tabWidthBehavior = FluTabView.Equal tab_view.tabWidthBehavior = FluTabView.Equal
} }
}, }
FluMenuItem{ FluMenuItem{
text:"SizeToContent" text:"SizeToContent"
onClicked: { onClicked: {
btn_tab_width_behavior.text = text btn_tab_width_behavior.text = text
tab_view.tabWidthBehavior = FluTabView.SizeToContent tab_view.tabWidthBehavior = FluTabView.SizeToContent
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Compact" text:"Compact"
onClicked: { onClicked: {
@ -62,27 +61,25 @@ FluScrollablePage{
tab_view.tabWidthBehavior = FluTabView.Compact tab_view.tabWidthBehavior = FluTabView.Compact
} }
} }
]
} }
FluDropDownButton{ FluDropDownButton{
id:btn_close_button_visibility id:btn_close_button_visibility
text:"Always" text:"Always"
Layout.preferredWidth: 120 Layout.preferredWidth: 120
items:[
FluMenuItem{ FluMenuItem{
text:"Nerver" text:"Nerver"
onClicked: { onClicked: {
btn_close_button_visibility.text = text btn_close_button_visibility.text = text
tab_view.closeButtonVisibility = FluTabView.Nerver tab_view.closeButtonVisibility = FluTabView.Nerver
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Always" text:"Always"
onClicked: { onClicked: {
btn_close_button_visibility.text = text btn_close_button_visibility.text = text
tab_view.closeButtonVisibility = FluTabView.Always tab_view.closeButtonVisibility = FluTabView.Always
} }
}, }
FluMenuItem{ FluMenuItem{
text:"OnHover" text:"OnHover"
onClicked: { onClicked: {
@ -90,7 +87,6 @@ FluScrollablePage{
tab_view.closeButtonVisibility = FluTabView.OnHover tab_view.closeButtonVisibility = FluTabView.OnHover
} }
} }
]
} }
} }
} }

View File

@ -5,141 +5,173 @@ import QtQuick.Window
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
FluScrollablePage{ FluContentPage{
title:"TableView" title:"TableView"
Component.onCompleted: { Component.onCompleted: {
const columns = [ loadData(1,1000)
{
title: '姓名',
dataIndex: 'name',
width:100
},
{
title: '年龄',
dataIndex: 'age',
width:100
},
{
title: '住址',
dataIndex: 'address',
width:200
},
{
title: '别名',
dataIndex: 'nickname',
width:100
},
{
title: '操作',
dataIndex: 'action',
width:120
},
];
table_view.columns = columns
loadData(1,10)
}
FluTableView{
id:table_view
Layout.fillWidth: true
Layout.topMargin: 20
pageCurrent:1
pageCount:10
itemCount: 1000
onRequestPage:
(page,count)=> {
loadData(page,count)
}
} }
Component{ Component{
id:com_action id:com_action
Item{ Item{
Row{ RowLayout{
anchors.centerIn: parent anchors.centerIn: parent
spacing: 10 FluButton{
text:"删除"
onClicked: {
table_view.closeEditor()
tableModel.removeRow(row)
}
}
FluFilledButton{ FluFilledButton{
text:"编辑" text:"编辑"
horizontalPadding: 6
onClicked: { onClicked: {
showSuccess(JSON.stringify(dataObject)) showSuccess(JSON.stringify(tableModel.getRow(row)))
}
}
FluFilledButton{
text:"删除"
horizontalPadding: 6
onClicked:{
showError(JSON.stringify(dataObject))
} }
} }
} }
} }
} }
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: 10
code:'FluTableView{
id:table_view
Layout.fillWidth: true
Layout.topMargin: 20
pageCurrent:1
pageCount:10
itemCount: 1000
onRequestPage:
(page,count)=> {
loadData(page,count)
}
Component.onCompleted: {
const columns = [
{
title: "姓名",
dataIndex: "name",
width:100
},
{
title: "年龄",
dataIndex: "age",
width:100
},
{
title: "住址",
dataIndex: "address",
width:200
},
{
title: "别名",
dataIndex: "nickname",
width:100
}
];
table_view.columns = columns
const dataSource = [
{
name: "孙悟空”,
age: 500,
address:"钟灵毓秀的花果山,如神仙仙境的水帘洞",
nickname:"齐天大圣"
}
];
table_view.dataSource = columns
}
}'
}
function loadData(page,count){ function loadData(page,count){
var numbers = [100, 300, 500, 1000];
function getRandomAge() {
var randomIndex = Math.floor(Math.random() * numbers.length);
return numbers[randomIndex];
}
var names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"];
function getRandomName(){
var randomIndex = Math.floor(Math.random() * names.length);
return names[randomIndex];
}
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
}
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
}
const dataSource = [] const dataSource = []
for(var i=0;i<count;i++){ for(var i=0;i<count;i++){
dataSource.push({ dataSource.push({
name: "孙悟空%1".arg(((page-1)*count+i)), name: getRandomName(),
age: 500, age:getRandomAge(),
address: "钟灵毓秀的花果山,如神仙仙境的水帘洞", address: getRandomAddresses(),
nickname: "齐天大圣", nickname: getRandomNickname(),
longstring:"你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好",
height:44,
minimumHeight:44,
maximumHeight:300,
action:com_action action:com_action
}) })
} }
table_view.dataSource = dataSource table_view.dataSource = dataSource
} }
Component{
id:com_combobox
FluComboBox {
anchors.fill: parent
focus: true
currentIndex: display
editable: true
model: ListModel {
ListElement { text: 100 }
ListElement { text: 300 }
ListElement { text: 500 }
ListElement { text: 1000 }
}
Component.onCompleted: {
currentIndex=[100,300,500,1000].findIndex((element) => element === Number(display))
selectAll()
}
onCommit: {
display = editText
tableView.closeEditor()
}
}
}
FluTableView{
id:table_view
anchors{
left: parent.left
right: parent.right
top: parent.top
bottom: gagination.top
}
anchors.topMargin: 20
columnSource:[
{
title: '姓名',
dataIndex: 'name',
width:100,
minimumWidth:80,
maximumWidth:200,
readOnly:true
},
{
title: '年龄',
dataIndex: 'age',
editDelegate:com_combobox,
width:100,
minimumWidth:100,
maximumWidth:100
},
{
title: '住址',
dataIndex: 'address',
width:200,
minimumWidth:100,
maximumWidth:250
},
{
title: '别名',
dataIndex: 'nickname',
width:100,
minimumWidth:80,
maximumWidth:200
},
{
title: '长字符串',
dataIndex: 'longstring',
width:200,
minimumWidth:100,
maximumWidth:300
},
{
title: '操作',
dataIndex: 'action',
width:160,
minimumWidth:160,
maximumWidth:160
}
]
}
FluPagination{
id:gagination
anchors{
bottom: parent.bottom
left: parent.left
}
pageCurrent: 1
itemCount: 100000
pageButtonCount: 7
__itemPerPage: 1000
onRequestPage:
(page,count)=> {
table_view.closeEditor()
loadData(page,count)
table_view.resetPosition()
}
}
} }

View File

@ -7,8 +7,9 @@ import "qrc:///example/qml/component"
FluScrollablePage{ FluScrollablePage{
title:"TextBox" pageMode: FluNavigationView.SingleInstance
title:"TextBox"
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
height: 68 height: 68
@ -165,6 +166,41 @@ FluScrollablePage{
}' }'
} }
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
FluSpinBox{
Layout.topMargin: 20
// disabled: spin_box_switch.checked
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
}
Row{
spacing: 5
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
}
FluToggleSwitch{
id:spin_box_switch
Layout.alignment: Qt.AlignRight
text:"Disabled"
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluSpinBox{
}'
}
function generateRandomNames(numNames) { function generateRandomNames(numNames) {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

View File

@ -27,6 +27,9 @@ FluScrollablePage{
} }
FluTimePicker{ FluTimePicker{
onCurrentChanged: {
showSuccess(current.toLocaleTimeString(Qt.locale("de_DE")))
}
} }
} }
@ -53,11 +56,14 @@ FluScrollablePage{
} }
FluText{ FluText{
text:"hourFormat=FluTimePicker.H" text:"hourFormat=FluTimePicker.HH"
} }
FluTimePicker{ FluTimePicker{
hourFormat:FluTimePicker.HH hourFormat:FluTimePicker.HH
onCurrentChanged: {
showSuccess(current.toLocaleTimeString(Qt.locale("de_DE")))
}
} }
} }

View File

@ -22,6 +22,12 @@ FluScrollablePage{
} }
FluToggleSwitch{ FluToggleSwitch{
disabled: toggle_switch.checked disabled: toggle_switch.checked
text:"Right"
}
FluToggleSwitch{
disabled: toggle_switch.checked
text:"Left"
textRight: false
} }
} }
FluToggleSwitch{ FluToggleSwitch{

View File

@ -60,21 +60,20 @@ FluScrollablePage {
id:btn_selection_model id:btn_selection_model
Layout.preferredWidth: 140 Layout.preferredWidth: 140
text:"None" text:"None"
items:[
FluMenuItem{ FluMenuItem{
text:"None" text:"None"
onClicked: { onClicked: {
btn_selection_model.text = text btn_selection_model.text = text
tree_view.selectionMode = FluTabView.Equal tree_view.selectionMode = FluTabView.Equal
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Single" text:"Single"
onClicked: { onClicked: {
btn_selection_model.text = text btn_selection_model.text = text
tree_view.selectionMode = FluTabView.SizeToContent tree_view.selectionMode = FluTabView.SizeToContent
} }
}, }
FluMenuItem{ FluMenuItem{
text:"Muiltple" text:"Muiltple"
onClicked: { onClicked: {
@ -82,7 +81,6 @@ FluScrollablePage {
tree_view.selectionMode = FluTabView.Compact tree_view.selectionMode = FluTabView.Compact
} }
} }
]
} }
FluFilledButton{ FluFilledButton{
text:"获取选中的数据" text:"获取选中的数据"

View File

@ -10,10 +10,6 @@ FluContentPage {
title: "Typography" title: "Typography"
rightPadding: 10 rightPadding: 10
Component.onCompleted: {
slider.seek(0)
}
FluArea{ FluArea{
anchors{ anchors{
top:parent.top top:parent.top
@ -73,7 +69,7 @@ FluContentPage {
FluSlider{ FluSlider{
id:slider id:slider
vertical:true orientation: Qt.Vertical
anchors{ anchors{
right: parent.right right: parent.right
rightMargin: 45 rightMargin: 45

View File

@ -4,6 +4,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Qt.labs.platform import Qt.labs.platform
import FluentUI import FluentUI
import example
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "qrc:///example/qml/global" import "qrc:///example/qml/global"
@ -112,6 +113,12 @@ CustomWindow {
} }
Row{ Row{
z:8 z:8
anchors{
top: parent.top
left: parent.left
topMargin: FluTools.isMacos() ? 20 : 5
leftMargin: 5
}
FluIconButton{ FluIconButton{
iconSource: FluentIcons.ChromeBack iconSource: FluentIcons.ChromeBack
width: 30 width: 30
@ -134,6 +141,7 @@ CustomWindow {
FluRemoteLoader{ FluRemoteLoader{
id:loader id:loader
lazy: true
anchors.fill: parent anchors.fill: parent
// source: "http://localhost:9000/RemoteComponent.qml" // source: "http://localhost:9000/RemoteComponent.qml"
source: "https://zhu-zichu.gitee.io/RemoteComponent.qml" source: "https://zhu-zichu.gitee.io/RemoteComponent.qml"
@ -200,54 +208,12 @@ CustomWindow {
} }
} }
Image{ CircularReveal{
id:img_cache id:reveal
visible: false target:window.contentItem
anchors.fill: parent anchors.fill: parent
} onImageChanged: {
changeDark()
Canvas{
id:canvas
anchors.fill: parent
property int centerX: canvas.width / 2
property int centerY: canvas.height / 2
property real radius: 0
property int maxRadius: 0
property url imageUrl
Behavior on radius{
id:anim_radius
NumberAnimation {
target: canvas
property: "radius"
duration: 666
easing.type: Easing.OutCubic
}
}
onRadiusChanged: {
canvas.requestPaint()
}
onPaint: {
var ctx = canvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvasSize.width, canvasSize.height);
ctx.save()
if(img_cache.source.toString().length!==0){
try{
ctx.drawImage(img_cache, 0, 0, canvasSize.width, canvasSize.height, 0, 0, canvasSize.width, canvasSize.height)
}catch(e){
img_cache.source = ""
}
}
clearArc(ctx, centerX, centerY, radius)
ctx.restore()
}
function clearArc(ctx,x, y, radius, startAngle, endAngle) {
ctx.beginPath()
ctx.globalCompositeOperation = 'destination-out'
ctx.fillStyle = 'black'
ctx.arc(x, y, radius, 0, 2*Math.PI);
ctx.fill();
ctx.closePath();
} }
} }
@ -256,32 +222,23 @@ CustomWindow {
} }
function handleDarkChanged(button){ function handleDarkChanged(button){
var changeDark = function(){ if(FluTools.isMacos()){
if(FluTheme.dark){ changeDark()
FluTheme.darkMode = FluDarkMode.Light
}else{ }else{
FluTheme.darkMode = FluDarkMode.Dark
}
}
if(FluTools.isWin()){
var target = window.contentItem var target = window.contentItem
var pos = button.mapToItem(target,0,0) var pos = button.mapToItem(target,0,0)
var mouseX = pos.x var mouseX = pos.x
var mouseY = pos.y var mouseY = pos.y
canvas.maxRadius = Math.max(distance(mouseX,mouseY,0,0),distance(mouseX,mouseY,target.width,0),distance(mouseX,mouseY,0,target.height),distance(mouseX,mouseY,target.width,target.height)) var radius = Math.max(distance(mouseX,mouseY,0,0),distance(mouseX,mouseY,target.width,0),distance(mouseX,mouseY,0,target.height),distance(mouseX,mouseY,target.width,target.height))
target.grabToImage(function(result) { reveal.start(reveal.width*Screen.devicePixelRatio,reveal.height*Screen.devicePixelRatio,Qt.point(mouseX,mouseY),radius)
img_cache.source = result.url }
canvas.requestPaint() }
changeDark()
canvas.centerX = mouseX function changeDark(){
canvas.centerY = mouseY if(FluTheme.dark){
anim_radius.enabled = false FluTheme.darkMode = FluDarkMode.Light
canvas.radius = 0
anim_radius.enabled = true
canvas.radius = canvas.maxRadius
},canvas.canvasSize)
}else{ }else{
changeDark() FluTheme.darkMode = FluDarkMode.Dark
} }
} }

View File

@ -1,30 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
import "qrc:///example/qml/component"
CustomWindow {
title:"视频播放器"
width: 640
height: 480
minimumWidth: 640
minimumHeight: 480
onInitArgument:
(argument)=>{
player.source = argument.source
}
FluMediaPlayer{
id:player
anchors{
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
}
}
}

View File

@ -13,6 +13,28 @@ CustomWindow {
fixSize: true fixSize: true
launchMode: FluWindow.Standard launchMode: FluWindow.Standard
FluMenuBar {
FluMenu {
title: qsTr("File")
Action { text: qsTr("New...") }
Action { text: qsTr("Open...") }
Action { text: qsTr("Save") }
Action { text: qsTr("Save As...") }
FluMenuSeparator { }
Action { text: qsTr("Quit") }
}
FluMenu {
title: qsTr("Edit")
Action { text: qsTr("Cut") }
Action { text: qsTr("Copy") }
Action { text: qsTr("Paste") }
}
FluMenu {
title: qsTr("Help")
Action { text: qsTr("About") }
}
}
FluText{ FluText{
anchors.centerIn: parent anchors.centerIn: parent
text:"我是一个Standard模式的窗口每次我都会创建一个新的窗口" text:"我是一个Standard模式的窗口每次我都会创建一个新的窗口"

View File

@ -0,0 +1,45 @@
#include "CircularReveal.h"
#include <QGuiApplication>
#include <QQuickItemGrabResult>
#include <QPainterPath>
CircularReveal::CircularReveal(QQuickItem* parent) : QQuickPaintedItem(parent)
{
_anim = new QPropertyAnimation(this, "radius", this);
_anim->setDuration(333);
_anim->setEasingCurve(QEasingCurve::OutCubic);
connect(_anim, &QPropertyAnimation::finished,this,[=](){
setVisible(false);
});
connect(this,&CircularReveal::radiusChanged,this,[=](){
update();
});
}
void CircularReveal::paint(QPainter* painter)
{
painter->save();
painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), _source);
QPainterPath path;
path.moveTo(_center.x(),_center.y());
path.addEllipse(QPointF(_center.x(),_center.y()), _radius, _radius);
painter->setCompositionMode(QPainter::CompositionMode_Clear);
painter->fillPath(path, Qt::black);
painter->restore();
}
void CircularReveal::start(int w,int h,const QPoint& center,int radius){
_anim->setStartValue(0);
_anim->setEndValue(radius);
_center = center;
_grabResult = _target->grabToImage(QSize(w,h));
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult);
}
void CircularReveal::handleGrabResult(){
_grabResult.data()->image().swap(_source);
update();
setVisible(true);
Q_EMIT imageChanged();
_anim->start();
}

View File

@ -0,0 +1,28 @@
#ifndef CIRCULARREVEAL_H
#define CIRCULARREVEAL_H
#include <QQuickItem>
#include <QQuickPaintedItem>
#include <QPainter>
#include <QPropertyAnimation>
#include "src/stdafx.h"
class CircularReveal : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY_AUTO(QQuickItem*,target)
Q_PROPERTY_AUTO(int,radius)
public:
CircularReveal(QQuickItem* parent = nullptr);
void paint(QPainter* painter) override;
Q_INVOKABLE void start(int w,int h,const QPoint& center,int radius);
Q_SIGNAL void imageChanged();
Q_SLOT void handleGrabResult();
private:
QImage _source;
QPropertyAnimation* _anim;
QPoint _center;
QSharedPointer<QQuickItemGrabResult> _grabResult;
};
#endif // CIRCULARREVEAL_H

View File

@ -6,6 +6,7 @@
#include <QProcess> #include <QProcess>
#include <FramelessHelper/Quick/framelessquickmodule.h> #include <FramelessHelper/Quick/framelessquickmodule.h>
#include <FramelessHelper/Core/private/framelessconfig_p.h> #include <FramelessHelper/Core/private/framelessconfig_p.h>
#include "src/component/CircularReveal.h"
#include "AppInfo.h" #include "AppInfo.h"
FRAMELESSHELPER_USE_NAMESPACE FRAMELESSHELPER_USE_NAMESPACE
@ -37,6 +38,8 @@ int main(int argc, char *argv[])
app.setQuitOnLastWindowClosed(false); app.setQuitOnLastWindowClosed(false);
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
FramelessHelper::Quick::registerTypes(&engine); FramelessHelper::Quick::registerTypes(&engine);
qmlRegisterType<CircularReveal>("example", 1, 0, "CircularReveal");
appInfo->init(&engine); appInfo->init(&engine);
const QUrl url(QStringLiteral("qrc:/example/qml/App.qml")); const QUrl url(QStringLiteral("qrc:/example/qml/App.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,

View File

@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.20)
project(fluentuiplugin LANGUAGES CXX) project(fluentuiplugin LANGUAGES CXX)
#配置通用编译 #配置通用编译
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE) if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
@ -13,9 +12,17 @@ endif()
set(QML_PLUGIN_DIRECTORY ${CMAKE_PREFIX_PATH}/qml/FluentUI) set(QML_PLUGIN_DIRECTORY ${CMAKE_PREFIX_PATH}/qml/FluentUI)
#设置版本号 #设置版本号
add_definitions(-DVERSION=1,3,3,0) add_definitions(-DVERSION=1,3,7,1)
find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml ShaderTools) find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml)
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
qt_standard_project_setup()
else()
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
endif()
#遍历所有Cpp文件 #遍历所有Cpp文件
file(GLOB_RECURSE CPP_FILES *.cpp *.h) file(GLOB_RECURSE CPP_FILES *.cpp *.h)
@ -32,7 +39,7 @@ foreach(filepath ${QML_PATHS})
endforeach(filepath) endforeach(filepath)
#遍历所有资源文件 #遍历所有资源文件
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp *.qsb *.metainfo) file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp)
foreach(filepath ${RES_PATHS}) foreach(filepath ${RES_PATHS})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND resource_files ${filename}) list(APPEND resource_files ${filename})
@ -57,8 +64,6 @@ qt_add_qml_module(fluentuiplugin
SOURCES ${sources_files} fluentui.rc SOURCES ${sources_files} fluentui.rc
QML_FILES ${qml_files} QML_FILES ${qml_files}
RESOURCES ${resource_files} RESOURCES ${resource_files}
#支持designer
DESIGNER_SUPPORTED
) )
#链接库 #链接库
@ -68,15 +73,5 @@ target_link_libraries(fluentuiplugin PUBLIC
Qt::QmlPrivate Qt::QmlPrivate
) )
#链接库 win32库 不然mingw会编译错误 #安装
if(WIN32) install(DIRECTORY ${QML_PLUGIN_DIRECTORY} DESTINATION ${CMAKE_INSTALL_PREFIX}/imports)
target_link_libraries(fluentuiplugin PRIVATE dwmapi user32)
endif()
#如果是debug则生成的库文件名后面拼接d
# 在MinGW和GCC/Clang中, 默认不会链接带`d`后缀的动态库
if(MSVC)
set_target_properties(fluentuiplugin PROPERTIES DEBUG_POSTFIX "d")
endif(MSVC)

View File

@ -38,11 +38,15 @@ void FluApp::run(){
void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegister* fluRegister){ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegister* fluRegister){
if(!routes().contains(route)){ if(!routes().contains(route)){
qErrnoWarning("没有找到当前路由"); qCritical()<<"No route found "<<route;
return; return;
} }
QQmlEngine *engine = qmlEngine(appWindow); QQmlEngine *engine = qmlEngine(appWindow);
QQmlComponent component(engine, routes().value(route).toString()); QQmlComponent component(engine, routes().value(route).toString());
if (component.isError()) {
qCritical() << component.errors();
return;
}
QVariantMap properties; QVariantMap properties;
properties.insert("route",route); properties.insert("route",route);
if(fluRegister){ if(fluRegister){
@ -105,3 +109,11 @@ QJsonArray FluApp::awesomelist(const QString& keyword)
void FluApp::closeApp(){ void FluApp::closeApp(){
qApp->exit(0); qApp->exit(0);
} }
void FluApp::deleteWindow(QQuickWindow* window){
if(window){
wnds.remove(window->winId());
window->deleteLater();
window = nullptr;
}
}

View File

@ -73,6 +73,8 @@ public:
*/ */
Q_INVOKABLE void closeApp(); Q_INVOKABLE void closeApp();
Q_INVOKABLE void deleteWindow(QQuickWindow* window);
public: public:
/** /**
* @brief wnds * @brief wnds

View File

@ -8,7 +8,7 @@ FluTextStyle::FluTextStyle(QObject *parent)
Caption(caption); Caption(caption);
QFont body; QFont body;
body.setPixelSize(14); body.setPixelSize(13);
Body(body); Body(body);
QFont bodyStrong; QFont bodyStrong;

View File

@ -2,6 +2,7 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QClipboard> #include <QClipboard>
#include <QUuid> #include <QUuid>
#include <QCursor>
FluTools* FluTools::m_instance = nullptr; FluTools* FluTools::m_instance = nullptr;
@ -63,6 +64,33 @@ bool FluTools::isWin(){
#endif #endif
} }
int FluTools::qtMajor(){
const QString qtVersion = QString::fromLatin1(qVersion());
const QStringList versionParts = qtVersion.split('.');
return versionParts[0].toInt();
}
int FluTools::qtMinor(){
const QString qtVersion = QString::fromLatin1(qVersion());
const QStringList versionParts = qtVersion.split('.');
return versionParts[1].toInt();
}
void FluTools::setQuitOnLastWindowClosed(bool val){ void FluTools::setQuitOnLastWindowClosed(bool val){
qApp->setQuitOnLastWindowClosed(val); qApp->setQuitOnLastWindowClosed(val);
} }
void FluTools::setOverrideCursor(Qt::CursorShape shape){
qApp->setOverrideCursor(QCursor(shape));
}
void FluTools::restoreOverrideCursor(){
qApp->restoreOverrideCursor();
}
void FluTools::deleteItem(QObject *p){
if(p){
delete p;
p = nullptr;
}
}

View File

@ -50,6 +50,15 @@ public:
Q_INVOKABLE void setQuitOnLastWindowClosed(bool val); Q_INVOKABLE void setQuitOnLastWindowClosed(bool val);
Q_INVOKABLE int qtMajor();
Q_INVOKABLE int qtMinor();
Q_INVOKABLE void setOverrideCursor(Qt::CursorShape shape);
Q_INVOKABLE void restoreOverrideCursor();
Q_INVOKABLE void deleteItem(QObject *p);
}; };
#endif // FLUTOOLS_H #endif // FLUTOOLS_H

View File

@ -1,7 +1,6 @@
#include "WindowHelper.h" #include "WindowHelper.h"
#include "FluRegister.h" #include "FluRegister.h"
#include "FluApp.h"
WindowHelper::WindowHelper(QObject *parent) WindowHelper::WindowHelper(QObject *parent)
: QObject{parent} : QObject{parent}
@ -19,10 +18,3 @@ QVariant WindowHelper::createRegister(QQuickWindow* window,const QString& path){
p->path(path); p->path(path);
return QVariant::fromValue(p); return QVariant::fromValue(p);
} }
void WindowHelper::deleteWindow(){
if(this->window){
FluApp::getInstance()->wnds.remove(this->window->winId());
this->window->deleteLater();
}
}

View File

@ -24,11 +24,6 @@ public:
*/ */
Q_INVOKABLE void initWindow(QQuickWindow* window); Q_INVOKABLE void initWindow(QQuickWindow* window);
/**
* @brief deleteWindow 销毁窗口释放资源QML中的Window close并不会销毁窗口只是把窗口隐藏了
*/
Q_INVOKABLE void deleteWindow();
/** /**
* @brief createRegister 创建一个FluRegsiter对象在FluWindow中registerForWindowResult方法调用 * @brief createRegister 创建一个FluRegsiter对象在FluWindow中registerForWindowResult方法调用
* @param window * @param window

View File

@ -76,21 +76,17 @@ Rectangle{
anchors.right: parent.right anchors.right: parent.right
height: root.height height: root.height
spacing: 0 spacing: 0
RowLayout{ FluToggleSwitch{
id:btn_dark
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: 5 Layout.rightMargin: 5
visible: showDark visible: showDark
spacing: 5
FluText{
text:darkText text:darkText
color:root.textColor textColor:root.textColor
}
FluToggleSwitch{
id:btn_dark
checked: FluTheme.dark checked: FluTheme.dark
textRight: false
clickListener:()=> darkClickListener(btn_dark) clickListener:()=> darkClickListener(btn_dark)
} }
}
FluIconButton{ FluIconButton{
id:btn_minimize id:btn_minimize
width: 40 width: 40
@ -147,4 +143,8 @@ Rectangle{
return btn_close return btn_close
} }
function darkButton(){
return btn_dark
}
} }

View File

@ -4,8 +4,9 @@ import FluentUI
Rectangle{ Rectangle{
property bool isDot: false property bool isDot: false
property bool showZero: true property bool showZero: false
property int count: 0 property int count: 0
property bool topRight: false
id:control id:control
color:Qt.rgba(255/255,77/255,79/255,1) color:Qt.rgba(255/255,77/255,79/255,1)
width: { width: {
@ -30,34 +31,40 @@ Rectangle{
} }
border.width: 1 border.width: 1
border.color: Qt.rgba(1,1,1,1) border.color: Qt.rgba(1,1,1,1)
visible: {
if(showZero)
return true
return count!==0
}
anchors{ anchors{
right: { right: {
if(parent) if(parent && topRight)
return parent.right return parent.right
return undefined return undefined
} }
top: { top: {
if(parent) if(parent && topRight)
return parent.top return parent.top
return undefined return undefined
} }
rightMargin: { rightMargin: {
if(parent && topRight){
if(isDot){ if(isDot){
return -2.5 return -2.5
} }
return -(control.width/2) return -(control.width/2)
} }
return 0
}
topMargin: { topMargin: {
if(parent && topRight){
if(isDot){ if(isDot){
return -2.5 return -2.5
} }
return -10 return -10
} }
return 0
}
}
visible: {
if(showZero)
return true
return count!==0
} }
Text{ Text{
anchors.centerIn: parent anchors.centerIn: parent

View File

@ -11,7 +11,7 @@ Button {
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 color textColor: { property color textColor: {
if(FluTheme.dark){ if(FluTheme.dark){
if(disabled){ if(!enabled){
return Qt.rgba(131/255,131/255,131/255,1) return Qt.rgba(131/255,131/255,131/255,1)
} }
if(pressed){ if(pressed){
@ -19,7 +19,7 @@ Button {
} }
return Qt.rgba(1,1,1,1) return Qt.rgba(1,1,1,1)
}else{ }else{
if(disabled){ if(!enabled){
return Qt.rgba(160/255,160/255,160/255,1) return Qt.rgba(160/255,160/255,160/255,1)
} }
if(pressed){ if(pressed){
@ -44,7 +44,7 @@ Button {
border.width: 1 border.width: 1
radius: 4 radius: 4
color:{ color:{
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
return hovered ? hoverColor :normalColor return hovered ? hoverColor :normalColor

View File

@ -243,8 +243,6 @@ Item {
} }
FluTextButton{ FluTextButton{
id:title id:title
leftPadding: 0
rightPadding: 0
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left

View File

@ -19,6 +19,10 @@ Button {
property color checkedPreesedColor: FluTheme.dark ? Qt.darker(checkedColor,1.3) : Qt.lighter(checkedColor,1.3) property color checkedPreesedColor: FluTheme.dark ? Qt.darker(checkedColor,1.3) : Qt.lighter(checkedColor,1.3)
property color checkedDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1) property color checkedDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
property color disableColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1) property color disableColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1)
property real size: 18
property alias textColor: btn_text.textColor
property bool textRight: true
property real textSpacing: 6
property var clickListener : function(){ property var clickListener : function(){
checked = !checked checked = !checked
} }
@ -39,13 +43,14 @@ Button {
Accessible.onPressAction: control.clicked() Accessible.onPressAction: control.clicked()
focusPolicy:Qt.TabFocus focusPolicy:Qt.TabFocus
contentItem: RowLayout{ contentItem: RowLayout{
spacing: 4 spacing: control.textSpacing
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
Rectangle{ Rectangle{
width: 20 width: control.size
height: 20 height: control.size
radius: 4 radius: 4
border.color: { border.color: {
if(disabled){ if(!enabled){
return borderDisableColor return borderDisableColor
} }
if(checked){ if(checked){
@ -62,7 +67,7 @@ Button {
border.width: 1 border.width: 1
color: { color: {
if(checked){ if(checked){
if(disabled){ if(!enabled){
return checkedDisableColor return checkedDisableColor
} }
if(pressed){ if(pressed){
@ -73,7 +78,7 @@ Button {
} }
return checkedColor return checkedColor
} }
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
if(hovered){ if(hovered){
@ -100,8 +105,9 @@ Button {
} }
} }
FluText{ FluText{
id:btn_text
text: control.text text: control.text
Layout.leftMargin: 5 Layout.alignment: Qt.AlignVCenter
visible: text !== "" visible: text !== ""
} }
} }

View File

@ -6,6 +6,7 @@ import QtQuick.Templates as T
ComboBox { ComboBox {
id: control id: control
signal commit
property bool disabled: false property bool disabled: false
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)
@ -24,7 +25,6 @@ ComboBox {
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
palette.text: control.palette.text palette.text: control.palette.text
palette.highlightedText: control.palette.highlightedText palette.highlightedText: control.palette.highlightedText
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: control.highlightedIndex === index highlighted: control.highlightedIndex === index
hoverEnabled: control.hoverEnabled hoverEnabled: control.hoverEnabled
} }
@ -37,7 +37,6 @@ ComboBox {
iconSize: 15 iconSize: 15
opacity: enabled ? 1 : 0.3 opacity: enabled ? 1 : 0.3
} }
contentItem: T.TextField { contentItem: T.TextField {
property bool disabled: !control.editable property bool disabled: !control.editable
leftPadding: !control.mirrored ? 12 : control.editable && activeFocus ? 3 : 1 leftPadding: !control.mirrored ? 12 : control.editable && activeFocus ? 3 : 1
@ -45,7 +44,8 @@ ComboBox {
topPadding: 6 - control.padding topPadding: 6 - control.padding
bottomPadding: 6 - control.padding bottomPadding: 6 - control.padding
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTheme.primaryColor.lightest selectionColor: Qt.alpha(FluTheme.primaryColor.lightest,0.6)
selectedTextColor: color
text: control.editable ? control.editText : control.displayText text: control.editable ? control.editText : control.displayText
enabled: control.editable enabled: control.editable
autoScroll: control.editable autoScroll: control.editable
@ -64,17 +64,25 @@ ComboBox {
border.width: 0 border.width: 0
inputItem: contentItem inputItem: contentItem
} }
Component.onCompleted: {
forceActiveFocus()
}
Keys.onEnterPressed: (event)=> handleCommit(event)
Keys.onReturnPressed:(event)=> handleCommit(event)
function handleCommit(event){
control.commit()
}
} }
background: Rectangle { background: Rectangle {
implicitWidth: 140 implicitWidth: 140
implicitHeight: 28 implicitHeight: 32
border.color: FluTheme.dark ? "#505050" : "#DFDFDF" border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
border.width: 1 border.width: 1
visible: !control.flat || control.down visible: !control.flat || control.down
radius: 4 radius: 4
FluFocusRectangle{ FluFocusRectangle{
visible: control.activeFocus visible: control.visualFocus
radius:4 radius:4
anchors.margins: -2 anchors.margins: -2
} }

View File

@ -4,20 +4,18 @@ import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import FluentUI import FluentUI
Item { FluPage {
property alias title: text_title.text property alias title: text_title.text
default property alias content: container.data default property alias content: container.data
property int leftPadding: 10 property int leftPadding: 10
property int topPadding: 0 property int topPadding: 0
property int rightPadding: 10 property int rightPadding: 10
property int bottomPadding: 10 property int bottomPadding: 10
property int pageMode: FluNavigationView.Standard
property string url: ''
id:control id:control
FluText{ FluText{
id:text_title id:text_title
visible: text !== "" visible: text !== ""
height: visible ? implicitHeight : 0 height: visible ? contentHeight : 0
font: FluTextStyle.Title font: FluTextStyle.Title
anchors{ anchors{
top: parent.top top: parent.top

View File

@ -14,12 +14,19 @@ TextEdit {
leftPadding: 0 leftPadding: 0
rightPadding: 0 rightPadding: 0
topPadding: 0 topPadding: 0
selectByMouse: true
selectedTextColor: color
bottomPadding: 0 bottomPadding: 0
selectionColor: FluTheme.primaryColor.lightest selectionColor: Qt.alpha(FluTheme.primaryColor.lightest,0.6)
font:FluTextStyle.Body font:FluTextStyle.Body
TapHandler { onSelectedTextChanged: {
control.forceActiveFocus()
}
MouseArea{
anchors.fill: parent
cursorShape: Qt.IBeamCursor
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
onTapped: control.echoMode !== TextInput.Password && menu.popup() onClicked: control.echoMode !== TextInput.Password && menu.popup()
} }
FluTextBoxMenu{ FluTextBoxMenu{
id:menu id:menu

View File

@ -8,11 +8,9 @@ Rectangle {
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1) property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/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 normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
property var window : Window.window
property bool showYear: true property bool showYear: true
property bool changeFlag: true property var current
readonly property var rowData: ["","",""] id:control
id:root
color: { color: {
if(mouse_area.containsMouse){ if(mouse_area.containsMouse){
return hoverColor return hoverColor
@ -24,6 +22,13 @@ Rectangle {
radius: 4 radius: 4
border.width: 1 border.width: 1
border.color: dividerColor border.color: dividerColor
Item{
id:d
property var window: Window.window
property bool changeFlag: true
property var rowData: ["","",""]
visible: false
}
MouseArea{ MouseArea{
id:mouse_area id:mouse_area
hoverEnabled: true hoverEnabled: true
@ -317,8 +322,19 @@ Rectangle {
} }
text: "确定" text: "确定"
onClicked: { onClicked: {
changeFlag = false d.changeFlag = false
popup.close() popup.close()
const year = text_year.text
const month = text_month.text
const day = text_day.text
const date = new Date()
date.setFullYear(parseInt(year));
date.setMonth(parseInt(month) - 1);
date.setDate(parseInt(day));
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
current = date
} }
} }
} }
@ -326,10 +342,10 @@ Rectangle {
} }
y:35 y:35
function showPopup() { function showPopup() {
changeFlag = true d.changeFlag = true
rowData[0] = text_year.text d.rowData[0] = text_year.text
rowData[1] = text_month.text d.rowData[1] = text_month.text
rowData[2] = text_day.text d.rowData[2] = text_day.text
const now = new Date(); const now = new Date();
var year = text_year.text === "年"? now.getFullYear() : Number(text_year.text); var year = text_year.text === "年"? now.getFullYear() : Number(text_year.text);
var month = text_month.text === "月"? now.getMonth() + 1 : Number(text_month.text); var month = text_month.text === "月"? now.getMonth() + 1 : Number(text_month.text);
@ -342,21 +358,21 @@ Rectangle {
list_view_3.model = generateMonthDaysArray(year,month) list_view_3.model = generateMonthDaysArray(year,month)
list_view_3.currentIndex = list_view_3.model.indexOf(day) list_view_3.currentIndex = list_view_3.model.indexOf(day)
text_day.text = day text_day.text = day
var pos = root.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(window.height>pos.y+root.height+container.height){ if(d.window.height>pos.y+control.height+container.height){
popup.y = root.height popup.y = control.height
} else if(pos.y>container.height){ } else if(pos.y>container.height){
popup.y = -container.height popup.y = -container.height
} else { } else {
popup.y = window.height-(pos.y+container.height) popup.y = d.window.height-(pos.y+container.height)
} }
popup.open() popup.open()
} }
onClosed: { onClosed: {
if(changeFlag){ if(d.changeFlag){
text_year.text = rowData[0] text_year.text = d.rowData[0]
text_month.text = rowData[1] text_month.text = d.rowData[1]
text_day.text = rowData[2] text_day.text = d.rowData[2]
} }
} }
} }

View File

@ -3,5 +3,5 @@ import QtQuick.Window
import FluentUI import FluentUI
Rectangle { Rectangle {
color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,230/255,234/255,1) color: FluTheme.dark ? Qt.rgba(60/255,60/255,60/255,1) : Qt.rgba(210/255,210/255,210/255,1)
} }

View File

@ -12,7 +12,7 @@ Button {
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 color textColor: { property color textColor: {
if(FluTheme.dark){ if(FluTheme.dark){
if(disabled){ if(!enabled){
return Qt.rgba(131/255,131/255,131/255,1) return Qt.rgba(131/255,131/255,131/255,1)
} }
if(pressed){ if(pressed){
@ -20,7 +20,7 @@ Button {
} }
return Qt.rgba(1,1,1,1) return Qt.rgba(1,1,1,1)
}else{ }else{
if(disabled){ if(!enabled){
return Qt.rgba(160/255,160/255,160/255,1) return Qt.rgba(160/255,160/255,160/255,1)
} }
if(pressed){ if(pressed){
@ -30,7 +30,7 @@ Button {
} }
} }
property var window : Window.window property var window : Window.window
property alias items: menu.content default property alias contentData: menu.contentData
Accessible.role: Accessible.Button Accessible.role: Accessible.Button
Accessible.name: control.text Accessible.name: control.text
Accessible.description: contentDescription Accessible.description: contentDescription
@ -51,7 +51,7 @@ Button {
radius:8 radius:8
} }
color:{ color:{
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
return hovered ? hoverColor :normalColor return hovered ? hoverColor :normalColor
@ -75,9 +75,9 @@ Button {
color: control.textColor color: control.textColor
} }
onClicked: { onClicked: {
if(items && menu.getContainerCount()!==0){ if(items && menu.count !==0){
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
var containerHeight = menu.getContainerHeight() var containerHeight = menu.count*36
if(window.height>pos.y+control.height+containerHeight){ if(window.height>pos.y+control.height+containerHeight){
menu.y = control.height menu.y = control.height
}else if(pos.y>containerHeight){ }else if(pos.y>containerHeight){
@ -90,6 +90,7 @@ Button {
} }
FluMenu{ FluMenu{
id:menu id:menu
modal:true
width: control.width width: control.width
} }
} }

View File

@ -57,7 +57,7 @@ Item {
iconSize: 15 iconSize: 15
Behavior on rotation { Behavior on rotation {
NumberAnimation{ NumberAnimation{
duration: 150 duration: 167
} }
} }
} }
@ -79,8 +79,7 @@ Item {
Behavior on height { Behavior on height {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 167
easing.type: Easing.BezierSpline easing.type: Easing.InCubic
easing.bezierCurve: expand ? [ 0, 0, 0, 1 ] : [ 1, 0, 0, 0 ]
} }
} }
} }

View File

@ -12,7 +12,7 @@ Button {
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2) property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)
property color textColor: { property color textColor: {
if(FluTheme.dark){ if(FluTheme.dark){
if(disabled){ if(!enabled){
return Qt.rgba(173/255,173/255,173/255,1) return Qt.rgba(173/255,173/255,173/255,1)
} }
return Qt.rgba(0,0,0,1) return Qt.rgba(0,0,0,1)
@ -38,7 +38,7 @@ Button {
radius:4 radius:4
} }
color:{ color:{
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
if(pressed){ if(pressed){

View File

@ -0,0 +1,27 @@
import QtQuick
import QtQuick.Templates as T
import FluentUI
T.HorizontalHeaderView {
id: control
implicitWidth: syncView ? syncView.width : 0
implicitHeight: Math.max(1, contentHeight)
delegate: Rectangle {
readonly property real cellPadding: 8
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, 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)
border.color: FluTheme.dark ? "#252525" : "#e4e4e4"
FluText {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
: modelData
width: parent.width
height: parent.height
font.bold: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}

View File

@ -9,12 +9,12 @@ Button {
property bool disabled: false property bool disabled: false
property int radius:4 property int radius:4
property string contentDescription: "" property string contentDescription: ""
property color hoverColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(0,0,0,0.03) property color hoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
property color pressedColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(0,0,0,0.06) property color pressedColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
property color normalColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) property color normalColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
property color disableColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) property color disableColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
property color color: { property color color: {
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
if(pressed){ if(pressed){
@ -24,12 +24,12 @@ Button {
} }
property color iconColor: { property color iconColor: {
if(FluTheme.dark){ if(FluTheme.dark){
if(disabled){ if(!enabled){
return Qt.rgba(130/255,130/255,130/255,1) return Qt.rgba(130/255,130/255,130/255,1)
} }
return Qt.rgba(1,1,1,1) return Qt.rgba(1,1,1,1)
}else{ }else{
if(disabled){ if(!enabled){
return Qt.rgba(161/255,161/255,161/255,1) return Qt.rgba(161/255,161/255,161/255,1)
} }
return Qt.rgba(0,0,0,1) return Qt.rgba(0,0,0,1)

View File

@ -0,0 +1,44 @@
import QtQuick
import QtQuick.Controls
import FluentUI
Item {
property alias sourceSize : image.sourceSize
property alias fillMode : image.fillMode
property url source
property string errorButtonText: "重新加载"
property var status
property var clickErrorListener : function(){
image.source = ""
image.source = control.source
}
id: control
Image{
id:image
anchors.fill: parent
source: control.source
opacity: control.status === Image.Ready
onStatusChanged:{
control.status = image.status
}
Behavior on opacity {
NumberAnimation{
duration: 83
}
}
}
Rectangle{
anchors.fill: parent
color: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
FluProgressRing{
anchors.centerIn: parent
visible: control.status === Image.Loading
}
FluFilledButton{
text: control.errorButtonText
anchors.centerIn: parent
visible: control.status === Image.Error
onClicked: clickErrorListener()
}
}
}

View File

@ -1,202 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtMultimedia
import FluentUI
Rectangle {
property url source
property bool showControl: false
property real volume: 30
id:control
width: 480
height: 270
color: FluColors.Black
clip: true
MouseArea{
anchors.fill: parent
preventStealing: true
onClicked: {
showControl = !showControl
}
}
MediaPlayer {
id: mediaplayer
property bool autoSeek:true
source: control.source
videoOutput: video_output
audioOutput: AudioOutput{
id:audio_output
}
onErrorStringChanged:
(error)=> {
console.debug(errorString)
}
onPositionChanged: {
if(autoSeek){
slider.seek(mediaplayer.position*slider.maxValue/mediaplayer.duration)
}
}
onMediaStatusChanged:
(status)=> {
if(status===2){
slider.maxValue = mediaplayer.duration
showControl = true
mediaplayer.play()
}
}
}
onSourceChanged: {
slider.seek(0)
}
VideoOutput {
id:video_output
anchors.fill: parent
}
Item{
height: 100
y:showControl ? control.height - 110 : control.height
anchors{
horizontalCenter: parent.horizontalCenter
}
width: 460
opacity: showControl
MouseArea{
anchors.fill: parent
}
Behavior on opacity{
NumberAnimation{
duration: 150
}
}
Behavior on y{
NumberAnimation{
duration: 150
}
}
Rectangle{
anchors.fill: parent
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
radius: 5
}
FluSlider{
id:slider
size:parent.width-20
y:20
anchors.horizontalCenter: parent.horizontalCenter
tipEnabled:false
onPressed: {
mediaplayer.autoSeek = false
mediaplayer.pause()
}
value:mediaplayer.position
onReleased: {
mediaplayer.autoSeek = true
mediaplayer.play()
}
onValueChanged: {
if(mediaplayer.autoSeek == false){
mediaplayer.position = value*mediaplayer.duration/slider.maxValue
}
}
onLineClickFunc:function(val){
mediaplayer.position = val*mediaplayer.duration/slider.maxValue
}
}
FluText{
id:start_time
anchors{
top: slider.bottom
topMargin: 10
left: slider.left
}
text: formatDuration(slider.value*mediaplayer.duration/slider.maxValue)
}
FluText{
id:end_time
anchors{
top: slider.bottom
right: slider.right
topMargin: 10
}
text: formatDuration(mediaplayer.duration)
}
Row{
spacing: 10
anchors{
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 10
}
FluIconButton{
iconSize: 17
iconSource: FluentIcons.SkipBack10
onClicked: {
mediaplayer.position = Math.max(mediaplayer.position-10*1000,0)
}
}
FluIconButton{
iconSize: 15
iconSource: mediaplayer.playbackState === MediaPlayer.PlayingState ? FluentIcons.Pause : FluentIcons.Play
onClicked: {
if(mediaplayer.playbackState === MediaPlayer.PlayingState){
mediaplayer.pause()
}else{
mediaplayer.play()
}
}
}
FluIconButton{
iconSize: 17
iconSource: FluentIcons.SkipForward30
onClicked: {
mediaplayer.position = Math.min(mediaplayer.position+30*1000,mediaplayer.duration)
}
}
}
FluIconButton{
id:btn_volume
iconSize: 17
iconSource: audio_output.muted ? FluentIcons.Mute : FluentIcons.Volume
anchors{
left: parent.left
leftMargin: 5
bottom: parent.bottom
bottomMargin: 10
}
onClicked: {
audio_output.muted = !audio_output.muted
}
}
FluSlider{
id:slider_volume
size: 80
dotSize: 20
value:30
anchors{
left:btn_volume.right
verticalCenter: btn_volume.verticalCenter
leftMargin: 10
}
onValueChanged:{
audio_output.volume = value/100
}
}
}
function formatDuration(duration) {
const seconds = Math.floor(duration / 1000);
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
return `${pad(hours)}:${pad(minutes)}:${pad(remainingSeconds)}`;
}
function pad(value) {
return value.toString().padStart(2, '0');
}
function pause(){
mediaplayer.pause()
}
function play(){
mediaplayer.play()
}
}

View File

@ -1,23 +1,26 @@
import QtQuick import QtQuick
import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.impl
import QtQuick.Templates as T
import FluentUI import FluentUI
Menu { T.Menu {
default property alias content: container.data property bool animEnabled: true
property bool enableAnimation: true id: control
id: popup implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
width: 140 contentWidth + leftPadding + rightPadding)
height: container.height implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
modal:true contentHeight + topPadding + bottomPadding)
dim:false margins: 0
overlap: 1
spacing: 0
delegate: FluMenuItem { }
enter: Transition { enter: Transition {
reversible: true
NumberAnimation { NumberAnimation {
property: "opacity" property: "opacity"
from:0 from:0
to:1 to:1
duration: enableAnimation ? 83 : 0 duration: animEnabled ? 83 : 0
} }
} }
exit:Transition { exit:Transition {
@ -25,38 +28,32 @@ Menu {
property: "opacity" property: "opacity"
from:1 from:1
to:0 to:0
duration: enableAnimation ? 83 : 0 duration: animEnabled ? 83 : 0
} }
} }
background:Item{ contentItem: ListView {
FluShadow{ implicitHeight: contentHeight
radius: 5 model: control.contentModel
} interactive: Window.window
} ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
contentItem: Item { : false
clip: true clip: true
Rectangle{ currentIndex: control.currentIndex
anchors.fill: parent ScrollIndicator.vertical: ScrollIndicator {}
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1) }
background: Rectangle {
implicitWidth: 150
implicitHeight: 36
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(240/255,240/255,240/255,1)
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1) border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
border.width: 1 border.width: 1
radius: 5 radius: 5
FluShadow{}
} }
Column{ T.Overlay.modal: Rectangle {
id:container color: Color.transparent(control.palette.shadow, 0.5)
spacing: 5 }
topPadding: 5 T.Overlay.modeless: Rectangle {
bottomPadding: 5 color: Color.transparent(control.palette.shadow, 0.12)
width: popup.width
function closePopup(){
popup.close()
}
}
}
function getContainerHeight(){
return container.height
}
function getContainerCount(){
return container.children.length
} }
} }

View File

@ -0,0 +1,21 @@
import QtQuick
import QtQuick.Templates as T
import QtQuick.Controls.impl
T.MenuBar {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
contentHeight + topPadding + bottomPadding)
delegate: FluMenuBarItem { }
contentItem: Row {
spacing: control.spacing
Repeater {
model: control.contentModel
}
}
background: Item {
implicitHeight: 30
}
}

View File

@ -0,0 +1,70 @@
import QtQuick
import QtQuick.Templates as T
import QtQuick.Controls.impl
import FluentUI
T.MenuBarItem {
property bool disabled: false
property color textColor: {
if(FluTheme.dark){
if(disabled){
return Qt.rgba(131/255,131/255,131/255,1)
}
if(pressed){
return Qt.rgba(162/255,162/255,162/255,1)
}
return Qt.rgba(1,1,1,1)
}else{
if(disabled){
return Qt.rgba(160/255,160/255,160/255,1)
}
if(pressed){
return Qt.rgba(96/255,96/255,96/255,1)
}
return Qt.rgba(0,0,0,1)
}
}
id: control
enabled: !disabled
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding,
implicitIndicatorHeight + topPadding + bottomPadding)
spacing: 6
padding: 6
leftPadding: 12
rightPadding: 16
icon.width: 24
icon.height: 24
icon.color: control.palette.buttonText
contentItem: FluText {
verticalAlignment: Text.AlignVCenter
text: control.text
color:control.textColor
}
background: Rectangle {
implicitWidth: 30
implicitHeight: 30
radius: 3
color: {
if(FluTheme.dark){
if(control.highlighted){
return Qt.rgba(1,1,1,0.06)
}
if(control.hovered){
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(control.highlighted){
return Qt.rgba(0,0,0,0.06)
}
if(control.hovered){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
}
}
}
}

View File

@ -1,53 +1,87 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.impl
import QtQuick.Templates as T
import FluentUI import FluentUI
Item { T.MenuItem {
property string text: "MenuItem" property color textColor: {
property var onClickFunc if(FluTheme.dark){
signal clicked if(!enabled){
return Qt.rgba(131/255,131/255,131/255,1)
}
if(pressed){
return Qt.rgba(162/255,162/255,162/255,1)
}
return Qt.rgba(1,1,1,1)
}else{
if(!enabled){
return Qt.rgba(160/255,160/255,160/255,1)
}
if(pressed){
return Qt.rgba(96/255,96/255,96/255,1)
}
return Qt.rgba(0,0,0,1)
}
}
id: control id: control
width: { implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
if(control.parent){ implicitContentWidth + leftPadding + rightPadding)
return control.parent.width implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding,
implicitIndicatorHeight + topPadding + bottomPadding)
padding: 6
spacing: 6
icon.width: 24
icon.height: 24
icon.color: control.palette.windowText
height: visible ? implicitHeight : 0
contentItem: FluText {
readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0
readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0
leftPadding: (!control.mirrored ? indicatorPadding : arrowPadding)+5
rightPadding: (control.mirrored ? indicatorPadding : arrowPadding)+5
verticalAlignment: Text.AlignVCenter
text: control.text
color: control.textColor
} }
return 140 indicator: FluIcon {
x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding
y: control.topPadding + (control.availableHeight - height) / 2
visible: control.checked
iconSource: FluentIcons.CheckMark
} }
height: 32 arrow: FluIcon {
x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding
y: control.topPadding + (control.availableHeight - height) / 2
visible: control.subMenu
iconSource: FluentIcons.ChevronRightMed
}
background: Item {
implicitWidth: 150
implicitHeight: 36
x: 1
y: 1
width: control.width - 2
height: control.height - 2
Rectangle{ Rectangle{
anchors.centerIn: parent anchors.fill: parent
width: control.width-40 anchors.margins: 3
height: 32
radius: 4 radius: 4
color:{ color:{
if(FluTheme.dark){ if(FluTheme.dark){
if(mouse_area.containsMouse){ if(control.highlighted){
return Qt.rgba(1,1,1,0.05) return Qt.rgba(1,1,1,0.06)
} }
return Qt.rgba(0,0,0,0) return Qt.rgba(0,0,0,0)
}else{ }else{
if(mouse_area.containsMouse){ if(control.highlighted){
return Qt.rgba(0,0,0,0.05) return Qt.rgba(0,0,0,0.06)
} }
return Qt.rgba(0,0,0,0) return Qt.rgba(0,0,0,0)
} }
} }
FluText{
text: control.text
anchors.centerIn: parent
}
MouseArea{
id:mouse_area
hoverEnabled: true
anchors.fill: parent
onClicked: {
if(control.onClickFunc){
control.onClickFunc()
return
}
control.parent.closePopup()
control.clicked()
}
} }
} }
} }

View File

@ -0,0 +1,19 @@
import QtQuick
import QtQuick.Controls.impl
import QtQuick.Templates as T
import FluentUI
T.MenuSeparator {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
padding: 0
verticalPadding: 0
contentItem: Rectangle {
implicitWidth: 188
implicitHeight: 1
color: FluTheme.dark ? Qt.rgba(60/255,60/255,60/255,1) : Qt.rgba(210/255,210/255,210/255,1)
}
}

View File

@ -4,6 +4,7 @@ import QtQuick.Controls.Basic
import FluentUI import FluentUI
TextArea{ TextArea{
signal commit
property bool disabled: false property bool disabled: false
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1) property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
@ -14,17 +15,20 @@ TextArea{
width: 300 width: 300
enabled: !disabled enabled: !disabled
color: { color: {
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
return normalColor return normalColor
} }
font:FluTextStyle.Body font:FluTextStyle.Body
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
padding: 8
leftPadding: 8
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTheme.primaryColor.lightest selectedTextColor: color
selectionColor: Qt.alpha(FluTheme.primaryColor.lightest,0.6)
placeholderTextColor: { placeholderTextColor: {
if(disabled){ if(!enabled){
return placeholderDisableColor return placeholderDisableColor
} }
if(focus){ if(focus){
@ -34,9 +38,23 @@ TextArea{
} }
selectByMouse: true selectByMouse: true
background: FluTextBoxBackground{ inputItem: control } background: FluTextBoxBackground{ inputItem: control }
TapHandler { Keys.onEnterPressed: (event)=> d.handleCommit(event)
Keys.onReturnPressed:(event)=> d.handleCommit(event)
QtObject{
id:d
function handleCommit(event){
if(event.modifiers & Qt.ControlModifier){
insert(control.cursorPosition, "\n")
return
}
control.commit()
}
}
MouseArea{
anchors.fill: parent
cursorShape: Qt.IBeamCursor
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
onTapped: control.echoMode !== TextInput.Password && menu.popup() onClicked: control.echoMode !== TextInput.Password && menu.popup()
} }
FluTextBoxMenu{ FluTextBoxMenu{
id:menu id:menu

View File

@ -14,7 +14,9 @@ Item {
} }
enum PageModeFlag{ enum PageModeFlag{
Standard = 0, Standard = 0,
SingleTask = 1 SingleTask = 1,
SingleTop = 2,
SingleInstance = 3
} }
property url logo property url logo
property string title: "" property string title: ""
@ -118,9 +120,7 @@ Item {
} }
Behavior on height { Behavior on height {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 83
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
} }
@ -136,9 +136,7 @@ Item {
} }
Behavior on height { Behavior on height {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 83
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
width: layout_list.width width: layout_list.width
@ -177,6 +175,33 @@ Item {
} }
model.isExpand = !model.isExpand model.isExpand = !model.isExpand
} }
Rectangle{
color:Qt.rgba(255/255,77/255,79/255,1)
width: 10
height: 10
radius: 5
border.width: 1
border.color: Qt.rgba(1,1,1,1)
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: 3
verticalCenterOffset: -8
}
visible: {
if(!model.isExpand){
for(var i=0;i<model.children.length;i++){
var item = model.children[i]
if(item.infoBadge && item.count !==0){
return true
}
}
}
return false
}
}
Rectangle{ Rectangle{
radius: 4 radius: 4
anchors.fill: parent anchors.fill: parent
@ -198,7 +223,9 @@ Item {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
} }
FluIcon{ FluIcon{
id:item_icon_expand
rotation: model.isExpand?0:180 rotation: model.isExpand?0:180
iconSource:FluentIcons.ChevronUp iconSource:FluentIcons.ChevronUp
iconSize: 15 iconSize: 15
@ -278,9 +305,11 @@ Item {
} }
return true return true
} }
elide: Text.ElideRight
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left:item_icon.right left:item_icon.right
right: item_icon_expand.left
} }
color:{ color:{
if(item_control.pressed){ if(item_control.pressed){
@ -298,9 +327,7 @@ Item {
Item{ Item{
Behavior on height { Behavior on height {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 83
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
clip: true clip: true
@ -428,6 +455,7 @@ Item {
} }
return true return true
} }
elide: Text.ElideRight
color:{ color:{
if(item_control.pressed){ if(item_control.pressed){
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
@ -437,6 +465,31 @@ Item {
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left:item_icon.right left:item_icon.right
right: item_dot_loader.left
}
}
Loader{
id:item_dot_loader
property bool isDot: (item_dot_loader.item&&item_dot_loader.item.isDot)
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: isDot ? 3 : 10
verticalCenterOffset: isDot ? -8 : 0
}
sourceComponent: {
if(model.infoBadge){
return model.infoBadge
}
return undefined
}
Connections{
target: d
function onIsCompactAndNotPanelChanged(){
if(item_dot_loader.item){
item_dot_loader.item.isDot = d.isCompactAndNotPanel
}
}
} }
} }
} }
@ -465,7 +518,7 @@ Item {
disabled: nav_swipe.depth <= 1 disabled: nav_swipe.depth <= 1
iconSize: 13 iconSize: 13
onClicked: { onClicked: {
nav_swipe.pop() FluTools.deleteItem(nav_swipe.pop())
d.stackItems.pop() d.stackItems.pop()
var item = d.stackItems[d.stackItems.length-1] var item = d.stackItems[d.stackItems.length-1]
if(item.idx<(nav_list.count - layout_footer.count)){ if(item.idx<(nav_list.count - layout_footer.count)){
@ -474,6 +527,20 @@ Item {
layout_footer.currentIndex = item.idx-(nav_list.count-layout_footer.count) layout_footer.currentIndex = item.idx-(nav_list.count-layout_footer.count)
} }
nav_list.currentIndex = item.idx nav_list.currentIndex = item.idx
if(nav_swipe.currentItem.pageMode === FluNavigationView.SingleInstance){
var url = nav_swipe.currentItem.url
var pageIndex = -1
for(var i=0;i<nav_swipe2.children.length;i++){
var obj = nav_swipe2.children[i]
if(obj.url === url){
pageIndex = i
break
}
}
if(pageIndex !== -1){
nav_swipe2.currentIndex = pageIndex
}
}
} }
} }
FluIconButton{ FluIconButton{
@ -497,8 +564,7 @@ Item {
Behavior on Layout.preferredWidth { Behavior on Layout.preferredWidth {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 167
easing.type: Easing.BezierSpline easing.type: Easing.InCubic
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
} }
@ -564,39 +630,27 @@ Item {
Behavior on anchors.leftMargin { Behavior on anchors.leftMargin {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 167
easing.type: Easing.BezierSpline easing.type: Easing.InCubic
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
StackView{ StackView{
id:nav_swipe id:nav_swipe
anchors.fill: parent anchors.fill: parent
clip: true clip: true
visible: !nav_swipe2.visible
popEnter : Transition{} popEnter : Transition{}
popExit : Transition { popExit : Transition {}
NumberAnimation { pushEnter: Transition {}
properties: "y"
from: 0
to: nav_swipe.height
duration: dontPageAnimation ? 0 : 167
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 1, 0, 0, 0 ]
}
}
pushEnter: Transition {
NumberAnimation {
properties: "y";
from: nav_swipe.height;
to: 0
duration: dontPageAnimation ? 0 : 167
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 0, 0, 0, 1 ]
}
}
pushExit : Transition{} pushExit : Transition{}
replaceEnter : Transition{} replaceEnter : Transition{}
replaceExit : Transition{} replaceExit : Transition{}
} }
StackLayout{
id:nav_swipe2
anchors.fill: nav_swipe
clip: true
visible: nav_swipe.currentItem.pageMode === FluNavigationView.SingleInstance
}
} }
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
@ -627,20 +681,17 @@ Item {
} }
return "transparent" return "transparent"
} }
clip: true
x: visible ? 0 : -width x: visible ? 0 : -width
Behavior on width { Behavior on width {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 167
easing.type: Easing.BezierSpline easing.type: Easing.InCubic
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
Behavior on x { Behavior on x {
NumberAnimation{ NumberAnimation{
duration: 167 duration: 167
easing.type: Easing.BezierSpline easing.type: Easing.InCubic
easing.bezierCurve: [ 0, 0, 0, 1 ]
} }
} }
visible: { visible: {
@ -705,7 +756,7 @@ Item {
clip: true clip: true
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
model:d.handleItems() model:d.handleItems()
highlightMoveDuration: 150 highlightMoveDuration: 167
highlight: Item{ highlight: Item{
clip: true clip: true
Rectangle{ Rectangle{
@ -808,6 +859,14 @@ Item {
duration: 83 duration: 83
} }
} }
Connections{
target: d
function onIsCompactChanged(){
if(!d.isCompact){
control_popup.close()
}
}
}
padding: 0 padding: 0
focus: true focus: true
contentItem: Item{ contentItem: Item{
@ -820,23 +879,49 @@ Item {
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
delegate:Button{ delegate:Button{
id:item_button id:item_button
width: 160 width: 180
padding:10 height: 38
focusPolicy:Qt.TabFocus focusPolicy:Qt.TabFocus
background: Rectangle{ background: Rectangle{
color: { color: {
if(hovered){ if(FluTheme.dark){
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) if(item_button.hovered){
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(item_button.hovered){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
} }
FluFocusRectangle{ FluFocusRectangle{
visible: item_button.activeFocus visible: item_button.activeFocus
radius:4 radius:4
} }
Loader{
id:item_dot_loader
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: 10
}
sourceComponent: {
if(model.infoBadge){
return model.infoBadge
}
return undefined
}
}
} }
contentItem: FluText{ contentItem: FluText{
text:modelData.title text:modelData.title
elide: Text.ElideRight
rightPadding: item_dot_loader.width
verticalAlignment: Qt.AlignVCenter
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
@ -858,14 +943,13 @@ Item {
} }
} }
background: FluRectangle{ background: FluRectangle{
implicitWidth: 160 implicitWidth: 180
implicitHeight: 38*Math.min(Math.max(list_view.count,1),8) implicitHeight: 38*Math.min(Math.max(list_view.count,1),8)
radius: [4,4,4,4] radius: [4,4,4,4]
FluShadow{ FluShadow{
radius: 4 radius: 4
} }
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1) color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
} }
function showPopup(pos,model){ function showPopup(pos,model){
control_popup.x = pos.x control_popup.x = pos.x
@ -874,6 +958,13 @@ Item {
control_popup.open() control_popup.open()
} }
} }
Component{
id:com_placeholder
Item{
property int pageMode: FluNavigationView.SingleInstance
property string url
}
}
function collapseAll(){ function collapseAll(){
for(var i=0;i<nav_list.model.length;i++){ for(var i=0;i<nav_list.model.length;i++){
var item = nav_list.model[i] var item = nav_list.model[i]
@ -893,10 +984,7 @@ Item {
return nav_list.model return nav_list.model
} }
function push(url,argument={}){ function push(url,argument={}){
if(nav_swipe.currentItem && nav_swipe.currentItem.url === url){ var page = nav_swipe.find(function(item) {
return
}
let page = nav_swipe.find(function(item) {
return item.url === url; return item.url === url;
}) })
if(page){ if(page){
@ -905,20 +993,58 @@ Item {
case FluNavigationView.SingleTask: case FluNavigationView.SingleTask:
while(nav_swipe.currentItem !== page) while(nav_swipe.currentItem !== page)
{ {
nav_swipe.pop() FluTools.deleteItem(nav_swipe.pop())
d.stackItems.pop() d.stackItems.pop()
} }
return return
case FluNavigationView.SingleTop:
if (nav_swipe.currentItem.url === url){
return
}
break
case FluNavigationView.Standard: case FluNavigationView.Standard:
default: default:
} }
} }
nav_swipe.push(url,Object.assign(argument,{url:url}))
var pageIndex = -1
for(var i=0;i<nav_swipe2.children.length;i++){
var item = nav_swipe2.children[i]
if(item.url === url){
pageIndex = i
break
}
}
var options = Object.assign(argument,{url:url})
if(pageIndex!==-1){
nav_swipe2.currentIndex = pageIndex
nav_swipe.push(com_placeholder,options)
}else{
var comp = Qt.createComponent(url)
if (comp.status === Component.Ready) {
var obj = comp.createObject(nav_swipe,options)
if(obj.pageMode === FluNavigationView.SingleInstance){
nav_swipe.push(com_placeholder,options)
nav_swipe2.children.push(obj)
nav_swipe2.currentIndex = nav_swipe2.count - 1
}else{
nav_swipe.push(obj)
}
}else{
console.error(comp.errorString())
}
}
d.stackItems.push(nav_list.model[nav_list.currentIndex]) d.stackItems.push(nav_list.model[nav_list.currentIndex])
} }
function getCurrentIndex(){ function getCurrentIndex(){
return nav_list.currentIndex return nav_list.currentIndex
} }
function getCurrentUrl(){
if(nav_swipe.currentItem){
return nav_swipe.currentItem.url
}
return undefined
}
function startPageByItem(data){ function startPageByItem(data){
var items = getItems() var items = getItems()
for(var i=0;i<items.length;i++){ for(var i=0;i<items.length;i++){

View File

@ -3,6 +3,6 @@ import QtQuick.Controls
import FluentUI import FluentUI
QtObject { QtObject {
default property list<QtObject> children; default property list<QtObject> children
id:flu_object; id:control
} }

View File

@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
import FluentUI
Item {
property int pageMode: FluNavigationView.SingleTop
property string url : ""
id: control
opacity: visible
visible: false
Behavior on opacity{
NumberAnimation{
duration: 83
}
}
Component.onCompleted: {
visible = true
}
}

View File

@ -9,9 +9,9 @@ Item {
property string nextText: "下一页>" property string nextText: "下一页>"
property int pageCurrent: 0 property int pageCurrent: 0
property int itemCount: 0 property int itemCount: 0
property int pageButtonCount: 5
property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0 property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0
property int __itemPerPage: 10 property int __itemPerPage: 10
property int pageButtonCount: 5
property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1 property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1
id: control id: control
implicitHeight: 40 implicitHeight: 40
@ -34,7 +34,6 @@ Item {
FluToggleButton{ FluToggleButton{
property int pageNumber:1 property int pageNumber:1
visible: control.pageCount>0 visible: control.pageCount>0
enabled: control.pageCurrent>1
checked: pageNumber === control.pageCurrent checked: pageNumber === control.pageCurrent
text:String(pageNumber) text:String(pageNumber)
clickListener:function() { clickListener:function() {

View File

@ -9,12 +9,14 @@ QtObject {
property int order : 0 property int order : 0
property int icon property int icon
property Component cusIcon property Component cusIcon
property Component infoBadge
property bool recentlyAdded: false property bool recentlyAdded: false
property bool recentlyUpdated: false property bool recentlyUpdated: false
property string desc property string desc
property var image property var image
property var parent property var parent
property int idx property int idx
property int count: 0
signal tap signal tap
property var tapFunc property var tapFunc
} }

View File

@ -4,6 +4,7 @@ import QtQuick.Controls.Basic
import FluentUI import FluentUI
TextField{ TextField{
signal commit
property bool disabled: false property bool disabled: false
property int iconSource: 0 property int iconSource: 0
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
@ -15,17 +16,20 @@ TextField{
width: 300 width: 300
enabled: !disabled enabled: !disabled
color: { color: {
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
return normalColor return normalColor
} }
font:FluTextStyle.Body font:FluTextStyle.Body
padding: 8
leftPadding: 8
echoMode:btn_reveal.pressed ? TextField.Normal : TextField.Password echoMode:btn_reveal.pressed ? TextField.Normal : TextField.Password
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTheme.primaryColor.lightest selectionColor: Qt.alpha(FluTheme.primaryColor.lightest,0.6)
selectedTextColor: color
placeholderTextColor: { placeholderTextColor: {
if(disabled){ if(!enabled){
return placeholderDisableColor return placeholderDisableColor
} }
if(focus){ if(focus){
@ -50,6 +54,14 @@ TextField{
} }
} }
} }
Keys.onEnterPressed: (event)=> d.handleCommit(event)
Keys.onReturnPressed:(event)=> d.handleCommit(event)
QtObject{
id:d
function handleCommit(event){
control.commit()
}
}
FluIconButton{ FluIconButton{
id:btn_reveal id:btn_reveal
iconSource:FluentIcons.RevealPasswordMedium iconSource:FluentIcons.RevealPasswordMedium
@ -64,10 +76,6 @@ TextField{
rightMargin: icon_end.visible ? 25 : 5 rightMargin: icon_end.visible ? 25 : 5
} }
} }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluTextBoxMenu{ FluTextBoxMenu{
id:menu id:menu
inputItem: control inputItem: control

View File

@ -28,6 +28,7 @@ Item {
spacing: 20 spacing: 20
interactive: false interactive: false
orientation: ListView.Horizontal orientation: ListView.Horizontal
highlightMoveDuration: 167
highlight: Item{ highlight: Item{
clip: true clip: true
Rectangle{ Rectangle{
@ -38,7 +39,8 @@ Item {
y:37 y:37
Behavior on width { Behavior on width {
NumberAnimation{ NumberAnimation{
duration: 150 duration: 167
easing.type: Easing.InCubic
} }
} }
} }
@ -61,11 +63,6 @@ Item {
return normalColor return normalColor
} }
} }
transitions: Transition {
NumberAnimation{
duration: 400;
}
}
} }
onClicked: { onClicked: {
nav_list.currentIndex = index nav_list.currentIndex = index

View File

@ -13,6 +13,9 @@ Button {
property color hoverColor: checked ? FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1) property color hoverColor: checked ? FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)
property color disableColor: checked ? FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(159/255,159/255,159/255,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1) property color disableColor: checked ? FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(159/255,159/255,159/255,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)
property alias textColor: btn_text.textColor property alias textColor: btn_text.textColor
property real size: 18
property bool textRight: true
property real textSpacing: 6
property var clickListener : function(){ property var clickListener : function(){
checked = !checked checked = !checked
} }
@ -33,28 +36,30 @@ Button {
font:FluTextStyle.Body font:FluTextStyle.Body
onClicked: clickListener() onClicked: clickListener()
contentItem: RowLayout{ contentItem: RowLayout{
spacing: control.textSpacing
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
Rectangle{ Rectangle{
id:rect_check id:rect_check
width: 20 width: control.size
height: 20 height: control.size
radius: 10 radius: size/2
border.width: { border.width: {
if(checked&&disabled){ if(checked&&!enabled){
return 4 return 3
} }
if(pressed){ if(pressed){
if(checked){ if(checked){
return 5 return 4
} }
return 1 return 1
} }
if(hovered){ if(hovered){
if(checked){ if(checked){
return 4 return 3
} }
return 1 return 1
} }
return checked ? 5 : 1 return checked ? 4 : 1
} }
Behavior on border.width { Behavior on border.width {
NumberAnimation{ NumberAnimation{
@ -64,13 +69,13 @@ Button {
} }
} }
border.color: { border.color: {
if(disabled){ if(!enabled){
return borderDisableColor return borderDisableColor
} }
return borderNormalColor return borderNormalColor
} }
color:{ color:{
if(disabled){ if(!enabled){
return disableColor return disableColor
} }
if(hovered){ if(hovered){

View File

@ -0,0 +1,30 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts
import FluentUI
ColumnLayout {
default property alias buttons: control.data
property int currentIndex : -1
id:control
onCurrentIndexChanged: {
for(var i = 0;i<buttons.length;i++){
buttons[i].checked = false
}
buttons[currentIndex].checked = true
}
Component.onCompleted: {
for(var i = 0;i<buttons.length;i++){
buttons[i].clickListener = function(){
for(var i = 0;i<buttons.length;i++){
var button = buttons[i]
if(this === button){
currentIndex = i
}
}
}
}
currentIndex = 0
}
}

View File

@ -2,25 +2,35 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import FluentUI import FluentUI
Item { FluStatusView {
id:control
property url source: "" property url source: ""
property bool lazy: false
color:"transparent"
id:control
onErrorClicked: {
reload()
}
Component.onCompleted: {
if(!lazy){
loader.source = control.source
}
}
Loader{ Loader{
id:loader id:loader
anchors.fill: parent anchors.fill: parent
source: control.source
asynchronous: true asynchronous: true
onStatusChanged: {
if(status === Loader.Error){
control.statusMode = FluStatusView.Error
}else if(status === Loader.Loading){
control.statusMode = FluStatusView.Loading
}else{
control.statusMode = FluStatusView.Success
}
} }
FluProgressRing{
anchors.centerIn: parent
visible: loader.status === Loader.Loading
} }
function reload(){ function reload(){
var timestamp = Date.now(); var timestamp = Date.now();
loader.source = control.source+"?"+timestamp loader.source = control.source+"?"+timestamp
} }
} }

View File

@ -1,189 +1,88 @@
import QtQuick import QtQuick
import QtQuick.Controls.Basic import QtQuick.Controls.impl
import QtQuick.Templates as T
import FluentUI import FluentUI
ScrollBar { T.ScrollBar {
property color handleNormalColor: Qt.rgba(134/255,134/255,134/255,1)
property color handleHoverColor: Qt.lighter(handleNormalColor)
property color handlePressColor: Qt.darker(handleNormalColor)
property bool expand: false
id: control id: control
property color color : FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(138/255,138/255,138/255,1)
property color pressedColor: FluTheme.dark ? Qt.darker(color,1.2) : Qt.lighter(color,1.2)
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,
implicitContentHeight + topPadding + bottomPadding) implicitContentHeight + topPadding + bottomPadding)
visible: control.policy !== ScrollBar.AlwaysOff
minimumSize: 0.3 padding: 2
topPadding:{ visible: control.policy !== T.ScrollBar.AlwaysOff
if(vertical){ minimumSize: Math.max(orientation === Qt.Horizontal ? height / width : width / height,0.3)
if(expand) contentItem: Item {
return 15 property bool collapsed: (control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0))
return 2 implicitWidth: control.interactive ? 6 : 2
}else{ implicitHeight: control.interactive ? 6 : 2
if(expand){
return 2 Rectangle{
} id:rect_bar
return 4 width: vertical ? 2 : parent.width
} height: horizontal ? 2 : parent.height
}
bottomPadding:{
if(vertical){
if(expand)
return 15
return 2
}else{
if(expand){
return 2
}
return 4
}
}
leftPadding:{
if(vertical){
if(expand){
return 2
}
return 4
}else{
if(expand)
return 15
return 2
}
}
rightPadding:{
if(vertical){
if(expand){
return 2
}
return 4
}else{
if(expand)
return 15
return 2
}
}
Behavior on topPadding {
NumberAnimation{
duration: 150
}
}
Behavior on bottomPadding {
NumberAnimation{
duration: 150
}
}
Behavior on leftPadding {
NumberAnimation{
duration: 150
}
}
Behavior on rightPadding {
NumberAnimation{
duration: 150
}
}
contentItem: Rectangle {
id:item_react
implicitWidth: expand ? 8 : 2
implicitHeight: expand ? 8 : 2
radius: width / 2
color: control.pressed?handlePressColor:control.hovered?handleHoverColor:handleNormalColor
opacity:(control.policy === ScrollBar.AlwaysOn || control.size < 1.0)?1.0:0.0
}
background: Rectangle{
radius: 5
color:{ color:{
if(expand && item_react.opacity){ if(control.pressed){
if(FluTheme.dark){ return control.pressedColor
return Qt.rgba(0,0,0,1)
} }
return Qt.rgba(1,1,1,1) return control .color
} }
return Qt.rgba(0,0,0,0) anchors{
right: vertical ? parent.right : undefined
bottom: horizontal ? parent.bottom : undefined
} }
MouseArea{ radius: width / 2
id:mouse_item visible: control.size < 1.0
hoverEnabled: true
anchors.fill: parent
onEntered: {
timer.restart()
} }
onExited: { states: [
timer.restart() State{
name:"hide"
when: contentItem.collapsed
PropertyChanges {
target: rect_bar
width: vertical ? 6 : parent.width
height: horizontal ? 6 : parent.height
} }
} }
} ,State{
Timer{ name:"show"
id:timer when: !contentItem.expand
interval: 800 PropertyChanges {
onTriggered: { target: rect_bar
expand = mouse_item.containsMouse || btn_top.hovered || btn_bottom.hovered || btn_left.hovered || btn_right.hovered width: vertical ? 2 : parent.width
height: horizontal ? 2 : parent.height
} }
} }
Behavior on implicitWidth { ]
transitions:[
Transition {
from: "hide"
SequentialAnimation {
PauseAnimation { duration: 450 }
NumberAnimation { NumberAnimation {
duration: 150 target: rect_bar
} properties: vertical ? "width" : "height"
} duration: 167
FluIconButton{ easing.type: Easing.InCubic
id:btn_top to:2
iconSource: FluentIcons.CaretSolidUp
anchors.horizontalCenter: parent.horizontalCenter
width:10
height:10
z:100
iconColor: hovered ? FluColors.Black : FluColors.Grey120
iconSize: 8
anchors.top: parent.top
anchors.topMargin: 4
visible:vertical && expand && item_react.opacity
onClicked:{
decrease()
}
}
FluIconButton{
id:btn_bottom
iconSource: FluentIcons.CaretSolidDown
visible:vertical && expand && item_react.opacity
width:10
height:10
iconSize: 8
iconColor: hovered ? FluColors.Black : FluColors.Grey120
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 4
onClicked:{
increase()
}
}
FluIconButton{
id:btn_left
iconSource: FluentIcons.CaretSolidLeft
visible:!vertical && expand && item_react.opacity
width:10
height:10
iconSize: 8
iconColor: hovered ? FluColors.Black : FluColors.Grey120
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
onClicked:{
decrease()
}
}
FluIconButton{
id:btn_right
iconSource: FluentIcons.CaretSolidRight
visible:!vertical && expand && item_react.opacity
width:10
height:10
iconSize: 8
iconColor: hovered ? FluColors.Black : FluColors.Grey120
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
onClicked:{
increase()
} }
} }
} }
,Transition {
from: "show"
NumberAnimation {
target: rect_bar
properties: vertical ? "width" : "height"
duration: 167
easing.type: Easing.InCubic
to:6
}
}
]
}
}

View File

@ -0,0 +1,49 @@
import QtQuick
import QtQuick.Controls.impl
import QtQuick.Templates as T
T.ScrollIndicator {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
padding: 2
contentItem: Rectangle {
implicitWidth: 2
implicitHeight: 2
color: control.palette.mid
visible: control.size < 1.0
opacity: 0.0
states: State {
name: "active"
when: control.active
PropertyChanges {
target: control
contentItem.opacity: 0.75
}
}
transitions: [
Transition {
from: "active"
SequentialAnimation {
PauseAnimation {
duration: 450
}
NumberAnimation {
target: control.contentItem
duration: 200
property: "opacity"
to: 0.0
}
}
}
]
}
}

View File

@ -4,7 +4,7 @@ import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import FluentUI import FluentUI
Item { FluPage {
property alias title: text_title.text property alias title: text_title.text
default property alias content: container.data default property alias content: container.data
property int spacing : 0 property int spacing : 0
@ -12,14 +12,12 @@ Item {
property int topPadding: 0 property int topPadding: 0
property int rightPadding: 10 property int rightPadding: 10
property int bottomPadding: 10 property int bottomPadding: 10
property int pageMode: FluNavigationView.Standard
property string url: ''
id:control id:control
FluText{ FluText{
id:text_title id:text_title
font: FluTextStyle.Title font: FluTextStyle.Title
visible: text !== "" visible: text !== ""
height: visible ? implicitHeight : 0 height: visible ? contentHeight : 0
padding: 0 padding: 0
anchors{ anchors{
top: parent.top top: parent.top
@ -43,6 +41,8 @@ Item {
contentWidth: parent.width contentWidth: parent.width
contentHeight: container.height contentHeight: container.height
ScrollBar.vertical: FluScrollBar { ScrollBar.vertical: FluScrollBar {
anchors.right: flickview.right
anchors.rightMargin: 2
} }
anchors{ anchors{
top: text_title.bottom top: text_title.bottom

Some files were not shown because too many files have changed in this diff Show More