Compare commits

...

61 Commits
1.5.9 ... 1.6.0

Author SHA1 Message Date
4b6fa1e65c update 2023-10-16 00:23:01 +08:00
f265753228 update 2023-10-15 23:57:37 +08:00
45b96faf7e update 2023-10-15 23:38:42 +08:00
473dec0990 update 2023-10-15 22:57:14 +08:00
939e04e4ca update 2023-10-15 17:24:33 +08:00
332c0ee54e update 2023-10-15 16:29:50 +08:00
d805147627 update 2023-10-14 13:18:45 +08:00
0ecab11e3c update 2023-10-14 01:34:00 +08:00
f0f2814d5e update 2023-10-14 01:24:01 +08:00
d71e474f40 update 2023-10-13 19:50:24 +08:00
aeca953d32 update 2023-10-13 18:38:27 +08:00
b1c0074a10 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-10-13 09:23:18 +08:00
f2feb19d68 update 2023-10-13 01:12:36 +08:00
992d8c142c update 2023-10-12 18:25:08 +08:00
16da5f1633 update 2023-10-11 23:56:16 +08:00
1003b34139 update 2023-10-11 22:37:07 +08:00
a2e15fc3b0 update 2023-10-11 11:18:48 +08:00
fecbf48482 Update README.md 2023-10-10 23:05:04 +08:00
20d52ac49a update 2023-10-10 20:04:26 +08:00
e8a77613bc update 2023-10-10 18:31:22 +08:00
54f52e0886 update 2023-10-10 15:06:44 +08:00
79ab73105e update 2023-10-09 12:23:25 +08:00
2bd961ee77 update 2023-10-09 10:22:01 +08:00
17829bac69 update 2023-10-08 19:59:55 +08:00
1d68de9287 update 2023-10-08 19:48:32 +08:00
9e8e55cb73 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-10-08 18:19:23 +08:00
29f363afdd update 2023-10-08 18:19:08 +08:00
ecced8abfb Merge pull request #304 from imaben/feat-delete-method
add delete method for http
2023-10-08 12:37:12 +08:00
5a49ffb7e0 add delete method for http 2023-10-08 11:38:57 +08:00
e631465231 update 2023-10-04 21:13:38 +08:00
50b1aaf8f5 update 2023-10-04 21:04:26 +08:00
93b55e7fea update 2023-10-04 19:28:05 +08:00
33fda1d025 update 2023-10-03 16:18:53 +08:00
a6e494d1c7 update 2023-10-03 10:36:19 +08:00
bfaff95fee update 2023-10-02 22:17:02 +08:00
f20bfc0466 update 2023-10-02 21:32:10 +08:00
69b371e807 update 2023-10-02 21:02:06 +08:00
b0545ffa2a update 2023-10-02 21:00:40 +08:00
91ba4d4792 update 2023-10-02 20:16:38 +08:00
3c7499c48b update 2023-10-02 10:16:23 +08:00
1b6743efeb update 2023-10-01 16:18:37 +08:00
68127a7303 update 2023-10-01 15:27:38 +08:00
895332f867 update 2023-10-01 14:59:35 +08:00
8127f7c3ed update 2023-09-29 20:40:27 +08:00
cbe26ce4cd update 2023-09-29 19:30:22 +08:00
c048336de1 update 2023-09-29 18:15:24 +08:00
d65d6fbbac update 2023-09-29 17:49:05 +08:00
674009e394 update 2023-09-29 17:39:45 +08:00
d8e3cf00b4 update 2023-09-29 17:22:22 +08:00
8e84ea1e3a update 2023-09-29 16:08:42 +08:00
5221c5bc63 update 2023-09-28 14:41:24 +08:00
a5b5a5b942 update 2023-09-28 13:12:39 +08:00
52c806eeff update 2023-09-28 12:31:20 +08:00
0e4d81c7c8 update 2023-09-27 18:15:39 +08:00
4a03ad4227 update 2023-09-27 18:10:20 +08:00
8e1e8a9db5 update 2023-09-27 15:18:10 +08:00
9354b8c0bf update 2023-09-26 20:57:52 +08:00
7723ac97fb update 2023-09-26 17:59:08 +08:00
5240f826c5 update 2023-09-26 11:29:11 +08:00
36da8cd785 update 2023-09-26 11:21:24 +08:00
7716ab02a6 update 2023-09-25 18:10:24 +08:00
153 changed files with 2750 additions and 1223 deletions

View File

@ -1,27 +1,7 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright 2009-2012, Iowa State University
# Copyright 2011-2015, Contributors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
set(HEAD_HASH) set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref") if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}") if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
@ -33,10 +13,8 @@ if(HEAD_CONTENTS MATCHES "ref")
endif() endif()
endif() endif()
else() else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif() endif()
if(NOT HEAD_HASH) if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH) string(STRIP "${HEAD_HASH}" HEAD_HASH)

View File

@ -0,0 +1,51 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "example"
#define MyAppVersion "${GIT_SEMVER}"
#define MyAppPublisher "ZhuZiChu"
#define MyAppURL "https://zhuzichu520.github.io/"
#define MyAppExeName "example.exe"
#define MyAppFileDir "dist"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{A053D1AE-AEA9-4105-A79B-B5F5BEDC9208}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
OutputDir=.\
OutputBaseFilename=installer
Compression=lzma
SolidCompression=yes
WizardStyle=modern
UninstallDisplayIcon={app}\{#MyAppExeName}
SetupIconFile=.\..\favicon.ico
[Languages]
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone
[Files]
Source: ".\..\{#MyAppFileDir}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\..\{#MyAppFileDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

View File

@ -38,7 +38,7 @@ jobs:
version: ${{ matrix.qt_ver }} version: ${{ matrix.qt_ver }}
cache: ${{steps.cache-qt.outputs.cache-hit}} cache: ${{steps.cache-qt.outputs.cache-hit}}
arch: ${{ matrix.qt_arch }} arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats' modules: 'qt5compat qtmultimedia qtshadertools qtimageformats qt3d'
- name: Set up Ninja - name: Set up Ninja
uses: seanmiddleditch/gha-setup-ninja@v3 uses: seanmiddleditch/gha-setup-ninja@v3

View File

@ -39,7 +39,7 @@ jobs:
version: ${{ matrix.qt_ver }} version: ${{ matrix.qt_ver }}
cache: ${{steps.cache-qt.outputs.cache-hit}} cache: ${{steps.cache-qt.outputs.cache-hit}}
arch: ${{ matrix.qt_arch }} arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats' modules: 'qt5compat qtmultimedia qtshadertools qtimageformats qt3d'
- name: Set up Ninja - name: Set up Ninja
uses: seanmiddleditch/gha-setup-ninja@v3 uses: seanmiddleditch/gha-setup-ninja@v3

View File

@ -47,7 +47,7 @@ jobs:
version: ${{ matrix.qt_ver }} version: ${{ matrix.qt_ver }}
arch: ${{ matrix.qt_arch }} arch: ${{ matrix.qt_arch }}
cache: ${{steps.cache-qt.outputs.cache-hit}} cache: ${{steps.cache-qt.outputs.cache-hit}}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats' modules: 'qt5compat qtmultimedia qtshadertools qtimageformats qt3d'
- name: Qt6 environment configuration - name: Qt6 environment configuration
if: ${{ startsWith( matrix.qt_ver, 6 ) }} if: ${{ startsWith( matrix.qt_ver, 6 ) }}
@ -85,14 +85,20 @@ jobs:
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: ${{ steps.package.outputs.packageName }} name: ${{ steps.package.outputs.packageName }}
path: ${{ steps.package.outputs.packageName }} path: dist
- name: inno setup install
if: startsWith(github.event.ref, 'refs/tags/')
uses: zhuzichu520/inno-setup-action@v1.0.1
with:
filepath: ./action-cli/InstallerScript.iss
- name: uploadRelease - name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ steps.package.outputs.packageName }}.zip file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

View File

@ -6,14 +6,14 @@ on:
- 'src/**' - 'src/**'
- 'example/**' - 'example/**'
- 'scripts/**' - 'scripts/**'
- '.github/workflows/windows_qt5.yml' - '.github/workflows/windows-qt5.yml'
pull_request: pull_request:
paths: paths:
- '*.txt' - '*.txt'
- 'example/**' - 'example/**'
- 'src/**' - 'src/**'
- 'scripts/**' - 'scripts/**'
- '.github/workflows/windows_qt5.yml' - '.github/workflows/windows-qt5.yml'
jobs: jobs:
build: build:
@ -72,14 +72,20 @@ jobs:
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: ${{ steps.package.outputs.packageName }} name: ${{ steps.package.outputs.packageName }}
path: ${{ steps.package.outputs.packageName }} path: dist
- name: inno setup install
if: startsWith(github.event.ref, 'refs/tags/')
uses: zhuzichu520/inno-setup-action@v1.0.1
with:
filepath: ./action-cli/InstallerScript.iss
- name: uploadRelease - name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ steps.package.outputs.packageName }}.zip file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

View File

@ -42,7 +42,7 @@ jobs:
version: ${{ matrix.qt_ver }} version: ${{ matrix.qt_ver }}
arch: ${{ matrix.qt_arch }} arch: ${{ matrix.qt_arch }}
cache: ${{steps.cache-qt.outputs.cache-hit}} cache: ${{steps.cache-qt.outputs.cache-hit}}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats qtspeech' modules: 'qt5compat qtmultimedia qtshadertools qtimageformats qtspeech qt3d'
- name: msvc-build - name: msvc-build
id: build id: build
@ -74,14 +74,20 @@ jobs:
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: ${{ steps.package.outputs.packageName }} name: ${{ steps.package.outputs.packageName }}
path: ${{ steps.package.outputs.packageName }} path: dist
- name: inno setup install
if: startsWith(github.event.ref, 'refs/tags/')
uses: zhuzichu520/inno-setup-action@v1.0.1
with:
filepath: ./action-cli/InstallerScript.iss
- name: uploadRelease - name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ steps.package.outputs.packageName }}.zip file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

3
.gitignore vendored
View File

@ -38,3 +38,6 @@ cmake-build-*
.idea .idea
example/Version.h example/Version.h
action-cli
dist

View File

@ -8,7 +8,6 @@ list(APPEND CMAKE_MODULE_PATH ${FLUENTUI_DIRECTORY}/.cmake/)
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
option(FLUENTUI_BUILD_EXAMPLES "Build FluentUI demo applications." ON) option(FLUENTUI_BUILD_EXAMPLES "Build FluentUI demo applications." ON)
option(FLUENTUI_BUILD_FRAMELESSHEPLER "Build FramelessHelper." ON)
option(FLUENTUI_BUILD_STATIC_LIB "Build static library." OFF) option(FLUENTUI_BUILD_STATIC_LIB "Build static library." OFF)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
@ -32,14 +31,12 @@ if (FLUENTUI_BUILD_EXAMPLES)
add_subdirectory(example) add_subdirectory(example)
endif () endif ()
if (FLUENTUI_BUILD_FRAMELESSHEPLER) set(FRAMELESSHELPER_BUILD_STATIC ON)
set(FRAMELESSHELPER_BUILD_STATIC ON) set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON)
set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON) set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
add_subdirectory(framelesshelper) add_subdirectory(framelesshelper)
endif ()
message("------------------------ FluentUI ------------------------") message("------------------------ FluentUI ------------------------")
message("Build FluentUI demo applications.: ${FLUENTUI_BUILD_EXAMPLES}") message("Build FluentUI demo applications.: ${FLUENTUI_BUILD_EXAMPLES}")
message("Build FramelessHelper.: ${FLUENTUI_BUILD_FRAMELESSHEPLER}")
message("Build static library.: ${FLUENTUI_BUILD_STATIC_LIB}") message("Build static library.: ${FLUENTUI_BUILD_STATIC_LIB}")
message("Path to FluentUI plugin.: ${FLUENTUI_QML_PLUGIN_DIRECTORY}") message("Path to FluentUI plugin.: ${FLUENTUI_QML_PLUGIN_DIRECTORY}")

View File

@ -6,7 +6,7 @@
QML FluentUI QML FluentUI
</h1> </h1>
<p align="center"> <p align="center">
A fluent design component library for Qt QML <a href="https://zhuzichu520.github.io">official wasm app.</a> A fluent design component library for Qt QML You need Pyside6 <a href="https://github.com/zhuzichu520/PySide6-FluentUI-QML">PySide6-FluentUI-QML</a>
</p> </p>
![win-badge] ![ubuntu-badge] ![macos-badge] ![release-badge] ![download-badge] ![download-latest] ![win-badge] ![ubuntu-badge] ![macos-badge] ![release-badge] ![download-badge] ![download-latest]

View File

