Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
3a46fd11c6 | |||
70f048f629 | |||
1f2d0d9b9f | |||
09e87e0fb8 | |||
0603a7603d | |||
d9a4f01e20 | |||
93709cd1dd | |||
0000e557a7 | |||
d2183e350e | |||
47caf4bb52 | |||
6fb9ee41fb | |||
b349c22434 | |||
12fa3487bb | |||
a76806645a | |||
738db25c2c | |||
9f8a5f5646 | |||
c59c07e756 |
2
.github/workflows/ubuntu.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
- name: ubuntu install GL library
|
||||
run: sudo apt-get install -y libglew-dev libglfw3-dev qml-module-qtquick-controls qml-module-qtquick-controls2
|
||||
run: sudo apt-get install -y libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-sync-dev libxcb-render-util0-dev libxcb-shm0-dev
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
18
README.md
@ -62,6 +62,12 @@
|
||||
|FluDatePicker|日期选择器||
|
||||
|FluMenu|菜单Popup||
|
||||
|FluNavigationView|响应式导航布局||
|
||||
|FluScrollbar|滚动条||
|
||||
|FluToggleButton|开关按钮||
|
||||
|FluPagination|分页组件||
|
||||
|FluTableView|表格组件||
|
||||
|FluMediaPlayer|播放器||
|
||||
|FluFlipView|FlipView||
|
||||
|
||||
# 部分效果预览
|
||||
|
||||
@ -77,6 +83,10 @@
|
||||
|
||||

|
||||
|
||||
## TableView表格组件
|
||||
|
||||

|
||||
|
||||
## FluTreeView树组件
|
||||
|
||||

|
||||
@ -85,13 +95,5 @@
|
||||
|
||||

|
||||
|
||||
## InfoBar提示框组件
|
||||
|
||||

|
||||
|
||||
## 多窗口路由跳转
|
||||
|
||||

|
||||
|
||||
### ⚡ Visitor count
|
||||

