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

@ -34,7 +34,7 @@ function(get_git_head_revision _refspecvar _hashvar)
endif()
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
set(GIT_DIR "")
endif()
@ -52,23 +52,23 @@ function(get_git_head_revision _refspecvar _hashvar)
if(NOT IS_DIRECTORY ${GIT_DIR})
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse
--show-superproject-working-tree
--show-superproject-working-tree
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${out}" STREQUAL "")
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
${submodule})
${submodule})
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
ABSOLUTE)
ABSOLUTE)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
file(READ ${GIT_DIR} worktree_ref)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${worktree_ref})
${worktree_ref})
string(STRIP ${git_worktree_dir} git_worktree_dir)
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
@ -88,7 +88,7 @@ function(get_git_head_revision _refspecvar _hashvar)
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar}
@ -299,12 +299,12 @@ git_describe(GIT_DESCRIBE)
git_commit_counts(GIT_COMMIT_COUNT)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
if(NOT IS_DIRECTORY ${GIT_DIR})
message(STATUS "Current .git not exist")
set(GIT_COMMIT_COUNT "1")
set(GIT_DESCRIBE "1.0.0")
set(GIT_TAG "1.0.0")
message(STATUS "Current .git not exist")
set(GIT_COMMIT_COUNT "1")
set(GIT_DESCRIBE "1.0.0")
set(GIT_TAG "1.0.0")
else()
message(STATUS "Current .git exist")
message(STATUS "Current .git exist")
endif()
string(REPLACE "." "," GIT_TAG_WITH_COMMA ${GIT_TAG})
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" GIT_SEMVER "${GIT_TAG}")

View File

@ -1,43 +1,21 @@
#
# 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)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

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 }}
cache: ${{steps.cache-qt.outputs.cache-hit}}
arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats qt3d'
- name: Set up Ninja
uses: seanmiddleditch/gha-setup-ninja@v3

View File

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

View File

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

View File

@ -6,14 +6,14 @@ on:
- 'src/**'
- 'example/**'
- 'scripts/**'
- '.github/workflows/windows_qt5.yml'
- '.github/workflows/windows-qt5.yml'
pull_request:
paths:
- '*.txt'
- 'example/**'
- 'src/**'
- 'scripts/**'
- '.github/workflows/windows_qt5.yml'
- '.github/workflows/windows-qt5.yml'
jobs:
build:
@ -72,14 +72,20 @@ jobs:
- uses: actions/upload-artifact@v2
with:
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
if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ steps.package.outputs.packageName }}.zip
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip
file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }}
overwrite: true
overwrite: true

View File

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

5
.gitignore vendored
View File

@ -37,4 +37,7 @@ build
cmake-build-*
.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)
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)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
@ -32,14 +31,12 @@ if (FLUENTUI_BUILD_EXAMPLES)
add_subdirectory(example)
endif ()
if (FLUENTUI_BUILD_FRAMELESSHEPLER)
set(FRAMELESSHELPER_BUILD_STATIC ON)
set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON)
add_subdirectory(framelesshelper)
endif ()
set(FRAMELESSHELPER_BUILD_STATIC ON)
set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON)
set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
add_subdirectory(framelesshelper)
message("------------------------ FluentUI ------------------------")
message("Build FluentUI demo applications.: ${FLUENTUI_BUILD_EXAMPLES}")
message("Build FramelessHelper.: ${FLUENTUI_BUILD_FRAMELESSHEPLER}")
message("Build static library.: ${FLUENTUI_BUILD_STATIC_LIB}")
message("Path to FluentUI plugin.: ${FLUENTUI_QML_PLUGIN_DIRECTORY}")

View File

