mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-01 15:42:20 +08:00
Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
997101f349 | |||
2b96f06fe0 | |||
6ea873f75c | |||
efd21a5f55 | |||
a7ff28466d | |||
64728632c7 | |||
a54a99bbe1 | |||
cb8b128598 | |||
153090637b | |||
c0efd71d31 | |||
2ead64e9b5 | |||
fc99c19479 | |||
1e9bd0fd05 | |||
b47f2d12ad | |||
9bf6ed9d1d | |||
c0726d89f0 | |||
06c9b4e382 | |||
26669f76e0 | |||
1729b46e13 | |||
5661d46862 | |||
2d492ceb95 | |||
736c19c41e | |||
ce552012f3 | |||
0df4c6858b | |||
ec9a9a5074 | |||
1b72b840d6 | |||
79d29769e1 | |||
a9d0dd9017 | |||
0b6491e730 | |||
7fe71c892b | |||
0b17d03f23 |
@ -2,7 +2,8 @@ cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(FluentUI VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/.cmake/")
|
||||
set(FLUENTUI_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
list(APPEND CMAKE_MODULE_PATH ${FLUENTUI_DIRECTORY}/.cmake/)
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
|
||||
@ -10,10 +11,16 @@ 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(Qt6 REQUIRED COMPONENTS Core Quick Qml)
|
||||
set(QT_SDK_DIR "${Qt6_DIR}")
|
||||
cmake_path(GET QT_SDK_DIR PARENT_PATH QT_SDK_DIR)
|
||||
cmake_path(GET QT_SDK_DIR PARENT_PATH QT_SDK_DIR)
|
||||
cmake_path(GET QT_SDK_DIR PARENT_PATH QT_SDK_DIR)
|
||||
|
||||
#设置QML插件输出目录,可以通过外部设置,如果外部没有设置就默认到<QT_SDK_DIR_PATH>\qml\FluentUI目录下
|
||||
set(FLUENTUI_QML_PLUGIN_DIRECTORY "" CACHE PATH "Path to FluentUI plugin")
|
||||
if(NOT FLUENTUI_QML_PLUGIN_DIRECTORY)
|
||||
set(FLUENTUI_QML_PLUGIN_DIRECTORY ${CMAKE_PREFIX_PATH}/qml/FluentUI)
|
||||
set(FLUENTUI_QML_PLUGIN_DIRECTORY ${QT_SDK_DIR}/qml/FluentUI)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
@ -25,11 +32,7 @@ endif ()
|
||||
|
||||
if (FLUENTUI_BUILD_FRAMELESSHEPLER)
|
||||
set(FRAMELESSHELPER_BUILD_STATIC ON)
|
||||
set(FRAMELESSHELPER_NO_SUMMARY OFF)
|
||||
set(FRAMELESSHELPER_NO_DEBUG_OUTPUT OFF)
|
||||
set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
|
||||
add_definitions(-DFRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT)
|
||||
add_definitions(-DFRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT)
|
||||
set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON)
|
||||
add_subdirectory(framelesshelper)
|
||||
endif ()
|
||||
|
||||
|
265
THIRD_PARTY_COPYRIGHT.txt
Normal file
265
THIRD_PARTY_COPYRIGHT.txt
Normal file
@ -0,0 +1,265 @@
|
||||
This product use Third Party code for certain functions may include licensed under
|
||||
terms that require meeting to display the following notices:
|
||||
|
||||
A text copy of this license is included with the download of
|
||||
this FluentUI software. You may obtain a copy of the
|
||||
source code from https://github.com/zhuzichu520/FluentUI
|
||||
|
||||
************************************************************************************
|
||||
About Qt 6.5.0 Libraries Used in This Project:
|
||||
|
||||
This project, "FluentUI", utilizes the Qt 6.5.0 library.
|
||||
Below is a list of the Qt modules used and their corresponding open-source licenses:
|
||||
|
||||
Qt Core - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt Quick - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt Quick Controls 2 - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt Gui - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt Multimedia - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt WebEngineQuick - LGPL v3 / GPL v3 / Commercial License
|
||||
Qt Sql - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt Svg - LGPL v3 / GPL v2 / Commercial License
|
||||
Qt Core5Compat - LGPL v3 / GPL v2 / Commercial License
|
||||
|
||||
Please note that the license information provided above is for reference only.
|
||||
For the exact licensing, refer to the official Qt documentation and source code:
|
||||
https://doc.qt.io/qt-6/licenses-used-in-qt.html
|
||||
You can choose an appropriate license based on your requirements.
|
||||
If you choose to use the LGPL or GPL licenses, please follow the relevant
|
||||
open-source license regulations, such as releasing source code,
|
||||
retaining copyright notices, etc.
|
||||
|
||||
We would like to thank the Qt project and its contributors for
|
||||
providing powerful tools and support for this project.
|
||||
For more information about the Qt project,
|
||||
please visit the official Qt website (https://www.qt.io/).
|
||||
|
||||
************************************************************************************
|
||||
framelesshelper
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
************************************************************************************
|
||||
zxing-cpp
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
@ -37,9 +37,9 @@ else()
|
||||
endif()
|
||||
|
||||
##生成版本信息头文件
|
||||
set(HEADER_FILE_VERSION_PATH ${CMAKE_SOURCE_DIR}/example/Version.h)
|
||||
set(HEADER_FILE_VERSION_PATH ${FLUENTUI_DIRECTORY}/example/Version.h)
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/.cmake/Version.h.in
|
||||
${FLUENTUI_DIRECTORY}/.cmake/Version.h.in
|
||||
${HEADER_FILE_VERSION_PATH}
|
||||
)
|
||||
|
||||
@ -69,7 +69,7 @@ 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
|
||||
${FLUENTUI_DIRECTORY}/.cmake/version_exe.rc.in
|
||||
${EXAMPLE_VERSION_RC_PATH}
|
||||
)
|
||||
endif()
|
||||
|
@ -7,6 +7,12 @@ FluObject{
|
||||
|
||||
property var navigationView
|
||||
|
||||
function rename(item, newName){
|
||||
if(newName && newName.trim().length>0){
|
||||
item.title = newName;
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItem{
|
||||
id:item_home
|
||||
count: 9
|
||||
@ -21,11 +27,38 @@ FluObject{
|
||||
}
|
||||
navigationView.push("qrc:/example/qml/page/T_Home.qml")
|
||||
}
|
||||
editDelegate: FluTextBox{
|
||||
text:item_home.title
|
||||
}
|
||||
menuDelegate: FluMenu{
|
||||
id:nav_item_right_menu
|
||||
width: 120
|
||||
FluMenuItem{
|
||||
text: "重命名"
|
||||
visible: true
|
||||
onClicked: {
|
||||
item_home.showEdit = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPaneItemExpander{
|
||||
id:item_expander_basic_input
|
||||
title:lang.basic_input
|
||||
icon:FluentIcons.CheckboxComposite
|
||||
editDelegate: FluTextBox{
|
||||
text:item_expander_basic_input.title
|
||||
}
|
||||
menuDelegate: FluMenu{
|
||||
FluMenuItem{
|
||||
text: "重命名"
|
||||
visible: true
|
||||
onClicked: {
|
||||
item_expander_basic_input.showEdit = true
|
||||
}
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
id:item_buttons
|
||||
count: 99
|
||||
@ -349,6 +382,18 @@ FluObject{
|
||||
navigationView.push("qrc:/example/qml/page/T_Timeline.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Screenshot"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/example/qml/page/T_Screenshot.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Captcha"
|
||||
onTap:{
|
||||
navigationView.push("qrc:/example/qml/page/T_Captcha.qml")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
title:"Chart"
|
||||
onTap:{
|
||||
@ -377,7 +422,7 @@ FluObject{
|
||||
FluPaneItem{
|
||||
title:"HotLoader"
|
||||
tapFunc:function(){
|
||||
FluApp.navigate("/hotload")
|
||||
FluApp.navigate("/hotload")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,16 +167,26 @@ FluScrollablePage{
|
||||
height: 68
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
FluIconButton{
|
||||
iconSource:FluentIcons.ChromeCloseContrast
|
||||
disabled:icon_button_switch.checked
|
||||
iconSize: 15
|
||||
Row{
|
||||
spacing: 20
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
onClicked:{
|
||||
showSuccess("点击IconButton")
|
||||
FluIconButton{
|
||||
iconSource:FluentIcons.ChromeCloseContrast
|
||||
disabled:icon_button_switch.checked
|
||||
iconSize: 15
|
||||
onClicked:{
|
||||
showSuccess("点击IconButton")
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
disabled:icon_button_switch.checked
|
||||
iconDelegate: Image{ width: 20; height: 20; source: "qrc:/example/res/image/ic_home_github.png" }
|
||||
onClicked:{
|
||||
showSuccess("点击IconButton")
|
||||
}
|
||||
}
|
||||
}
|
||||
FluToggleSwitch{
|
||||
|
54
example/qml/page/T_Captcha.qml
Normal file
54
example/qml/page/T_Captcha.qml
Normal file
@ -0,0 +1,54 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "qrc:///example/qml/component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"Captcha"
|
||||
|
||||
|
||||
FluCaptcha{
|
||||
id:captcha
|
||||
Layout.topMargin: 20
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
captcha.refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text:"Refresh"
|
||||
Layout.topMargin: 20
|
||||
onClicked: {
|
||||
captcha.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
spacing: 10
|
||||
Layout.topMargin: 10
|
||||
FluTextBox{
|
||||
id:text_box
|
||||
placeholderText: "请输入验证码"
|
||||
}
|
||||
FluButton{
|
||||
text:"verify"
|
||||
onClicked: {
|
||||
var success = captcha.verify(text_box.text)
|
||||
if(success){
|
||||
showSuccess("验证码正确")
|
||||
}else{
|
||||
showError("错误验证,请重新输入")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -22,7 +22,7 @@ FluScrollablePage{
|
||||
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
height: 320
|
||||
Layout.preferredHeight: 320
|
||||
Image {
|
||||
id: bg
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
@ -68,7 +68,12 @@ FluScrollablePage{
|
||||
id: control
|
||||
width: 220
|
||||
height: 240
|
||||
FluShadow{
|
||||
radius:8
|
||||
anchors.fill: item_content
|
||||
}
|
||||
FluItem{
|
||||
id:item_content
|
||||
radius: [8,8,8,8]
|
||||
width: 200
|
||||
height: 220
|
||||
@ -77,6 +82,7 @@ FluScrollablePage{
|
||||
anchors.fill: parent
|
||||
tintColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
target: bg
|
||||
tintOpacity: FluTheme.dark ? 0.8 : 0.9
|
||||
blurRadius : 40
|
||||
targetRect: Qt.rect(list.x-list.contentX+10+(control.width)*index,list.y+10,width,height)
|
||||
}
|
||||
@ -86,14 +92,14 @@ FluScrollablePage{
|
||||
color:{
|
||||
if(FluTheme.dark){
|
||||
if(item_mouse.containsMouse){
|
||||
return Qt.rgba(1,1,1,0.06)
|
||||
return Qt.rgba(1,1,1,0.03)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0.03)
|
||||
return Qt.rgba(0,0,0,0.0)
|
||||
}else{
|
||||
if(item_mouse.containsMouse){
|
||||
return Qt.rgba(0,0,0,0.09)
|
||||
return Qt.rgba(0,0,0,0.03)
|
||||
}
|
||||
return Qt.rgba(0,0,0,0.06)
|
||||
return Qt.rgba(0,0,0,0.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,10 +141,11 @@ FluScrollablePage{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onWheel: (wheel)=>{
|
||||
if (wheel.angleDelta.y > 0) scrollbar_header.decrease()
|
||||
else scrollbar_header.increase()
|
||||
}
|
||||
onWheel:
|
||||
(wheel)=>{
|
||||
if (wheel.angleDelta.y > 0) scrollbar_header.decrease()
|
||||
else scrollbar_header.increase()
|
||||
}
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(model.url)
|
||||
}
|
||||
@ -249,7 +256,7 @@ FluScrollablePage{
|
||||
|
||||
GridView{
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: contentHeight
|
||||
Layout.preferredHeight: contentHeight
|
||||
cellHeight: 120
|
||||
cellWidth: 320
|
||||
model:ItemsOriginal.getRecentlyAddedData()
|
||||
@ -266,7 +273,7 @@ FluScrollablePage{
|
||||
|
||||
GridView{
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: contentHeight
|
||||
Layout.preferredHeight: contentHeight
|
||||
cellHeight: 120
|
||||
cellWidth: 320
|
||||
interactive: false
|
||||
|
@ -133,6 +133,15 @@ FluContentPage{
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: 36
|
||||
text: "下载文件"
|
||||
onClicked: {
|
||||
folder_dialog.open()
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
id:btn_upload
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: 36
|
||||
text: "文件上传"
|
||||
onClicked: {
|
||||
file_dialog.open()
|
||||
}
|
||||
@ -140,8 +149,48 @@ FluContentPage{
|
||||
}
|
||||
}
|
||||
|
||||
FolderDialog {
|
||||
FileDialog {
|
||||
id: file_dialog
|
||||
onAccepted: {
|
||||
var param = {}
|
||||
for(var i=0;i<selectedFiles.length;i++){
|
||||
var fileUrl = selectedFiles[i]
|
||||
var fileName = FluTools.getFileNameByUrl(fileUrl)
|
||||
var filePath = FluTools.toLocalPath(fileUrl)
|
||||
param[fileName] = filePath
|
||||
}
|
||||
console.debug(JSON.stringify(param))
|
||||
var callable = {}
|
||||
callable.onStart = function(){
|
||||
btn_upload.disabled = true
|
||||
}
|
||||
callable.onFinish = function(){
|
||||
btn_upload.disabled = false
|
||||
btn_upload.text = "上传文件"
|
||||
layout_upload_file_size.visible = false
|
||||
text_upload_file_size.text = ""
|
||||
}
|
||||
callable.onSuccess = function(result){
|
||||
text_info.text = result
|
||||
console.debug(result)
|
||||
}
|
||||
callable.onError = function(status,errorString,result){
|
||||
text_info.text = result
|
||||
console.debug(result)
|
||||
}
|
||||
callable.onUploadProgress = function(sent,total){
|
||||
var locale = Qt.locale()
|
||||
var precent = (sent/total * 100).toFixed(0) + "%"
|
||||
btn_upload.text = "上传中..."+precent
|
||||
text_upload_file_size.text = "%1/%2".arg(locale.formattedDataSize(sent)).arg(locale.formattedDataSize(total))
|
||||
layout_upload_file_size.visible = true
|
||||
}
|
||||
http.upload("https://httpbingo.org/post",callable,param)
|
||||
}
|
||||
}
|
||||
|
||||
FolderDialog {
|
||||
id: folder_dialog
|
||||
currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
||||
onAccepted: {
|
||||
var callable = {}
|
||||
@ -151,8 +200,8 @@ FluContentPage{
|
||||
callable.onFinish = function(){
|
||||
btn_download.disabled = false
|
||||
btn_download.text = "下载文件"
|
||||
layout_file_size.visible = false
|
||||
text_file_size.text = ""
|
||||
layout_download_file_size.visible = false
|
||||
text_download_file_size.text = ""
|
||||
}
|
||||
callable.onSuccess = function(result){
|
||||
showSuccess(result)
|
||||
@ -164,8 +213,8 @@ FluContentPage{
|
||||
var locale = Qt.locale()
|
||||
var precent = (recv/total * 100).toFixed(0) + "%"
|
||||
btn_download.text = "下载中..."+precent
|
||||
text_file_size.text = "%1/%2".arg(locale.formattedDataSize(recv)).arg(locale.formattedDataSize(total))
|
||||
layout_file_size.visible = true
|
||||
text_download_file_size.text = "%1/%2".arg(locale.formattedDataSize(recv)).arg(locale.formattedDataSize(total))
|
||||
layout_download_file_size.visible = true
|
||||
}
|
||||
var path = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4"
|
||||
http.download("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",callable,path)
|
||||
@ -183,6 +232,7 @@ FluContentPage{
|
||||
Flickable{
|
||||
clip: true
|
||||
id:scrollview
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
contentWidth: width
|
||||
@ -198,7 +248,7 @@ FluContentPage{
|
||||
}
|
||||
|
||||
FluRectangle{
|
||||
id:layout_file_size
|
||||
id:layout_download_file_size
|
||||
radius: [4,4,4,4]
|
||||
height: 36
|
||||
width: 160
|
||||
@ -206,7 +256,22 @@ FluContentPage{
|
||||
x:layout_flick.width
|
||||
y: 173 - layout_flick.contentY
|
||||
FluText{
|
||||
id:text_file_size
|
||||
id:text_download_file_size
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FluRectangle{
|
||||
id:layout_upload_file_size
|
||||
radius: [4,4,4,4]
|
||||
height: 36
|
||||
width: 160
|
||||
visible: false
|
||||
x:layout_flick.width
|
||||
y: 210 - layout_flick.contentY
|
||||
FluText{
|
||||
id:text_upload_file_size
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ FluScrollablePage{
|
||||
size:slider_size.value
|
||||
text:text_box.text
|
||||
color:color_picker.colorValue
|
||||
bgColor: bgcolor_picker.colorValue
|
||||
margins:slider_margins.value
|
||||
Layout.preferredWidth: size
|
||||
Layout.preferredHeight: size
|
||||
}
|
||||
@ -48,6 +50,35 @@ FluScrollablePage{
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
spacing: 10
|
||||
Layout.topMargin: 10
|
||||
FluText{
|
||||
text:"bgColor:"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
FluColorPicker{
|
||||
id:bgcolor_picker
|
||||
Component.onCompleted: {
|
||||
setColor(Qt.rgba(1,1,1,1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
spacing: 10
|
||||
FluText{
|
||||
text:"margins:"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
FluSlider{
|
||||
id:slider_margins
|
||||
from:0
|
||||
to:80
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
spacing: 10
|
||||
FluText{
|
||||
@ -56,7 +87,7 @@ FluScrollablePage{
|
||||
}
|
||||
FluSlider{
|
||||
id:slider_size
|
||||
from:60
|
||||
from:120
|
||||
to:260
|
||||
value: 120
|
||||
}
|
||||
|
54
example/qml/page/T_Screenshot.qml
Normal file
54
example/qml/page/T_Screenshot.qml
Normal file
@ -0,0 +1,54 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
import "qrc:///example/qml/component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title:"Screenshot"
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 100
|
||||
paddings: 10
|
||||
Layout.topMargin: 20
|
||||
|
||||
FluFilledButton{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text:"Open Screenshot"
|
||||
onClicked: {
|
||||
screenshot.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
Layout.preferredHeight: 400
|
||||
Layout.preferredWidth: 400
|
||||
Layout.topMargin: 10
|
||||
Layout.leftMargin: 4
|
||||
color: FluTheme.dark ? FluColors.Black : FluColors.White
|
||||
FluShadow{
|
||||
radius: 0
|
||||
color: FluTheme.primaryColor.dark
|
||||
}
|
||||
Image{
|
||||
id:image
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
asynchronous: true
|
||||
}
|
||||
}
|
||||
|
||||
FluScreenshot{
|
||||
id:screenshot
|
||||
captrueMode: FluScreenshotType.File
|
||||
saveFolder: FluTools.getApplicationDirPath()+"/screenshot"
|
||||
onCaptrueCompleted:
|
||||
(captrue)=>{
|
||||
image.source = captrue
|
||||
}
|
||||
}
|
||||
}
|
@ -64,9 +64,6 @@ FluContentPage{
|
||||
address: getRandomAddresses(),
|
||||
nickname: getRandomNickname(),
|
||||
longstring:"你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好",
|
||||
height:42,
|
||||
minimumHeight:42,
|
||||
maximumHeight:300,
|
||||
action:com_action
|
||||
})
|
||||
}
|
||||
@ -110,10 +107,7 @@ FluContentPage{
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
width:100,
|
||||
minimumWidth:80,
|
||||
maximumWidth:200,
|
||||
readOnly:true
|
||||
readOnly:true,
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
|
@ -16,7 +16,7 @@ FluScrollablePage{
|
||||
height: 16
|
||||
radius: 8
|
||||
border.width: 4
|
||||
border.color: FluColors.Red.dark
|
||||
border.color: FluTheme.dark ? FluColors.Teal.lighter : FluColors.Teal.dark
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,9 +24,10 @@ FluScrollablePage{
|
||||
id:com_lable
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
horizontalAlignment: textAlignment
|
||||
font.bold: true
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.lable
|
||||
color: FluTheme.primaryColor.dark
|
||||
color: FluTheme.dark ? FluColors.Teal.lighter : FluColors.Teal.dark
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
@ -41,16 +42,22 @@ FluScrollablePage{
|
||||
id:com_text
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
horizontalAlignment: textAlignment
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.text
|
||||
font.bold: true
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
showSuccess(modelData.text)
|
||||
linkColor: FluTheme.dark ? FluColors.Teal.lighter : FluColors.Teal.dark
|
||||
onLinkActivated:
|
||||
(link)=> {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
onLinkHovered:
|
||||
(link)=> {
|
||||
if(link === ""){
|
||||
FluTools.restoreOverrideCursor()
|
||||
}else{
|
||||
FluTools.setOverrideCursor(Qt.PointingHandCursor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,18 +65,15 @@ FluScrollablePage{
|
||||
id:list_model
|
||||
ListElement{
|
||||
lable:"2013-09-01"
|
||||
lableDelegate:()=>com_lable
|
||||
textDelegate:()=>com_text
|
||||
text:"考上家里蹲大学"
|
||||
text:"考上中国皮城大学,杰斯武器工坊专业"
|
||||
}
|
||||
ListElement{
|
||||
lable:"2017-07-01"
|
||||
text:"大学毕业,在寝室打了4年LOL,没想到毕业还要找工作,瞬间蒙蔽~害"
|
||||
text:"大学毕业,在寝室打了4年LOL,没想到毕业还要找工作,瞬间蒙蔽,害"
|
||||
}
|
||||
ListElement{
|
||||
lable:"2017-09-01"
|
||||
text:"开始找工作,毕业即失业!回农村老家躺平,继承三亩良田!!"
|
||||
dot:()=>com_dot
|
||||
text:"开始找工作,毕业即失业!回农村老家躺平,继承三亩良田"
|
||||
}
|
||||
ListElement{
|
||||
lable:"2018-02-01"
|
||||
@ -85,12 +89,19 @@ FluScrollablePage{
|
||||
}
|
||||
ListElement{
|
||||
lable:"2022-08-01"
|
||||
text:"额,被老板卖到甲方公司,走时老板还问我想不想去,我说:'哪里工资高就去哪里?',老板:'无语'"
|
||||
text:"额,被老板卖到甲方公司,走时老板还问我想不想去,我说:'哪里工资高就去哪里',老板:'无语'"
|
||||
}
|
||||
ListElement{
|
||||
lable:"2023-02-28"
|
||||
text:"开发FluentUI组件库"
|
||||
}
|
||||
ListElement{
|
||||
lable:"2023-03-28(富文本展示)"
|
||||
text:'将FluentUI源码开源到<a href="https://github.com/zhuzichu520/FluentUI">github</a>,并发布视频到<a href="https://www.bilibili.com/video/BV1mg4y1M71w">B站</a>'
|
||||
lableDelegate:()=>com_lable
|
||||
textDelegate:()=>com_text
|
||||
dot:()=>com_dot
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
@ -150,6 +161,8 @@ FluScrollablePage{
|
||||
FluTimeline{
|
||||
id:time_line
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
Layout.bottomMargin: 20
|
||||
mode: FluTimelineType.Alternate
|
||||
model:list_model
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ CustomWindow {
|
||||
// pageMode: FluNavigationViewType.NoStack
|
||||
items: ItemsOriginal
|
||||
footerItems:ItemsFooter
|
||||
topPadding:FluTools.isMacos() ? 20 : 5
|
||||
topPadding:FluTools.isMacos() ? 20 : 0
|
||||
displayMode:MainEvent.displayMode
|
||||
logo: "qrc:/example/res/image/favicon.ico"
|
||||
title:"FluentUI"
|
||||
|
@ -21,7 +21,6 @@ CircularReveal::CircularReveal(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||
void CircularReveal::paint(QPainter* painter)
|
||||
{
|
||||
painter->save();
|
||||
painter->eraseRect(boundingRect());
|
||||
painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), _source);
|
||||
QPainterPath path;
|
||||
path.moveTo(_center.x(),_center.y());
|
||||
|
@ -27,6 +27,7 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
||||
#ifdef Q_OS_WIN // 此设置仅在Windows下生效
|
||||
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);
|
||||
|
@ -11,8 +11,6 @@ if(APPLE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml)
|
||||
|
||||
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
|
||||
qt_standard_project_setup()
|
||||
else()
|
||||
@ -36,7 +34,7 @@ foreach(filepath ${QML_PATHS})
|
||||
endforeach(filepath)
|
||||
|
||||
#遍历所有资源文件
|
||||
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp *.js qmldir)
|
||||
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp *.js)
|
||||
foreach(filepath ${RES_PATHS})
|
||||
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
|
||||
list(APPEND resource_files ${filename})
|
||||
@ -68,7 +66,7 @@ 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_DIRECTORY}/.cmake/version_dll.rc.in
|
||||
${FLUENTUI_VERSION_RC_PATH}
|
||||
)
|
||||
endif()
|
||||
|
12
src/Def.h
12
src/Def.h
@ -4,6 +4,18 @@
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
|
||||
namespace FluScreenshotType {
|
||||
Q_NAMESPACE
|
||||
enum CaptrueMode {
|
||||
Pixmap = 0x0000,
|
||||
File = 0x0001,
|
||||
};
|
||||
Q_ENUM_NS(CaptrueMode)
|
||||
QML_NAMED_ELEMENT(FluScreenshotType)
|
||||
}
|
||||
|
||||
|
||||
namespace FluThemeType {
|
||||
Q_NAMESPACE
|
||||
enum DarkMode {
|
||||
|
73
src/FluCaptcha.cpp
Normal file
73
src/FluCaptcha.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "FluCaptcha.h"
|
||||
#include <QTime>
|
||||
#include <QChar>
|
||||
#include <QPainter>
|
||||
#include <QRandomGenerator>
|
||||
#include <qmath.h>
|
||||
|
||||
FluCaptcha::FluCaptcha(QQuickItem *parent)
|
||||
: QQuickPaintedItem(parent)
|
||||
{
|
||||
font(QFont("楷体",25,QFont::Bold,true));
|
||||
setWidth(180);
|
||||
setHeight(80);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void FluCaptcha::paint(QPainter* painter)
|
||||
{
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect().toRect(),QColor(255,255,255,255));
|
||||
QPen pen;
|
||||
painter->setFont(_font);
|
||||
for(int i=0;i<100;i++)
|
||||
{
|
||||
pen = QPen(QColor(_generaNumber(256),_generaNumber(256),_generaNumber(256)));
|
||||
painter->setPen(pen);
|
||||
painter->drawPoint(_generaNumber(180),_generaNumber(80));
|
||||
}
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
pen = QPen(QColor(_generaNumber(256),_generaNumber(256),_generaNumber(256)));
|
||||
painter->setPen(pen);
|
||||
painter->drawLine(_generaNumber(180),_generaNumber(80),_generaNumber(180),_generaNumber(80));
|
||||
}
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
pen = QPen(QColor(_generaNumber(255),_generaNumber(255),_generaNumber(255)));
|
||||
painter->setPen(pen);
|
||||
painter->drawText(15+35*i,10+_generaNumber(15),30,40,Qt::AlignCenter, QString(_code[i]));
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
int FluCaptcha::_generaNumber(int number){
|
||||
return QRandomGenerator::global()->bounded(0,number);
|
||||
}
|
||||
|
||||
void FluCaptcha::refresh(){
|
||||
this->_code.clear();
|
||||
for(int i = 0;i < 4;++i)
|
||||
{
|
||||
int num = _generaNumber(3);
|
||||
if(num == 0)
|
||||
{
|
||||
this->_code += QString::number(_generaNumber(10));
|
||||
}
|
||||
else if(num == 1)
|
||||
{
|
||||
int temp = 'A';
|
||||
this->_code += static_cast<QChar>(temp + _generaNumber(26));
|
||||
}
|
||||
else if(num == 2)
|
||||
{
|
||||
int temp = 'a';
|
||||
this->_code += static_cast<QChar>(temp + _generaNumber(26));
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
bool FluCaptcha::verify(const QString& code){
|
||||
return this->_code == code;
|
||||
}
|
24
src/FluCaptcha.h
Normal file
24
src/FluCaptcha.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef FLUCAPTCHA_H
|
||||
#define FLUCAPTCHA_H
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQuickPaintedItem>
|
||||
#include <QPainter>
|
||||
#include "stdafx.h"
|
||||
|
||||
class FluCaptcha : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QFont,font);
|
||||
QML_NAMED_ELEMENT(FluCaptcha)
|
||||
private:
|
||||
int _generaNumber(int number);
|
||||
QString _code;
|
||||
public:
|
||||
explicit FluCaptcha(QQuickItem *parent = nullptr);
|
||||
void paint(QPainter* painter) override;
|
||||
Q_INVOKABLE void refresh();
|
||||
Q_INVOKABLE bool verify(const QString& code);
|
||||
};
|
||||
|
||||
#endif // FLUCAPTCHA_H
|
@ -13,6 +13,7 @@ FluColors *FluColors::getInstance()
|
||||
FluColors::FluColors(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
Transparent("#00000000");
|
||||
Black("#000000");
|
||||
White("#ffffff");
|
||||
Grey10("#faf9f8");
|
||||
|
@ -12,6 +12,7 @@
|
||||
class FluColors : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,Transparent);
|
||||
Q_PROPERTY_AUTO(QString,Black);
|
||||
Q_PROPERTY_AUTO(QString,White);
|
||||
Q_PROPERTY_AUTO(QString,Grey10);
|
||||
|
@ -43,8 +43,6 @@ void FluHttp::post(QString url,QJSValue callable,QMap<QString, QVariant> params,
|
||||
QNetworkRequest request(_url);
|
||||
addHeaders(&request,data["headers"].toMap());
|
||||
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
|
||||
QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart.boundary());
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
|
||||
for (const auto& each : data["params"].toMap().toStdMap())
|
||||
{
|
||||
const QString& key = each.first;
|
||||
@ -74,7 +72,7 @@ void FluHttp::post(QString url,QJSValue callable,QMap<QString, QVariant> params,
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
onError(callable,status,errorString);
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,7 +111,7 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMap<QStri
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
onError(callable,status,errorString);
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,7 +150,7 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap<QString, QVariant> par
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
onError(callable,status,errorString);
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,7 +188,7 @@ void FluHttp::get(QString url,QJSValue callable,QMap<QString, QVariant> params,Q
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
onError(callable,status,errorString);
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,7 +209,7 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QStri
|
||||
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
|
||||
if (!file->open(mode))
|
||||
{
|
||||
onError(callable,-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()));
|
||||
onError(callable,-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()),"");
|
||||
onFinish(callable);
|
||||
return;
|
||||
}
|
||||
@ -229,7 +227,7 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QStri
|
||||
file->write(reply->readAll());
|
||||
onSuccess(callable,filePath);
|
||||
}else{
|
||||
onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
|
||||
onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),"");
|
||||
}
|
||||
_cache.removeOne(reply);
|
||||
reply->deleteLater();
|
||||
@ -238,6 +236,56 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QStri
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::upload(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
|
||||
QMap<QString, QVariant> data = invokeIntercept(params,headers,"upload").toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
QUrl _url(url);
|
||||
QNetworkRequest request(_url);
|
||||
addHeaders(&request,data["headers"].toMap());
|
||||
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
|
||||
for (const auto& each : data["params"].toMap().toStdMap())
|
||||
{
|
||||
const QString& key = each.first;
|
||||
const QString& filePath = each.second.toString();
|
||||
QFile *file = new QFile(filePath);
|
||||
file->open(QIODevice::ReadOnly);
|
||||
file->setParent(&multiPart);
|
||||
QString dispositionHeader = QString("form-data; name=\"%1\"; filename=\"%2\"").arg(key,filePath);
|
||||
QHttpPart part;
|
||||
part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
|
||||
part.setBodyDevice(file);
|
||||
multiPart.append(part);
|
||||
}
|
||||
QEventLoop loop;
|
||||
QNetworkReply* reply = manager.post(request,&multiPart);
|
||||
_cache.append(reply);
|
||||
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
|
||||
loop.quit();
|
||||
});
|
||||
connect(reply,&QNetworkReply::uploadProgress,this,[=](qint64 bytesSent, qint64 bytesTotal){
|
||||
onUploadProgress(callable,bytesSent,bytesTotal);
|
||||
});
|
||||
loop.exec();
|
||||
QString result = QString::fromUtf8(reply->readAll());
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString errorString = reply->errorString();
|
||||
bool isSuccess = reply->error() == QNetworkReply::NoError;
|
||||
_cache.removeOne(reply);
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
if (isSuccess) {
|
||||
onSuccess(callable,result);
|
||||
}else{
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
onFinish(callable);
|
||||
});
|
||||
}
|
||||
|
||||
QVariant FluHttp::invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method){
|
||||
QMap<QString, QVariant> requet = {
|
||||
{"params",params},
|
||||
@ -282,10 +330,10 @@ void FluHttp::onFinish(const QJSValue& callable){
|
||||
MainThread::post([=](){onFinish.call();});
|
||||
}
|
||||
|
||||
void FluHttp::onError(const QJSValue& callable,int status,QString errorString){
|
||||
void FluHttp::onError(const QJSValue& callable,int status,QString errorString,QString result){
|
||||
QJSValue onError = callable.property("onError");
|
||||
QJSValueList args;
|
||||
args<<status<<errorString;
|
||||
args<<status<<errorString<<result;
|
||||
MainThread::post([=](){onError.call(args);});
|
||||
}
|
||||
|
||||
@ -303,3 +351,11 @@ void FluHttp::onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 to
|
||||
QJSValue onDownloadProgress = callable.property("onDownloadProgress");
|
||||
MainThread::post([=](){onDownloadProgress.call(args);});
|
||||
}
|
||||
|
||||
void FluHttp::onUploadProgress(const QJSValue& callable,qint64 sent, qint64 total){
|
||||
QJSValueList args;
|
||||
args<<static_cast<double>(sent);
|
||||
args<<static_cast<double>(total);
|
||||
QJSValue onUploadProgress = callable.property("onUploadProgress");
|
||||
MainThread::post([=](){onUploadProgress.call(args);});
|
||||
}
|
||||
|
@ -20,18 +20,20 @@ private:
|
||||
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& params);
|
||||
void onStart(const QJSValue& callable);
|
||||
void onFinish(const QJSValue& callable);
|
||||
void onError(const QJSValue& callable,int status,QString errorString);
|
||||
void onError(const QJSValue& callable,int status,QString errorString,QString result);
|
||||
void onSuccess(const QJSValue& callable,QString result);
|
||||
void onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 total);
|
||||
void onUploadProgress(const QJSValue& callable,qint64 recv, qint64 total);
|
||||
public:
|
||||
explicit FluHttp(QObject *parent = nullptr);
|
||||
~FluHttp();
|
||||
//神坑!!! 如果参数使用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 get(QString url,QJSValue callable,QMap<QString, QVariant> params= {},QMap<QString, QVariant> headers = {});
|
||||
Q_INVOKABLE void post(QString url,QJSValue callable,QMap<QString, QVariant> params= {},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 upload(QString url,QJSValue callable,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
|
||||
Q_INVOKABLE void cancel();
|
||||
private:
|
||||
QList<QPointer<QNetworkReply>> _cache;
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <QClipboard>
|
||||
#include <QUuid>
|
||||
#include <QCursor>
|
||||
#include <QScreen>
|
||||
#include <QFileInfo>
|
||||
#include <QTextDocument>
|
||||
|
||||
FluTools* FluTools::m_instance = nullptr;
|
||||
@ -100,8 +102,24 @@ QString FluTools::toLocalPath(const QUrl& url){
|
||||
return url.toLocalFile();
|
||||
}
|
||||
|
||||
QString FluTools::getFileNameByUrl(const QUrl& url){
|
||||
return QFileInfo(url.toLocalFile()).fileName();
|
||||
}
|
||||
|
||||
QString FluTools::html2PlantText(const QString& html){
|
||||
QTextDocument textDocument;
|
||||
textDocument.setHtml(html);
|
||||
return textDocument.toPlainText();
|
||||
}
|
||||
|
||||
QRect FluTools::getVirtualGeometry(){
|
||||
return qApp->primaryScreen()->virtualGeometry();
|
||||
}
|
||||
|
||||
QString FluTools::getApplicationDirPath(){
|
||||
return qApp->applicationDirPath();
|
||||
}
|
||||
|
||||
QUrl FluTools::getUrlByFilePath(const QString& path){
|
||||
return QUrl::fromLocalFile(path);
|
||||
}
|
||||
|
@ -109,6 +109,32 @@ public:
|
||||
*/
|
||||
Q_INVOKABLE void deleteItem(QObject *p);
|
||||
|
||||
/**
|
||||
* @brief getFileNameByUrl
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
Q_INVOKABLE QString getFileNameByUrl(const QUrl& url);
|
||||
|
||||
/**
|
||||
* @brief getVirtualGeometry
|
||||
* @return
|
||||
*/
|
||||
Q_INVOKABLE QRect getVirtualGeometry();
|
||||
|
||||
/**
|
||||
* @brief getApplicationDirPath
|
||||
* @return
|
||||
*/
|
||||
Q_INVOKABLE QString getApplicationDirPath();
|
||||
|
||||
/**
|
||||
* @brief getUrlByFilePath
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
Q_INVOKABLE QUrl getUrlByFilePath(const QString& path);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "FluQRCode.h"
|
||||
#include "QRCode.h"
|
||||
|
||||
#include "BarcodeFormat.h"
|
||||
#include "BitMatrix.h"
|
||||
@ -6,15 +6,17 @@
|
||||
|
||||
using namespace ZXing;
|
||||
|
||||
FluQRCode::FluQRCode(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||
QRCode::QRCode(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||
{
|
||||
color(QColor(0,0,0,255));
|
||||
bgColor(QColor(255,255,255,255));
|
||||
size(100);
|
||||
setWidth(_size);
|
||||
setHeight(_size);
|
||||
connect(this,&FluQRCode::textChanged,this,[=]{update();});
|
||||
connect(this,&FluQRCode::colorChanged,this,[=]{update();});
|
||||
connect(this,&FluQRCode::sizeChanged,this,[=]{
|
||||
connect(this,&QRCode::textChanged,this,[=]{update();});
|
||||
connect(this,&QRCode::colorChanged,this,[=]{update();});
|
||||
connect(this,&QRCode::bgColorChanged,this,[=]{update();});
|
||||
connect(this,&QRCode::sizeChanged,this,[=]{
|
||||
setWidth(_size);
|
||||
setHeight(_size);
|
||||
update();
|
||||
@ -22,7 +24,7 @@ FluQRCode::FluQRCode(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||
}
|
||||
|
||||
|
||||
void FluQRCode::paint(QPainter* painter)
|
||||
void QRCode::paint(QPainter* painter)
|
||||
{
|
||||
if(_text.isEmpty()){
|
||||
return;
|
||||
@ -31,7 +33,6 @@ void FluQRCode::paint(QPainter* painter)
|
||||
return;
|
||||
}
|
||||
painter->save();
|
||||
painter->eraseRect(boundingRect());
|
||||
auto format = ZXing::BarcodeFormatFromString("QRCode");
|
||||
auto writer = MultiFormatWriter(format);
|
||||
writer.setMargin(0);
|
||||
@ -46,6 +47,9 @@ void FluQRCode::paint(QPainter* painter)
|
||||
if (qRed(pixel) == 0 && qGreen(pixel) == 0 && qBlue(pixel) == 0) {
|
||||
rgbImage.setPixelColor(x, y, _color);
|
||||
}
|
||||
if (qRed(pixel) == 255 && qGreen(pixel) == 255 && qBlue(pixel) == 255) {
|
||||
rgbImage.setPixelColor(x, y, _bgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), rgbImage);
|
@ -1,22 +1,23 @@
|
||||
#ifndef FLUQRCODE_H
|
||||
#define FLUQRCODE_H
|
||||
#ifndef QRCODE_H
|
||||
#define QRCODE_H
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQuickPaintedItem>
|
||||
#include <QPainter>
|
||||
#include "stdafx.h"
|
||||
|
||||
class FluQRCode : public QQuickPaintedItem
|
||||
class QRCode : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,text)
|
||||
Q_PROPERTY_AUTO(QColor,color)
|
||||
Q_PROPERTY_AUTO(QColor,bgColor)
|
||||
Q_PROPERTY_AUTO(int,size);
|
||||
QML_NAMED_ELEMENT(FluQRCode)
|
||||
QML_NAMED_ELEMENT(QRCode)
|
||||
public:
|
||||
explicit FluQRCode(QQuickItem *parent = nullptr);
|
||||
explicit QRCode(QQuickItem *parent = nullptr);
|
||||
void paint(QPainter* painter) override;
|
||||
|
||||
};
|
||||
|
||||
#endif // FLUQRCODE_H
|
||||
#endif // QRCODE_H
|
73
src/Screenshot.cpp
Normal file
73
src/Screenshot.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "Screenshot.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QQuickWindow>
|
||||
#include <QDir>
|
||||
#include <Def.h>
|
||||
#include <QtMath>
|
||||
#include <QThreadPool>
|
||||
|
||||
Screenshot::Screenshot(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||
{
|
||||
_desktopGeometry = qApp->primaryScreen()->virtualGeometry();
|
||||
maskColor(QColor(0,0,0,80));
|
||||
start(QPoint(0,0));
|
||||
end(QPoint(0,0));
|
||||
connect(this,&Screenshot::startChanged,this,[=]{update();});
|
||||
connect(this,&Screenshot::endChanged,this,[=]{update();});
|
||||
}
|
||||
|
||||
void Screenshot::paint(QPainter* painter)
|
||||
{
|
||||
painter->save();
|
||||
painter->fillRect(_desktopGeometry,_maskColor);
|
||||
painter->setCompositionMode(QPainter::CompositionMode_Clear);
|
||||
painter->fillRect(QRect(_start.x(),_start.y(),_end.x()-_start.x(),_end.y()-_start.y()), Qt::black);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
ScreenshotBackground::ScreenshotBackground(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||
{
|
||||
_devicePixelRatio = qApp->primaryScreen()->devicePixelRatio();
|
||||
_desktopGeometry = qApp->primaryScreen()->virtualGeometry();
|
||||
_desktopPixmap = qApp->primaryScreen()->grabWindow(0, _desktopGeometry.x(), _desktopGeometry.y(), _desktopGeometry.width(), _desktopGeometry.height());
|
||||
int w = qApp->primaryScreen()->geometry().width();
|
||||
int h = qApp->primaryScreen()->geometry().height();
|
||||
foreach (auto item, qApp->screens()) {
|
||||
if(item != qApp->primaryScreen()){
|
||||
w = w + item->geometry().width()/qApp->primaryScreen()->devicePixelRatio();
|
||||
}
|
||||
}
|
||||
setWidth(w);
|
||||
setHeight(h);
|
||||
}
|
||||
|
||||
void ScreenshotBackground::paint(QPainter* painter)
|
||||
{
|
||||
painter->save();
|
||||
_sourcePixmap = _desktopPixmap.copy();
|
||||
painter->drawPixmap(_desktopGeometry,_sourcePixmap);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void ScreenshotBackground::capture(const QPoint& start,const QPoint& end){
|
||||
auto pixelRatio = qApp->primaryScreen()->devicePixelRatio();
|
||||
auto x = qMin(start.x(),end.x()) * pixelRatio;
|
||||
auto y = qMin(start.y(),end.y()) * pixelRatio;
|
||||
auto w = qAbs(end.x()-start.x()) * pixelRatio;
|
||||
auto h = qAbs(end.y()-start.y()) * pixelRatio;
|
||||
_captureRect = QRect(x,y,w,h);
|
||||
if(_captureMode == FluScreenshotType::CaptrueMode::Pixmap){
|
||||
Q_EMIT captrueToPixmapCompleted(_sourcePixmap.copy(_captureRect));
|
||||
}
|
||||
if(_captureMode == FluScreenshotType::CaptrueMode::File){
|
||||
QDir dir = _saveFolder;
|
||||
if (!dir.exists(_saveFolder)){
|
||||
dir.mkpath(_saveFolder);
|
||||
}
|
||||
auto filePath = _saveFolder.append("/").append(QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch())).append(".png");
|
||||
_sourcePixmap.copy(_captureRect).save(filePath);
|
||||
Q_EMIT captrueToFileCompleted(QUrl::fromLocalFile(filePath));
|
||||
}
|
||||
}
|
||||
|
47
src/Screenshot.h
Normal file
47
src/Screenshot.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef SCREENSHOT_H
|
||||
#define SCREENSHOT_H
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQuickPaintedItem>
|
||||
#include <QPainter>
|
||||
#include <QQuickItemGrabResult>
|
||||
#include "stdafx.h"
|
||||
|
||||
class ScreenshotBackground : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT;
|
||||
QML_NAMED_ELEMENT(ScreenshotBackground)
|
||||
Q_PROPERTY_AUTO(QString,saveFolder);
|
||||
Q_PROPERTY_AUTO(int,captureMode);
|
||||
public:
|
||||
ScreenshotBackground(QQuickItem* parent = nullptr);
|
||||
void paint(QPainter* painter) override;
|
||||
Q_INVOKABLE void capture(const QPoint& start,const QPoint& end);
|
||||
Q_SIGNAL void captrueToPixmapCompleted(QPixmap captrue);
|
||||
Q_SIGNAL void captrueToFileCompleted(QUrl captrue);
|
||||
private:
|
||||
QRect _desktopGeometry;
|
||||
QPixmap _desktopPixmap;
|
||||
QPixmap _sourcePixmap;
|
||||
qreal _devicePixelRatio;
|
||||
QSharedPointer<QQuickItemGrabResult> _grabResult;
|
||||
QRect _captureRect;
|
||||
};
|
||||
|
||||
|
||||
class Screenshot : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(Screenshot)
|
||||
Q_PROPERTY_AUTO(QPoint,start);
|
||||
Q_PROPERTY_AUTO(QPoint,end);
|
||||
Q_PROPERTY_AUTO(QColor,maskColor);
|
||||
public:
|
||||
Screenshot(QQuickItem* parent = nullptr);
|
||||
void paint(QPainter* painter) override;
|
||||
|
||||
private:
|
||||
QRect _desktopGeometry;
|
||||
};
|
||||
|
||||
#endif // SCREENSHOT_H
|
@ -25,7 +25,7 @@ FluItem {
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(255, 255, 255, luminosity)
|
||||
color: Qt.rgba(1, 1, 1, luminosity)
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
|
@ -16,13 +16,21 @@ Button{
|
||||
Rectangle{
|
||||
id:layout_color
|
||||
radius: 5
|
||||
color: container.colorValue
|
||||
color:"#00000000"
|
||||
border.color: {
|
||||
if(hovered)
|
||||
return FluTheme.primaryColor.light
|
||||
return FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
return FluTheme.dark ? Qt.rgba(100/255,100/255,100/255,1) : Qt.rgba(200/255,200/255,200/255,1)
|
||||
}
|
||||
border.width: 1
|
||||
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
radius: 5
|
||||
color: container.colorValue
|
||||
}
|
||||
|
||||
}
|
||||
contentItem: Item{}
|
||||
onClicked: {
|
||||
|
@ -6,7 +6,7 @@ import QtQuick.Templates as T
|
||||
|
||||
ComboBox {
|
||||
id: control
|
||||
signal commit
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
@ -71,7 +71,7 @@ ComboBox {
|
||||
Keys.onEnterPressed: (event)=> handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> handleCommit(event)
|
||||
function handleCommit(event){
|
||||
control.commit()
|
||||
control.commit(control.editText)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ Button {
|
||||
property color pressedColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
|
||||
property Component iconDelegate: com_icon
|
||||
property color color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
@ -54,16 +55,22 @@ Button {
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
Component{
|
||||
id:com_icon
|
||||
FluIcon {
|
||||
id:text_icon
|
||||
font.pixelSize: iconSize
|
||||
iconSize: control.iconSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
anchors.centerIn: parent
|
||||
iconColor: control.iconColor
|
||||
iconSource: control.iconSource;
|
||||
iconSource: control.iconSource
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
Loader{
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: iconDelegate
|
||||
}
|
||||
FluTooltip{
|
||||
id:tool_tip
|
||||
|
@ -4,7 +4,7 @@ import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextArea{
|
||||
signal commit
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
@ -36,6 +36,7 @@ TextArea{
|
||||
return placeholderNormalColor
|
||||
}
|
||||
selectByMouse: true
|
||||
width: background.implicitWidth
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: control
|
||||
implicitWidth: 240
|
||||
@ -49,7 +50,7 @@ TextArea{
|
||||
insert(control.cursorPosition, "\n")
|
||||
return
|
||||
}
|
||||
control.commit()
|
||||
control.commit(control.text)
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
|
@ -16,6 +16,8 @@ Item {
|
||||
property int topPadding: 0
|
||||
property int navWidth: 300
|
||||
property int pageMode: FluNavigationViewType.Stack
|
||||
property FluMenu navItemRightMenu
|
||||
property FluMenu navItemExpanderRightMenu
|
||||
signal logoClicked
|
||||
id:control
|
||||
Item{
|
||||
@ -66,10 +68,6 @@ Item {
|
||||
}
|
||||
return data
|
||||
}
|
||||
function refreshWindow(){
|
||||
Window.window.height = Window.window.height-1
|
||||
Window.window.height = Window.window.height+1
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
d.displayMode = Qt.binding(function(){
|
||||
@ -99,9 +97,7 @@ Item {
|
||||
if(d.displayMode === FluNavigationViewType.Compact){
|
||||
collapseAll()
|
||||
}
|
||||
if(d.displayMode === FluNavigationViewType.Minimal){
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
Component{
|
||||
@ -167,6 +163,20 @@ Item {
|
||||
leftMargin: 6
|
||||
rightMargin: 6
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: function(mouse){
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
if(model.menuDelegate){
|
||||
loader_item_menu.sourceComponent = model.menuDelegate
|
||||
loader_item_menu.item.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
z:-100
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if(d.isCompactAndNotPanel){
|
||||
control_popup.showPopup(Qt.point(50,mapToItem(control,0,0).y),model.children)
|
||||
@ -189,7 +199,6 @@ Item {
|
||||
}
|
||||
visible: {
|
||||
if(!model.isExpand){
|
||||
|
||||
for(var i=0;i<model.children.length;i++){
|
||||
var item = model.children[i]
|
||||
if(item.infoBadge && item.count !==0){
|
||||
@ -317,6 +326,36 @@ Item {
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id:item_edit_loader
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: item_title.left
|
||||
right: item_title.right
|
||||
rightMargin: 8
|
||||
}
|
||||
sourceComponent: model.showEdit ? model.editDelegate : undefined
|
||||
onStatusChanged: {
|
||||
if(status === Loader.Ready){
|
||||
item.forceActiveFocus()
|
||||
item_connection_edit_focus.target = item
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
id:item_connection_edit_focus
|
||||
ignoreUnknownSignals:true
|
||||
function onActiveFocusChanged(focus){
|
||||
if(focus === false){
|
||||
model.showEdit = false
|
||||
}
|
||||
}
|
||||
function onCommit(text){
|
||||
model.title = text
|
||||
model.showEdit = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -356,6 +395,19 @@ Item {
|
||||
leftMargin: 6
|
||||
rightMargin: 6
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: function(mouse){
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
if(model.menuDelegate){
|
||||
loader_item_menu.sourceComponent = model.menuDelegate
|
||||
loader_item_menu.item.popup();
|
||||
}
|
||||
}
|
||||
}
|
||||
z:-100
|
||||
}
|
||||
onClicked: {
|
||||
if(type === 0){
|
||||
if(model.tapFunc){
|
||||
@ -468,6 +520,36 @@ Item {
|
||||
right: item_dot_loader.left
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id:item_edit_loader
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: item_title.left
|
||||
right: item_title.right
|
||||
rightMargin: 8
|
||||
}
|
||||
sourceComponent: model.showEdit ? model.editDelegate : undefined
|
||||
onStatusChanged: {
|
||||
if(status === Loader.Ready){
|
||||
item.forceActiveFocus()
|
||||
item_connection_edit_focus.target = item
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
id:item_connection_edit_focus
|
||||
ignoreUnknownSignals:true
|
||||
function onActiveFocusChanged(focus){
|
||||
if(focus === false){
|
||||
model.showEdit = false
|
||||
}
|
||||
}
|
||||
function onCommit(text){
|
||||
model.title = text
|
||||
model.showEdit = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id:item_dot_loader
|
||||
property bool isDot: (item_dot_loader.item&&item_dot_loader.item.isDot)
|
||||
@ -681,6 +763,7 @@ Item {
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
visible: d.isMinimalAndPanel||d.isCompactAndPanel
|
||||
hoverEnabled: true
|
||||
onWheel: {
|
||||
}
|
||||
onClicked: {
|
||||
@ -713,11 +796,6 @@ Item {
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
onRunningChanged: {
|
||||
if(!running){
|
||||
d.refreshWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Behavior on x {
|
||||
@ -725,11 +803,6 @@ Item {
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
onRunningChanged: {
|
||||
if(!running){
|
||||
d.refreshWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visible: {
|
||||
@ -993,6 +1066,9 @@ Item {
|
||||
control_popup.open()
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id:loader_item_menu
|
||||
}
|
||||
Component{
|
||||
id:com_placeholder
|
||||
Item{
|
||||
|
@ -19,4 +19,7 @@ QtObject {
|
||||
property int count: 0
|
||||
signal tap
|
||||
property var tapFunc
|
||||
property Component menuDelegate
|
||||
property Component editDelegate
|
||||
property bool showEdit
|
||||
}
|
||||
|
@ -10,4 +10,7 @@ FluObject {
|
||||
property Component cusIcon
|
||||
property bool isExpand: false
|
||||
property var parent
|
||||
property Component menuDelegate
|
||||
property Component editDelegate
|
||||
property bool showEdit
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextField{
|
||||
signal commit
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property int iconSource: 0
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
@ -59,7 +59,7 @@ TextField{
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
control.commit()
|
||||
control.commit(control.text)
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
|
23
src/imports/FluentUI/Controls/FluQRCode.qml
Normal file
23
src/imports/FluentUI/Controls/FluQRCode.qml
Normal file
@ -0,0 +1,23 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
property alias text: qrcode.text
|
||||
property alias color: qrcode.color
|
||||
property alias bgColor: qrcode.bgColor
|
||||
property int size: 50
|
||||
property int margins: 0
|
||||
id:control
|
||||
width: size
|
||||
height: size
|
||||
Rectangle{
|
||||
color: bgColor
|
||||
anchors.fill: parent
|
||||
}
|
||||
QRCode{
|
||||
id:qrcode
|
||||
size:control.size-margins
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
526
src/imports/FluentUI/Controls/FluScreenshot.qml
Normal file
526
src/imports/FluentUI/Controls/FluScreenshot.qml
Normal file
@ -0,0 +1,526 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import Qt.labs.platform
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
id:control
|
||||
property int captrueMode: FluScreenshotType.Pixmap
|
||||
property int dotSize: 5
|
||||
property int borderSize: 1
|
||||
property var saveFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
|
||||
property color borderColor: FluTheme.primaryColor.dark
|
||||
signal captrueCompleted(var captrue)
|
||||
|
||||
QtObject{
|
||||
id:d
|
||||
property int dotMouseSize: control.dotSize+10
|
||||
property int dotMargins: -(control.dotSize-control.borderSize)/2
|
||||
property bool enablePosition: false
|
||||
property int menuMargins: 6
|
||||
}
|
||||
Loader {
|
||||
id:loader
|
||||
}
|
||||
Component{
|
||||
id:com_screen
|
||||
Window{
|
||||
property bool isZeroPos: screenshot.start === Qt.point(0,0) && screenshot.end === Qt.point(0,0)
|
||||
id:window_screen
|
||||
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
|
||||
x:-1
|
||||
y:-1
|
||||
width: 1
|
||||
height: 1
|
||||
visible: true
|
||||
color: "#00000000"
|
||||
onVisibleChanged: {
|
||||
if(!window_screen.visible){
|
||||
loader.sourceComponent = undefined
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
setGeometry(0,0,screenshot_background.width,screenshot_background.height)
|
||||
}
|
||||
ScreenshotBackground{
|
||||
id:screenshot_background
|
||||
captureMode:control.captrueMode
|
||||
saveFolder: {
|
||||
if(typeof control.saveFolder === 'string'){
|
||||
return control.saveFolder
|
||||
}else{
|
||||
return FluTools.toLocalPath(control.saveFolder)
|
||||
}
|
||||
}
|
||||
onCaptrueToPixmapCompleted:
|
||||
(captrue)=>{
|
||||
control.captrueCompleted(captrue)
|
||||
loader.sourceComponent = undefined
|
||||
}
|
||||
onCaptrueToFileCompleted:
|
||||
(captrue)=>{
|
||||
control.captrueCompleted(captrue)
|
||||
loader.sourceComponent = undefined
|
||||
}
|
||||
}
|
||||
Screenshot{
|
||||
id:screenshot
|
||||
anchors.fill: parent
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton | Qt.LeftButton
|
||||
onPressed:
|
||||
(mouse)=>{
|
||||
if(mouse.button === Qt.LeftButton){
|
||||
d.enablePosition = true
|
||||
screenshot.start = Qt.point(mouse.x,mouse.y)
|
||||
screenshot.end = Qt.point(mouse.x,mouse.y)
|
||||
}
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(d.enablePosition){
|
||||
screenshot.end = Qt.point(mouse.x,mouse.y)
|
||||
}
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=>{
|
||||
if(mouse.button === Qt.LeftButton){
|
||||
d.enablePosition = false
|
||||
screenshot.end = Qt.point(mouse.x,mouse.y)
|
||||
}
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=>{
|
||||
if(mouse.button === Qt.LeftButton){
|
||||
d.enablePosition = false
|
||||
screenshot.end = Qt.point(mouse.x,mouse.y)
|
||||
}
|
||||
}
|
||||
onClicked:
|
||||
(mouse)=>{
|
||||
if (mouse.button === Qt.RightButton){
|
||||
if(isZeroPos){
|
||||
loader.sourceComponent = undefined
|
||||
return
|
||||
}
|
||||
screenshot.start = Qt.point(0,0)
|
||||
screenshot.end = Qt.point(0,0)
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_capture
|
||||
x:Math.min(screenshot.start.x,screenshot.end.x)
|
||||
y:Math.min(screenshot.start.y,screenshot.end.y)
|
||||
width: Math.abs(screenshot.end.x - screenshot.start.x)
|
||||
height: Math.abs(screenshot.end.y - screenshot.start.y)
|
||||
color:"#00000000"
|
||||
border.width: control.borderSize
|
||||
border.color: control.borderColor
|
||||
MouseArea{
|
||||
property point clickPos: Qt.point(0,0)
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.SizeAllCursor
|
||||
onPressed:
|
||||
(mouse)=>{
|
||||
clickPos = Qt.point(mouse.x, mouse.y)
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
var delta = Qt.point(mouse.x - clickPos.x,mouse.y - clickPos.y)
|
||||
var w = Math.abs(screenshot.end.x - screenshot.start.x)
|
||||
var h = Math.abs(screenshot.end.y - screenshot.start.y)
|
||||
var x = Math.min(Math.max(rect_capture.x + delta.x,0),window_screen.width-w)
|
||||
var y =Math.min(Math.max(rect_capture.y + delta.y,0),window_screen.height-h)
|
||||
screenshot.start = Qt.point(x,y)
|
||||
screenshot.end = Qt.point(x+w,y+h)
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_top_left
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
left: rect_capture.left
|
||||
leftMargin: d.dotMargins
|
||||
topMargin: d.dotMargins
|
||||
top: rect_capture.top
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeFDiagCursor
|
||||
anchors.centerIn: rect_top_left
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
FluTools.setOverrideCursor(cursorShape)
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x+w,y+h)
|
||||
screenshot.end = Qt.point(x,y)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
screenshot.end = mapToItem(screenshot,Qt.point(mouse.x,mouse.y))
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_top_center
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
horizontalCenter: rect_capture.horizontalCenter
|
||||
topMargin: d.dotMargins
|
||||
top: rect_capture.top
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeVerCursor
|
||||
anchors.centerIn: rect_top_center
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
FluTools.setOverrideCursor(cursorShape)
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x+w,y+h)
|
||||
screenshot.end = Qt.point(x,y)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
screenshot.end = Qt.point(x,mapToItem(screenshot,Qt.point(mouse.x,mouse.y)).y)
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_top_right
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
right: rect_capture.right
|
||||
rightMargin: d.dotMargins
|
||||
topMargin: d.dotMargins
|
||||
top: rect_capture.top
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeBDiagCursor
|
||||
anchors.centerIn: rect_top_right
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x,y+h)
|
||||
screenshot.end = Qt.point(x+w,y)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
screenshot.end = mapToItem(screenshot,Qt.point(mouse.x,mouse.y))
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_right_center
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
right: rect_capture.right
|
||||
rightMargin: d.dotMargins
|
||||
verticalCenter: rect_capture.verticalCenter
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeHorCursor
|
||||
anchors.centerIn: rect_right_center
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x,y)
|
||||
screenshot.end = Qt.point(x+w,y+h)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
var y = rect_capture.y
|
||||
var h = rect_capture.height
|
||||
screenshot.end = Qt.point(mapToItem(screenshot,Qt.point(mouse.x,mouse.y)).x,y+h)
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_right_bottom
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
right: rect_capture.right
|
||||
rightMargin: d.dotMargins
|
||||
bottom: rect_capture.bottom
|
||||
bottomMargin: d.dotMargins
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeFDiagCursor
|
||||
anchors.centerIn: rect_right_bottom
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x,y)
|
||||
screenshot.end = Qt.point(x+w,y+h)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
screenshot.end = mapToItem(screenshot,Qt.point(mouse.x,mouse.y))
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_bottom_center
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
horizontalCenter: rect_capture.horizontalCenter
|
||||
bottom: rect_capture.bottom
|
||||
bottomMargin: d.dotMargins
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeVerCursor
|
||||
anchors.centerIn: rect_bottom_center
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x,y)
|
||||
screenshot.end = Qt.point(x+w,y+h)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var w = rect_capture.width
|
||||
screenshot.end = Qt.point(x+w,mapToItem(screenshot,Qt.point(mouse.x,mouse.y)).y)
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_bottom_left
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
left: rect_capture.left
|
||||
leftMargin: d.dotMargins
|
||||
bottom: rect_capture.bottom
|
||||
bottomMargin: d.dotMargins
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeBDiagCursor
|
||||
anchors.centerIn: rect_bottom_left
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x+w,y)
|
||||
screenshot.end = Qt.point(x,y+h)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
screenshot.end = mapToItem(screenshot,Qt.point(mouse.x,mouse.y))
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_left_center
|
||||
width: control.dotSize
|
||||
height: control.dotSize
|
||||
color: control.borderColor
|
||||
visible: !isZeroPos
|
||||
anchors{
|
||||
left: rect_capture.left
|
||||
leftMargin: d.dotMargins
|
||||
verticalCenter: rect_capture.verticalCenter
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
cursorShape: Qt.SizeHorCursor
|
||||
anchors.centerIn: rect_left_center
|
||||
width: d.dotMouseSize
|
||||
height: d.dotMouseSize
|
||||
visible: !isZeroPos
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
var x = rect_capture.x
|
||||
var y = rect_capture.y
|
||||
var w = rect_capture.width
|
||||
var h = rect_capture.height
|
||||
screenshot.start = Qt.point(x+w,y)
|
||||
screenshot.end = Qt.point(x,y+h)
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
var y = rect_capture.y
|
||||
var h = rect_capture.height
|
||||
screenshot.end = Qt.point(mapToItem(screenshot,Qt.point(mouse.x,mouse.y)).x,y+h)
|
||||
}
|
||||
onCanceled:
|
||||
(mouse)=> {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
}
|
||||
Pane{
|
||||
width: 100
|
||||
height: 40
|
||||
visible: {
|
||||
if(screenshot.start === Qt.point(0,0) && screenshot.end === Qt.point(0,0)){
|
||||
return false
|
||||
}
|
||||
if(d.enablePosition){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
x:rect_capture.x + rect_capture.width - width
|
||||
y:{
|
||||
if(rect_capture.y + rect_capture.height + d.menuMargins < screenshot.height-height){
|
||||
return rect_capture.y + rect_capture.height + d.menuMargins
|
||||
}else if(rect_capture.y - height - d.menuMargins > 0){
|
||||
return rect_capture.y - height - d.menuMargins
|
||||
}else{
|
||||
screenshot.height - height - d.menuMargins
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
FluIconButton{
|
||||
iconSource: FluentIcons.Cancel
|
||||
iconSize: 18
|
||||
iconColor: Qt.rgba(247/255,75/255,77/255,1)
|
||||
onClicked: {
|
||||
loader.sourceComponent = undefined
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
iconSource: FluentIcons.AcceptMedium
|
||||
iconColor: FluTheme.primaryColor.dark
|
||||
onClicked: {
|
||||
screenshot_background.capture(screenshot.start,screenshot.end)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function open(){
|
||||
loader.sourceComponent = com_screen
|
||||
}
|
||||
}
|
@ -32,6 +32,8 @@ Rectangle {
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property int defaultItemWidth: 100
|
||||
property int defaultItemHeight: 42
|
||||
property var header_rows:[]
|
||||
property bool selectionFlag: true
|
||||
function obtEditDelegate(column,row){
|
||||
@ -182,6 +184,12 @@ Rectangle {
|
||||
}
|
||||
columnWidthProvider: function(column) {
|
||||
var w = columnSource[column].width
|
||||
if(!w){
|
||||
w = columnSource[column].minimumWidth
|
||||
}
|
||||
if(!w){
|
||||
w = d.defaultItemWidth
|
||||
}
|
||||
if(column === item_loader.column){
|
||||
item_loader.width = w
|
||||
}
|
||||
@ -199,6 +207,12 @@ Rectangle {
|
||||
return 0
|
||||
}
|
||||
var h = table_model.getRow(row).height
|
||||
if(!h){
|
||||
h = table_model.getRow(row).minimumHeight
|
||||
}
|
||||
if(!h){
|
||||
return d.defaultItemHeight
|
||||
}
|
||||
if(row === item_loader.row){
|
||||
item_loader.height = h
|
||||
}
|
||||
@ -219,7 +233,16 @@ Rectangle {
|
||||
required property bool selected
|
||||
color: (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06))
|
||||
implicitHeight: 40
|
||||
implicitWidth: columnSource[column].width
|
||||
implicitWidth: {
|
||||
var w = columnSource[column].width
|
||||
if(!w){
|
||||
w = columnSource[column].minimumWidth
|
||||
}
|
||||
if(!w){
|
||||
w = d.defaultItemWidth
|
||||
}
|
||||
return w
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
visible: !item_loader.sourceComponent
|
||||
@ -378,7 +401,7 @@ Rectangle {
|
||||
anchors.right: parent.right
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
visible: !(obj.width === obj.minimumWidth && obj.width === obj.maximumWidth)
|
||||
visible: !(obj.width === obj.minimumWidth && obj.width === obj.maximumWidth && obj.width)
|
||||
cursorShape: Qt.SplitHCursor
|
||||
onPressed :
|
||||
(mouse)=>{
|
||||
@ -402,13 +425,17 @@ Rectangle {
|
||||
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
|
||||
var minimumWidth = obj.minimumWidth
|
||||
var maximumWidth = obj.maximumWidth
|
||||
var w = obj.width
|
||||
if(!w){
|
||||
w = d.defaultItemWidth
|
||||
}
|
||||
if(!minimumWidth){
|
||||
minimumWidth = 100
|
||||
minimumWidth = d.defaultItemWidth
|
||||
}
|
||||
if(!maximumWidth){
|
||||
maximumWidth = 65535
|
||||
}
|
||||
obj.width = Math.min(Math.max(minimumWidth, obj.width + delta.x),maximumWidth)
|
||||
obj.width = Math.min(Math.max(minimumWidth, w + delta.x),maximumWidth)
|
||||
table_view.forceLayout()
|
||||
}
|
||||
}
|
||||
@ -492,7 +519,7 @@ Rectangle {
|
||||
cursorShape: Qt.SplitVCursor
|
||||
visible: {
|
||||
var obj = table_model.getRow(row)
|
||||
return !(obj.height === obj.minimumHeight && obj.width === obj.maximumHeight)
|
||||
return !(obj.height === obj.minimumHeight && obj.height === obj.maximumHeight && obj.height)
|
||||
}
|
||||
onPressed :
|
||||
(mouse)=>{
|
||||
@ -517,13 +544,17 @@ Rectangle {
|
||||
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
|
||||
var minimumHeight = obj.minimumHeight
|
||||
var maximumHeight = obj.maximumHeight
|
||||
var h = obj.height
|
||||
if(!h){
|
||||
h = d.defaultItemHeight
|
||||
}
|
||||
if(!minimumHeight){
|
||||
minimumHeight = 42
|
||||
minimumHeight = d.defaultItemHeight
|
||||
}
|
||||
if(!maximumHeight){
|
||||
maximumHeight = 65535
|
||||
}
|
||||
obj.height = Math.min(Math.max(minimumHeight, obj.height + delta.y),maximumHeight)
|
||||
obj.height = Math.min(Math.max(minimumHeight, h + delta.y),maximumHeight)
|
||||
table_model.setRow(row,obj)
|
||||
table_view.forceLayout()
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextField{
|
||||
signal commit
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property int iconSource: 0
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
@ -60,7 +60,7 @@ TextField{
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
control.commit()
|
||||
control.commit(control.text)
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
|
@ -5,7 +5,7 @@ import FluentUI
|
||||
Item{
|
||||
property int mode: FluTimelineType.Left
|
||||
property alias model: repeater.model
|
||||
property color lineColor: Qt.rgba(240/255,240/255,240/255,1)
|
||||
property color lineColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
|
||||
id:control
|
||||
implicitWidth: 380
|
||||
implicitHeight: layout_column.height
|
||||
@ -90,21 +90,19 @@ Item{
|
||||
id:com_lable
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
horizontalAlignment: textAlignment
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.lable
|
||||
color: FluTheme.primaryColor.dark
|
||||
color: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_text
|
||||
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
horizontalAlignment: textAlignment
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.text
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Column{
|
||||
@ -152,7 +150,7 @@ Item{
|
||||
|
||||
Loader{
|
||||
property var modelData: control.model.get(index)
|
||||
property int textAlignment: state === "Right" ? Qt.AlignRight : Qt.AlignLeft
|
||||
property bool isRight: state === "Right"
|
||||
id:loader_lable
|
||||
sourceComponent: {
|
||||
if(!modelData){
|
||||
@ -223,7 +221,7 @@ Item{
|
||||
Loader{
|
||||
id:loader_text
|
||||
property var modelData: control.model.get(index)
|
||||
property int textAlignment: state === "Right" ? Qt.AlignRight : Qt.AlignLeft
|
||||
property bool isRight: state === "Right"
|
||||
state: {
|
||||
if(d.isRight){
|
||||
return "Right"
|
||||
@ -288,10 +286,7 @@ Item{
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,9 +58,18 @@ Popup{
|
||||
target: d.window
|
||||
function onWidthChanged(){
|
||||
canvas.requestPaint()
|
||||
timer_delay.restart()
|
||||
}
|
||||
function onHeightChanged(){
|
||||
canvas.requestPaint()
|
||||
timer_delay.restart()
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 200
|
||||
onTriggered: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
}
|
||||
Canvas{
|
||||
|
@ -10,6 +10,12 @@ Window {
|
||||
property var argument:({})
|
||||
property var background : com_background
|
||||
property Component loadingItem: com_loading
|
||||
property color backgroundColor: {
|
||||
if(active){
|
||||
return FluTheme.dark ? Qt.rgba(26/255,34/255,40/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(237/255,237/255,237/255,1)
|
||||
}
|
||||
property var _pageRegister
|
||||
property string _route
|
||||
property var closeFunc: function(event){
|
||||
@ -34,12 +40,7 @@ Window {
|
||||
Component{
|
||||
id:com_background
|
||||
Rectangle{
|
||||
color: {
|
||||
if(active){
|
||||
return FluTheme.dark ? Qt.rgba(26/255,34/255,40/255,1) : Qt.rgba(238/255,244/255,249/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
}
|
||||
color: window.backgroundColor
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
|
@ -1,86 +0,0 @@
|
||||
module FluentUI
|
||||
classname FluentUIPlugin
|
||||
typeinfo plugins.qmltypes
|
||||
|
||||
FluAcrylic 1.0 Controls/FluAcrylic.qml
|
||||
FluAppBar 1.0 Controls/FluAppBar.qml
|
||||
FluArea 1.0 Controls/FluArea.qml
|
||||
FluAutoSuggestBox 1.0 Controls/FluAutoSuggestBox.qml
|
||||
FluBadge 1.0 Controls/FluBadge.qml
|
||||
FluBreadcrumbBar 1.0 Controls/FluBreadcrumbBar.qml
|
||||
FluButton 1.0 Controls/FluButton.qml
|
||||
FluCalendarPicker 1.0 Controls/FluCalendarPicker.qml
|
||||
FluCalendarView 1.0 Controls/FluCalendarView.qml
|
||||
FluCarousel 1.0 Controls/FluCarousel.qml
|
||||
FluCheckBox 1.0 Controls/FluCheckBox.qml
|
||||
FluColorPicker 1.0 Controls/FluColorPicker.qml
|
||||
FluColorView 1.0 Controls/FluColorView.qml
|
||||
FluComboBox 1.0 Controls/FluComboBox.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
|
||||
FluDropDownButton 1.0 Controls/FluDropDownButton.qml
|
||||
FluExpander 1.0 Controls/FluExpander.qml
|
||||
FluFilledButton 1.0 Controls/FluFilledButton.qml
|
||||
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
|
||||
FluItemDelegate 1.0 Controls/FluItemDelegate.qml
|
||||
FluMenu 1.0 Controls/FluMenu.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
|
||||
FluPage 1.0 Controls/FluPage.qml
|
||||
FluPagination 1.0 Controls/FluPagination.qml
|
||||
FluPaneItem 1.0 Controls/FluPaneItem.qml
|
||||
FluPaneItemEmpty 1.0 Controls/FluPaneItemEmpty.qml
|
||||
FluPaneItemExpander 1.0 Controls/FluPaneItemExpander.qml
|
||||
FluPaneItemHeader 1.0 Controls/FluPaneItemHeader.qml
|
||||
FluPaneItemSeparator 1.0 Controls/FluPaneItemSeparator.qml
|
||||
FluPasswordBox 1.0 Controls/FluPasswordBox.qml
|
||||
FluPivot 1.0 Controls/FluPivot.qml
|
||||
FluPivotItem 1.0 Controls/FluPivotItem.qml
|
||||
FluPopup 1.0 Controls/FluPopup.qml
|
||||
FluProgressBar 1.0 Controls/FluProgressBar.qml
|
||||
FluProgressRing 1.0 Controls/FluProgressRing.qml
|
||||
FluRadioButton 1.0 Controls/FluRadioButton.qml
|
||||
FluRadioButtons 1.0 Controls/FluRadioButtons.qml
|
||||
FluRatingControl 1.0 Controls/FluRatingControl.qml
|
||||
FluRectangle 1.0 Controls/FluRectangle.qml
|
||||
FluRemoteLoader 1.0 Controls/FluRemoteLoader.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
|
||||
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
|
||||
FluTextBoxMenu 1.0 Controls/FluTextBoxMenu.qml
|
||||
FluTextButton 1.0 Controls/FluTextButton.qml
|
||||
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
|
||||
FluTimeline 1.0 Controls/FluTimeline.qml
|
||||
FluChart 1.0 Controls/FluChart.qml
|
||||
plugin fluentuiplugin
|
Reference in New Issue
Block a user