|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 383 KiB After Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 382 KiB |
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 218 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 103 KiB |
BIN
doc/preview/tableview.png
Normal file
After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 49 KiB |
@ -7,6 +7,8 @@ set(CMAKE_AUTOUIC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(platform 64)
|
||||
else()
|
||||
@ -44,20 +46,17 @@ add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QT_RESOURCES} ${RC_ICONS}
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
file(GLOB DLL_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../third/msvc/*.dll)
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${DLL_FILES}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/msvc/*.dll)
|
||||
else()
|
||||
file(GLOB DLL_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../third/mingw/*.dll)
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${DLL_FILES}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/mingw/*.dll)
|
||||
endif()
|
||||
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
|
||||
file(GLOB DLL_FILES ${DLLPATH})
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${DLL_FILES}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
|
@ -52,12 +52,12 @@ FluScrollablePage{
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:' showInfo("这是一个Info样式的InfoBar")
|
||||
code:'showInfo("这是一个Info样式的InfoBar")
|
||||
|
||||
showWarning("这是一个Warning样式的InfoBar")
|
||||
showWarning("这是一个Warning样式的InfoBar")
|
||||
|
||||
showError("这是一个Error样式的InfoBar")
|
||||
showError("这是一个Error样式的InfoBar")
|
||||
|
||||
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar")'
|
||||
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar")'
|
||||
}
|
||||
}
|
||||
|
50
example/T_Settings.qml
Normal file
@ -0,0 +1,50 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "qrc:///global/"
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"Settings"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 168
|
||||
paddings: 10
|
||||
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"NavigationView Display Mode"
|
||||
fontStyle: FluText.BodyStrong
|
||||
Layout.bottomMargin: 4
|
||||
}
|
||||
|
||||
Repeater{
|
||||
id:repeater
|
||||
model: [{title:"Open",mode:FluNavigationView.Open},{title:"Compact",mode:FluNavigationView.Compact},{title:"Minimal",mode:FluNavigationView.Minimal},{title:"Auto",mode:FluNavigationView.Auto}]
|
||||
delegate: FluRadioButton{
|
||||
selected : MainEvent.displayMode===modelData.mode
|
||||
text:modelData.title
|
||||
onClicked:{
|
||||
MainEvent.displayMode = modelData.mode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
91
example/T_StatusView.qml
Normal file
@ -0,0 +1,91 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"StatusView"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
id:layout_actions
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 50
|
||||
paddings: 10
|
||||
RowLayout{
|
||||
spacing: 14
|
||||
FluDropDownButton{
|
||||
id:btn_status_mode
|
||||
Layout.preferredWidth: 140
|
||||
text:"Loading"
|
||||
items:[
|
||||
FluMenuItem{
|
||||
text:"Loading"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Loading
|
||||
}
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Empty"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Empty
|
||||
}
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Error"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Error
|
||||
}
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Success"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Success
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
height: 380
|
||||
paddings: 10
|
||||
FluStatusView{
|
||||
id:status_view
|
||||
anchors.fill: parent
|
||||
onErrorClicked:{
|
||||
showError("点击重新加载")
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color:FluTheme.primaryColor.dark
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluStatusView{
|
||||
anchors.fill: parent
|
||||
statusMode: FluStatusView.Loading
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color:FluTheme.primaryColor.dark
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
@ -45,12 +45,10 @@ FluScrollablePage{
|
||||
loadData(1,10)
|
||||
}
|
||||
|
||||
|
||||
FluTableView{
|
||||
id:table_view
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
width:parent.width
|
||||
pageCurrent:1
|
||||
pageCount:10
|
||||
itemCount: 1000
|
||||
@ -102,9 +100,61 @@ FluScrollablePage{
|
||||
action:com_action
|
||||
})
|
||||
}
|
||||
|
||||
table_view.dataSource = dataSource
|
||||
}
|
||||
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
code:'FluTableView{
|
||||
id:table_view
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
width:parent.width
|
||||
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
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -113,7 +113,12 @@ FluExpander{
|
||||
"FluTooltip",
|
||||
"FluTreeView",
|
||||
"FluWindow",
|
||||
"FluWindowResize"
|
||||
"FluWindowResize",
|
||||
"FluToggleButton",
|
||||
"FluTableView",
|
||||
"FluColors",
|
||||
"FluTheme",
|
||||
"FluStatusView"
|
||||
];
|
||||
code = code.replace(/\n/g, "<br>");
|
||||
code = code.replace(/ /g, " ");
|
||||
|
@ -5,17 +5,22 @@ import FluentUI
|
||||
|
||||
FluObject{
|
||||
id:footer_items
|
||||
|
||||
property var navigationView
|
||||
|
||||
FluPaneItemSeparator{}
|
||||
FluPaneItem{
|
||||
title:"意见反馈"
|
||||
onTap:{
|
||||
Qt.openUrlExternally("https://github.com/zhuzichu520/FluentUI/issues/new")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"关于"
|
||||
onTap:{
|
||||
title:"About"
|
||||
icon:FluentIcons.Contact
|
||||
tapFunc:function(){
|
||||
FluApp.navigate("/about")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Settings"
|
||||
icon:FluentIcons.Settings
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Settings.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,12 @@ FluObject{
|
||||
navigationView.push("qrc:/T_Rectangle.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"StatusView"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_StatusView.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Carousel"
|
||||
onTap:{
|
||||
@ -302,7 +308,6 @@ FluObject{
|
||||
if(navigationView.getCurrentIndex() === i){
|
||||
return
|
||||
}
|
||||
item.tap()
|
||||
navigationView.setCurrentIndex(i)
|
||||
if(item.parent){
|
||||
item.parent.isExpand = true
|
||||
|
10
example/global/MainEvent.qml
Normal file
@ -0,0 +1,10 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
|
||||
property int displayMode : FluNavigationView.Auto
|
||||
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
singleton ItemsOriginal 1.0 ItemsOriginal.qml
|
||||
singleton ItemsFooter 1.0 ItemsFooter.qml
|
||||
singleton MainEvent 1.0 MainEvent.qml
|
||||
|
@ -36,7 +36,7 @@ FluWindow {
|
||||
fontStyle: FluText.Title
|
||||
}
|
||||
FluText{
|
||||
text:"v1.2.1"
|
||||
text:"v1.2.3"
|
||||
fontStyle: FluText.Body
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
|
@ -15,9 +15,10 @@ FluWindow {
|
||||
|
||||
FluAppBar{
|
||||
id:appbar
|
||||
z:10
|
||||
z:9
|
||||
showDark: true
|
||||
width:parent.width
|
||||
darkText: "Dark Mode"
|
||||
}
|
||||
|
||||
FluNavigationView{
|
||||
@ -25,15 +26,16 @@ FluWindow {
|
||||
anchors.fill: parent
|
||||
items: ItemsOriginal
|
||||
footerItems:ItemsFooter
|
||||
z:11
|
||||
displayMode:MainEvent.displayMode
|
||||
logo: "qrc:/res/image/favicon.ico"
|
||||
z: 11
|
||||
title:"FluentUI"
|
||||
autoSuggestBox:FluAutoSuggestBox{
|
||||
width: 280
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.Zoom
|
||||
iconSource: FluentIcons.Search
|
||||
items: ItemsOriginal.getSearchData()
|
||||
placeholderText: "查找"
|
||||
placeholderText: "Search"
|
||||
onItemClicked:
|
||||
(data)=>{
|
||||
ItemsOriginal.startPageByItem(data)
|
||||
@ -41,8 +43,8 @@ FluWindow {
|
||||
}
|
||||
Component.onCompleted: {
|
||||
ItemsOriginal.navigationView = nav_view
|
||||
ItemsFooter.navigationView = nav_view
|
||||
nav_view.setCurrentIndex(0)
|
||||
nav_view.push("qrc:/T_Home.qml")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,5 +157,8 @@
|
||||
<file>T_Pivot.qml</file>
|
||||
<file>component/CodeExpander.qml</file>
|
||||
<file>T_TableView.qml</file>
|
||||
<file>T_StatusView.qml</file>
|
||||
<file>T_Settings.qml</file>
|
||||
<file>global/MainEvent.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -10,6 +10,10 @@ set(QT_INSTALL_QML ${Qt6Core_DIR}/../../../qml)
|
||||
set(TARGET_TYPE SHARED)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
endif()
|
||||
|
||||
set(TARGET_RESOURCES res.qrc)
|
||||
set(TARGET_SOURCES
|
||||
Def.cpp
|
||||
|
@ -33,6 +33,8 @@ void Fluent::registerTypes(const char *uri){
|
||||
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper");
|
||||
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
|
||||
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluStatusView.qml"),uri,major,minor,"FluStatusView");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPagination.qml"),uri,major,minor,"FluPagination");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluToggleButton.qml"),uri,major,minor,"FluToggleButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTableView.qml"),uri,major,minor,"FluTableView");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPivotItem.qml"),uri,major,minor,"FluPivotItem");
|
||||
|
@ -5,6 +5,7 @@ import FluentUI
|
||||
FluTextBox{
|
||||
property var items:[]
|
||||
property string emptyText: "没有找到结果"
|
||||
property int autoSuggestBoxReplacement: FluentIcons.Search
|
||||
signal itemClicked(var data)
|
||||
signal handleClicked
|
||||
QtObject{
|
||||
|
@ -48,6 +48,5 @@ FluControl {
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
|
@ -6,48 +6,112 @@ import FluentUI
|
||||
|
||||
Item {
|
||||
|
||||
property alias logo : image_logo.source
|
||||
property string title: ""
|
||||
property FluObject items
|
||||
property FluObject footerItems
|
||||
property int displayMode: width<=700 ? FluNavigationView.Minimal : FluNavigationView.Open
|
||||
property bool displaMinimalMenu : false
|
||||
property Component autoSuggestBox
|
||||
|
||||
id:root
|
||||
|
||||
onDisplayModeChanged: {
|
||||
if(displayMode === FluNavigationView.Minimal){
|
||||
anim_navi.enabled = false
|
||||
displaMinimalMenu = false
|
||||
timer_anim_enable.restart()
|
||||
}
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer_anim_enable
|
||||
interval: 150
|
||||
onTriggered: {
|
||||
anim_navi.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
enum DisplayMode {
|
||||
Minimal,
|
||||
Open,
|
||||
Compact,
|
||||
Minimal,
|
||||
Auto
|
||||
}
|
||||
|
||||
property url logo
|
||||
property string title: ""
|
||||
property FluObject items
|
||||
property FluObject footerItems
|
||||
property int displayMode: FluNavigationView.Auto
|
||||
property Component autoSuggestBox
|
||||
property var window : {
|
||||
if(Window.window == null)
|
||||
return null
|
||||
return Window.window
|
||||
}
|
||||
|
||||
id:control
|
||||
|
||||
QtObject{
|
||||
id:d
|
||||
property bool enableStack: true
|
||||
property int displayMode: {
|
||||
if(control.displayMode !==FluNavigationView.Auto){
|
||||
return control.displayMode
|
||||
}
|
||||
if(control.width<=700){
|
||||
return FluNavigationView.Minimal
|
||||
}else if(control.width<=900){
|
||||
return FluNavigationView.Compact
|
||||
}else{
|
||||
return FluNavigationView.Open
|
||||
}
|
||||
}
|
||||
property var stackItems: []
|
||||
property bool enableNavigationPanel: false
|
||||
property bool isCompact: d.displayMode === FluNavigationView.Compact
|
||||
property bool isMinimal: d.displayMode === FluNavigationView.Minimal
|
||||
property bool isCompactAndPanel: d.displayMode === FluNavigationView.Compact && d.enableNavigationPanel
|
||||
property bool isCompactAndNotPanel:d.displayMode === FluNavigationView.Compact && !d.enableNavigationPanel
|
||||
property bool isMinimalAndPanel: d.displayMode === FluNavigationView.Minimal && d.enableNavigationPanel
|
||||
|
||||
onIsCompactAndNotPanelChanged: {
|
||||
collapseAll()
|
||||
}
|
||||
|
||||
onDisplayModeChanged: {
|
||||
if(d.displayMode === FluNavigationView.Compact){
|
||||
collapseAll()
|
||||
}
|
||||
if(d.displayMode === FluNavigationView.Minimal){
|
||||
anim_layout_list_x.enabled = false
|
||||
d.enableNavigationPanel = false
|
||||
timer_anim_x_enable.restart()
|
||||
}
|
||||
}
|
||||
|
||||
function handleItems(){
|
||||
var idx = 0
|
||||
var data = []
|
||||
if(items){
|
||||
for(var i=0;i<items.children.length;i++){
|
||||
var item = items.children[i]
|
||||
item.idx = idx
|
||||
data.push(item)
|
||||
idx++
|
||||
if(item instanceof FluPaneItemExpander){
|
||||
for(var j=0;j<item.children.length;j++){
|
||||
var itemChild = item.children[j]
|
||||
itemChild.parent = item
|
||||
itemChild.idx = idx
|
||||
data.push(itemChild)
|
||||
idx++
|
||||
}
|
||||
}
|
||||
}
|
||||
if(footerItems){
|
||||
var comEmpty = Qt.createComponent("FluPaneItemEmpty.qml");
|
||||
for(var k=0;k<footerItems.children.length;k++){
|
||||
var itemFooter = footerItems.children[k]
|
||||
if (comEmpty.status === Component.Ready) {
|
||||
var objEmpty = comEmpty.createObject(items,{idx:idx});
|
||||
itemFooter.idx = idx;
|
||||
data.push(objEmpty)
|
||||
idx++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_panel_item_empty
|
||||
Item{
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_panel_item_separatorr
|
||||
FluDivider{
|
||||
width: nav_list.width
|
||||
width: layout_list.width
|
||||
height: {
|
||||
if(model.parent){
|
||||
return model.parent.isExpand ? 1 : 0
|
||||
@ -76,7 +140,7 @@ Item {
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
width: nav_list.width
|
||||
width: layout_list.width
|
||||
FluText{
|
||||
text:model.title
|
||||
fontStyle: FluText.BodyStrong
|
||||
@ -93,8 +157,7 @@ Item {
|
||||
id:com_panel_item_expander
|
||||
Item{
|
||||
height: 38
|
||||
width: nav_list.width
|
||||
|
||||
width: layout_list.width
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors{
|
||||
@ -134,6 +197,18 @@ Item {
|
||||
right: parent.right
|
||||
rightMargin: 12
|
||||
}
|
||||
opacity: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
visible:opacity
|
||||
Behavior on opacity {
|
||||
NumberAnimation{
|
||||
duration: 220
|
||||
}
|
||||
}
|
||||
Behavior on rotation {
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
@ -145,12 +220,16 @@ Item {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
control_popup.showPopup(Qt.point(50,mapToItem(control,0,0).y),model.children)
|
||||
return
|
||||
}
|
||||
model.isExpand = !model.isExpand
|
||||
}
|
||||
}
|
||||
color: {
|
||||
if(FluTheme.dark){
|
||||
if((nav_list.currentIndex === position)&&type===0){
|
||||
if((nav_list.currentIndex === idx)&&type===0){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
@ -158,7 +237,7 @@ Item {
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}else{
|
||||
if(nav_list.currentIndex === position&&type===0){
|
||||
if(nav_list.currentIndex === idx&&type===0){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
@ -167,7 +246,6 @@ Item {
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon{
|
||||
id:item_icon
|
||||
iconSource: {
|
||||
@ -185,10 +263,21 @@ Item {
|
||||
leftMargin: 3
|
||||
}
|
||||
}
|
||||
|
||||
FluText{
|
||||
id:item_title
|
||||
text:model.title
|
||||
opacity: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
visible:opacity
|
||||
Behavior on opacity {
|
||||
NumberAnimation{
|
||||
duration: 220
|
||||
}
|
||||
}
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:item_icon.right
|
||||
@ -219,8 +308,7 @@ Item {
|
||||
}
|
||||
return 38
|
||||
}
|
||||
width: nav_list.width
|
||||
|
||||
width: layout_list.width
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors{
|
||||
@ -238,33 +326,55 @@ Item {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if(type===0){
|
||||
if(type === 0){
|
||||
if(model.tapFunc){
|
||||
model.tapFunc()
|
||||
return
|
||||
}
|
||||
if(nav_list.currentIndex !== position){
|
||||
nav_list.currentIndex = position
|
||||
model.tap()
|
||||
}else{
|
||||
nav_list.currentIndex = idx
|
||||
layout_footer.currentIndex = -1
|
||||
if(d.isMinimal || d.isCompact){
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
}else{
|
||||
model.tap()
|
||||
if(model.tapFunc){
|
||||
model.tapFunc()
|
||||
}else{
|
||||
model.tap()
|
||||
d.stackItems.push(model)
|
||||
nav_list.currentIndex = nav_list.count-layout_footer.count+idx
|
||||
layout_footer.currentIndex = idx
|
||||
if(d.isMinimal || d.isCompact){
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
}
|
||||
displaMinimalMenu = false
|
||||
}
|
||||
}
|
||||
color: {
|
||||
if(FluTheme.dark){
|
||||
if((nav_list.currentIndex === position)&&type===0){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
if(type===0){
|
||||
if(nav_list.currentIndex === idx){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
}else{
|
||||
if(nav_list.currentIndex === (nav_list.count-layout_footer.count+idx)){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return Qt.rgba(1,1,1,0.03)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}else{
|
||||
if(nav_list.currentIndex === position&&type===0){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
if(type===0){
|
||||
if(nav_list.currentIndex === idx){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
}else{
|
||||
if(nav_list.currentIndex === (nav_list.count-layout_footer.count+idx)){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return Qt.rgba(0,0,0,0.03)
|
||||
@ -272,7 +382,6 @@ Item {
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon{
|
||||
id:item_icon
|
||||
iconSource: {
|
||||
@ -290,10 +399,21 @@ Item {
|
||||
leftMargin: 3
|
||||
}
|
||||
}
|
||||
|
||||
FluText{
|
||||
id:item_title
|
||||
text:model.title
|
||||
opacity: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
visible:opacity
|
||||
Behavior on opacity {
|
||||
NumberAnimation{
|
||||
duration: 220
|
||||
}
|
||||
}
|
||||
color:{
|
||||
if(item_mouse.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
@ -309,6 +429,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id:nav_app_bar
|
||||
width: parent.width
|
||||
@ -327,11 +448,17 @@ Item {
|
||||
iconSize: 13
|
||||
onClicked: {
|
||||
nav_swipe.pop()
|
||||
nav_list.stackIndex.pop()
|
||||
var index = nav_list.stackIndex[nav_list.stackIndex.length-1]
|
||||
nav_list.enableStack = false
|
||||
nav_list.currentIndex = index
|
||||
nav_list.enableStack = true
|
||||
d.stackItems.pop()
|
||||
var item = d.stackItems[d.stackItems.length-1]
|
||||
d.enableStack = false
|
||||
if(item.idx<(nav_list.count - layout_footer.count)){
|
||||
layout_footer.currentIndex = -1
|
||||
}else{
|
||||
console.debug(item.idx-(nav_list.count-layout_footer.count))
|
||||
layout_footer.currentIndex = item.idx-(nav_list.count-layout_footer.count)
|
||||
}
|
||||
nav_list.currentIndex = item.idx
|
||||
d.enableStack = true
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
@ -340,17 +467,17 @@ Item {
|
||||
iconSize: 15
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 40
|
||||
visible: displayMode === FluNavigationView.Minimal
|
||||
visible: d.isMinimal
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: {
|
||||
displaMinimalMenu = !displaMinimalMenu
|
||||
d.enableNavigationPanel = !d.enableNavigationPanel
|
||||
}
|
||||
}
|
||||
|
||||
Image{
|
||||
id:image_logo
|
||||
Layout.preferredHeight: 20
|
||||
Layout.preferredWidth: 20
|
||||
source: control.logo
|
||||
Layout.leftMargin: {
|
||||
if(btn_nav.visible){
|
||||
return 12
|
||||
@ -361,7 +488,7 @@ Item {
|
||||
}
|
||||
FluText{
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text:root.title
|
||||
text:control.title
|
||||
Layout.leftMargin: 12
|
||||
fontStyle: FluText.Body
|
||||
}
|
||||
@ -370,12 +497,12 @@ Item {
|
||||
|
||||
Item{
|
||||
anchors{
|
||||
left: displayMode === FluNavigationView.Minimal ? parent.left : layout_list.right
|
||||
left: d.isMinimal || d.isCompactAndPanel ? parent.left : layout_list.right
|
||||
top: nav_app_bar.bottom
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
leftMargin: d.isCompactAndPanel ? 50 : 0
|
||||
}
|
||||
|
||||
StackView{
|
||||
id:nav_swipe
|
||||
anchors.fill: parent
|
||||
@ -395,19 +522,39 @@ Item {
|
||||
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
enabled: (displayMode === FluNavigationView.Minimal && displaMinimalMenu)
|
||||
enabled: d.isMinimalAndPanel||d.isCompactAndPanel
|
||||
onClicked: {
|
||||
displaMinimalMenu = false
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
id:layout_list
|
||||
width: 300
|
||||
width: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
return 50
|
||||
}
|
||||
return 300
|
||||
}
|
||||
Behavior on width{
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
Behavior on x{
|
||||
id:anim_layout_list_x
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
border.color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,230/255,234/255,1)
|
||||
border.width: displayMode === FluNavigationView.Minimal ? 1 : 0
|
||||
border.width: d.isMinimal || d.isCompactAndPanel ? 1 : 0
|
||||
color: {
|
||||
if(displayMode === FluNavigationView.Minimal){
|
||||
if(d.isMinimal || d.isCompactAndPanel){
|
||||
return FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
}
|
||||
if(window && window.active){
|
||||
@ -415,64 +562,62 @@ Item {
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
}
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
x: {
|
||||
if(displayMode !== FluNavigationView.Minimal)
|
||||
return 0
|
||||
return (displayMode === FluNavigationView.Minimal && displaMinimalMenu) ? 0 : -width
|
||||
}
|
||||
Behavior on x{
|
||||
id:anim_navi
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color{
|
||||
ColorAnimation {
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
|
||||
x: {
|
||||
if(d.displayMode !== FluNavigationView.Minimal)
|
||||
return 0
|
||||
return d.isMinimalAndPanel ? 0 : -width
|
||||
}
|
||||
Item{
|
||||
id:layout_header
|
||||
width: layout_list.width
|
||||
clip: true
|
||||
y:nav_app_bar.height
|
||||
height: {
|
||||
if(loader_auto_suggest_box.item){
|
||||
return loader_auto_suggest_box.item.height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
height: 38
|
||||
Loader{
|
||||
id:loader_auto_suggest_box
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: autoSuggestBox
|
||||
visible: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
visible:d.isCompactAndNotPanel
|
||||
hoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
|
||||
pressedColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
|
||||
normalColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
|
||||
width:38
|
||||
height:34
|
||||
x:6
|
||||
y:2
|
||||
iconSize: 15
|
||||
iconSource: {
|
||||
if(loader_auto_suggest_box.item){
|
||||
return loader_auto_suggest_box.item.autoSuggestBoxReplacement
|
||||
}
|
||||
return 0
|
||||
}
|
||||
onClicked: {
|
||||
d.enableNavigationPanel = !d.enableNavigationPanel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView{
|
||||
id:nav_list
|
||||
property bool enableStack: true
|
||||
property var stackIndex: []
|
||||
clip: true
|
||||
anchors{
|
||||
top: layout_header.bottom
|
||||
topMargin: 6
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: layout_footer.top
|
||||
}
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model:d.handleItems()
|
||||
highlightMoveDuration: 150
|
||||
currentIndex: -1
|
||||
onCurrentIndexChanged: {
|
||||
if(enableStack){
|
||||
stackIndex.push(currentIndex)
|
||||
}
|
||||
}
|
||||
highlight: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
@ -487,11 +632,26 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model:handleItems()
|
||||
onCurrentIndexChanged: {
|
||||
if(d.enableStack){
|
||||
var item = model[currentIndex]
|
||||
if(item instanceof FluPaneItem){
|
||||
item.tap()
|
||||
d.stackItems.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
currentIndex: -1
|
||||
anchors{
|
||||
top: layout_header.bottom
|
||||
topMargin: 6
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: layout_footer.top
|
||||
}
|
||||
delegate: Loader{
|
||||
property var model: modelData
|
||||
property var position: index
|
||||
property var idx: index
|
||||
property int type: 0
|
||||
sourceComponent: {
|
||||
if(modelData instanceof FluPaneItem){
|
||||
@ -506,24 +666,43 @@ Item {
|
||||
if(modelData instanceof FluPaneItemExpander){
|
||||
return com_panel_item_expander
|
||||
}
|
||||
if(modelData instanceof FluPaneItemEmpty){
|
||||
return com_panel_item_empty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView{
|
||||
id:layout_footer
|
||||
clip: true
|
||||
width: layout_list.width
|
||||
height: childrenRect.height
|
||||
anchors.bottom: parent.bottom
|
||||
interactive: false
|
||||
currentIndex: -1
|
||||
model: {
|
||||
if(footerItems){
|
||||
return footerItems.children
|
||||
}
|
||||
}
|
||||
currentIndex: -1
|
||||
highlightMoveDuration: 150
|
||||
highlight: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
height: 18
|
||||
radius: 1.5
|
||||
color: FluTheme.primaryColor.dark
|
||||
width: 3
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: Loader{
|
||||
property var model: modelData
|
||||
property var position: index
|
||||
property var idx: index
|
||||
property int type: 1
|
||||
sourceComponent: {
|
||||
if(modelData instanceof FluPaneItem){
|
||||
@ -540,27 +719,91 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function handleItems(){
|
||||
var idx = 0
|
||||
var data = []
|
||||
if(items){
|
||||
for(var i=0;i<items.children.length;i++){
|
||||
var item = items.children[i]
|
||||
item.idx = idx
|
||||
data.push(item)
|
||||
idx++
|
||||
if(item instanceof FluPaneItemExpander){
|
||||
for(var j=0;j<item.children.length;j++){
|
||||
var itemChild = item.children[j]
|
||||
itemChild.parent = item
|
||||
itemChild.idx = idx
|
||||
data.push(itemChild)
|
||||
idx++
|
||||
Popup{
|
||||
property var childModel
|
||||
id:control_popup
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
background: Rectangle{
|
||||
width: 160
|
||||
radius: 4
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
|
||||
height: 38*Math.min(Math.max(list_view.count,1),8)
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
currentIndex: -1
|
||||
model: control_popup.childModel
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
delegate:FluControl{
|
||||
width: 160
|
||||
padding:10
|
||||
background: Rectangle{
|
||||
color: {
|
||||
if(hovered){
|
||||
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
contentItem: FluText{
|
||||
text:modelData.title
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
if(modelData.tapFunc){
|
||||
modelData.tapFunc()
|
||||
}else{
|
||||
nav_list.currentIndex = idx
|
||||
layout_footer.currentIndex = -1
|
||||
if(d.isMinimal || d.isCompact){
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
control_popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
function showPopup(pos,model){
|
||||
control_popup.x = pos.x
|
||||
control_popup.y = pos.y
|
||||
control_popup.childModel = model
|
||||
control_popup.open()
|
||||
}
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer_anim_x_enable
|
||||
interval: 150
|
||||
onTriggered: {
|
||||
anim_layout_list_x.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
function collapseAll(){
|
||||
for(var i=0;i<nav_list.model.length;i++){
|
||||
var item = nav_list.model[i]
|
||||
if(item instanceof FluPaneItemExpander){
|
||||
item.isExpand = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentIndex(index){
|
||||
nav_list.currentIndex = index
|
||||
}
|
||||
|
||||
function getItems(){
|
||||
@ -571,10 +814,6 @@ Item {
|
||||
nav_swipe.push(url)
|
||||
}
|
||||
|
||||
function setCurrentIndex(index){
|
||||
nav_list.currentIndex = index
|
||||
}
|
||||
|
||||
function getCurrentIndex(){
|
||||
return nav_list.currentIndex
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import QtQuick.Layouts
|
||||
|
||||
@ -7,6 +8,8 @@ Item {
|
||||
|
||||
|
||||
signal requestPage(int page,int count)
|
||||
property string previousText: "<上一页"
|
||||
property string nextText: "下一页>"
|
||||
property int pageCurrent: 0
|
||||
property int itemCount: 0
|
||||
property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0
|
||||
@ -28,7 +31,7 @@ Item {
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent<=1
|
||||
text:"<上一页"
|
||||
text:control.previousText
|
||||
onClicked: {
|
||||
control.calcNewPage(control.pageCurrent-1);
|
||||
}
|
||||
@ -76,8 +79,7 @@ Item {
|
||||
}
|
||||
FluToggleButton{
|
||||
property int pageNumber:control.pageCount
|
||||
visible: control.pageCount>0
|
||||
enabled: control.pageCurrent>1
|
||||
visible: control.pageCount>1
|
||||
selected: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
onClicked: {
|
||||
@ -88,7 +90,7 @@ Item {
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent>=control.pageCount
|
||||
text:"下一页>"
|
||||
text:control.nextText
|
||||
onClicked: {
|
||||
control.calcNewPage(control.pageCurrent+1);
|
||||
}
|
||||
|
7
src/controls/FluPaneItemEmpty.qml
Normal file
@ -0,0 +1,7 @@
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluApp.uuid()
|
||||
property var parent
|
||||
property int idx
|
||||
}
|
@ -2,12 +2,10 @@
|
||||
import FluentUI
|
||||
|
||||
FluObject {
|
||||
readonly property int flag : 3
|
||||
readonly property string key : FluApp.uuid()
|
||||
property string title
|
||||
property int icon
|
||||
property bool isExpand: false
|
||||
property var parent
|
||||
property int idx
|
||||
signal tap
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
readonly property int flag : 1
|
||||
readonly property string key : FluApp.uuid()
|
||||
property string title
|
||||
property var parent
|
||||
|
@ -1,7 +1,6 @@
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
readonly property int flag : 2
|
||||
readonly property string key : FluApp.uuid()
|
||||
property var parent
|
||||
property int idx
|
||||
|
@ -9,14 +9,6 @@ Item{
|
||||
property bool shadow: true
|
||||
default property alias contentItem: container.data
|
||||
|
||||
Rectangle{
|
||||
id:container
|
||||
width: control.width
|
||||
height: control.height
|
||||
opacity: 0
|
||||
color:control.color
|
||||
}
|
||||
|
||||
FluShadow{
|
||||
anchors.fill: container
|
||||
radius: control.radius[0]
|
||||
@ -28,6 +20,14 @@ Item{
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
id:container
|
||||
width: control.width
|
||||
height: control.height
|
||||
opacity: 0
|
||||
color:control.color
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: canvas
|
||||
anchors.fill: parent
|
||||
|
@ -10,7 +10,6 @@ ScrollBar {
|
||||
property color handlePressColor: Qt.darker(handleNormalColor)
|
||||
property bool expand: false
|
||||
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
@ -144,7 +143,7 @@ ScrollBar {
|
||||
iconSize: 8
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 4
|
||||
visible:vertical && expand
|
||||
visible:vertical && expand && item_react.opacity
|
||||
onClicked:{
|
||||
decrease()
|
||||
}
|
||||
@ -152,7 +151,7 @@ ScrollBar {
|
||||
FluIconButton{
|
||||
id:btn_bottom
|
||||
iconSource: FluentIcons.CaretSolidDown
|
||||
visible:vertical && expand
|
||||
visible:vertical && expand && item_react.opacity
|
||||
width:10
|
||||
height:10
|
||||
iconSize: 8
|
||||
@ -167,7 +166,7 @@ ScrollBar {
|
||||
FluIconButton{
|
||||
id:btn_left
|
||||
iconSource: FluentIcons.CaretSolidLeft
|
||||
visible:!vertical && expand
|
||||
visible:!vertical && expand && item_react.opacity
|
||||
width:10
|
||||
height:10
|
||||
iconSize: 8
|
||||
@ -182,7 +181,7 @@ ScrollBar {
|
||||
FluIconButton{
|
||||
id:btn_right
|
||||
iconSource: FluentIcons.CaretSolidRight
|
||||
visible:!vertical && expand
|
||||
visible:!vertical && expand && item_react.opacity
|
||||
width:10
|
||||
height:10
|
||||
iconSize: 8
|
||||
|
108
src/controls/FluStatusView.qml
Normal file
@ -0,0 +1,108 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
|
||||
enum StatusMode {
|
||||
Loading,
|
||||
Empty,
|
||||
Error,
|
||||
Success
|
||||
}
|
||||
default property alias content: container.data
|
||||
property int statusMode: FluStatusView.Loading
|
||||
signal errorClicked
|
||||
|
||||
Item{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
visible: statusMode === FluStatusView.Success
|
||||
}
|
||||
|
||||
FluArea{
|
||||
paddings: 0
|
||||
border.width: 0
|
||||
anchors.fill: container
|
||||
visible: opacity
|
||||
opacity: statusMode === FluStatusView.Loading
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
ColumnLayout{
|
||||
anchors.centerIn: parent
|
||||
visible: statusMode === FluStatusView.Loading
|
||||
FluProgressRing{
|
||||
indeterminate: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
FluText{
|
||||
text:"正在加载..."
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluArea{
|
||||
paddings: 0
|
||||
border.width: 0
|
||||
anchors.fill: container
|
||||
visible: opacity
|
||||
opacity: statusMode === FluStatusView.Empty
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
ColumnLayout{
|
||||
anchors.centerIn: parent
|
||||
visible: statusMode === FluStatusView.Empty
|
||||
FluText{
|
||||
text:"空空如也"
|
||||
fontStyle: FluText.BodyStrong
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluArea{
|
||||
paddings: 0
|
||||
border.width: 0
|
||||
anchors.fill: container
|
||||
visible: opacity
|
||||
opacity: statusMode === FluStatusView.Error
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
ColumnLayout{
|
||||
anchors.centerIn: parent
|
||||
FluText{
|
||||
text:"页面出错了..."
|
||||
fontStyle: FluText.BodyStrong
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
FluFilledButton{
|
||||
id:btn_error
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text:"重新加载"
|
||||
onClicked:{
|
||||
errorClicked.call()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showSuccessView(){
|
||||
statusMode = FluStatusView.Success
|
||||
}
|
||||
function showLoadingView(){
|
||||
statusMode = FluStatusView.Loading
|
||||
}
|
||||
function showEmptyView(){
|
||||
statusMode = FluStatusView.Empty
|
||||
}
|
||||
function showErrorView(){
|
||||
statusMode = FluStatusView.Error
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,8 @@ FluControl {
|
||||
|
||||
property bool disabled: false
|
||||
property color normalColor: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.3) : Qt.lighter(normalColor,1.3)
|
||||
property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.15) : Qt.lighter(normalColor,1.15)
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.3) : Qt.lighter(normalColor,1.3)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property bool textBold: true
|
||||
|
||||
@ -36,6 +37,9 @@ FluControl {
|
||||
if(disabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,5 @@ FluControl {
|
||||
}
|
||||
}
|
||||
}
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
|
@ -70,5 +70,7 @@
|
||||
<file>controls/FluTableView.qml</file>
|
||||
<file>controls/FluPagination.qml</file>
|
||||
<file>controls/FluToggleButton.qml</file>
|
||||
<file>controls/FluStatusView.qml</file>
|
||||
<file>controls/FluPaneItemEmpty.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|