@ -6,7 +6,7 @@
QML FluentUI
</h1>
<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>
![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)
#遍历所有资源文件
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})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND resource_files ${filename})
endforeach(filepath)
endif()
#如果是Windows平台则生成rc文件
#如果是Windows平台则生成rc文件还有inno setup脚本文件
set(EXAMPLE_VERSION_RC_PATH "")
if(WIN32)
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
${EXAMPLE_VERSION_RC_PATH}
)
configure_file(
${FLUENTUI_DIRECTORY}/.cmake/InstallerScript.iss.in
${CMAKE_SOURCE_DIR}/action-cli/InstallerScript.iss
)
endif()
#添加可执行文件
@ -100,9 +104,9 @@ if(WIN32)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(3RDPARTY_ARCH_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Win_x64)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
if(MSVC)
set(DLLPATH ${3RDPARTY_ARCH_DIR}/msvc/*.dll)
else()
elseif(MINGW)
set(DLLPATH ${3RDPARTY_ARCH_DIR}/mingw/*.dll)
endif()
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
@ -156,8 +160,6 @@ target_link_libraries(example PRIVATE
Qt${QT_VERSION_MAJOR}::Svg
Qt${QT_VERSION_MAJOR}::Network
fluentuiplugin
FramelessHelper::Core
FramelessHelper::Quick
)
#安装

View File

@ -123,7 +123,6 @@
<file>res/image/qrcode_zfb.jpg</file>
<file>qml/App.qml</file>
<file>qml/component/CodeExpander.qml</file>
<file>qml/component/CustomWindow.qml</file>
<file>qml/global/ItemsFooter.qml</file>
<file>qml/global/ItemsOriginal.qml</file>
<file>qml/global/qmldir</file>
@ -187,5 +186,8 @@
<file>qml/page/T_StaggeredView.qml</file>
<file>qml/viewmodel/SettingsViewModel.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>
</RCC>

View File

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

View File

@ -139,7 +139,8 @@ FluExpander{
"FluRangeSlider",
"FluStaggeredView",
"FluProgressButton",
"FluLoadingButton"
"FluLoadingButton",
"FluClip"
];
code = code.replace(/\n/g, "<br>");
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{}
FluPaneItem{
title:lang.about
title:Lang.about
icon:FluentIcons.Contact
onDropped: { FluApp.navigate("/about") }
onTapListener:function(){
@ -21,7 +21,7 @@ FluObject{
}
FluPaneItem{
title:lang.settings
title:Lang.settings
icon:FluentIcons.Settings
url:"qrc:/example/qml/page/T_Settings.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }

View File

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

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

View File

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

View File

@ -11,27 +11,35 @@ FluScrollablePage{
FluArea{
Layout.fillWidth: true
height: 68
height: 72
paddings: 10
Layout.topMargin: 20
FluText{
text:"A 2-state CheckBox"
}
Row{
spacing: 30
anchors.verticalCenter: parent.verticalCenter
FluCheckBox{
disabled: check_box_switch.checked
anchors{
top: parent.top
topMargin: 30
}
FluCheckBox{
disabled: check_box_switch.checked
disabled: check_box_switch_two.checked
}
FluCheckBox{
disabled: check_box_switch_two.checked
text:"Right"
}
FluCheckBox{
disabled: check_box_switch.checked
disabled: check_box_switch_two.checked
text:"Left"
textRight: false
}
}
FluToggleSwitch{
id:check_box_switch
id:check_box_switch_two
anchors{
right: parent.right
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
height: parent.height
contentWidth: width
boundsBehavior: Flickable.StopAtBounds
contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {}
FluText{

View File

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

View File

@ -12,16 +12,15 @@ FluScrollablePage{
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 460
height: 80
paddings: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
verticalCenter: parent.verticalCenter
}
RowLayout{
Layout.topMargin: 20
FluRectangle{
@ -61,70 +60,6 @@ FluScrollablePage{
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{
@ -134,14 +69,6 @@ FluScrollablePage{
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

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

View File

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

View File

@ -7,12 +7,45 @@ import "qrc:///example/qml/component"
FluContentPage{
id:root
title:"TableView"
signal checkBoxChanged
property var dataSource : []
property int sortType: 0
Component.onCompleted: {
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{
id:com_action
Item{
@ -23,11 +56,15 @@ FluContentPage{
onClicked: {
table_view.closeEditor()
tableModel.removeRow(row)
checkBoxChanged()
}
}
FluFilledButton{
text:"编辑"
onClicked: {
var obj = tableModel.getRow(row)
obj.name = "12345"
tableModel.setRow(row,obj)
showSuccess(JSON.stringify(tableModel.getRow(row)))
}
}
@ -35,39 +72,44 @@ FluContentPage{
}
}
function loadData(page,count){
var numbers = [100, 300, 500, 1000];
function getRandomAge() {
var randomIndex = Math.floor(Math.random() * numbers.length);
return numbers[randomIndex];
Component{
id:com_column_checbox
Item{
RowLayout{
anchors.centerIn: parent
FluText{
text:"全选"
Layout.alignment: Qt.AlignVCenter
}
FluCheckBox{
checked: true === options.checked
enableAnimation: false
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 names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"];
function getRandomName(){
var randomIndex = Math.floor(Math.random() * names.length);
return names[randomIndex];
}
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
}
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
}
const dataSource = []
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{
@ -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{
id:table_view
anchors{
@ -104,13 +228,27 @@ FluContentPage{
}
anchors.topMargin: 20
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: '姓名',
dataIndex: 'name',
readOnly:true,
},
{
title: '年龄',
title: table_view.customItem(com_column_sort_age,{sort:0}),
dataIndex: 'age',
editDelegate:com_combobox,
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也都懂一丢丢什么都会什么都不精通钱途无望"
}
ListElement{
lable:"2020-06-01"
lable:"2021-06-01"
text:"由于某个项目紧急临时加入Qt项目组就因为大学学了点C++),本来是想进去打个酱油,到后面竟然成开发主力,坑啊"
}
ListElement{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -139,7 +139,8 @@ FluExpander{
"FluRangeSlider",
"FluStaggeredView",
"FluProgressButton",
"FluLoadingButton"
"FluLoadingButton",
"FluClip"
];
code = code.replace(/\n/g, "<br>");
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{}
FluPaneItem{
title:lang.about
title:Lang.about
icon:FluentIcons.Contact
onDropped: { FluApp.navigate("/about") }
onTapListener:function(){
@ -21,7 +21,7 @@ FluObject{
}
FluPaneItem{
title:lang.settings
title:Lang.settings
icon:FluentIcons.Settings
url:"qrc:/example/qml/page/T_Settings.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }

View File

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

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

View File

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

View File

@ -12,27 +12,35 @@ FluScrollablePage{
FluArea{
Layout.fillWidth: true
height: 68
height: 72
paddings: 10
Layout.topMargin: 20
FluText{
text:"A 2-state CheckBox"
}
Row{
spacing: 30
anchors.verticalCenter: parent.verticalCenter
FluCheckBox{
disabled: check_box_switch.checked
anchors{
top: parent.top
topMargin: 30
}
FluCheckBox{
disabled: check_box_switch.checked
disabled: check_box_switch_two.checked
}
FluCheckBox{
disabled: check_box_switch_two.checked
text:"Right"
}
FluCheckBox{
disabled: check_box_switch.checked
disabled: check_box_switch_two.checked
text:"Left"
textRight: false
}
}
FluToggleSwitch{
id:check_box_switch
id:check_box_switch_two
anchors{
right: parent.right
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
height: parent.height
contentWidth: width
boundsBehavior: Flickable.StopAtBounds
contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {}
FluText{

View File

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

View File

@ -13,16 +13,15 @@ FluScrollablePage{
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 460
height: 80
paddings: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
verticalCenter: parent.verticalCenter
}
RowLayout{
Layout.topMargin: 20
FluRectangle{
@ -62,70 +61,6 @@ FluScrollablePage{
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{
@ -135,14 +70,6 @@ FluScrollablePage{
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

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

View File

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

View File

@ -8,12 +8,45 @@ import "../component"
FluContentPage{
id:root
title:"TableView"
signal checkBoxChanged
property var dataSource : []
property int sortType: 0
Component.onCompleted: {
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{
id:com_action
Item{
@ -24,11 +57,15 @@ FluContentPage{
onClicked: {
table_view.closeEditor()
tableModel.removeRow(row)
checkBoxChanged()
}
}
FluFilledButton{
text:"编辑"
onClicked: {
var obj = tableModel.getRow(row)
obj.name = "12345"
tableModel.setRow(row,obj)
showSuccess(JSON.stringify(tableModel.getRow(row)))
}
}
@ -36,39 +73,44 @@ FluContentPage{
}
}
function loadData(page,count){
var numbers = [100, 300, 500, 1000];
function getRandomAge() {
var randomIndex = Math.floor(Math.random() * numbers.length);
return numbers[randomIndex];
Component{
id:com_column_checbox
Item{
RowLayout{
anchors.centerIn: parent
FluText{
text:"全选"
Layout.alignment: Qt.AlignVCenter
}
FluCheckBox{
checked: true === options.checked
enableAnimation: false
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 names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"];
function getRandomName(){
var randomIndex = Math.floor(Math.random() * names.length);
return names[randomIndex];
}
var nicknames = ["复海大圣","混天大圣","移山大圣","通风大圣","驱神大圣","齐天大圣","平天大圣"]
function getRandomNickname(){
var randomIndex = Math.floor(Math.random() * nicknames.length);
return nicknames[randomIndex];
}
var addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length);
return addresses[randomIndex];
}
const dataSource = []
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{
@ -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{
id:table_view
anchors{
@ -105,13 +229,27 @@ FluContentPage{
}
anchors.topMargin: 20
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: '姓名',
dataIndex: 'name',
readOnly:true,
},
{
title: '年龄',
title: table_view.customItem(com_column_sort_age,{sort:0}),
dataIndex: 'age',
editDelegate:com_combobox,
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也都懂一丢丢什么都会什么都不精通钱途无望"
}
ListElement{
lable:"2020-06-01"
lable:"2021-06-01"
text:"由于某个项目紧急临时加入Qt项目组就因为大学学了点C++),本来是想进去打个酱油,到后面竟然成开发主力,坑啊"
}
ListElement{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,39 +3,14 @@
#include <QQmlContext>
#include <QDebug>
#include <QGuiApplication>
#include "lang/En.h"
#include "lang/Zh.h"
#include "Version.h"
AppInfo::AppInfo(QObject *parent)
: QObject{parent}
{
version(APPLICATION_VERSION);
lang(new En());
}
void AppInfo::init(QQmlApplicationEngine *engine){
QQmlContext * context = 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);
engine->rootContext();
}

View File

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

View File

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

View File

@ -20,9 +20,11 @@ public:
~SettingsHelper() override;
void init(char *argv[]);
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 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:
void save(const QString& key,QVariant val);
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 <QSslConfiguration>
#include <QProcess>
#include <FramelessHelper/Quick/framelessquickmodule.h>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include <QtQml/qqmlextensionplugin.h>
#include <QLoggingCategory>
#include "AppInfo.h"
#include "src/component/CircularReveal.h"
#include "src/component/FileWatcher.h"
@ -22,11 +21,9 @@ Q_IMPORT_QML_PLUGIN(FluentUIPlugin)
#include <FluentUI.h>
#endif
FRAMELESSHELPER_USE_NAMESPACE
int main(int argc, char *argv[])
{
SettingsHelper::getInstance()->init(argv);
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
@ -35,11 +32,11 @@ int main(int argc, char *argv[])
#endif
#endif
qputenv("QT_QUICK_CONTROLS_STYLE","Basic");
FramelessHelper::Quick::initialize();
QGuiApplication::setOrganizationName("ZhuZiChu");
QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io");
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))
QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
@ -47,22 +44,12 @@ int main(int argc, char *argv[])
#endif
}
QGuiApplication app(argc, argv);
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::ForceHideWindowFrameBorder);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow,false);
#endif
#ifdef Q_OS_MACOS
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
#endif
// QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.general=true"));
// qSetMessagePattern("%{category}: %{message}");
QQmlApplicationEngine engine;
AppInfo::getInstance()->init(&engine);
engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance());
engine.rootContext()->setContextProperty("SettingsHelper",SettingsHelper::getInstance());
FramelessHelper::Quick::registerTypes(&engine);
#ifdef FLUENTUI_BUILD_STATIC_LIB
FluentUI::getInstance()->registerTypes(&engine);
#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() {
New-Item -ItemType Directory $archiveName
New-Item -ItemType Directory dist
# 拷贝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")
Remove-Item -Path $archiveName -Include $excludeList -Recurse -Force
Remove-Item -Path dist -Include $excludeList -Recurse -Force
# 打包zip
Compress-Archive -Path $archiveName $archiveName'.zip'
Compress-Archive -Path dist $archiveName'.zip'
}
if ($null -eq $archiveName || $null -eq $targetName) {

View File

@ -25,22 +25,22 @@ Write-Host "scriptDir" $scriptDir
function Main() {
New-Item -ItemType Directory $archiveName
New-Item -ItemType Directory dist
# 拷贝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")
Remove-Item -Path $archiveName -Include $excludeList -Recurse -Force
Remove-Item -Path dist -Include $excludeList -Recurse -Force
# 拷贝vcRedist dll
$redistDll="{0}{1}\*.CRT\*.dll" -f $env:vcToolsRedistDir.Trim(),$env:msvcArch
Copy-Item $redistDll $archiveName\
Copy-Item $redistDll dist\
# 拷贝WinSDK dll
$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
Compress-Archive -Path $archiveName $archiveName'.zip'
Compress-Archive -Path dist $archiveName'.zip'
}
if ($null -eq $archiveName || $null -eq $targetName) {

View File

@ -120,8 +120,17 @@ else()
)
endif()
#去掉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
@ -129,6 +138,8 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
Qt${QT_VERSION_MAJOR}::QuickPrivate
Qt${QT_VERSION_MAJOR}::QmlPrivate
ZXing
FramelessHelper::Core
FramelessHelper::Quick
)
#安装

View File

@ -8,9 +8,13 @@
#include <QUuid>
#include <QFontDatabase>
#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}{
vsync(false);
httpInterceptor(nullptr);
}
@ -18,7 +22,20 @@ FluApp::~FluApp(){
}
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(){
@ -30,7 +47,7 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
qCritical()<<"No route found "<<route;
return;
}
QQmlEngine *engine = qmlEngine(appWindow);
QQmlEngine *engine = qmlEngine(_application);
QQmlComponent component(engine, routes().value(route).toString());
if (component.isError()) {
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("argument",argument);
QQuickWindow *view=nullptr;
for (auto& pair : wnds) {
QString r = pair->property("_route").toString();
QQuickWindow *win=nullptr;
for (const auto& pair : _windows.toStdMap()) {
QString r = pair.second->property("_route").toString();
if(r == route){
view = pair;
win = pair.second;
break;
}
}
if(view){
//如果窗口存在,则判断启动模式
int launchMode = view->property("launchMode").toInt();
if(win){
int launchMode = win->property("launchMode").toInt();
if(launchMode == 1){
view->setProperty("argument",argument);
view->show();
view->raise();
view->requestActivate();
win->setProperty("argument",argument);
win->show();
win->raise();
win->requestActivate();
return;
}else if(launchMode == 2){
view->close();
win->close();
}
}
view = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties));
wnds.insert(view->winId(),view);
win = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties));
if(fluRegister){
fluRegister->to(view);
fluRegister->to(win);
}
view->setColor(QColor(Qt::transparent));
win->setColor(QColor(Qt::transparent));
}
QJsonArray FluApp::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()){
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);
}
}
void FluApp::exit(int retCode){
for (const auto& pair : _windows.toStdMap()) {
removeWindow(pair.second);
}
return arr;
qApp->exit(retCode);
}
void FluApp::closeApp(){
qApp->exit(0);
void FluApp::addWindow(QQuickWindow* window){
_windows.insert(window->winId(),window);
}
void FluApp::deleteWindow(QQuickWindow* window){
void FluApp::removeWindow(QQuickWindow* window){
if(window){
wnds.remove(window->winId());
_windows.remove(window->winId());
window->deleteLater();
window = nullptr;
}

View File

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

View File

@ -33,7 +33,7 @@ QMap<QString, QVariant> HttpRequest::toMap(){
if(headers().isNull()){
_headers = QMap<QString,QVariant>();
}else{
_params = params();
_headers = headers();
}
QMap<QString, QVariant> request = {
{"url",url()},
@ -110,11 +110,16 @@ void FluHttp::post(HttpRequest* r,HttpCallable* c){
part.setBody(value.toUtf8());
multiPart.append(part);
}
QEventLoop loop;
QNetworkReply* reply = manager.post(req,&multiPart);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
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();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -169,11 +174,16 @@ void FluHttp::postString(HttpRequest* r,HttpCallable* c){
addHeaders(&req,data["headers"].toMap());
QString contentType = QString("text/plain;charset=utf-8");
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(req,params.toUtf8());
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
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();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -227,11 +237,16 @@ void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
addHeaders(&req,data["headers"].toMap());
QString contentType = QString("application/json;charset=utf-8");
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(req,QJsonDocument::fromVariant(data["params"]).toJson());
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
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();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -284,11 +299,16 @@ void FluHttp::get(HttpRequest* r,HttpCallable* c){
addQueryParam(&url,data["params"].toMap());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QEventLoop loop;
auto reply = QPointer(manager.get(req));
QNetworkReply* reply = manager.get(req);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
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();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
@ -337,9 +357,6 @@ void FluHttp::download(HttpRequest* r,HttpCallable* c){
if (!dir.exists(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;
auto filePath = getCacheFilePath(httpId);
QSharedPointer<QFile> fileCache(new QFile(filePath));
@ -364,7 +381,15 @@ void FluHttp::download(HttpRequest* r,HttpCallable* c){
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
}
QNetworkReply* reply = manager.get(req);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_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))
{
qDebug()<<"FileCache Error";
@ -411,7 +436,6 @@ void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
qDebug()<<data["params"].toMap();
for (const auto& each : data["params"].toMap().toStdMap())
{
const QString& key = each.first;
@ -426,11 +450,16 @@ void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
part.setBodyDevice(file);
multiPart.append(part);
}
QEventLoop loop;
QNetworkReply* reply = manager.post(req,&multiPart);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
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){
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){
if(!FluApp::getInstance()->httpInterceptor()){
return request;
@ -498,11 +583,12 @@ bool FluHttp::cacheExists(const QString& httpId){
}
QString FluHttp::getCacheFilePath(const QString& httpId){
QDir dir = _cacheDir;
if (!dir.exists(_cacheDir)){
dir.mkpath(_cacheDir);
QString path = FluTools::getInstance()->toLocalPath(QUrl(_cacheDir));
QDir dir = path;
if (!dir.exists(path)){
dir.mkpath(path);
}
auto filePath = _cacheDir+"/"+httpId;
auto filePath = path+"/"+httpId;
return filePath;
}

View File

@ -69,6 +69,7 @@ public:
Q_INVOKABLE void postJson(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void download(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 void cancel();
private:

View File

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

View File

@ -36,6 +36,22 @@ bool FluTheme::eventFilter(QObject *obj, QEvent *event){
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(){
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
return (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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