Compare commits

..

15 Commits
1.4.0 ... 1.5.1

Author SHA1 Message Date
73518fb831 update 2023-08-10 16:22:43 +08:00
312aebae73 update 2023-08-10 16:08:27 +08:00
3c349da98f update 2023-08-08 21:59:18 +08:00
dba7332d89 update 2023-08-08 21:57:08 +08:00
3fefb08140 update 2023-08-08 21:33:16 +08:00
1c69d5daab update 2023-08-08 21:31:33 +08:00
ec76240aed update 2023-08-08 21:03:15 +08:00
0a967ca47b update 2023-08-08 20:21:32 +08:00
8dbbf4e547 update 2023-08-08 19:59:06 +08:00
ebad24e809 update 2023-08-08 15:44:10 +08:00
b7acae1470 update 2023-08-07 22:11:08 +08:00
f8340bdf59 update 2023-08-07 21:46:54 +08:00
e4fb9989d0 update 2023-08-07 18:18:04 +08:00
9bd98c68e4 Merge pull request #232 from FeJQ/FluNavigationView-pr
给FluPaneItemSeparator增加spacing和size属性
2023-08-04 12:05:15 +08:00
7cd9b7c6bc 给FluPaneItemSeparator增加spacing和size属性 2023-08-03 18:14:52 +08:00
34 changed files with 1258 additions and 237 deletions

View File

@ -0,0 +1,308 @@
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(_git_find_closest_git_dir _start_dir _git_dir_var)
set(cur_dir "${_start_dir}")
set(git_dir "${_start_dir}/.git")
while(NOT EXISTS "${git_dir}")
set(git_previous_parent "${cur_dir}")
get_filename_component(cur_dir ${cur_dir} DIRECTORY)
if(cur_dir STREQUAL git_previous_parent)
set(${_git_dir_var}
""
PARENT_SCOPE)
return()
endif()
set(git_dir "${cur_dir}/.git")
endwhile()
set(${_git_dir_var}
"${git_dir}"
PARENT_SCOPE)
endfunction()
function(get_git_head_revision _refspecvar _hashvar)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
else()
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
endif()
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
set(GIT_DIR "")
endif()
endif()
if("${GIT_DIR}" STREQUAL "")
set(${_refspecvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
set(${_hashvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT IS_DIRECTORY ${GIT_DIR})
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse
--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})
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)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
file(READ ${GIT_DIR} worktree_ref)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${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")
endif()
else()
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar}
"${HEAD_REF}"
PARENT_SCOPE)
set(${_hashvar}
"${HEAD_HASH}"
PARENT_SCOPE)
endfunction()
function(git_latest_tag _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --abbrev=0 --tag
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "GIT-TAG-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_commit_counts _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-list HEAD --count
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "GIT-TAG-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_release_version _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" symbolic-ref --short -q HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
string(FIND ${out} "release/" found})
if(${out} MATCHES "^release/.+$")
string(REPLACE "release/" "" tmp_out ${out})
set(${_var} "${tmp_out}" PARENT_SCOPE)
else()
set(${_var} "" PARENT_SCOPE)
endif()
endfunction()
function(git_describe_working_tree _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var}
"CLEAN"
PARENT_SCOPE)
else()
set(${_var}
"DIRTY"
PARENT_SCOPE)
endif()
endfunction()
git_release_version(GIT_TAG)
git_get_exact_tag(GIT_EXACT_TAG)
if(GIT_TAG STREQUAL "")
git_latest_tag(GIT_TAG)
endif()
if(GIT_TAG STREQUAL "GIT-TAG-NOTFOUND")
set(GIT_TAG "1.0.0")
endif ()
git_describe(GIT_DESCRIBE)
git_commit_counts(GIT_COMMIT_COUNT)
string(REPLACE "." "," GIT_TAG_WITH_COMMA ${GIT_TAG})
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" GIT_SEMVER "${GIT_TAG}")
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" SEMVER_SPLITED "${GIT_SEMVER}")
set(MAJOR_VERSION ${CMAKE_MATCH_1})
set(MINOR_VERSION ${CMAKE_MATCH_2})
set(PATCH_VERSION ${CMAKE_MATCH_3})
MATH(EXPR VERSION_COUNTER "${MAJOR_VERSION} * 10000 + ${MINOR_VERSION} * 100 + ${PATCH_VERSION}")
message(STATUS "Current git tag: ${GIT_TAG}, commit count: ${GIT_COMMIT_COUNT}, describe: ${GIT_DESCRIBE}")
message(STATUS "Current semver: major: ${MAJOR_VERSION}, minor: ${MINOR_VERSION}, patch: ${PATCH_VERSION}, counter: ${VERSION_COUNTER}")

View File

@ -0,0 +1,43 @@
#
# 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()
else()
# detached HEAD
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)
endif()

12
.cmake/Version.h.in Normal file
View File

@ -0,0 +1,12 @@
// 应用程序版本信息
// 请勿修改此头文件,因为这个文件是自动生成的
#ifndef VERSION_H
#define VERSION_H
#include <QtGlobal>
#define APPLICATION_VERSION "${GIT_SEMVER}.${GIT_COMMIT_COUNT}"
#define VERSION_COUNTER ${GIT_COMMIT_COUNT}
#define COMMIT_HASH "${GIT_DESCRIBE}"
#endif // VERSION_H

32
.cmake/version_dll.rc.in Normal file
View File

