Compare commits
72 Commits
Author | SHA1 | Date | |
---|---|---|---|
2acb3c34bd | |||
1df3b4ba96 | |||
5ea3cb1054 | |||
5afd2ec518 | |||
59527fc954 | |||
c26fdfaee3 | |||
878dbd668b | |||
b10a0752fb | |||
51e73e7f8e | |||
3a46fd11c6 | |||
70f048f629 | |||
1f2d0d9b9f | |||
09e87e0fb8 | |||
0603a7603d | |||
d9a4f01e20 | |||
93709cd1dd | |||
0000e557a7 | |||
d2183e350e | |||
47caf4bb52 | |||
6fb9ee41fb | |||
b349c22434 | |||
12fa3487bb | |||
a76806645a | |||
738db25c2c | |||
9f8a5f5646 | |||
c59c07e756 | |||
2084b5afa3 | |||
f8d717f41b | |||
be58fc5e7d | |||
1c0bc7208a | |||
d89aaec062 | |||
13abd275b4 | |||
e8460c2409 | |||
6de1b9d78f | |||
64fa2b6370 | |||
8970a0c09a | |||
e7cea72825 | |||
93186edfbe | |||
e60883bc60 | |||
47ab4dabbd | |||
206669e5f0 | |||
08457dc75e | |||
0c59a233ea | |||
fcb8da2c50 | |||
a8701256d4 | |||
8eaa4b6cbb | |||
af80a882d0 | |||
9d89328a43 | |||
0d4477437f | |||
6b3e73ce0b | |||
625bc74e26 | |||
731e4f27b4 | |||
fce64eccc6 | |||
689e0805e7 | |||
986f1242dd | |||
a9c97a5c56 | |||
81e78834d0 | |||
5279a2c7b2 | |||
6391fc8dc6 | |||
9cf4b4b1af | |||
32c0b4ccd6 | |||
b2bfdd17da | |||
27db8160d4 | |||
ed0c9048b0 | |||
de2c891912 | |||
16daeb5268 | |||
0b37ddcb6e | |||
d2e3e6dd4b | |||
1e5bd75123 | |||
1b97b197a4 | |||
936a310ca6 | |||
3236be8a7f |
21
.github/workflows/macos.yml
vendored
@ -16,26 +16,25 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11.0]
|
||||
os: [macos-12]
|
||||
qt_ver: [6.4.3]
|
||||
qt_arch: [clang_64]
|
||||
env:
|
||||
targetName: example
|
||||
steps:
|
||||
# macos 11.0 默认环境变了,要指定
|
||||
- name: prepare env
|
||||
if: ${{ matrix.os == 'macos-11.0' }}
|
||||
run: |
|
||||
softwareupdate --all --install --force
|
||||
sudo xcode-select --print-path
|
||||
sudo xcode-select --switch /Library/Developer/CommandLineTools
|
||||
- name: '⚙️ Cache Qt'
|
||||
id: cache-qt
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.workspace }}/Qt
|
||||
key: ${{runner.os}}-qtcachedir-${{ matrix.qt_ver }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
cached: 'false'
|
||||
cache: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools'
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
@ -60,6 +59,6 @@ jobs:
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: bin/release/${{ env.targetName }}.dmg
|
||||
asset_name: ${{ env.targetName }}_${{ matrix.os }}_${{ matrix.qt_ver }}.dmg
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}.dmg
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
16
.github/workflows/ubuntu.yml
vendored
@ -24,15 +24,21 @@ jobs:
|
||||
env:
|
||||
targetName: example
|
||||
steps:
|
||||
- name: '⚙️ Cache Qt'
|
||||
id: cache-qt
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.workspace }}/Qt
|
||||
key: ${{runner.os}}-qtcachedir-${{ matrix.qt_ver }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
cached: 'false'
|
||||
cache: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools'
|
||||
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
|
||||
@ -44,6 +50,8 @@ jobs:
|
||||
uses: miurahr/install-linuxdeploy-action@v1
|
||||
with:
|
||||
plugins: qt appimage
|
||||
- name: Check if svg file exists
|
||||
run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi
|
||||
# 打包
|
||||
- name: package
|
||||
run: |
|
||||
@ -64,6 +72,6 @@ jobs:
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ env.targetName }}.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ matrix.os }}_${{ matrix.qt_ver }}.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}.AppImage
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
76
.github/workflows/windows-mingw.yml
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
name: Windows MinGW
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.pro'
|
||||
- 'src/**'
|
||||
- '.github/workflows/windows-mingw.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.pro'
|
||||
- 'src/**'
|
||||
- '.github/workflows/windows-mingw.yml'
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- qt_arch: win64_mingw
|
||||
qt_ver: 6.4.3
|
||||
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
||||
qt_tools_mingw_install: mingw900_64
|
||||
env:
|
||||
targetName: example.exe
|
||||
fileName: example
|
||||
steps:
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
cache: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Qt6 environment configuration
|
||||
if: ${{ startsWith( matrix.qt_ver, 6 ) }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "${{ env.Qt6_DIR }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
Write-Output "${{ env.Qt6_DIR }}/../../Tools/${{ matrix.qt_tools_mingw_install }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
- name: where is qmake & where is mingw32-make
|
||||
shell: pwsh
|
||||
run: |
|
||||
Get-Command -Name 'qmake' | Format-List
|
||||
Get-Command -Name 'mingw32-make' | Format-List
|
||||
- name: mingw-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
qmake
|
||||
mingw32-make
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "::set-output name=packageName::$name"
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
15
.github/workflows/windows.yml
vendored
@ -16,10 +16,11 @@ jobs:
|
||||
name: Build
|
||||
# 运行平台, windows-latest目前是windows server 2019
|
||||
# 参考文档 https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md
|
||||
runs-on: windows-2019
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
# 矩阵配置
|
||||
matrix:
|
||||
os: [windows-2019]
|
||||
include:
|
||||
- qt_ver: 6.4.3
|
||||
qt_arch: win64_msvc2019_64
|
||||
@ -30,6 +31,12 @@ jobs:
|
||||
fileName: example
|
||||
# 步骤
|
||||
steps:
|
||||
- name: '⚙️ Cache Qt'
|
||||
id: cache-qt
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.workspace }}\Qt
|
||||
key: ${{runner.os}}-qtcachedir-${{ matrix.qt_ver }}
|
||||
# 安装Qt
|
||||
- name: Install Qt
|
||||
# 使用外部action。这个action专门用来安装Qt
|
||||
@ -37,8 +44,8 @@ jobs:
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
cached: 'false'
|
||||
modules: 'qt5compat qtmultimedia qtshadertools'
|
||||
cache: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
# 拉取代码
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@ -80,6 +87,6 @@ jobs:
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
3
.gitignore
vendored
@ -32,4 +32,5 @@ target_wrapper.*
|
||||
CMakeLists.txt.user*
|
||||
|
||||
src/build-preset/plugins.qmltypes
|
||||
bin
|
||||
bin
|
||||
.DS_Store
|
5
CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(FluentUI VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(example)
|
21
License
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 zhuzichu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
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 |
@ -2,13 +2,16 @@
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtMultimedia
|
||||
import FluentUI
|
||||
|
||||
Window {
|
||||
id:app
|
||||
color: "#00000000"
|
||||
//初始化一个MediaPlayer,解决macos切换到T_MediaPalyer页面崩溃问题
|
||||
MediaPlayer{}
|
||||
Component.onCompleted: {
|
||||
FluApp.init(app,properties)
|
||||
FluApp.init(app)
|
||||
FluTheme.frameless = ("windows" === Qt.platform.os)
|
||||
FluTheme.dark = false
|
||||
FluApp.routes = {
|
||||
@ -16,6 +19,7 @@ Window {
|
||||
"/about":"qrc:/page/AboutPage.qml",
|
||||
"/login":"qrc:/page/LoginPage.qml",
|
||||
"/chat":"qrc:/page/ChatPage.qml",
|
||||
"/media":"qrc:/page/MediaPage.qml",
|
||||
}
|
||||
FluApp.initialRoute = "/"
|
||||
FluApp.run()
|
||||
|
7
example/AppInfo.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "AppInfo.h"
|
||||
|
||||
AppInfo::AppInfo(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
version("1.2.4");
|
||||
}
|
15
example/AppInfo.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef APPINFO_H
|
||||
#define APPINFO_H
|
||||
|
||||
#include <QObject>
|
||||
#include "stdafx.h"
|
||||
|
||||
class AppInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,version)
|
||||
public:
|
||||
explicit AppInfo(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // APPINFO_H
|
85
example/CMakeLists.txt
Normal file
@ -0,0 +1,85 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(example)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
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()
|
||||
set(platform 32)
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../bin/debug)
|
||||
else()
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../bin/release)
|
||||
endif()
|
||||
|
||||
find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED)
|
||||
|
||||
set(SOURCES
|
||||
ChatController.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
ChatController.h
|
||||
)
|
||||
|
||||
set(RESOURCES
|
||||
qml.qrc
|
||||
)
|
||||
|
||||
set(RC_ICONS
|
||||
favicon.ico
|
||||
)
|
||||
|
||||
qt_add_resources(QT_RESOURCES ${RESOURCES})
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QT_RESOURCES} ${RC_ICONS})
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/msvc/*.dll)
|
||||
else()
|
||||
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
|
||||
QT_DEPRECATED_WARNINGS
|
||||
QT_NO_WARNING_OUTPUT
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Quick
|
||||
Qt6::QuickControls2
|
||||
Qt6::Concurrent
|
||||
Qt6::Network
|
||||
Qt6::Multimedia
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE WIN32 _WINDOWS)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST Info.plist
|
||||
)
|
||||
endif()
|
@ -67,7 +67,6 @@ FluContentPage {
|
||||
width:parent.width
|
||||
wrapMode: Text.WrapAnywhere
|
||||
text: modelData.name
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -11,9 +12,10 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 106
|
||||
paddings: 10
|
||||
@ -99,5 +101,19 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'Rectangle{
|
||||
width: 40
|
||||
height: 40
|
||||
radius: 8
|
||||
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||
FluBadge{
|
||||
count: 100
|
||||
isDot: false
|
||||
color: Qt.rgba(82/255,196/255,26/255,1)
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,15 +3,15 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
title:"Buttons"
|
||||
|
||||
spacing: 20
|
||||
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluText{
|
||||
Layout.topMargin: 20
|
||||
@ -19,9 +19,10 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
|
||||
FluTextButton{
|
||||
disabled:text_button_switch.selected
|
||||
@ -48,11 +49,21 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTextButton{
|
||||
text:"Text Button"
|
||||
onClicked: {
|
||||
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
|
||||
FluButton{
|
||||
disabled:button_switch.selected
|
||||
@ -79,10 +90,20 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluButton{
|
||||
text:"Standard Button"
|
||||
onClicked: {
|
||||
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
Layout.topMargin: 20
|
||||
paddings: 10
|
||||
|
||||
FluFilledButton{
|
||||
@ -110,13 +131,63 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluFilledButton{
|
||||
text:"Filled Button"
|
||||
onClicked: {
|
||||
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
Layout.topMargin: 20
|
||||
paddings: 10
|
||||
|
||||
FluToggleButton{
|
||||
disabled:toggle_button_switch.selected
|
||||
text:"Toggle Button"
|
||||
onClicked: {
|
||||
selected = !selected
|
||||
}
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
}
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id:toggle_button_switch
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text:"Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluToggleButton{
|
||||
text:"Toggle Button"
|
||||
onClicked: {
|
||||
selected = !selected
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
|
||||
Layout.topMargin: 20
|
||||
FluIconButton{
|
||||
iconSource:FluentIcons.ChromeCloseContrast
|
||||
disabled:icon_button_switch.selected
|
||||
@ -143,12 +214,21 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluIconButton{
|
||||
iconSource:FluentIcons.ChromeCloseContrast
|
||||
onClicked: {
|
||||
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
|
||||
Layout.topMargin: 20
|
||||
FluDropDownButton{
|
||||
disabled:drop_down_button_switch.selected
|
||||
text:"DropDownButton"
|
||||
@ -184,12 +264,32 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluDropDownButton{
|
||||
text:"DropDownButton"
|
||||
items:[
|
||||
FluMenuItem{
|
||||
text:"Menu_1"
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Menu_2"
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Menu_3"
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Menu_4"
|
||||
}
|
||||
]
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 100
|
||||
paddings: 10
|
||||
|
||||
Layout.topMargin: 20
|
||||
ColumnLayout{
|
||||
spacing: 8
|
||||
anchors{
|
||||
@ -225,13 +325,23 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluRadioButton{
|
||||
selected:true
|
||||
text:"Text Button"
|
||||
onClicked: {
|
||||
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
|
||||
Layout.topMargin: 20
|
||||
FluCheckBox{
|
||||
disabled:check_box_switch.selected
|
||||
text:"Check Box"
|
||||
@ -240,8 +350,6 @@ FluScrollablePage{
|
||||
left: parent.left
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
anchors{
|
||||
@ -255,6 +363,10 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluCheckBox{
|
||||
text:"Check Box"
|
||||
}'
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,18 +11,25 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 350
|
||||
paddings: 10
|
||||
FluCalendarView{
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluCalendarView{
|
||||
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 80
|
||||
paddings: 10
|
||||
@ -34,5 +42,11 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluCalendarPicker{
|
||||
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,9 +11,10 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 370
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
@ -35,4 +37,14 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluCarousel{
|
||||
width: 400
|
||||
height: 300
|
||||
Component.onCompleted: {
|
||||
setData([{url:"qrc:/res/image/banner_1.jpg"},{url:"qrc:/res/image/banner_2.jpg"},{url:"qrc:/res/image/banner_3.jpg"}])
|
||||
}
|
||||
}'
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,14 +11,28 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluCheckBox{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
Row{
|
||||
spacing: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
FluCheckBox{
|
||||
}
|
||||
FluCheckBox{
|
||||
text:"Text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluCheckBox{
|
||||
Layout.topMargin: 20
|
||||
text:"Text"
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluCheckBox{
|
||||
text:"Text"
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,9 +11,10 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 280
|
||||
Layout.topMargin: 20
|
||||
paddings: 10
|
||||
@ -37,9 +39,15 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluColorView{
|
||||
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 60
|
||||
paddings: 10
|
||||
@ -54,6 +62,12 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluColorPicker{
|
||||
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,44 +11,42 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 80
|
||||
paddings: 10
|
||||
|
||||
ColumnLayout{
|
||||
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"showYear=true"
|
||||
}
|
||||
|
||||
FluDatePicker{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluDatePicker{
|
||||
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 80
|
||||
paddings: 10
|
||||
|
||||
ColumnLayout{
|
||||
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"showYear=false"
|
||||
}
|
||||
@ -56,8 +55,13 @@ FluScrollablePage{
|
||||
showYear:false
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluDatePicker{
|
||||
showYear:false
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,6 +11,40 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
FluButton{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.topMargin: 20
|
||||
text:"Show Dialog"
|
||||
onClicked: {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluContentDialog{
|
||||
id:dialog
|
||||
title:"友情提示"
|
||||
message:"确定要退出程序么?"
|
||||
negativeText:"取消"
|
||||
onNegativeClicked:{
|
||||
showSuccess("点击取消按钮")
|
||||
}
|
||||
positiveText:"确定"
|
||||
onPositiveClicked:{
|
||||
showSuccess("点击确定按钮")
|
||||
}
|
||||
}
|
||||
dialog.open()
|
||||
'
|
||||
}
|
||||
|
||||
FluContentDialog{
|
||||
id:dialog
|
||||
@ -25,11 +60,5 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
Layout.topMargin: 20
|
||||
text:"Show Dialog"
|
||||
onClicked: {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,56 +11,99 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluExpander{
|
||||
headerText:"打开一个单选框"
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: layout_column.height+40
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
spacing: 8
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: 15
|
||||
leftMargin: 15
|
||||
}
|
||||
Repeater{
|
||||
id:repeater
|
||||
property int selecIndex : 0
|
||||
model: 3
|
||||
delegate: FluRadioButton{
|
||||
selected : repeater.selecIndex===index
|
||||
text:"Radio Button_"+index
|
||||
onClicked:{
|
||||
repeater.selecIndex = index
|
||||
Column{
|
||||
id:layout_column
|
||||
spacing: 15
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:parent.left
|
||||
}
|
||||
|
||||
FluExpander{
|
||||
headerText:"打开一个单选框"
|
||||
Layout.topMargin: 20
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
spacing: 8
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: 15
|
||||
leftMargin: 15
|
||||
}
|
||||
Repeater{
|
||||
id:repeater
|
||||
property int selecIndex : 0
|
||||
model: 3
|
||||
delegate: FluRadioButton{
|
||||
selected : repeater.selecIndex===index
|
||||
text:"Radio Button_"+index
|
||||
onClicked:{
|
||||
repeater.selecIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluExpander{
|
||||
Layout.topMargin: 20
|
||||
headerText:"打开一个滑动文本框"
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
Flickable{
|
||||
id:scrollview
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
contentWidth: width
|
||||
contentHeight: text_info.height
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
FluText{
|
||||
id:text_info
|
||||
width: scrollview.width
|
||||
wrapMode: Text.WrapAnywhere
|
||||
padding: 14
|
||||
text:"先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。宫中府中,俱为一体;陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明;故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏。臣不胜受恩感激。今当远离,临表涕零,不知所言。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
FluExpander{
|
||||
Layout.topMargin: 20
|
||||
headerText:"打开一个滑动文本框"
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
Flickable{
|
||||
id:scrollview
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
contentWidth: width
|
||||
contentHeight: text_info.height
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
FluText{
|
||||
id:text_info
|
||||
width: scrollview.width
|
||||
wrapMode: Text.WrapAnywhere
|
||||
padding: 14
|
||||
text:"先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。宫中府中,俱为一体;陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明;故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏。臣不胜受恩感激。今当远离,临表涕零,不知所言。"
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluExpander{
|
||||
headerText:"打开一个单选框"
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
Flickable{
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
contentWidth: width
|
||||
contentHeight: text_info.height
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
FluText{
|
||||
id:text_info
|
||||
width: scrollview.width
|
||||
wrapMode: Text.WrapAnywhere
|
||||
padding: 14
|
||||
text:"先帝创业未半而中道崩殂,今天下三分......""
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
120
example/T_FlipView.qml
Normal file
@ -0,0 +1,120 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"FlipView"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 340
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
ColumnLayout{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
FluText{
|
||||
text:"水平方向的FlipView"
|
||||
}
|
||||
FluFlipView{
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_2.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_3.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluFlipView{
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 340
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
ColumnLayout{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
FluText{
|
||||
text:"垂直方向的FlipView"
|
||||
}
|
||||
FluFlipView{
|
||||
vertical:true
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
sourceSize: Qt.size(400,300)
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_2.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_3.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluFlipView{
|
||||
vertical:true
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Image{
|
||||
source: "qrc:/res/image/banner_1.jpg"
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
}
|
@ -129,7 +129,7 @@ FluScrollablePage{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onWheel: {
|
||||
onWheel: (wheel)=>{
|
||||
if (wheel.angleDelta.y > 0) scrollbar_header.decrease()
|
||||
else scrollbar_header.increase()
|
||||
}
|
||||
@ -142,20 +142,6 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
|
||||
ListModel{
|
||||
id:model_added
|
||||
Component.onCompleted: {
|
||||
append(ItemsOriginal.getRecentlyAddedData())
|
||||
}
|
||||
}
|
||||
|
||||
ListModel{
|
||||
id:model_update
|
||||
Component.onCompleted: {
|
||||
append(ItemsOriginal.getRecentlyUpdatedData())
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_item
|
||||
Item{
|
||||
@ -187,7 +173,7 @@ FluScrollablePage{
|
||||
id:item_icon
|
||||
height: 40
|
||||
width: 40
|
||||
source: model.image
|
||||
source: modelData.image
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
@ -197,7 +183,7 @@ FluScrollablePage{
|
||||
|
||||
FluText{
|
||||
id:item_title
|
||||
text:model.title
|
||||
text:modelData.title
|
||||
fontStyle: FluText.BodyStrong
|
||||
anchors{
|
||||
left: item_icon.right
|
||||
@ -208,7 +194,7 @@ FluScrollablePage{
|
||||
|
||||
FluText{
|
||||
id:item_desc
|
||||
text:model.desc
|
||||
text:modelData.desc
|
||||
color:FluColors.Grey120
|
||||
wrapMode: Text.WrapAnywhere
|
||||
elide: Text.ElideRight
|
||||
@ -241,7 +227,7 @@ FluScrollablePage{
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
ItemsOriginal.startPageByItem(model)
|
||||
ItemsOriginal.startPageByItem(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,7 +246,7 @@ FluScrollablePage{
|
||||
implicitHeight: contentHeight
|
||||
cellHeight: 120
|
||||
cellWidth: 320
|
||||
model:model_added
|
||||
model:ItemsOriginal.getRecentlyAddedData()
|
||||
interactive: false
|
||||
delegate: com_item
|
||||
}
|
||||
@ -278,7 +264,7 @@ FluScrollablePage{
|
||||
cellHeight: 120
|
||||
cellWidth: 320
|
||||
interactive: false
|
||||
model: model_update
|
||||
model: ItemsOriginal.getRecentlyUpdatedData()
|
||||
delegate: com_item
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,33 +11,53 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluButton{
|
||||
text:"Info"
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
onClicked: {
|
||||
showInfo("这是一个Info样式的InfoBar")
|
||||
height: 200
|
||||
paddings: 10
|
||||
ColumnLayout{
|
||||
spacing: 14
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
FluButton{
|
||||
text:"Info"
|
||||
onClicked: {
|
||||
showInfo("这是一个Info样式的InfoBar")
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"Warning"
|
||||
onClicked: {
|
||||
showWarning("这是一个Warning样式的InfoBar")
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"Error"
|
||||
onClicked: {
|
||||
showError("这是一个Error样式的InfoBar")
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"Success"
|
||||
onClicked: {
|
||||
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"Warning"
|
||||
Layout.topMargin: 20
|
||||
onClicked: {
|
||||
showWarning("这是一个Warning样式的InfoBar")
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"Error"
|
||||
Layout.topMargin: 20
|
||||
onClicked: {
|
||||
showError("这是一个Error样式的InfoBar")
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"Success"
|
||||
Layout.topMargin: 20
|
||||
onClicked: {
|
||||
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar")
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'showInfo("这是一个Info样式的InfoBar")
|
||||
|
||||
showWarning("这是一个Warning样式的InfoBar")
|
||||
|
||||
showError("这是一个Error样式的InfoBar")
|
||||
|
||||
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar")'
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,6 +11,7 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
onVisibleChanged: {
|
||||
if(visible){
|
||||
@ -18,9 +20,8 @@ FluScrollablePage{
|
||||
player.pause()
|
||||
}
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 320
|
||||
Layout.topMargin: 20
|
||||
paddings: 10
|
||||
@ -31,11 +32,34 @@ FluScrollablePage{
|
||||
}
|
||||
FluMediaPlayer{
|
||||
id:player
|
||||
// source:"http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4"
|
||||
source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
|
||||
// source:"http://video.chinanews.com/flv/2019/04/23/400/111773_web.mp4"
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
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"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,30 +11,66 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluButton{
|
||||
text:"左击菜单"
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 100
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
onClicked:{
|
||||
menu.popup()
|
||||
Column{
|
||||
id:layout_column
|
||||
spacing: 15
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:parent.left
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"左击菜单"
|
||||
Layout.topMargin: 20
|
||||
onClicked:{
|
||||
menu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"右击菜单"
|
||||
Layout.topMargin: 20
|
||||
onClicked: {
|
||||
showSuccess("请按鼠标右击")
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: {
|
||||
menu.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FluButton{
|
||||
text:"右击菜单"
|
||||
Layout.topMargin: 20
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluMenu{
|
||||
id:menu
|
||||
FluMenuItem:{
|
||||
text:"删除"
|
||||
onClicked: {
|
||||
showSuccess("请按鼠标右击")
|
||||
showError("删除")
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: {
|
||||
menu.popup()
|
||||
}
|
||||
}
|
||||
FluMenuItem:{
|
||||
text:"修改"
|
||||
onClicked: {
|
||||
showInfo"修改")
|
||||
}
|
||||
}
|
||||
}
|
||||
menu.popup()
|
||||
'
|
||||
}
|
||||
|
||||
FluMenu{
|
||||
id:menu
|
||||
@ -46,7 +83,7 @@ FluScrollablePage{
|
||||
FluMenuItem{
|
||||
text:"修改"
|
||||
onClicked: {
|
||||
showError("修改")
|
||||
showInfo("修改")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,18 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
property string password: ""
|
||||
property var loginPageRegister: registerForPageResult("/login")
|
||||
|
||||
title:"MultiWindow"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
|
||||
property string password: ""
|
||||
|
||||
property var loginPageRegister: registerForPageResult("/login")
|
||||
spacing: 0
|
||||
|
||||
Connections{
|
||||
target: loginPageRegister
|
||||
@ -24,11 +25,10 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 100
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
|
||||
Column{
|
||||
spacing: 15
|
||||
anchors{
|
||||
@ -46,9 +46,19 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluButton{
|
||||
text:"点击跳转"
|
||||
onClicked: {
|
||||
FluApp.navigate("/about")
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 130
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
@ -68,13 +78,30 @@ FluScrollablePage{
|
||||
loginPageRegister.launch({username:"zhuzichu"})
|
||||
}
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"登录窗口返回过来的密码->"+password
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'property var loginPageRegister: registerForPageResult("/login")
|
||||
|
||||
Connections{
|
||||
target: loginPageRegister
|
||||
function onResult(data)
|
||||
{
|
||||
password = data.password
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"点击跳转"
|
||||
onClicked: {
|
||||
loginPageRegister.launch({username:"zhuzichu"})
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
}
|
||||
|
82
example/T_Pivot.qml
Normal file
@ -0,0 +1,82 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"Pivot"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 400
|
||||
paddings: 10
|
||||
|
||||
FluPivot{
|
||||
anchors.fill: parent
|
||||
FluPivotItem{
|
||||
title:"All"
|
||||
contentItem:FluText{
|
||||
text:"All emails go here."
|
||||
}
|
||||
}
|
||||
FluPivotItem{
|
||||
title:"Unread"
|
||||
contentItem:FluText{
|
||||
text:"Unread emails go here."
|
||||
}
|
||||
}
|
||||
FluPivotItem{
|
||||
title:"Flagged"
|
||||
contentItem:FluText{
|
||||
text:"Flagged emails go here."
|
||||
}
|
||||
}
|
||||
FluPivotItem{
|
||||
title:"Urgent"
|
||||
contentItem:FluText{
|
||||
text:"Urgent emails go here."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluPivot{
|
||||
anchors.fill: parent
|
||||
FluPivotItem:{
|
||||
text:"All"
|
||||
contentItem: FluText{
|
||||
text:"All emails go here."
|
||||
}
|
||||
}
|
||||
FluPivotItem:{
|
||||
text:"Unread"
|
||||
contentItem: FluText{
|
||||
text:"Unread emails go here."
|
||||
}
|
||||
}
|
||||
FluPivotItem:{
|
||||
text:"Flagged"
|
||||
contentItem: FluText{
|
||||
text:"Flagged emails go here."
|
||||
}
|
||||
}
|
||||
FluPivotItem:{
|
||||
text:"Urgent"
|
||||
contentItem: FluText{
|
||||
text:"Urgent emails go here."
|
||||
}
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,30 +11,59 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluProgressBar{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluProgressRing{
|
||||
Layout.topMargin: 10
|
||||
}
|
||||
FluProgressBar{
|
||||
id:progress_bar
|
||||
Layout.topMargin: 20
|
||||
indeterminate: false
|
||||
}
|
||||
FluProgressRing{
|
||||
id:progress_ring
|
||||
Layout.topMargin: 10
|
||||
indeterminate: false
|
||||
}
|
||||
FluSlider{
|
||||
Layout.topMargin: 30
|
||||
value:50
|
||||
onValueChanged:{
|
||||
progress_bar.progress = value/100
|
||||
progress_ring.progress = value/100
|
||||
height: 260
|
||||
paddings: 10
|
||||
ColumnLayout{
|
||||
spacing: 20
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
FluProgressBar{
|
||||
}
|
||||
FluProgressRing{
|
||||
}
|
||||
FluProgressBar{
|
||||
id:progress_bar
|
||||
indeterminate: false
|
||||
}
|
||||
FluProgressRing{
|
||||
id:progress_ring
|
||||
indeterminate: false
|
||||
}
|
||||
FluSlider{
|
||||
value:50
|
||||
onValueChanged:{
|
||||
progress_bar.progress = value/100
|
||||
progress_ring.progress = value/100
|
||||
}
|
||||
}
|
||||
}
|
||||
Layout.bottomMargin: 30
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluProgressBar{
|
||||
|
||||
}
|
||||
|
||||
FluProgressRing{
|
||||
|
||||
}
|
||||
|
||||
FluProgressBar{
|
||||
indeterminate: false
|
||||
}
|
||||
|
||||
FluProgressRing{
|
||||
indeterminate: false
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,108 +11,141 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
RowLayout{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#0078d4"
|
||||
radius:[0,0,0,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#744da9"
|
||||
radius:[15,15,15,15]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#ffeb3b"
|
||||
radius:[15,0,0,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#f7630c"
|
||||
radius:[0,15,0,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#e71123"
|
||||
radius:[0,0,15,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#b4009e"
|
||||
radius:[0,0,0,15]
|
||||
height: 480
|
||||
paddings: 10
|
||||
|
||||
Column{
|
||||
spacing: 15
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
Layout.topMargin: 20
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#0078d4"
|
||||
radius:[0,0,0,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#744da9"
|
||||
radius:[15,15,15,15]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#ffeb3b"
|
||||
radius:[15,0,0,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#f7630c"
|
||||
radius:[0,15,0,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#e71123"
|
||||
radius:[0,0,15,0]
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
color:"#b4009e"
|
||||
radius:[0,0,0,15]
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"配合图片使用"
|
||||
fontStyle: FluText.SubTitle
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
RowLayout{
|
||||
spacing: 14
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[25,0,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
source: "qrc:/res/svg/avatar_1.svg"
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[10,10,10,10]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_2.svg"
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[25,25,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_3.svg"
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[0,25,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_4.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 1080/5
|
||||
height: 1439/5
|
||||
radius:[25,25,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
source: "qrc:/res/image/image_huoyin.webp"
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
Layout.topMargin: 10
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"配合图片使用"
|
||||
fontStyle: FluText.SubTitle
|
||||
Layout.topMargin: 20
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluRectangle{
|
||||
radius: [25,25,25,25]
|
||||
width: 50
|
||||
height: 50
|
||||
Image{
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
source: "qrc:/res/svg/avatar_4.svg"
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
RowLayout{
|
||||
spacing: 14
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[25,0,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
source: "qrc:/res/svg/avatar_1.svg"
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[10,10,10,10]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_2.svg"
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[25,25,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_3.svg"
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
height: 50
|
||||
radius:[0,25,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_4.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 1080/5
|
||||
height: 1439/5
|
||||
radius:[25,25,25,25]
|
||||
Image {
|
||||
asynchronous: true
|
||||
source: "qrc:/res/image/image_huoyin.webp"
|
||||
anchors.fill: parent
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
Layout.topMargin: 10
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import "./component"
|
||||
import FluentUI
|
||||
|
||||
FluScrollablePage{
|
||||
@ -10,17 +11,46 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluSlider{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 100
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
value: 50
|
||||
Layout.leftMargin: 10
|
||||
FluSlider{
|
||||
value: 50
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
FluSlider{
|
||||
vertical:true
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluSlider{
|
||||
value:50
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 200
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 10
|
||||
Layout.bottomMargin: 20
|
||||
value: 50
|
||||
FluSlider{
|
||||
value: 50
|
||||
vertical:true
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluSlider{
|
||||
vertical:true
|
||||
value:50
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
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
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,6 +11,7 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
property var colors : [FluColors.Yellow,FluColors.Orange,FluColors.Red,FluColors.Magenta,FluColors.Purple,FluColors.Blue,FluColors.Teal,FluColors.Green]
|
||||
|
||||
@ -32,7 +34,7 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 50
|
||||
paddings: 10
|
||||
@ -69,7 +71,7 @@ FluScrollablePage{
|
||||
FluDropDownButton{
|
||||
id:btn_close_button_visibility
|
||||
text:"Always"
|
||||
Layout.preferredWidth: 120
|
||||
Layout.preferredWidth: 120
|
||||
items:[
|
||||
FluMenuItem{
|
||||
text:"Nerver"
|
||||
@ -98,8 +100,8 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.topMargin: 5
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
height: 400
|
||||
paddings: 10
|
||||
FluTabView{
|
||||
@ -109,5 +111,27 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTabView{
|
||||
anchors.fill: parent
|
||||
Component.onCompleted: {
|
||||
newTab()
|
||||
newTab()
|
||||
newTab()
|
||||
}
|
||||
Component{
|
||||
id:com_page
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color: argument
|
||||
}
|
||||
}
|
||||
function newTab(){
|
||||
tab_view.appendTab("qrc:/res/image/favicon.ico","Document 1",com_page,argument)
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
}
|
||||
|
160
example/T_TableView.qml
Normal file
@ -0,0 +1,160 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"TableView"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
Component.onCompleted: {
|
||||
const columns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
width:100
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
dataIndex: 'age',
|
||||
width:100
|
||||
},
|
||||
{
|
||||
title: '住址',
|
||||
dataIndex: 'address',
|
||||
width:200
|
||||
},
|
||||
{
|
||||
title: '别名',
|
||||
dataIndex: 'nickname',
|
||||
width:100
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
width:100
|
||||
},
|
||||
];
|
||||
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{
|
||||
id:com_action
|
||||
Item{
|
||||
Row{
|
||||
anchors.centerIn: parent
|
||||
spacing: 10
|
||||
FluFilledButton{
|
||||
text:"编辑"
|
||||
topPadding:3
|
||||
bottomPadding:3
|
||||
leftPadding:3
|
||||
rightPadding:3
|
||||
onClicked:{
|
||||
console.debug(dataModel.index)
|
||||
showSuccess(JSON.stringify(dataObject))
|
||||
}
|
||||
}
|
||||
FluFilledButton{
|
||||
text:"删除"
|
||||
topPadding:3
|
||||
bottomPadding:3
|
||||
leftPadding:3
|
||||
rightPadding:3
|
||||
onClicked:{
|
||||
showError(JSON.stringify(dataObject))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadData(page,count){
|
||||
const dataSource = []
|
||||
for(var i=0;i<count;i++){
|
||||
dataSource.push({
|
||||
name: "孙悟空%1".arg(((page-1)*count+i)),
|
||||
age: 500,
|
||||
address: "钟灵毓秀的花果山,如神仙仙境的水帘洞",
|
||||
nickname: "齐天大圣",
|
||||
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
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,32 +11,122 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluTextBox{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
placeholderText: "单行输入框"
|
||||
Layout.preferredWidth: 300
|
||||
disabled:toggle_switch.selected
|
||||
|
||||
FluTextBox{
|
||||
Layout.topMargin: 20
|
||||
placeholderText: "单行输入框"
|
||||
Layout.preferredWidth: 300
|
||||
disabled:text_box_switch.selected
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
}
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id:text_box_switch
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text:"Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
FluMultiLineTextBox{
|
||||
Layout.topMargin: 20
|
||||
Layout.preferredWidth: 300
|
||||
placeholderText: "多行输入框"
|
||||
disabled:toggle_switch.selected
|
||||
}
|
||||
FluAutoSuggestBox{
|
||||
Layout.topMargin: 20
|
||||
items:generateRandomNames(100)
|
||||
placeholderText: "AutoSuggestBox"
|
||||
Layout.preferredWidth: 300
|
||||
disabled:toggle_switch.selected
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTextBox{
|
||||
placeholderText:"单行输入框"
|
||||
}'
|
||||
}
|
||||
|
||||
FluToggleSwitch{
|
||||
id:toggle_switch
|
||||
text:"Disabled"
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
|
||||
FluMultilineTextBox{
|
||||
Layout.topMargin: 20
|
||||
placeholderText: "多行输入框"
|
||||
Layout.preferredWidth: 300
|
||||
disabled:text_box_multi_switch.selected
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
}
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id:text_box_multi_switch
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text:"Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluMultilineTextBox{
|
||||
placeholderText:"多行输入框"
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
|
||||
FluAutoSuggestBox{
|
||||
Layout.topMargin: 20
|
||||
placeholderText: "AutoSuggestBox"
|
||||
Layout.preferredWidth: 300
|
||||
items:generateRandomNames(100)
|
||||
disabled:text_box_suggest_switch.selected
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
}
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id:text_box_suggest_switch
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text:"Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluAutoSuggestBox{
|
||||
placeholderText:"AutoSuggestBox"
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
function generateRandomNames(numNames) {
|
||||
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,52 +11,78 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
RowLayout{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
Repeater{
|
||||
model: [FluColors.Yellow,FluColors.Orange,FluColors.Red,FluColors.Magenta,FluColors.Purple,FluColors.Blue,FluColors.Teal,FluColors.Green]
|
||||
delegate: FluRectangle{
|
||||
width: 42
|
||||
height: 42
|
||||
radius: [4,4,4,4]
|
||||
color: mouse_item.containsMouse ? Qt.lighter(modelData.normal,1.1) : modelData.normal
|
||||
FluIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.AcceptMedium
|
||||
iconSize: 15
|
||||
visible: modelData === FluTheme.primaryColor
|
||||
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_item
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
FluTheme.primaryColor = modelData
|
||||
height: 210
|
||||
paddings: 10
|
||||
ColumnLayout{
|
||||
spacing:0
|
||||
anchors{
|
||||
left: parent.left
|
||||
}
|
||||
RowLayout{
|
||||
Layout.topMargin: 10
|
||||
Repeater{
|
||||
model: [FluColors.Yellow,FluColors.Orange,FluColors.Red,FluColors.Magenta,FluColors.Purple,FluColors.Blue,FluColors.Teal,FluColors.Green]
|
||||
delegate: FluRectangle{
|
||||
width: 42
|
||||
height: 42
|
||||
radius: [4,4,4,4]
|
||||
color: mouse_item.containsMouse ? Qt.lighter(modelData.normal,1.1) : modelData.normal
|
||||
FluIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.AcceptMedium
|
||||
iconSize: 15
|
||||
visible: modelData === FluTheme.primaryColor
|
||||
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_item
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
FluTheme.primaryColor = modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"夜间模式"
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluToggleSwitch{
|
||||
Layout.topMargin: 5
|
||||
selected: FluTheme.dark
|
||||
clickFunc:function(){
|
||||
FluTheme.dark = !FluTheme.dark
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"native文本渲染"
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluToggleSwitch{
|
||||
Layout.topMargin: 5
|
||||
selected: FluTheme.nativeText
|
||||
clickFunc:function(){
|
||||
FluTheme.nativeText = !FluTheme.nativeText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"夜间模式"
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluToggleSwitch{
|
||||
selected: FluTheme.dark
|
||||
clickFunc:function(){
|
||||
FluTheme.dark = !FluTheme.dark
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"native文本渲染"
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluToggleSwitch{
|
||||
selected: FluTheme.nativeText
|
||||
clickFunc:function(){
|
||||
FluTheme.nativeText = !FluTheme.nativeText
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTheme.primaryColor = FluColors.Orange
|
||||
|
||||
FluTheme.dark = true
|
||||
|
||||
FluTheme.nativeText = true
|
||||
'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,9 +11,10 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 80
|
||||
paddings: 10
|
||||
@ -33,10 +35,15 @@ FluScrollablePage{
|
||||
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTimePicker{
|
||||
|
||||
}'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 80
|
||||
paddings: 10
|
||||
@ -49,15 +56,20 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"hourFormat=FluTimePicker.HH"
|
||||
text:"hourFormat=FluTimePicker.H"
|
||||
}
|
||||
|
||||
FluTimePicker{
|
||||
hourFormat:FluTimePicker.HH
|
||||
hourFormat:FluTimePicker.HH
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTimePicker{
|
||||
hourFormat:FluTimePicker.HH
|
||||
}'
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,12 +11,29 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluToggleSwitch{
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
Row{
|
||||
spacing: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
FluToggleSwitch{
|
||||
}
|
||||
FluToggleSwitch{
|
||||
text:"Text"
|
||||
}
|
||||
}
|
||||
}
|
||||
FluToggleSwitch{
|
||||
Layout.topMargin: 20
|
||||
text:"Text"
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluToggleSwitch{
|
||||
text:"Text"
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
@ -10,15 +11,15 @@ FluScrollablePage{
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
FluText{
|
||||
Layout.topMargin: 20
|
||||
text:"鼠标悬停不动,弹出Tooltip"
|
||||
}
|
||||
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 68
|
||||
paddings: 10
|
||||
@ -42,9 +43,21 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluIconButton{
|
||||
iconSource:FluentIcons.ChromeCloseContrast
|
||||
iconSize: 15
|
||||
text:"删除"
|
||||
onClicked:{
|
||||
showSuccess("点击IconButton")
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
FluArea{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 68
|
||||
paddings: 10
|
||||
@ -72,6 +85,22 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluButton{
|
||||
id:button_1
|
||||
text:"删除"
|
||||
FluTooltip{
|
||||
visible: button_1.hovered
|
||||
text:button_1.text
|
||||
delay: 1000
|
||||
}
|
||||
onClicked:{
|
||||
showSuccess("点击一个Button")
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,13 +3,15 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "./component"
|
||||
|
||||
FluContentPage {
|
||||
FluScrollablePage {
|
||||
|
||||
title:"TreeView"
|
||||
leftPadding:10
|
||||
rightPadding:10
|
||||
bottomPadding:20
|
||||
spacing: 0
|
||||
|
||||
function randomName() {
|
||||
var names = ["张三", "李四", "王五", "赵六", "钱七", "孙八", "周九", "吴十"]
|
||||
@ -50,95 +52,110 @@ FluContentPage {
|
||||
return [tree_view.createItem(randomCompany(), true, subtrees)].concat(createOrg(numLevels - 1, numSubtrees, numEmployees))
|
||||
}
|
||||
|
||||
|
||||
FluTreeView{
|
||||
id:tree_view
|
||||
width:240
|
||||
anchors{
|
||||
top:parent.top
|
||||
left:parent.left
|
||||
bottom:parent.bottom
|
||||
}
|
||||
onItemClicked:
|
||||
(model)=>{
|
||||
showSuccess(model.text)
|
||||
FluArea{
|
||||
id:layout_actions
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
height: 50
|
||||
paddings: 10
|
||||
RowLayout{
|
||||
spacing: 14
|
||||
FluDropDownButton{
|
||||
id:btn_selection_model
|
||||
Layout.preferredWidth: 140
|
||||
text:"None"
|
||||
items:[
|
||||
FluMenuItem{
|
||||
text:"None"
|
||||
onClicked: {
|
||||
btn_selection_model.text = text
|
||||
tree_view.selectionMode = FluTabView.Equal
|
||||
}
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Single"
|
||||
onClicked: {
|
||||
btn_selection_model.text = text
|
||||
tree_view.selectionMode = FluTabView.SizeToContent
|
||||
}
|
||||
},
|
||||
FluMenuItem{
|
||||
text:"Muiltple"
|
||||
onClicked: {
|
||||
btn_selection_model.text = text
|
||||
tree_view.selectionMode = FluTabView.Compact
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
FluFilledButton{
|
||||
text:"获取选中的数据"
|
||||
onClicked: {
|
||||
if(tree_view.selectionMode === FluTreeView.None){
|
||||
showError("当前非选择模式,没有选中的数据")
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Single){
|
||||
if(!tree_view.signleData()){
|
||||
showError("没有选中数据")
|
||||
return
|
||||
}
|
||||
showSuccess(tree_view.signleData().text)
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Multiple){
|
||||
if(tree_view.multipData().length===0){
|
||||
showError("没有选中数据")
|
||||
return
|
||||
}
|
||||
var info = []
|
||||
tree_view.multipData().map((value)=>info.push(value.text))
|
||||
showSuccess(info.join(","))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
var org = createOrg(3, 3, 3)
|
||||
updateData(org)
|
||||
|
||||
}
|
||||
}
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
paddings: 10
|
||||
height: 400
|
||||
FluTreeView{
|
||||
id:tree_view
|
||||
width:240
|
||||
anchors{
|
||||
top:parent.top
|
||||
left:parent.left
|
||||
bottom:parent.bottom
|
||||
}
|
||||
onItemClicked:
|
||||
(model)=>{
|
||||
showSuccess(model.text)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
var org = createOrg(3, 3, 3)
|
||||
createItem()
|
||||
updateData(org)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ColumnLayout{
|
||||
anchors{
|
||||
left: tree_view.right
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:{
|
||||
if(tree_view.selectionMode === FluTreeView.None){
|
||||
return "selectionMode->FluTreeView.None"
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Single){
|
||||
return "selectionMode->FluTreeView.Single"
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Multiple){
|
||||
return "selectionMode->FluTreeView.Multiple"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"None"
|
||||
onClicked: {
|
||||
tree_view.selectionMode = FluTreeView.None
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"Single"
|
||||
onClicked: {
|
||||
tree_view.selectionMode = FluTreeView.Single
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"Multiple"
|
||||
onClicked: {
|
||||
tree_view.selectionMode = FluTreeView.Multiple
|
||||
}
|
||||
}
|
||||
|
||||
FluFilledButton{
|
||||
text:"获取选中的数据"
|
||||
onClicked: {
|
||||
if(tree_view.selectionMode === FluTreeView.None){
|
||||
showError("当前非选择模式,没有选中的数据")
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Single){
|
||||
if(!tree_view.signleData()){
|
||||
showError("没有选中数据")
|
||||
return
|
||||
}
|
||||
showSuccess(tree_view.signleData().text)
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Multiple){
|
||||
if(tree_view.multipData().length===0){
|
||||
showError("没有选中数据")
|
||||
return
|
||||
}
|
||||
var info = []
|
||||
tree_view.multipData().map((value)=>info.push(value.text))
|
||||
showSuccess(info.join(","))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
code:'FluTreeView{
|
||||
id:tree_view
|
||||
width:240
|
||||
height:600
|
||||
Component.onCompleted: {
|
||||
var datas = []
|
||||
datas.push(createItem("Node1",false))
|
||||
datas.push(createItem("Node2",false))
|
||||
datas.push(createItem("Node2",true,[createItem("Node2-1",false),createItem("Node2-2",false)]))
|
||||
updateData(datas)
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -15,15 +15,19 @@ FluContentPage {
|
||||
slider.seek(0)
|
||||
}
|
||||
|
||||
ScrollView{
|
||||
clip: true
|
||||
width: parent.width
|
||||
contentWidth: parent.width
|
||||
FluArea{
|
||||
anchors{
|
||||
top:parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
topMargin: 20
|
||||
}
|
||||
paddings: 10
|
||||
ColumnLayout{
|
||||
spacing: 0
|
||||
FluText{
|
||||
text:"Display"
|
||||
Layout.topMargin: 20
|
||||
padding: 0
|
||||
pixelSize: textSize
|
||||
fontStyle: FluText.Display
|
||||
@ -65,21 +69,26 @@ FluContentPage {
|
||||
fontStyle: FluText.Caption
|
||||
}
|
||||
}
|
||||
|
||||
FluSlider{
|
||||
id:slider
|
||||
vertical:true
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 45
|
||||
top: parent.top
|
||||
topMargin: 30
|
||||
}
|
||||
onValueChanged:{
|
||||
textSize = value/100*6+FluTheme.textSize
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
FluSlider{
|
||||
id:slider
|
||||
vertical:true
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 45
|
||||
top: parent.top
|
||||
topMargin: 30
|
||||
}
|
||||
onValueChanged:{
|
||||
textSize = value/100*6+FluTheme.textSize
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
130
example/component/CodeExpander.qml
Normal file
@ -0,0 +1,130 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluExpander{
|
||||
|
||||
property string code: ""
|
||||
|
||||
headerText: "Source"
|
||||
contentHeight:content.height
|
||||
|
||||
FluMultilineTextBox{
|
||||
id:content
|
||||
width:parent.width
|
||||
readOnly:true
|
||||
text:highlightQmlCode(code)
|
||||
focus:false
|
||||
textFormat: FluMultilineTextBox.RichText
|
||||
KeyNavigation.priority: KeyNavigation.BeforeItem
|
||||
background:Rectangle{
|
||||
radius: 4
|
||||
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 ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
iconSource:FluentIcons.Copy
|
||||
anchors{
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
rightMargin: 5
|
||||
topMargin: 5
|
||||
}
|
||||
onClicked:{
|
||||
FluApp.clipText(content.text)
|
||||
showSuccess("复制成功")
|
||||
}
|
||||
}
|
||||
|
||||
function htmlEncode(e){
|
||||
var i,s;
|
||||
for(i in s={
|
||||
"&":/&/g,//""//":/"/g,"'":/'/g,
|
||||
"<":/</g,">":/>/g,"<br/>":/\n/g,
|
||||
" ":/ /g," ":/\t/g
|
||||
})e=e.replace(s[i],i);
|
||||
return e;
|
||||
}
|
||||
|
||||
function highlightQmlCode(code) {
|
||||
// 定义 QML 关键字列表
|
||||
var qmlKeywords = [
|
||||
"FluTextButton",
|
||||
"FluAppBar",
|
||||
"FluAutoSuggestBox",
|
||||
"FluBadge",
|
||||
"FluButton",
|
||||
"FluCalendarPicker",
|
||||
"FluCalendarView",
|
||||
"FluCarousel",
|
||||
"FluCheckBox",
|
||||
"FluColorPicker",
|
||||
"FluColorView",
|
||||
"FluComboBox",
|
||||
"FluContentDialog",
|
||||
"FluContentPage",
|
||||
"FluControl",
|
||||
"FluDatePicker",
|
||||
"FluDivider",
|
||||
"FluDropDownButton",
|
||||
"FluExpander",
|
||||
"FluFilledButton",
|
||||
"FluFlipView",
|
||||
"FluFocusRectangle",
|
||||
"FluIcon",
|
||||
"FluIconButton",
|
||||
"FluInfoBar",
|
||||
"FluItem",
|
||||
"FluMediaPlayer",
|
||||
"FluMenu",
|
||||
"FluMenuItem",
|
||||
"FluMultilineTextBox",
|
||||
"FluNavigationView",
|
||||
"FluObject",
|
||||
"FluPaneItem",
|
||||
"FluPaneItemExpander",
|
||||
"FluPaneItemHeader",
|
||||
"FluPaneItemSeparator",
|
||||
"FluPivot",
|
||||
"FluPivotItem",
|
||||
"FluProgressBar",
|
||||
"FluProgressRing",
|
||||
"FluRadioButton",
|
||||
"FluRectangle",
|
||||
"FluScrollablePage",
|
||||
"FluScrollBar",
|
||||
"FluShadow",
|
||||
"FluSlider",
|
||||
"FluTabView",
|
||||
"FluText",
|
||||
"FluTextArea",
|
||||
"FluTextBox",
|
||||
"FluTextBoxBackground",
|
||||
"FluTextBoxMenu",
|
||||
"FluTextButton",
|
||||
"FluTextFiled",
|
||||
"FluTimePicker",
|
||||
"FluToggleSwitch",
|
||||
"FluTooltip",
|
||||
"FluTreeView",
|
||||
"FluWindow",
|
||||
"FluWindowResize",
|
||||
"FluToggleButton",
|
||||
"FluTableView",
|
||||
"FluColors",
|
||||
"FluTheme",
|
||||
"FluStatusView"
|
||||
];
|
||||
code = code.replace(/\n/g, "<br>");
|
||||
code = code.replace(/ /g, " ");
|
||||
return code.replace(RegExp("\\b(" + qmlKeywords.join("|") + ")\\b", "g"), "<span style='color: #c23a80'>$1</span>");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
QT += quick quickcontrols2 concurrent network multimedia
|
||||
CONFIG += c++11
|
||||
QT += quick quickcontrols2 concurrent network multimedia
|
||||
CONFIG += c++17
|
||||
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
|
||||
|
||||
HEADERS += \
|
||||
ChatController.h
|
||||
ChatController.h \
|
||||
AppInfo.h
|
||||
|
||||
SOURCES += \
|
||||
ChatController.cpp \
|
||||
AppInfo.cpp \
|
||||
main.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
@ -23,21 +25,15 @@ CONFIG(debug,debug|release) {
|
||||
}
|
||||
|
||||
win32 {
|
||||
contains(QT_ARCH, i386) {
|
||||
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/Win_x86/*.dll) $$DESTDIR
|
||||
contains(QMAKE_CC, cl) {
|
||||
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, \\)
|
||||
} else {
|
||||
QMAKE_PRE_LINK += $$QMAKE_COPY $$COPYDLL
|
||||
}
|
||||
|
||||
contains(QMAKE_CC, cl) {
|
||||
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/msvc/*.dll) $$DESTDIR
|
||||
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, $$QMAKE_DIR_SEP)
|
||||
} else {
|
||||
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/Win_x64/*.dll) $$DESTDIR
|
||||
contains(QMAKE_CC, cl) {
|
||||
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, \\)
|
||||
} else {
|
||||
QMAKE_PRE_LINK += $$QMAKE_COPY $$COPYDLL
|
||||
}
|
||||
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/mingw/*.dll) $$DESTDIR
|
||||
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, $$QMAKE_DIR_SEP)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
import QtQuick
|
||||
import FluentUI
|
||||
|
||||
|
||||
FluObject{
|
||||
|
||||
property var navigationView
|
||||
@ -16,224 +15,244 @@ FluObject{
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
title:"Inputs"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Buttons"
|
||||
image:"qrc:/res/image/control/Button.png"
|
||||
recentlyUpdated:true
|
||||
desc:"A control that responds to user input and raisesa Click event."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Buttons.qml")
|
||||
FluPaneItemExpander{
|
||||
title:"Basic input"
|
||||
icon:FluentIcons.CheckboxComposite
|
||||
FluPaneItem{
|
||||
title:"Buttons"
|
||||
image:"qrc:/res/image/control/Button.png"
|
||||
recentlyUpdated:true
|
||||
desc:"A control that responds to user input and raisesa Click event."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Buttons.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Slider"
|
||||
image:"qrc:/res/image/control/Slider.png"
|
||||
recentlyUpdated:true
|
||||
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Slider.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"CheckBox"
|
||||
image:"qrc:/res/image/control/Checkbox.png"
|
||||
recentlyUpdated:true
|
||||
desc:"A control that a user can select or clear."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_CheckBox.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"ToggleSwitch"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_ToggleSwitch.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Slider"
|
||||
image:"qrc:/res/image/control/Slider.png"
|
||||
recentlyUpdated:true
|
||||
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Slider.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"CheckBox"
|
||||
image:"qrc:/res/image/control/Checkbox.png"
|
||||
recentlyUpdated:true
|
||||
desc:"A control that a user can select or clear."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_CheckBox.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"ToggleSwitch"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_ToggleSwitch.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
FluPaneItemExpander{
|
||||
title:"Form"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"TextBox"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TextBox.qml")
|
||||
icon:FluentIcons.GridView
|
||||
FluPaneItem{
|
||||
title:"TextBox"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TextBox.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"TimePicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TimePicker.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"DatePicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_DatePicker.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"CalendarPicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_CalendarPicker.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"ColorPicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_ColorPicker.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"TimePicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TimePicker.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"DatePicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_DatePicker.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"CalendarPicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_CalendarPicker.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"ColorPicker"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_ColorPicker.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
FluPaneItemExpander{
|
||||
title:"Surface"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"InfoBar"
|
||||
image:"qrc:/res/image/control/InfoBar.png"
|
||||
recentlyUpdated:true
|
||||
desc:"An inline message to display app-wide statuschange information."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_InfoBar.qml")
|
||||
icon:FluentIcons.SurfaceHub
|
||||
FluPaneItem{
|
||||
title:"InfoBar"
|
||||
image:"qrc:/res/image/control/InfoBar.png"
|
||||
recentlyUpdated:true
|
||||
desc:"An inline message to display app-wide statuschange information."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_InfoBar.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Progress"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Progress.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Badge"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Badge.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Rectangle"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Rectangle.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"StatusView"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_StatusView.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Carousel"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Carousel.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Expander"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Expander.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Progress"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Progress.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Badge"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Badge.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Rectangle"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Rectangle.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Carousel"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Carousel.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Expander"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Expander.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
FluPaneItemExpander{
|
||||
title:"Popus"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Dialog"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Dialog.qml")
|
||||
icon:FluentIcons.ButtonMenu
|
||||
FluPaneItem{
|
||||
title:"Dialog"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Dialog.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Tooltip"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Tooltip.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Menu"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Menu.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Tooltip"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Tooltip.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Menu"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Menu.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
FluPaneItemExpander{
|
||||
title:"Navigation"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"TabView"
|
||||
image:"qrc:/res/image/control/TabView.png"
|
||||
recentlyAdded:true
|
||||
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TabView.qml")
|
||||
icon:FluentIcons.AllApps
|
||||
FluPaneItem{
|
||||
title:"Pivot"
|
||||
image:"qrc:/res/image/control/Pivot.png"
|
||||
recentlyAdded:true
|
||||
order:3
|
||||
desc:"Presents information from different sources in atabbed view."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Pivot.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"TabView"
|
||||
image:"qrc:/res/image/control/TabView.png"
|
||||
recentlyAdded:true
|
||||
order:1
|
||||
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TabView.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"TreeView"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TreeView.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"TableView"
|
||||
image:"qrc:/res/image/control/DataGrid.png"
|
||||
recentlyAdded:true
|
||||
order:4
|
||||
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TableView.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"MultiWindow"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_MultiWindow.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"FlipView"
|
||||
image:"qrc:/res/image/control/FlipView.png"
|
||||
recentlyAdded:true
|
||||
order:2
|
||||
desc:"Presents a collection of items that the user canflip through, one item at a time."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_FlipView.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"TreeView"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_TreeView.qml")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FluPaneItem{
|
||||
title:"MultiWindow"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_MultiWindow.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
FluPaneItemExpander{
|
||||
title:"Theming"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Theme"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Theme.qml")
|
||||
icon:FluentIcons.Brightness
|
||||
FluPaneItem{
|
||||
title:"Theme"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Theme.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Typography"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Typography.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Awesome"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Awesome.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"Awesome"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Awesome.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Typography"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_Typography.qml")
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemHeader{
|
||||
FluPaneItemExpander{
|
||||
title:"Media"
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
title:"MediaPlayer"
|
||||
image:"qrc:/res/image/control/MediaPlayerElement.png"
|
||||
recentlyAdded:true
|
||||
desc:"A control to display video and image content."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_MediaPlayer.qml")
|
||||
icon:FluentIcons.Media
|
||||
FluPaneItem{
|
||||
title:"MediaPlayer"
|
||||
image:"qrc:/res/image/control/MediaPlayerElement.png"
|
||||
recentlyAdded:true
|
||||
order:0
|
||||
desc:"A control to display video and image content."
|
||||
onTap:{
|
||||
navigationView.push("qrc:/T_MediaPlayer.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,14 +263,24 @@ FluObject{
|
||||
if(item instanceof FluPaneItem && item.recentlyAdded){
|
||||
arr.push(item)
|
||||
}
|
||||
if(item instanceof FluPaneItemExpander){
|
||||
for(var j=0;j<item.children.length;j++){
|
||||
var itemChild = item.children[j]
|
||||
if(itemChild instanceof FluPaneItem && itemChild.recentlyAdded){
|
||||
arr.push(itemChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
arr.sort(function(o1,o2){ return o2.order-o1.order })
|
||||
return arr
|
||||
}
|
||||
|
||||
function getRecentlyUpdatedData(){
|
||||
var arr = []
|
||||
for(var i=0;i<children.length;i++){
|
||||
var item = children[i]
|
||||
var items = navigationView.getItems();
|
||||
for(var i=0;i<items.length;i++){
|
||||
var item = items[i]
|
||||
if(item instanceof FluPaneItem && item.recentlyUpdated){
|
||||
arr.push(item)
|
||||
}
|
||||
@ -261,8 +290,9 @@ FluObject{
|
||||
|
||||
function getSearchData(){
|
||||
var arr = []
|
||||
for(var i=0;i<children.length;i++){
|
||||
var item = children[i]
|
||||
var items = navigationView.getItems();
|
||||
for(var i=0;i<items.length;i++){
|
||||
var item = items[i]
|
||||
if(item instanceof FluPaneItem){
|
||||
arr.push({title:item.title,key:item.key})
|
||||
}
|
||||
@ -270,17 +300,8 @@ FluObject{
|
||||
return arr
|
||||
}
|
||||
|
||||
function startPageByItem(item){
|
||||
for(var i=0;i<children.length;i++){
|
||||
if(children[i].key === item.key){
|
||||
if(navigationView.getCurrentIndex() === i){
|
||||
return
|
||||
}
|
||||
children[i].tap()
|
||||
navigationView.setCurrentIndex(i)
|
||||
return
|
||||
}
|
||||
}
|
||||
function startPageByItem(data){
|
||||
navigationView.startPageByItem(data)
|
||||
}
|
||||
|
||||
}
|
||||
|
9
example/global/MainEvent.qml
Normal file
@ -0,0 +1,9 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
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
|
||||
|
@ -5,34 +5,19 @@
|
||||
#include <QQuickWindow>
|
||||
#include <QQuickStyle>
|
||||
#include <QProcess>
|
||||
#include "AppInfo.h"
|
||||
#include "ChatController.h"
|
||||
|
||||
QMap<QString, QVariant> properties(){
|
||||
QMap<QString, QVariant> map;
|
||||
// map["installHelper"] = QVariant::fromValue(QVariant::fromValue(InstallHelper::getInstance()));
|
||||
return map;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setOrganizationName("ZhuZiChu");
|
||||
QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io");
|
||||
QCoreApplication::setApplicationName("FluentUI");
|
||||
// QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
|
||||
QQuickStyle::setStyle("Basic");
|
||||
QGuiApplication app(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
|
||||
qmlRegisterType<ChatController>("Controller",1,0,"ChatController");
|
||||
|
||||
QMapIterator<QString, QVariant> iterator(properties());
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
QString key = iterator.key();
|
||||
QVariant value = iterator.value();
|
||||
engine.rootContext()->setContextProperty(key,value);
|
||||
}
|
||||
engine.rootContext()->setContextProperty("properties",properties());
|
||||
engine.rootContext()->setContextProperty("appInfo",new AppInfo());
|
||||
const QUrl url(QStringLiteral("qrc:/App.qml"));
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
|
@ -5,6 +5,8 @@ import FluentUI
|
||||
|
||||
FluWindow {
|
||||
|
||||
id:window
|
||||
|
||||
width: 500
|
||||
height: 600
|
||||
minimumWidth: 500
|
||||
@ -36,7 +38,7 @@ FluWindow {
|
||||
fontStyle: FluText.Title
|
||||
}
|
||||
FluText{
|
||||
text:"v1.1.6"
|
||||
text:"v%1".arg(appInfo.version)
|
||||
fontStyle: FluText.Body
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ FluWindow {
|
||||
rightMargin: 10
|
||||
}
|
||||
height: Math.min(textbox.implicitHeight,64)
|
||||
FluMultiLineTextBox{
|
||||
FluMultilineTextBox{
|
||||
id:textbox
|
||||
focus:true
|
||||
placeholderText: "请输入消息"
|
||||
|
@ -1,5 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluWindow {
|
||||
@ -11,8 +12,6 @@ FluWindow {
|
||||
minimumHeight: 400
|
||||
maximumWidth: 400
|
||||
maximumHeight: 400
|
||||
modality:2
|
||||
|
||||
title:"登录"
|
||||
|
||||
onInitArgument:
|
||||
|
@ -15,26 +15,27 @@ FluWindow {
|
||||
|
||||
FluAppBar{
|
||||
id:appbar
|
||||
z:10
|
||||
z:9
|
||||
showDark: true
|
||||
width:parent.width
|
||||
darkText: "Dark Mode"
|
||||
}
|
||||
|
||||
|
||||
FluNavigationView{
|
||||
id:nav_view
|
||||
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)
|
||||
@ -42,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")
|
||||
}
|
||||
}
|
||||
|
||||
|
37
example/page/MediaPage.qml
Normal file
@ -0,0 +1,37 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
FluWindow {
|
||||
|
||||
width: 640
|
||||
height: 480
|
||||
minimumWidth: 640
|
||||
minimumHeight: 480
|
||||
|
||||
title:"视频播放器"
|
||||
|
||||
onInitArgument:
|
||||
(argument)=>{
|
||||
player.source = argument.source
|
||||
}
|
||||
|
||||
FluAppBar{
|
||||
id:appbar
|
||||
title:"视频播放器"
|
||||
width:parent.width
|
||||
}
|
||||
|
||||
|
||||
FluMediaPlayer{
|
||||
id:player
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: appbar.bottom
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -152,5 +152,13 @@
|
||||
<file>global/ItemsOriginal.qml</file>
|
||||
<file>global/qmldir</file>
|
||||
<file>global/ItemsFooter.qml</file>
|
||||
<file>page/MediaPage.qml</file>
|
||||
<file>T_FlipView.qml</file>
|
||||
<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>
|
||||
|
34
scripts/windows-mingw-publish.ps1
Normal file
@ -0,0 +1,34 @@
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[string] $archiveName, [string] $targetName
|
||||
)
|
||||
# 外部环境变量包括:
|
||||
# archiveName: ${{ matrix.qt_ver }}-${{ matrix.qt_arch }}
|
||||
|
||||
|
||||
# archiveName: 5.15.2-win64_mingw81
|
||||
|
||||
$scriptDir = $PSScriptRoot
|
||||
$currentDir = Get-Location
|
||||
Write-Host "currentDir" $currentDir
|
||||
Write-Host "scriptDir" $scriptDir
|
||||
|
||||
function Main() {
|
||||
|
||||
New-Item -ItemType Directory $archiveName
|
||||
# 拷贝exe
|
||||
Copy-Item bin\release\* $archiveName\
|
||||
# 拷贝依赖
|
||||
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
|
||||
# 删除不必要的文件
|
||||
$excludeList = @("*.qmlc", "*.ilk", "*.exp", "*.lib", "*.pdb")
|
||||
Remove-Item -Path $archiveName -Include $excludeList -Recurse -Force
|
||||
# 打包zip
|
||||
Compress-Archive -Path $archiveName $archiveName'.zip'
|
||||
}
|
||||
|
||||
if ($null -eq $archiveName || $null -eq $targetName) {
|
||||
Write-Host "args missing, archiveName is" $archiveName ", targetName is" $targetName
|
||||
return
|
||||
}
|
||||
Main
|
72
src/CMakeLists.txt
Normal file
@ -0,0 +1,72 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(FluentUI)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
find_package(Qt6 COMPONENTS Core Quick Svg REQUIRED)
|
||||
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
|
||||
FluApp.cpp
|
||||
FluColorSet.cpp
|
||||
FluColors.cpp
|
||||
FluRegister.cpp
|
||||
FluTheme.cpp
|
||||
Fluent.cpp
|
||||
FluentUI.cpp
|
||||
WindowHelper.cpp
|
||||
qml_plugin.cpp
|
||||
)
|
||||
|
||||
set(TARGET_HEADERS
|
||||
Def.h
|
||||
FluApp.h
|
||||
FluColorSet.h
|
||||
FluColors.h
|
||||
FluRegister.h
|
||||
FluTheme.h
|
||||
Fluent.h
|
||||
FluentUI.h
|
||||
FramelessView.h
|
||||
WindowHelper.h
|
||||
qml_plugin.h
|
||||
stdafx.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_win.cpp)
|
||||
else()
|
||||
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_unix.cpp)
|
||||
endif()
|
||||
|
||||
add_definitions(-DVERSION_IN="1.0.0")
|
||||
add_definitions(-DVURI_STR="FluentUI")
|
||||
|
||||
add_library(${PROJECT_NAME} ${TARGET_TYPE} ${TARGET_SOURCES} ${TARGET_HEADERS} ${TARGET_RESOURCES})
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
|
||||
else()
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick Qt6::Svg)
|
||||
|
||||
if(WIN32)
|
||||
include(build_windows.cmake)
|
||||
else()
|
||||
include(build_macos.cmake)
|
||||
endif()
|
@ -7,8 +7,20 @@
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
#include <QClipboard>
|
||||
#include "FluTheme.h"
|
||||
#include "Def.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <dwmapi.h>
|
||||
#include <Windows.h>
|
||||
#include <windowsx.h>
|
||||
static bool isCompositionEnabled()
|
||||
{
|
||||
BOOL composition_enabled = FALSE;
|
||||
bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK;
|
||||
return composition_enabled && success;
|
||||
}
|
||||
#endif
|
||||
|
||||
FluApp* FluApp::m_instance = nullptr;
|
||||
|
||||
@ -25,12 +37,16 @@ FluApp::FluApp(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
void FluApp::init(QWindow *window,QMap<QString, QVariant> properties){
|
||||
void FluApp::init(QQuickWindow *window){
|
||||
this->appWindow = window;
|
||||
this->properties = properties;
|
||||
}
|
||||
|
||||
void FluApp::run(){
|
||||
#ifdef Q_OS_WIN
|
||||
if(!isCompositionEnabled()){
|
||||
FluTheme::getInstance()->frameless(false);
|
||||
}
|
||||
#endif
|
||||
navigate(initialRoute());
|
||||
}
|
||||
|
||||
@ -39,38 +55,23 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
|
||||
qErrnoWarning("没有找到当前路由");
|
||||
return;
|
||||
}
|
||||
bool isAppWindow = route == initialRoute();
|
||||
FramelessView *view = new FramelessView();
|
||||
QQmlEngine *engine = qmlEngine(appWindow);
|
||||
QQmlComponent component(engine, routes().value(route).toString());
|
||||
QVariantMap properties;
|
||||
if(fluRegister){
|
||||
properties.insert("pageRegister",QVariant::fromValue(fluRegister));
|
||||
}
|
||||
properties.insert("argument",argument);
|
||||
QQuickWindow *view = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties));
|
||||
wnds.insert(view->winId(),view);
|
||||
if(fluRegister){
|
||||
fluRegister->to(view);
|
||||
view->setProperty("pageRegister",QVariant::fromValue(fluRegister));
|
||||
}
|
||||
view->setProperty("argument",argument);
|
||||
QMapIterator<QString, QVariant> iterator(properties);
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
QString key = iterator.key();
|
||||
QVariant value = iterator.value();
|
||||
view->engine()->rootContext()->setContextProperty(key,value);
|
||||
}
|
||||
view->setColor(QColor(Qt::transparent));
|
||||
QObject::connect(view, &QQuickView::statusChanged, view, [&](QQuickView::Status status) {
|
||||
if (status == QQuickView::Status::Ready) {
|
||||
Q_EMIT windowReady(view);
|
||||
view->moveToScreenCenter();
|
||||
view->show();
|
||||
}
|
||||
});
|
||||
view->setSource((routes().value(route).toString()));
|
||||
if(isAppWindow){
|
||||
QObject::connect(view->engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
|
||||
}else{
|
||||
view->closeDeleteLater();
|
||||
if(view->maximumWidth()==view->minimumWidth()&&view->maximumHeight()==view->minimumHeight()){
|
||||
view->resize(view->minimumSize());
|
||||
}
|
||||
}
|
||||
|
||||
bool FluApp::equalsWindow(FramelessView *view,QWindow *window){
|
||||
return view->winId() == window->winId();
|
||||
view->show();
|
||||
}
|
||||
|
||||
QJsonArray FluApp::awesomelist(const QString& keyword)
|
||||
|
11
src/FluApp.h
@ -8,7 +8,6 @@
|
||||
#include <QJsonObject>
|
||||
#include <QQmlEngine>
|
||||
#include "FluRegister.h"
|
||||
#include "FramelessView.h"
|
||||
#include "stdafx.h"
|
||||
|
||||
class FluApp : public QObject
|
||||
@ -27,11 +26,7 @@ public:
|
||||
|
||||
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
|
||||
|
||||
Q_INVOKABLE void init(QWindow *window,QMap<QString, QVariant> properties);
|
||||
|
||||
Q_SIGNAL void windowReady(FramelessView *view);
|
||||
|
||||
Q_INVOKABLE bool equalsWindow(FramelessView *view,QWindow *window);
|
||||
Q_INVOKABLE void init(QQuickWindow *window);
|
||||
|
||||
Q_INVOKABLE QJsonArray awesomelist(const QString& keyword = "");
|
||||
|
||||
@ -39,11 +34,11 @@ public:
|
||||
|
||||
Q_INVOKABLE QString uuid();
|
||||
|
||||
public:
|
||||
QMap<quint64, QQuickWindow*> wnds;
|
||||
private:
|
||||
QMap<QString, QVariant> properties;
|
||||
static FluApp* m_instance;
|
||||
QWindow *appWindow;
|
||||
|
||||
};
|
||||
|
||||
#endif // FLUAPP_H
|
||||
|
@ -2,15 +2,15 @@
|
||||
#define FLUREGISTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <FramelessView.h>
|
||||
#include <QQuickWindow>
|
||||
#include <QJsonObject>
|
||||
#include "stdafx.h"
|
||||
|
||||
class FluRegister : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(FramelessView*,from)
|
||||
Q_PROPERTY_AUTO(FramelessView*,to)
|
||||
Q_PROPERTY_AUTO(QQuickWindow*,from)
|
||||
Q_PROPERTY_AUTO(QQuickWindow*,to)
|
||||
Q_PROPERTY_AUTO(QString,path);
|
||||
public:
|
||||
explicit FluRegister(QObject *parent = nullptr);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickWindow>
|
||||
#include "FluColors.h"
|
||||
#include "NativeEventFilter.h"
|
||||
#include "FluTheme.h"
|
||||
#include "WindowHelper.h"
|
||||
#include "FluApp.h"
|
||||
@ -32,6 +33,15 @@ 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");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPivot.qml"),uri,major,minor,"FluPivot");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFlipView.qml"),uri,major,minor,"FluFlipView");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemExpander.qml"),uri,major,minor,"FluPaneItemExpander");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTabView.qml"),uri,major,minor,"FluTabView");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluArea.qml"),uri,major,minor,"FluArea");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluBadge.qml"),uri,major,minor,"FluBadge");
|
||||
@ -57,7 +67,7 @@ void Fluent::registerTypes(const char *uri){
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextButton.qml"),uri,major,minor,"FluTextButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultiLineTextBox.qml"),uri,major,minor,"FluMultiLineTextBox");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultilineTextBox.qml"),uri,major,minor,"FluMultilineTextBox");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTooltip.qml"),uri,major,minor,"FluTooltip");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDivider.qml"),uri,major,minor,"FluDivider");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIcon.qml"),uri,major,minor,"FluIcon");
|
||||
@ -86,6 +96,8 @@ void Fluent::registerTypes(const char *uri){
|
||||
|
||||
void Fluent::initializeEngine(QQmlEngine *engine, const char *uri)
|
||||
{
|
||||
nativeEvent = new NativeEventFilter();
|
||||
qApp->installNativeEventFilter(nativeEvent);
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(uri)
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -3,17 +3,25 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
#include "NativeEventFilter.h"
|
||||
|
||||
class Fluent: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Q_INVOKABLE QString version() const;
|
||||
~Fluent(){
|
||||
if (nativeEvent != Q_NULLPTR) {
|
||||
delete nativeEvent;
|
||||
nativeEvent = Q_NULLPTR;
|
||||
}
|
||||
}
|
||||
void registerTypes(const char *uri);
|
||||
void initializeEngine(QQmlEngine *engine, const char *uri);
|
||||
static Fluent *getInstance();
|
||||
private:
|
||||
static Fluent* m_instance;
|
||||
NativeEventFilter *nativeEvent = Q_NULLPTR;
|
||||
};
|
||||
|
||||
#endif // FLUENT_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
QT += qml quick svg
|
||||
CONFIG += plugin c++11
|
||||
CONFIG += plugin c++17
|
||||
TEMPLATE = lib
|
||||
TARGET = FluentUI
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
@ -19,7 +19,7 @@ HEADERS += \
|
||||
FluTheme.h \
|
||||
Fluent.h \
|
||||
FluentUI.h \
|
||||
FramelessView.h \
|
||||
NativeEventFilter.h \
|
||||
WindowHelper.h \
|
||||
qml_plugin.h \
|
||||
stdafx.h
|
||||
@ -33,16 +33,12 @@ SOURCES += \
|
||||
FluTheme.cpp \
|
||||
Fluent.cpp \
|
||||
FluentUI.cpp \
|
||||
NativeEventFilter.cpp \
|
||||
WindowHelper.cpp \
|
||||
qml_plugin.cpp \
|
||||
|
||||
win32 {
|
||||
LIBS += -ldwmapi -luser32
|
||||
SOURCES += \
|
||||
FramelessView_win.cpp
|
||||
} else {
|
||||
SOURCES += \
|
||||
FramelessView_unix.cpp
|
||||
}
|
||||
|
||||
DEFINES += VERSION_IN=\\\"1.0.0\\\"
|
||||
|
@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QQuickView>
|
||||
#include <QRegion>
|
||||
|
||||
class FramelessViewPrivate;
|
||||
class FramelessView : public QQuickView
|
||||
{
|
||||
Q_OBJECT
|
||||
using Super = QQuickView;
|
||||
Q_PROPERTY(bool isMax READ isMax NOTIFY isMaxChanged)
|
||||
Q_PROPERTY(bool isFull READ isFull NOTIFY isFullChanged)
|
||||
public:
|
||||
explicit FramelessView(QWindow *parent = nullptr);
|
||||
~FramelessView();
|
||||
void moveToScreenCenter();
|
||||
void closeDeleteLater();
|
||||
bool isMax() const;
|
||||
bool isFull() const;
|
||||
QQuickItem *titleItem() const;
|
||||
|
||||
static QMap<WId,FramelessView*> *windowCache;
|
||||
static QRect calcCenterGeo(const QRect &screenGeo, const QSize &normalSize);
|
||||
public slots:
|
||||
void setIsMax(bool isMax);
|
||||
void setIsFull(bool isFull);
|
||||
void setTitleItem(QQuickItem* item);
|
||||
|
||||
signals:
|
||||
void isMaxChanged(bool isMax);
|
||||
void isFullChanged(bool isFull);
|
||||
void mousePressed(int xPos, int yPos, int button);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
bool event(QEvent *ev) override;
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
# else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||
# endif
|
||||
void mousePressEvent(QMouseEvent* event) override
|
||||
{
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
emit mousePressed(event->position().x(), event->position().y(), event->button());
|
||||
#else
|
||||
emit mousePressed(event->x(), event->y(), event->button());
|
||||
#endif
|
||||
Super::mousePressEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
FramelessViewPrivate *d;
|
||||
};
|
@ -1,138 +0,0 @@
|
||||
#include "FramelessView.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
#include <FluTheme.h>
|
||||
|
||||
class FramelessViewPrivate
|
||||
{
|
||||
public:
|
||||
bool m_isMax = false;
|
||||
bool m_isFull = false;
|
||||
bool m_deleteLater = false;
|
||||
QQuickItem *m_titleItem = nullptr;
|
||||
};
|
||||
|
||||
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
|
||||
{
|
||||
if(FluTheme::getInstance()->frameless()){
|
||||
setFlags( Qt::Window | Qt::FramelessWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
}
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
(void)state;
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
connect(FluTheme::getInstance(),&FluTheme::framelessChanged,this,[=](){
|
||||
setFlag(Qt::Window,false);
|
||||
setFlag(Qt::Window,true);
|
||||
});
|
||||
}
|
||||
|
||||
FramelessView::~FramelessView()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void FramelessView::showEvent(QShowEvent *e)
|
||||
{
|
||||
Super::showEvent(e);
|
||||
}
|
||||
|
||||
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
int h = normalSize.height();
|
||||
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
|
||||
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
|
||||
if (screenGeo.width() < w) {
|
||||
x = screenGeo.x();
|
||||
w = screenGeo.width();
|
||||
}
|
||||
if (screenGeo.height() < h) {
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
return { x, y, w, h };
|
||||
}
|
||||
|
||||
void FramelessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
|
||||
setMinimumSize(geo.size());
|
||||
}
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
|
||||
void FramelessView::closeDeleteLater(){
|
||||
d->m_deleteLater = true;
|
||||
}
|
||||
|
||||
bool FramelessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
|
||||
bool FramelessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
|
||||
QQuickItem *FramelessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
|
||||
void FramelessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
return;
|
||||
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
|
||||
void FramelessView::setIsFull(bool isFull)
|
||||
{
|
||||
if(d->m_isFull == isFull)
|
||||
return;
|
||||
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
|
||||
void FramelessView::setTitleItem(QQuickItem *item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
void FramelessView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Super::resizeEvent(e);
|
||||
}
|
||||
|
||||
bool FramelessView::event(QEvent *ev)
|
||||
{
|
||||
if (ev->type() == QEvent::Close) {
|
||||
if(d->m_deleteLater){
|
||||
deleteLater();
|
||||
ev->setAccepted(false);
|
||||
}
|
||||
}
|
||||
return QQuickWindow::event(ev);
|
||||
}
|
||||
|
@ -1,268 +0,0 @@
|
||||
#include "FramelessView.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
#include <FluTheme.h>
|
||||
#include <QTimer>
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <windowsx.h>
|
||||
#pragma comment(lib, "Dwmapi.lib")
|
||||
#pragma comment(lib, "User32.lib")
|
||||
|
||||
|
||||
static bool isCompositionEnabled()
|
||||
{
|
||||
BOOL composition_enabled = FALSE;
|
||||
bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK;
|
||||
return composition_enabled && success;
|
||||
}
|
||||
|
||||
static bool isMaxWin(QWindow* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowMaximized;
|
||||
}
|
||||
static bool isFullWin(QQuickView* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowFullScreen;
|
||||
}
|
||||
static bool isFixWin(QQuickView* win)
|
||||
{
|
||||
return win->minimumWidth() == win->maximumWidth() && win->minimumHeight() == win->maximumHeight();
|
||||
}
|
||||
static long hitTest(RECT winrect, long x, long y, int borderWidth)
|
||||
{
|
||||
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top) && (y < winrect.top + borderWidth))
|
||||
{
|
||||
return HTTOPLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth)
|
||||
{
|
||||
return HTTOPRIGHT;
|
||||
}
|
||||
else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOMLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOMRIGHT;
|
||||
}
|
||||
else if (x >= winrect.left && x < winrect.left + borderWidth)
|
||||
{
|
||||
return HTLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth)
|
||||
{
|
||||
return HTRIGHT;
|
||||
}
|
||||
else if (y >= winrect.top && y < winrect.top + borderWidth)
|
||||
{
|
||||
return HTTOP;
|
||||
}
|
||||
else if (y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class FramelessViewPrivate
|
||||
{
|
||||
public:
|
||||
bool m_isMax = false;
|
||||
bool m_isFull = false;
|
||||
bool m_deleteLater = false;
|
||||
bool m_isFirst = true;
|
||||
QQuickItem *m_titleItem = nullptr;
|
||||
};
|
||||
|
||||
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
|
||||
{
|
||||
if(!isCompositionEnabled()){
|
||||
FluTheme::getInstance()->frameless(false);
|
||||
}
|
||||
if(FluTheme::getInstance()->frameless()){
|
||||
setFlag(Qt::FramelessWindowHint,true);
|
||||
}
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [=](Qt::WindowState state) {
|
||||
(void)state;
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
connect(FluTheme::getInstance(),&FluTheme::framelessChanged,this,[=](){
|
||||
setFlag(Qt::Window,false);
|
||||
setFlag(Qt::Window,true);
|
||||
});
|
||||
}
|
||||
|
||||
FramelessView::~FramelessView()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void FramelessView::showEvent(QShowEvent *e)
|
||||
{
|
||||
static const MARGINS shadow_state[2] { { 0, 0, 0, 0 }, { 1, 1, 1, 1 } };
|
||||
::DwmExtendFrameIntoClientArea((HWND)(winId()), &shadow_state[true]);
|
||||
if(FluTheme::getInstance()->frameless()){
|
||||
setFlag(Qt::FramelessWindowHint,false);
|
||||
}
|
||||
Super::showEvent(e);
|
||||
}
|
||||
|
||||
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
int h = normalSize.height();
|
||||
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
|
||||
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
|
||||
if (screenGeo.width() < w) {
|
||||
x = screenGeo.x();
|
||||
w = screenGeo.width();
|
||||
}
|
||||
if (screenGeo.height() < h) {
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
return { x, y, w, h };
|
||||
}
|
||||
|
||||
void FramelessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
|
||||
setMinimumSize(geo.size());
|
||||
}
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
|
||||
void FramelessView::closeDeleteLater(){
|
||||
d->m_deleteLater = true;
|
||||
}
|
||||
|
||||
bool FramelessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
|
||||
bool FramelessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
|
||||
QQuickItem *FramelessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
|
||||
void FramelessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
return;
|
||||
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
|
||||
void FramelessView::setIsFull(bool isFull)
|
||||
{
|
||||
if(d->m_isFull == isFull)
|
||||
return;
|
||||
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
|
||||
void FramelessView::setTitleItem(QQuickItem *item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
if (!msg || !msg->hwnd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (msg->message == WM_NCHITTEST && FluTheme::getInstance()->frameless())
|
||||
{
|
||||
RECT winrect;
|
||||
GetWindowRect(HWND(winId()), &winrect);
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
*result = 0;
|
||||
if (!isMaxWin(this) && !isFullWin(this) && !isFixWin(this))
|
||||
{
|
||||
*result = hitTest(winrect, x, y, 4);
|
||||
if (0 != *result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}else if (msg->message == WM_NCCALCSIZE && FluTheme::getInstance()->frameless())
|
||||
{
|
||||
const auto mode = static_cast<BOOL>(msg->wParam);
|
||||
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
|
||||
if (mode == TRUE)
|
||||
{
|
||||
*result = WVR_REDRAW;
|
||||
if (!isMaxWin(this) && !isFullWin(this))
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top -= 0.1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top += 0.1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}else if (msg->message == WM_WINDOWPOSCHANGING)
|
||||
{
|
||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(msg->lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
void FramelessView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Super::resizeEvent(e);
|
||||
}
|
||||
|
||||
bool FramelessView::event(QEvent *ev)
|
||||
{
|
||||
if (ev->type() == QEvent::Close) {
|
||||
if(d->m_deleteLater){
|
||||
deleteLater();
|
||||
ev->setAccepted(false);
|
||||
}
|
||||
}
|
||||
return QQuickWindow::event(ev);
|
||||
}
|
||||
|
81
src/NativeEventFilter.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "NativeEventFilter.h"
|
||||
#include "FluTheme.h"
|
||||
#include "FluApp.h"
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
#include <windowsx.h>
|
||||
#endif
|
||||
|
||||
bool NativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
if (eventType == "windows_generic_MSG" && FluTheme::getInstance()->frameless()) {
|
||||
MSG* msg = static_cast<MSG *>(message);
|
||||
if (msg == Q_NULLPTR)
|
||||
return false;
|
||||
switch(msg->message) {
|
||||
case WM_COMMAND: {
|
||||
SendMessage(msg->hwnd, WM_SYSCOMMAND, msg->wParam, msg->lParam);
|
||||
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return true;
|
||||
}
|
||||
case WM_NCCALCSIZE:{
|
||||
NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam);
|
||||
if (params.rgrc[0].top != 0)
|
||||
params.rgrc[0].top -= 1;
|
||||
*result = WVR_REDRAW;
|
||||
return true;
|
||||
}
|
||||
case WM_NCHITTEST: {
|
||||
auto view = FluApp::getInstance()->wnds[(WId)msg->hwnd];
|
||||
bool isResize = !(view->maximumWidth()==view->minimumWidth()&&view->maximumHeight()==view->minimumHeight());
|
||||
const LONG borderWidth = 8;
|
||||
RECT winrect;
|
||||
GetWindowRect(msg->hwnd, &winrect);
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
if (x >= winrect.left && x < winrect.left + borderWidth &&
|
||||
y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
return true;
|
||||
}
|
||||
if (x < winrect.right && x >= winrect.right - borderWidth &&
|
||||
y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
return true;
|
||||
}
|
||||
if (x >= winrect.left && x < winrect.left + borderWidth &&
|
||||
y >= winrect.top && y < winrect.top + borderWidth && isResize) {
|
||||
*result = HTTOPLEFT;
|
||||
return true;
|
||||
}
|
||||
if (x < winrect.right && x >= winrect.right - borderWidth &&
|
||||
y >= winrect.top && y < winrect.top + borderWidth && isResize) {
|
||||
*result = HTTOPRIGHT;
|
||||
return true;
|
||||
}
|
||||
if (x >= winrect.left && x < winrect.left + borderWidth && isResize) {
|
||||
*result = HTLEFT;
|
||||
return true;
|
||||
}
|
||||
if (x < winrect.right && x >= winrect.right - borderWidth && isResize) {
|
||||
*result = HTRIGHT;
|
||||
return true;
|
||||
}
|
||||
if (y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
|
||||
*result = HTBOTTOM;
|
||||
return true;
|
||||
}
|
||||
if (y >= winrect.top && y < winrect.top + borderWidth && isResize) {
|
||||
*result = HTTOP;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
14
src/NativeEventFilter.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef NATIVEEVENTFILTER_H
|
||||
#define NATIVEEVENTFILTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
|
||||
class NativeEventFilter : public QAbstractNativeEventFilter
|
||||
{
|
||||
|
||||
public:
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
};
|
||||
|
||||
#endif // NATIVEEVENTFILTER_H
|
@ -1,6 +1,19 @@
|
||||
#include "WindowHelper.h"
|
||||
|
||||
#include "FluRegister.h"
|
||||
#include "FluApp.h"
|
||||
#include "FluTheme.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <dwmapi.h>
|
||||
#include <Windows.h>
|
||||
#include <windowsx.h>
|
||||
enum class Style : DWORD
|
||||
{
|
||||
windowed = (WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN),
|
||||
aero_borderless = (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN)
|
||||
};
|
||||
#endif
|
||||
|
||||
WindowHelper::WindowHelper(QObject *parent)
|
||||
: QObject{parent}
|
||||
@ -8,51 +21,18 @@ WindowHelper::WindowHelper(QObject *parent)
|
||||
|
||||
}
|
||||
|
||||
void WindowHelper::setTitle(const QString& text){
|
||||
window->setTitle(text);
|
||||
}
|
||||
|
||||
void WindowHelper::initWindow(FramelessView* window){
|
||||
void WindowHelper::initWindow(QQuickWindow* window){
|
||||
this->window = window;
|
||||
}
|
||||
|
||||
QJsonObject WindowHelper::getArgument(){
|
||||
return window->property("argument").toJsonObject();
|
||||
}
|
||||
|
||||
QVariant WindowHelper::getPageRegister(){
|
||||
return window->property("pageRegister");
|
||||
}
|
||||
|
||||
void WindowHelper::setMinimumWidth(int width){
|
||||
this->window->setMinimumWidth(width);
|
||||
}
|
||||
void WindowHelper::setMaximumWidth(int width){
|
||||
this->window->setMaximumWidth(width);
|
||||
}
|
||||
void WindowHelper::setMinimumHeight(int height){
|
||||
this->window->setMinimumHeight(height);
|
||||
}
|
||||
void WindowHelper::setMaximumHeight(int height){
|
||||
this->window->setMaximumHeight(height);
|
||||
}
|
||||
void WindowHelper::updateWindow(){
|
||||
this->window->setFlag(Qt::Window,false);
|
||||
this->window->setFlag(Qt::Window,true);
|
||||
}
|
||||
void WindowHelper::setOpacity(qreal opacity){
|
||||
this->window->setOpacity(opacity);
|
||||
}
|
||||
void WindowHelper::setModality(int type){
|
||||
if(type == 0){
|
||||
this->window->setModality(Qt::NonModal);
|
||||
}else if(type == 1){
|
||||
this->window->setModality(Qt::WindowModal);
|
||||
}else if(type == 2){
|
||||
this->window->setModality(Qt::ApplicationModal);
|
||||
}else{
|
||||
this->window->setModality(Qt::NonModal);
|
||||
#ifdef Q_OS_WIN
|
||||
if(FluTheme::getInstance()->frameless()){
|
||||
HWND wnd = (HWND)window->winId();
|
||||
SetWindowLongPtr(wnd, GWL_STYLE, static_cast<LONG>(Style::aero_borderless));
|
||||
const MARGINS shadow_on = { 1, 1, 1, 1 };
|
||||
DwmExtendFrameIntoClientArea(wnd, &shadow_on);
|
||||
SetWindowPos(wnd, Q_NULLPTR, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||
ShowWindow(wnd, SW_SHOW);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QVariant WindowHelper::createRegister(const QString& path){
|
||||
@ -61,3 +41,10 @@ QVariant WindowHelper::createRegister(const QString& path){
|
||||
p->path(path);
|
||||
return QVariant::fromValue(p);
|
||||
}
|
||||
|
||||
void WindowHelper::destoryWindow(){
|
||||
if(this->window){
|
||||
FluApp::getInstance()->wnds.remove(this->window->winId());
|
||||
this->window->deleteLater();
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <QQuickItem>
|
||||
#include <QWindow>
|
||||
#include <QJsonObject>
|
||||
#include "FramelessView.h"
|
||||
|
||||
class WindowHelper : public QObject
|
||||
{
|
||||
@ -15,22 +14,12 @@ class WindowHelper : public QObject
|
||||
public:
|
||||
explicit WindowHelper(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void initWindow(FramelessView* window);
|
||||
Q_INVOKABLE void setTitle(const QString& text);
|
||||
Q_INVOKABLE void setMinimumWidth(int width);
|
||||
Q_INVOKABLE void setMaximumWidth(int width);
|
||||
Q_INVOKABLE void setMinimumHeight(int height);
|
||||
Q_INVOKABLE void setMaximumHeight(int height);
|
||||
Q_INVOKABLE QJsonObject getArgument();
|
||||
Q_INVOKABLE QVariant getPageRegister();
|
||||
Q_INVOKABLE void updateWindow();
|
||||
Q_INVOKABLE void setOpacity(qreal opacity);
|
||||
Q_INVOKABLE void setModality(int type);
|
||||
Q_INVOKABLE void initWindow(QQuickWindow* window);
|
||||
Q_INVOKABLE void destoryWindow();
|
||||
Q_INVOKABLE QVariant createRegister(const QString& path);
|
||||
|
||||
private:
|
||||
FramelessView* window;
|
||||
|
||||
QQuickWindow* window;
|
||||
};
|
||||
|
||||
#endif // WINDOWHELPER_H
|
||||
|
32
src/build_macos.cmake
Normal file
@ -0,0 +1,32 @@
|
||||
set(OUTP ${CMAKE_BINARY_DIR}/bin/FluentUI/)
|
||||
|
||||
add_definitions(-DMACOS)
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX ${OUTP})
|
||||
set(CMAKE_INSTALL_DESTDIR ${OUTP})
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(QMAKE_MOC_OPTIONS -Muri=${uri})
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND chmod -R 777 ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh PRESET ${CMAKE_CURRENT_SOURCE_DIR}/ ${OUTP}
|
||||
)
|
||||
|
||||
|
||||
|
||||
if(${TARGET_TYPE} STREQUAL "SHARED")
|
||||
|
||||
set(INST_QMLPATH ${QT_INSTALL_QML}/FluentUI)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/ ${OUTP} ${INST_QMLPATH}
|
||||
)
|
||||
|
||||
endif()
|
27
src/build_windows.cmake
Normal file
@ -0,0 +1,27 @@
|
||||
set(OUTP "${CMAKE_BINARY_DIR}/bin/FluentUI")
|
||||
set(BUILDBIN_PATH "${OUTP}")
|
||||
set(QTQMLFLUENT_PATH "${QT_INSTALL_QML}/FluentUI")
|
||||
set(PRESET_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build-preset")
|
||||
set(SOLIBFILE_PATH "${CMAKE_BINARY_DIR}/libFluentUI.so")
|
||||
set(ANDROID NO)
|
||||
if (ANDROID)
|
||||
set(ANDROID YES)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTP})
|
||||
else()
|
||||
set(CMAKE_INSTALL_PREFIX "${OUTP}")
|
||||
endif()
|
||||
set(SHAREDSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/win_install.bat SHARED ${CMAKE_CURRENT_SOURCE_DIR} ${PRESET_PATH} ${BUILDBIN_PATH} ${QTQMLFLUENT_PATH} ${ANDROID} ${SOLIBFILE_PATH})
|
||||
set(STATICSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/win_install.bat STATIC ${CMAKE_CURRENT_SOURCE_DIR} ${PRESET_PATH} ${BUILDBIN_PATH} ${QTQMLFLUENT_PATH} ${ANDROID} ${SOLIBFILE_PATH})
|
||||
string(REPLACE "/" "\\" SHAREDSCRIPT "${SHAREDSCRIPT}")
|
||||
string(REPLACE "/" "\\" STATICSCRIPT "${STATICSCRIPT}")
|
||||
if (${TARGET_TYPE} STREQUAL "SHARED")
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${SHAREDSCRIPT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${STATICSCRIPT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
endif()
|
@ -4,17 +4,14 @@ QTQMLFLUENT_PATH = $$[QT_INSTALL_QML]/FluentUI
|
||||
PRESET_PATH = $$PWD/build-preset
|
||||
SOLIBFILE_PATH = $$OUT_PWD/libFluentUI.so
|
||||
ANDROID = NO
|
||||
|
||||
android{
|
||||
ANDROID=YES
|
||||
QMAKE_PRE_LINK *= md $$replace(OUTP, /, \\)
|
||||
}else{
|
||||
DESTDIR += $$OUTP
|
||||
}
|
||||
|
||||
SHAREDSCRIPT = "$$PWD\win_install.bat" SHARED "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
|
||||
STATICSCRIPT = "$$PWD\win_install.bat" STATIC "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
|
||||
|
||||
CONFIG(sharedlib){
|
||||
QMAKE_POST_LINK *= $$replace(SHAREDSCRIPT, /, \\)
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ Item {
|
||||
pickerCursor.y = Math.max(0, Math.min(height, mouse.y)-cursorHeight)
|
||||
}
|
||||
}
|
||||
onPositionChanged: {
|
||||
onPositionChanged:(mouse)=> {
|
||||
handleMouse(mouse)
|
||||
}
|
||||
onPressed: handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
|
||||
function setValue(val) {
|
||||
|
@ -7,23 +7,35 @@ import FluentUI
|
||||
Rectangle{
|
||||
|
||||
property string title: ""
|
||||
property string darkText : "夜间模式"
|
||||
property string minimizeText : "最小化"
|
||||
property string restoreText : "向下还原"
|
||||
property string maximizeText : "最大化"
|
||||
property string closeText : "关闭"
|
||||
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
|
||||
property color minimizeNormalColor: Qt.rgba(0,0,0,0)
|
||||
property color minimizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
|
||||
property color maximizeNormalColor: Qt.rgba(0,0,0,0)
|
||||
property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
|
||||
property color closeNormalColor: Qt.rgba(0,0,0,0)
|
||||
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
|
||||
|
||||
|
||||
property bool showDark: false
|
||||
property bool showFps: false
|
||||
property var window: Window.window
|
||||
property color borerlessColor : FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
property bool resizable: {
|
||||
if(window == null){
|
||||
return false
|
||||
}
|
||||
return !(window.minimumHeight === window.maximumHeight && window.maximumWidth === window.minimumWidth)
|
||||
|
||||
Item{
|
||||
id:d
|
||||
property var win: Window.window
|
||||
property bool isRestore: win && Window.Maximized === win.visibility
|
||||
property bool resizable: win && !(win.minimumHeight === win.maximumHeight && win.maximumWidth === win.minimumWidth)
|
||||
}
|
||||
|
||||
id:root
|
||||
color: Qt.rgba(0,0,0,0)
|
||||
visible: FluTheme.frameless
|
||||
height: visible ? 30 : 0
|
||||
clip: true
|
||||
opacity: visible
|
||||
z: 65535
|
||||
|
||||
TapHandler {
|
||||
@ -34,7 +46,7 @@ Rectangle{
|
||||
DragHandler {
|
||||
target: null
|
||||
grabPermissions: TapHandler.CanTakeOverFromAnything
|
||||
onActiveChanged: if (active) { window.startSystemMove(); }
|
||||
onActiveChanged: if (active) { d.win.startSystemMove(); }
|
||||
}
|
||||
|
||||
FluText {
|
||||
@ -55,13 +67,6 @@ Rectangle{
|
||||
height: root.height
|
||||
spacing: 0
|
||||
|
||||
TFpsMonitor{
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.rightMargin: 20
|
||||
Layout.topMargin: 5
|
||||
color:root.textColor
|
||||
visible: showFps
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@ -69,7 +74,7 @@ Rectangle{
|
||||
visible: showDark
|
||||
spacing: 5
|
||||
FluText{
|
||||
text:"夜间模式"
|
||||
text:darkText
|
||||
color:root.textColor
|
||||
}
|
||||
FluToggleSwitch{
|
||||
@ -86,53 +91,24 @@ Rectangle{
|
||||
iconSource : FluentIcons.ChromeMinimize
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 11
|
||||
text:"最小化"
|
||||
text:minimizeText
|
||||
radius: 0
|
||||
textColor: root.textColor
|
||||
color:{
|
||||
if(FluTheme.dark){
|
||||
if(hovered){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}else{
|
||||
if(hovered){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
iconColor: root.textColor
|
||||
color: hovered ? minimizeHoverColor : minimizeNormalColor
|
||||
onClicked: {
|
||||
window.showMinimized()
|
||||
d.win.showMinimized()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
width: 40
|
||||
height: 30
|
||||
property bool isRestore:{
|
||||
if(window == null)
|
||||
return false
|
||||
return Window.Maximized === window.visibility
|
||||
}
|
||||
iconSource : isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
|
||||
color:{
|
||||
if(FluTheme.dark){
|
||||
if(hovered){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}else{
|
||||
if(hovered){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
|
||||
color: hovered ? maximizeHoverColor : maximizeNormalColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: resizable
|
||||
visible: d.resizable
|
||||
radius: 0
|
||||
textColor: root.textColor
|
||||
text:isRestore?"向下还原":"最大化"
|
||||
iconColor: root.textColor
|
||||
text:d.isRestore?restoreText:maximizeText
|
||||
iconSize: 11
|
||||
onClicked: {
|
||||
toggleMaximized()
|
||||
@ -141,26 +117,26 @@ Rectangle{
|
||||
FluIconButton{
|
||||
iconSource : FluentIcons.ChromeClose
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text:"关闭"
|
||||
text:closeText
|
||||
width: 40
|
||||
height: 30
|
||||
radius: 0
|
||||
iconSize: 10
|
||||
textColor: hovered ? Qt.rgba(1,1,1,1) : root.textColor
|
||||
color:hovered ? Qt.rgba(251/255,115/255,115/255,1) : "#00000000"
|
||||
iconColor: hovered ? Qt.rgba(1,1,1,1) : root.textColor
|
||||
color:hovered ? closeHoverColor : closeNormalColor
|
||||
onClicked: {
|
||||
Window.window.close()
|
||||
d.win.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMaximized() {
|
||||
if(!resizable)
|
||||
if(!d.resizable)
|
||||
return
|
||||
if (window.visibility === Window.Maximized) {
|
||||
window.showNormal();
|
||||
if (d.win.visibility === Window.Maximized) {
|
||||
d.win.showNormal();
|
||||
} else {
|
||||
window.showMaximized();
|
||||
d.win.showMaximized();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,138 +2,30 @@
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
TextField{
|
||||
|
||||
FluTextBox{
|
||||
property var items:[]
|
||||
property int fontStyle: FluText.Body
|
||||
property int pixelSize : FluTheme.textSize
|
||||
property int iconSource: 0
|
||||
property bool disabled: false
|
||||
property string emptyText: "没有找到结果"
|
||||
property int autoSuggestBoxReplacement: FluentIcons.Search
|
||||
signal itemClicked(var data)
|
||||
signal handleClicked
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flagVisible: true
|
||||
}
|
||||
id:input
|
||||
id:control
|
||||
width: 300
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(disabled){
|
||||
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
}
|
||||
selectionColor: FluTheme.primaryColor.lightest
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
placeholderTextColor: {
|
||||
if(disabled){
|
||||
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(focus){
|
||||
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
rightPadding: icon_right.visible ? 50 : 30
|
||||
selectByMouse: true
|
||||
Keys.onUpPressed: {
|
||||
list_view.currentIndex = Math.max(list_view.currentIndex-1,0)
|
||||
}
|
||||
Keys.onDownPressed: {
|
||||
list_view.currentIndex = Math.min(list_view.currentIndex+1,list_view.count-1)
|
||||
}
|
||||
Keys.onEnterPressed:handleClicked()
|
||||
Keys.onReturnPressed:handleClicked()
|
||||
font.bold: {
|
||||
switch (fontStyle) {
|
||||
case FluText.Display:
|
||||
return true
|
||||
case FluText.TitleLarge:
|
||||
return true
|
||||
case FluText.Title:
|
||||
return true
|
||||
case FluText.SubTitle:
|
||||
return true
|
||||
case FluText.BodyStrong:
|
||||
return true
|
||||
case FluText.Body:
|
||||
return false
|
||||
case FluText.Caption:
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
font.pixelSize: {
|
||||
switch (fontStyle) {
|
||||
case FluText.Display:
|
||||
return text.pixelSize * 4.857
|
||||
case FluText.TitleLarge:
|
||||
return text.pixelSize * 2.857
|
||||
case FluText.Title:
|
||||
return text.pixelSize * 2
|
||||
case FluText.SubTitle:
|
||||
return text.pixelSize * 1.428
|
||||
case FluText.Body:
|
||||
return text.pixelSize * 1.0
|
||||
case FluText.BodyStrong:
|
||||
return text.pixelSize * 1.0
|
||||
case FluText.Caption:
|
||||
return text.pixelSize * 0.857
|
||||
default:
|
||||
return text.pixelSize * 1.0
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
iconSource:FluentIcons.ChromeClose
|
||||
iconSize: 10
|
||||
width: 20
|
||||
height: 20
|
||||
opacity: 0.5
|
||||
visible: input.text !== ""
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: icon_right.visible ? 25 : 5
|
||||
}
|
||||
onClicked:{
|
||||
input.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: input
|
||||
|
||||
|
||||
FluIcon{
|
||||
id:icon_right
|
||||
iconSource: input.iconSource
|
||||
iconSize: 15
|
||||
opacity: 0.5
|
||||
visible: input.iconSource != 0
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
searchData()
|
||||
loadData()
|
||||
}
|
||||
|
||||
Popup{
|
||||
id:input_popup
|
||||
y:input.height
|
||||
id:control_popup
|
||||
y:control.height
|
||||
focus: false
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "y"
|
||||
from:0
|
||||
to:input_popup.y
|
||||
to:control_popup.y
|
||||
duration: 150
|
||||
}
|
||||
NumberAnimation {
|
||||
@ -149,7 +41,7 @@ TextField{
|
||||
}
|
||||
}
|
||||
background: Rectangle{
|
||||
width: input.width
|
||||
width: control.width
|
||||
radius: 4
|
||||
FluShadow{
|
||||
radius: 4
|
||||
@ -163,11 +55,11 @@ TextField{
|
||||
currentIndex: -1
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
header: Item{
|
||||
width: input.width
|
||||
width: control.width
|
||||
height: visible ? 38 : 0
|
||||
visible: list_view.count === 0
|
||||
FluText{
|
||||
text:"没有找到结果"
|
||||
text:emptyText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
@ -176,7 +68,7 @@ TextField{
|
||||
}
|
||||
}
|
||||
delegate:Control{
|
||||
width: input.width
|
||||
width: control.width
|
||||
padding:10
|
||||
background: Rectangle{
|
||||
color: {
|
||||
@ -192,7 +84,7 @@ TextField{
|
||||
id:mouse_area
|
||||
anchors.fill: parent
|
||||
Connections{
|
||||
target: input
|
||||
target: control
|
||||
function onHandleClicked(){
|
||||
if((list_view.currentIndex === index)){
|
||||
handleClick(modelData)
|
||||
@ -223,72 +115,41 @@ TextField{
|
||||
}
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
loadData()
|
||||
if(d.flagVisible){
|
||||
control_popup.visible = true
|
||||
}
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: control.echoMode !== TextInput.Password && menu.popup()
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
|
||||
function handleClick(modelData){
|
||||
input_popup.visible = false
|
||||
input.itemClicked(modelData)
|
||||
control_popup.visible = false
|
||||
control.itemClicked(modelData)
|
||||
updateText(modelData.title)
|
||||
}
|
||||
|
||||
function updateText(text){
|
||||
d.flagVisible = false
|
||||
input.text = text
|
||||
control.text = text
|
||||
d.flagVisible = true
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
searchData()
|
||||
if(d.flagVisible){
|
||||
input_popup.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: input.echoMode !== TextInput.Password && menu.popup()
|
||||
}
|
||||
|
||||
FluMenu{
|
||||
id:menu
|
||||
focus: false
|
||||
FluMenuItem{
|
||||
text: "剪切"
|
||||
visible: input.text !== ""
|
||||
onClicked: {
|
||||
input.cut()
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text: "复制"
|
||||
visible: input.selectedText !== ""
|
||||
onClicked: {
|
||||
input.copy()
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text: "粘贴"
|
||||
visible: input.canPaste
|
||||
onClicked: {
|
||||
input.paste()
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text: "全选"
|
||||
visible: input.text !== ""
|
||||
onClicked: {
|
||||
input.selectAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function searchData(){
|
||||
function loadData(){
|
||||
var result = []
|
||||
if(items==null){
|
||||
list_view.model = result
|
||||
return
|
||||
}
|
||||
items.map(function(item){
|
||||
if(item.title.indexOf(input.text)!==-1){
|
||||
if(item.title.indexOf(control.text)!==-1){
|
||||
result.push(item)
|
||||
}
|
||||
})
|
||||
@ -296,4 +157,3 @@ TextField{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
FluControl {
|
||||
|
||||
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)
|
||||
@ -43,11 +43,17 @@ Button {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,10 @@ 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 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 string text: "请选择日期"
|
||||
property var window : Window.window
|
||||
|
||||
id:root
|
||||
id:control
|
||||
color: {
|
||||
if(mouse_area.containsMouse){
|
||||
return hoverColor
|
||||
@ -44,7 +45,7 @@ Rectangle {
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:"请选择日期"
|
||||
text:control.text
|
||||
}
|
||||
|
||||
FluIcon{
|
||||
@ -95,15 +96,15 @@ Rectangle {
|
||||
}
|
||||
background: Item{}
|
||||
function showPopup() {
|
||||
var pos = root.mapToItem(null, 0, 0)
|
||||
if(window.height>pos.y+root.height+popup.height){
|
||||
popup.y = root.height
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(window.height>pos.y+control.height+popup.height){
|
||||
popup.y = control.height
|
||||
} else if(pos.y>popup.height){
|
||||
popup.y = -popup.height
|
||||
} else {
|
||||
popup.y = window.height-(pos.y+popup.height)
|
||||
}
|
||||
popup.x = -(popup.width-root.width)/2
|
||||
popup.x = -(popup.width-control.width)/2
|
||||
popup.open()
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
FluControl {
|
||||
|
||||
property bool selected: false
|
||||
property var clickFunc
|
||||
@ -12,10 +12,13 @@ Button {
|
||||
property color borderSelectedColor: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
property color borderHoverColor: FluTheme.dark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1)
|
||||
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color borderPressedColor: FluTheme.dark ? Qt.rgba(90/255,90/255,90/255,1) : Qt.rgba(191/255,191/255,191/255,1)
|
||||
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1)
|
||||
property color selectedColor: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color selectedHoverColor: FluTheme.dark ? Qt.darker(selectedColor,1.1) : Qt.lighter(selectedColor,1.1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(72/255,72/255,72/255,1) : Qt.rgba(236/255,236/255,236/255,1)
|
||||
property color selectedHoverColor: FluTheme.dark ? Qt.darker(selectedColor,1.15) : Qt.lighter(selectedColor,1.15)
|
||||
property color selectedPreesedColor: FluTheme.dark ? Qt.darker(selectedColor,1.3) : Qt.lighter(selectedColor,1.3)
|
||||
property color selectedDisableColor: 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)
|
||||
|
||||
@ -52,6 +55,9 @@ Button {
|
||||
if(selected){
|
||||
return borderSelectedColor
|
||||
}
|
||||
if(pressed){
|
||||
return borderPressedColor
|
||||
}
|
||||
if(hovered){
|
||||
return borderHoverColor
|
||||
}
|
||||
@ -63,6 +69,9 @@ Button {
|
||||
if(disabled){
|
||||
return selectedDisableColor
|
||||
}
|
||||
if(pressed){
|
||||
return selectedPreesedColor
|
||||
}
|
||||
if(hovered){
|
||||
return selectedHoverColor
|
||||
}
|
||||
|
@ -4,8 +4,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
|
||||
Button{
|
||||
FluControl{
|
||||
id:control
|
||||
width: 36
|
||||
height: 36
|
||||
|
13
src/controls/FluControl.qml
Normal file
@ -0,0 +1,13 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.Button {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
}
|
@ -3,7 +3,7 @@ import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
FluControl {
|
||||
|
||||
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)
|
||||
@ -58,11 +58,17 @@ Button {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,13 @@
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
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.1) : Qt.lighter(normalColor,1.1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)
|
||||
|
||||
id: control
|
||||
enabled: !disabled
|
||||
@ -27,6 +28,9 @@ Button {
|
||||
if(disabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
@ -44,6 +48,5 @@ Button {
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
|
116
src/controls/FluFlipView.qml
Normal file
@ -0,0 +1,116 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
|
||||
property bool vertical: false
|
||||
default property alias content : swipe.contentData
|
||||
property alias currentIndex: swipe.currentIndex
|
||||
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flag: true
|
||||
}
|
||||
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onWheel:
|
||||
(wheel)=>{
|
||||
if(!d.flag)
|
||||
return
|
||||
if (wheel.angleDelta.y > 0){
|
||||
btn_start.clicked()
|
||||
}else{
|
||||
btn_end.clicked()
|
||||
}
|
||||
d.flag = false
|
||||
timer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer
|
||||
interval: 250
|
||||
onTriggered: {
|
||||
d.flag = true
|
||||
}
|
||||
}
|
||||
|
||||
SwipeView {
|
||||
id:swipe
|
||||
clip: true
|
||||
interactive: false
|
||||
orientation:control.vertical ? Qt.Vertical : Qt.Horizontal
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
FluControl{
|
||||
id:btn_start
|
||||
height: vertical ? 20 : 40
|
||||
width: vertical ? 40 : 20
|
||||
anchors{
|
||||
left: vertical ? undefined : parent.left
|
||||
leftMargin: vertical ? undefined : 2
|
||||
verticalCenter: vertical ? undefined : parent.verticalCenter
|
||||
horizontalCenter: !vertical ? undefined : parent.horizontalCenter
|
||||
top: !vertical ? undefined :parent.top
|
||||
topMargin: !vertical ? undefined :2
|
||||
}
|
||||
background: Rectangle{
|
||||
radius: 4
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
|
||||
}
|
||||
contentItem:FluIcon{
|
||||
iconSource: vertical ? FluentIcons.CaretUpSolid8 : FluentIcons.CaretLeftSolid8
|
||||
width: 10
|
||||
height: 10
|
||||
iconSize: 10
|
||||
iconColor: btn_start.hovered ? FluColors.Grey220 : FluColors.Grey120
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
visible: swipe.currentIndex !==0
|
||||
onClicked: {
|
||||
swipe.currentIndex = Math.max(swipe.currentIndex - 1, 0)
|
||||
}
|
||||
}
|
||||
|
||||
FluControl{
|
||||
id:btn_end
|
||||
height: vertical ? 20 : 40
|
||||
width: vertical ? 40 : 20
|
||||
anchors{
|
||||
right: vertical ? undefined : parent.right
|
||||
rightMargin: vertical ? undefined : 2
|
||||
verticalCenter: vertical ? undefined : parent.verticalCenter
|
||||
horizontalCenter: !vertical ? undefined : parent.horizontalCenter
|
||||
bottom: !vertical ? undefined :parent.bottom
|
||||
bottomMargin: !vertical ? undefined :2
|
||||
}
|
||||
background: Rectangle{
|
||||
radius: 4
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
|
||||
}
|
||||
visible: swipe.currentIndex !== swipe.count - 1
|
||||
contentItem:FluIcon{
|
||||
iconSource: vertical ? FluentIcons.CaretDownSolid8 : FluentIcons.CaretRightSolid8
|
||||
width: 10
|
||||
height: 10
|
||||
iconSize: 10
|
||||
iconColor: btn_end.hovered ? FluColors.Grey220 : FluColors.Grey120
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
onClicked: {
|
||||
swipe.currentIndex = Math.min(swipe.currentIndex + 1,swipe.count-1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,22 +2,26 @@
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
FluControl {
|
||||
|
||||
property int iconSize: 20
|
||||
property int iconSource
|
||||
property bool disabled: false
|
||||
property int radius:4
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : 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 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 color: {
|
||||
if(disabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor : normalColor
|
||||
}
|
||||
property color textColor: {
|
||||
property color iconColor: {
|
||||
if(FluTheme.dark){
|
||||
if(disabled){
|
||||
return Qt.rgba(130/255,130/255,130/255,1)
|
||||
@ -34,6 +38,7 @@ Button {
|
||||
id:control
|
||||
width: 30
|
||||
height: 30
|
||||
clip: true
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
padding: 0
|
||||
@ -57,7 +62,7 @@ Button {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
anchors.centerIn: parent
|
||||
color:control.textColor
|
||||
color:control.iconColor
|
||||
text: (String.fromCharCode(iconSource).toString(16));
|
||||
}
|
||||
FluTooltip{
|
||||
|
@ -28,7 +28,9 @@ Rectangle {
|
||||
property bool autoSeek:true
|
||||
source: control.source
|
||||
videoOutput: video_output
|
||||
audioOutput:audio_output
|
||||
audioOutput: AudioOutput{
|
||||
id:audio_output
|
||||
}
|
||||
onErrorChanged:
|
||||
(error)=> {
|
||||
console.debug(error)
|
||||
@ -41,10 +43,9 @@ Rectangle {
|
||||
onMediaStatusChanged:
|
||||
(status)=> {
|
||||
if(status===2){
|
||||
mediaplayer.play()
|
||||
}else if(status===5){
|
||||
slider.maxValue = mediaplayer.duration
|
||||
showControl = true
|
||||
mediaplayer.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,10 +54,6 @@ Rectangle {
|
||||
slider.seek(0)
|
||||
}
|
||||
|
||||
AudioOutput{
|
||||
id:audio_output
|
||||
}
|
||||
|
||||
VideoOutput {
|
||||
id:video_output
|
||||
anchors.fill: parent
|
||||
@ -66,21 +63,23 @@ Rectangle {
|
||||
height: 100
|
||||
y:showControl ? control.height - 110 : control.height
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: 10
|
||||
rightMargin: 10
|
||||
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)
|
||||
@ -102,13 +101,11 @@ Rectangle {
|
||||
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
|
||||
}
|
||||
@ -124,7 +121,6 @@ Rectangle {
|
||||
text: formatDuration(slider.value*mediaplayer.duration/slider.maxValue)
|
||||
}
|
||||
|
||||
|
||||
FluText{
|
||||
id:end_time
|
||||
anchors{
|
||||
@ -135,7 +131,6 @@ Rectangle {
|
||||
text: formatDuration(mediaplayer.duration)
|
||||
}
|
||||
|
||||
|
||||
Row{
|
||||
spacing: 10
|
||||
anchors{
|
||||
@ -170,11 +165,10 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FluIconButton{
|
||||
id:btn_volume
|
||||
iconSize: 17
|
||||
iconSource: audio_output.volume ? FluentIcons.Volume : FluentIcons.Mute
|
||||
iconSource: audio_output.muted ? FluentIcons.Mute : FluentIcons.Volume
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 5
|
||||
@ -182,7 +176,7 @@ Rectangle {
|
||||
bottomMargin: 10
|
||||
}
|
||||
onClicked: {
|
||||
audio_output.volume = !audio_output.volume
|
||||
audio_output.muted = !audio_output.muted
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +194,6 @@ Rectangle {
|
||||
audio_output.volume = value/100
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function formatDuration(duration) {
|
||||
|
@ -2,36 +2,37 @@
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
TextArea{
|
||||
FluTextArea{
|
||||
|
||||
property int fontStyle: FluText.Body
|
||||
property int pixelSize : FluTheme.textSize
|
||||
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 disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
|
||||
id:input
|
||||
id:control
|
||||
width: 300
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(disabled){
|
||||
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
return disableColor
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
return normalColor
|
||||
}
|
||||
enabled: !disabled
|
||||
wrapMode: Text.WrapAnywhere
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectByMouse: true
|
||||
selectionColor: FluTheme.primaryColor.lightest
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: input
|
||||
}
|
||||
placeholderTextColor: {
|
||||
if(disabled){
|
||||
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
return placeholderDisableColor
|
||||
}
|
||||
if(focus){
|
||||
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
return placeholderFocusColor
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
return placeholderNormalColor
|
||||
}
|
||||
font.bold: {
|
||||
switch (fontStyle) {
|
||||
@ -73,40 +74,15 @@ TextArea{
|
||||
return text.pixelSize * 1.0
|
||||
}
|
||||
}
|
||||
selectByMouse: true
|
||||
background: FluTextBoxBackground{ inputItem: control }
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: input.echoMode !== TextInput.Password && menu.popup()
|
||||
onTapped: control.echoMode !== TextInput.Password && menu.popup()
|
||||
}
|
||||
FluMenu{
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
focus: false
|
||||
FluMenuItem{
|
||||
text: "剪切"
|
||||
visible: input.text !== ""
|
||||
onClicked: {
|
||||
input.cut()
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text: "复制"
|
||||
visible: input.selectedText !== ""
|
||||
onClicked: {
|
||||
input.copy()
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text: "粘贴"
|
||||
visible: input.canPaste
|
||||
onClicked: {
|
||||
input.paste()
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text: "全选"
|
||||
visible: input.text !== ""
|
||||
onClicked: {
|
||||
input.selectAll()
|
||||
}
|
||||
}
|
||||
inputItem: control
|
||||
}
|
||||
|
||||
}
|
@ -6,57 +6,141 @@ 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
|
||||
height: 1
|
||||
width: layout_list.width
|
||||
height: {
|
||||
if(model.parent){
|
||||
return model.parent.isExpand ? 1 : 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
Behavior on height {
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_panel_item_header
|
||||
Item{
|
||||
height: 30
|
||||
width: nav_list.width
|
||||
height: {
|
||||
if(model.parent){
|
||||
return model.parent.isExpand ? 30 : 0
|
||||
}
|
||||
return 30
|
||||
}
|
||||
Behavior on height {
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
width: layout_list.width
|
||||
FluText{
|
||||
text:model.title
|
||||
fontStyle: FluText.BodyStrong
|
||||
@ -70,11 +154,10 @@ Item {
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_panel_item
|
||||
id:com_panel_item_expander
|
||||
Item{
|
||||
height: 38
|
||||
width: nav_list.width
|
||||
|
||||
width: layout_list.width
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors{
|
||||
@ -92,48 +175,77 @@ Item {
|
||||
height: 18
|
||||
radius: 1.5
|
||||
color: FluTheme.primaryColor.dark
|
||||
visible: nav_list.currentIndex === position && type===0
|
||||
visible: {
|
||||
for(var i=0;i<model.children.length;i++){
|
||||
var item = model.children[i]
|
||||
if(item.idx === nav_list.currentIndex && !model.isExpand){
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
FluIcon{
|
||||
rotation: model.isExpand?0:180
|
||||
iconSource:FluentIcons.ChevronUp
|
||||
iconSize: 15
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if(type===0){
|
||||
model.repTap()
|
||||
if(nav_list.currentIndex !== position){
|
||||
nav_list.currentIndex = position
|
||||
model.tap()
|
||||
}
|
||||
}else{
|
||||
model.tap()
|
||||
if(d.isCompactAndNotPanel){
|
||||
control_popup.showPopup(Qt.point(50,mapToItem(control,0,0).y),model.children)
|
||||
return
|
||||
}
|
||||
displaMinimalMenu = false
|
||||
model.isExpand = !model.isExpand
|
||||
}
|
||||
}
|
||||
color: {
|
||||
if(FluTheme.dark){
|
||||
if((nav_list.currentIndex === idx)&&type===0){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return Qt.rgba(1,1,1,0.03)
|
||||
}
|
||||
if((nav_list.currentIndex === position)&&type===0){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}else{
|
||||
if(nav_list.currentIndex === idx&&type===0){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return Qt.rgba(0,0,0,0.03)
|
||||
}
|
||||
if(nav_list.currentIndex === position&&type===0){
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon{
|
||||
id:item_icon
|
||||
iconSource: {
|
||||
@ -151,10 +263,163 @@ 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
|
||||
}
|
||||
color:{
|
||||
if(item_mouse.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_panel_item
|
||||
Item{
|
||||
Behavior on height {
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
clip: true
|
||||
height: {
|
||||
if(model.parent){
|
||||
return model.parent.isExpand ? 38 : 0
|
||||
}
|
||||
return 38
|
||||
}
|
||||
width: layout_list.width
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
topMargin: 2
|
||||
bottomMargin: 2
|
||||
leftMargin: 6
|
||||
rightMargin: 6
|
||||
}
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if(type === 0){
|
||||
if(model.tapFunc){
|
||||
model.tapFunc()
|
||||
}else{
|
||||
nav_list.currentIndex = idx
|
||||
layout_footer.currentIndex = -1
|
||||
if(d.isMinimal || d.isCompact){
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
}else{
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
color: {
|
||||
if(FluTheme.dark){
|
||||
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(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)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
FluIcon{
|
||||
id:item_icon
|
||||
iconSource: {
|
||||
if(model.icon){
|
||||
return model.icon
|
||||
}
|
||||
return 0
|
||||
}
|
||||
width: 30
|
||||
height: 30
|
||||
iconSize: 15
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:parent.left
|
||||
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
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:item_icon.right
|
||||
@ -164,6 +429,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id:nav_app_bar
|
||||
width: parent.width
|
||||
@ -182,30 +448,40 @@ 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{
|
||||
id:btn_nav
|
||||
iconSource: FluentIcons.GlobalNavButton
|
||||
iconSize: 15
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredWidth: d.isMinimal ? 40 : 0
|
||||
Layout.preferredHeight: 40
|
||||
visible: displayMode === FluNavigationView.Minimal
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: {
|
||||
displaMinimalMenu = !displaMinimalMenu
|
||||
d.enableNavigationPanel = !d.enableNavigationPanel
|
||||
}
|
||||
Behavior on Layout.preferredWidth{
|
||||
NumberAnimation{
|
||||
duration: 220
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image{
|
||||
id:image_logo
|
||||
Layout.preferredHeight: 20
|
||||
Layout.preferredWidth: 20
|
||||
source: control.logo
|
||||
Layout.leftMargin: {
|
||||
if(btn_nav.visible){
|
||||
return 12
|
||||
@ -216,7 +492,7 @@ Item {
|
||||
}
|
||||
FluText{
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text:root.title
|
||||
text:control.title
|
||||
Layout.leftMargin: 12
|
||||
fontStyle: FluText.Body
|
||||
}
|
||||
@ -225,12 +501,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
|
||||
@ -250,19 +526,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){
|
||||
@ -270,50 +566,98 @@ 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
|
||||
opacity: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
visible: opacity
|
||||
Behavior on opacity{
|
||||
NumberAnimation{
|
||||
duration: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
visible:opacity
|
||||
opacity:d.isCompactAndNotPanel
|
||||
Behavior on opacity{
|
||||
NumberAnimation{
|
||||
duration: 220
|
||||
}
|
||||
}
|
||||
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
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model:d.handleItems()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -321,23 +665,9 @@ Item {
|
||||
right: parent.right
|
||||
bottom: layout_footer.top
|
||||
}
|
||||
highlightMoveDuration: 150
|
||||
currentIndex: -1
|
||||
onCurrentIndexChanged: {
|
||||
if(enableStack){
|
||||
stackIndex.push(currentIndex)
|
||||
}
|
||||
}
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
|
||||
model:{
|
||||
if(items){
|
||||
return items.children
|
||||
}
|
||||
}
|
||||
delegate: Loader{
|
||||
property var model: modelData
|
||||
property var position: index
|
||||
property var idx: index
|
||||
property int type: 0
|
||||
sourceComponent: {
|
||||
if(modelData instanceof FluPaneItem){
|
||||
@ -349,24 +679,46 @@ Item {
|
||||
if(modelData instanceof FluPaneItemSeparator){
|
||||
return com_panel_item_separatorr
|
||||
}
|
||||
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){
|
||||
@ -383,16 +735,121 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function push(url){
|
||||
nav_swipe.push(url)
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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(){
|
||||
return nav_list.model
|
||||
}
|
||||
|
||||
function push(url){
|
||||
nav_swipe.push(url)
|
||||
}
|
||||
|
||||
function getCurrentIndex(){
|
||||
return nav_list.currentIndex
|
||||
}
|
||||
|
||||
function startPageByItem(data){
|
||||
var items = getItems();
|
||||
for(var i=0;i<items.length;i++){
|
||||
var item = items[i]
|
||||
if(item.key === data.key){
|
||||
if(getCurrentIndex() === i){
|
||||
return
|
||||
}
|
||||
setCurrentIndex(i)
|
||||
if(item.parent && !d.isCompactAndNotPanel){
|
||||
item.parent.isExpand = true
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
112
src/controls/FluPagination.qml
Normal file
@ -0,0 +1,112 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
id: control
|
||||
|
||||
|
||||
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
|
||||
property int __itemPerPage: 10
|
||||
property int pageButtonCount: 5
|
||||
property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1
|
||||
|
||||
|
||||
implicitHeight: 40
|
||||
implicitWidth: content.width
|
||||
|
||||
Row{
|
||||
id: content
|
||||
height: control.height
|
||||
spacing: 25
|
||||
padding: 10
|
||||
|
||||
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent<=1
|
||||
text:control.previousText
|
||||
onClicked: {
|
||||
control.calcNewPage(control.pageCurrent-1);
|
||||
}
|
||||
}
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
FluToggleButton{
|
||||
property int pageNumber:1
|
||||
visible: control.pageCount>0
|
||||
enabled: control.pageCurrent>1
|
||||
selected: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
onClicked: {
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: (control.pageCount>control.pageButtonCount&&
|
||||
control.pageCurrent>control.__pageButtonHalf)
|
||||
text: "..."
|
||||
}
|
||||
Repeater{
|
||||
id: button_repeator
|
||||
model: (control.pageCount<2)?0:(control.pageCount>=control.pageButtonCount)?(control.pageButtonCount-2):(control.pageCount-2)
|
||||
delegate:FluToggleButton{
|
||||
property int pageNumber: {
|
||||
return (control.pageCurrent<=control.__pageButtonHalf)
|
||||
?(2+index)
|
||||
:(control.pageCount-control.pageCurrent<=control.pageButtonCount-control.__pageButtonHalf)
|
||||
?(control.pageCount-button_repeator.count+index)
|
||||
:(control.pageCurrent+2+index-control.__pageButtonHalf)
|
||||
}
|
||||
text:String(pageNumber)
|
||||
selected: pageNumber === control.pageCurrent
|
||||
onClicked: {
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: (control.pageCount>control.pageButtonCount&&
|
||||
control.pageCount-control.pageCurrent>control.pageButtonCount-control.__pageButtonHalf)
|
||||
text: "..."
|
||||
}
|
||||
FluToggleButton{
|
||||
property int pageNumber:control.pageCount
|
||||
visible: control.pageCount>1
|
||||
selected: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
onClicked: {
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent>=control.pageCount
|
||||
text:control.nextText
|
||||
onClicked: {
|
||||
control.calcNewPage(control.pageCurrent+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calcNewPage(page)
|
||||
{
|
||||
if(!page)
|
||||
return
|
||||
let page_num=Number(page)
|
||||
if(page_num<1||page_num>control.pageCount||page_num===control.pageCurrent)
|
||||
return
|
||||
control.pageCurrent=page_num
|
||||
control.requestPage(page_num,control.__itemPerPage)
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -3,12 +3,16 @@ import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluApp.uuid()
|
||||
readonly property int flag : 0
|
||||
property string title
|
||||
property int order : 0
|
||||
property int icon
|
||||
property bool recentlyAdded: false
|
||||
property bool recentlyUpdated: false
|
||||
property string desc
|
||||
property var image
|
||||
property var parent
|
||||
property int idx
|
||||
signal tap
|
||||
signal repTap
|
||||
property var tapFunc
|
||||
}
|
||||
|