@ -64,14 +64,14 @@ if(QT_VERSION VERSION_GREATER_EQUAL "6.2")
endforeach(filepath) endforeach(filepath)
#遍历所有资源文件 #遍历所有资源文件
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp qmldir) file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp *.obj qmldir)
foreach(filepath ${RES_PATHS}) foreach(filepath ${RES_PATHS})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND resource_files ${filename}) list(APPEND resource_files ${filename})
endforeach(filepath) endforeach(filepath)
endif() endif()
#如果是Windows平台则生成rc文件 #如果是Windows平台则生成rc文件还有inno setup脚本文件
set(EXAMPLE_VERSION_RC_PATH "") set(EXAMPLE_VERSION_RC_PATH "")
if(WIN32) if(WIN32)
set(EXAMPLE_VERSION_RC_PATH ${CMAKE_BINARY_DIR}/version_${PROJECT_NAME}.rc) set(EXAMPLE_VERSION_RC_PATH ${CMAKE_BINARY_DIR}/version_${PROJECT_NAME}.rc)
@ -79,6 +79,10 @@ if(WIN32)
${FLUENTUI_DIRECTORY}/.cmake/version_exe.rc.in ${FLUENTUI_DIRECTORY}/.cmake/version_exe.rc.in
${EXAMPLE_VERSION_RC_PATH} ${EXAMPLE_VERSION_RC_PATH}
) )
configure_file(
${FLUENTUI_DIRECTORY}/.cmake/InstallerScript.iss.in
${CMAKE_SOURCE_DIR}/action-cli/InstallerScript.iss
)
endif() endif()
#添加可执行文件 #添加可执行文件
@ -100,9 +104,9 @@ if(WIN32)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(3RDPARTY_ARCH_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Win_x64) set(3RDPARTY_ARCH_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Win_x64)
endif() endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") if(MSVC)
set(DLLPATH ${3RDPARTY_ARCH_DIR}/msvc/*.dll) set(DLLPATH ${3RDPARTY_ARCH_DIR}/msvc/*.dll)
else() elseif(MINGW)
set(DLLPATH ${3RDPARTY_ARCH_DIR}/mingw/*.dll) set(DLLPATH ${3RDPARTY_ARCH_DIR}/mingw/*.dll)
endif() endif()
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}") string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
@ -156,8 +160,6 @@ target_link_libraries(example PRIVATE
Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Svg
Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Network
fluentuiplugin fluentuiplugin
FramelessHelper::Core
FramelessHelper::Quick
) )
#安装 #安装

View File

@ -123,7 +123,6 @@
<file>res/image/qrcode_zfb.jpg</file> <file>res/image/qrcode_zfb.jpg</file>
<file>qml/App.qml</file> <file>qml/App.qml</file>
<file>qml/component/CodeExpander.qml</file> <file>qml/component/CodeExpander.qml</file>
<file>qml/component/CustomWindow.qml</file>
<file>qml/global/ItemsFooter.qml</file> <file>qml/global/ItemsFooter.qml</file>
<file>qml/global/ItemsOriginal.qml</file> <file>qml/global/ItemsOriginal.qml</file>
<file>qml/global/qmldir</file> <file>qml/global/qmldir</file>
@ -187,5 +186,8 @@
<file>qml/page/T_StaggeredView.qml</file> <file>qml/page/T_StaggeredView.qml</file>
<file>qml/viewmodel/SettingsViewModel.qml</file> <file>qml/viewmodel/SettingsViewModel.qml</file>
<file>qml/viewmodel/TextBoxViewModel.qml</file> <file>qml/viewmodel/TextBoxViewModel.qml</file>
<file>qml/page/T_Clip.qml</file>
<file>qml/page/T_3D.qml</file>
<file>qml/global/Lang.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -15,6 +15,13 @@ Window {
} }
} }
Connections{
target: FluApp
function onVsyncChanged(){
SettingsHelper.saveVsync(FluApp.vsync)
}
}
FluHttpInterceptor{ FluHttpInterceptor{
id:interceptor id:interceptor
function onIntercept(request){ function onIntercept(request){
@ -33,6 +40,7 @@ Window {
Component.onCompleted: { Component.onCompleted: {
FluApp.init(app) FluApp.init(app)
FluApp.vsync = SettingsHelper.getVsync()
FluTheme.darkMode = SettingsHelper.getDarkMode() FluTheme.darkMode = SettingsHelper.getDarkMode()
FluTheme.enableAnimation = true FluTheme.enableAnimation = true
FluApp.routes = { FluApp.routes = {

View File

@ -139,7 +139,8 @@ FluExpander{
"FluRangeSlider", "FluRangeSlider",
"FluStaggeredView", "FluStaggeredView",
"FluProgressButton", "FluProgressButton",
"FluLoadingButton" "FluLoadingButton",
"FluClip"
]; ];
code = code.replace(/\n/g, "<br>"); code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;"); code = code.replace(/ /g, "&nbsp;");

View File

@ -1,64 +0,0 @@
import QtQuick
import QtQuick.Layouts
import FluentUI
import org.wangwenx190.FramelessHelper
FluWindow {
id:window
property bool fixSize
property alias titleVisible: title_bar.titleVisible
property bool appBarVisible: true
default property alias content: container.data
FluAppBar {
id: title_bar
title: window.title
visible: window.appBarVisible
icon:"qrc:/example/res/image/favicon.ico"
anchors {
top: parent.top
left: parent.left
right: parent.right
}
darkText: lang.dark_mode
}
Item{
id:container
anchors{
top: title_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
FramelessHelper{
id:framless_helper
onReady: {
setTitleBarItem(title_bar)
moveWindowToDesktopCenter()
setHitTestVisible(title_bar.minimizeButton())
setHitTestVisible(title_bar.maximizeButton())
setHitTestVisible(title_bar.closeButton())
setWindowFixedSize(fixSize)
title_bar.maximizeButton.visible = !fixSize
if (blurBehindWindowEnabled)
window.background = undefined
window.show()
}
}
Connections{
target: FluTheme
function onDarkChanged(){
if (FluTheme.dark)
FramelessUtils.systemTheme = FramelessHelperConstants.Dark
else
FramelessUtils.systemTheme = FramelessHelperConstants.Light
}
}
function setHitTestVisible(com){
framless_helper.setHitTestVisible(com)
}
function setTitleBarItem(com){
framless_helper.setTitleBarItem(com)
}
}

View File

@ -12,7 +12,7 @@ FluObject{
FluPaneItemSeparator{} FluPaneItemSeparator{}
FluPaneItem{ FluPaneItem{
title:lang.about title:Lang.about
icon:FluentIcons.Contact icon:FluentIcons.Contact
onDropped: { FluApp.navigate("/about") } onDropped: { FluApp.navigate("/about") }
onTapListener:function(){ onTapListener:function(){
@ -21,7 +21,7 @@ FluObject{
} }
FluPaneItem{ FluPaneItem{
title:lang.settings title:Lang.settings
icon:FluentIcons.Settings icon:FluentIcons.Settings
url:"qrc:/example/qml/page/T_Settings.qml" url:"qrc:/example/qml/page/T_Settings.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }

View File

@ -16,7 +16,7 @@ FluObject{
FluPaneItem{ FluPaneItem{
id:item_home id:item_home
count: 9 count: 9
title:lang.home title:Lang.home
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_home.count count: item_home.count
} }
@ -45,9 +45,15 @@ FluObject{
} }
} }
FluPaneItemExpander{
title:"PaneItemExpander Disabled"
iconVisible: false
disabled: true
}
FluPaneItemExpander{ FluPaneItemExpander{
id:item_expander_basic_input id:item_expander_basic_input
title:lang.basic_input title:Lang.basic_input
icon:FluentIcons.CheckboxComposite icon:FluentIcons.CheckboxComposite
editDelegate: FluTextBox{ editDelegate: FluTextBox{
text:item_expander_basic_input.title text:item_expander_basic_input.title
@ -129,10 +135,15 @@ FluObject{
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{
title:"PaneItem Disabled"
disabled: true
icon: FluentIcons.Error
}
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.form title:Lang.form
icon:FluentIcons.GridView icon:FluentIcons.GridView
FluPaneItem{ FluPaneItem{
title:"TextBox" title:"TextBox"
@ -167,7 +178,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.surface title:Lang.surface
icon:FluentIcons.SurfaceHub icon:FluentIcons.SurfaceHub
FluPaneItem{ FluPaneItem{
title:"InfoBar" title:"InfoBar"
@ -202,6 +213,12 @@ FluObject{
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{
title:"Clip"
url:"qrc:/example/qml/page/T_Clip.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) }
}
FluPaneItem{ FluPaneItem{
title:"StatusView" title:"StatusView"
url:"qrc:/example/qml/page/T_StatusView.qml" url:"qrc:/example/qml/page/T_StatusView.qml"
@ -235,7 +252,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.popus title:Lang.popus
icon:FluentIcons.ButtonMenu icon:FluentIcons.ButtonMenu
FluPaneItem{ FluPaneItem{
title:"Dialog" title:"Dialog"
@ -273,7 +290,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.navigation title:Lang.navigation
icon:FluentIcons.AllApps icon:FluentIcons.AllApps
FluPaneItem{ FluPaneItem{
title:"Pivot" title:"Pivot"
@ -342,7 +359,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.theming title:Lang.theming
icon:FluentIcons.Brightness icon:FluentIcons.Brightness
FluPaneItem{ FluPaneItem{
title:"Acrylic" title:"Acrylic"
@ -376,7 +393,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.other title:Lang.other
icon:FluentIcons.Shop icon:FluentIcons.Shop
FluPaneItem{ FluPaneItem{
title:"QRCode" title:"QRCode"
@ -442,6 +459,12 @@ FluObject{
} }
onDropped:{ FluApp.navigate("/hotload") } onDropped:{ FluApp.navigate("/hotload") }
} }
FluPaneItem{
title:"3D"
url:"qrc:/example/qml/page/T_3D.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) }
}
} }
function getRecentlyAddedData(){ function getRecentlyAddedData(){

View File

@ -0,0 +1,77 @@
pragma Singleton
import QtQuick
QtObject {
property string home
property string basic_input
property string form
property string surface
property string popus
property string navigation
property string theming
property string media
property string dark_mode
property string sys_dark_mode
property string search
property string about
property string settings
property string locale
property string navigation_view_display_mode
property string other
function zh(){
home="首页"
basic_input="基本输入"
form="表单"
surface="表面"
popus="弹窗"
navigation="导航"
theming="主题"
media="媒体"
dark_mode="夜间模式"
sys_dark_mode="跟随系统"
search="查找"
about="关于"
settings="设置"
locale="语言环境"
navigation_view_display_mode="导航视图显示模式"
other="其他"
}
function en(){
home="Home"
basic_input="Basic Input"
form="Form"
surface="Surfaces"
popus="Popus"
navigation="Navigation"
theming="Theming"
media="Media"
dark_mode="Dark Mode"
sys_dark_mode="Sync with system"
search="Search"
about="About"
settings="Settings"
locale="Locale"
navigation_view_display_mode="NavigationView Display Mode"
other="Other"
}
property string __locale
property var __localeList: ["Zh","En"]
on__LocaleChanged: {
if(__locale === "Zh"){
zh()
}else{
en()
}
}
Component.onCompleted: {
__locale = "En"
}
}

View File

@ -1,2 +1,3 @@
singleton ItemsOriginal 1.0 ItemsOriginal.qml singleton ItemsOriginal 1.0 ItemsOriginal.qml
singleton ItemsFooter 1.0 ItemsFooter.qml singleton ItemsFooter 1.0 ItemsFooter.qml
singleton Lang 1.0 Lang.qml

View File

@ -0,0 +1,120 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
import FluentUI
import Qt3D.Core
import Qt3D.Render
import Qt3D.Input
import Qt3D.Extras
import QtQuick.Scene3D
import QtQuick.Dialogs
import Qt.labs.platform
import "qrc:///example/qml/component"
FluContentPage{
id:root
title:"3D"
Scene3D{
id:scene_3d
anchors.fill: parent
focus: true
aspects: ["input", "logic"]
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
Entity {
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 22.5
aspectRatio: scene_3d.width / scene_3d.height
nearPlane: 1
farPlane: 1000.0
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
position: Qt.vector3d( 0.0, 0.0, 15.0 )
}
FirstPersonCameraController {
linearSpeed: 100
lookSpeed: 50
camera: camera
}
components: [
RenderSettings{
activeFrameGraph: ForwardRenderer{
clearColor: Qt.rgba(0,0,0,0);
camera: camera
}
},
InputSettings{}
]
Mesh {
id: mesh
source: "https://zhu-zichu.gitee.io/test.obj"
}
PhongMaterial {
id: material
ambient: color_picker.colorValue
}
Transform{
id:transform
scale: 1.0
translation: Qt.vector3d(0, 0, 0)
rotation: fromEulerAngles(0, 0, 0)
property real hAngle:0.0
NumberAnimation on hAngle{
from:0
to:360.0
duration: 5000
loops: Animation.Infinite
}
matrix:{
var m=Qt.matrix4x4();
m.rotate(hAngle,Qt.vector3d(0,1,0));
m.translate(Qt.vector3d(0,0,0));
return m;
}
}
Entity {
id: entity
components: [mesh, material,transform]
}
}
}
ColumnLayout{
RowLayout{
spacing: 10
Layout.topMargin: 20
FluText{
text:"tintColor:"
Layout.alignment: Qt.AlignVCenter
}
FluColorPicker{
id:color_picker
enableAlphaChannel:false
Component.onCompleted: {
setColor("gray")
}
}
}
FluButton{
text:"选择obj资源"
onClicked: {
file_dialog.open()
}
}
}
FileDialog {
id: file_dialog
nameFilters: ["Obj files (*.obj)"]
folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
onAccepted: {
var fileUrl = file_dialog.currentFile
mesh.source = fileUrl
}
}
}

View File

@ -25,7 +25,7 @@ FluContentPage {
leftMargin: 14 leftMargin: 14
} }
onClicked: { onClicked: {
grid_view.model = FluApp.awesomelist(text_box.text) grid_view.model = FluTheme.awesomeList(text_box.text)
} }
} }
GridView{ GridView{
@ -34,7 +34,7 @@ FluContentPage {
cellHeight: 80 cellHeight: 80
clip: true clip: true
boundsBehavior: GridView.StopAtBounds boundsBehavior: GridView.StopAtBounds
model:FluApp.awesomelist() model:FluTheme.awesomeList()
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
anchors{ anchors{
topMargin: 10 topMargin: 10

View File

@ -36,7 +36,7 @@ FluScrollablePage{
left: parent.left left: parent.left
} }
FluCalendarPicker{ FluCalendarPicker{
current:Date.fromLocaleString("2013年7月11日 21:17:42") current:new Date()
onAccepted:{ onAccepted:{
showSuccess(current.toLocaleString()) showSuccess(current.toLocaleString())
} }

View File

@ -11,27 +11,35 @@ FluScrollablePage{
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
height: 68 height: 72
paddings: 10 paddings: 10
Layout.topMargin: 20 Layout.topMargin: 20
FluText{
text:"A 2-state CheckBox"
}
Row{ Row{
spacing: 30 spacing: 30
anchors.verticalCenter: parent.verticalCenter anchors{
FluCheckBox{ top: parent.top
disabled: check_box_switch.checked topMargin: 30
} }
FluCheckBox{ FluCheckBox{
disabled: check_box_switch.checked disabled: check_box_switch_two.checked
}
FluCheckBox{
disabled: check_box_switch_two.checked
text:"Right" text:"Right"
} }
FluCheckBox{ FluCheckBox{
disabled: check_box_switch.checked disabled: check_box_switch_two.checked
text:"Left" text:"Left"
textRight: false textRight: false
} }
} }
FluToggleSwitch{ FluToggleSwitch{
id:check_box_switch id:check_box_switch_two
anchors{ anchors{
right: parent.right right: parent.right
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
@ -47,4 +55,60 @@ FluScrollablePage{
}' }'
} }
FluArea{
Layout.fillWidth: true
height: 72
paddings: 10
Layout.topMargin: 20
FluText{
text:"A 3-state CheckBox"
}
Row{
spacing: 30
anchors{
top: parent.top
topMargin: 30
}
FluCheckBox{
property int count: 1
text:"Three State"
disabled: check_box_switch_three.checked
clickListener: function(){
var flag = count%3
if(flag === 0){
checked = false
indeterminate = false
}
if(flag === 1){
checked = true
indeterminate = false
}
if(flag === 2){
checked = true
indeterminate = true
}
count++
}
}
}
FluToggleSwitch{
id:check_box_switch_three
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text:"Disabled"
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCheckBox{
text:"Text"
indeterminate:true
}'
}
} }

View File

@ -0,0 +1,107 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
import FluentUI
import "qrc:///example/qml/component"
FluScrollablePage{
title:"Clip"
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 380
paddings: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"配合图片使用(software渲染下该组件将没有效果)"
font: FluTextStyle.Subtitle
Layout.topMargin: 20
}
RowLayout{
spacing: 14
FluClip{
width: 50
height: 50
radius:[25,0,25,25]
Image {
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_1.svg"
sourceSize: Qt.size(width,height)
}
}
FluClip{
width: 50
height: 50
radius:[10,10,10,10]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_2.svg"
}
}
FluClip{
width: 50
height: 50
radius:[25,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_3.svg"
}
}
FluClip{
width: 50
height: 50
radius:[0,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_4.svg"
}
}
}
FluClip{
width: 1920/5
height: 1200/5
radius:[8,8,8,8]
Image {
asynchronous: true
source: "qrc:/example/res/image/banner_1.jpg"
anchors.fill: parent
sourceSize: Qt.size(2*width,2*height)
}
Layout.topMargin: 20
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluClip{
radius: [25,25,25,25]
width: 50
height: 50
Image{
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_4.svg"
sourceSize: Qt.size(width,height)
}
}'
}
}

View File

@ -58,6 +58,7 @@ FluScrollablePage{
width: parent.width width: parent.width
height: parent.height height: parent.height
contentWidth: width contentWidth: width
boundsBehavior: Flickable.StopAtBounds
contentHeight: text_info.height contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
FluText{ FluText{

View File

@ -10,7 +10,7 @@ import "qrc:///example/qml/component"
FluContentPage{ FluContentPage{
title:"Http" title:"Http"
property string cacheDirPath: FluTools.getApplicationDirPath() + "/cache/http" property string cacheDirPath: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation) + "/cache/http"
property bool isDownCompleted: false property bool isDownCompleted: false
FluHttp{ FluHttp{
@ -100,6 +100,9 @@ FluContentPage{
params.custtel = "1234567890" params.custtel = "1234567890"
params.custemail = "zhuzichu520@gmail.com" params.custemail = "zhuzichu520@gmail.com"
request.params = params request.params = params
var headers = {}
headers.test = "123456789456465321354"
request.headers = headers
http.post(request,callable) http.post(request,callable)
} }
} }
@ -127,6 +130,15 @@ FluContentPage{
http.postString(request,callable) http.postString(request,callable)
} }
} }
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/delete")
http.deleteResource(request,callable)
}
}
FluProgressButton{ FluProgressButton{
id:btn_download id:btn_download
implicitWidth: parent.width implicitWidth: parent.width
@ -264,7 +276,7 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "打开缓存路径" text: "打开缓存路径"
onClicked: { onClicked: {
Qt.openUrlExternally("file:///"+cacheDirPath) Qt.openUrlExternally(cacheDirPath)
} }
} }
FluButton{ FluButton{

View File

@ -12,16 +12,15 @@ FluScrollablePage{
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 20 Layout.topMargin: 20
height: 460 height: 80
paddings: 10 paddings: 10
Column{ Column{
spacing: 15 spacing: 15
anchors{ anchors{
verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
verticalCenter: parent.verticalCenter
} }
RowLayout{ RowLayout{
Layout.topMargin: 20 Layout.topMargin: 20
FluRectangle{ FluRectangle{
@ -61,70 +60,6 @@ FluScrollablePage{
radius:[0,0,0,15] radius:[0,0,0,15]
} }
} }
FluText{
text:"配合图片使用"
font: FluTextStyle.Subtitle
Layout.topMargin: 20
}
RowLayout{
spacing: 14
FluClip{
width: 50
height: 50
radius:[25,0,25,25]
Image {
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_1.svg"
sourceSize: Qt.size(width,height)
}
}
FluClip{
width: 50
height: 50
radius:[10,10,10,10]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_2.svg"
}
}
FluClip{
width: 50
height: 50
radius:[25,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_3.svg"
}
}
FluClip{
width: 50
height: 50
radius:[0,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_4.svg"
}
}
}
FluClip{
width: 1920/5
height: 1200/5
radius:[8,8,8,8]
Image {
asynchronous: true
source: "qrc:/example/res/image/banner_1.jpg"
anchors.fill: parent
sourceSize: Qt.size(2*width,2*height)
}
Layout.topMargin: 20
}
} }
} }
CodeExpander{ CodeExpander{
@ -134,14 +69,6 @@ FluScrollablePage{
radius: [25,25,25,25] radius: [25,25,25,25]
width: 50 width: 50
height: 50 height: 50
Image{
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_4.svg"
sourceSize: Qt.size(width,height)
}
}' }'
} }
} }

View File

@ -3,6 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import FluentUI import FluentUI
import Qt.labs.platform
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
FluScrollablePage{ FluScrollablePage{
@ -47,7 +48,7 @@ FluScrollablePage{
FluScreenshot{ FluScreenshot{
id:screenshot id:screenshot
captrueMode: FluScreenshotType.File captrueMode: FluScreenshotType.File
saveFolder: FluTools.getApplicationDirPath()+"/screenshot" saveFolder: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation)+"/screenshot"
onCaptrueCompleted: onCaptrueCompleted:
(captrue)=>{ (captrue)=>{
image.source = captrue image.source = captrue

View File

@ -62,30 +62,46 @@ FluScrollablePage{
height: 50 height: 50
paddings: 10 paddings: 10
FluCheckBox{ FluCheckBox{
text:"Software Render" text:"V-Sync"
checked: SettingsHelper.getReander() === "software" checked: FluApp.vsync
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onClicked: { onClicked: {
if(SettingsHelper.getReander() === "software"){ FluApp.vsync = !FluApp.vsync
dialog_restart.open()
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
FluCheckBox{
text:"Software Render"
checked: SettingsHelper.getRender() === "software"
anchors.verticalCenter: parent.verticalCenter
onClicked: {
if(SettingsHelper.getRender() === "software"){
SettingsHelper.saveRender("") SettingsHelper.saveRender("")
}else{ }else{
SettingsHelper.saveRender("software") SettingsHelper.saveRender("software")
} }
dialog_render.open() dialog_restart.open()
} }
} }
} }
FluContentDialog{ FluContentDialog{
id:dialog_render id:dialog_restart
title:"友情提示" title:"友情提示"
message:"此操作需要重启才能生效,是否重新启动?" message:"此操作需要重启才能生效,是否重新启动?"
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
negativeText: "取消" negativeText: "取消"
positiveText:"确定" positiveText:"确定"
onPositiveClicked:{ onPositiveClicked:{
window.deleteWindow() FluApp.exit(931)
AppInfo.restart()
} }
} }
@ -102,7 +118,7 @@ FluScrollablePage{
left: parent.left left: parent.left
} }
FluText{ FluText{
text:lang.dark_mode text:Lang.dark_mode
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
@ -132,7 +148,7 @@ FluScrollablePage{
left: parent.left left: parent.left
} }
FluText{ FluText{
text:lang.navigation_view_display_mode text:Lang.navigation_view_display_mode
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
@ -163,7 +179,7 @@ FluScrollablePage{
} }
FluText{ FluText{
text:lang.locale text:Lang.locale
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
@ -171,12 +187,12 @@ FluScrollablePage{
Flow{ Flow{
spacing: 5 spacing: 5
Repeater{ Repeater{
model: ["Zh","En"] model: Lang.__localeList
delegate: FluRadioButton{ delegate: FluRadioButton{
checked: AppInfo.lang.objectName === modelData checked: Lang.__locale === modelData
text:modelData text:modelData
clickListener:function(){ clickListener:function(){
AppInfo.changeLang(modelData) Lang.__locale = modelData
} }
} }
} }

View File

@ -7,12 +7,45 @@ import "qrc:///example/qml/component"
FluContentPage{ FluContentPage{
id:root
title:"TableView" title:"TableView"
signal checkBoxChanged
property var dataSource : []
property int sortType: 0
Component.onCompleted: { Component.onCompleted: {
loadData(1,1000) loadData(1,1000)
} }
onSortTypeChanged: {
table_view.closeEditor()
if(sortType === 0){
table_view.sort()
}else if(sortType === 1){
table_view.sort((a, b) => a.age - b.age);
}else if(sortType === 2){
table_view.sort((a, b) => b.age - a.age);
}
}
Component{
id:com_checbox
Item{
FluCheckBox{
anchors.centerIn: parent
checked: true === options.checked
enableAnimation: false
clickListener: function(){
var obj = tableModel.getRow(row)
obj.checkbox = table_view.customItem(com_checbox,{checked:!options.checked})
tableModel.setRow(row,obj)
checkBoxChanged()
}
}
}
}
Component{ Component{
id:com_action id:com_action
Item{ Item{
@ -23,11 +56,15 @@ FluContentPage{
onClicked: { onClicked: {
table_view.closeEditor() table_view.closeEditor()
tableModel.removeRow(row) tableModel.removeRow(row)
checkBoxChanged()
} }
} }
FluFilledButton{ FluFilledButton{
text:"编辑" text:"编辑"
onClicked: { onClicked: {
var obj = tableModel.getRow(row)
obj.name = "12345"
tableModel.setRow(row,obj)
showSuccess(JSON.stringify(tableModel.getRow(row))) showSuccess(JSON.stringify(tableModel.getRow(row)))
} }
} }
@ -35,39 +72,44 @@ FluContentPage{
} }
} }
function loadData(page,count){
var numbers = [100, 300, 500, 1000]; Component{
function getRandomAge() { id:com_column_checbox
var randomIndex = Math.floor(Math.random() * numbers.length); Item{
return numbers[randomIndex]; RowLayout{
anchors.centerIn: parent
FluText{
text:"全选"
Layout.alignment: Qt.AlignVCenter
} }
var names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"]; FluCheckBox{
function getRandomName(){ checked: true === options.checked
var randomIndex = Math.floor(Math.random() * names.length); enableAnimation: false
return names[randomIndex]; Layout.alignment: Qt.AlignVCenter
clickListener: function(){
var checked = !options.checked
itemModel.display = table_view.customItem(com_column_checbox,{"checked":checked})
for(var i =0;i< tableModel.rowCount ;i++){
var rowData = tableModel.getRow(i)
rowData.checkbox = table_view.customItem(com_checbox,{"checked":checked})
tableModel.setRow(i,rowData)
}
}
}
Connections{
target: root
function onCheckBoxChanged(){
for(var i =0;i< tableModel.rowCount ;i++){
if(false === tableModel.getRow(i).checkbox.options.checked){
itemModel.display = table_view.customItem(com_column_checbox,{"checked":false})
return
}
}
itemModel.display = table_view.customItem(com_column_checbox,{"checked":true})
} }
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
} }
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
} }
const dataSource = []
for(var i=0;i<count;i++){
dataSource.push({
name: getRandomName(),
age:getRandomAge(),
address: getRandomAddresses(),
nickname: getRandomNickname(),
longstring:"你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好",
action:com_action
})
} }
table_view.dataSource = dataSource
} }
Component{ Component{
@ -94,6 +136,88 @@ FluContentPage{
} }
} }
Component{
id:com_avatar
Item{
FluClip{
anchors.centerIn: parent
width: 40
height: 40
radius: [20,20,20,20]
Image{
anchors.fill: parent
source: {
if(options && options.avatar){
return options.avatar
}
return ""
}
sourceSize: Qt.size(80,80)
}
}
}
}
Component{
id:com_column_sort_age
Item{
FluText{
text:"年龄"
anchors.centerIn: parent
}
ColumnLayout{
spacing: 0
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: 4
}
FluIconButton{
Layout.preferredWidth: 20
Layout.preferredHeight: 15
iconSize: 12
verticalPadding:0
horizontalPadding:0
iconSource: FluentIcons.ChevronUp
iconColor: {
if(1 === root.sortType){
return FluTheme.primaryColor.dark
}
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
}
onClicked: {
if(root.sortType === 1){
root.sortType = 0
return
}
root.sortType = 1
}
}
FluIconButton{
Layout.preferredWidth: 20
Layout.preferredHeight: 15
iconSize: 12
verticalPadding:0
horizontalPadding:0
iconSource: FluentIcons.ChevronDown
iconColor: {
if(2 === root.sortType){
return FluTheme.primaryColor.dark
}
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
}
onClicked: {
if(root.sortType === 2){
root.sortType = 0
return
}
root.sortType = 2
}
}
}
}
}
FluTableView{ FluTableView{
id:table_view id:table_view
anchors{ anchors{
@ -104,13 +228,27 @@ FluContentPage{
} }
anchors.topMargin: 20 anchors.topMargin: 20
columnSource:[ columnSource:[
{
title: table_view.customItem(com_column_checbox,{checked:true}),
dataIndex: 'checkbox',
width:80,
minimumWidth:80,
maximumWidth:80,
},
{
title: '头像',
dataIndex: 'avatar',
width:100,
minimumWidth:100,
maximumWidth:100
},
{ {
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'name',
readOnly:true, readOnly:true,
}, },
{ {
title: '年龄', title: table_view.customItem(com_column_sort_age,{sort:0}),
dataIndex: 'age', dataIndex: 'age',
editDelegate:com_combobox, editDelegate:com_combobox,
width:100, width:100,
@ -166,6 +304,50 @@ FluContentPage{
} }
} }
function loadData(page,count){
var numbers = [100, 300, 500, 1000];
function getRandomAge() {
var randomIndex = Math.floor(Math.random() * numbers.length);
return numbers[randomIndex];
}
var names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"];
function getRandomName(){
var randomIndex = Math.floor(Math.random() * names.length);
return names[randomIndex];
}
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
}
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
}
var avatars = ["qrc:/example/res/svg/avatar_1.svg", "qrc:/example/res/svg/avatar_2.svg", "qrc:/example/res/svg/avatar_3.svg", "qrc:/example/res/svg/avatar_4.svg","qrc:/example/res/svg/avatar_5.svg","qrc:/example/res/svg/avatar_6.svg","qrc:/example/res/svg/avatar_7.svg","qrc:/example/res/svg/avatar_8.svg","qrc:/example/res/svg/avatar_9.svg","qrc:/example/res/svg/avatar_10.svg","qrc:/example/res/svg/avatar_11.svg","qrc:/example/res/svg/avatar_12.svg"];
function getAvatar(){
var randomIndex = Math.floor(Math.random() * avatars.length);
return avatars[randomIndex];
}
const dataSource = []
for(var i=0;i<count;i++){
dataSource.push({
checkbox: table_view.customItem(com_checbox,{checked:true}),
avatar:table_view.customItem(com_avatar,{avatar:getAvatar()}),
name: getRandomName(),
age:getRandomAge(),
address: getRandomAddresses(),
nickname: getRandomNickname(),
longstring:"你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好",
action: table_view.customItem(com_action),
minimumHeight:50
})
}
root.dataSource = dataSource
table_view.dataSource = root.dataSource
}
} }

View File

@ -84,7 +84,7 @@ FluScrollablePage{
text:"找到一份Android外包开发岗位开发了一个Android应用满满成就感前端、服务端、Flutter也都懂一丢丢什么都会什么都不精通钱途无望" text:"找到一份Android外包开发岗位开发了一个Android应用满满成就感前端、服务端、Flutter也都懂一丢丢什么都会什么都不精通钱途无望"
} }
ListElement{ ListElement{
lable:"2020-06-01" lable:"2021-06-01"
text:"由于某个项目紧急临时加入Qt项目组就因为大学学了点C++),本来是想进去打个酱油,到后面竟然成开发主力,坑啊" text:"由于某个项目紧急临时加入Qt项目组就因为大学学了点C++),本来是想进去打个酱油,到后面竟然成开发主力,坑啊"
} }
ListElement{ ListElement{

View File

@ -4,7 +4,7 @@ import QtQuick.Layouts
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
title:"关于" title:"关于"

View File

@ -5,7 +5,7 @@ import FluentUI
import example import example
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
title:"热加载" title:"热加载"

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
title:"登录" title:"登录"

View File

@ -9,7 +9,7 @@ import "qrc:///example/qml/component"
import "qrc:///example/qml/global" import "qrc:///example/qml/global"
import "qrc:///example/qml/viewmodel" import "qrc:///example/qml/viewmodel"
CustomWindow { FluWindow {
id:window id:window
title: "FluentUI" title: "FluentUI"
@ -18,14 +18,15 @@ CustomWindow {
closeDestory:false closeDestory:false
minimumWidth: 520 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
appBarVisible: false
launchMode: FluWindowType.SingleTask launchMode: FluWindowType.SingleTask
appBar: undefined
SettingsViewModel{ SettingsViewModel{
id:viewmodel_settings id:viewmodel_settings
} }
closeFunc:function(event){ closeListener:function(event){
dialog_close.open() dialog_close.open()
event.accepted = false event.accepted = false
} }
@ -37,7 +38,6 @@ CustomWindow {
checkUpdate(false) checkUpdate(false)
} }
} }
Component.onCompleted: { Component.onCompleted: {
FluTools.setQuitOnLastWindowClosed(false) FluTools.setQuitOnLastWindowClosed(false)
tour.open() tour.open()
@ -58,8 +58,7 @@ CustomWindow {
MenuItem { MenuItem {
text: "退出" text: "退出"
onTriggered: { onTriggered: {
window.deleteWindow() FluApp.exit()
FluApp.closeApp()
} }
} }
} }
@ -86,8 +85,7 @@ CustomWindow {
positiveText:"退出" positiveText:"退出"
neutralText:"取消" neutralText:"取消"
onPositiveClicked:{ onPositiveClicked:{
window.deleteWindow() FluApp.exit()
FluApp.closeApp()
} }
} }
@ -120,7 +118,7 @@ CustomWindow {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
darkText: lang.dark_mode darkText: Lang.dark_mode
showDark: true showDark: true
z:7 z:7
darkClickListener:(button)=>handleDarkChanged(button) darkClickListener:(button)=>handleDarkChanged(button)
@ -170,7 +168,7 @@ CustomWindow {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
darkText: lang.dark_mode darkText: Lang.dark_mode
showDark: true showDark: true
darkClickListener:(button)=>handleDarkChanged(button) darkClickListener:(button)=>handleDarkChanged(button)
z:7 z:7
@ -201,11 +199,9 @@ CustomWindow {
} }
} }
autoSuggestBox:FluAutoSuggestBox{ autoSuggestBox:FluAutoSuggestBox{
width: 280
anchors.centerIn: parent
iconSource: FluentIcons.Search iconSource: FluentIcons.Search
items: ItemsOriginal.getSearchData() items: ItemsOriginal.getSearchData()
placeholderText: lang.search placeholderText: Lang.search
onItemClicked: onItemClicked:
(data)=>{ (data)=>{
ItemsOriginal.startPageByItem(data) ItemsOriginal.startPageByItem(data)

View File

@ -5,7 +5,7 @@ import FluentUI
import example import example
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
width: 800 width: 800

View File

@ -4,7 +4,7 @@ import QtQuick.Layouts
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
title:"SingleInstance" title:"SingleInstance"

View File

@ -4,7 +4,7 @@ import QtQuick.Layouts
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
title:"SingleTask" title:"SingleTask"

View File

@ -4,7 +4,7 @@ import QtQuick.Layouts
import FluentUI import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
CustomWindow { FluWindow {
id:window id:window
title:"Standard" title:"Standard"

View File

@ -15,6 +15,13 @@ Window {
} }
} }
Connections{
target: FluApp
function onVsyncChanged(){
SettingsHelper.saveVsync(FluApp.vsync)
}
}
FluHttpInterceptor{ FluHttpInterceptor{
id:interceptor id:interceptor
function onIntercept(request){ function onIntercept(request){
@ -33,6 +40,7 @@ Window {
Component.onCompleted: { Component.onCompleted: {
FluApp.init(app) FluApp.init(app)
FluApp.vsync = SettingsHelper.getVsync()
FluTheme.darkMode = SettingsHelper.getDarkMode() FluTheme.darkMode = SettingsHelper.getDarkMode()
FluTheme.enableAnimation = true FluTheme.enableAnimation = true
FluApp.routes = { FluApp.routes = {

View File

@ -139,7 +139,8 @@ FluExpander{
"FluRangeSlider", "FluRangeSlider",
"FluStaggeredView", "FluStaggeredView",
"FluProgressButton", "FluProgressButton",
"FluLoadingButton" "FluLoadingButton",
"FluClip"
]; ];
code = code.replace(/\n/g, "<br>"); code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;"); code = code.replace(/ /g, "&nbsp;");

View File

@ -1,64 +0,0 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import FluentUI 1.0
import org.wangwenx190.FramelessHelper 1.0
FluWindow {
id:window
property bool fixSize
property alias titleVisible: title_bar.titleVisible
property bool appBarVisible: true
default property alias content: container.data
FluAppBar {
id: title_bar
title: window.title
visible: window.appBarVisible
icon:"qrc:/example/res/image/favicon.ico"
anchors {
top: parent.top
left: parent.left
right: parent.right
}
darkText: lang.dark_mode
}
Item{
id:container
anchors{
top: title_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
FramelessHelper{
id:framless_helper
onReady: {
setTitleBarItem(title_bar)
moveWindowToDesktopCenter()
setHitTestVisible(title_bar.minimizeButton())
setHitTestVisible(title_bar.maximizeButton())
setHitTestVisible(title_bar.closeButton())
setWindowFixedSize(fixSize)
title_bar.maximizeButton.visible = !fixSize
if (blurBehindWindowEnabled)
window.background = undefined
window.show()
}
}
Connections{
target: FluTheme
function onDarkChanged(){
if (FluTheme.dark)
FramelessUtils.systemTheme = FramelessHelperConstants.Dark
else
FramelessUtils.systemTheme = FramelessHelperConstants.Light
}
}
function setHitTestVisible(com){
framless_helper.setHitTestVisible(com)
}
function setTitleBarItem(com){
framless_helper.setTitleBarItem(com)
}
}

View File

@ -12,7 +12,7 @@ FluObject{
FluPaneItemSeparator{} FluPaneItemSeparator{}
FluPaneItem{ FluPaneItem{
title:lang.about title:Lang.about
icon:FluentIcons.Contact icon:FluentIcons.Contact
onDropped: { FluApp.navigate("/about") } onDropped: { FluApp.navigate("/about") }
onTapListener:function(){ onTapListener:function(){
@ -21,7 +21,7 @@ FluObject{
} }
FluPaneItem{ FluPaneItem{
title:lang.settings title:Lang.settings
icon:FluentIcons.Settings icon:FluentIcons.Settings
url:"qrc:/example/qml/page/T_Settings.qml" url:"qrc:/example/qml/page/T_Settings.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }

View File

@ -16,7 +16,7 @@ FluObject{
FluPaneItem{ FluPaneItem{
id:item_home id:item_home
count: 9 count: 9
title:lang.home title:Lang.home
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_home.count count: item_home.count
} }
@ -45,9 +45,15 @@ FluObject{
} }
} }
FluPaneItemExpander{
title:"PaneItemExpander Disabled"
iconVisible: false
disabled: true
}
FluPaneItemExpander{ FluPaneItemExpander{
id:item_expander_basic_input id:item_expander_basic_input
title:lang.basic_input title:Lang.basic_input
icon:FluentIcons.CheckboxComposite icon:FluentIcons.CheckboxComposite
editDelegate: FluTextBox{ editDelegate: FluTextBox{
text:item_expander_basic_input.title text:item_expander_basic_input.title
@ -129,10 +135,15 @@ FluObject{
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{
title:"PaneItem Disabled"
disabled: true
icon: FluentIcons.Error
}
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.form title:Lang.form
icon:FluentIcons.GridView icon:FluentIcons.GridView
FluPaneItem{ FluPaneItem{
title:"TextBox" title:"TextBox"
@ -167,7 +178,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.surface title:Lang.surface
icon:FluentIcons.SurfaceHub icon:FluentIcons.SurfaceHub
FluPaneItem{ FluPaneItem{
title:"InfoBar" title:"InfoBar"
@ -202,6 +213,12 @@ FluObject{
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{
title:"Clip"
url:"qrc:/example/qml/page/T_Clip.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) }
}
FluPaneItem{ FluPaneItem{
title:"StatusView" title:"StatusView"
url:"qrc:/example/qml/page/T_StatusView.qml" url:"qrc:/example/qml/page/T_StatusView.qml"
@ -235,7 +252,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.popus title:Lang.popus
icon:FluentIcons.ButtonMenu icon:FluentIcons.ButtonMenu
FluPaneItem{ FluPaneItem{
title:"Dialog" title:"Dialog"
@ -273,7 +290,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.navigation title:Lang.navigation
icon:FluentIcons.AllApps icon:FluentIcons.AllApps
FluPaneItem{ FluPaneItem{
title:"Pivot" title:"Pivot"
@ -342,7 +359,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.theming title:Lang.theming
icon:FluentIcons.Brightness icon:FluentIcons.Brightness
FluPaneItem{ FluPaneItem{
title:"Acrylic" title:"Acrylic"
@ -376,7 +393,7 @@ FluObject{
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:lang.other title:Lang.other
icon:FluentIcons.Shop icon:FluentIcons.Shop
FluPaneItem{ FluPaneItem{
title:"QRCode" title:"QRCode"
@ -442,6 +459,12 @@ FluObject{
} }
onDropped:{ FluApp.navigate("/hotload") } onDropped:{ FluApp.navigate("/hotload") }
} }
FluPaneItem{
title:"3D"
url:"qrc:/example/qml/page/T_3D.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) }
}
} }
function getRecentlyAddedData(){ function getRecentlyAddedData(){

View File

@ -0,0 +1,77 @@
pragma Singleton
import QtQuick 2.15
QtObject {
property string home
property string basic_input
property string form
property string surface
property string popus
property string navigation
property string theming
property string media
property string dark_mode
property string sys_dark_mode
property string search
property string about
property string settings
property string locale
property string navigation_view_display_mode
property string other
function zh(){
home="首页"
basic_input="基本输入"
form="表单"
surface="表面"
popus="弹窗"
navigation="导航"
theming="主题"
media="媒体"
dark_mode="夜间模式"
sys_dark_mode="跟随系统"
search="查找"
about="关于"
settings="设置"
locale="语言环境"
navigation_view_display_mode="导航视图显示模式"
other="其他"
}
function en(){
home="Home"
basic_input="Basic Input"
form="Form"
surface="Surfaces"
popus="Popus"
navigation="Navigation"
theming="Theming"
media="Media"
dark_mode="Dark Mode"
sys_dark_mode="Sync with system"
search="Search"
about="About"
settings="Settings"
locale="Locale"
navigation_view_display_mode="NavigationView Display Mode"
other="Other"
}
property string __locale
property var __localeList: ["Zh","En"]
on__LocaleChanged: {
if(__locale === "Zh"){
zh()
}else{
en()
}
}
Component.onCompleted: {
__locale = "En"
}
}

View File

@ -1,2 +1,3 @@
singleton ItemsOriginal 1.0 ItemsOriginal.qml singleton ItemsOriginal 1.0 ItemsOriginal.qml
singleton ItemsFooter 1.0 ItemsFooter.qml singleton ItemsFooter 1.0 ItemsFooter.qml
singleton Lang 1.0 Lang.qml

121
example/qml/page/T_3D.qml Normal file
View File

@ -0,0 +1,121 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import Qt3D.Core 2.15
import Qt3D.Render 2.15
import Qt3D.Input 2.12
import Qt3D.Extras 2.15
import QtQuick.Scene3D 2.15
import QtQuick.Dialogs 1.3
import Qt.labs.platform 1.1
import FluentUI 1.0
import "qrc:///example/qml/component"
import "../component"
FluContentPage{
id:root
title:"3D"
Scene3D{
id:scene_3d
anchors.fill: parent
focus: true
aspects: ["input", "logic"]
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
Entity {
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 22.5
aspectRatio: scene_3d.width / scene_3d.height
nearPlane: 1
farPlane: 1000.0
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
position: Qt.vector3d( 0.0, 0.0, 15.0 )
}
FirstPersonCameraController {
linearSpeed: 100
lookSpeed: 50
camera: camera
}
components: [
RenderSettings{
activeFrameGraph: ForwardRenderer{
clearColor: Qt.rgba(0,0,0,0);
camera: camera
}
},
InputSettings{}
]
Mesh {
id: mesh
source: "https://zhu-zichu.gitee.io/test.obj"
}
PhongMaterial {
id: material
ambient: color_picker.colorValue
}
Transform{
id:transform
scale: 1.0
translation: Qt.vector3d(0, 0, 0)
rotation: fromEulerAngles(0, 0, 0)
property real hAngle:0.0
NumberAnimation on hAngle{
from:0
to:360.0
duration: 5000
loops: Animation.Infinite
}
matrix:{
var m=Qt.matrix4x4();
m.rotate(hAngle,Qt.vector3d(0,1,0));
m.translate(Qt.vector3d(0,0,0));
return m;
}
}
Entity {
id: entity
components: [mesh, material,transform]
}
}
}
ColumnLayout{
RowLayout{
spacing: 10
Layout.topMargin: 20
FluText{
text:"tintColor:"
Layout.alignment: Qt.AlignVCenter
}
FluColorPicker{
id:color_picker
enableAlphaChannel:false
Component.onCompleted: {
setColor("gray")
}
}
}
FluButton{
text:"选择obj资源"
onClicked: {
file_dialog.open()
}
}
}
FileDialog {
id: file_dialog
nameFilters: ["Obj files (*.obj)"]
folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
onAccepted: {
var fileUrl = file_dialog.currentFile
mesh.source = fileUrl
}
}
}

View File

@ -25,7 +25,7 @@ FluContentPage {
leftMargin: 14 leftMargin: 14
} }
onClicked: { onClicked: {
grid_view.model = FluApp.awesomelist(text_box.text) grid_view.model = FluTheme.awesomeList(text_box.text)
} }
} }
GridView{ GridView{
@ -34,7 +34,7 @@ FluContentPage {
cellHeight: 80 cellHeight: 80
clip: true clip: true
boundsBehavior: GridView.StopAtBounds boundsBehavior: GridView.StopAtBounds
model:FluApp.awesomelist() model:FluTheme.awesomeList()
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
anchors{ anchors{
topMargin: 10 topMargin: 10

View File

@ -37,7 +37,7 @@ FluScrollablePage{
left: parent.left left: parent.left
} }
FluCalendarPicker{ FluCalendarPicker{
current:Date.fromLocaleString("2013年7月11日 21:17:42") current:new Date()
onAccepted:{ onAccepted:{
showSuccess(current.toLocaleString()) showSuccess(current.toLocaleString())
} }

View File

@ -12,27 +12,35 @@ FluScrollablePage{
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
height: 68 height: 72
paddings: 10 paddings: 10
Layout.topMargin: 20 Layout.topMargin: 20
FluText{
text:"A 2-state CheckBox"
}
Row{ Row{
spacing: 30 spacing: 30
anchors.verticalCenter: parent.verticalCenter anchors{
FluCheckBox{ top: parent.top
disabled: check_box_switch.checked topMargin: 30
} }
FluCheckBox{ FluCheckBox{
disabled: check_box_switch.checked disabled: check_box_switch_two.checked
}
FluCheckBox{
disabled: check_box_switch_two.checked
text:"Right" text:"Right"
} }
FluCheckBox{ FluCheckBox{
disabled: check_box_switch.checked disabled: check_box_switch_two.checked
text:"Left" text:"Left"
textRight: false textRight: false
} }
} }
FluToggleSwitch{ FluToggleSwitch{
id:check_box_switch id:check_box_switch_two
anchors{ anchors{
right: parent.right right: parent.right
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
@ -48,4 +56,60 @@ FluScrollablePage{
}' }'
} }
FluArea{
Layout.fillWidth: true
height: 72
paddings: 10
Layout.topMargin: 20
FluText{
text:"A 3-state CheckBox"
}
Row{
spacing: 30
anchors{
top: parent.top
topMargin: 30
}
FluCheckBox{
property int count: 1
text:"Three State"
disabled: check_box_switch_three.checked
clickListener: function(){
var flag = count%3
if(flag === 0){
checked = false
indeterminate = false
}
if(flag === 1){
checked = true
indeterminate = false
}
if(flag === 2){
checked = true
indeterminate = true
}
count++
}
}
}
FluToggleSwitch{
id:check_box_switch_three
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
}
text:"Disabled"
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCheckBox{
text:"Text"
indeterminate:true
}'
}
} }

108
example/qml/page/T_Clip.qml Normal file
View File

@ -0,0 +1,108 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import FluentUI 1.0
import "../component"
import "qrc:///example/qml/component"
FluScrollablePage{
title:"Clip"
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 380
paddings: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"配合图片使用(software渲染下该组件将没有效果)"
font: FluTextStyle.Subtitle
Layout.topMargin: 20
}
RowLayout{
spacing: 14
FluClip{
width: 50
height: 50
radius:[25,0,25,25]
Image {
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_1.svg"
sourceSize: Qt.size(width,height)
}
}
FluClip{
width: 50
height: 50
radius:[10,10,10,10]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_2.svg"
}
}
FluClip{
width: 50
height: 50
radius:[25,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_3.svg"
}
}
FluClip{
width: 50
height: 50
radius:[0,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_4.svg"
}
}
}
FluClip{
width: 1920/5
height: 1200/5
radius:[8,8,8,8]
Image {
asynchronous: true
source: "qrc:/example/res/image/banner_1.jpg"
anchors.fill: parent
sourceSize: Qt.size(2*width,2*height)
}
Layout.topMargin: 20
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluClip{
radius: [25,25,25,25]
width: 50
height: 50
Image{
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_4.svg"
sourceSize: Qt.size(width,height)
}
}'
}
}

View File

@ -59,6 +59,7 @@ FluScrollablePage{
width: parent.width width: parent.width
height: parent.height height: parent.height
contentWidth: width contentWidth: width
boundsBehavior: Flickable.StopAtBounds
contentHeight: text_info.height contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
FluText{ FluText{

View File

@ -11,7 +11,7 @@ import "../component"
FluContentPage{ FluContentPage{
title:"Http" title:"Http"
property string cacheDirPath: FluTools.getApplicationDirPath() + "/cache/http" property string cacheDirPath: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation) + "/cache/http"
property bool isDownCompleted: false property bool isDownCompleted: false
FluHttp{ FluHttp{
@ -101,6 +101,9 @@ FluContentPage{
params.custtel = "1234567890" params.custtel = "1234567890"
params.custemail = "zhuzichu520@gmail.com" params.custemail = "zhuzichu520@gmail.com"
request.params = params request.params = params
var headers = {}
headers.test = "123456789456465321354"
request.headers = headers
http.post(request,callable) http.post(request,callable)
} }
} }
@ -128,6 +131,15 @@ FluContentPage{
http.postString(request,callable) http.postString(request,callable)
} }
} }
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/delete")
http.deleteResource(request,callable)
}
}
FluProgressButton{ FluProgressButton{
id:btn_download id:btn_download
implicitWidth: parent.width implicitWidth: parent.width
@ -265,7 +277,7 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "打开缓存路径" text: "打开缓存路径"
onClicked: { onClicked: {
Qt.openUrlExternally("file:///"+cacheDirPath) Qt.openUrlExternally(cacheDirPath)
} }
} }
FluButton{ FluButton{

View File

@ -13,16 +13,15 @@ FluScrollablePage{
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 20 Layout.topMargin: 20
height: 460 height: 80
paddings: 10 paddings: 10
Column{ Column{
spacing: 15 spacing: 15
anchors{ anchors{
verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
verticalCenter: parent.verticalCenter
} }
RowLayout{ RowLayout{
Layout.topMargin: 20 Layout.topMargin: 20
FluRectangle{ FluRectangle{
@ -62,70 +61,6 @@ FluScrollablePage{
radius:[0,0,0,15] radius:[0,0,0,15]
} }
} }
FluText{
text:"配合图片使用"
font: FluTextStyle.Subtitle
Layout.topMargin: 20
}
RowLayout{
spacing: 14
FluClip{
width: 50
height: 50
radius:[25,0,25,25]
Image {
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_1.svg"
sourceSize: Qt.size(width,height)
}
}
FluClip{
width: 50
height: 50
radius:[10,10,10,10]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_2.svg"
}
}
FluClip{
width: 50
height: 50
radius:[25,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_3.svg"
}
}
FluClip{
width: 50
height: 50
radius:[0,25,25,25]
Image {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/example/res/svg/avatar_4.svg"
}
}
}
FluClip{
width: 1920/5
height: 1200/5
radius:[8,8,8,8]
Image {
asynchronous: true
source: "qrc:/example/res/image/banner_1.jpg"
anchors.fill: parent
sourceSize: Qt.size(2*width,2*height)
}
Layout.topMargin: 20
}
} }
} }
CodeExpander{ CodeExpander{
@ -135,14 +70,6 @@ FluScrollablePage{
radius: [25,25,25,25] radius: [25,25,25,25]
width: 50 width: 50
height: 50 height: 50
Image{
asynchronous: true
anchors.fill: parent
source: "qrc:/example/res/svg/avatar_4.svg"
sourceSize: Qt.size(width,height)
}
}' }'
} }
} }

View File

@ -3,6 +3,7 @@ import QtQuick.Layouts 1.15
import QtQuick.Window 2.15 import QtQuick.Window 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import FluentUI 1.0 import FluentUI 1.0
import Qt.labs.platform 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
@ -48,7 +49,7 @@ FluScrollablePage{
FluScreenshot{ FluScreenshot{
id:screenshot id:screenshot
captrueMode: FluScreenshotType.File captrueMode: FluScreenshotType.File
saveFolder: FluTools.getApplicationDirPath()+"/screenshot" saveFolder: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation)+"/screenshot"
onCaptrueCompleted: onCaptrueCompleted:
(captrue)=>{ (captrue)=>{
image.source = captrue image.source = captrue

View File

@ -65,30 +65,46 @@ FluScrollablePage{
height: 50 height: 50
paddings: 10 paddings: 10
FluCheckBox{ FluCheckBox{
text:"Software Render" text:"V-Sync"
checked: SettingsHelper.getReander() === "software" checked: FluApp.vsync
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onClicked: { onClicked: {
if(SettingsHelper.getReander() === "software"){ FluApp.vsync = !FluApp.vsync
dialog_restart.open()
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
FluCheckBox{
text:"Software Render"
checked: SettingsHelper.getRender() === "software"
anchors.verticalCenter: parent.verticalCenter
onClicked: {
if(SettingsHelper.getRender() === "software"){
SettingsHelper.saveRender("") SettingsHelper.saveRender("")
}else{ }else{
SettingsHelper.saveRender("software") SettingsHelper.saveRender("software")
} }
dialog_render.open() dialog_restart.open()
} }
} }
} }
FluContentDialog{ FluContentDialog{
id:dialog_render id:dialog_restart
title:"友情提示" title:"友情提示"
message:"此操作需要重启才能生效,是否重新启动?" message:"此操作需要重启才能生效,是否重新启动?"
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
negativeText: "取消" negativeText: "取消"
positiveText:"确定" positiveText:"确定"
onPositiveClicked:{ onPositiveClicked:{
window.deleteWindow() FluApp.exit(931)
AppInfo.restart()
} }
} }
@ -105,7 +121,7 @@ FluScrollablePage{
left: parent.left left: parent.left
} }
FluText{ FluText{
text:lang.dark_mode text:Lang.dark_mode
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
@ -135,7 +151,7 @@ FluScrollablePage{
left: parent.left left: parent.left
} }
FluText{ FluText{
text:lang.navigation_view_display_mode text:Lang.navigation_view_display_mode
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
@ -166,7 +182,7 @@ FluScrollablePage{
} }
FluText{ FluText{
text:lang.locale text:Lang.locale
font: FluTextStyle.BodyStrong font: FluTextStyle.BodyStrong
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
@ -174,12 +190,12 @@ FluScrollablePage{
Flow{ Flow{
spacing: 5 spacing: 5
Repeater{ Repeater{
model: ["Zh","En"] model: Lang.__localeList
delegate: FluRadioButton{ delegate: FluRadioButton{
checked: AppInfo.lang.objectName === modelData checked: Lang.__locale === modelData
text:modelData text:modelData
clickListener:function(){ clickListener:function(){
AppInfo.changeLang(modelData) Lang.__locale = modelData
} }
} }
} }

View File

@ -8,12 +8,45 @@ import "../component"
FluContentPage{ FluContentPage{
id:root
title:"TableView" title:"TableView"
signal checkBoxChanged
property var dataSource : []
property int sortType: 0
Component.onCompleted: { Component.onCompleted: {
loadData(1,1000) loadData(1,1000)
} }
onSortTypeChanged: {
table_view.closeEditor()
if(sortType === 0){
table_view.sort()
}else if(sortType === 1){
table_view.sort((a, b) => a.age - b.age);
}else if(sortType === 2){
table_view.sort((a, b) => b.age - a.age);
}
}
Component{
id:com_checbox
Item{
FluCheckBox{
anchors.centerIn: parent
checked: true === options.checked
enableAnimation: false
clickListener: function(){
var obj = tableModel.getRow(row)
obj.checkbox = table_view.customItem(com_checbox,{checked:!options.checked})
tableModel.setRow(row,obj)
checkBoxChanged()
}
}
}
}
Component{ Component{
id:com_action id:com_action
Item{ Item{
@ -24,11 +57,15 @@ FluContentPage{
onClicked: { onClicked: {
table_view.closeEditor() table_view.closeEditor()
tableModel.removeRow(row) tableModel.removeRow(row)
checkBoxChanged()
} }
} }
FluFilledButton{ FluFilledButton{
text:"编辑" text:"编辑"
onClicked: { onClicked: {
var obj = tableModel.getRow(row)
obj.name = "12345"
tableModel.setRow(row,obj)
showSuccess(JSON.stringify(tableModel.getRow(row))) showSuccess(JSON.stringify(tableModel.getRow(row)))
} }
} }
@ -36,39 +73,44 @@ FluContentPage{
} }
} }
function loadData(page,count){
var numbers = [100, 300, 500, 1000]; Component{
function getRandomAge() { id:com_column_checbox
var randomIndex = Math.floor(Math.random() * numbers.length); Item{
return numbers[randomIndex]; RowLayout{
anchors.centerIn: parent
FluText{
text:"全选"
Layout.alignment: Qt.AlignVCenter
} }
var names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"]; FluCheckBox{
function getRandomName(){ checked: true === options.checked
var randomIndex = Math.floor(Math.random() * names.length); enableAnimation: false
return names[randomIndex]; Layout.alignment: Qt.AlignVCenter
clickListener: function(){
var checked = !options.checked
itemModel.display = table_view.customItem(com_column_checbox,{"checked":checked})
for(var i =0;i< tableModel.rowCount ;i++){
var rowData = tableModel.getRow(i)
rowData.checkbox = table_view.customItem(com_checbox,{"checked":checked})
tableModel.setRow(i,rowData)
}
}
}
Connections{
target: root
function onCheckBoxChanged(){
for(var i =0;i< tableModel.rowCount ;i++){
if(false === tableModel.getRow(i).checkbox.options.checked){
itemModel.display = table_view.customItem(com_column_checbox,{"checked":false})
return
}
}
itemModel.display = table_view.customItem(com_column_checbox,{"checked":true})
} }
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
} }
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
} }
const dataSource = []
for(var i=0;i<count;i++){
dataSource.push({
name: getRandomName(),
age:getRandomAge(),
address: getRandomAddresses(),
nickname: getRandomNickname(),
longstring:"你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好",
action:com_action
})
} }
table_view.dataSource = dataSource
} }
Component{ Component{
@ -95,6 +137,88 @@ FluContentPage{
} }
} }
Component{
id:com_avatar
Item{
FluClip{
anchors.centerIn: parent
width: 40
height: 40
radius: [20,20,20,20]
Image{
anchors.fill: parent
source: {
if(options && options.avatar){
return options.avatar
}
return ""
}
sourceSize: Qt.size(80,80)
}
}
}
}
Component{
id:com_column_sort_age
Item{
FluText{
text:"年龄"
anchors.centerIn: parent
}
ColumnLayout{
spacing: 0
anchors{
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: 4
}
FluIconButton{
Layout.preferredWidth: 20
Layout.preferredHeight: 15
iconSize: 12
verticalPadding:0
horizontalPadding:0
iconSource: FluentIcons.ChevronUp
iconColor: {
if(1 === root.sortType){
return FluTheme.primaryColor.dark
}
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
}
onClicked: {
if(root.sortType === 1){
root.sortType = 0
return
}
root.sortType = 1
}
}
FluIconButton{
Layout.preferredWidth: 20
Layout.preferredHeight: 15
iconSize: 12
verticalPadding:0
horizontalPadding:0
iconSource: FluentIcons.ChevronDown
iconColor: {
if(2 === root.sortType){
return FluTheme.primaryColor.dark
}
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
}
onClicked: {
if(root.sortType === 2){
root.sortType = 0
return
}
root.sortType = 2
}
}
}
}
}
FluTableView{ FluTableView{
id:table_view id:table_view
anchors{ anchors{
@ -105,13 +229,27 @@ FluContentPage{
} }
anchors.topMargin: 20 anchors.topMargin: 20
columnSource:[ columnSource:[
{
title: table_view.customItem(com_column_checbox,{checked:true}),
dataIndex: 'checkbox',
width:80,
minimumWidth:80,
maximumWidth:80,
},
{
title: '头像',
dataIndex: 'avatar',
width:100,
minimumWidth:100,
maximumWidth:100
},
{ {
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'name',
readOnly:true, readOnly:true,
}, },
{ {
title: '年龄', title: table_view.customItem(com_column_sort_age,{sort:0}),
dataIndex: 'age', dataIndex: 'age',
editDelegate:com_combobox, editDelegate:com_combobox,
width:100, width:100,
@ -167,6 +305,50 @@ FluContentPage{
} }
} }
function loadData(page,count){
var numbers = [100, 300, 500, 1000];
function getRandomAge() {
var randomIndex = Math.floor(Math.random() * numbers.length);
return numbers[randomIndex];
}
var names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"];
function getRandomName(){
var randomIndex = Math.floor(Math.random() * names.length);
return names[randomIndex];
}
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
}
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
}
var avatars = ["qrc:/example/res/svg/avatar_1.svg", "qrc:/example/res/svg/avatar_2.svg", "qrc:/example/res/svg/avatar_3.svg", "qrc:/example/res/svg/avatar_4.svg","qrc:/example/res/svg/avatar_5.svg","qrc:/example/res/svg/avatar_6.svg","qrc:/example/res/svg/avatar_7.svg","qrc:/example/res/svg/avatar_8.svg","qrc:/example/res/svg/avatar_9.svg","qrc:/example/res/svg/avatar_10.svg","qrc:/example/res/svg/avatar_11.svg","qrc:/example/res/svg/avatar_12.svg"];
function getAvatar(){
var randomIndex = Math.floor(Math.random() * avatars.length);
return avatars[randomIndex];
}
const dataSource = []
for(var i=0;i<count;i++){
dataSource.push({
checkbox: table_view.customItem(com_checbox,{checked:true}),
avatar:table_view.customItem(com_avatar,{avatar:getAvatar()}),
name: getRandomName(),
age:getRandomAge(),
address: getRandomAddresses(),
nickname: getRandomNickname(),
longstring:"你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好",
action: table_view.customItem(com_action),
minimumHeight:50
})
}
root.dataSource = dataSource
table_view.dataSource = root.dataSource
}
} }

View File

@ -85,7 +85,7 @@ FluScrollablePage{
text:"找到一份Android外包开发岗位开发了一个Android应用满满成就感前端、服务端、Flutter也都懂一丢丢什么都会什么都不精通钱途无望" text:"找到一份Android外包开发岗位开发了一个Android应用满满成就感前端、服务端、Flutter也都懂一丢丢什么都会什么都不精通钱途无望"
} }
ListElement{ ListElement{
lable:"2020-06-01" lable:"2021-06-01"
text:"由于某个项目紧急临时加入Qt项目组就因为大学学了点C++),本来是想进去打个酱油,到后面竟然成开发主力,坑啊" text:"由于某个项目紧急临时加入Qt项目组就因为大学学了点C++),本来是想进去打个酱油,到后面竟然成开发主力,坑啊"
} }
ListElement{ ListElement{

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
title:"关于" title:"关于"

View File

@ -6,7 +6,7 @@ import example 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
title:"热加载" title:"热加载"

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
title:"登录" title:"登录"

View File

@ -12,7 +12,7 @@ import "../component"
import "../viewmodel" import "../viewmodel"
import "../global" import "../global"
CustomWindow { FluWindow {
id:window id:window
title: "FluentUI" title: "FluentUI"
@ -21,14 +21,14 @@ CustomWindow {
closeDestory:false closeDestory:false
minimumWidth: 520 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
appBarVisible: false
launchMode: FluWindowType.SingleTask launchMode: FluWindowType.SingleTask
appBar: undefined
SettingsViewModel{ SettingsViewModel{
id:viewmodel_settings id:viewmodel_settings
} }
closeFunc:function(event){ closeListener:function(event){
dialog_close.open() dialog_close.open()
event.accepted = false event.accepted = false
} }
@ -61,8 +61,7 @@ CustomWindow {
MenuItem { MenuItem {
text: "退出" text: "退出"
onTriggered: { onTriggered: {
window.deleteWindow() FluApp.exit()
FluApp.closeApp()
} }
} }
} }
@ -89,8 +88,7 @@ CustomWindow {
positiveText:"退出" positiveText:"退出"
neutralText:"取消" neutralText:"取消"
onPositiveClicked:{ onPositiveClicked:{
window.deleteWindow() FluApp.exit()
FluApp.closeApp()
} }
} }
@ -123,7 +121,7 @@ CustomWindow {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
darkText: lang.dark_mode darkText: Lang.dark_mode
showDark: true showDark: true
z:7 z:7
darkClickListener:(button)=>handleDarkChanged(button) darkClickListener:(button)=>handleDarkChanged(button)
@ -173,7 +171,7 @@ CustomWindow {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
darkText: lang.dark_mode darkText: Lang.dark_mode
showDark: true showDark: true
darkClickListener:(button)=>handleDarkChanged(button) darkClickListener:(button)=>handleDarkChanged(button)
z:7 z:7
@ -204,11 +202,9 @@ CustomWindow {
} }
} }
autoSuggestBox:FluAutoSuggestBox{ autoSuggestBox:FluAutoSuggestBox{
width: 280
anchors.centerIn: parent
iconSource: FluentIcons.Search iconSource: FluentIcons.Search
items: ItemsOriginal.getSearchData() items: ItemsOriginal.getSearchData()
placeholderText: lang.search placeholderText: Lang.search
onItemClicked: onItemClicked:
(data)=>{ (data)=>{
ItemsOriginal.startPageByItem(data) ItemsOriginal.startPageByItem(data)

View File

@ -6,7 +6,7 @@ import example 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
width: 800 width: 800

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
title:"SingleInstance" title:"SingleInstance"

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
title:"SingleTask" title:"SingleTask"

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
import "../component" import "../component"
CustomWindow { FluWindow {
id:window id:window
title:"Standard" title:"Standard"

View File

@ -3,39 +3,14 @@
#include <QQmlContext> #include <QQmlContext>
#include <QDebug> #include <QDebug>
#include <QGuiApplication> #include <QGuiApplication>
#include "lang/En.h"
#include "lang/Zh.h"
#include "Version.h" #include "Version.h"
AppInfo::AppInfo(QObject *parent) AppInfo::AppInfo(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
version(APPLICATION_VERSION); version(APPLICATION_VERSION);
lang(new En());
} }
void AppInfo::init(QQmlApplicationEngine *engine){ void AppInfo::init(QQmlApplicationEngine *engine){
QQmlContext * context = engine->rootContext(); engine->rootContext();
Lang* lang = this->lang();
context->setContextProperty("lang",lang);
QObject::connect(this,&AppInfo::langChanged,this,[=]{
context->setContextProperty("lang",this->lang());
});
}
void AppInfo::changeLang(const QString& locale){
if(_lang){
_lang->deleteLater();
}
if(locale=="Zh"){
lang(new Zh());
}else if(locale=="En"){
lang(new En());
}else {
lang(new En());
}
}
void AppInfo::restart(){
qApp->exit(931);
} }

View File

@ -3,7 +3,6 @@
#include <QObject> #include <QObject>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include "lang/Lang.h"
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
@ -11,14 +10,11 @@ class AppInfo : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString,version) Q_PROPERTY_AUTO(QString,version)
Q_PROPERTY_AUTO(Lang*,lang)
private: private:
explicit AppInfo(QObject *parent = nullptr); explicit AppInfo(QObject *parent = nullptr);
public: public:
SINGLETONG(AppInfo) SINGLETONG(AppInfo)
void init(QQmlApplicationEngine *engine); void init(QQmlApplicationEngine *engine);
Q_INVOKABLE void changeLang(const QString& locale);
Q_INVOKABLE void restart();
}; };
#endif // APPINFO_H #endif // APPINFO_H

View File

@ -1,6 +1,7 @@
#include "SettingsHelper.h" #include "SettingsHelper.h"
#include <QDataStream> #include <QDataStream>
#include <QStandardPaths>
SettingsHelper::SettingsHelper(QObject *parent) : QObject(parent) SettingsHelper::SettingsHelper(QObject *parent) : QObject(parent)
{ {
@ -34,7 +35,7 @@ void SettingsHelper::init(char *argv[]){
auto applicationPath = QString::fromStdString(argv[0]); auto applicationPath = QString::fromStdString(argv[0]);
const QFileInfo fileInfo(applicationPath); const QFileInfo fileInfo(applicationPath);
const QString iniFileName = fileInfo.completeBaseName() + ".ini"; const QString iniFileName = fileInfo.completeBaseName() + ".ini";
const QString iniFilePath = fileInfo.dir().path() + "/" + iniFileName; const QString iniFilePath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + iniFileName;
qDebug()<<iniFilePath; qDebug()<<"Application configuration file path->"<<iniFilePath;
m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat)); m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat));
} }

View File

@ -20,9 +20,11 @@ public:
~SettingsHelper() override; ~SettingsHelper() override;
void init(char *argv[]); void init(char *argv[]);
Q_INVOKABLE void saveRender(const QString& render){save("render",render);} Q_INVOKABLE void saveRender(const QString& render){save("render",render);}
Q_INVOKABLE QString getReander(){return get("render").toString();} Q_INVOKABLE QString getRender(){return get("render").toString();}
Q_INVOKABLE void saveDarkMode(int darkModel){save("darkMode",darkModel);} Q_INVOKABLE void saveDarkMode(int darkModel){save("darkMode",darkModel);}
Q_INVOKABLE int getDarkMode(){return get("darkMode").toInt(0);} Q_INVOKABLE int getDarkMode(){return get("darkMode").toInt(0);}
Q_INVOKABLE void saveVsync(bool vsync){save("vsync",vsync);}
Q_INVOKABLE bool getVsync(){return get("vsync").toBool();}
private: private:
void save(const QString& key,QVariant val); void save(const QString& key,QVariant val);
QVariant get(const QString& key); QVariant get(const QString& key);

View File

@ -1,23 +0,0 @@
#include "En.h"
En::En(QObject *parent)
: Lang{parent}
{
setObjectName("En");
home("Home");
basic_input("Basic Input");
form("Form");
surface("Surfaces");
popus("Popus");
navigation("Navigation");
theming("Theming");
media("Media");
dark_mode("Dark Mode");
sys_dark_mode("Sync with system");
search("Search");
about("About");
settings("Settings");
locale("Locale");
navigation_view_display_mode("NavigationView Display Mode");
other("Other");
}

View File

@ -1,17 +0,0 @@
#ifndef EN_H
#define EN_H
#include <QObject>
#include "Lang.h"
class En : public Lang
{
Q_OBJECT
public:
explicit En(QObject *parent = nullptr);
signals:
};
#endif // EN_H

View File

@ -1,7 +0,0 @@
#include "Lang.h"
Lang::Lang(QObject *parent)
: QObject{parent}
{
}

View File

@ -1,31 +0,0 @@
#ifndef LANG_H
#define LANG_H
#include <QObject>
#include "../stdafx.h"
class Lang : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(QString,home);
Q_PROPERTY_AUTO(QString,basic_input);
Q_PROPERTY_AUTO(QString,form);
Q_PROPERTY_AUTO(QString,surface);
Q_PROPERTY_AUTO(QString,popus);
Q_PROPERTY_AUTO(QString,navigation);
Q_PROPERTY_AUTO(QString,theming);
Q_PROPERTY_AUTO(QString,media);
Q_PROPERTY_AUTO(QString,dark_mode);
Q_PROPERTY_AUTO(QString,sys_dark_mode);
Q_PROPERTY_AUTO(QString,search);
Q_PROPERTY_AUTO(QString,about);
Q_PROPERTY_AUTO(QString,settings);
Q_PROPERTY_AUTO(QString,navigation_view_display_mode);
Q_PROPERTY_AUTO(QString,locale);
Q_PROPERTY_AUTO(QString,other);
public:
explicit Lang(QObject *parent = nullptr);
};
#endif // LANG_H

View File

@ -1,23 +0,0 @@
#include "Zh.h"
Zh::Zh(QObject *parent)
: Lang{parent}
{
setObjectName("Zh");
home("首页");
basic_input("基本输入");
form("表单");
surface("表面");
popus("弹窗");
navigation("导航");
theming("主题");
media("媒体");
dark_mode("夜间模式");
sys_dark_mode("跟随系统");
search("查找");
about("关于");
settings("设置");
locale("语言环境");
navigation_view_display_mode("导航视图显示模式");
other("其他");
}

View File

@ -1,17 +0,0 @@
#ifndef ZH_H
#define ZH_H
#include <QObject>
#include "Lang.h"
class Zh : public Lang
{
Q_OBJECT
public:
explicit Zh(QObject *parent = nullptr);
signals:
};
#endif // ZH_H

View File

@ -6,9 +6,8 @@
#include <QNetworkProxy> #include <QNetworkProxy>
#include <QSslConfiguration> #include <QSslConfiguration>
#include <QProcess> #include <QProcess>
#include <FramelessHelper/Quick/framelessquickmodule.h>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include <QtQml/qqmlextensionplugin.h> #include <QtQml/qqmlextensionplugin.h>
#include <QLoggingCategory>
#include "AppInfo.h" #include "AppInfo.h"
#include "src/component/CircularReveal.h" #include "src/component/CircularReveal.h"
#include "src/component/FileWatcher.h" #include "src/component/FileWatcher.h"
@ -22,11 +21,9 @@ Q_IMPORT_QML_PLUGIN(FluentUIPlugin)
#include <FluentUI.h> #include <FluentUI.h>
#endif #endif
FRAMELESSHELPER_USE_NAMESPACE
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
SettingsHelper::getInstance()->init(argv); QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
@ -35,11 +32,11 @@ int main(int argc, char *argv[])
#endif #endif
#endif #endif
qputenv("QT_QUICK_CONTROLS_STYLE","Basic"); qputenv("QT_QUICK_CONTROLS_STYLE","Basic");
FramelessHelper::Quick::initialize();
QGuiApplication::setOrganizationName("ZhuZiChu"); QGuiApplication::setOrganizationName("ZhuZiChu");
QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io"); QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io");
QGuiApplication::setApplicationName("FluentUI"); QGuiApplication::setApplicationName("FluentUI");
if(SettingsHelper::getInstance()->getReander()=="software"){ SettingsHelper::getInstance()->init(argv);
if(SettingsHelper::getInstance()->getRender()=="software"){
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
QQuickWindow::setGraphicsApi(QSGRendererInterface::Software); QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #elif (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
@ -47,22 +44,12 @@ int main(int argc, char *argv[])
#endif #endif
} }
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial); // QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.general=true"));
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow); // qSetMessagePattern("%{category}: %{message}");
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
#ifdef Q_OS_WIN
FramelessConfig::instance()->set(Global::Option::ForceHideWindowFrameBorder);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow,false);
#endif
#ifdef Q_OS_MACOS
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
#endif
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
AppInfo::getInstance()->init(&engine); AppInfo::getInstance()->init(&engine);
engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance()); engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance());
engine.rootContext()->setContextProperty("SettingsHelper",SettingsHelper::getInstance()); engine.rootContext()->setContextProperty("SettingsHelper",SettingsHelper::getInstance());
FramelessHelper::Quick::registerTypes(&engine);
#ifdef FLUENTUI_BUILD_STATIC_LIB #ifdef FLUENTUI_BUILD_STATIC_LIB
FluentUI::getInstance()->registerTypes(&engine); FluentUI::getInstance()->registerTypes(&engine);
#endif #endif

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -15,16 +15,16 @@ Write-Host "scriptDir" $scriptDir
function Main() { function Main() {
New-Item -ItemType Directory $archiveName New-Item -ItemType Directory dist
# 拷贝exe # 拷贝exe
Copy-Item bin\release\* $archiveName\ -Force -Recurse | Out-Null Copy-Item bin\release\* dist\ -Force -Recurse | Out-Null
# 拷贝依赖 # 拷贝依赖
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName windeployqt --qmldir . --plugindir dist\plugins --no-translations --compiler-runtime dist\$targetName
# 删除不必要的文件 # 删除不必要的文件
$excludeList = @("*.qmlc", "*.ilk", "*.exp", "*.lib", "*.pdb") $excludeList = @("*.qmlc", "*.ilk", "*.exp", "*.lib", "*.pdb")
Remove-Item -Path $archiveName -Include $excludeList -Recurse -Force Remove-Item -Path dist -Include $excludeList -Recurse -Force
# 打包zip # 打包zip
Compress-Archive -Path $archiveName $archiveName'.zip' Compress-Archive -Path dist $archiveName'.zip'
} }
if ($null -eq $archiveName || $null -eq $targetName) { if ($null -eq $archiveName || $null -eq $targetName) {

View File

@ -25,22 +25,22 @@ Write-Host "scriptDir" $scriptDir
function Main() { function Main() {
New-Item -ItemType Directory $archiveName New-Item -ItemType Directory dist
# 拷贝exe # 拷贝exe
Copy-Item bin\release\* $archiveName\ -Force -Recurse | Out-Null Copy-Item bin\release\* dist -Force -Recurse | Out-Null
# 拷贝依赖 # 拷贝依赖
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName windeployqt --qmldir . --plugindir dist\plugins --no-translations --compiler-runtime dist\$targetName
# 删除不必要的文件 # 删除不必要的文件
$excludeList = @("*.qmlc", "*.ilk", "*.exp", "*.lib", "*.pdb") $excludeList = @("*.qmlc", "*.ilk", "*.exp", "*.lib", "*.pdb")
Remove-Item -Path $archiveName -Include $excludeList -Recurse -Force Remove-Item -Path dist -Include $excludeList -Recurse -Force
# 拷贝vcRedist dll # 拷贝vcRedist dll
$redistDll="{0}{1}\*.CRT\*.dll" -f $env:vcToolsRedistDir.Trim(),$env:msvcArch $redistDll="{0}{1}\*.CRT\*.dll" -f $env:vcToolsRedistDir.Trim(),$env:msvcArch
Copy-Item $redistDll $archiveName\ Copy-Item $redistDll dist\
# 拷贝WinSDK dll # 拷贝WinSDK dll
$sdkDll="{0}Redist\{1}ucrt\DLLs\{2}\*.dll" -f $env:winSdkDir.Trim(),$env:winSdkVer.Trim(),$env:msvcArch $sdkDll="{0}Redist\{1}ucrt\DLLs\{2}\*.dll" -f $env:winSdkDir.Trim(),$env:winSdkVer.Trim(),$env:msvcArch
Copy-Item $sdkDll $archiveName\ Copy-Item $sdkDll dist\
# 打包zip # 打包zip
Compress-Archive -Path $archiveName $archiveName'.zip' Compress-Archive -Path dist $archiveName'.zip'
} }
if ($null -eq $archiveName || $null -eq $targetName) { if ($null -eq $archiveName || $null -eq $targetName) {

View File

@ -120,8 +120,17 @@ else()
) )
endif() endif()
#去掉mingw生成的动态库libxxx前缀lib不去掉前缀会导致 module "FluentUI" plugin "fluentuiplugin" not found #去掉mingw生成的动态库libxxx前缀lib不去掉前缀会导致 module "FluentUI" plugin "fluentuiplugin" not found
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") if(MINGW)
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ".debug")
endif()
#MSVC Debug 添加后缀d与Qt插件风格保持一致
if(MSVC)
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "d")
endif()
#链接库 #链接库
target_link_libraries(${PROJECT_NAME} PUBLIC target_link_libraries(${PROJECT_NAME} PUBLIC
@ -129,6 +138,8 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
Qt${QT_VERSION_MAJOR}::QuickPrivate Qt${QT_VERSION_MAJOR}::QuickPrivate
Qt${QT_VERSION_MAJOR}::QmlPrivate Qt${QT_VERSION_MAJOR}::QmlPrivate
ZXing ZXing
FramelessHelper::Core
FramelessHelper::Quick
) )
#安装 #安装

View File

@ -8,9 +8,13 @@
#include <QUuid> #include <QUuid>
#include <QFontDatabase> #include <QFontDatabase>
#include <QClipboard> #include <QClipboard>
#include "Def.h" #include <FramelessHelper/Quick/framelessquickmodule.h>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
FRAMELESSHELPER_USE_NAMESPACE
FluApp::FluApp(QObject *parent):QObject{parent}{ FluApp::FluApp(QObject *parent):QObject{parent}{
vsync(false);
httpInterceptor(nullptr); httpInterceptor(nullptr);
} }
@ -18,7 +22,20 @@ FluApp::~FluApp(){
} }
void FluApp::init(QQuickWindow *window){ void FluApp::init(QQuickWindow *window){
this->appWindow = window; this->_application = window;
FramelessHelper::Quick::initialize();
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
#ifdef Q_OS_WIN
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow,false);
#endif
#ifdef Q_OS_MACOS
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
#endif
QQmlEngine *engine = qmlEngine(_application);
FramelessHelper::Quick::registerTypes(engine);
} }
void FluApp::run(){ void FluApp::run(){
@ -30,7 +47,7 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
qCritical()<<"No route found "<<route; qCritical()<<"No route found "<<route;
return; return;
} }
QQmlEngine *engine = qmlEngine(appWindow); QQmlEngine *engine = qmlEngine(_application);
QQmlComponent component(engine, routes().value(route).toString()); QQmlComponent component(engine, routes().value(route).toString());
if (component.isError()) { if (component.isError()) {
qCritical() << component.errors(); qCritical() << component.errors();
@ -42,65 +59,47 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
properties.insert("_pageRegister",QVariant::fromValue(fluRegister)); properties.insert("_pageRegister",QVariant::fromValue(fluRegister));
} }
properties.insert("argument",argument); properties.insert("argument",argument);
QQuickWindow *view=nullptr; QQuickWindow *win=nullptr;
for (auto& pair : wnds) { for (const auto& pair : _windows.toStdMap()) {
QString r = pair->property("_route").toString(); QString r = pair.second->property("_route").toString();
if(r == route){ if(r == route){
view = pair; win = pair.second;
break; break;
} }
} }
if(view){ if(win){
//如果窗口存在,则判断启动模式 int launchMode = win->property("launchMode").toInt();
int launchMode = view->property("launchMode").toInt();
if(launchMode == 1){ if(launchMode == 1){
view->setProperty("argument",argument); win->setProperty("argument",argument);
view->show(); win->show();
view->raise(); win->raise();
view->requestActivate(); win->requestActivate();
return; return;
}else if(launchMode == 2){ }else if(launchMode == 2){
view->close(); win->close();
} }
} }
view = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties)); win = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties));
wnds.insert(view->winId(),view);
if(fluRegister){ if(fluRegister){
fluRegister->to(view); fluRegister->to(win);
} }
view->setColor(QColor(Qt::transparent)); win->setColor(QColor(Qt::transparent));
} }
QJsonArray FluApp::awesomelist(const QString& keyword){ void FluApp::exit(int retCode){
QJsonArray arr; for (const auto& pair : _windows.toStdMap()) {
QMetaEnum enumType = Fluent_Awesome::staticMetaObject.enumerator(Fluent_Awesome::staticMetaObject.indexOfEnumerator("Fluent_AwesomeType")); removeWindow(pair.second);
for(int i=0; i < enumType.keyCount(); ++i){
QString name = enumType.key(i);
int icon = enumType.value(i);
if(keyword.isEmpty()){
QJsonObject obj;
obj.insert("name",name);
obj.insert("icon",icon);
arr.append(obj);
}else{
if(name.contains(keyword)){
QJsonObject obj;
obj.insert("name",name);
obj.insert("icon",icon);
arr.append(obj);
} }
} qApp->exit(retCode);
}
return arr;
} }
void FluApp::closeApp(){ void FluApp::addWindow(QQuickWindow* window){
qApp->exit(0); _windows.insert(window->winId(),window);
} }
void FluApp::deleteWindow(QQuickWindow* window){ void FluApp::removeWindow(QQuickWindow* window){
if(window){ if(window){
wnds.remove(window->winId()); _windows.remove(window->winId());
window->deleteLater(); window->deleteLater();
window = nullptr; window = nullptr;
} }

View File

@ -19,6 +19,7 @@
class FluApp : public QObject class FluApp : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(bool,vsync)
Q_PROPERTY_AUTO(QString,initialRoute); Q_PROPERTY_AUTO(QString,initialRoute);
Q_PROPERTY_AUTO(QJsonObject,routes); Q_PROPERTY_AUTO(QJsonObject,routes);
Q_PROPERTY_AUTO(FluHttpInterceptor*,httpInterceptor); Q_PROPERTY_AUTO(FluHttpInterceptor*,httpInterceptor);
@ -33,13 +34,12 @@ public:
Q_INVOKABLE void run(); Q_INVOKABLE void run();
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr); Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
Q_INVOKABLE void init(QQuickWindow *window); Q_INVOKABLE void init(QQuickWindow *window);
Q_INVOKABLE QJsonArray awesomelist(const QString& keyword = ""); Q_INVOKABLE void exit(int retCode = 0);
Q_INVOKABLE void closeApp(); void addWindow(QQuickWindow* window);
Q_INVOKABLE void deleteWindow(QQuickWindow* window); void removeWindow(QQuickWindow* window);
public:
QMap<quint64, QQuickWindow*> wnds;
private: private:
QWindow *appWindow; QMap<quint64, QQuickWindow*> _windows;
QWindow* _application;
}; };
#endif // FLUAPP_H #endif // FLUAPP_H

View File

@ -33,7 +33,7 @@ QMap<QString, QVariant> HttpRequest::toMap(){
if(headers().isNull()){ if(headers().isNull()){
_headers = QMap<QString,QVariant>(); _headers = QMap<QString,QVariant>();
}else{ }else{
_params = params(); _headers = headers();
} }
QMap<QString, QVariant> request = { QMap<QString, QVariant> request = {
{"url",url()}, {"url",url()},
@ -110,11 +110,16 @@ void FluHttp::post(HttpRequest* r,HttpCallable* c){
part.setBody(value.toUtf8()); part.setBody(value.toUtf8());
multiPart.append(part); multiPart.append(part);
} }
QEventLoop loop;
QNetworkReply* reply = manager.post(req,&multiPart); QNetworkReply* reply = manager.post(req,&multiPart);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply); _cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();}); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();}); connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec(); loop.exec();
QString result = QString::fromUtf8(reply->readAll()); QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -169,11 +174,16 @@ void FluHttp::postString(HttpRequest* r,HttpCallable* c){
addHeaders(&req,data["headers"].toMap()); addHeaders(&req,data["headers"].toMap());
QString contentType = QString("text/plain;charset=utf-8"); QString contentType = QString("text/plain;charset=utf-8");
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType); req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(req,params.toUtf8()); QNetworkReply* reply = manager.post(req,params.toUtf8());
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply); _cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();}); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();}); connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec(); loop.exec();
QString result = QString::fromUtf8(reply->readAll()); QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -227,11 +237,16 @@ void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
addHeaders(&req,data["headers"].toMap()); addHeaders(&req,data["headers"].toMap());
QString contentType = QString("application/json;charset=utf-8"); QString contentType = QString("application/json;charset=utf-8");
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType); req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(req,QJsonDocument::fromVariant(data["params"]).toJson()); QNetworkReply* reply = manager.post(req,QJsonDocument::fromVariant(data["params"]).toJson());
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply); _cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();}); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();}); connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec(); loop.exec();
QString result = QString::fromUtf8(reply->readAll()); QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -284,11 +299,16 @@ void FluHttp::get(HttpRequest* r,HttpCallable* c){
addQueryParam(&url,data["params"].toMap()); addQueryParam(&url,data["params"].toMap());
QNetworkRequest req(url); QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap()); addHeaders(&req,data["headers"].toMap());
QEventLoop loop; QNetworkReply* reply = manager.get(req);
auto reply = QPointer(manager.get(req)); if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply); _cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();}); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();}); connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec(); loop.exec();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString(); QString errorString = reply->errorString();
@ -337,9 +357,6 @@ void FluHttp::download(HttpRequest* r,HttpCallable* c){
if (!dir.exists(dir.path())){ if (!dir.exists(dir.path())){
dir.mkpath(dir.path()); dir.mkpath(dir.path());
} }
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();});
qint64 seek = 0; qint64 seek = 0;
auto filePath = getCacheFilePath(httpId); auto filePath = getCacheFilePath(httpId);
QSharedPointer<QFile> fileCache(new QFile(filePath)); QSharedPointer<QFile> fileCache(new QFile(filePath));
@ -364,7 +381,15 @@ void FluHttp::download(HttpRequest* r,HttpCallable* c){
file->open(QIODevice::WriteOnly|QIODevice::Truncate); file->open(QIODevice::WriteOnly|QIODevice::Truncate);
} }
QNetworkReply* reply = manager.get(req); QNetworkReply* reply = manager.get(req);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply); _cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
if (!fileCache->open(QIODevice::WriteOnly|QIODevice::Truncate)) if (!fileCache->open(QIODevice::WriteOnly|QIODevice::Truncate))
{ {
qDebug()<<"FileCache Error"; qDebug()<<"FileCache Error";
@ -411,7 +436,6 @@ void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
QNetworkRequest req(url); QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap()); addHeaders(&req,data["headers"].toMap());
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType); QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
qDebug()<<data["params"].toMap();
for (const auto& each : data["params"].toMap().toStdMap()) for (const auto& each : data["params"].toMap().toStdMap())
{ {
const QString& key = each.first; const QString& key = each.first;
@ -426,11 +450,16 @@ void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
part.setBodyDevice(file); part.setBodyDevice(file);
multiPart.append(part); multiPart.append(part);
} }
QEventLoop loop;
QNetworkReply* reply = manager.post(req,&multiPart); QNetworkReply* reply = manager.post(req,&multiPart);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply); _cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();}); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();}); connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
connect(reply,&QNetworkReply::uploadProgress,reply,[=](qint64 bytesSent, qint64 bytesTotal){ connect(reply,&QNetworkReply::uploadProgress,reply,[=](qint64 bytesSent, qint64 bytesTotal){
onUploadProgress(callable,bytesSent,bytesTotal); onUploadProgress(callable,bytesSent,bytesTotal);
}); });
@ -450,6 +479,62 @@ void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
}); });
} }
void FluHttp::deleteResource(HttpRequest* request,HttpCallable* callable)
{
request->method("deleteResource");
auto requestMap = request->toMap();
auto httpId = request->httpId();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
onFinish(callable,request);
return;
}
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
for (int i = 0; i < retry(); ++i) {
QUrl url(request->url());
addQueryParam(&url,data["params"].toMap());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QEventLoop loop;
QNetworkReply* reply = manager.deleteResource(req);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();});
loop.exec();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
QString result = QString::fromUtf8(reply->readAll());
if (isSuccess) {
handleCache(httpId,result);
onSuccess(callable,result);
break;
}else{
if(i == retry()-1){
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
onError(callable,status,errorString,result);
}
}
QNetworkReply::NetworkError error = reply->error();
if(error == QNetworkReply::OperationCanceledError){
break;
}
reply->deleteLater();
reply = nullptr;
}
onFinish(callable,request);
});
}
QVariant FluHttp::invokeIntercept(QMap<QString, QVariant> request){ QVariant FluHttp::invokeIntercept(QMap<QString, QVariant> request){
if(!FluApp::getInstance()->httpInterceptor()){ if(!FluApp::getInstance()->httpInterceptor()){
return request; return request;
@ -498,11 +583,12 @@ bool FluHttp::cacheExists(const QString& httpId){
} }
QString FluHttp::getCacheFilePath(const QString& httpId){ QString FluHttp::getCacheFilePath(const QString& httpId){
QDir dir = _cacheDir; QString path = FluTools::getInstance()->toLocalPath(QUrl(_cacheDir));
if (!dir.exists(_cacheDir)){ QDir dir = path;
dir.mkpath(_cacheDir); if (!dir.exists(path)){
dir.mkpath(path);
} }
auto filePath = _cacheDir+"/"+httpId; auto filePath = path+"/"+httpId;
return filePath; return filePath;
} }

View File

@ -69,6 +69,7 @@ public:
Q_INVOKABLE void postJson(HttpRequest* request,HttpCallable* callable); Q_INVOKABLE void postJson(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void download(HttpRequest* request,HttpCallable* callable); Q_INVOKABLE void download(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void upload(HttpRequest* request,HttpCallable* callable); Q_INVOKABLE void upload(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void deleteResource(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE qreal getBreakPointProgress(HttpRequest* request); Q_INVOKABLE qreal getBreakPointProgress(HttpRequest* request);
Q_INVOKABLE void cancel(); Q_INVOKABLE void cancel();
private: private:

View File

@ -2,7 +2,6 @@
#include <QPainterPath> #include <QPainterPath>
FluRectangle::FluRectangle(QQuickItem* parent) : QQuickPaintedItem(parent){ FluRectangle::FluRectangle(QQuickItem* parent) : QQuickPaintedItem(parent){
setFlag(ItemHasContents, true);
color(QColor(255,255,255,255)); color(QColor(255,255,255,255));
radius({0,0,0,0}); radius({0,0,0,0});
connect(this,&FluRectangle::colorChanged,this,[=]{update();}); connect(this,&FluRectangle::colorChanged,this,[=]{update();});

View File

@ -36,6 +36,22 @@ bool FluTheme::eventFilter(QObject *obj, QEvent *event){
return false; return false;
} }
QJsonArray FluTheme::awesomeList(const QString& keyword){
QJsonArray arr;
QMetaEnum enumType = Fluent_Awesome::staticMetaObject.enumerator(Fluent_Awesome::staticMetaObject.indexOfEnumerator("Fluent_AwesomeType"));
for(int i=0; i < enumType.keyCount(); ++i){
QString name = enumType.key(i);
int icon = enumType.value(i);
if(keyword.isEmpty() || name.contains(keyword)){
QJsonObject obj;
obj.insert("name",name);
obj.insert("icon",icon);
arr.append(obj);
}
}
return arr;
}
bool FluTheme::systemDark(){ bool FluTheme::systemDark(){
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
return (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark); return (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark);

View File

@ -3,6 +3,8 @@
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include <QJsonArray>
#include <QJsonObject>
#include "FluColorSet.h" #include "FluColorSet.h"
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
@ -26,9 +28,10 @@ private:
bool systemDark(); bool systemDark();
public: public:
SINGLETONG(FluTheme) SINGLETONG(FluTheme)
Q_INVOKABLE QJsonArray awesomeList(const QString& keyword = "");
Q_SIGNAL void darkChanged();
static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();} static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
bool dark(); bool dark();
Q_SIGNAL void darkChanged();
private: private:
bool _dark; bool _dark;
bool _systemDark; bool _systemDark;

View File

@ -38,7 +38,7 @@ QVariant FluTreeModel::data(const QModelIndex &index, int role) const {
}; };
QHash<int, QByteArray> FluTreeModel::roleNames() const { QHash<int, QByteArray> FluTreeModel::roleNames() const {
return { {Qt::DisplayRole, "modelData"} }; return { {Qt::DisplayRole, "dataModel"} };
}; };
void FluTreeModel::setData(QList<Node*> data){ void FluTreeModel::setData(QList<Node*> data){

View File

@ -1,7 +1,7 @@
#include "FluentUI.h" #include "FluentUI.h"
#include <QGuiApplication> #include <QGuiApplication>
#include "WindowHelper.h" #include "WindowLifecycle.h"
#include "Def.h" #include "Def.h"
#include "FluApp.h" #include "FluApp.h"
#include "FluColors.h" #include "FluColors.h"
@ -42,7 +42,7 @@ void FluentUI::registerTypes(const char *uri){
#if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) #if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))
Q_INIT_RESOURCE(fluentui); Q_INIT_RESOURCE(fluentui);
#endif #endif
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper"); qmlRegisterType<WindowLifecycle>(uri,major,minor,"WindowLifecycle");
qmlRegisterType<QRCode>(uri,major,minor,"QRCode"); qmlRegisterType<QRCode>(uri,major,minor,"QRCode");
qmlRegisterType<FluCaptcha>(uri,major,minor,"FluCaptcha"); qmlRegisterType<FluCaptcha>(uri,major,minor,"FluCaptcha");
qmlRegisterType<FluWatermark>(uri,major,minor,"FluWatermark"); qmlRegisterType<FluWatermark>(uri,major,minor,"FluWatermark");

View File

@ -197,23 +197,14 @@ Rectangle {
} }
function _hsla(h, s, b, a) { function _hsla(h, s, b, a) {
if(!enableAlphaChannel){
a = 1
}
var lightness = (2 - s)*b var lightness = (2 - s)*b
var satHSL = s*b/((lightness <= 1) ? lightness : 2 - lightness) var satHSL = s*b/((lightness <= 1) ? lightness : 2 - lightness)
lightness /= 2 lightness /= 2
var c = Qt.hsla(h, satHSL, lightness, a) var c = Qt.hsla(h, satHSL, lightness, a)
colorChanged(c) colorChanged(c)
return c
}
function _rgb(rgb, a) {
var c = Qt.rgba(rgb.r, rgb.g, rgb.b, a)
colorChanged(c)
return c return c
} }

View File

@ -164,21 +164,16 @@ Rectangle{
onClicked: closeClickListener() onClicked: closeClickListener()
} }
} }
function minimizeButton(){ function minimizeButton(){
return btn_minimize return btn_minimize
} }
function maximizeButton(){ function maximizeButton(){
return btn_maximize return btn_maximize
} }
function closeButton(){ function closeButton(){
return btn_close return btn_close
} }
function darkButton(){ function darkButton(){
return btn_dark return btn_dark
} }
} }

View File

@ -72,7 +72,7 @@ Rectangle {
height: container.height height: container.height
width: container.width width: container.width
modal: true modal: true
dim:false Overlay.modal: Item {}
enter: Transition { enter: Transition {
reversible: true reversible: true
NumberAnimation { NumberAnimation {

View File

@ -1,9 +1,10 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Window 2.15
import "./../JS/Chart.js" as Chart import "./../JS/Chart.js" as Chart
Canvas { Canvas {
id: control id: control
property var window: Window.window
property var jsChart: undefined property var jsChart: undefined
property string chartType property string chartType
property var chartData property var chartData

View File

@ -26,6 +26,7 @@ Button {
property var clickListener : function(){ property var clickListener : function(){
checked = !checked checked = !checked
} }
property bool indeterminate : false
id:control id:control
enabled: !disabled enabled: !disabled
onClicked: clickListener() onClicked: clickListener()
@ -98,11 +99,26 @@ Button {
duration: 83 duration: 83
} }
} }
FluIcon {
anchors.centerIn: parent
iconSource: FluentIcons.CheckboxIndeterminate
iconSize: 14
visible: indeterminate
iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
Behavior on visible {
enabled: control.enableAnimation
NumberAnimation{
duration: 83
}
}
}
FluIcon { FluIcon {
anchors.centerIn: parent anchors.centerIn: parent
iconSource: FluentIcons.AcceptMedium iconSource: FluentIcons.AcceptMedium
iconSize: 15 iconSize: 14
visible: checked visible: checked && !indeterminate
iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1) iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
Behavior on visible { Behavior on visible {
enabled: control.enableAnimation enabled: control.enableAnimation

View File

@ -11,6 +11,7 @@ Button{
implicitWidth: width implicitWidth: width
implicitHeight: height implicitHeight: height
property alias colorValue: container.colorValue property alias colorValue: container.colorValue
property alias enableAlphaChannel: container.enableAlphaChannel
background: background:
Rectangle{ Rectangle{
id:layout_color id:layout_color
@ -27,7 +28,7 @@ Button{
anchors.fill: parent anchors.fill: parent
anchors.margins: 4 anchors.margins: 4
radius: 5 radius: 5
color: container.colorValue color: control.colorValue
} }
} }
@ -42,7 +43,7 @@ Button{
Menu{ Menu{
id:popup id:popup
modal: true modal: true
dim:false Overlay.modal: Item {}
height: container.height height: container.height
width: container.width width: container.width
contentItem: Item{ contentItem: Item{

View File

@ -6,6 +6,7 @@ import "ColorPicker"
Item { Item {
id:control id:control
property alias colorValue: color_picker.colorValue property alias colorValue: color_picker.colorValue
property alias enableAlphaChannel: color_picker.enableAlphaChannel
property int radius: 5 property int radius: 5
width: color_picker.width+10 width: color_picker.width+10
height: color_picker.height height: color_picker.height

View File

@ -11,6 +11,7 @@ FluPopup {
property string neutralText: "Neutral" property string neutralText: "Neutral"
property string negativeText: "Negative" property string negativeText: "Negative"
property string positiveText: "Positive" property string positiveText: "Positive"
property alias messageTextFormart: text_message.textFormat
property int delayTime: 100 property int delayTime: 100
signal neutralClicked signal neutralClicked
signal negativeClicked signal negativeClicked
@ -24,6 +25,9 @@ FluPopup {
anchors.fill: parent anchors.fill: parent
color: 'transparent' color: 'transparent'
radius:5 radius:5
FluShadow{
radius: 5
}
FluText{ FluText{
id:text_title id:text_title
font: FluTextStyle.TitleLarge font: FluTextStyle.TitleLarge
@ -41,6 +45,7 @@ FluPopup {
Flickable{ Flickable{
id:sroll_message id:sroll_message
contentWidth: width contentWidth: width
clip: true
anchors{ anchors{
top:text_title.bottom top:text_title.bottom
left: parent.left left: parent.left

View File

@ -106,7 +106,7 @@ Rectangle {
modal: true modal: true
width: container.width width: container.width
height: container.height height: container.height
dim:false Overlay.modal: Item {}
enter: Transition { enter: Transition {
reversible: true reversible: true
NumberAnimation { NumberAnimation {

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