@ -0,0 +1,32 @@
1 VERSIONINFO
FILEVERSION ${GIT_TAG_WITH_COMMA},${GIT_COMMIT_COUNT}
PRODUCTVERSION ${GIT_TAG_WITH_COMMA},${GIT_COMMIT_COUNT}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404b0"
BEGIN
VALUE "CompanyName", "ZhuZiChu"
VALUE "FileDescription", "${PROJECT_DESCRIPTION}"
VALUE "FileVersion", "${GIT_SEMVER}.${GIT_COMMIT_COUNT}"
VALUE "InternalName", "${PROJECT_NAME}.dll"
VALUE "LegalCopyright", "Copyright (C) 2023 ZhuZiChu. All rights reserved."
VALUE "OriginalFilename", "${PROJECT_NAME}.dll"
VALUE "ProductName", "${PROJECT_NAME}"
VALUE "ProductVersion", "${GIT_SEMVER}.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END

34
.cmake/version_exe.rc.in Normal file
View File

@ -0,0 +1,34 @@
1 VERSIONINFO
FILEVERSION ${GIT_TAG_WITH_COMMA},${GIT_COMMIT_COUNT}
PRODUCTVERSION ${GIT_TAG_WITH_COMMA},${GIT_COMMIT_COUNT}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404b0"
BEGIN
VALUE "CompanyName", "ZhuZiChu"
VALUE "FileDescription", "${PROJECT_DESCRIPTION}"
VALUE "FileVersion", "${GIT_SEMVER}.${GIT_COMMIT_COUNT}"
VALUE "InternalName", "${PROJECT_NAME}.exe"
VALUE "LegalCopyright", "Copyright (C) 2023 ZhuZiChu. All rights reserved."
VALUE "OriginalFilename", "${PROJECT_NAME}.exe"
VALUE "ProductName", "${PROJECT_NAME}"
VALUE "ProductVersion", "${GIT_SEMVER}.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
IDI_ICON1 ICON DISCARDABLE "${CMAKE_SOURCE_DIR}/example/favicon.ico"

3
.gitignore vendored
View File

@ -31,9 +31,10 @@ target_wrapper.*
# QtCreator CMake
CMakeLists.txt.user*
src/build-preset/plugins.qmltypes
bin
.DS_Store
build
cmake-build-*
.idea
example/Version.h

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "framelesshelper"]
path = framelesshelper
url = https://github.com/zhuzichu520/framelesshelper.git
[submodule "zxing-cpp"]
path = zxing-cpp
url = https://github.com/zhuzichu520/zxing-cpp.git

View File

@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.20)
project(FluentUI VERSION 0.1 LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/.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)
@ -13,6 +17,7 @@ if(NOT FLUENTUI_QML_PLUGIN_DIRECTORY)
endif()
add_subdirectory(src)
add_subdirectory(zxing-cpp)
if (FLUENTUI_BUILD_EXAMPLES)
add_subdirectory(example)

View File

@ -26,9 +26,6 @@ endif()
#获取文件路径分隔符(解决执行命令的时候有些平台会报错)
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
#设置版本号
add_definitions(-DVERSION=1,4,0,0)
find_package(Qt6 REQUIRED COMPONENTS Quick Svg Network)
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
@ -39,6 +36,13 @@ else()
set(CMAKE_AUTOUIC ON)
endif()
##生成版本信息头文件
set(HEADER_FILE_VERSION_PATH ${CMAKE_SOURCE_DIR}/example/Version.h)
configure_file(
${CMAKE_SOURCE_DIR}/.cmake/Version.h.in
${HEADER_FILE_VERSION_PATH}
)
#遍历所有Cpp文件
file(GLOB_RECURSE CPP_FILES *.cpp *.h)
foreach(filepath ${CPP_FILES})
@ -60,11 +64,21 @@ foreach(filepath ${RES_PATHS})
list(APPEND resource_files ${filename})
endforeach(filepath)
#如果是Windows平台则生成rc文件
set(EXAMPLE_VERSION_RC_PATH "")
if(WIN32)
set(EXAMPLE_VERSION_RC_PATH ${CMAKE_BINARY_DIR}/version_${PROJECT_NAME}.rc)
configure_file(
${CMAKE_SOURCE_DIR}/.cmake/version_exe.rc.in
${EXAMPLE_VERSION_RC_PATH}
)
endif()
#添加可执行文件
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if (WIN32)
qt_add_executable(example
${sources_files}
example.rc
${EXAMPLE_VERSION_RC_PATH}
)
else ()
qt_add_executable(example

View File

@ -1,42 +0,0 @@
#include <windows.h>
IDI_ICON1 ICON "favicon.ico"
#define STR(x) #x
#define VER_JOIN(a,b,c,d) STR(a.b.c.d)
#define VER_JOIN_(x) VER_JOIN x
#define VER_STR VER_JOIN_((VERSION))
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION
PRODUCTVERSION VERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Built by the FluentUI."
VALUE "CompanyName", "zhuzichu"
VALUE "FileDescription", "example"
VALUE "FileVersion", VER_STR
VALUE "InternalName", ""
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", ""
VALUE "ProductName", "example"
VALUE "ProductVersion", VER_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -38,7 +38,7 @@ FluExpander{
topMargin: 5
}
onClicked:{
FluTools.clipText(content.text)
FluTools.clipText(FluTools.html2PlantText(content.text))
showSuccess("复制成功")
}
}
@ -132,7 +132,9 @@ FluExpander{
"FluImage",
"FluSpinBox",
"FluHttp",
"FluWatermark"
"FluWatermark",
"FluTour",
"FluQRCode"
];
code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;");

View File

@ -323,9 +323,26 @@ FluObject{
}
}
FluPaneItemSeparator{
spacing:20
size:1
}
FluPaneItemExpander{
title:lang.other
icon:FluentIcons.Shop
FluPaneItem{
title:"QRCode"
onTap:{
navigationView.push("qrc:/example/qml/page/T_QRCode.qml")
}
}
FluPaneItem{
title:"Tour"
onTap:{
navigationView.push("qrc:/example/qml/page/T_Tour.qml")
}
}
FluPaneItem{
title:"Http"
onTap:{

View File

@ -9,6 +9,19 @@ FluScrollablePage{
title:"Carousel"
ListModel{
id:data_model
ListElement{
url:"qrc:/example/res/image/banner_1.jpg"
}
ListElement{
url:"qrc:/example/res/image/banner_2.jpg"
}
ListElement{
url:"qrc:/example/res/image/banner_3.jpg"
}
}
FluArea{
Layout.fillWidth: true
height: 370
@ -24,23 +37,95 @@ FluScrollablePage{
text:"轮播图支持无限轮播无限滑动用ListView实现的组件"
}
FluCarousel{
id:carousel
radius:[5,5,5,5]
delegate: Component{
Image {
anchors.fill: parent
source: model.url
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
}
Layout.topMargin: 20
Layout.leftMargin: 5
Component.onCompleted: {
carousel.setData([{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}])
model = [{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}]
}
}
}
}
FluArea{
Layout.fillWidth: true
height: 340
paddings: 10
Layout.topMargin: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left:parent.left
}
FluCarousel{
radius:[15,15,15,15]
loopTime:1500
indicatorGravity: Qt.AlignHCenter | Qt.AlignTop
indicatorMarginTop:15
delegate: Component{
Item{
anchors.fill: parent
Image {
anchors.fill: parent
source: model.url
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Rectangle{
height: 40
width: parent.width
anchors.bottom: parent.bottom
color: "#33000000"
FluText{
anchors.fill: parent
verticalAlignment: Qt.AlignVCenter
horizontalAlignment: Qt.AlignHCenter
text:model.title
color: FluColors.Grey10
font.pixelSize: 15
}
}
}
}
Layout.topMargin: 20
Layout.leftMargin: 5
Component.onCompleted: {
var arr = []
arr.push({url:"qrc:/example/res/image/banner_1.jpg",title:"共同应对全球性问题"})
arr.push({url:"qrc:/example/res/image/banner_2.jpg",title:"三小只全程没互动"})
arr.push({url:"qrc:/example/res/image/banner_3.jpg",title:"有效投资扩大 激发增长动能"})
model = arr
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCarousel{
id:carousel
width: 400
height: 300
delegate: Component{
Image {
anchors.fill: parent
source: model.url
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
}
Component.onCompleted: {
setData([{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}])
carousel.model = [{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}]
}
}'
}

View File

@ -0,0 +1,75 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import Qt5Compat.GraphicalEffects
import "qrc:///example/qml/component"
FluScrollablePage{
title:"QRCode"
FluQRCode{
id:qrcode
Layout.topMargin: 20
size:slider_size.value
text:text_box.text
color:color_picker.colorValue
Layout.preferredWidth: size
Layout.preferredHeight: size
}
RowLayout{
spacing: 10
Layout.topMargin: 20
FluText{
text:"text:"
Layout.alignment: Qt.AlignVCenter
}
FluTextBox{
id:text_box
text:"会磨刀的小猪"
}
}
RowLayout{
spacing: 10
Layout.topMargin: 10
FluText{
text:"color:"
Layout.alignment: Qt.AlignVCenter
}
FluColorPicker{
id:color_picker
Component.onCompleted: {
setColor(Qt.rgba(0,0,0,1))
}
}
}
RowLayout{
spacing: 10
FluText{
text:"size:"
Layout.alignment: Qt.AlignVCenter
}
FluSlider{
id:slider_size
from:60
to:260
value: 120
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: 20
code:'FluQRCode{
color:"red"
text:"会磨刀的小猪"
size:100
}'
}
}

View File

@ -0,0 +1,80 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "qrc:///example/qml/component"
FluScrollablePage{
title:"Tour"
FluTour{
id:tour
steps:[
{title:"Upload File",description: "Put your files here.",target:()=>btn_upload},
{title:"Save",description: "Save your changes.",target:()=>btn_save},
{title:"Other Actions",description: "Click to see other actions.",target:()=>btn_more}
]
}
FluArea{
Layout.fillWidth: true
height: 130
paddings: 10
Layout.topMargin: 20
FluFilledButton{
anchors{
top: parent.top
topMargin: 14
}
text:"Begin Tour"
onClicked: {
tour.open()
}
}
Row{
spacing: 20
anchors{
top: parent.top
topMargin: 60
}
FluButton{
id:btn_upload
text:"Upload"
onClicked: {
showInfo("Upload")
}
}
FluFilledButton{
id:btn_save
text:"Save"
onClicked: {
showInfo("Save")
}
}
FluIconButton{
id:btn_more
iconSource: FluentIcons.More
onClicked: {
showInfo("More")
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTour{
id:tour
steps:[
{title:"Upload File",description: "Put your files here.",target:()=>btn_upload},
{title:"Save",description: "Save your changes.",target:()=>btn_save},
{title:"Other Actions",description: "Click to see other actions.",target:()=>btn_more}
]
}'
}
}

View File

@ -27,6 +27,7 @@ CustomWindow {
Component.onCompleted: {
FluTools.setQuitOnLastWindowClosed(false)
tour.open()
}
SystemTrayIcon {
@ -146,6 +147,7 @@ CustomWindow {
visible: flipable.flipAngle !== 180
anchors.fill: flipable
FluAppBar {
id:app_bar_front
anchors {
top: parent.top
left: parent.left
@ -174,7 +176,8 @@ CustomWindow {
title:"FluentUI"
onLogoClicked:{
clickCount += 1
if(clickCount === 1){
showSuccess("点击%1次".arg(clickCount))
if(clickCount === 5){
loader.reload()
flipable.flipped = true
clickCount = 0
@ -258,4 +261,20 @@ CustomWindow {
}
}
Shortcut {
sequence: "F6"
context: Qt.WindowShortcut
onActivated: {
tour.open()
}
}
FluTour{
id:tour
steps:[
{title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>app_bar_front.darkButton()},
{title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()}
]
}
}

View File

@ -4,16 +4,12 @@
#include <QDebug>
#include "lang/En.h"
#include "lang/Zh.h"
#define STR(x) #x
#define VER_JOIN(a,b,c,d) STR(a.b.c.d)
#define VER_JOIN_(x) VER_JOIN x
#define VER_STR VER_JOIN_((VERSION))
#include "Version.h"
AppInfo::AppInfo(QObject *parent)
: QObject{parent}
{
version(VER_STR);
version(APPLICATION_VERSION);
lang(new En());
}

View File

@ -11,9 +11,6 @@ if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
#设置版本号
add_definitions(-DVERSION=1,4,0,0)
find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml)
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
@ -66,6 +63,16 @@ else()
set(PLUGIN_TARGET_NAME ${PROJECT_NAME})
endif()
#如果是Windows平台则生成rc文件
set(FLUENTUI_VERSION_RC_PATH "")
if(WIN32)
set(FLUENTUI_VERSION_RC_PATH ${CMAKE_BINARY_DIR}/version_${PROJECT_NAME}.rc)
configure_file(
${CMAKE_SOURCE_DIR}/.cmake/version_dll.rc.in
${FLUENTUI_VERSION_RC_PATH}
)
endif()
qt_add_qml_module(${PROJECT_NAME}
PLUGIN_TARGET ${PLUGIN_TARGET_NAME}
OUTPUT_DIRECTORY ${FLUENTUI_QML_PLUGIN_DIRECTORY}
@ -73,7 +80,7 @@ qt_add_qml_module(${PROJECT_NAME}
URI "FluentUI"
#修改qmltypes文件名称。默认fluentuiplugin.qmltypes使用默认名称有时候import FluentUI会爆红所以修改成plugins.qmltypes
TYPEINFO "plugins.qmltypes"
SOURCES ${sources_files} fluentui.rc
SOURCES ${sources_files} ${FLUENTUI_VERSION_RC_PATH}
QML_FILES ${qml_files}
RESOURCES ${resource_files}
)
@ -83,6 +90,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
Qt::CorePrivate
Qt::QuickPrivate
Qt::QmlPrivate
ZXing
)
#安装

View File

@ -32,8 +32,8 @@ void FluHttp::handleReply(QNetworkReply* reply){
_cache.append(reply);
}
void FluHttp::post(QString url,QJSValue callable,QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"post").toMap();
void FluHttp::post(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"post").toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
for (int i = 0; i < retry(); ++i) {
@ -82,8 +82,8 @@ void FluHttp::post(QString url,QJSValue callable,QVariantMap params,QVariantMap
});
}
void FluHttp::postString(QString url,QJSValue callable,QString params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"postString").toMap();
void FluHttp::postString(QString url,QJSValue callable,QString params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"postString").toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
for (int i = 0; i < retry(); ++i) {
@ -121,8 +121,8 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QVariantMa
});
}
void FluHttp::postJson(QString url,QJSValue callable,QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"postJson").toMap();
void FluHttp::postJson(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"postJson").toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
for (int i = 0; i < retry(); ++i) {
@ -160,8 +160,8 @@ void FluHttp::postJson(QString url,QJSValue callable,QVariantMap params,QVariant
});
}
void FluHttp::get(QString url,QJSValue callable,QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"get").toMap();
void FluHttp::get(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"get").toMap();
QThreadPool::globalInstance()->start([=](){
for (int i = 0; i < retry(); ++i) {
onStart(callable);
@ -198,8 +198,8 @@ void FluHttp::get(QString url,QJSValue callable,QVariantMap params,QVariantMap h
});
}
void FluHttp::download(QString url,QJSValue callable,QString filePath,QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"download").toMap();
void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"download").toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
QNetworkAccessManager manager;
@ -239,7 +239,7 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QVariantMa
}
QVariant FluHttp::invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method){
QVariantMap requet = {
QMap<QString, QVariant> requet = {
{"params",params},
{"headers",headers},
{"method",method}

View File

@ -26,11 +26,12 @@ private:
public:
explicit FluHttp(QObject *parent = nullptr);
~FluHttp();
Q_INVOKABLE void get(QString url,QJSValue callable,QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void post(QString url,QJSValue callable,QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void postString(QString url,QJSValue callable,QString params = "",QVariantMap headers = {});
Q_INVOKABLE void postJson(QString url,QJSValue callable,QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void download(QString url,QJSValue callable,QString filePath,QVariantMap params = {},QVariantMap headers = {});
//神坑!!! 如果参数使用QVariantMap会有问题在6.4.3版本中QML一调用就会编译失败。所以改用QMap<QString, QVariant>
Q_INVOKABLE void get(QString url,QJSValue callable,QMap<QString, QVariant> = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void post(QString url,QJSValue callable,QMap<QString, QVariant> = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void postString(QString url,QJSValue callable,QString params = "",QMap<QString, QVariant> headers = {});
Q_INVOKABLE void postJson(QString url,QJSValue callable,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void download(QString url,QJSValue callable,QString filePath,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void cancel();
private:
QList<QPointer<QNetworkReply>> _cache;

53
src/FluQRCode.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "FluQRCode.h"
#include "BarcodeFormat.h"
#include "BitMatrix.h"
#include "MultiFormatWriter.h"
using namespace ZXing;
FluQRCode::FluQRCode(QQuickItem* parent) : QQuickPaintedItem(parent)
{
color(QColor(0,0,0,255));
size(100);
setWidth(_size);
setHeight(_size);
connect(this,&FluQRCode::textChanged,this,[=]{update();});
connect(this,&FluQRCode::colorChanged,this,[=]{update();});
connect(this,&FluQRCode::sizeChanged,this,[=]{
setWidth(_size);
setHeight(_size);
update();
});
}
void FluQRCode::paint(QPainter* painter)
{
if(_text.isEmpty()){
return;
}
if(_text.length()>1108){
return;
}
painter->save();
painter->eraseRect(boundingRect());
auto format = ZXing::BarcodeFormatFromString("QRCode");
auto writer = MultiFormatWriter(format);
writer.setMargin(0);
writer.setEncoding(ZXing::CharacterSet::UTF8);
auto matrix = writer.encode(_text.toUtf8().constData(), 0, 0);
auto bitmap = ToMatrix<uint8_t>(matrix);
auto image = QImage(bitmap.data(), bitmap.width(), bitmap.height(), bitmap.width(), QImage::Format::Format_Grayscale8).copy();
QImage rgbImage = image.convertToFormat(QImage::Format_ARGB32);
for (int y = 0; y < rgbImage.height(); ++y) {
for (int x = 0; x < rgbImage.width(); ++x) {
QRgb pixel = rgbImage.pixel(x, y);
if (qRed(pixel) == 0 && qGreen(pixel) == 0 && qBlue(pixel) == 0) {
rgbImage.setPixelColor(x, y, _color);
}
}
}
painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), rgbImage);
painter->restore();
}

22
src/FluQRCode.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef FLUQRCODE_H
#define FLUQRCODE_H
#include <QQuickItem>
#include <QQuickPaintedItem>
#include <QPainter>
#include "stdafx.h"
class FluQRCode : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY_AUTO(QString,text)
Q_PROPERTY_AUTO(QColor,color)
Q_PROPERTY_AUTO(int,size);
QML_NAMED_ELEMENT(FluQRCode)
public:
explicit FluQRCode(QQuickItem *parent = nullptr);
void paint(QPainter* painter) override;
};
#endif // FLUQRCODE_H

View File

@ -3,6 +3,7 @@
#include <QClipboard>
#include <QUuid>
#include <QCursor>
#include <QTextDocument>
FluTools* FluTools::m_instance = nullptr;
@ -98,3 +99,9 @@ void FluTools::deleteItem(QObject *p){
QString FluTools::toLocalPath(const QUrl& url){
return url.toLocalFile();
}
QString FluTools::html2PlantText(const QString& html){
QTextDocument textDocument;
textDocument.setHtml(html);
return textDocument.toPlainText();
}

View File

@ -90,6 +90,12 @@ public:
*/
Q_INVOKABLE void restoreOverrideCursor();
/**
* @brief html2PlantText 将html转换成纯文本
* @param html
*/
Q_INVOKABLE QString html2PlantText(const QString& html);
/**
* @brief toLocalPath 获取文件路径可以去掉windows系统下的file:///macos下的file://
* @param url

View File

@ -1,40 +0,0 @@
#include <windows.h>
#define STR(x) #x
#define VER_JOIN(a,b,c,d) STR(a.b.c.d)
#define VER_JOIN_(x) VER_JOIN x
#define VER_STR VER_JOIN_((VERSION))
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION
PRODUCTVERSION VERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "FluentUI for QML."
VALUE "CompanyName", "zhuzichu"
VALUE "FileDescription", "fluentui"
VALUE "FileVersion", VER_STR
VALUE "InternalName", ""
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", ""
VALUE "ProductName", "fluentui"
VALUE "ProductVersion", VER_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -2,22 +2,41 @@ import QtQuick
import QtQuick.Controls
import FluentUI
Item {
property bool flagXChanged: true
property int radius : 5
FluItem {
property int loopTime: 2000
property var model
property Component delegate
property bool showIndicator: true
property int indicatorGravity : Qt.AlignBottom | Qt.AlignHCenter
property int indicatorMarginLeft: 0
property int indicatorMarginRight: 0
property int indicatorMarginTop: 0
property int indicatorMarginBottom: 20
property int indicatorSpacing: 10
property alias indicatorAnchors: layout_indicator.anchors
property Component indicatorDelegate : com_indicator
id:control
width: 400
height: 300
ListModel{
id:content_model
}
FluRectangle{
anchors.fill: parent
radius: [control.radius,control.radius,control.radius,control.radius]
FluShadow{
radius:control.radius
QtObject{
id:d
property bool flagXChanged: true
function setData(data){
if(!data){
return
}
content_model.clear()
content_model.append(data[data.length-1])
content_model.append(data)
content_model.append(data[0])
list_view.highlightMoveDuration = 0
list_view.currentIndex = 1
list_view.highlightMoveDuration = 250
timer_run.restart()
}
}
ListView{
id:list_view
@ -30,8 +49,18 @@ Item {
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
Component.onCompleted: {
d.setData(control.model)
}
Connections{
target: control
function onModelChanged(){
d.setData(control.model)
}
}
orientation : ListView.Horizontal
delegate: Item{
id:item_control
width: ListView.view.width
height: ListView.view.height
property int displayIndex: {
@ -41,11 +70,16 @@ Item {
return 0
return index-1
}
Image {
Loader{
property int displayIndex : item_control.displayIndex
property var model: list_view.model.get(index)
anchors.fill: parent
source: model.url
asynchronous: true
fillMode:Image.PreserveAspectCrop
sourceComponent: {
if(model){
return control.delegate
}
return undefined
}
}
}
onMovementEnded:{
@ -55,15 +89,15 @@ Item {
}else if(currentIndex === list_view.count-1){
currentIndex = 1
}
flagXChanged = false
timer_run.start()
d.flagXChanged = false
timer_run.restart()
}
onMovementStarted: {
flagXChanged = true
d.flagXChanged = true
timer_run.stop()
}
onContentXChanged: {
if(flagXChanged){
if(d.flagXChanged){
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
var minY = Math.max(0,(list_view.width*(currentIndex-1)))
if(contentX>=maxX){
@ -75,29 +109,63 @@ Item {
}
}
}
}
Row{
spacing: 10
anchors{
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 20
}
visible: showIndicator
Repeater{
model: list_view.count
Component{
id:com_indicator
Rectangle{
width: 8
height: 8
radius: 4
visible: {
if(index===0 || index===list_view.count-1)
return false
return true
FluShadow{
radius: 4
}
scale: checked ? 1.2 : 1
color: checked ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.7)
border.width: mouse_item.containsMouse ? 1 : 0
border.color: FluTheme.primaryColor.dark
MouseArea{
id:mouse_item
hoverEnabled: true
anchors.fill: parent
onClicked: {
changedIndex(realIndex)
}
}
}
}
Row{
id:layout_indicator
spacing: control.indicatorSpacing
anchors{
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
bottom: (indicatorGravity & Qt.AlignBottom) ? parent.bottom : undefined
top: (indicatorGravity & Qt.AlignTop) ? parent.top : undefined
left: (indicatorGravity & Qt.AlignLeft) ? parent.left : undefined
right: (indicatorGravity & Qt.AlignRight) ? parent.right : undefined
bottomMargin: control.indicatorMarginBottom
leftMargin: control.indicatorMarginBottom
rightMargin: control.indicatorMarginBottom
topMargin: control.indicatorMarginBottom
}
visible: showIndicator
Repeater{
id:repeater_indicator
model: list_view.count
Loader{
property int displayIndex: {
if(index === 0)
return list_view.count-3
if(index === list_view.count-1)
return 0
return index-1
}
property int realIndex: index
property bool checked: list_view.currentIndex === index
sourceComponent: {
if(index===0 || index===list_view.count-1)
return undefined
return control.indicatorDelegate
}
border.width: 1
border.color: FluColors.Grey100
color: list_view.currentIndex === index ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.5)
}
}
}
@ -121,12 +189,13 @@ Item {
timer_anim.start()
}
}
function setData(data){
content_model.clear()
content_model.append(data[data.length-1])
content_model.append(data)
content_model.append(data[0])
list_view.currentIndex = 1
function changedIndex(index){
d.flagXChanged = true
timer_run.stop()
list_view.currentIndex = index
d.flagXChanged = false
timer_run.restart()
}
}

View File

@ -3,5 +3,16 @@ import QtQuick.Window
import FluentUI
Rectangle {
property real spacing
property alias separatorHeight:separator.height
id:root
color:Qt.rgba(0,0,0,0)
height: spacing*2+separator.height
Rectangle{
id:separator
color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
width:parent.width
anchors.centerIn: parent
}
}

View File

@ -18,7 +18,7 @@ Item {
property int pageMode: FluNavigationViewType.Stack
signal logoClicked
id:control
QtObject{
Item{
id:d
property bool animDisabled:false
property var stackItems: []
@ -66,6 +66,10 @@ Item {
}
return data
}
function refreshWindow(){
Window.window.width = Window.window.width-1
Window.window.width = Window.window.width+1
}
}
Component.onCompleted: {
d.displayMode = Qt.binding(function(){
@ -110,11 +114,12 @@ Item {
id:com_panel_item_separatorr
FluDivider{
width: layout_list.width
height: {
spacing: model.spacing
separatorHeight: {
if(model.parent){
return model.parent.isExpand ? 1 : 0
return model.parent.isExpand ? model.size : 0
}
return 1
return model.size
}
}
}
@ -708,6 +713,11 @@ Item {
NumberAnimation{
duration: 167
easing.type: Easing.OutCubic
onRunningChanged: {
if(!running){
d.refreshWindow()
}
}
}
}
Behavior on x {
@ -715,6 +725,11 @@ Item {
NumberAnimation{
duration: 167
easing.type: Easing.OutCubic
onRunningChanged: {
if(!running){
d.refreshWindow()
}
}
}
}
visible: {
@ -1109,4 +1124,7 @@ Item {
function navButton(){
return btn_nav
}
function logoButton(){
return image_logo
}
}

View File

@ -6,4 +6,6 @@ QtObject {
readonly property string key : FluTools.uuid()
property int _idx
property var parent
property real spacing
property int size:1
}

View File

@ -40,27 +40,27 @@ Item{
anchors.fill: parent
visible: false
onPaint: {
var ctx = getContext("2d");
var x = 0;
var y = 0;
var w = control.width;
var h = control.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
var ctx = getContext("2d")
var x = 0
var y = 0
var w = control.width
var h = control.height
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.save()
ctx.beginPath();
ctx.moveTo(x + radius[0], y);
ctx.lineTo(x + w - radius[1], y);
ctx.arcTo(x + w, y, x + w, y + radius[1], radius[1]);
ctx.lineTo(x + w, y + h - radius[2]);
ctx.arcTo(x + w, y + h, x + w - radius[2], y + h, radius[2]);
ctx.lineTo(x + radius[3], y + h);
ctx.arcTo(x, y + h, x, y + h - radius[3], radius[3]);
ctx.lineTo(x, y + radius[0]);
ctx.arcTo(x, y, x + radius[0], y, radius[0]);
ctx.closePath();
ctx.fillStyle = control.color;
ctx.fill();
ctx.restore();
ctx.moveTo(x + radius[0], y)
ctx.lineTo(x + w - radius[1], y)
ctx.arcTo(x + w, y, x + w, y + radius[1], radius[1])
ctx.lineTo(x + w, y + h - radius[2])
ctx.arcTo(x + w, y + h, x + w - radius[2], y + h, radius[2])
ctx.lineTo(x + radius[3], y + h)
ctx.arcTo(x, y + h, x, y + h - radius[3], radius[3])
ctx.lineTo(x, y + radius[0])
ctx.arcTo(x, y, x + radius[0], y, radius[0])
ctx.closePath()
ctx.fillStyle = "#000000"
ctx.fill()
ctx.restore()
}
}
OpacityMask {

View File

@ -0,0 +1,178 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
import QtQuick.Window
import FluentUI
Popup{
property var steps : []
property int targetMargins: 5
property Component nextButton: com_next_button
property Component prevButton: com_prev_button
property int index : 0
id:control
padding: 0
anchors.centerIn: Overlay.overlay
width: d.window?.width
height: d.window?.height
background: Item{}
contentItem: Item{}
onVisibleChanged: {
if(visible){
control.index = 0
}
}
onIndexChanged: {
canvas.requestPaint()
}
Component{
id:com_next_button
FluFilledButton{
text: isEnd ? "结束导览" :"下一步"
onClicked: {
if(isEnd){
control.close()
}else{
control.index = control.index + 1
}
}
}
}
Component{
id:com_prev_button
FluButton{
text: "上一步"
onClicked: {
control.index = control.index - 1
}
}
}
Item{
id:d
property var window: Window.window
property var pos:Qt.point(0,0)
property var step : steps[index]
property var target : step.target()
}
Connections{
target: d.window
function onWidthChanged(){
canvas.requestPaint()
}
function onHeightChanged(){
canvas.requestPaint()
}
}
Canvas{
id:canvas
anchors.fill: parent
onPaint: {
d.pos = d.target.mapToGlobal(0,0)
d.pos = Qt.point(d.pos.x-d.window.x,d.pos.y-d.window.y)
var ctx = canvas.getContext("2d")
ctx.clearRect(0, 0, canvasSize.width, canvasSize.height)
ctx.save()
ctx.fillStyle = "#88000000"
ctx.fillRect(0, 0, canvasSize.width, canvasSize.height)
ctx.globalCompositeOperation = 'destination-out'
ctx.fillStyle = 'black'
drawRoundedRect(Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2),2,ctx)
ctx.restore()
}
function drawRoundedRect(rect, r, ctx) {
var ptA = Qt.point(rect.x + r, rect.y)
var ptB = Qt.point(rect.x + rect.width, rect.y)
var ptC = Qt.point(rect.x + rect.width, rect.y + rect.height)
var ptD = Qt.point(rect.x, rect.y + rect.height)
var ptE = Qt.point(rect.x, rect.y)
ctx.beginPath()
ctx.moveTo(ptA.x, ptA.y)
ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r)
ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r)
ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r)
ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r)
ctx.fill()
ctx.closePath()
}
}
FluArea{
id:layout_panne
radius: 5
width: 500
height: 88 + text_desc.height
color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
x: Math.min(Math.max(0,d.pos.x+d.target.width/2-width/2),d.window?.width-width)
y: d.pos.y+d.target.height+control.targetMargins + 15
border.width: 0
FluText{
text: d.step.title
font: FluTextStyle.BodyStrong
elide: Text.ElideRight
anchors{
top: parent.top
left: parent.left
topMargin: 15
leftMargin: 15
right: parent.right
rightMargin: 32
}
}
FluText{
id:text_desc
font: FluTextStyle.Body
wrapMode: Text.WrapAnywhere
maximumLineCount: 4
elide: Text.ElideRight
text: d.step.description
anchors{
top: parent.top
left: parent.left
right: parent.right
rightMargin: 15
topMargin: 42
leftMargin: 15
}
}
Loader{
id:loader_next
property bool isEnd: control.index === steps.length-1
sourceComponent: com_next_button
anchors{
top:text_desc.bottom
topMargin: 10
right: parent.right
rightMargin: 15
}
}
Loader{
id:loader_prev
visible: control.index !== 0
sourceComponent: com_prev_button
anchors{
right:loader_next.left
top: loader_next.top
rightMargin: 14
}
}
FluIconButton{
anchors{
right: parent.right
top: parent.top
margins: 10
}
width: 26
height: 26
iconSize: 12
iconSource : FluentIcons.ChromeClose
onClicked: {
control.close()
}
}
}
FluIcon{
iconSource: FluentIcons.FlickDown
color: layout_panne.color
x: d.pos.x+d.target.width/2-10
y: d.pos.y+d.target.height
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 266 KiB

View File

@ -1,11 +1,10 @@
module FluentUI
module FluentUI
classname FluentUIPlugin
designersupported
typeinfo plugins.qmltypes
FluAcrylic 1.0 Controls/FluAcrylic.qml
FluAppBar 1.0 Controls/FluAppBar.qml
FluArea 1.0 Controls/FluArea.qml
FluAcrylic 1.0 Controls/FluAcrylic.qml
FluAutoSuggestBox 1.0 Controls/FluAutoSuggestBox.qml
FluBadge 1.0 Controls/FluBadge.qml
FluBreadcrumbBar 1.0 Controls/FluBreadcrumbBar.qml
@ -17,9 +16,9 @@ FluCheckBox 1.0 Controls/FluCheckBox.qml
FluColorPicker 1.0 Controls/FluColorPicker.qml
FluColorView 1.0 Controls/FluColorView.qml
FluComboBox 1.0 Controls/FluComboBox.qml
FluControl 1.0 Controls/FluControl.qml
FluContentDialog 1.0 Controls/FluContentDialog.qml
FluContentPage 1.0 Controls/FluContentPage.qml
FluControl 1.0 Controls/FluControl.qml
FluCopyableText 1.0 Controls/FluCopyableText.qml
FluDatePicker 1.0 Controls/FluDatePicker.qml
FluDivider 1.0 Controls/FluDivider.qml
@ -30,15 +29,15 @@ FluFlipView 1.0 Controls/FluFlipView.qml
FluFocusRectangle 1.0 Controls/FluFocusRectangle.qml
FluIcon 1.0 Controls/FluIcon.qml
FluIconButton 1.0 Controls/FluIconButton.qml
FluImage 1.0 Controls/FluImage.qml
FluInfoBar 1.0 Controls/FluInfoBar.qml
FluItem 1.0 Controls/FluItem.qml
FluImage 1.0 Controls/FluImage.qml
FluMediaPlayer 1.0 Controls/FluMediaPlayer.qml
FluItemDelegate 1.0 Controls/FluItemDelegate.qml
FluMenu 1.0 Controls/FluMenu.qml
FluMenuItem 1.0 Controls/FluMenuItem.qml
FluMenuSeparator 1.0 Controls/FluMenuSeparator.qml
FluMenuBar 1.0 Controls/FluMenuBar.qml
FluMenuBarItem 1.0 Controls/FluMenuBarItem.qml
FluMenuItem 1.0 Controls/FluMenuItem.qml
FluMenuSeparator 1.0 Controls/FluMenuSeparator.qml
FluMultilineTextBox 1.0 Controls/FluMultilineTextBox.qml
FluNavigationView 1.0 Controls/FluNavigationView.qml
FluObject 1.0 Controls/FluObject.qml
@ -60,14 +59,16 @@ FluRadioButtons 1.0 Controls/FluRadioButtons.qml
FluRatingControl 1.0 Controls/FluRatingControl.qml
FluRectangle 1.0 Controls/FluRectangle.qml
FluRemoteLoader 1.0 Controls/FluRemoteLoader.qml
FluScrollablePage 1.0 Controls/FluScrollablePage.qml
FluScrollBar 1.0 Controls/FluScrollBar.qml
FluScrollIndicator 1.0 Controls/FluScrollIndicator.qml
FluScrollablePage 1.0 Controls/FluScrollablePage.qml
FluShadow 1.0 Controls/FluShadow.qml
FluSlider 1.0 Controls/FluSlider.qml
FluSpinBox 1.0 Controls/FluSpinBox.qml
FluStatusView 1.0 Controls/FluStatusView.qml
FluTableView 1.0 Controls/FluTableView.qml
FluTabView 1.0 Controls/FluTabView.qml
FluTableModelColumn 1.0 Controls/FluTableModelColumn.qml
FluTableView 1.0 Controls/FluTableView.qml
FluText 1.0 Controls/FluText.qml
FluTextBox 1.0 Controls/FluTextBox.qml
FluTextBoxBackground 1.0 Controls/FluTextBoxBackground.qml
@ -77,7 +78,7 @@ FluTimePicker 1.0 Controls/FluTimePicker.qml
FluToggleButton 1.0 Controls/FluToggleButton.qml
FluToggleSwitch 1.0 Controls/FluToggleSwitch.qml
FluTooltip 1.0 Controls/FluTooltip.qml
FluTour 1.0 Controls/FluTour.qml
FluTreeView 1.0 Controls/FluTreeView.qml
FluWindow 1.0 Controls/FluWindow.qml
FluSingleton 1.0 Controls/FluSingleton.qml
plugin fluentuiplugin

1
zxing-cpp Submodule

Submodule zxing-cpp added at cf9becfa1b