mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-08 12:47:40 +08:00
Compare commits
24 Commits
1.7.3
...
5fd934b5f5
Author | SHA1 | Date | |
---|---|---|---|
5fd934b5f5 | |||
b7fde5f79c | |||
41cbeef3fd | |||
f616a2da6a | |||
b6c3f0eda9 | |||
06aa16c0eb | |||
c52439ac39 | |||
e81a2cc849 | |||
485bcc8acc | |||
07fedb43a8 | |||
d6c0492665 | |||
9d06c6d1e9 | |||
0ca486dfa1 | |||
3257f59c68 | |||
ff68491baf | |||
247b8db7c4 | |||
07a43825d1 | |||
e0254f2f80 | |||
37101c97c5 | |||
7e1490f8f4 | |||
98770cb907 | |||
bd942659df | |||
796be2a8f2 | |||
d655dc0141 |
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(example VERSION 1.0 LANGUAGES CXX)
|
||||
project(example VERSION 1.0)
|
||||
|
||||
#配置通用编译
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
@ -166,7 +166,7 @@ if (CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
add_custom_target(Script-DeployRelease
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/dist
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${CMAKE_SOURCE_DIR}/dist
|
||||
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/dist/${PROJECT_NAME}.exe -qmldir=${CMAKE_CURRENT_LIST_DIR}
|
||||
COMMAND ${QT_DEPLOY_QT} --qmldir=${CMAKE_CURRENT_LIST_DIR} --plugindir ${CMAKE_SOURCE_DIR}/dist/plugins --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/dist/${PROJECT_NAME}.exe
|
||||
COMMENT "Windows Deploying Qt Dependencies After Build........."
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
@ -181,8 +181,6 @@
|
||||
<file>res/image/image_1.jpg</file>
|
||||
<file>qml/window/PageWindow.qml</file>
|
||||
<file>qml/page/T_StaggeredLayout.qml</file>
|
||||
<file>qml/viewmodel/SettingsViewModel.qml</file>
|
||||
<file>qml/viewmodel/TextBoxViewModel.qml</file>
|
||||
<file>qml/page/T_Clip.qml</file>
|
||||
<file>qml/page/T_3D.qml</file>
|
||||
<file>qml/page/T_Network.qml</file>
|
||||
@ -208,5 +206,6 @@
|
||||
<file>res/template/src/qml.qrc.in</file>
|
||||
<file>res/template/src/zh_CN.ts.in</file>
|
||||
<file>res/template/src/README.md.in</file>
|
||||
<file>qml/global/GlobalModel.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -535,104 +535,104 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="322"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="98"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="106"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="83"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="91"/>
|
||||
<source>Quit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="99"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="84"/>
|
||||
<source>Are you sure you want to exit the program?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="100"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="85"/>
|
||||
<source>Minimize</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>Friendly Reminder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="107"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="351"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="92"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="336"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="118"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<source>Open in Separate Window</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="215"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="200"/>
|
||||
<source>Click Time</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="225"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="210"/>
|
||||
<source>Search</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="316"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="301"/>
|
||||
<source>Finish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="317"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="302"/>
|
||||
<source>Next</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="318"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="303"/>
|
||||
<source>Previous</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="322"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Here you can switch to night mode.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="324"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Hide Easter eggs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="324"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Try a few more clicks!!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="348"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="333"/>
|
||||
<source>Upgrade Tips</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="349"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>FluentUI is currently up to date </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="349"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source> -- The current app version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="349"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>
|
||||
Now go and download the new version?
|
||||
|
||||
@ -641,17 +641,17 @@ Updated content:
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="352"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="379"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="364"/>
|
||||
<source>The current version is already the latest</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="386"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="371"/>
|
||||
<source>The network is abnormal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1149,7 +1149,8 @@ Updated content:
|
||||
<name>T_DatePicker</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_DatePicker.qml" line="10"/>
|
||||
<source>TimePicker</source>
|
||||
<source>DatePicker</source>
|
||||
<oldsource>TimePicker</oldsource>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
@ -1521,46 +1522,46 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_MultiWindow</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="13"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="12"/>
|
||||
<source>MultiWindow</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="35"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="36"/>
|
||||
<source><font color='red'>Standard</font> mode window,a new window is created every time</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="38"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="62"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="85"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="119"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="154"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="39"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="63"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="86"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="120"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="155"/>
|
||||
<source>Create Window</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="58"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="59"/>
|
||||
<source><font color='red'>SingleTask</font> mode window,If a window exists, this activates the window</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="82"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="83"/>
|
||||
<source><font color='red'>SingleInstance</font> mode window,If the window exists, destroy the window and create a new window</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="116"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="117"/>
|
||||
<source>Create the window without carrying any parameters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="151"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="152"/>
|
||||
<source>Create a window with the parameter username: zhuzichu</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="160"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="161"/>
|
||||
<source>Login Window Returned Password - ></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1568,7 +1569,7 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_Network</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_Network.qml" line="12"/>
|
||||
<location filename="qml/page/T_Network.qml" line="13"/>
|
||||
<source>Network</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1735,97 +1736,97 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_Settings</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="12"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="11"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="43"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="29"/>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="49"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="35"/>
|
||||
<source>Check for Updates</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="65"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="51"/>
|
||||
<source>Use System AppBar</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="81"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="67"/>
|
||||
<source>Fits AppBar Windows</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="92"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="78"/>
|
||||
<source>Friendly Reminder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="93"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="79"/>
|
||||
<source>This action requires a restart of the program to take effect, is it restarted?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="95"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="81"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="96"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="82"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="115"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="101"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="120"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="106"/>
|
||||
<source>System</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="120"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="106"/>
|
||||
<source>Light</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="120"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="106"/>
|
||||
<source>Dark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="145"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="131"/>
|
||||
<source>Navigation View Display Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Open</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Compact</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Minimal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Auto</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="185"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="171"/>
|
||||
<source>Language</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2023,36 +2024,36 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_TextBox</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="11"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="10"/>
|
||||
<source>TextBox</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="24"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="19"/>
|
||||
<source>Single-line Input Box</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="43"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="74"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="112"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="143"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="172"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="34"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="65"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="98"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="129"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="158"/>
|
||||
<source>Disabled</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="61"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="52"/>
|
||||
<source>Please enter your password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="94"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="84"/>
|
||||
<source>Multi-line Input Box</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="129"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="115"/>
|
||||
<source>AutoSuggestBox</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -535,104 +535,104 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="322"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished">夜间模式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="98"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="106"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="83"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="91"/>
|
||||
<source>Quit</source>
|
||||
<translation type="unfinished">退出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="99"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="84"/>
|
||||
<source>Are you sure you want to exit the program?</source>
|
||||
<translation type="unfinished">您确定要退出程序吗</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="100"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="85"/>
|
||||
<source>Minimize</source>
|
||||
<translation type="unfinished">最小化</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>Friendly Reminder</source>
|
||||
<translation type="unfinished">友情提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
|
||||
<translation type="unfinished">FluentUI 在托盘中处于隐藏状态,单击托盘以再次激活窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="107"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="351"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="92"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="336"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="118"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<source>Open in Separate Window</source>
|
||||
<translation type="unfinished">在独立窗口中打开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="215"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="200"/>
|
||||
<source>Click Time</source>
|
||||
<translation type="unfinished">点击次数</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="225"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="210"/>
|
||||
<source>Search</source>
|
||||
<translation type="unfinished">搜索</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="316"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="301"/>
|
||||
<source>Finish</source>
|
||||
<translation type="unfinished">完成</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="317"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="302"/>
|
||||
<source>Next</source>
|
||||
<translation type="unfinished">下一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="318"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="303"/>
|
||||
<source>Previous</source>
|
||||
<translation type="unfinished">上一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="322"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Here you can switch to night mode.</source>
|
||||
<translation type="unfinished">在这里,您可以切换到夜间模式。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="324"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Hide Easter eggs</source>
|
||||
<translation type="unfinished">隐藏彩蛋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="324"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Try a few more clicks!!</source>
|
||||
<translation type="unfinished">再试几下!!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="348"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="333"/>
|
||||
<source>Upgrade Tips</source>
|
||||
<translation type="unfinished">升级提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="349"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>FluentUI is currently up to date </source>
|
||||
<translation type="unfinished">FluentUI 目前最新版本 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="349"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source> -- The current app version</source>
|
||||
<translation type="unfinished"> -- 当前应用版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="349"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>
|
||||
Now go and download the new version?
|
||||
|
||||
@ -645,17 +645,17 @@ Updated content:
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="352"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="379"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="364"/>
|
||||
<source>The current version is already the latest</source>
|
||||
<translation type="unfinished">当前版本已经是最新版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="386"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="371"/>
|
||||
<source>The network is abnormal</source>
|
||||
<translation type="unfinished">网络异常</translation>
|
||||
</message>
|
||||
@ -1153,8 +1153,8 @@ Updated content:
|
||||
<name>T_DatePicker</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_DatePicker.qml" line="10"/>
|
||||
<source>TimePicker</source>
|
||||
<translation type="unfinished">时间选择器</translation>
|
||||
<source>DatePicker</source>
|
||||
<translation type="unfinished">日期选择器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_DatePicker.qml" line="23"/>
|
||||
@ -1561,46 +1561,46 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_MultiWindow</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="13"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="12"/>
|
||||
<source>MultiWindow</source>
|
||||
<translation type="unfinished">多窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="35"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="36"/>
|
||||
<source><font color='red'>Standard</font> mode window,a new window is created every time</source>
|
||||
<translation type="unfinished"><font color='red'>Standard</font> 模式窗口,每次都会创建新窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="38"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="62"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="85"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="119"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="154"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="39"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="63"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="86"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="120"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="155"/>
|
||||
<source>Create Window</source>
|
||||
<translation type="unfinished">创建窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="58"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="59"/>
|
||||
<source><font color='red'>SingleTask</font> mode window,If a window exists, this activates the window</source>
|
||||
<translation type="unfinished"><font color='red'>SingleTask</font> 模式窗口,如果窗口存在,这激活该窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="82"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="83"/>
|
||||
<source><font color='red'>SingleInstance</font> mode window,If the window exists, destroy the window and create a new window</source>
|
||||
<translation type="unfinished"><font color='red'>SingleInstance</font> 模式窗口,如果窗口存在,则销毁窗口,然后新建窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="116"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="117"/>
|
||||
<source>Create the window without carrying any parameters</source>
|
||||
<translation type="unfinished">创建一个窗口,不携带任何参数</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="151"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="152"/>
|
||||
<source>Create a window with the parameter username: zhuzichu</source>
|
||||
<translation type="unfinished">创建一个窗口,并携带参数用户名:zhuzichu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="160"/>
|
||||
<location filename="qml/page/T_MultiWindow.qml" line="161"/>
|
||||
<source>Login Window Returned Password - ></source>
|
||||
<translation type="unfinished">登录窗口返回过来的密码 - ></translation>
|
||||
</message>
|
||||
@ -1608,7 +1608,7 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_Network</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_Network.qml" line="12"/>
|
||||
<location filename="qml/page/T_Network.qml" line="13"/>
|
||||
<source>Network</source>
|
||||
<translation type="unfinished">网络</translation>
|
||||
</message>
|
||||
@ -1785,97 +1785,97 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_Settings</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="12"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="11"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="43"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="29"/>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished">当前版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="49"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="35"/>
|
||||
<source>Check for Updates</source>
|
||||
<translation type="unfinished">检查更新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="65"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="51"/>
|
||||
<source>Use System AppBar</source>
|
||||
<translation type="unfinished">使用系统应用栏</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="81"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="67"/>
|
||||
<source>Fits AppBar Windows</source>
|
||||
<translation type="unfinished">沉浸式应用栏</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="92"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="78"/>
|
||||
<source>Friendly Reminder</source>
|
||||
<translation type="unfinished">友情提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="93"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="79"/>
|
||||
<source>This action requires a restart of the program to take effect, is it restarted?</source>
|
||||
<translation type="unfinished">此操作需要重启程序才能生效,是否重新启动?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="95"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="81"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="96"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="82"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="115"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="101"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished">夜间模式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="120"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="106"/>
|
||||
<source>System</source>
|
||||
<translation type="unfinished">跟随系统</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="120"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="106"/>
|
||||
<source>Light</source>
|
||||
<translation type="unfinished">浅色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="120"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="106"/>
|
||||
<source>Dark</source>
|
||||
<translation type="unfinished">深色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="145"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="131"/>
|
||||
<source>Navigation View Display Mode</source>
|
||||
<translation type="unfinished">导航视图</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Open</source>
|
||||
<translation type="unfinished">开放</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Compact</source>
|
||||
<translation type="unfinished">紧凑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Minimal</source>
|
||||
<translation type="unfinished">极简</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="150"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="136"/>
|
||||
<source>Auto</source>
|
||||
<translation type="unfinished">自动</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Settings.qml" line="185"/>
|
||||
<location filename="qml/page/T_Settings.qml" line="171"/>
|
||||
<source>Language</source>
|
||||
<translation type="unfinished">语言</translation>
|
||||
</message>
|
||||
@ -2093,36 +2093,36 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
<context>
|
||||
<name>T_TextBox</name>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="11"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="10"/>
|
||||
<source>TextBox</source>
|
||||
<translation type="unfinished">文本框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="24"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="19"/>
|
||||
<source>Single-line Input Box</source>
|
||||
<translation type="unfinished">单行输入框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="43"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="74"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="112"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="143"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="172"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="34"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="65"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="98"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="129"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="158"/>
|
||||
<source>Disabled</source>
|
||||
<translation type="unfinished">禁用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="61"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="52"/>
|
||||
<source>Please enter your password</source>
|
||||
<translation type="unfinished">请输入您的密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="94"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="84"/>
|
||||
<source>Multi-line Input Box</source>
|
||||
<translation type="unfinished">多行输入框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TextBox.qml" line="129"/>
|
||||
<location filename="qml/page/T_TextBox.qml" line="115"/>
|
||||
<source>AutoSuggestBox</source>
|
||||
<translation type="unfinished">自动建议框</translation>
|
||||
</message>
|
||||
|
@ -4,33 +4,29 @@ import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
FluLauncher {
|
||||
id: app
|
||||
|
||||
Connections{
|
||||
target: FluTheme
|
||||
function onDarkModeChanged(){
|
||||
SettingsHelper.saveDarkMode(FluTheme.darkMode)
|
||||
}
|
||||
}
|
||||
|
||||
Connections{
|
||||
target: FluApp
|
||||
function onUseSystemAppBarChanged(){
|
||||
SettingsHelper.saveUseSystemAppBar(FluApp.useSystemAppBar)
|
||||
}
|
||||
}
|
||||
|
||||
Connections{
|
||||
target: TranslateHelper
|
||||
function onCurrentChanged(){
|
||||
SettingsHelper.saveLanguage(TranslateHelper.current)
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
FluNetwork.openLog = false
|
||||
FluNetwork.setInterceptor(function(param){
|
||||
Network.openLog = false
|
||||
Network.setInterceptor(function(param){
|
||||
param.addHeader("Token","000000000000000000000")
|
||||
})
|
||||
FluApp.init(app,Qt.locale(TranslateHelper.current))
|
||||
@ -38,7 +34,7 @@ Item {
|
||||
FluApp.useSystemAppBar = SettingsHelper.getUseSystemAppBar()
|
||||
FluTheme.darkMode = SettingsHelper.getDarkMode()
|
||||
FluTheme.enableAnimation = true
|
||||
FluApp.routes = {
|
||||
FluRouter.routes = {
|
||||
"/":"qrc:/example/qml/window/MainWindow.qml",
|
||||
"/about":"qrc:/example/qml/window/AboutWindow.qml",
|
||||
"/login":"qrc:/example/qml/window/LoginWindow.qml",
|
||||
@ -51,9 +47,9 @@ Item {
|
||||
}
|
||||
var args = Qt.application.arguments
|
||||
if(args.length>=2 && args[1].startsWith("-crashed=")){
|
||||
FluApp.navigate("/crash",{crashFilePath:args[1].replace("-crashed=","")})
|
||||
FluRouter.navigate("/crash",{crashFilePath:args[1].replace("-crashed=","")})
|
||||
}else{
|
||||
FluApp.navigate("/")
|
||||
FluRouter.navigate("/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,9 @@ FluExpander{
|
||||
"FluLoadingButton",
|
||||
"FluClip",
|
||||
"FluNetwork",
|
||||
"FluShortcutPicker"
|
||||
"FluShortcutPicker",
|
||||
"FluWindowResultLauncher",
|
||||
"FluRouter"
|
||||
];
|
||||
code = code.replace(/\n/g, "<br>");
|
||||
code = code.replace(/ /g, " ");
|
||||
|
10
example/qml/global/GlobalModel.qml
Normal file
10
example/qml/global/GlobalModel.qml
Normal file
@ -0,0 +1,10 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
QtObject{
|
||||
|
||||
property int displayMode: FluNavigationViewType.Auto
|
||||
|
||||
}
|
@ -16,7 +16,7 @@ FluObject{
|
||||
title:qsTr("About")
|
||||
icon:FluentIcons.Contact
|
||||
onTapListener:function(){
|
||||
FluApp.navigate("/about")
|
||||
FluRouter.navigate("/about")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +462,7 @@ FluObject{
|
||||
FluPaneItem{
|
||||
title: qsTr("Hot Loader")
|
||||
onTapListener: function(){
|
||||
FluApp.navigate("/hotload")
|
||||
FluRouter.navigate("/hotload")
|
||||
}
|
||||
}
|
||||
FluPaneItem{
|
||||
|
@ -1,2 +1,3 @@
|
||||
singleton ItemsOriginal 1.0 ItemsOriginal.qml
|
||||
singleton ItemsOriginal 1.0 ItemsOriginal.qml
|
||||
singleton ItemsFooter 1.0 ItemsFooter.qml
|
||||
singleton GlobalModel 1.0 GlobalModel.qml
|
||||
|
@ -7,7 +7,7 @@ import "../component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title: qsTr("TimePicker")
|
||||
title: qsTr("DatePicker")
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
|
@ -8,16 +8,17 @@ import "../component"
|
||||
FluScrollablePage{
|
||||
|
||||
property string password: ""
|
||||
property var loginPageRegister: registerForWindowResult("/login")
|
||||
|
||||
title: qsTr("MultiWindow")
|
||||
|
||||
Connections{
|
||||
target: loginPageRegister
|
||||
function onResult(data)
|
||||
{
|
||||
password = data.password
|
||||
}
|
||||
FluWindowResultLauncher{
|
||||
id:loginResultLauncher
|
||||
path: "/login"
|
||||
onResult:
|
||||
(data)=>{
|
||||
password = data.password
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FluArea{
|
||||
@ -37,7 +38,7 @@ FluScrollablePage{
|
||||
FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
FluApp.navigate("/standardWindow")
|
||||
FluRouter.navigate("/standardWindow")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,7 +62,7 @@ FluScrollablePage{
|
||||
FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
FluApp.navigate("/singleTaskWindow")
|
||||
FluRouter.navigate("/singleTaskWindow")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,7 +85,7 @@ FluScrollablePage{
|
||||
FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
FluApp.navigate("/singleInstanceWindow")
|
||||
FluRouter.navigate("/singleInstanceWindow")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +119,7 @@ FluScrollablePage{
|
||||
FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
FluApp.navigate("/about")
|
||||
FluRouter.navigate("/about")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,7 +130,7 @@ FluScrollablePage{
|
||||
code:'FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
FluApp.navigate("/about")
|
||||
FluRouter.navigate("/about")
|
||||
}
|
||||
}
|
||||
'
|
||||
@ -153,7 +154,7 @@ FluScrollablePage{
|
||||
FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
loginPageRegister.launch({username:"zhuzichu"})
|
||||
loginResultLauncher.launch({username:"zhuzichu"})
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
@ -164,20 +165,19 @@ FluScrollablePage{
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: -1
|
||||
code:'property var loginPageRegister: registerForWindowResult("/login")
|
||||
|
||||
Connections{
|
||||
target: loginPageRegister
|
||||
function onResult(data)
|
||||
{
|
||||
password = data.password
|
||||
}
|
||||
code:'FluWindowResultLauncher{
|
||||
id:loginResultLauncher
|
||||
path: "/login"
|
||||
onResult:
|
||||
(data)=>{
|
||||
password = data.password
|
||||
}
|
||||
}
|
||||
|
||||
FluButton{
|
||||
text: qsTr("Create Window")
|
||||
onClicked: {
|
||||
loginPageRegister.launch({username:"zhuzichu"})
|
||||
loginResultLauncher.launch({username:"zhuzichu"})
|
||||
}
|
||||
}
|
||||
'
|
||||
|
@ -4,6 +4,7 @@ import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
import Qt.labs.platform 1.0
|
||||
import example 1.0
|
||||
import "../component"
|
||||
|
||||
FluContentPage{
|
||||
@ -11,7 +12,7 @@ FluContentPage{
|
||||
id:root
|
||||
title: qsTr("Network")
|
||||
|
||||
FluNetworkCallable{
|
||||
NetworkCallable{
|
||||
id:callable
|
||||
onStart: {
|
||||
showLoading()
|
||||
@ -56,7 +57,7 @@ FluContentPage{
|
||||
text: "Get"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.get("https://httpbingo.org/get")
|
||||
Network.get("https://httpbingo.org/get")
|
||||
.addQuery("name","孙悟空")
|
||||
.addQuery("age",500)
|
||||
.addQuery("address","花果山水帘洞")
|
||||
@ -70,7 +71,7 @@ FluContentPage{
|
||||
text: "Head"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.head("https://httpbingo.org/head")
|
||||
Network.head("https://httpbingo.org/head")
|
||||
.addQuery("name","孙悟空")
|
||||
.addQuery("age",500)
|
||||
.addQuery("address","花果山水帘洞")
|
||||
@ -84,7 +85,7 @@ FluContentPage{
|
||||
text: "Post Body"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postBody("https://httpbingo.org/post")
|
||||
Network.postBody("https://httpbingo.org/post")
|
||||
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||
.bind(root)
|
||||
.go(callable)
|
||||
@ -96,7 +97,7 @@ FluContentPage{
|
||||
text: "Post Form"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postForm("https://httpbingo.org/post")
|
||||
Network.postForm("https://httpbingo.org/post")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -110,7 +111,7 @@ FluContentPage{
|
||||
text: "Post JSON"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -124,7 +125,7 @@ FluContentPage{
|
||||
text: "Post JSON Array"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJsonArray("https://httpbingo.org/post")
|
||||
Network.postJsonArray("https://httpbingo.org/post")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -138,7 +139,7 @@ FluContentPage{
|
||||
text: "Put Body"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.putBody("https://httpbingo.org/put")
|
||||
Network.putBody("https://httpbingo.org/put")
|
||||
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||
.bind(root)
|
||||
.go(callable)
|
||||
@ -150,7 +151,7 @@ FluContentPage{
|
||||
text: "Put Form"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.putForm("https://httpbingo.org/put")
|
||||
Network.putForm("https://httpbingo.org/put")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -164,7 +165,7 @@ FluContentPage{
|
||||
text: "Put JSON"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.putJson("https://httpbingo.org/put")
|
||||
Network.putJson("https://httpbingo.org/put")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -178,7 +179,7 @@ FluContentPage{
|
||||
text: "Put JSON Array"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.putJsonArray("https://httpbingo.org/put")
|
||||
Network.putJsonArray("https://httpbingo.org/put")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -192,7 +193,7 @@ FluContentPage{
|
||||
text: "Patch Body"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.patchBody("https://httpbingo.org/patch")
|
||||
Network.patchBody("https://httpbingo.org/patch")
|
||||
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||
.bind(root)
|
||||
.go(callable)
|
||||
@ -204,7 +205,7 @@ FluContentPage{
|
||||
text: "Patch Form"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.patchForm("https://httpbingo.org/patch")
|
||||
Network.patchForm("https://httpbingo.org/patch")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -218,7 +219,7 @@ FluContentPage{
|
||||
text: "Patch JSON"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.patchJson("https://httpbingo.org/patch")
|
||||
Network.patchJson("https://httpbingo.org/patch")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -232,7 +233,7 @@ FluContentPage{
|
||||
text: "Patch JSON Array"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
|
||||
Network.patchJsonArray("https://httpbingo.org/patch")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -246,7 +247,7 @@ FluContentPage{
|
||||
text: "Delete Body"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.deleteBody("https://httpbingo.org/delete")
|
||||
Network.deleteBody("https://httpbingo.org/delete")
|
||||
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||
.bind(root)
|
||||
.go(callable)
|
||||
@ -258,7 +259,7 @@ FluContentPage{
|
||||
text: "Delete Form"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.deleteForm("https://httpbingo.org/delete")
|
||||
Network.deleteForm("https://httpbingo.org/delete")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -272,7 +273,7 @@ FluContentPage{
|
||||
text: "Delete JSON"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.deleteJson("https://httpbingo.org/delete")
|
||||
Network.deleteJson("https://httpbingo.org/delete")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -286,7 +287,7 @@ FluContentPage{
|
||||
text: "Delete JSON Array"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
|
||||
Network.deleteJsonArray("https://httpbingo.org/delete")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -300,7 +301,7 @@ FluContentPage{
|
||||
text: "Open Log"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -315,7 +316,7 @@ FluContentPage{
|
||||
text: "Custom Header"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.addHeader("os","PC")
|
||||
.addHeader("version","1.0.0")
|
||||
.add("name","孙悟空")
|
||||
@ -331,8 +332,8 @@ FluContentPage{
|
||||
text: "RequestFailedReadCache"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
.setCacheMode(FluNetworkType.RequestFailedReadCache)
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.setCacheMode(NetworkType.RequestFailedReadCache)
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -347,8 +348,8 @@ FluContentPage{
|
||||
text: "IfNoneCacheRequest"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.setCacheMode(NetworkType.IfNoneCacheRequest)
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -363,8 +364,8 @@ FluContentPage{
|
||||
text: "FirstCacheThenRequest"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.setCacheMode(NetworkType.FirstCacheThenRequest)
|
||||
.add("name","孙悟空")
|
||||
.add("age",500)
|
||||
.add("address","花果山水帘洞")
|
||||
@ -379,7 +380,7 @@ FluContentPage{
|
||||
text: "Timeout And Retry"
|
||||
onClicked: {
|
||||
text_info.text = ""
|
||||
FluNetwork.postJson("https://httpbingo.org/post")
|
||||
Network.postJson("https://httpbingo.org/post")
|
||||
.setTimeout(5000)
|
||||
.setRetry(3)
|
||||
.add("name","孙悟空")
|
||||
@ -407,7 +408,7 @@ FluContentPage{
|
||||
text: "Download File"
|
||||
onClicked: {
|
||||
folder_dialog.showDialog(function(path){
|
||||
FluNetwork.get("http://vjs.zencdn.net/v/oceans.mp4")
|
||||
Network.get("http://vjs.zencdn.net/v/oceans.mp4")
|
||||
.toDownload(path)
|
||||
.bind(root)
|
||||
.go(callable_download_file)
|
||||
@ -421,7 +422,7 @@ FluContentPage{
|
||||
text: "Breakpoint Download File"
|
||||
onClicked: {
|
||||
folder_dialog.showDialog(function(path){
|
||||
FluNetwork.get("http://vjs.zencdn.net/v/oceans.mp4")
|
||||
Network.get("http://vjs.zencdn.net/v/oceans.mp4")
|
||||
.toDownload(path,true)
|
||||
.bind(root)
|
||||
.go(callable_breakpoint_download_file)
|
||||
@ -431,7 +432,7 @@ FluContentPage{
|
||||
}
|
||||
}
|
||||
|
||||
FluNetworkCallable{
|
||||
NetworkCallable{
|
||||
id:callable_upload_file
|
||||
onStart: {
|
||||
btn_upload.disabled = true
|
||||
@ -455,7 +456,7 @@ FluContentPage{
|
||||
}
|
||||
}
|
||||
|
||||
FluNetworkCallable{
|
||||
NetworkCallable{
|
||||
id:callable_download_file
|
||||
onStart: {
|
||||
btn_download.progress = 0
|
||||
@ -480,7 +481,7 @@ FluContentPage{
|
||||
}
|
||||
}
|
||||
|
||||
FluNetworkCallable{
|
||||
NetworkCallable{
|
||||
id:callable_breakpoint_download_file
|
||||
onStart: {
|
||||
btn_download_breakpoint.progress = 0
|
||||
@ -508,7 +509,7 @@ FluContentPage{
|
||||
FileDialog {
|
||||
id: file_dialog
|
||||
onAccepted: {
|
||||
FluNetwork.postForm("https://httpbingo.org/post")
|
||||
Network.postForm("https://httpbingo.org/post")
|
||||
.setRetry(1)//只请求一次
|
||||
.add("accessToken","12345678")
|
||||
.addFile("file",FluTools.toLocalPath(file_dialog.currentFile))
|
||||
|
@ -4,33 +4,19 @@ import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
import "../component"
|
||||
import "../viewmodel"
|
||||
import "../global"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title: qsTr("Settings")
|
||||
|
||||
SettingsViewModel{
|
||||
id:viewmodel_settings
|
||||
}
|
||||
|
||||
FluEvent{
|
||||
id:event_checkupdate_finish
|
||||
name: "checkUpdateFinish"
|
||||
onTriggered: {
|
||||
btn_checkupdate.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
FluEventBus.registerEvent(event_checkupdate_finish)
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
FluEventBus.unRegisterEvent(event_checkupdate_finish)
|
||||
}
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
@ -95,7 +81,7 @@ FluScrollablePage{
|
||||
negativeText: qsTr("Cancel")
|
||||
positiveText: qsTr("OK")
|
||||
onPositiveClicked: {
|
||||
FluApp.exit(931)
|
||||
FluRouter.exit(931)
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,10 +135,10 @@ FluScrollablePage{
|
||||
Repeater{
|
||||
model: [{title:qsTr("Open"),mode:FluNavigationViewType.Open},{title:qsTr("Compact"),mode:FluNavigationViewType.Compact},{title:qsTr("Minimal"),mode:FluNavigationViewType.Minimal},{title:qsTr("Auto"),mode:FluNavigationViewType.Auto}]
|
||||
delegate: FluRadioButton{
|
||||
checked : viewmodel_settings.displayMode===modelData.mode
|
||||
text:modelData.title
|
||||
text: modelData.title
|
||||
checked: GlobalModel.displayMode === modelData.mode
|
||||
clickListener:function(){
|
||||
viewmodel_settings.displayMode = modelData.mode
|
||||
GlobalModel.displayMode = modelData.mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,11 @@ import QtQuick.Layouts 1.15
|
||||
import QtQuick.Window 2.15
|
||||
import FluentUI 1.0
|
||||
import "../component"
|
||||
import "../viewmodel"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
title: qsTr("TextBox")
|
||||
|
||||
TextBoxViewModel{
|
||||
id:viewModel
|
||||
}
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 68
|
||||
@ -24,10 +19,6 @@ FluScrollablePage{
|
||||
placeholderText: qsTr("Single-line Input Box")
|
||||
disabled: text_box_switch.checked
|
||||
cleanEnabled: true
|
||||
text: viewModel.text1
|
||||
onTextChanged: {
|
||||
viewModel.text1 = text
|
||||
}
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
@ -82,7 +73,6 @@ FluScrollablePage{
|
||||
}'
|
||||
}
|
||||
|
||||
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
height: 36+multiine_textbox.height
|
||||
@ -92,10 +82,6 @@ FluScrollablePage{
|
||||
FluMultilineTextBox{
|
||||
id: multiine_textbox
|
||||
placeholderText: qsTr("Multi-line Input Box")
|
||||
text:viewModel.text2
|
||||
onTextChanged: {
|
||||
viewModel.text2 = text
|
||||
}
|
||||
disabled: text_box_multi_switch.checked
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
|
@ -1,14 +0,0 @@
|
||||
import QtQuick 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
FluViewModel{
|
||||
|
||||
objectName: "SettingsViewModel"
|
||||
scope: FluViewModelType.Application
|
||||
property int displayMode
|
||||
|
||||
onInitData: {
|
||||
displayMode = FluNavigationViewType.Auto
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import QtQuick 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
FluViewModel {
|
||||
objectName: "TextBoxView"
|
||||
property string text1
|
||||
property string text2
|
||||
}
|
@ -31,7 +31,7 @@ FluWindow {
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
FluApp.navigate("/")
|
||||
FluRouter.navigate("/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ FluWindow {
|
||||
FluFilledButton{
|
||||
text: qsTr("Restart Program")
|
||||
onClicked: {
|
||||
FluApp.exit(931)
|
||||
FluRouter.exit(931)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ FluWindow {
|
||||
showError(qsTr("Please feel free to enter a password"))
|
||||
return
|
||||
}
|
||||
onResult({password:textbox_password.text})
|
||||
setResult({password:textbox_password.text})
|
||||
window.close()
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import Qt.labs.platform 1.1
|
||||
import FluentUI 1.0
|
||||
import example 1.0
|
||||
import "../component"
|
||||
import "../viewmodel"
|
||||
import "../global"
|
||||
|
||||
FluWindow {
|
||||
@ -29,37 +28,23 @@ FluWindow {
|
||||
z:7
|
||||
}
|
||||
|
||||
SettingsViewModel{
|
||||
id:viewmodel_settings
|
||||
}
|
||||
|
||||
FluEvent{
|
||||
id:event_checkupdate
|
||||
name: "checkUpdate"
|
||||
onTriggered: {
|
||||
checkUpdate(false)
|
||||
}
|
||||
}
|
||||
|
||||
onFirstVisible: {
|
||||
timer_tour_delay.restart()
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer_tour_delay
|
||||
interval: 200
|
||||
onTriggered: {
|
||||
tour.open()
|
||||
}
|
||||
onLazyLoad: {
|
||||
tour.open()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
checkUpdate(true)
|
||||
FluEventBus.registerEvent(event_checkupdate)
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
FluEventBus.unRegisterEvent(event_checkupdate)
|
||||
FluRouter.exit()
|
||||
}
|
||||
|
||||
SystemTrayIcon {
|
||||
@ -71,7 +56,7 @@ FluWindow {
|
||||
MenuItem {
|
||||
text: "退出"
|
||||
onTriggered: {
|
||||
FluApp.exit()
|
||||
FluRouter.exit()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,7 +91,7 @@ FluWindow {
|
||||
positiveText: qsTr("Quit")
|
||||
neutralText: qsTr("Cancel")
|
||||
onPositiveClicked:{
|
||||
FluApp.exit(0)
|
||||
FluRouter.exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +103,7 @@ FluWindow {
|
||||
text: qsTr("Open in Separate Window")
|
||||
font.pixelSize: 12
|
||||
onClicked: {
|
||||
FluApp.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
|
||||
FluRouter.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,14 +160,14 @@ FluWindow {
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
appBar.setHitTestVisible(layout_back_buttons)
|
||||
window.setHitTestVisible(layout_back_buttons)
|
||||
}
|
||||
}
|
||||
FluRemoteLoader{
|
||||
id:loader
|
||||
lazy: true
|
||||
anchors.fill: parent
|
||||
source: "https://zhu-zichu.gitee.io/Qt_168_LieflatPage.qml"
|
||||
source: "https://zhu-zichu.gitee.io/Qt_174_LieflatPage.qml"
|
||||
}
|
||||
}
|
||||
front: Item{
|
||||
@ -197,7 +182,7 @@ FluWindow {
|
||||
z:999
|
||||
//Stack模式,每次切换都会将页面压入栈中,随着栈的页面增多,消耗的内存也越多,内存消耗多就会卡顿,这时候就需要按返回将页面pop掉,释放内存。该模式可以配合FluPage中的launchMode属性,设置页面的启动模式
|
||||
// pageMode: FluNavigationViewType.Stack
|
||||
//NoStack模式,每次切换都会销毁之前的页面然后创建一个新的页面,只需消耗少量内存,可以配合FluViewModel保存页面数据(推荐)
|
||||
//NoStack模式,每次切换都会销毁之前的页面然后创建一个新的页面,只需消耗少量内存
|
||||
pageMode: FluNavigationViewType.NoStack
|
||||
items: ItemsOriginal
|
||||
footerItems:ItemsFooter
|
||||
@ -207,7 +192,7 @@ FluWindow {
|
||||
}
|
||||
return FluTools.isMacos() ? 20 : 0
|
||||
}
|
||||
displayMode:viewmodel_settings.displayMode
|
||||
displayMode: GlobalModel.displayMode
|
||||
logo: "qrc:/example/res/image/favicon.ico"
|
||||
title:"FluentUI"
|
||||
onLogoClicked:{
|
||||
@ -233,9 +218,9 @@ FluWindow {
|
||||
ItemsOriginal.paneItemMenu = nav_item_right_menu
|
||||
ItemsFooter.navigationView = nav_view
|
||||
ItemsFooter.paneItemMenu = nav_item_right_menu
|
||||
appBar.setHitTestVisible(nav_view.buttonMenu)
|
||||
appBar.setHitTestVisible(nav_view.buttonBack)
|
||||
appBar.setHitTestVisible(nav_view.imageLogo)
|
||||
window.setHitTestVisible(nav_view.buttonMenu)
|
||||
window.setHitTestVisible(nav_view.buttonBack)
|
||||
window.setHitTestVisible(nav_view.imageLogo)
|
||||
setCurrentIndex(0)
|
||||
}
|
||||
}
|
||||
@ -355,7 +340,7 @@ FluWindow {
|
||||
}
|
||||
}
|
||||
|
||||
FluNetworkCallable{
|
||||
NetworkCallable{
|
||||
id:callable
|
||||
property bool silent: true
|
||||
onStart: {
|
||||
@ -391,7 +376,7 @@ FluWindow {
|
||||
|
||||
function checkUpdate(silent){
|
||||
callable.silent = silent
|
||||
FluNetwork.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
|
||||
Network.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
|
||||
.go(callable)
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
FluLauncher {
|
||||
id: app
|
||||
Component.onCompleted: {
|
||||
FluApp.init(app)
|
||||
FluApp.windowIcon = "qrc:/logo.ico"
|
||||
FluApp.routes = {
|
||||
FluRouter.routes = {
|
||||
"/":"qrc:/main.qml",
|
||||
}
|
||||
FluApp.navigate("/")
|
||||
FluRouter.navigate("/")
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ if (CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
add_custom_target(Script-DeployRelease
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/dist
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${CMAKE_SOURCE_DIR}/dist
|
||||
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/dist/${PROJECT_NAME}.exe -qmldir=${CMAKE_CURRENT_LIST_DIR}
|
||||
COMMAND ${QT_DEPLOY_QT} --qmldir=${CMAKE_CURRENT_LIST_DIR} --plugindir ${CMAKE_SOURCE_DIR}/dist/plugins --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/dist/${PROJECT_NAME}.exe
|
||||
COMMENT "Windows Deploying Qt Dependencies After Build........."
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "FluNetwork.h"
|
||||
#include "Network.h"
|
||||
|
||||
#include <QUrlQuery>
|
||||
#include <QBuffer>
|
||||
@ -18,11 +18,11 @@
|
||||
#include <QEventLoop>
|
||||
#include <QGuiApplication>
|
||||
|
||||
FluNetworkCallable::FluNetworkCallable(QObject *parent):QObject{parent}{
|
||||
NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{
|
||||
|
||||
}
|
||||
|
||||
QString FluNetworkParams::method2String(){
|
||||
QString NetworkParams::method2String(){
|
||||
switch (_method) {
|
||||
case METHOD_GET:
|
||||
return "GET";
|
||||
@ -41,25 +41,25 @@ QString FluNetworkParams::method2String(){
|
||||
}
|
||||
}
|
||||
|
||||
int FluNetworkParams::getTimeout(){
|
||||
int NetworkParams::getTimeout(){
|
||||
if(_timeout != -1){
|
||||
return _timeout;
|
||||
}
|
||||
return FluNetwork::getInstance()->timeout();
|
||||
return Network::getInstance()->timeout();
|
||||
}
|
||||
|
||||
int FluNetworkParams::getRetry(){
|
||||
int NetworkParams::getRetry(){
|
||||
if(_retry != -1){
|
||||
return _retry;
|
||||
}
|
||||
return FluNetwork::getInstance()->retry();
|
||||
return Network::getInstance()->retry();
|
||||
}
|
||||
|
||||
bool FluNetworkParams::getOpenLog(){
|
||||
bool NetworkParams::getOpenLog(){
|
||||
if(!_openLog.isNull()){
|
||||
return _openLog.toBool();
|
||||
}
|
||||
return FluNetwork::getInstance()->openLog();
|
||||
return Network::getInstance()->openLog();
|
||||
}
|
||||
|
||||
FluDownloadParam::FluDownloadParam(QObject *parent)
|
||||
@ -74,12 +74,12 @@ FluDownloadParam::FluDownloadParam(QString destPath,bool append,QObject *parent)
|
||||
this->_append = append;
|
||||
}
|
||||
|
||||
FluNetworkParams::FluNetworkParams(QObject *parent)
|
||||
NetworkParams::NetworkParams(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
}
|
||||
|
||||
FluNetworkParams::FluNetworkParams(QString url,Type type,Method method,QObject *parent)
|
||||
NetworkParams::NetworkParams(QString url,Type type,Method method,QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
this->_method = method;
|
||||
@ -87,62 +87,62 @@ FluNetworkParams::FluNetworkParams(QString url,Type type,Method method,QObject *
|
||||
this->_type = type;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::add(QString key,QVariant val){
|
||||
NetworkParams* NetworkParams::add(QString key,QVariant val){
|
||||
_paramMap.insert(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::addFile(QString key,QVariant val){
|
||||
NetworkParams* NetworkParams::addFile(QString key,QVariant val){
|
||||
_fileMap.insert(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::addHeader(QString key,QVariant val){
|
||||
NetworkParams* NetworkParams::addHeader(QString key,QVariant val){
|
||||
_headerMap.insert(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::addQuery(QString key,QVariant val){
|
||||
NetworkParams* NetworkParams::addQuery(QString key,QVariant val){
|
||||
_queryMap.insert(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::setBody(QString val){
|
||||
NetworkParams* NetworkParams::setBody(QString val){
|
||||
_body = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::setTimeout(int val){
|
||||
NetworkParams* NetworkParams::setTimeout(int val){
|
||||
_timeout = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::setRetry(int val){
|
||||
NetworkParams* NetworkParams::setRetry(int val){
|
||||
_retry = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::setCacheMode(int val){
|
||||
NetworkParams* NetworkParams::setCacheMode(int val){
|
||||
_cacheMode = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::toDownload(QString destPath,bool append){
|
||||
NetworkParams* NetworkParams::toDownload(QString destPath,bool append){
|
||||
_downloadParam = new FluDownloadParam(destPath,append,this);
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::bind(QObject* target){
|
||||
NetworkParams* NetworkParams::bind(QObject* target){
|
||||
_target = target;
|
||||
return this;
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetworkParams::openLog(QVariant val){
|
||||
NetworkParams* NetworkParams::openLog(QVariant val){
|
||||
_openLog = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
QString FluNetworkParams::buildCacheKey(){
|
||||
QString NetworkParams::buildCacheKey(){
|
||||
QJsonObject obj;
|
||||
obj.insert("url",_url);
|
||||
obj.insert("method",method2String());
|
||||
@ -161,30 +161,30 @@ QString FluNetworkParams::buildCacheKey(){
|
||||
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
|
||||
}
|
||||
|
||||
void FluNetworkParams::go(FluNetworkCallable* callable){
|
||||
void NetworkParams::go(NetworkCallable* callable){
|
||||
QJSValueList data;
|
||||
data<<qjsEngine(callable)->newQObject(this);
|
||||
FluNetwork::getInstance()->_interceptor.call(data);
|
||||
Network::getInstance()->_interceptor.call(data);
|
||||
if(_downloadParam){
|
||||
FluNetwork::getInstance()->handleDownload(this,callable);
|
||||
Network::getInstance()->handleDownload(this,callable);
|
||||
}else{
|
||||
FluNetwork::getInstance()->handle(this,callable);
|
||||
Network::getInstance()->handle(this,callable);
|
||||
}
|
||||
}
|
||||
|
||||
void FluNetwork::handle(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
QPointer<FluNetworkCallable> callable(c);
|
||||
void Network::handle(NetworkParams* params,NetworkCallable* c){
|
||||
QPointer<NetworkCallable> callable(c);
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
if(!callable.isNull()){
|
||||
callable->start();
|
||||
}
|
||||
QString cacheKey = params->buildCacheKey();
|
||||
if(params->_cacheMode == FluNetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)){
|
||||
if(params->_cacheMode == NetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)){
|
||||
if(!callable.isNull()){
|
||||
callable->cache(readCache(cacheKey));
|
||||
}
|
||||
}
|
||||
if(params->_cacheMode == FluNetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)){
|
||||
if(params->_cacheMode == NetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)){
|
||||
if(!callable.isNull()){
|
||||
callable->cache(readCache(cacheKey));
|
||||
callable->finish();
|
||||
@ -214,21 +214,21 @@ void FluNetwork::handle(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
reply->abort();
|
||||
}
|
||||
};
|
||||
QMetaObject::Connection conn_destoryed = {};
|
||||
QMetaObject::Connection conn_destroyed = {};
|
||||
QMetaObject::Connection conn_quit = {};
|
||||
if(params->_target){
|
||||
conn_destoryed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
|
||||
conn_destroyed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
|
||||
}
|
||||
conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
|
||||
loop.exec();
|
||||
if(conn_destoryed){
|
||||
disconnect(conn_destoryed);
|
||||
if(conn_destroyed){
|
||||
disconnect(conn_destroyed);
|
||||
}
|
||||
if(conn_quit){
|
||||
disconnect(conn_quit);
|
||||
}
|
||||
QString response;
|
||||
if(params->_method == FluNetworkParams::METHOD_HEAD){
|
||||
if(params->_method == NetworkParams::METHOD_HEAD){
|
||||
response = headerList2String(reply->rawHeaderPairs());
|
||||
}else{
|
||||
if(reply->isOpen()){
|
||||
@ -238,7 +238,7 @@ void FluNetwork::handle(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if(httpStatus == 200){
|
||||
if(!callable.isNull()){
|
||||
if(params->_cacheMode != FluNetworkType::CacheMode::NoCache){
|
||||
if(params->_cacheMode != NetworkType::CacheMode::NoCache){
|
||||
saveResponse(cacheKey,response);
|
||||
}
|
||||
callable->success(response);
|
||||
@ -248,7 +248,7 @@ void FluNetwork::handle(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
}else{
|
||||
if(i == params->getRetry()-1){
|
||||
if(!callable.isNull()){
|
||||
if(params->_cacheMode == FluNetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)){
|
||||
if(params->_cacheMode == NetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)){
|
||||
if(!callable.isNull()){
|
||||
callable->cache(readCache(cacheKey));
|
||||
}
|
||||
@ -267,8 +267,8 @@ void FluNetwork::handle(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
});
|
||||
}
|
||||
|
||||
void FluNetwork::handleDownload(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
QPointer<FluNetworkCallable> callable(c);
|
||||
void Network::handleDownload(NetworkParams* params,NetworkCallable* c){
|
||||
QPointer<NetworkCallable> callable(c);
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
if(!callable.isNull()){
|
||||
callable->start();
|
||||
@ -336,10 +336,10 @@ void FluNetwork::handleDownload(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
};
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
QMetaObject::Connection conn_destoryed = {};
|
||||
QMetaObject::Connection conn_destroyed = {};
|
||||
QMetaObject::Connection conn_quit = {};
|
||||
if(params->_target){
|
||||
conn_destoryed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
|
||||
conn_destroyed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
|
||||
}
|
||||
conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
|
||||
connect(reply,&QNetworkReply::readyRead,reply,[reply,seek,destFile,cacheFile,callable]{
|
||||
@ -377,8 +377,8 @@ void FluNetwork::handleDownload(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
}
|
||||
printRequestEndLog(request,params,reply,destPath);
|
||||
}
|
||||
if(conn_destoryed){
|
||||
disconnect(conn_destoryed);
|
||||
if(conn_destroyed){
|
||||
disconnect(conn_destroyed);
|
||||
}
|
||||
if(conn_quit){
|
||||
disconnect(conn_quit);
|
||||
@ -391,7 +391,7 @@ void FluNetwork::handleDownload(FluNetworkParams* params,FluNetworkCallable* c){
|
||||
});
|
||||
}
|
||||
|
||||
QString FluNetwork::readCache(const QString& key){
|
||||
QString Network::readCache(const QString& key){
|
||||
auto filePath = getCacheFilePath(key);
|
||||
QString result;
|
||||
QFile file(filePath);
|
||||
@ -405,11 +405,11 @@ QString FluNetwork::readCache(const QString& key){
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FluNetwork::cacheExists(const QString& key){
|
||||
bool Network::cacheExists(const QString& key){
|
||||
return QFile(getCacheFilePath(key)).exists();
|
||||
}
|
||||
|
||||
QString FluNetwork::getCacheFilePath(const QString& key){
|
||||
QString Network::getCacheFilePath(const QString& key){
|
||||
QDir cacheDir(_cacheDir);
|
||||
if(!cacheDir.exists()){
|
||||
cacheDir.mkpath(_cacheDir);
|
||||
@ -417,7 +417,7 @@ QString FluNetwork::getCacheFilePath(const QString& key){
|
||||
return cacheDir.absoluteFilePath(key);
|
||||
}
|
||||
|
||||
QString FluNetwork::headerList2String(const QList<QNetworkReply::RawHeaderPair>& data){
|
||||
QString Network::headerList2String(const QList<QNetworkReply::RawHeaderPair>& data){
|
||||
QJsonObject object;
|
||||
for (auto it = data.constBegin(); it != data.constEnd(); ++it) {
|
||||
object.insert(QString(it->first),QString(it->second));
|
||||
@ -425,7 +425,7 @@ QString FluNetwork::headerList2String(const QList<QNetworkReply::RawHeaderPair>&
|
||||
return QJsonDocument(object).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
QString FluNetwork::map2String(const QMap<QString, QVariant>& map){
|
||||
QString Network::map2String(const QMap<QString, QVariant>& map){
|
||||
QStringList parameters;
|
||||
for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
|
||||
parameters << QString("%1=%2").arg(it.key(), it.value().toString());
|
||||
@ -433,10 +433,10 @@ QString FluNetwork::map2String(const QMap<QString, QVariant>& map){
|
||||
return parameters.join(" ");
|
||||
}
|
||||
|
||||
void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,FluNetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<FluNetworkCallable> callable){
|
||||
void Network::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<NetworkCallable> callable){
|
||||
QByteArray verb = params->method2String().toUtf8();
|
||||
switch (params->_type) {
|
||||
case FluNetworkParams::TYPE_FORM:{
|
||||
case NetworkParams::TYPE_FORM:{
|
||||
bool isFormData = !params->_fileMap.isEmpty();
|
||||
if(isFormData){
|
||||
QHttpMultiPart *multiPart = new QHttpMultiPart();
|
||||
@ -484,7 +484,7 @@ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest requ
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FluNetworkParams::TYPE_JSON:{
|
||||
case NetworkParams::TYPE_JSON:{
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
|
||||
QJsonObject json;
|
||||
for (const auto& each : params->_paramMap.toStdMap())
|
||||
@ -495,7 +495,7 @@ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest requ
|
||||
reply = manager->sendCustomRequest(request,verb,data);
|
||||
break;
|
||||
}
|
||||
case FluNetworkParams::TYPE_JSONARRAY:{
|
||||
case NetworkParams::TYPE_JSONARRAY:{
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
|
||||
QJsonArray jsonArray;
|
||||
for (const auto& each : params->_paramMap.toStdMap())
|
||||
@ -508,7 +508,7 @@ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest requ
|
||||
reply = manager->sendCustomRequest(request,params->method2String().toUtf8(),data);
|
||||
break;
|
||||
}
|
||||
case FluNetworkParams::TYPE_BODY:{
|
||||
case NetworkParams::TYPE_BODY:{
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain;charset=utf-8"));
|
||||
QByteArray data = params->_body.toUtf8();
|
||||
reply = manager->sendCustomRequest(request,verb,data);
|
||||
@ -523,7 +523,7 @@ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest requ
|
||||
}
|
||||
}
|
||||
|
||||
void FluNetwork::printRequestStartLog(QNetworkRequest request,FluNetworkParams* params){
|
||||
void Network::printRequestStartLog(QNetworkRequest request,NetworkParams* params){
|
||||
if(!params->getOpenLog()){
|
||||
return;
|
||||
}
|
||||
@ -551,7 +551,7 @@ void FluNetwork::printRequestStartLog(QNetworkRequest request,FluNetworkParams*
|
||||
}
|
||||
}
|
||||
|
||||
void FluNetwork::printRequestEndLog(QNetworkRequest request,FluNetworkParams* params,QNetworkReply*& reply,const QString& response){
|
||||
void Network::printRequestEndLog(QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,const QString& response){
|
||||
if(!params->getOpenLog()){
|
||||
return;
|
||||
}
|
||||
@ -560,7 +560,7 @@ void FluNetwork::printRequestEndLog(QNetworkRequest request,FluNetworkParams* pa
|
||||
qDebug()<<"<Result>"<<qUtf8Printable(response);
|
||||
}
|
||||
|
||||
void FluNetwork::saveResponse(QString key,QString response){
|
||||
void Network::saveResponse(QString key,QString response){
|
||||
QSharedPointer<QFile> file(new QFile(getCacheFilePath(key)));
|
||||
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
|
||||
if (!file->open(mode))
|
||||
@ -570,7 +570,7 @@ void FluNetwork::saveResponse(QString key,QString response){
|
||||
file->write(response.toUtf8().toBase64());
|
||||
}
|
||||
|
||||
void FluNetwork::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
|
||||
void Network::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
|
||||
request->setHeader(QNetworkRequest::UserAgentHeader,QString::fromStdString("Mozilla/5.0 %1/%2").arg(QGuiApplication::applicationName(),QGuiApplication::applicationVersion()));
|
||||
QMapIterator<QString, QVariant> iter(headers);
|
||||
while (iter.hasNext())
|
||||
@ -580,7 +580,7 @@ void FluNetwork::addHeaders(QNetworkRequest* request,const QMap<QString, QVarian
|
||||
}
|
||||
}
|
||||
|
||||
void FluNetwork::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
|
||||
void Network::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
|
||||
QMapIterator<QString, QVariant> iter(params);
|
||||
QUrlQuery urlQuery(*url);
|
||||
while (iter.hasNext())
|
||||
@ -591,7 +591,7 @@ void FluNetwork::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
|
||||
url->setQuery(urlQuery);
|
||||
}
|
||||
|
||||
FluNetwork::FluNetwork(QObject *parent): QObject{parent}
|
||||
Network::Network(QObject *parent): QObject{parent}
|
||||
{
|
||||
timeout(5000);
|
||||
retry(3);
|
||||
@ -599,78 +599,78 @@ FluNetwork::FluNetwork(QObject *parent): QObject{parent}
|
||||
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"));
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::get(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_NONE,FluNetworkParams::METHOD_GET,this);
|
||||
NetworkParams* Network::get(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_GET,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::head(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_NONE,FluNetworkParams::METHOD_HEAD,this);
|
||||
NetworkParams* Network::head(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_HEAD,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::postBody(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_BODY,FluNetworkParams::METHOD_POST,this);
|
||||
NetworkParams* Network::postBody(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_POST,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::putBody(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_BODY,FluNetworkParams::METHOD_PUT,this);
|
||||
NetworkParams* Network::putBody(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PUT,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::patchBody(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_BODY,FluNetworkParams::METHOD_PATCH,this);
|
||||
NetworkParams* Network::patchBody(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PATCH,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::deleteBody(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_BODY,FluNetworkParams::METHOD_DELETE,this);
|
||||
NetworkParams* Network::deleteBody(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_DELETE,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::postForm(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_FORM,FluNetworkParams::METHOD_POST,this);
|
||||
NetworkParams* Network::postForm(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_POST,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::putForm(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_FORM,FluNetworkParams::METHOD_PUT,this);
|
||||
NetworkParams* Network::putForm(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PUT,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::patchForm(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_FORM,FluNetworkParams::METHOD_PATCH,this);
|
||||
NetworkParams* Network::patchForm(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PATCH,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::deleteForm(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_FORM,FluNetworkParams::METHOD_DELETE,this);
|
||||
NetworkParams* Network::deleteForm(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_DELETE,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::postJson(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSON,FluNetworkParams::METHOD_POST,this);
|
||||
NetworkParams* Network::postJson(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_POST,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::putJson(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSON,FluNetworkParams::METHOD_PUT,this);
|
||||
NetworkParams* Network::putJson(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PUT,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::patchJson(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSON,FluNetworkParams::METHOD_PATCH,this);
|
||||
NetworkParams* Network::patchJson(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PATCH,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::deleteJson(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSON,FluNetworkParams::METHOD_DELETE,this);
|
||||
NetworkParams* Network::deleteJson(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_DELETE,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::postJsonArray(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSONARRAY,FluNetworkParams::METHOD_POST,this);
|
||||
NetworkParams* Network::postJsonArray(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_POST,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::putJsonArray(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSONARRAY,FluNetworkParams::METHOD_PUT,this);
|
||||
NetworkParams* Network::putJsonArray(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PUT,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::patchJsonArray(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSONARRAY,FluNetworkParams::METHOD_PATCH,this);
|
||||
NetworkParams* Network::patchJsonArray(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PATCH,this);
|
||||
}
|
||||
|
||||
FluNetworkParams* FluNetwork::deleteJsonArray(const QString& url){
|
||||
return new FluNetworkParams(url,FluNetworkParams::TYPE_JSONARRAY,FluNetworkParams::METHOD_DELETE,this);
|
||||
NetworkParams* Network::deleteJsonArray(const QString& url){
|
||||
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_DELETE,this);
|
||||
}
|
||||
|
||||
void FluNetwork::setInterceptor(QJSValue interceptor){
|
||||
void Network::setInterceptor(QJSValue interceptor){
|
||||
this->_interceptor = interceptor;
|
||||
}
|
169
example/src/helper/Network.h
Normal file
169
example/src/helper/Network.h
Normal file
@ -0,0 +1,169 @@
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QFile>
|
||||
#include <QJsonValue>
|
||||
#include <QJSValue>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include "src/stdafx.h"
|
||||
#include "src/singleton.h"
|
||||
|
||||
namespace NetworkType {
|
||||
Q_NAMESPACE
|
||||
enum CacheMode {
|
||||
NoCache = 0x0000,
|
||||
RequestFailedReadCache = 0x0001,
|
||||
IfNoneCacheRequest = 0x0002,
|
||||
FirstCacheThenRequest = 0x0004,
|
||||
};
|
||||
Q_ENUM_NS(CacheMode)
|
||||
QML_NAMED_ELEMENT(NetworkType)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The NetworkCallable class
|
||||
*/
|
||||
class NetworkCallable : public QObject{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(NetworkCallable)
|
||||
public:
|
||||
explicit NetworkCallable(QObject *parent = nullptr);
|
||||
Q_SIGNAL void start();
|
||||
Q_SIGNAL void finish();
|
||||
Q_SIGNAL void error(int status,QString errorString,QString result);
|
||||
Q_SIGNAL void success(QString result);
|
||||
Q_SIGNAL void cache(QString result);
|
||||
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
|
||||
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluDownloadParam class
|
||||
*/
|
||||
class FluDownloadParam : public QObject{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FluDownloadParam(QObject *parent = nullptr);
|
||||
FluDownloadParam(QString destPath,bool append,QObject *parent = nullptr);
|
||||
public:
|
||||
QString _destPath;
|
||||
bool _append;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The NetworkParams class
|
||||
*/
|
||||
class NetworkParams : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(NetworkParams)
|
||||
public:
|
||||
enum Method{
|
||||
METHOD_GET,
|
||||
METHOD_HEAD,
|
||||
METHOD_POST,
|
||||
METHOD_PUT,
|
||||
METHOD_PATCH,
|
||||
METHOD_DELETE
|
||||
};
|
||||
enum Type{
|
||||
TYPE_NONE,
|
||||
TYPE_FORM,
|
||||
TYPE_JSON,
|
||||
TYPE_JSONARRAY,
|
||||
TYPE_BODY
|
||||
};
|
||||
explicit NetworkParams(QObject *parent = nullptr);
|
||||
NetworkParams(QString url,Type type,Method method,QObject *parent = nullptr);
|
||||
Q_INVOKABLE NetworkParams* addQuery(QString key,QVariant val);
|
||||
Q_INVOKABLE NetworkParams* addHeader(QString key,QVariant val);
|
||||
Q_INVOKABLE NetworkParams* add(QString key,QVariant val);
|
||||
Q_INVOKABLE NetworkParams* addFile(QString key,QVariant val);
|
||||
Q_INVOKABLE NetworkParams* setBody(QString val);
|
||||
Q_INVOKABLE NetworkParams* setTimeout(int val);
|
||||
Q_INVOKABLE NetworkParams* setRetry(int val);
|
||||
Q_INVOKABLE NetworkParams* setCacheMode(int val);
|
||||
Q_INVOKABLE NetworkParams* toDownload(QString destPath,bool append = false);
|
||||
Q_INVOKABLE NetworkParams* bind(QObject* target);
|
||||
Q_INVOKABLE NetworkParams* openLog(QVariant val);
|
||||
Q_INVOKABLE void go(NetworkCallable* result);
|
||||
QString buildCacheKey();
|
||||
QString method2String();
|
||||
int getTimeout();
|
||||
int getRetry();
|
||||
bool getOpenLog();
|
||||
public:
|
||||
FluDownloadParam* _downloadParam = nullptr;
|
||||
QObject* _target = nullptr;
|
||||
Method _method;
|
||||
Type _type;
|
||||
QString _url;
|
||||
QString _body;
|
||||
QMap<QString, QVariant> _queryMap;
|
||||
QMap<QString, QVariant> _headerMap;
|
||||
QMap<QString, QVariant> _paramMap;
|
||||
QMap<QString, QVariant> _fileMap;
|
||||
int _timeout = -1;
|
||||
int _retry = -1;
|
||||
QVariant _openLog;
|
||||
int _cacheMode = NetworkType::CacheMode::NoCache;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Network class
|
||||
*/
|
||||
class Network : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(int,timeout)
|
||||
Q_PROPERTY_AUTO(int,retry)
|
||||
Q_PROPERTY_AUTO(QString,cacheDir)
|
||||
Q_PROPERTY_AUTO(bool,openLog)
|
||||
QML_NAMED_ELEMENT(Network)
|
||||
QML_SINGLETON
|
||||
private:
|
||||
explicit Network(QObject *parent = nullptr);
|
||||
public:
|
||||
SINGLETON(Network)
|
||||
static Network *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||
Q_INVOKABLE NetworkParams* get(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* head(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* postBody(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* putBody(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* patchBody(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* deleteBody(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* postForm(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* putForm(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* patchForm(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* deleteForm(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* postJson(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* putJson(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* patchJson(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* deleteJson(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* postJsonArray(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* putJsonArray(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* patchJsonArray(const QString& url);
|
||||
Q_INVOKABLE NetworkParams* deleteJsonArray(const QString& url);
|
||||
Q_INVOKABLE void setInterceptor(QJSValue interceptor);
|
||||
void handle(NetworkParams* params,NetworkCallable* result);
|
||||
void handleDownload(NetworkParams* params,NetworkCallable* result);
|
||||
private:
|
||||
void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<NetworkCallable> callable);
|
||||
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
|
||||
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers);
|
||||
void saveResponse(QString key,QString response);
|
||||
QString readCache(const QString& key);
|
||||
bool cacheExists(const QString& key);
|
||||
QString getCacheFilePath(const QString& key);
|
||||
QString map2String(const QMap<QString, QVariant>& map);
|
||||
QString headerList2String(const QList<QNetworkReply::RawHeaderPair>& data);
|
||||
void printRequestStartLog(QNetworkRequest request,NetworkParams* params);
|
||||
void printRequestEndLog(QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,const QString& response);
|
||||
public:
|
||||
QJSValue _interceptor;
|
||||
};
|
||||
|
||||
#endif // Network_H
|
@ -24,7 +24,7 @@ public:
|
||||
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar){save("useSystemAppBar",useSystemAppBar);}
|
||||
Q_INVOKABLE bool getUseSystemAppBar(){return get("useSystemAppBar",QVariant(false)).toBool();}
|
||||
Q_INVOKABLE void saveLanguage(QString language){save("language",language);}
|
||||
Q_INVOKABLE QString getLanguage(){return get("language",QVariant("en")).toString();}
|
||||
Q_INVOKABLE QString getLanguage(){return get("language",QVariant("en_US")).toString();}
|
||||
private:
|
||||
void save(const QString& key,QVariant val);
|
||||
QVariant get(const QString& key,QVariant def={});
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "src/helper/SettingsHelper.h"
|
||||
#include "src/helper/InitalizrHelper.h"
|
||||
#include "src/helper/TranslateHelper.h"
|
||||
#include "src/helper/Network.h"
|
||||
|
||||
#ifdef FLUENTUI_BUILD_STATIC_LIB
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(6, 2, 0))
|
||||
@ -51,6 +52,7 @@ int main(int argc, char *argv[])
|
||||
QGuiApplication::setApplicationName("FluentUI");
|
||||
QGuiApplication::setApplicationDisplayName("FluentUI Exmaple");
|
||||
QGuiApplication::setApplicationVersion(APPLICATION_VERSION);
|
||||
QGuiApplication::setQuitOnLastWindowClosed(false);
|
||||
SettingsHelper::getInstance()->init(argv);
|
||||
Log::setup(argv,"example");
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
||||
@ -64,18 +66,25 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
const char *uri = "example";
|
||||
int major = 1;
|
||||
int minor = 0;
|
||||
//@uri example
|
||||
qmlRegisterType<CircularReveal>(uri, major, minor, "CircularReveal");
|
||||
qmlRegisterType<FileWatcher>(uri, major, minor, "FileWatcher");
|
||||
qmlRegisterType<FpsItem>(uri, major, minor, "FpsItem");
|
||||
qmlRegisterType<NetworkCallable>(uri,major,minor,"NetworkCallable");
|
||||
qmlRegisterType<NetworkParams>(uri,major,minor,"NetworkParams");
|
||||
QQmlApplicationEngine engine;
|
||||
TranslateHelper::getInstance()->init(&engine);
|
||||
engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance());
|
||||
engine.rootContext()->setContextProperty("SettingsHelper",SettingsHelper::getInstance());
|
||||
engine.rootContext()->setContextProperty("InitalizrHelper",InitalizrHelper::getInstance());
|
||||
engine.rootContext()->setContextProperty("TranslateHelper",TranslateHelper::getInstance());
|
||||
engine.rootContext()->setContextProperty("Network",Network::getInstance());
|
||||
#ifdef FLUENTUI_BUILD_STATIC_LIB
|
||||
FluentUI::getInstance()->registerTypes(&engine);
|
||||
#endif
|
||||
qmlRegisterType<CircularReveal>("example", 1, 0, "CircularReveal");
|
||||
qmlRegisterType<FileWatcher>("example", 1, 0, "FileWatcher");
|
||||
qmlRegisterType<FpsItem>("example", 1, 0, "FpsItem");
|
||||
const QUrl url(QStringLiteral("qrc:/example/qml/App.qml"));
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
|
@ -13,7 +13,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
#设置版本号
|
||||
add_definitions(-DFLUENTUI_VERSION=1,7,3,0)
|
||||
add_definitions(-DFLUENTUI_VERSION=1,7,4,0)
|
||||
|
||||
if (FLUENTUI_BUILD_STATIC_LIB)
|
||||
add_definitions(-DFLUENTUI_BUILD_STATIC_LIB)
|
||||
@ -46,13 +46,13 @@ endif()
|
||||
#国际化
|
||||
find_program(QT_LUPDATE NAMES lupdate)
|
||||
find_program(QT_LRELEASE NAMES lrelease)
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}_en_US.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts ${PROJECT_NAME}_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} ${PROJECT_NAME}_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/fluentui_en_US.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts fluentui_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} fluentui_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif ()
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}_zh_CN.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts ${PROJECT_NAME}_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} ${PROJECT_NAME}_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/fluentui_zh_CN.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts fluentui_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} fluentui_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif ()
|
||||
|
||||
file(GLOB QM_FILE_PATHS ${CMAKE_CURRENT_LIST_DIR}/ *.qm)
|
||||
@ -73,11 +73,15 @@ if(QT_VERSION VERSION_GREATER_EQUAL "6.2")
|
||||
endif()
|
||||
|
||||
#遍历所有qml文件
|
||||
file(GLOB_RECURSE QML_PATHS *.qml)
|
||||
file(GLOB_RECURSE QML_PATHS *.qml qmldir)
|
||||
foreach(filepath ${QML_PATHS})
|
||||
if(${filepath} MATCHES "Qt${QT_VERSION_MAJOR}/")
|
||||
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
|
||||
list(APPEND qml_files ${filename})
|
||||
if(${filename} MATCHES "qmldir")
|
||||
list(APPEND resource_files ${filename})
|
||||
else()
|
||||
list(APPEND qml_files ${filename})
|
||||
endif()
|
||||
endif()
|
||||
endforeach(filepath)
|
||||
|
||||
|
21
src/Def.h
21
src/Def.h
@ -4,27 +4,6 @@
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
namespace FluViewModelType {
|
||||
Q_NAMESPACE
|
||||
enum Scope {
|
||||
Window = 0x0000,
|
||||
Application = 0x0001
|
||||
};
|
||||
Q_ENUM_NS(Scope)
|
||||
QML_NAMED_ELEMENT(FluViewModelType)
|
||||
}
|
||||
|
||||
namespace FluNetworkType {
|
||||
Q_NAMESPACE
|
||||
enum CacheMode {
|
||||
NoCache = 0x0000,
|
||||
RequestFailedReadCache = 0x0001,
|
||||
IfNoneCacheRequest = 0x0002,
|
||||
FirstCacheThenRequest = 0x0004,
|
||||
};
|
||||
Q_ENUM_NS(CacheMode)
|
||||
QML_NAMED_ELEMENT(FluNetworkType)
|
||||
}
|
||||
|
||||
namespace FluThemeType {
|
||||
Q_NAMESPACE
|
||||
|
@ -24,83 +24,10 @@ void FluApp::init(QObject *target,QLocale locale){
|
||||
qApp->installTranslator(_translator);
|
||||
const QStringList uiLanguages = _locale.uiLanguages();
|
||||
for (const QString &name : uiLanguages) {
|
||||
const QString baseName = "fluentuiplugin_" + QLocale(name).name();
|
||||
const QString baseName = "fluentui_" + QLocale(name).name();
|
||||
if (_translator->load(":/qt/qml/FluentUI/i18n/"+ baseName)) {
|
||||
_engine->retranslate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FluApp::run(){
|
||||
navigate(initialRoute());
|
||||
}
|
||||
|
||||
void FluApp::navigate(const QString& route,const QJsonObject& argument,FluWindowRegister* windowRegister){
|
||||
if(!routes().contains(route)){
|
||||
qCritical()<<"Not Found Route "<<route;
|
||||
return;
|
||||
}
|
||||
QQmlComponent component(_engine, routes().value(route).toString());
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errors();
|
||||
return;
|
||||
}
|
||||
QVariantMap properties;
|
||||
properties.insert("_route",route);
|
||||
if(windowRegister){
|
||||
properties.insert("_windowRegister",QVariant::fromValue(windowRegister));
|
||||
}
|
||||
properties.insert("argument",argument);
|
||||
QQuickWindow *win=nullptr;
|
||||
for (const auto& pair : _windows.toStdMap()) {
|
||||
QString r = pair.second->property("_route").toString();
|
||||
if(r == route){
|
||||
win = pair.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(win){
|
||||
int launchMode = win->property("launchMode").toInt();
|
||||
if(launchMode == 1){
|
||||
win->setProperty("argument",argument);
|
||||
win->show();
|
||||
win->raise();
|
||||
win->requestActivate();
|
||||
return;
|
||||
}else if(launchMode == 2){
|
||||
win->close();
|
||||
}
|
||||
}
|
||||
win = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties));
|
||||
if(windowRegister){
|
||||
windowRegister->to(win);
|
||||
}
|
||||
}
|
||||
|
||||
void FluApp::exit(int retCode){
|
||||
for (const auto& pair : _windows.toStdMap()) {
|
||||
pair.second->close();
|
||||
removeWindow(pair.second);
|
||||
}
|
||||
qApp->exit(retCode);
|
||||
}
|
||||
|
||||
void FluApp::addWindow(QQuickWindow* window){
|
||||
_windows.insert(window->winId(),window);
|
||||
}
|
||||
|
||||
void FluApp::removeWindow(QQuickWindow* window){
|
||||
if(window){
|
||||
_windows.remove(window->winId());
|
||||
window->deleteLater();
|
||||
window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QVariant FluApp::createWindowRegister(QQuickWindow* window,const QString& path){
|
||||
FluWindowRegister *p = new FluWindowRegister(window);
|
||||
p->from(window);
|
||||
p->path(path);
|
||||
return QVariant::fromValue(p);
|
||||
}
|
||||
|
12
src/FluApp.h
12
src/FluApp.h
@ -4,12 +4,11 @@
|
||||
#include <QObject>
|
||||
#include <QWindow>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QJsonArray>
|
||||
#include <QQmlContext>
|
||||
#include <QJsonObject>
|
||||
#include <QQmlEngine>
|
||||
#include <QTranslator>
|
||||
#include "FluWindowRegister.h"
|
||||
#include <QQuickWindow>
|
||||
#include "stdafx.h"
|
||||
#include "singleton.h"
|
||||
|
||||
@ -19,8 +18,6 @@
|
||||
class FluApp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,initialRoute);
|
||||
Q_PROPERTY_AUTO(QJsonObject,routes);
|
||||
Q_PROPERTY_AUTO(bool,useSystemAppBar);
|
||||
Q_PROPERTY_AUTO(QString,windowIcon);
|
||||
Q_PROPERTY_AUTO(QLocale,locale);
|
||||
@ -32,15 +29,8 @@ private:
|
||||
public:
|
||||
SINGLETON(FluApp)
|
||||
static FluApp *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||
Q_INVOKABLE void run();
|
||||
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluWindowRegister* windowRegister = nullptr);
|
||||
Q_INVOKABLE void init(QObject *target,QLocale locale = QLocale::system());
|
||||
Q_INVOKABLE void exit(int retCode = 0);
|
||||
Q_INVOKABLE QVariant createWindowRegister(QQuickWindow* window,const QString& path);
|
||||
void addWindow(QQuickWindow* window);
|
||||
void removeWindow(QQuickWindow* window);
|
||||
private:
|
||||
QMap<quint64, QQuickWindow*> _windows;
|
||||
QQmlEngine *_engine;
|
||||
QTranslator* _translator = nullptr;
|
||||
};
|
||||
|
@ -1,23 +0,0 @@
|
||||
#include "FluEventBus.h"
|
||||
|
||||
FluEvent::FluEvent(QObject *parent):QObject{parent}{
|
||||
}
|
||||
|
||||
FluEventBus::FluEventBus(QObject *parent):QObject{parent}{
|
||||
}
|
||||
|
||||
void FluEventBus::registerEvent(FluEvent* event){
|
||||
_eventData.append(event);
|
||||
}
|
||||
|
||||
void FluEventBus::unRegisterEvent(FluEvent* event){
|
||||
_eventData.removeOne(event);
|
||||
}
|
||||
|
||||
void FluEventBus::post(const QString& name,const QMap<QString, QVariant>& data){
|
||||
foreach (auto event, _eventData) {
|
||||
if(event->name()==name){
|
||||
Q_EMIT event->triggered(data);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
#ifndef FLUEVENTBUS_H
|
||||
#define FLUEVENTBUS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
#include "stdafx.h"
|
||||
#include "singleton.h"
|
||||
|
||||
/**
|
||||
* @brief The FluEvent class
|
||||
*/
|
||||
class FluEvent : public QObject{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,name);
|
||||
QML_NAMED_ELEMENT(FluEvent)
|
||||
public:
|
||||
explicit FluEvent(QObject *parent = nullptr);
|
||||
Q_SIGNAL void triggered(QMap<QString, QVariant> data);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluEventBus class
|
||||
*/
|
||||
class FluEventBus : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(FluEventBus)
|
||||
QML_SINGLETON
|
||||
private:
|
||||
explicit FluEventBus(QObject *parent = nullptr);
|
||||
public:
|
||||
SINGLETON(FluEventBus)
|
||||
static FluEventBus *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||
Q_INVOKABLE void registerEvent(FluEvent* event);
|
||||
Q_INVOKABLE void unRegisterEvent(FluEvent* event);
|
||||
Q_INVOKABLE void post(const QString& name,const QMap<QString, QVariant>& params = {});
|
||||
private:
|
||||
QList<FluEvent*> _eventData;
|
||||
};
|
||||
|
||||
#endif // FLUEVENTBUS_H
|
458
src/FluFrameless.cpp
Normal file
458
src/FluFrameless.cpp
Normal file
@ -0,0 +1,458 @@
|
||||
#include "FluFrameless.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#pragma comment (lib,"dwmapi.lib")
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <dwmapi.h>
|
||||
static inline QByteArray qtNativeEventType()
|
||||
{
|
||||
static const auto result = "windows_generic_MSG";
|
||||
return result;
|
||||
}
|
||||
static inline bool isCompositionEnabled(){
|
||||
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
|
||||
HMODULE module = ::LoadLibraryW(L"dwmapi.dll");
|
||||
if (module)
|
||||
{
|
||||
BOOL composition_enabled = false;
|
||||
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
|
||||
dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||
if (dwm_is_composition_enabled)
|
||||
{
|
||||
dwm_is_composition_enabled(&composition_enabled);
|
||||
}
|
||||
return composition_enabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
FluFrameless::FluFrameless(QQuickItem *parent)
|
||||
: QQuickItem{parent}
|
||||
{
|
||||
appbar(nullptr);
|
||||
maximizeButton(nullptr);
|
||||
minimizedButton(nullptr);
|
||||
closeButton(nullptr);
|
||||
topmost(false);
|
||||
disabled(false);
|
||||
}
|
||||
|
||||
FluFrameless::~FluFrameless(){
|
||||
qApp->removeNativeEventFilter(this);
|
||||
}
|
||||
|
||||
void FluFrameless::componentComplete(){
|
||||
if(_disabled){
|
||||
return;
|
||||
}
|
||||
_current = window()->winId();
|
||||
window()->setFlags(( window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint);
|
||||
if(!_fixSize){
|
||||
window()->setFlag(Qt::WindowMaximizeButtonHint);
|
||||
}
|
||||
window()->installEventFilter(this);
|
||||
qApp->installNativeEventFilter(this);
|
||||
if(_appbar){
|
||||
_appbar->installEventFilter(this);
|
||||
}
|
||||
if(_maximizeButton){
|
||||
setHitTestVisible(_maximizeButton);
|
||||
}
|
||||
if(_minimizedButton){
|
||||
setHitTestVisible(_minimizedButton);
|
||||
}
|
||||
if(_closeButton){
|
||||
setHitTestVisible(_closeButton);
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
if(_fixSize){
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME);
|
||||
for (int i = 0; i < qApp->screens().count(); ++i) {
|
||||
connect( qApp->screens().at(i),&QScreen::logicalDotsPerInchChanged,this,[=]{
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME);
|
||||
}
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
connect(window(),&QQuickWindow::screenChanged,this,[hwnd]{
|
||||
::SetWindowPos(hwnd,0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
|
||||
::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
});
|
||||
#endif
|
||||
connect(this,&FluFrameless::topmostChanged,this,[this]{
|
||||
_setWindowTopmost(topmost());
|
||||
});
|
||||
_setWindowTopmost(topmost());
|
||||
}
|
||||
|
||||
bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
|
||||
#ifdef Q_OS_WIN
|
||||
if ((eventType != qtNativeEventType()) || !message) {
|
||||
return false;
|
||||
}
|
||||
const auto msg = static_cast<const MSG *>(message);
|
||||
const HWND hwnd = msg->hwnd;
|
||||
if (!hwnd || !msg) {
|
||||
return false;
|
||||
}
|
||||
const qint64 wid = reinterpret_cast<qint64>(hwnd);
|
||||
if(wid != _current){
|
||||
return false;
|
||||
}
|
||||
const UINT uMsg = msg->message;
|
||||
const WPARAM wParam = msg->wParam;
|
||||
const LPARAM lParam = msg->lParam;
|
||||
static QPoint offsetXY;
|
||||
if(uMsg == WM_WINDOWPOSCHANGING){
|
||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else if(uMsg == WM_NCCALCSIZE){
|
||||
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||
const LONG originalTop = clientRect->top;
|
||||
const LONG originalLeft = clientRect->left;
|
||||
const LONG originalRight = clientRect->right;
|
||||
const LONG originalBottom = clientRect->bottom;
|
||||
const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam);
|
||||
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
|
||||
*result = hitTestResult;
|
||||
return true;
|
||||
}
|
||||
int offsetSize = 0;
|
||||
bool isMaximum = ::IsZoomed(hwnd);
|
||||
offsetXY = QPoint(abs(clientRect->left - originalLeft),abs(clientRect->top - originalTop));
|
||||
if(isMaximum || _isFullScreen()){
|
||||
offsetSize = 0;
|
||||
}else{
|
||||
offsetSize = 1;
|
||||
}
|
||||
if(!isCompositionEnabled()){
|
||||
offsetSize = 0;
|
||||
}
|
||||
if (!isMaximum || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) {
|
||||
clientRect->top = originalTop + offsetSize;
|
||||
clientRect->bottom = originalBottom - offsetSize;
|
||||
clientRect->left = originalLeft + offsetSize;
|
||||
clientRect->right = originalRight - offsetSize;
|
||||
}
|
||||
*result = WVR_REDRAW;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCHITTEST){
|
||||
if(_hitMaximizeButton()){
|
||||
if (*result == HTNOWHERE) {
|
||||
*result = HTZOOM;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*result = 0;
|
||||
POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
POINT nativeLocalPos = nativeGlobalPos;
|
||||
::ScreenToClient(hwnd, &nativeLocalPos);
|
||||
RECT clientRect{0, 0, 0, 0};
|
||||
::GetClientRect(hwnd, &clientRect);
|
||||
auto clientWidth = clientRect.right-clientRect.left;
|
||||
auto clientHeight = clientRect.bottom-clientRect.top;
|
||||
bool left = nativeLocalPos.x < _margins;
|
||||
bool right = nativeLocalPos.x > clientWidth - _margins;
|
||||
bool top = nativeLocalPos.y < _margins;
|
||||
bool bottom = nativeLocalPos.y > clientHeight - _margins;
|
||||
*result = 0;
|
||||
if (!_fixSize && !_isFullScreen() && !_isMaximized()) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
if(_hitAppBar()){
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
*result = HTCLIENT;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN){
|
||||
if(_hitMaximizeButton()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_maximizeButton,&event);
|
||||
return true;
|
||||
}
|
||||
}else if(uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP){
|
||||
if(_hitMaximizeButton()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_maximizeButton,&event);
|
||||
return true;
|
||||
}
|
||||
}else if(uMsg == WM_NCPAINT){
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCACTIVATE){
|
||||
*result = ::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1);
|
||||
return true;
|
||||
}else if(uMsg == WM_GETMINMAXINFO){
|
||||
MINMAXINFO* minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
minmaxInfo->ptMaxPosition.x = 0;
|
||||
minmaxInfo->ptMaxPosition.y = 0;
|
||||
minmaxInfo->ptMaxSize.x = 0;
|
||||
minmaxInfo->ptMaxSize.y = 0;
|
||||
#else
|
||||
auto pixelRatio = window()->devicePixelRatio();
|
||||
auto geometry = window()->screen()->availableGeometry();
|
||||
RECT rect;
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
|
||||
minmaxInfo->ptMaxPosition.x = rect.left - offsetXY.x();
|
||||
minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x();
|
||||
minmaxInfo->ptMaxSize.x = geometry.width()*pixelRatio + offsetXY.x() * 2;
|
||||
minmaxInfo->ptMaxSize.y = geometry.height()*pixelRatio + offsetXY.y() * 2;
|
||||
#endif
|
||||
return false;
|
||||
}else if(uMsg == WM_NCRBUTTONDOWN){
|
||||
if (wParam == HTCAPTION) {
|
||||
_showSystemMenu(QCursor::pos());
|
||||
}
|
||||
}else if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN){
|
||||
const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0));
|
||||
const bool spacePressed = ((wParam == VK_SPACE) || (::GetKeyState(VK_SPACE) < 0));
|
||||
if (altPressed && spacePressed) {
|
||||
auto pos = window()->position();
|
||||
_showSystemMenu(QPoint(pos.x(),pos.y()+_appbar->height()));
|
||||
}
|
||||
}else if(uMsg == WM_SYSCOMMAND){
|
||||
if(wParam == SC_MINIMIZE){
|
||||
if(window()->transientParent()){
|
||||
window()->transientParent()->showMinimized();
|
||||
}else{
|
||||
window()->showMinimized();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FluFrameless::_isMaximized(){
|
||||
return window()->visibility() == QWindow::Maximized;
|
||||
}
|
||||
|
||||
bool FluFrameless::_isFullScreen(){
|
||||
return window()->visibility() == QWindow::FullScreen;
|
||||
}
|
||||
|
||||
void FluFrameless::_showSystemMenu(QPoint point){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd,GWL_STYLE);
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU);
|
||||
const HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
|
||||
if(_isMaximized() || _isFullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_DISABLED);
|
||||
}
|
||||
if(!_fixSize && !_isMaximized() && !_isFullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_DISABLED);
|
||||
}
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), point.x()*window()->devicePixelRatio(), point.y()*window()->devicePixelRatio(), 0, hwnd, nullptr);
|
||||
if (result != FALSE) {
|
||||
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
|
||||
}
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style &~ WS_SYSMENU);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FluFrameless::_containsCursorToItem(QQuickItem* item){
|
||||
if(!item || !item->isVisible()){
|
||||
return false;
|
||||
}
|
||||
auto point = QCursor::pos();
|
||||
auto rect = QRectF(item->mapToGlobal(QPoint(0,0)),item->size());
|
||||
if(point.x()>rect.x() && point.x()<(rect.x()+rect.width()) && point.y()>rect.y() && point.y()<(rect.y()+rect.height())){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FluFrameless::_hitAppBar(){
|
||||
foreach (auto item, _hitTestList) {
|
||||
if(_containsCursorToItem(item)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(_containsCursorToItem(_appbar)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FluFrameless::_hitMaximizeButton(){
|
||||
if(_containsCursorToItem(_maximizeButton)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FluFrameless::_updateCursor(int edges){
|
||||
switch (edges) {
|
||||
case 0:
|
||||
window()->setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
window()->setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Qt::LeftEdge | Qt::TopEdge:
|
||||
case Qt::RightEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Qt::RightEdge | Qt::TopEdge:
|
||||
case Qt::LeftEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FluFrameless::showFullScreen(){
|
||||
window()->showFullScreen();
|
||||
}
|
||||
|
||||
void FluFrameless::showMaximized(){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
::ShowWindow(hwnd,3);
|
||||
#else
|
||||
window()->showMaximized();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFrameless::showMinimized(){
|
||||
window()->showMinimized();
|
||||
}
|
||||
|
||||
void FluFrameless::showNormal(){
|
||||
window()->showNormal();
|
||||
}
|
||||
|
||||
void FluFrameless::setHitTestVisible(QQuickItem* val){
|
||||
_hitTestList.append(val);
|
||||
}
|
||||
|
||||
|
||||
void FluFrameless::_setWindowTopmost(bool topmost){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
if(topmost){
|
||||
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}else{
|
||||
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
#else
|
||||
window()->setFlag(Qt::WindowStaysOnTopHint,topmost);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){
|
||||
#ifndef Q_OS_WIN
|
||||
switch (ev->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
if(_edges!=0){
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
if(event->button() == Qt::LeftButton){
|
||||
_updateCursor(_edges);
|
||||
window()->startSystemResize(Qt::Edges(_edges));
|
||||
}
|
||||
}else{
|
||||
if(_hitAppBar()){
|
||||
window()->startSystemMove();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
_edges = 0;
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if(_isMaximized() || _isFullScreen()){
|
||||
break;
|
||||
}
|
||||
if(_fixSize){
|
||||
break;
|
||||
}
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
QPoint p =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
event->pos();
|
||||
#else
|
||||
event->position().toPoint();
|
||||
#endif
|
||||
if(p.x() >= _margins && p.x() <= (window()->width() - _margins) && p.y() >= _margins && p.y() <= (window()->height() - _margins)){
|
||||
if(_edges != 0){
|
||||
_edges = 0;
|
||||
_updateCursor(_edges);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_edges = 0;
|
||||
if ( p.x() < _margins ) {
|
||||
_edges |= Qt::LeftEdge;
|
||||
}
|
||||
if ( p.x() > (window()->width() - _margins) ) {
|
||||
_edges |= Qt::RightEdge;
|
||||
}
|
||||
if ( p.y() < _margins ) {
|
||||
_edges |= Qt::TopEdge;
|
||||
}
|
||||
if ( p.y() > (window()->height() - _margins) ) {
|
||||
_edges |= Qt::BottomEdge;
|
||||
}
|
||||
_updateCursor(_edges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return QObject::eventFilter(obj, ev);
|
||||
}
|
57
src/FluFrameless.h
Normal file
57
src/FluFrameless.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef FLUFRAMELESS_H
|
||||
#define FLUFRAMELESS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include "stdafx.h"
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
||||
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
||||
#else
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = long;
|
||||
using QT_ENTER_EVENT_TYPE = QEvent;
|
||||
#endif
|
||||
|
||||
|
||||
class FluFrameless : public QQuickItem,QAbstractNativeEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QQuickItem*,appbar)
|
||||
Q_PROPERTY_AUTO(bool,topmost)
|
||||
Q_PROPERTY_AUTO(QQuickItem*,maximizeButton)
|
||||
Q_PROPERTY_AUTO(QQuickItem*,minimizedButton)
|
||||
Q_PROPERTY_AUTO(QQuickItem*,closeButton)
|
||||
Q_PROPERTY_AUTO(bool,disabled)
|
||||
Q_PROPERTY_AUTO(bool,fixSize)
|
||||
QML_NAMED_ELEMENT(FluFrameless)
|
||||
public:
|
||||
explicit FluFrameless(QQuickItem* parent = nullptr);
|
||||
~FluFrameless();
|
||||
void componentComplete() override;
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
||||
Q_INVOKABLE void showFullScreen();
|
||||
Q_INVOKABLE void showMaximized();
|
||||
Q_INVOKABLE void showMinimized();
|
||||
Q_INVOKABLE void showNormal();
|
||||
Q_INVOKABLE void setHitTestVisible(QQuickItem*);
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
private:
|
||||
bool _isFullScreen();
|
||||
bool _isMaximized();
|
||||
void _updateCursor(int edges);
|
||||
void _setWindowTopmost(bool topmost);
|
||||
void _showSystemMenu(QPoint point);
|
||||
bool _containsCursorToItem(QQuickItem* item);
|
||||
bool _hitAppBar();
|
||||
bool _hitMaximizeButton();
|
||||
private:
|
||||
qint64 _current;
|
||||
int _edges = 0;
|
||||
int _margins = 8;
|
||||
QList<QPointer<QQuickItem>> _hitTestList;
|
||||
};
|
||||
|
||||
#endif // FLUFRAMELESS_H
|
@ -1,500 +0,0 @@
|
||||
#include "FluFramelessHelper.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QQuickItem>
|
||||
#include "FluTools.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#pragma comment (lib,"dwmapi.lib")
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
static inline QByteArray qtNativeEventType()
|
||||
{
|
||||
static const auto result = "windows_generic_MSG";
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool isCompositionEnabled(){
|
||||
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
|
||||
HMODULE module = ::LoadLibraryW(L"dwmapi.dll");
|
||||
if (module)
|
||||
{
|
||||
BOOL composition_enabled = false;
|
||||
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
|
||||
dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||
if (dwm_is_composition_enabled)
|
||||
{
|
||||
dwm_is_composition_enabled(&composition_enabled);
|
||||
}
|
||||
return composition_enabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FramelessEventFilter::FramelessEventFilter(FluFramelessHelper* helper){
|
||||
_helper = helper;
|
||||
_current = _helper->window->winId();
|
||||
}
|
||||
|
||||
bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
|
||||
#ifdef Q_OS_WIN
|
||||
if ((eventType != qtNativeEventType()) || !message || _helper.isNull() || _helper->window.isNull()) {
|
||||
return false;
|
||||
}
|
||||
const auto msg = static_cast<const MSG *>(message);
|
||||
const HWND hwnd = msg->hwnd;
|
||||
if (!hwnd || !msg) {
|
||||
return false;
|
||||
}
|
||||
const qint64 wid = reinterpret_cast<qint64>(hwnd);
|
||||
if(wid != _current){
|
||||
return false;
|
||||
}
|
||||
const UINT uMsg = msg->message;
|
||||
const WPARAM wParam = msg->wParam;
|
||||
const LPARAM lParam = msg->lParam;
|
||||
static QPoint offsetXY;
|
||||
if(uMsg == WM_WINDOWPOSCHANGING){
|
||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else if(uMsg == WM_NCCALCSIZE){
|
||||
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||
const LONG originalTop = clientRect->top;
|
||||
const LONG originalLeft = clientRect->left;
|
||||
const LONG originalRight = clientRect->right;
|
||||
const LONG originalBottom = clientRect->bottom;
|
||||
const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam);
|
||||
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
|
||||
*result = hitTestResult;
|
||||
return true;
|
||||
}
|
||||
int offsetSize = 0;
|
||||
bool isMaximum = ::IsZoomed(hwnd);
|
||||
offsetXY = QPoint(abs(clientRect->left - originalLeft),abs(clientRect->top - originalTop));
|
||||
if(isMaximum || _helper->fullScreen()){
|
||||
offsetSize = 0;
|
||||
}else{
|
||||
offsetSize = 1;
|
||||
}
|
||||
if(!isCompositionEnabled()){
|
||||
offsetSize = 0;
|
||||
}
|
||||
if (!isMaximum || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) {
|
||||
clientRect->top = originalTop + offsetSize;
|
||||
clientRect->bottom = originalBottom - offsetSize;
|
||||
clientRect->left = originalLeft + offsetSize;
|
||||
clientRect->right = originalRight - offsetSize;
|
||||
}
|
||||
*result = WVR_REDRAW;
|
||||
return true;
|
||||
}if(uMsg == WM_NCHITTEST){
|
||||
if(FluTools::getInstance()->isWindows11OrGreater() && _helper->hoverMaxBtn() && _helper->resizeable()){
|
||||
if (*result == HTNOWHERE) {
|
||||
*result = HTZOOM;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*result = 0;
|
||||
POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
POINT nativeLocalPos = nativeGlobalPos;
|
||||
::ScreenToClient(hwnd, &nativeLocalPos);
|
||||
RECT clientRect{0, 0, 0, 0};
|
||||
::GetClientRect(hwnd, &clientRect);
|
||||
auto clientWidth = clientRect.right-clientRect.left;
|
||||
auto clientHeight = clientRect.bottom-clientRect.top;
|
||||
int margins = _helper->getMargins();
|
||||
bool left = nativeLocalPos.x < margins;
|
||||
bool right = nativeLocalPos.x > clientWidth - margins;
|
||||
bool top = nativeLocalPos.y < margins;
|
||||
bool bottom = nativeLocalPos.y > clientHeight - margins;
|
||||
*result = 0;
|
||||
if (_helper->resizeable() && !_helper->fullScreen() && !_helper->maximized()) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
QVariant appBar = _helper->getAppBar();
|
||||
if(!appBar.isNull()&& _helper->hoverAppBar()){
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
*result = HTCLIENT;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN){
|
||||
if(_helper->hoverMaxBtn()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_helper->maximizeButton(),&event);
|
||||
return true;
|
||||
}
|
||||
}else if(uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP){
|
||||
if(_helper->hoverMaxBtn()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_helper->maximizeButton(),&event);
|
||||
}
|
||||
}else if(uMsg == WM_NCPAINT){
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCACTIVATE){
|
||||
*result = ::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1);
|
||||
return true;
|
||||
}else if(uMsg == WM_GETMINMAXINFO){
|
||||
MINMAXINFO* minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
minmaxInfo->ptMaxPosition.x = 0;
|
||||
minmaxInfo->ptMaxPosition.y = 0;
|
||||
minmaxInfo->ptMaxSize.x = 0;
|
||||
minmaxInfo->ptMaxSize.y = 0;
|
||||
#else
|
||||
auto pixelRatio = _helper->window->devicePixelRatio();
|
||||
auto geometry = _helper->window->screen()->availableGeometry();
|
||||
RECT rect;
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
|
||||
minmaxInfo->ptMaxPosition.x = rect.left - offsetXY.x();
|
||||
minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x();
|
||||
minmaxInfo->ptMaxSize.x = geometry.width()*pixelRatio + offsetXY.x() * 2;
|
||||
minmaxInfo->ptMaxSize.y = geometry.height()*pixelRatio + offsetXY.y() * 2;
|
||||
#endif
|
||||
return false;
|
||||
}else if(uMsg == WM_NCRBUTTONDOWN){
|
||||
if (wParam == HTCAPTION) {
|
||||
_helper->showSystemMenu(QCursor::pos());
|
||||
}
|
||||
}else if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN){
|
||||
const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0));
|
||||
const bool spacePressed = ((wParam == VK_SPACE) || (::GetKeyState(VK_SPACE) < 0));
|
||||
if (altPressed && spacePressed) {
|
||||
auto pos = _helper->window->position();
|
||||
_helper->showSystemMenu(QPoint(pos.x(),pos.y()+_helper->getAppBarHeight()));
|
||||
}
|
||||
}else if(uMsg == WM_SYSCOMMAND){
|
||||
if(wParam == SC_MINIMIZE){
|
||||
if(_helper->window->transientParent()){
|
||||
_helper->window->transientParent()->showMinimized();
|
||||
}else{
|
||||
_helper->window->showMinimized();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FluFramelessHelper::FluFramelessHelper(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
}
|
||||
|
||||
void FluFramelessHelper::classBegin(){
|
||||
}
|
||||
|
||||
void FluFramelessHelper::_updateCursor(int edges){
|
||||
switch (edges) {
|
||||
case 0:
|
||||
window->setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
window->setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
window->setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Qt::LeftEdge | Qt::TopEdge:
|
||||
case Qt::RightEdge | Qt::BottomEdge:
|
||||
window->setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Qt::RightEdge | Qt::TopEdge:
|
||||
case Qt::LeftEdge | Qt::BottomEdge:
|
||||
window->setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::eventFilter(QObject *obj, QEvent *ev){
|
||||
if (!window.isNull() && window->flags()) {
|
||||
switch (ev->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
if(_edges!=0){
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
if(event->button() == Qt::LeftButton){
|
||||
_updateCursor(_edges);
|
||||
window->startSystemResize(Qt::Edges(_edges));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
_edges = 0;
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if(maximized() || fullScreen()){
|
||||
break;
|
||||
}
|
||||
if(!resizeable()){
|
||||
break;
|
||||
}
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
QPoint p =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
event->pos();
|
||||
#else
|
||||
event->position().toPoint();
|
||||
#endif
|
||||
if(p.x() >= _margins && p.x() <= (window->width() - _margins) && p.y() >= _margins && p.y() <= (window->height() - _margins)){
|
||||
if(_edges != 0){
|
||||
_edges = 0;
|
||||
_updateCursor(_edges);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_edges = 0;
|
||||
if ( p.x() < _margins ) {
|
||||
_edges |= Qt::LeftEdge;
|
||||
}
|
||||
if ( p.x() > (window->width() - _margins) ) {
|
||||
_edges |= Qt::RightEdge;
|
||||
}
|
||||
if ( p.y() < _margins ) {
|
||||
_edges |= Qt::TopEdge;
|
||||
}
|
||||
if ( p.y() > (window->height() - _margins) ) {
|
||||
_edges |= Qt::BottomEdge;
|
||||
}
|
||||
_updateCursor(_edges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void FluFramelessHelper::componentComplete(){
|
||||
auto o = parent();
|
||||
do {
|
||||
window = qobject_cast<QQuickWindow *>(o);
|
||||
if (window) {
|
||||
break;
|
||||
}
|
||||
o = o->parent();
|
||||
} while (nullptr != o);
|
||||
if(!window.isNull()){
|
||||
_stayTop = QQmlProperty(window,"stayTop");
|
||||
_screen = QQmlProperty(window,"screen");
|
||||
_fixSize = QQmlProperty(window,"fixSize");
|
||||
_realHeight = QQmlProperty(window,"_realHeight");
|
||||
_realWidth = QQmlProperty(window,"_realWidth");
|
||||
_appBarHeight = QQmlProperty(window,"_appBarHeight");
|
||||
_appBar = window->property("appBar");
|
||||
#ifdef Q_OS_WIN
|
||||
if(!_appBar.isNull()){
|
||||
_appBar.value<QObject*>()->setProperty("systemMoveEnable",false);
|
||||
}
|
||||
window->setFlags((window->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
if(FluTools::getInstance()->isSoftware()){
|
||||
window->setFlag(Qt::FramelessWindowHint,false);
|
||||
}
|
||||
#endif
|
||||
if(resizeable()){
|
||||
window->setFlag(Qt::WindowMaximizeButtonHint);
|
||||
}
|
||||
_nativeEvent =new FramelessEventFilter(this);
|
||||
qApp->installNativeEventFilter(_nativeEvent);
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||
if(resizeable()){
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME);
|
||||
}else{
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME);
|
||||
for (int i = 0; i < qApp->screens().count(); ++i) {
|
||||
connect( qApp->screens().at(i),&QScreen::logicalDotsPerInchChanged,this,[=]{
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
});
|
||||
}
|
||||
}
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
#else
|
||||
window->setFlags((window->flags() & (~Qt::WindowMinMaxButtonsHint) & (~Qt::Dialog)) | Qt::FramelessWindowHint | Qt::Window);
|
||||
window->installEventFilter(this);
|
||||
#endif
|
||||
int w = _realWidth.read().toInt();
|
||||
int h = _realHeight.read().toInt()+_appBarHeight.read().toInt();
|
||||
if(!resizeable()){
|
||||
window->setMaximumSize(QSize(w,h));
|
||||
window->setMinimumSize(QSize(w,h));
|
||||
}
|
||||
window->resize(QSize(w,h));
|
||||
_onStayTopChange();
|
||||
_stayTop.connectNotifySignal(this,SLOT(_onStayTopChange()));
|
||||
_screen.connectNotifySignal(this,SLOT(_onScreenChanged()));
|
||||
Q_EMIT loadCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
void FluFramelessHelper::_onScreenChanged(){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
::SetWindowPos(hwnd,0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
|
||||
::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFramelessHelper::showSystemMenu(QPoint point){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd,GWL_STYLE);
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU);
|
||||
const HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
|
||||
if(maximized() || fullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_DISABLED);
|
||||
}
|
||||
if(resizeable() && !maximized() && !fullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_DISABLED);
|
||||
}
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), point.x()*window->devicePixelRatio(), point.y()*window->devicePixelRatio(), 0, hwnd, nullptr);
|
||||
if (result != FALSE) {
|
||||
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
|
||||
}
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style &~ WS_SYSMENU);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFramelessHelper::showMaximized(){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
::ShowWindow(hwnd,3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFramelessHelper::_onStayTopChange(){
|
||||
bool isStayTop = _stayTop.read().toBool();
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
if(isStayTop){
|
||||
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}else{
|
||||
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
#else
|
||||
window->setFlag(Qt::WindowStaysOnTopHint,isStayTop);
|
||||
#endif
|
||||
}
|
||||
|
||||
FluFramelessHelper::~FluFramelessHelper(){
|
||||
if (!window.isNull()) {
|
||||
window->setFlags(Qt::Window);
|
||||
#ifdef Q_OS_WIN
|
||||
qApp->removeNativeEventFilter(_nativeEvent);
|
||||
delete _nativeEvent;
|
||||
#endif
|
||||
window->removeEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::hoverMaxBtn(){
|
||||
if(_appBar.isNull()){
|
||||
return false;
|
||||
}
|
||||
QVariant var;
|
||||
QMetaObject::invokeMethod(_appBar.value<QObject*>(), "_maximizeButtonHover",Q_RETURN_ARG(QVariant, var));
|
||||
if(var.isNull()){
|
||||
return false;
|
||||
}
|
||||
return var.toBool();
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::hoverAppBar(){
|
||||
if(_appBar.isNull()){
|
||||
return false;
|
||||
}
|
||||
QVariant var;
|
||||
QMetaObject::invokeMethod(_appBar.value<QObject*>(), "_appBarHover",Q_RETURN_ARG(QVariant, var));
|
||||
if(var.isNull()){
|
||||
return false;
|
||||
}
|
||||
return var.toBool();
|
||||
}
|
||||
|
||||
QVariant FluFramelessHelper::getAppBar(){
|
||||
return _appBar;
|
||||
}
|
||||
|
||||
int FluFramelessHelper::getAppBarHeight(){
|
||||
if(_appBar.isNull()){
|
||||
return 0;
|
||||
}
|
||||
QVariant var = _appBar.value<QObject*>()->property("height");
|
||||
if(var.isNull()){
|
||||
return 0;
|
||||
}
|
||||
return var.toInt();
|
||||
}
|
||||
|
||||
QObject* FluFramelessHelper::maximizeButton(){
|
||||
if(_appBar.isNull()){
|
||||
return nullptr;
|
||||
}
|
||||
QVariant var = _appBar.value<QObject*>()->property("buttonMaximize");
|
||||
if(var.isNull()){
|
||||
return nullptr;
|
||||
}
|
||||
return var.value<QObject*>();
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::resizeable(){
|
||||
return !_fixSize.read().toBool();
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::maximized(){
|
||||
return window->visibility() == QWindow::Maximized;
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::fullScreen(){
|
||||
return window->visibility() == QWindow::FullScreen;
|
||||
}
|
||||
|
||||
int FluFramelessHelper::getMargins(){
|
||||
return _margins;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
#ifndef FLUFRAMELESSHELPER_H
|
||||
#define FLUFRAMELESSHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickWindow>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QQmlProperty>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
||||
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
||||
#else
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = long;
|
||||
using QT_ENTER_EVENT_TYPE = QEvent;
|
||||
#endif
|
||||
|
||||
class FluFramelessHelper;
|
||||
|
||||
/**
|
||||
* @brief The FramelessEventFilter class
|
||||
*/
|
||||
class FramelessEventFilter : public QAbstractNativeEventFilter
|
||||
{
|
||||
public:
|
||||
FramelessEventFilter(FluFramelessHelper* helper);
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
||||
public:
|
||||
QPointer<FluFramelessHelper> _helper = nullptr;
|
||||
qint64 _current = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluFramelessHelper class
|
||||
*/
|
||||
class FluFramelessHelper : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
QML_NAMED_ELEMENT(FluFramelessHelper)
|
||||
public:
|
||||
explicit FluFramelessHelper(QObject *parent = nullptr);
|
||||
~FluFramelessHelper();
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
bool hoverMaxBtn();
|
||||
bool hoverAppBar();
|
||||
bool resizeable();
|
||||
int getMargins();
|
||||
bool maximized();
|
||||
bool fullScreen();
|
||||
int getAppBarHeight();
|
||||
QVariant getAppBar();
|
||||
QObject* maximizeButton();
|
||||
void setOriginalPos(QVariant pos);
|
||||
Q_INVOKABLE void showSystemMenu(QPoint point);
|
||||
Q_INVOKABLE void showMaximized();
|
||||
Q_SIGNAL void loadCompleted();
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
private:
|
||||
void _updateCursor(int edges);
|
||||
Q_SLOT void _onStayTopChange();
|
||||
Q_SLOT void _onScreenChanged();
|
||||
public:
|
||||
QPointer<QQuickWindow> window = nullptr;
|
||||
private:
|
||||
FramelessEventFilter* _nativeEvent = nullptr;
|
||||
QQmlProperty _stayTop;
|
||||
QQmlProperty _screen;
|
||||
QQmlProperty _fixSize;
|
||||
QQmlProperty _realHeight;
|
||||
QQmlProperty _realWidth;
|
||||
QQmlProperty _appBarHeight;
|
||||
QVariant _appBar;
|
||||
int _edges = 0;
|
||||
int _margins = 8;
|
||||
};
|
||||
|
||||
#endif // FLUFRAMELESSHELPER_H
|
158
src/FluNetwork.h
158
src/FluNetwork.h
@ -1,158 +0,0 @@
|
||||
#ifndef FLUNETWORK_H
|
||||
#define FLUNETWORK_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QFile>
|
||||
#include <QJsonValue>
|
||||
#include <QJSValue>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include "Def.h"
|
||||
#include "stdafx.h"
|
||||
#include "singleton.h"
|
||||
|
||||
/**
|
||||
* @brief The NetworkCallable class
|
||||
*/
|
||||
class FluNetworkCallable : public QObject{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(FluNetworkCallable)
|
||||
public:
|
||||
explicit FluNetworkCallable(QObject *parent = nullptr);
|
||||
Q_SIGNAL void start();
|
||||
Q_SIGNAL void finish();
|
||||
Q_SIGNAL void error(int status,QString errorString,QString result);
|
||||
Q_SIGNAL void success(QString result);
|
||||
Q_SIGNAL void cache(QString result);
|
||||
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
|
||||
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluDownloadParam class
|
||||
*/
|
||||
class FluDownloadParam : public QObject{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FluDownloadParam(QObject *parent = nullptr);
|
||||
FluDownloadParam(QString destPath,bool append,QObject *parent = nullptr);
|
||||
public:
|
||||
QString _destPath;
|
||||
bool _append;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluNetworkParams class
|
||||
*/
|
||||
class FluNetworkParams : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(FluNetworkParams)
|
||||
public:
|
||||
enum Method{
|
||||
METHOD_GET,
|
||||
METHOD_HEAD,
|
||||
METHOD_POST,
|
||||
METHOD_PUT,
|
||||
METHOD_PATCH,
|
||||
METHOD_DELETE
|
||||
};
|
||||
enum Type{
|
||||
TYPE_NONE,
|
||||
TYPE_FORM,
|
||||
TYPE_JSON,
|
||||
TYPE_JSONARRAY,
|
||||
TYPE_BODY
|
||||
};
|
||||
explicit FluNetworkParams(QObject *parent = nullptr);
|
||||
FluNetworkParams(QString url,Type type,Method method,QObject *parent = nullptr);
|
||||
Q_INVOKABLE FluNetworkParams* addQuery(QString key,QVariant val);
|
||||
Q_INVOKABLE FluNetworkParams* addHeader(QString key,QVariant val);
|
||||
Q_INVOKABLE FluNetworkParams* add(QString key,QVariant val);
|
||||
Q_INVOKABLE FluNetworkParams* addFile(QString key,QVariant val);
|
||||
Q_INVOKABLE FluNetworkParams* setBody(QString val);
|
||||
Q_INVOKABLE FluNetworkParams* setTimeout(int val);
|
||||
Q_INVOKABLE FluNetworkParams* setRetry(int val);
|
||||
Q_INVOKABLE FluNetworkParams* setCacheMode(int val);
|
||||
Q_INVOKABLE FluNetworkParams* toDownload(QString destPath,bool append = false);
|
||||
Q_INVOKABLE FluNetworkParams* bind(QObject* target);
|
||||
Q_INVOKABLE FluNetworkParams* openLog(QVariant val);
|
||||
Q_INVOKABLE void go(FluNetworkCallable* result);
|
||||
QString buildCacheKey();
|
||||
QString method2String();
|
||||
int getTimeout();
|
||||
int getRetry();
|
||||
bool getOpenLog();
|
||||
public:
|
||||
FluDownloadParam* _downloadParam = nullptr;
|
||||
QObject* _target = nullptr;
|
||||
Method _method;
|
||||
Type _type;
|
||||
QString _url;
|
||||
QString _body;
|
||||
QMap<QString, QVariant> _queryMap;
|
||||
QMap<QString, QVariant> _headerMap;
|
||||
QMap<QString, QVariant> _paramMap;
|
||||
QMap<QString, QVariant> _fileMap;
|
||||
int _timeout = -1;
|
||||
int _retry = -1;
|
||||
QVariant _openLog;
|
||||
int _cacheMode = FluNetworkType::CacheMode::NoCache;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluNetwork class
|
||||
*/
|
||||
class FluNetwork : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(int,timeout)
|
||||
Q_PROPERTY_AUTO(int,retry)
|
||||
Q_PROPERTY_AUTO(QString,cacheDir)
|
||||
Q_PROPERTY_AUTO(bool,openLog)
|
||||
QML_NAMED_ELEMENT(FluNetwork)
|
||||
QML_SINGLETON
|
||||
private:
|
||||
explicit FluNetwork(QObject *parent = nullptr);
|
||||
public:
|
||||
SINGLETON(FluNetwork)
|
||||
static FluNetwork *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||
Q_INVOKABLE FluNetworkParams* get(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* head(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* postBody(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* putBody(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* patchBody(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* deleteBody(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* postForm(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* putForm(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* patchForm(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* deleteForm(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* postJson(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* putJson(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* patchJson(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* deleteJson(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* postJsonArray(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* putJsonArray(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* patchJsonArray(const QString& url);
|
||||
Q_INVOKABLE FluNetworkParams* deleteJsonArray(const QString& url);
|
||||
Q_INVOKABLE void setInterceptor(QJSValue interceptor);
|
||||
void handle(FluNetworkParams* params,FluNetworkCallable* result);
|
||||
void handleDownload(FluNetworkParams* params,FluNetworkCallable* result);
|
||||
private:
|
||||
void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,FluNetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<FluNetworkCallable> callable);
|
||||
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
|
||||
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers);
|
||||
void saveResponse(QString key,QString response);
|
||||
QString readCache(const QString& key);
|
||||
bool cacheExists(const QString& key);
|
||||
QString getCacheFilePath(const QString& key);
|
||||
QString map2String(const QMap<QString, QVariant>& map);
|
||||
QString headerList2String(const QList<QNetworkReply::RawHeaderPair>& data);
|
||||
void printRequestStartLog(QNetworkRequest request,FluNetworkParams* params);
|
||||
void printRequestEndLog(QNetworkRequest request,FluNetworkParams* params,QNetworkReply*& reply,const QString& response);
|
||||
public:
|
||||
QJSValue _interceptor;
|
||||
};
|
||||
|
||||
#endif // FLUNETWORK_H
|
@ -86,9 +86,9 @@ void FluTools::restoreOverrideCursor(){
|
||||
qApp->restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void FluTools::deleteItem(QObject *p){
|
||||
void FluTools::deleteLater(QObject *p){
|
||||
if(p){
|
||||
delete p;
|
||||
p->deleteLater();
|
||||
p = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
Q_INVOKABLE void restoreOverrideCursor();
|
||||
Q_INVOKABLE QString html2PlantText(const QString& html);
|
||||
Q_INVOKABLE QString toLocalPath(const QUrl& url);
|
||||
Q_INVOKABLE void deleteItem(QObject *p);
|
||||
Q_INVOKABLE void deleteLater(QObject *p);
|
||||
Q_INVOKABLE QString getFileNameByUrl(const QUrl& url);
|
||||
Q_INVOKABLE QRect getVirtualGeometry();
|
||||
Q_INVOKABLE QString getApplicationDirPath();
|
||||
|
@ -1,113 +0,0 @@
|
||||
#include "FluViewModel.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
#include "Def.h"
|
||||
|
||||
FluViewModelManager::FluViewModelManager(QObject *parent): QObject{parent}{
|
||||
}
|
||||
|
||||
void FluViewModelManager::insertViewModel(FluViewModel* value){
|
||||
_viewmodel.append(value);
|
||||
}
|
||||
|
||||
void FluViewModelManager::deleteViewModel(FluViewModel* value){
|
||||
_viewmodel.removeOne(value);
|
||||
}
|
||||
|
||||
QObject* FluViewModelManager::getModel(const QString& key){
|
||||
return _data.value(key);
|
||||
}
|
||||
|
||||
void FluViewModelManager::insert(const QString& key,QObject* value){
|
||||
_data.insert(key,value);
|
||||
}
|
||||
|
||||
bool FluViewModelManager::exist(const QString& key){
|
||||
return _data.contains(key);
|
||||
}
|
||||
|
||||
void FluViewModelManager::refreshViewModel(FluViewModel* viewModel,QString key,QVariant value){
|
||||
foreach (auto item, _viewmodel) {
|
||||
if(item->getKey() == viewModel->getKey()){
|
||||
item->enablePropertyChange = false;
|
||||
item->setProperty(key.toLatin1().constData(),value);
|
||||
item->enablePropertyChange = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluPropertyObserver::FluPropertyObserver(QString name,QObject* model,QObject *parent):QObject{parent}{
|
||||
_name = name;
|
||||
_model = model;
|
||||
_property = QQmlProperty(parent,_name);
|
||||
_property.connectNotifySignal(this,SLOT(_propertyChange()));
|
||||
}
|
||||
|
||||
FluPropertyObserver::~FluPropertyObserver(){
|
||||
}
|
||||
|
||||
void FluPropertyObserver::_propertyChange(){
|
||||
auto viewModel = (FluViewModel*)parent();
|
||||
if(viewModel->enablePropertyChange){
|
||||
auto value = _property.read();
|
||||
_model->setProperty(_name.toLatin1().constData(),value);
|
||||
FluViewModelManager::getInstance()->refreshViewModel(viewModel,_name,value);
|
||||
}
|
||||
}
|
||||
|
||||
FluViewModel::FluViewModel(QObject *parent):QObject{parent}{
|
||||
scope(FluViewModelType::Scope::Window);
|
||||
FluViewModelManager::getInstance()->insertViewModel(this);
|
||||
}
|
||||
|
||||
FluViewModel::~FluViewModel(){
|
||||
FluViewModelManager::getInstance()->deleteViewModel(this);
|
||||
}
|
||||
|
||||
void FluViewModel::classBegin(){
|
||||
}
|
||||
|
||||
void FluViewModel::componentComplete(){
|
||||
auto o = parent();
|
||||
while (nullptr != o) {
|
||||
_window = o;
|
||||
o = o->parent();
|
||||
}
|
||||
const QMetaObject* obj = metaObject();
|
||||
if(_scope == FluViewModelType::Scope::Window){
|
||||
_key = property("objectName").toString()+"-"+QString::number(reinterpret_cast<qulonglong>(_window), 16);
|
||||
}else{
|
||||
_key = property("objectName").toString();
|
||||
}
|
||||
QObject * model;
|
||||
if(!FluViewModelManager::getInstance()->exist(_key)){
|
||||
if(_scope == FluViewModelType::Scope::Window){
|
||||
model = new QObject(_window);
|
||||
}else{
|
||||
model = new QObject();
|
||||
}
|
||||
Q_EMIT initData();
|
||||
for (int i = 0; i < obj->propertyCount(); ++i) {
|
||||
const QMetaProperty property = obj->property(i);
|
||||
QString propertyName = property.name();
|
||||
auto value = property.read(this);
|
||||
model->setProperty(propertyName.toLatin1().constData(),value);
|
||||
new FluPropertyObserver(propertyName,model,this);
|
||||
}
|
||||
FluViewModelManager::getInstance()->insert(_key,model);
|
||||
}else{
|
||||
model = FluViewModelManager::getInstance()->getModel(_key);
|
||||
for (int i = 0; i < obj->propertyCount(); ++i) {
|
||||
const QMetaProperty property = obj->property(i);
|
||||
QString propertyName = property.name();
|
||||
new FluPropertyObserver(propertyName,model,this);
|
||||
}
|
||||
}
|
||||
foreach (auto key, model->dynamicPropertyNames()) {
|
||||
setProperty(key,model->property(key));
|
||||
}
|
||||
}
|
||||
|
||||
QString FluViewModel::getKey(){
|
||||
return _key;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
#ifndef FLUVIEWMODEL_H
|
||||
#define FLUVIEWMODEL_H
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QQuickWindow>
|
||||
#include <QQmlProperty>
|
||||
#include "stdafx.h"
|
||||
#include "singleton.h"
|
||||
|
||||
/**
|
||||
* @brief The FluViewModel class
|
||||
*/
|
||||
class FluViewModel : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
Q_PROPERTY_AUTO(int,scope);
|
||||
QML_NAMED_ELEMENT(FluViewModel)
|
||||
public:
|
||||
explicit FluViewModel(QObject *parent = nullptr);
|
||||
~FluViewModel();
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
Q_SIGNAL void initData();
|
||||
QString getKey();
|
||||
bool enablePropertyChange = true;
|
||||
private:
|
||||
QObject* _window = nullptr;
|
||||
QString _key = "";
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluPropertyObserver class
|
||||
*/
|
||||
class FluPropertyObserver: public QObject{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FluPropertyObserver(QString name,QObject* model,QObject *parent = nullptr);
|
||||
~FluPropertyObserver();
|
||||
private:
|
||||
Q_SLOT void _propertyChange();
|
||||
private:
|
||||
QString _name = "";
|
||||
QQmlProperty _property;
|
||||
QObject* _model = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluViewModelManager class
|
||||
*/
|
||||
class FluViewModelManager:public QObject{
|
||||
Q_OBJECT
|
||||
private:
|
||||
explicit FluViewModelManager(QObject *parent = nullptr);
|
||||
public:
|
||||
SINGLETON(FluViewModelManager)
|
||||
bool exist(const QString& key);
|
||||
void insert(const QString& key,QObject* value);
|
||||
QObject* getModel(const QString& key);
|
||||
void insertViewModel(FluViewModel* value);
|
||||
void deleteViewModel(FluViewModel* value);
|
||||
void refreshViewModel(FluViewModel* viewModel,QString key,QVariant value);
|
||||
private:
|
||||
QMap<QString,QObject*> _data;
|
||||
QList<FluViewModel*> _viewmodel;
|
||||
};
|
||||
|
||||
#endif // FLUVIEWMODEL_H
|
@ -1,28 +0,0 @@
|
||||
#include "FluWindowLifecycle.h"
|
||||
|
||||
#include "FluApp.h"
|
||||
|
||||
FluWindowLifecycle::FluWindowLifecycle(QObject *parent):QObject{parent}{
|
||||
|
||||
}
|
||||
|
||||
void FluWindowLifecycle::onCompleted(QQuickWindow* window){
|
||||
_window = window;
|
||||
if(_window && _window->transientParent() == nullptr){
|
||||
FluApp::getInstance()->addWindow(_window);
|
||||
}
|
||||
}
|
||||
|
||||
void FluWindowLifecycle::onDestoryOnClose(){
|
||||
if(_window && _window->transientParent() == nullptr){
|
||||
FluApp::getInstance()->removeWindow(_window);
|
||||
_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FluWindowLifecycle::onDestruction(){
|
||||
|
||||
}
|
||||
|
||||
void FluWindowLifecycle::onVisible(bool visible){
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#ifndef FLUWINDOWLIFECYCLE_H
|
||||
#define FLUWINDOWLIFECYCLE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickWindow>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QQuickItem>
|
||||
#include <QWindow>
|
||||
#include <QJsonObject>
|
||||
|
||||
/**
|
||||
* @brief The FluWindowLifecycle class
|
||||
*/
|
||||
class FluWindowLifecycle : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(FluWindowLifecycle)
|
||||
public:
|
||||
explicit FluWindowLifecycle(QObject *parent = nullptr);
|
||||
Q_INVOKABLE void onCompleted(QQuickWindow* window);
|
||||
Q_INVOKABLE void onDestruction();
|
||||
Q_INVOKABLE void onVisible(bool visible);
|
||||
Q_INVOKABLE void onDestoryOnClose();
|
||||
private:
|
||||
QQuickWindow* _window = nullptr;
|
||||
};
|
||||
|
||||
#endif // FLUWINDOWLIFECYCLE_H
|
@ -1,18 +0,0 @@
|
||||
#include "FluWindowRegister.h"
|
||||
|
||||
#include "FluApp.h"
|
||||
#include <QCoreApplication>
|
||||
|
||||
FluWindowRegister::FluWindowRegister(QObject *parent):QObject{parent}{
|
||||
from(nullptr);
|
||||
to(nullptr);
|
||||
path("");
|
||||
}
|
||||
|
||||
void FluWindowRegister::launch(const QJsonObject& argument){
|
||||
FluApp::getInstance()->navigate(path(),argument,this);
|
||||
}
|
||||
|
||||
void FluWindowRegister::onResult(const QJsonObject& data){
|
||||
Q_EMIT result(data);
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#ifndef FLUWINDOWREGISTER_H
|
||||
#define FLUWINDOWREGISTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickWindow>
|
||||
#include <QJsonObject>
|
||||
#include "stdafx.h"
|
||||
|
||||
/**
|
||||
* @brief The FluWindowRegister class
|
||||
*/
|
||||
class FluWindowRegister : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QQuickWindow*,from)
|
||||
Q_PROPERTY_AUTO(QQuickWindow*,to)
|
||||
Q_PROPERTY_AUTO(QString,path);
|
||||
public:
|
||||
explicit FluWindowRegister(QObject *parent = nullptr);
|
||||
Q_INVOKABLE void launch(const QJsonObject& argument = {});
|
||||
Q_INVOKABLE void onResult(const QJsonObject& data = {});
|
||||
Q_SIGNAL void result(const QJsonObject& data);
|
||||
};
|
||||
|
||||
#endif // FLUWINDOWREGISTER_H
|
@ -1,7 +1,6 @@
|
||||
#include "FluentUI.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include "FluWindowLifecycle.h"
|
||||
#include "Def.h"
|
||||
#include "FluApp.h"
|
||||
#include "FluColors.h"
|
||||
@ -10,14 +9,11 @@
|
||||
#include "FluTextStyle.h"
|
||||
#include "FluWatermark.h"
|
||||
#include "FluCaptcha.h"
|
||||
#include "FluEventBus.h"
|
||||
#include "FluTreeModel.h"
|
||||
#include "FluViewModel.h"
|
||||
#include "FluRectangle.h"
|
||||
#include "FluNetwork.h"
|
||||
#include "FluFramelessHelper.h"
|
||||
#include "FluQrCodeItem.h"
|
||||
#include "FluTableSortProxyModel.h"
|
||||
#include "FluFrameless.h"
|
||||
|
||||
void FluentUI::registerTypes(QQmlEngine *engine){
|
||||
initializeEngine(engine,uri);
|
||||
@ -27,18 +23,15 @@ void FluentUI::registerTypes(QQmlEngine *engine){
|
||||
void FluentUI::registerTypes(const char *uri){
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))
|
||||
Q_INIT_RESOURCE(fluentui);
|
||||
qmlRegisterType<FluWindowLifecycle>(uri,major,minor,"FluWindowLifecycle");
|
||||
|
||||
//@uri FluentUI
|
||||
qmlRegisterType<FluQrCodeItem>(uri,major,minor,"FluQrCodeItem");
|
||||
qmlRegisterType<FluCaptcha>(uri,major,minor,"FluCaptcha");
|
||||
qmlRegisterType<FluWatermark>(uri,major,minor,"FluWatermark");
|
||||
qmlRegisterType<FluAccentColor>(uri,major,minor,"FluAccentColor");
|
||||
qmlRegisterType<FluEvent>(uri,major,minor,"FluEvent");
|
||||
qmlRegisterType<FluViewModel>(uri,major,minor,"FluViewModel");
|
||||
qmlRegisterType<FluTreeModel>(uri,major,minor,"FluTreeModel");
|
||||
qmlRegisterType<FluRectangle>(uri,major,minor,"FluRectangle");
|
||||
qmlRegisterType<FluNetworkCallable>(uri,major,minor,"FluNetworkCallable");
|
||||
qmlRegisterType<FluNetworkParams>(uri,major,minor,"FluNetworkParams");
|
||||
qmlRegisterType<FluFramelessHelper>(uri,major,minor,"FluFramelessHelper");
|
||||
qmlRegisterType<FluFrameless>(uri,major,minor,"FluFrameless");
|
||||
qmlRegisterType<FluTableSortProxyModel>(uri,major,minor,"FluTableSortProxyModel");
|
||||
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAcrylic.qml"),uri,major,minor,"FluAcrylic");
|
||||
@ -128,6 +121,11 @@ void FluentUI::registerTypes(const char *uri){
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLoader.qml"),uri,major,minor,"FluLoader");
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluShortcutPicker.qml"),uri,major,minor,"FluShortcutPicker");
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSplitLayout.qml"),uri,major,minor,"FluSplitLayout");
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindowResultLauncher.qml"),uri,major,minor,"FluWindowResultLauncher");
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLauncher.qml"),uri,major,minor,"FluLauncher");
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluEvent.qml"),uri,major,minor,"FluEvent");
|
||||
qmlRegisterSingletonType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRouter.qml"),uri,major,minor,"FluRouter");
|
||||
qmlRegisterSingletonType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluEventBus.qml"),uri,major,minor,"FluEventBus");
|
||||
|
||||
qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluThemeType::staticMetaObject, uri,major,minor,"FluThemeType", "Access to enums & flags only");
|
||||
@ -141,8 +139,6 @@ void FluentUI::registerTypes(const char *uri){
|
||||
qmlRegisterUncreatableMetaObject(FluTabViewType::staticMetaObject, uri,major,minor,"FluTabViewType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluNavigationViewType::staticMetaObject, uri,major,minor,"FluNavigationViewType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri,major,minor,"FluTimelineType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluViewModelType::staticMetaObject, uri,major,minor,"FluViewModelType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluNetworkType::staticMetaObject, uri,major,minor,"FluNetworkType", "Access to enums & flags only");
|
||||
|
||||
qmlRegisterModule(uri,major,minor);
|
||||
#endif
|
||||
@ -154,18 +150,9 @@ void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){
|
||||
font.setFamily("微软雅黑");
|
||||
QGuiApplication::setFont(font);
|
||||
#endif
|
||||
FluApp* app = FluApp::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluApp",app);
|
||||
FluColors* colors = FluColors::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluColors",colors);
|
||||
FluTheme* theme = FluTheme::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluTheme",theme);
|
||||
FluTools* tools = FluTools::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluTools",tools);
|
||||
FluTextStyle* textStyle = FluTextStyle::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluTextStyle",textStyle);
|
||||
FluEventBus* eventBus = FluEventBus::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluEventBus",eventBus);
|
||||
FluNetwork* network = FluNetwork::getInstance();
|
||||
engine->rootContext()->setContextProperty("FluNetwork",network);
|
||||
engine->rootContext()->setContextProperty("FluApp",FluApp::getInstance());
|
||||
engine->rootContext()->setContextProperty("FluColors",FluColors::getInstance());
|
||||
engine->rootContext()->setContextProperty("FluTheme",FluTheme::getInstance());
|
||||
engine->rootContext()->setContextProperty("FluTools",FluTools::getInstance());
|
||||
engine->rootContext()->setContextProperty("FluTextStyle",FluTextStyle::getInstance());
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
id: control
|
||||
property color tintColor: Qt.rgba(1, 1, 1, 1)
|
||||
property real tintOpacity: 0.65
|
||||
property real luminosity: 0.01
|
||||
property real noiseOpacity: 0.02
|
||||
property alias target: effect_source.sourceItem
|
||||
property int blurRadius: 32
|
||||
property rect targetRect: Qt.rect(control.x, control.y, control.width,
|
||||
control.height)
|
||||
ShaderEffectSource {
|
||||
id: effect_source
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
sourceRect: control.targetRect
|
||||
}
|
||||
FastBlur {
|
||||
id: fast_blur
|
||||
anchors.fill: parent
|
||||
source: effect_source
|
||||
radius: control.blurRadius
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(1, 1, 1, luminosity)
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(tintColor.r, tintColor.g, tintColor.b, tintOpacity)
|
||||
}
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: "../Image/noise.png"
|
||||
fillMode: Image.Tile
|
||||
opacity: control.noiseOpacity
|
||||
}
|
||||
}
|
@ -1,347 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Rectangle{
|
||||
property string title: ""
|
||||
property string darkText : qsTr("Dark")
|
||||
property string lightText : qsTr("Light")
|
||||
property string minimizeText : qsTr("Minimize")
|
||||
property string restoreText : qsTr("Restore")
|
||||
property string maximizeText : qsTr("Maximize")
|
||||
property string closeText : qsTr("Close")
|
||||
property string stayTopText : qsTr("Sticky on Top")
|
||||
property string stayTopCancelText : qsTr("Sticky on Top cancelled")
|
||||
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
|
||||
property color minimizeNormalColor: FluTheme.itemNormalColor
|
||||
property color minimizeHoverColor: FluTheme.itemHoverColor
|
||||
property color minimizePressColor: FluTheme.itemPressColor
|
||||
property color maximizeNormalColor: FluTheme.itemNormalColor
|
||||
property color maximizeHoverColor: FluTheme.itemHoverColor
|
||||
property color maximizePressColor: FluTheme.itemPressColor
|
||||
property color closeNormalColor: Qt.rgba(0,0,0,0)
|
||||
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
|
||||
property color closePressColor: Qt.rgba(251/255,115/255,115/255,0.8)
|
||||
property bool showDark: false
|
||||
property bool showClose: true
|
||||
property bool showMinimize: true
|
||||
property bool showMaximize: true
|
||||
property bool showStayTop: true
|
||||
property bool titleVisible: true
|
||||
property url icon
|
||||
property int iconSize: 20
|
||||
property bool isMac: FluTools.isMacos()
|
||||
property color borerlessColor : FluTheme.primaryColor
|
||||
property bool systemMoveEnable: true
|
||||
property var maxClickListener : function(){
|
||||
if(FluTools.isMacos()){
|
||||
if (d.win.visibility === Window.FullScreen)
|
||||
d.win.showNormal()
|
||||
else
|
||||
d.win.showFullScreen()
|
||||
}else{
|
||||
if (d.win.visibility === Window.Maximized)
|
||||
d.win.showNormal()
|
||||
else
|
||||
d.win.showMaximized()
|
||||
d.hoverMaxBtn = false
|
||||
}
|
||||
}
|
||||
property var minClickListener: function(){
|
||||
if(d.win.transientParent != null){
|
||||
d.win.transientParent.showMinimized()
|
||||
}else{
|
||||
d.win.showMinimized()
|
||||
}
|
||||
}
|
||||
property var closeClickListener : function(){
|
||||
d.win.close()
|
||||
}
|
||||
property var stayTopClickListener: function(){
|
||||
if(d.win instanceof FluWindow){
|
||||
d.win.stayTop = !d.win.stayTop
|
||||
}
|
||||
}
|
||||
property var darkClickListener: function(){
|
||||
if(FluTheme.dark){
|
||||
FluTheme.darkMode = FluThemeType.Light
|
||||
}else{
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
property var systemMenuListener: function(){
|
||||
if(d.win instanceof FluWindow){
|
||||
d.win.showSystemMenu()
|
||||
}
|
||||
}
|
||||
property alias buttonStayTop: btn_stay_top
|
||||
property alias buttonMinimize: btn_minimize
|
||||
property alias buttonMaximize: btn_maximize
|
||||
property alias buttonClose: btn_close
|
||||
property alias buttonDark: btn_dark
|
||||
id:control
|
||||
color: Qt.rgba(0,0,0,0)
|
||||
height: visible ? 30 : 0
|
||||
opacity: visible
|
||||
z: 65535
|
||||
Item{
|
||||
id:d
|
||||
property var hitTestList: []
|
||||
property bool hoverMaxBtn: false
|
||||
property var win: Window.window
|
||||
property bool stayTop: {
|
||||
if(d.win instanceof FluWindow){
|
||||
return d.win.stayTop
|
||||
}
|
||||
return false
|
||||
}
|
||||
property bool isRestore: win && Window.Maximized === win.visibility
|
||||
property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
|
||||
function containsPointToItem(point,item){
|
||||
var pos = item.mapToGlobal(0,0)
|
||||
var rect = Qt.rect(pos.x,pos.y,item.width,item.height)
|
||||
if(point.x>rect.x && point.x<(rect.x+rect.width) && point.y>rect.y && point.y<(rect.y+rect.height)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_app_bar
|
||||
anchors.fill: parent
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable){
|
||||
d.win.startSystemMove()
|
||||
}
|
||||
}
|
||||
onDoubleClicked:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable && d.resizable && Qt.LeftButton){
|
||||
btn_maximize.clicked()
|
||||
}
|
||||
}
|
||||
acceptedButtons: Qt.LeftButton|Qt.RightButton
|
||||
onClicked:
|
||||
(mouse)=>{
|
||||
if (systemMoveEnable && mouse.button === Qt.RightButton){
|
||||
control.systemMenuListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: isMac ? undefined : parent.left
|
||||
leftMargin: isMac ? undefined : 10
|
||||
horizontalCenter: isMac ? parent.horizontalCenter : undefined
|
||||
}
|
||||
spacing: 10
|
||||
Image{
|
||||
width: control.iconSize
|
||||
height: control.iconSize
|
||||
visible: status === Image.Ready ? true : false
|
||||
source: control.icon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
FluText {
|
||||
text: title
|
||||
visible: control.titleVisible
|
||||
color:control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_mac_buttons
|
||||
RowLayout{
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
Layout.preferredWidth: 12
|
||||
normalImage: "../Image/btn_close_normal.png"
|
||||
hoveredImage: "../Image/btn_close_hovered.png"
|
||||
pushedImage: "../Image/btn_close_pushed.png"
|
||||
visible: showClose
|
||||
onClicked: closeClickListener()
|
||||
}
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
Layout.preferredWidth: 12
|
||||
normalImage: "../Image/btn_min_normal.png"
|
||||
hoveredImage: "../Image/btn_min_hovered.png"
|
||||
pushedImage: "../Image/btn_min_pushed.png"
|
||||
onClicked: minClickListener()
|
||||
visible: showMinimize
|
||||
}
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
Layout.preferredWidth: 12
|
||||
normalImage: "../Image/btn_max_normal.png"
|
||||
hoveredImage: "../Image/btn_max_hovered.png"
|
||||
pushedImage: "../Image/btn_max_pushed.png"
|
||||
onClicked: maxClickListener()
|
||||
visible: d.resizable && showMaximize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
sourceComponent: isMac ? com_mac_buttons : undefined
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
id:layout_row
|
||||
anchors.right: parent.right
|
||||
height: control.height
|
||||
spacing: 0
|
||||
Component.onCompleted: {
|
||||
setHitTestVisible(layout_row)
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_dark
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
rightPadding: 2
|
||||
iconSource: FluTheme.dark ? FluentIcons.Brightness : FluentIcons.QuietHours
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 15
|
||||
visible: showDark
|
||||
text: FluTheme.dark ? control.lightText : control.darkText
|
||||
radius: 0
|
||||
iconColor:control.textColor
|
||||
onClicked:()=> darkClickListener(btn_dark)
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_stay_top
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : FluentIcons.Pinned
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 14
|
||||
visible: {
|
||||
if(!(d.win instanceof FluWindow)){
|
||||
return false
|
||||
}
|
||||
return showStayTop
|
||||
}
|
||||
text:d.stayTop ? control.stayTopCancelText : control.stayTopText
|
||||
radius: 0
|
||||
iconColor: d.stayTop ? FluTheme.primaryColor : control.textColor
|
||||
onClicked: stayTopClickListener()
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_minimize
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : FluentIcons.ChromeMinimize
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 11
|
||||
text:minimizeText
|
||||
radius: 0
|
||||
visible: !isMac && showMinimize
|
||||
iconColor: control.textColor
|
||||
color: {
|
||||
if(pressed){
|
||||
return minimizePressColor
|
||||
}
|
||||
return hovered ? minimizeHoverColor : minimizeNormalColor
|
||||
}
|
||||
onClicked: minClickListener()
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_maximize
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
|
||||
color: {
|
||||
if(down){
|
||||
return maximizePressColor
|
||||
}
|
||||
if(FluTools.isWindows11OrGreater()){
|
||||
return d.hoverMaxBtn ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
return hovered ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: d.resizable && !isMac && showMaximize
|
||||
radius: 0
|
||||
iconColor: control.textColor
|
||||
text:d.isRestore?restoreText:maximizeText
|
||||
iconSize: 11
|
||||
onClicked: maxClickListener()
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_close
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : FluentIcons.ChromeClose
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text:closeText
|
||||
visible: !isMac && showClose
|
||||
radius: 0
|
||||
iconSize: 10
|
||||
iconColor: hovered ? Qt.rgba(1,1,1,1) : control.textColor
|
||||
color:{
|
||||
if(pressed){
|
||||
return closePressColor
|
||||
}
|
||||
return hovered ? closeHoverColor : closeNormalColor
|
||||
}
|
||||
onClicked: closeClickListener()
|
||||
}
|
||||
}
|
||||
function _maximizeButtonHover(){
|
||||
var hover = false
|
||||
if(btn_maximize.visible && FluTools.isWindows11OrGreater() && d.resizable){
|
||||
if(d.containsPointToItem(FluTools.cursorPos(),btn_maximize)){
|
||||
hover = true
|
||||
}else{
|
||||
if(btn_maximize.down){
|
||||
btn_maximize.down = false
|
||||
}
|
||||
}
|
||||
}
|
||||
d.hoverMaxBtn = hover
|
||||
return hover;
|
||||
}
|
||||
function _appBarHover(){
|
||||
var cursorPos = FluTools.cursorPos()
|
||||
for(var i =0 ;i< d.hitTestList.length; i++){
|
||||
var item = d.hitTestList[i]
|
||||
if(item.visible){
|
||||
if(d.containsPointToItem(cursorPos,item)){
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d.containsPointToItem(cursorPos,control)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
function setHitTestVisible(id){
|
||||
d.hitTestList.push(id)
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
default property alias contentData : layout_content.data
|
||||
property int paddings : 0
|
||||
property int leftPadding : 0
|
||||
property int rightPadding : 0
|
||||
property int topPadding : 0
|
||||
property int bottomPadding : 0
|
||||
id:control
|
||||
radius: 4
|
||||
color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
implicitHeight: height
|
||||
implicitWidth: width
|
||||
Item {
|
||||
id: layout_content
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Math.max(paddings,leftPadding)
|
||||
anchors.rightMargin: Math.max(paddings,rightPadding)
|
||||
anchors.topMargin: Math.max(paddings,topPadding)
|
||||
anchors.bottomMargin: Math.max(paddings,bottomPadding)
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluTextBox{
|
||||
property var items:[]
|
||||
property string emptyText: qsTr("No results found")
|
||||
property int autoSuggestBoxReplacement: FluentIcons.Search
|
||||
property var filter: function(item){
|
||||
if(item.title.indexOf(control.text)!==-1){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
signal itemClicked(var data)
|
||||
id:control
|
||||
Component.onCompleted: {
|
||||
d.loadData()
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property bool flagVisible: true
|
||||
property var window : Window.window
|
||||
function handleClick(modelData){
|
||||
control_popup.visible = false
|
||||
control.itemClicked(modelData)
|
||||
d.updateText(modelData.title)
|
||||
}
|
||||
function updateText(text){
|
||||
d.flagVisible = false
|
||||
control.text = text
|
||||
d.flagVisible = true
|
||||
}
|
||||
function loadData(){
|
||||
var result = []
|
||||
if(items==null){
|
||||
list_view.model = result
|
||||
return
|
||||
}
|
||||
items.map(function(item){
|
||||
if(control.filter(item)){
|
||||
result.push(item)
|
||||
}
|
||||
})
|
||||
list_view.model = result
|
||||
}
|
||||
}
|
||||
onActiveFocusChanged: {
|
||||
if(!activeFocus){
|
||||
control_popup.visible = false
|
||||
}
|
||||
}
|
||||
Popup{
|
||||
id:control_popup
|
||||
y:control.height
|
||||
focus: false
|
||||
padding: 0
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
contentItem: FluRectangle{
|
||||
radius: [4,4,4,4]
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
header: Item{
|
||||
width: control.width
|
||||
height: visible ? 38 : 0
|
||||
visible: list_view.count === 0
|
||||
FluText{
|
||||
text:emptyText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate:FluControl{
|
||||
id:item_control
|
||||
height: 38
|
||||
width: control.width
|
||||
onClicked:{
|
||||
d.handleClick(modelData)
|
||||
}
|
||||
background: Rectangle{
|
||||
FluFocusRectangle{
|
||||
visible: item_control.activeFocus
|
||||
radius:4
|
||||
}
|
||||
color: {
|
||||
if(hovered){
|
||||
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
contentItem: FluText{
|
||||
text:modelData.title
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
verticalAlignment : Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Item{
|
||||
id:container
|
||||
implicitWidth: control.width
|
||||
implicitHeight: 38*Math.min(Math.max(list_view.count,1),8)
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
d.loadData()
|
||||
if(d.flagVisible){
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.implicitHeight){
|
||||
control_popup.y = control.height
|
||||
} else if(pos.y>container.implicitHeight){
|
||||
control_popup.y = -container.implicitHeight
|
||||
} else {
|
||||
control_popup.y = d.window.height-(pos.y+container.implicitHeight)
|
||||
}
|
||||
control_popup.visible = true
|
||||
}
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Rectangle{
|
||||
property bool isDot: false
|
||||
property bool showZero: false
|
||||
property int count: 0
|
||||
property bool topRight: false
|
||||
id:control
|
||||
color:Qt.rgba(255/255,77/255,79/255,1)
|
||||
width: {
|
||||
if(isDot)
|
||||
return 10
|
||||
if(count<10){
|
||||
return 20
|
||||
}else if(count<100){
|
||||
return 30
|
||||
}
|
||||
return 40
|
||||
}
|
||||
height: {
|
||||
if(isDot)
|
||||
return 10
|
||||
return 20
|
||||
}
|
||||
radius: {
|
||||
if(isDot)
|
||||
return 5
|
||||
return 10
|
||||
}
|
||||
border.width: 1
|
||||
border.color: Qt.rgba(1,1,1,1)
|
||||
anchors{
|
||||
right: {
|
||||
if(parent && topRight)
|
||||
return parent.right
|
||||
return undefined
|
||||
}
|
||||
top: {
|
||||
if(parent && topRight)
|
||||
return parent.top
|
||||
return undefined
|
||||
}
|
||||
rightMargin: {
|
||||
if(parent && topRight){
|
||||
if(isDot){
|
||||
return -2.5
|
||||
}
|
||||
return -(control.width/2)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
topMargin: {
|
||||
if(parent && topRight){
|
||||
if(isDot){
|
||||
return -2.5
|
||||
}
|
||||
return -10
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
visible: {
|
||||
if(showZero)
|
||||
return true
|
||||
return count!==0
|
||||
}
|
||||
FluText{
|
||||
anchors.centerIn: parent
|
||||
color: Qt.rgba(1,1,1,1)
|
||||
visible: !isDot
|
||||
text:{
|
||||
if(count<100)
|
||||
return count
|
||||
return count+"+"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int textSize: 15
|
||||
property string separator: "/"
|
||||
property var items: []
|
||||
property int spacing: 5
|
||||
signal clickItem(var model)
|
||||
id:control
|
||||
implicitWidth: 300
|
||||
height: 30
|
||||
onItemsChanged: {
|
||||
list_model.clear()
|
||||
list_model.append(items)
|
||||
}
|
||||
ListModel{
|
||||
id:list_model
|
||||
}
|
||||
ListView{
|
||||
id:list_view
|
||||
width: parent.width
|
||||
height: 30
|
||||
orientation: ListView.Horizontal
|
||||
model: list_model
|
||||
clip: true
|
||||
spacing : control.spacing
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
remove: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: FluTheme.enableAnimation ? 83 : 1
|
||||
}
|
||||
}
|
||||
add: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: FluTheme.enableAnimation ? 83 : 1
|
||||
}
|
||||
}
|
||||
delegate: Item{
|
||||
height: item_layout.height
|
||||
width: item_layout.width
|
||||
RowLayout{
|
||||
id:item_layout
|
||||
spacing: list_view.spacing
|
||||
height: list_view.height
|
||||
|
||||
FluText{
|
||||
text:model.title
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: {
|
||||
if(item_mouse.pressed){
|
||||
return FluTheme.dark ? Qt.rgba(150/255,150/255,150/235,1) : Qt.rgba(134/255,134/255,134/235,1)
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return FluTheme.dark ? Qt.rgba(204/255,204/255,204/235,1) : Qt.rgba(92/255,92/255,92/235,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/235,1) : Qt.rgba(26/255,26/255,26/235,1)
|
||||
}
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
control.clickItem(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:control.separator
|
||||
font.pixelSize: control.textSize
|
||||
visible: list_view.count-1 !== index
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function remove(index,count){
|
||||
list_model.remove(index,count)
|
||||
}
|
||||
function count(){
|
||||
return list_model.count
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
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(246/255,246/255,246/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id: control
|
||||
enabled: !disabled
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
font:FluTextStyle.Body
|
||||
focusPolicy:Qt.TabFocus
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
radius: 4
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:4
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
}
|
||||
}
|
@ -1,661 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property string text: qsTr("Pick a date")
|
||||
property date from: new Date(1924, 0, 1)
|
||||
property date to: new Date(2124, 11, 31)
|
||||
property var current
|
||||
signal accepted()
|
||||
id:control
|
||||
color: {
|
||||
if(mouse_area.containsMouse){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
height: 30
|
||||
width: 120
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: dividerColor
|
||||
MouseArea{
|
||||
id:mouse_area
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
popup.showPopup()
|
||||
}
|
||||
}
|
||||
CalendarModel {
|
||||
id:calender_model
|
||||
from: control.from
|
||||
to: control.to
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property var window : Window.window
|
||||
property date displayDate: {
|
||||
if(control.current){
|
||||
return control.current
|
||||
}
|
||||
return new Date()
|
||||
}
|
||||
property date toDay : new Date()
|
||||
property int pageIndex: 0
|
||||
signal nextButton
|
||||
signal previousButton
|
||||
property point yearRing : Qt.point(0,0)
|
||||
}
|
||||
FluText{
|
||||
id:text_date
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
rightMargin: 30
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:{
|
||||
if(control.current){
|
||||
return control.current.toLocaleDateString(FluApp.locale,"yyyy/M/d")
|
||||
}
|
||||
return control.text
|
||||
}
|
||||
}
|
||||
FluIcon{
|
||||
iconSource: FluentIcons.Calendar
|
||||
iconSize: 14
|
||||
iconColor: text_date.color
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 12
|
||||
}
|
||||
}
|
||||
Menu{
|
||||
id:popup
|
||||
height: container.height
|
||||
width: container.width
|
||||
modal: true
|
||||
Overlay.modal: Item {}
|
||||
enter: Transition {
|
||||
reversible: true
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
clip: true
|
||||
FluArea{
|
||||
id:container
|
||||
width: 300
|
||||
height: 360
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.leftMargin: parent.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluTextButton{
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
contentItem: FluText {
|
||||
text: d.displayDate.toLocaleString(FluApp.locale, "MMMM yyyy")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
visible: d.pageIndex === 0
|
||||
onClicked: {
|
||||
d.pageIndex = 1
|
||||
}
|
||||
}
|
||||
FluTextButton{
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
contentItem: FluText {
|
||||
text: d.displayDate.toLocaleString(FluApp.locale, "yyyy")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
visible: d.pageIndex === 1
|
||||
onClicked: {
|
||||
d.pageIndex = 2
|
||||
}
|
||||
}
|
||||
FluTextButton{
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
contentItem: FluText {
|
||||
text: "%1-%2".arg(d.yearRing.x).arg(d.yearRing.y)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
textColor: FluTheme.fontTertiaryColor
|
||||
}
|
||||
visible: d.pageIndex === 2
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:icon_up
|
||||
iconSource: FluentIcons.CaretUpSolid8
|
||||
iconSize: 10
|
||||
onClicked: {
|
||||
d.previousButton()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:icon_down
|
||||
iconSource: FluentIcons.CaretDownSolid8
|
||||
iconSize: 10
|
||||
Layout.rightMargin: parent.spacing
|
||||
onClicked: {
|
||||
d.nextButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluDivider{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
StackView{
|
||||
id:stack_view
|
||||
anchors.fill: parent
|
||||
initialItem: com_page_one
|
||||
replaceEnter : Transition{
|
||||
OpacityAnimator{
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 88
|
||||
}
|
||||
ScaleAnimator{
|
||||
from: 0.5
|
||||
to: 1
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
replaceExit : Transition{
|
||||
OpacityAnimator{
|
||||
from: 1
|
||||
to: 0
|
||||
duration: 88
|
||||
}
|
||||
ScaleAnimator{
|
||||
from: 1.0
|
||||
to: 0.5
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onPageIndexChanged(){
|
||||
if(d.pageIndex === 0){
|
||||
stack_view.replace(com_page_one)
|
||||
}
|
||||
if(d.pageIndex === 1){
|
||||
stack_view.replace(com_page_two)
|
||||
}
|
||||
if(d.pageIndex === 2){
|
||||
stack_view.replace(com_page_three)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_page_three
|
||||
GridView{
|
||||
id:grid_view
|
||||
cellHeight: 75
|
||||
cellWidth: 75
|
||||
clip: true
|
||||
boundsBehavior: GridView.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model: {
|
||||
var fromYear = calender_model.from.getFullYear()
|
||||
var toYear = calender_model.to.getFullYear()
|
||||
return toYear-fromYear+1
|
||||
}
|
||||
highlightRangeMode: GridView.StrictlyEnforceRange
|
||||
onCurrentIndexChanged:{
|
||||
var year = currentIndex + calender_model.from.getFullYear()
|
||||
var start = Math.ceil(year / 10) * 10
|
||||
var end = start+10
|
||||
d.yearRing = Qt.point(start,end)
|
||||
}
|
||||
highlightMoveDuration: 100
|
||||
Component.onCompleted: {
|
||||
grid_view.highlightMoveDuration = 0
|
||||
currentIndex = d.displayDate.getFullYear()-calender_model.from.getFullYear()
|
||||
timer_delay.restart()
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onNextButton(){
|
||||
grid_view.currentIndex = Math.min(grid_view.currentIndex+16,grid_view.count-1)
|
||||
}
|
||||
function onPreviousButton(){
|
||||
grid_view.currentIndex = Math.max(grid_view.currentIndex-16,0)
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 100
|
||||
onTriggered: {
|
||||
grid_view.highlightMoveDuration = 100
|
||||
}
|
||||
}
|
||||
currentIndex: -1
|
||||
delegate: Item{
|
||||
property int year : calender_model.from.getFullYear()+modelData
|
||||
property bool toYear: year === d.toDay.getFullYear()
|
||||
implicitHeight: 75
|
||||
implicitWidth: 75
|
||||
FluControl{
|
||||
id:control_delegate
|
||||
width: 60
|
||||
height: 60
|
||||
anchors.centerIn: parent
|
||||
Rectangle{
|
||||
width: 48
|
||||
height: 48
|
||||
radius: width/2
|
||||
color: {
|
||||
if(toYear){
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2)
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1)
|
||||
}
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluColors.Transparent
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
FluText{
|
||||
text: year
|
||||
anchors.centerIn: parent
|
||||
opacity: {
|
||||
if(year >= d.yearRing.x && year <= d.yearRing.y){
|
||||
return 1
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return 1
|
||||
}
|
||||
return 0.3
|
||||
}
|
||||
color: {
|
||||
if(toYear){
|
||||
return FluColors.White
|
||||
}
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
d.displayDate = new Date(year,0,1)
|
||||
d.pageIndex = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_page_two
|
||||
|
||||
ListView{
|
||||
id:listview
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
spacing: 0
|
||||
highlightMoveDuration: 100
|
||||
model: {
|
||||
var fromYear = calender_model.from.getFullYear()
|
||||
var toYear = calender_model.to.getFullYear()
|
||||
var yearsArray = []
|
||||
for (var i = fromYear; i <= toYear; i++) {
|
||||
yearsArray.push(i)
|
||||
}
|
||||
return yearsArray
|
||||
}
|
||||
currentIndex: -1
|
||||
onCurrentIndexChanged:{
|
||||
var year = model[currentIndex]
|
||||
var month = d.displayDate.getMonth()
|
||||
d.displayDate = new Date(year,month,1)
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onNextButton(){
|
||||
listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1)
|
||||
}
|
||||
function onPreviousButton(){
|
||||
listview.currentIndex = Math.max(listview.currentIndex-1,0)
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
listview.highlightMoveDuration = 0
|
||||
currentIndex = model.indexOf(d.displayDate.getFullYear())
|
||||
timer_delay.restart()
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 100
|
||||
onTriggered: {
|
||||
listview.highlightMoveDuration = 100
|
||||
}
|
||||
}
|
||||
delegate: Item{
|
||||
id:layout_congrol
|
||||
property int year : modelData
|
||||
width: listview.width
|
||||
height: 75*3
|
||||
GridView{
|
||||
anchors.fill: parent
|
||||
cellHeight: 75
|
||||
cellWidth: 75
|
||||
clip: true
|
||||
interactive: false
|
||||
boundsBehavior: GridView.StopAtBounds
|
||||
model: 12
|
||||
delegate: Item{
|
||||
property int month : modelData
|
||||
property bool toMonth: layout_congrol.year === d.toDay.getFullYear() && month === d.toDay.getMonth()
|
||||
implicitHeight: 75
|
||||
implicitWidth: 75
|
||||
FluControl{
|
||||
id:control_delegate
|
||||
width: 60
|
||||
height: 60
|
||||
anchors.centerIn: parent
|
||||
Rectangle{
|
||||
width: 48
|
||||
height: 48
|
||||
radius: width/2
|
||||
color: {
|
||||
if(toMonth){
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2)
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1)
|
||||
}
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluColors.Transparent
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
FluText{
|
||||
text: new Date(layout_congrol.year,month).toLocaleString(FluApp.locale, "MMMM")
|
||||
anchors.centerIn: parent
|
||||
opacity: {
|
||||
if(layout_congrol.year === d.displayDate.getFullYear()){
|
||||
return 1
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return 1
|
||||
}
|
||||
return 0.3
|
||||
}
|
||||
color: {
|
||||
if(toMonth){
|
||||
return FluColors.White
|
||||
}
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
d.displayDate = new Date(layout_congrol.year,month)
|
||||
d.pageIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_page_one
|
||||
ColumnLayout {
|
||||
DayOfWeekRow {
|
||||
id: dayOfWeekRow
|
||||
locale: FluApp.locale
|
||||
font.bold: false
|
||||
delegate: Label {
|
||||
text: model.shortName
|
||||
font: dayOfWeekRow.font
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Layout.column: 1
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
ListView{
|
||||
id:listview
|
||||
property bool isCompleted: false
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
spacing: 0
|
||||
highlightMoveDuration: 100
|
||||
currentIndex: -1
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
onCurrentIndexChanged:{
|
||||
if(isCompleted){
|
||||
var month = calender_model.monthAt(currentIndex)
|
||||
var year = calender_model.yearAt(currentIndex)
|
||||
d.displayDate = new Date(year,month,1)
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
listview.model = calender_model
|
||||
listview.highlightMoveDuration = 0
|
||||
currentIndex = calender_model.indexOf(d.displayDate)
|
||||
timer_delay.restart()
|
||||
isCompleted = true
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 100
|
||||
onTriggered: {
|
||||
listview.highlightMoveDuration = 100
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onNextButton(){
|
||||
listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1)
|
||||
}
|
||||
function onPreviousButton(){
|
||||
listview.currentIndex = Math.max(listview.currentIndex-1,0)
|
||||
}
|
||||
}
|
||||
delegate: MonthGrid {
|
||||
id: grid
|
||||
width: listview.width
|
||||
height: listview.height
|
||||
month: model.month
|
||||
year: model.year
|
||||
spacing: 0
|
||||
locale: FluApp.locale
|
||||
delegate: FluControl {
|
||||
required property bool today
|
||||
required property int year
|
||||
required property int month
|
||||
required property int day
|
||||
required property int visibleMonth
|
||||
id: control_delegate
|
||||
visibleMonth: grid.month
|
||||
implicitHeight: 40
|
||||
implicitWidth: 40
|
||||
Rectangle{
|
||||
width: 34
|
||||
height: 34
|
||||
radius: width/2
|
||||
color: {
|
||||
if(today){
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2)
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1)
|
||||
}
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluColors.Transparent
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Rectangle{
|
||||
width: 40
|
||||
height: 40
|
||||
border.width: 1
|
||||
anchors.centerIn: parent
|
||||
radius: width/2
|
||||
border.color: FluTheme.primaryColor
|
||||
color: FluColors.Transparent
|
||||
visible: {
|
||||
if(control.current){
|
||||
var y = control.current.getFullYear()
|
||||
var m = control.current.getMonth()
|
||||
var d = control.current.getDate()
|
||||
if(y === year && m === month && d === day){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: day
|
||||
opacity: {
|
||||
if(month === grid.month){
|
||||
return 1
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return 1
|
||||
}
|
||||
return 0.3
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
color: {
|
||||
if(today){
|
||||
return FluColors.White
|
||||
}
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
control.current = new Date(year,month,day)
|
||||
control.accepted()
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
x: grid.leftPadding
|
||||
y: grid.topPadding
|
||||
width: grid.availableWidth
|
||||
height: grid.availableHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Item{
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
function showPopup() {
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.height){
|
||||
popup.y = control.height
|
||||
} else if(pos.y>container.height){
|
||||
popup.y = -container.height
|
||||
} else {
|
||||
popup.y = d.window.height-(pos.y+container.height)
|
||||
}
|
||||
popup.x = -(popup.width-control.width)/2
|
||||
popup.open()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,206 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property bool autoPlay: true
|
||||
property int loopTime: 2000
|
||||
property var model
|
||||
property Component delegate
|
||||
property bool showIndicator: true
|
||||
property int indicatorGravity : Qt.AlignBottom | Qt.AlignHCenter
|
||||
property int indicatorMarginLeft: 0
|
||||
property int indicatorMarginRight: 0
|
||||
property int indicatorMarginTop: 0
|
||||
property int indicatorMarginBottom: 20
|
||||
property int indicatorSpacing: 10
|
||||
property alias indicatorAnchors: layout_indicator.anchors
|
||||
property Component indicatorDelegate : com_indicator
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
ListModel{
|
||||
id:content_model
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flagXChanged: true
|
||||
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
||||
function setData(data){
|
||||
if(!data){
|
||||
return
|
||||
}
|
||||
content_model.clear()
|
||||
content_model.append(data[data.length-1])
|
||||
content_model.append(data)
|
||||
content_model.append(data[0])
|
||||
list_view.highlightMoveDuration = 0
|
||||
list_view.currentIndex = 1
|
||||
list_view.highlightMoveDuration = 250
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
snapMode: ListView.SnapOneItem
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
model:content_model
|
||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
Component.onCompleted: {
|
||||
d.setData(control.model)
|
||||
}
|
||||
interactive: list_view.count>3
|
||||
Connections{
|
||||
target: control
|
||||
function onModelChanged(){
|
||||
d.setData(control.model)
|
||||
}
|
||||
}
|
||||
orientation : ListView.Horizontal
|
||||
delegate: Item{
|
||||
id:item_control
|
||||
width: ListView.view.width
|
||||
height: ListView.view.height
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return content_model.count-3
|
||||
if(index === content_model.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
FluLoader{
|
||||
property int displayIndex : item_control.displayIndex
|
||||
property var model: list_view.model.get(index)
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(model){
|
||||
return control.delegate
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
onMovementEnded:{
|
||||
currentIndex = list_view.contentX/list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count-2
|
||||
}else if(currentIndex === list_view.count-1){
|
||||
currentIndex = 1
|
||||
}
|
||||
d.flagXChanged = false
|
||||
timer_run.restart()
|
||||
}
|
||||
onMovementStarted: {
|
||||
d.flagXChanged = true
|
||||
timer_run.stop()
|
||||
}
|
||||
onContentXChanged: {
|
||||
if(d.flagXChanged){
|
||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
||||
var minY = Math.max(0,(list_view.width*(currentIndex-1)))
|
||||
if(contentX>=maxX){
|
||||
contentX = maxX
|
||||
}
|
||||
if(contentX<=minY){
|
||||
contentX = minY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_indicator
|
||||
Rectangle{
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 4
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
scale: checked ? 1.2 : 1
|
||||
color: checked ? FluTheme.primaryColor : Qt.rgba(1,1,1,0.7)
|
||||
border.width: mouse_item.containsMouse ? 1 : 0
|
||||
border.color: FluTheme.primaryColor
|
||||
MouseArea{
|
||||
id:mouse_item
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
changedIndex(realIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
anchors{
|
||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||
bottom: (indicatorGravity & Qt.AlignBottom) ? parent.bottom : undefined
|
||||
top: (indicatorGravity & Qt.AlignTop) ? parent.top : undefined
|
||||
left: (indicatorGravity & Qt.AlignLeft) ? parent.left : undefined
|
||||
right: (indicatorGravity & Qt.AlignRight) ? parent.right : undefined
|
||||
bottomMargin: control.indicatorMarginBottom
|
||||
leftMargin: control.indicatorMarginBottom
|
||||
rightMargin: control.indicatorMarginBottom
|
||||
topMargin: control.indicatorMarginBottom
|
||||
}
|
||||
visible: showIndicator
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_anim
|
||||
interval: 250
|
||||
onTriggered: {
|
||||
list_view.highlightMoveDuration = 0
|
||||
if(list_view.currentIndex === list_view.count-1){
|
||||
list_view.currentIndex = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_run
|
||||
interval: control.loopTime
|
||||
repeat: d.isAnimEnable
|
||||
onTriggered: {
|
||||
list_view.highlightMoveDuration = 250
|
||||
list_view.currentIndex = list_view.currentIndex+1
|
||||
timer_anim.start()
|
||||
}
|
||||
}
|
||||
function changedIndex(index){
|
||||
d.flagXChanged = true
|
||||
timer_run.stop()
|
||||
list_view.currentIndex = index
|
||||
d.flagXChanged = false
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
import QtQuick
|
||||
import "./../JS/Chart.js" as Chart
|
||||
|
||||
Canvas {
|
||||
id: control
|
||||
property string chartType
|
||||
property var chartData
|
||||
property var chartOptions
|
||||
property double chartAnimationProgress: 0.1
|
||||
property int animationEasingType: Easing.InOutExpo
|
||||
property double animationDuration: 300
|
||||
property alias animationRunning: chartAnimator.running
|
||||
signal animationFinished()
|
||||
function animateToNewData()
|
||||
{
|
||||
chartAnimationProgress = 0.1;
|
||||
d.jsChart.update();
|
||||
chartAnimator.restart();
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property var jsChart: undefined
|
||||
property var memorizedContext
|
||||
property var memorizedData
|
||||
property var memorizedOptions
|
||||
}
|
||||
MouseArea {
|
||||
id: event
|
||||
anchors.fill: control
|
||||
hoverEnabled: true
|
||||
enabled: true
|
||||
property var handler: undefined
|
||||
property QtObject mouseEvent: QtObject {
|
||||
property int left: 0
|
||||
property int top: 0
|
||||
property int x: 0
|
||||
property int y: 0
|
||||
property int clientX: 0
|
||||
property int clientY: 0
|
||||
property string type: ""
|
||||
property var target
|
||||
}
|
||||
function submitEvent(mouse, type) {
|
||||
mouseEvent.type = type
|
||||
mouseEvent.clientX = mouse ? mouse.x : 0;
|
||||
mouseEvent.clientY = mouse ? mouse.y : 0;
|
||||
mouseEvent.x = mouse ? mouse.x : 0;
|
||||
mouseEvent.y = mouse ? mouse.y : 0;
|
||||
mouseEvent.left = 0;
|
||||
mouseEvent.top = 0;
|
||||
mouseEvent.target = control;
|
||||
if(handler) {
|
||||
handler(mouseEvent);
|
||||
}
|
||||
control.requestPaint();
|
||||
}
|
||||
onClicked:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "click");
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "mousemove");
|
||||
}
|
||||
onExited: {
|
||||
submitEvent(undefined, "mouseout");
|
||||
}
|
||||
onEntered: {
|
||||
submitEvent(undefined, "mouseenter");
|
||||
}
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "mousedown");
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "mouseup");
|
||||
}
|
||||
}
|
||||
PropertyAnimation {
|
||||
id: chartAnimator
|
||||
target: control
|
||||
property: "chartAnimationProgress"
|
||||
alwaysRunToEnd: true
|
||||
to: 1
|
||||
duration: control.animationDuration
|
||||
easing.type: control.animationEasingType
|
||||
onFinished: {
|
||||
control.animationFinished();
|
||||
}
|
||||
}
|
||||
onChartAnimationProgressChanged: {
|
||||
control.requestPaint();
|
||||
}
|
||||
onPaint: {
|
||||
if(control.getContext('2d') !== null && d.memorizedContext !== control.getContext('2d') || d.memorizedData !== control.chartData || d.memorizedOptions !== control.chartOptions) {
|
||||
var ctx = control.getContext('2d');
|
||||
d.jsChart = Chart.build(ctx, {type: control.chartType,data: control.chartData,options: control.chartOptions});
|
||||
d.memorizedData = control.chartData ;
|
||||
d.memorizedContext = control.getContext('2d');
|
||||
d.memorizedOptions = control.chartOptions;
|
||||
d.jsChart.bindEvents(function(newHandler) {event.handler = newHandler;});
|
||||
chartAnimator.start();
|
||||
}
|
||||
d.jsChart.draw(chartAnimationProgress);
|
||||
}
|
||||
onWidthChanged: {
|
||||
if(d.jsChart) {
|
||||
d.jsChart.resize();
|
||||
}
|
||||
}
|
||||
onHeightChanged: {
|
||||
if(d.jsChart) {
|
||||
d.jsChart.resize();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color borderNormalColor: FluTheme.dark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1)
|
||||
property color bordercheckedColor: FluTheme.primaryColor
|
||||
property color borderHoverColor: FluTheme.dark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1)
|
||||
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color borderPressedColor: FluTheme.dark ? Qt.rgba(90/255,90/255,90/255,1) : Qt.rgba(191/255,191/255,191/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1)
|
||||
property color checkedColor: FluTheme.primaryColor
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(72/255,72/255,72/255,1) : Qt.rgba(236/255,236/255,236/255,1)
|
||||
property color checkedHoverColor: FluTheme.dark ? Qt.darker(checkedColor,1.15) : Qt.lighter(checkedColor,1.15)
|
||||
property color checkedPreesedColor: FluTheme.dark ? Qt.darker(checkedColor,1.3) : Qt.lighter(checkedColor,1.3)
|
||||
property color checkedDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1)
|
||||
property real size: 18
|
||||
property alias textColor: btn_text.textColor
|
||||
property bool textRight: true
|
||||
property real textSpacing: 6
|
||||
property bool enableAnimation: FluTheme.enableAnimation
|
||||
property var clickListener : function(){
|
||||
checked = !checked
|
||||
}
|
||||
property bool indeterminate : false
|
||||
id:control
|
||||
enabled: !disabled
|
||||
onClicked: clickListener()
|
||||
onCheckableChanged: {
|
||||
if(checkable){
|
||||
checkable = false
|
||||
}
|
||||
}
|
||||
background: Item{
|
||||
FluFocusRectangle{
|
||||
radius: 4
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
horizontalPadding:0
|
||||
verticalPadding: 0
|
||||
padding: 0
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
focusPolicy:Qt.TabFocus
|
||||
contentItem: RowLayout{
|
||||
spacing: control.textSpacing
|
||||
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
|
||||
Rectangle{
|
||||
width: control.size
|
||||
height: control.size
|
||||
radius: 4
|
||||
border.color: {
|
||||
if(!enabled){
|
||||
return borderDisableColor
|
||||
}
|
||||
if(checked){
|
||||
return bordercheckedColor
|
||||
}
|
||||
if(pressed){
|
||||
return borderPressedColor
|
||||
}
|
||||
if(hovered){
|
||||
return borderHoverColor
|
||||
}
|
||||
return borderNormalColor
|
||||
}
|
||||
border.width: 1
|
||||
color: {
|
||||
if(checked){
|
||||
if(!enabled){
|
||||
return checkedDisableColor
|
||||
}
|
||||
if(pressed){
|
||||
return checkedPreesedColor
|
||||
}
|
||||
if(hovered){
|
||||
return checkedHoverColor
|
||||
}
|
||||
return checkedColor
|
||||
}
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(hovered){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
Behavior on color {
|
||||
enabled: control.enableAnimation
|
||||
ColorAnimation{
|
||||
duration: 83
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.CheckboxIndeterminate
|
||||
iconSize: 14
|
||||
visible: indeterminate
|
||||
iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
Behavior on visible {
|
||||
enabled: control.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 83
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.AcceptMedium
|
||||
iconSize: 14
|
||||
visible: checked && !indeterminate
|
||||
iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
Behavior on visible {
|
||||
enabled: control.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 83
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
id:btn_text
|
||||
text: control.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: text !== ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import FluentUI
|
||||
|
||||
FluRectangle {
|
||||
id:control
|
||||
color: "#00000000"
|
||||
layer.enabled: !FluTools.isSoftware()
|
||||
layer.textureSize: Qt.size(control.width*2*Math.ceil(Screen.devicePixelRatio),control.height*2*Math.ceil(Screen.devicePixelRatio))
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: ShaderEffectSource{
|
||||
sourceItem: FluRectangle{
|
||||
radius: control.radius
|
||||
width: control.width
|
||||
height: control.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,589 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Button{
|
||||
id:control
|
||||
width: 36
|
||||
height: 36
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
property color current : Qt.rgba(1,1,1,1)
|
||||
signal accepted()
|
||||
property int colorHandleRadius: 8
|
||||
property string cancelText: "取消"
|
||||
property string okText: "确定"
|
||||
property string titleText: "颜色选择器"
|
||||
property string editText: "编辑颜色"
|
||||
property string redText: "红色"
|
||||
property string greenText: "绿色"
|
||||
property string blueText: "蓝色"
|
||||
property string opacityText: "透明度"
|
||||
background:
|
||||
Rectangle{
|
||||
id:layout_color
|
||||
radius: 5
|
||||
color:"#00000000"
|
||||
border.color: {
|
||||
if(hovered)
|
||||
return FluTheme.primaryColor
|
||||
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: control.current
|
||||
}
|
||||
}
|
||||
contentItem: Item{}
|
||||
onClicked: {
|
||||
color_dialog.open()
|
||||
}
|
||||
FluPopup{
|
||||
id:color_dialog
|
||||
implicitWidth: 326
|
||||
implicitHeight: 560
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
width: parent.width
|
||||
height: 60
|
||||
radius: 5
|
||||
z:999
|
||||
anchors.bottom: parent.bottom
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
RowLayout{
|
||||
anchors
|
||||
{
|
||||
centerIn: parent
|
||||
margins: spacing
|
||||
fill: parent
|
||||
}
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluButton{
|
||||
text: control.cancelText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
color_dialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluFilledButton{
|
||||
text: control.okText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
current = layout_color_hue.colorValue
|
||||
control.accepted()
|
||||
color_dialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem: Flickable{
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: Math.min(layout_content.height,560,color_dialog.height)
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
contentHeight: layout_content.height + 70
|
||||
contentWidth: width
|
||||
clip: true
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
Item{
|
||||
id: layout_content
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
FluText{
|
||||
id: text_titile
|
||||
font: FluTextStyle.Subtitle
|
||||
text: control.titleText
|
||||
anchors{
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
leftMargin: 20
|
||||
topMargin: 20
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id: layout_sb
|
||||
width: 200
|
||||
height: 200
|
||||
anchors{
|
||||
left: parent.left
|
||||
top: text_titile.bottom
|
||||
leftMargin: 12
|
||||
}
|
||||
FluClip{
|
||||
id: layout_color_hue
|
||||
property color colorValue
|
||||
property real xPercent: pickerCursor.x/width
|
||||
property real yPercent: pickerCursor.y/height
|
||||
property real blackPercent: blackCursor.x/(layout_black.width-12)
|
||||
property real opacityPercent: opacityCursor.x/(layout_opacity.width-12)
|
||||
property color opacityColor:{
|
||||
var c = blackColor
|
||||
c = Qt.rgba(c.r,c.g,c.b,opacityPercent)
|
||||
return c
|
||||
}
|
||||
onOpacityColorChanged: {
|
||||
layout_color_hue.colorValue = opacityColor
|
||||
updateColorText(opacityColor)
|
||||
}
|
||||
function updateColorText(color){
|
||||
text_box_r.text = String(Math.floor(color.r*255))
|
||||
text_box_g.text = String(Math.floor(color.g*255))
|
||||
text_box_b.text = String(Math.floor(color.b*255))
|
||||
text_box_a.text = String(Math.floor(color.a*100))
|
||||
var colorString = color.toString().slice(1)
|
||||
if(color.a===1){
|
||||
colorString = "FF"+colorString
|
||||
}
|
||||
text_box_color.text = colorString.toUpperCase()
|
||||
}
|
||||
property color blackColor: {
|
||||
var c = whiteColor
|
||||
c = Qt.rgba(c.r*blackPercent,c.g*blackPercent,c.b*blackPercent,1)
|
||||
return c
|
||||
}
|
||||
property color hueColor: {
|
||||
var v = 1.0-xPercent
|
||||
var c
|
||||
if(0.0 <= v && v < 0.16) {
|
||||
c = Qt.rgba(1.0, 0.0, v/0.16, 1.0)
|
||||
} else if(0.16 <= v && v < 0.33) {
|
||||
c = Qt.rgba(1.0 - (v-0.16)/0.17, 0.0, 1.0, 1.0)
|
||||
} else if(0.33 <= v && v < 0.5) {
|
||||
c = Qt.rgba(0.0, ((v-0.33)/0.17), 1.0, 1.0)
|
||||
} else if(0.5 <= v && v < 0.76) {
|
||||
c = Qt.rgba(0.0, 1.0, 1.0 - (v-0.5)/0.26, 1.0)
|
||||
} else if(0.76 <= v && v < 0.85) {
|
||||
c = Qt.rgba((v-0.76)/0.09, 1.0, 0.0, 1.0)
|
||||
} else if(0.85 <= v && v <= 1.0) {
|
||||
c = Qt.rgba(1.0, 1.0 - (v-0.85)/0.15, 0.0, 1.0)
|
||||
} else {
|
||||
c = Qt.rgba(1.0,0.0,0.0,1.0)
|
||||
}
|
||||
return c
|
||||
}
|
||||
property color whiteColor: {
|
||||
var c = hueColor
|
||||
c = Qt.rgba((1-c.r)*yPercent+c.r,(1-c.g)*yPercent+c.g,(1-c.b)*yPercent+c.b,1.0)
|
||||
return c
|
||||
}
|
||||
function updateColor(){
|
||||
var r = Number(text_box_r.text)/255
|
||||
var g = Number(text_box_g.text)/255
|
||||
var b = Number(text_box_b.text)/255
|
||||
var opacityPercent = Number(text_box_a.text)/100
|
||||
var blackPercent = Math.max(r,g,b)
|
||||
r = r/blackPercent
|
||||
g = g/blackPercent
|
||||
b = b/blackPercent
|
||||
var yPercent = Math.min(r,g,b)
|
||||
if(r === g && r === b){
|
||||
r = 1
|
||||
b = 1
|
||||
g = 1
|
||||
}else{
|
||||
r = (yPercent-r)/(yPercent-1)
|
||||
g = (yPercent-g)/(yPercent-1)
|
||||
b = (yPercent-b)/(yPercent-1)
|
||||
}
|
||||
var xPercent
|
||||
if (r === 1.0 && g === 0.0 && b <= 1.0) {
|
||||
if(b===0.0){
|
||||
xPercent = 0
|
||||
}else{
|
||||
xPercent = 1.0 - b * 0.16
|
||||
}
|
||||
} else if (r <= 1.0 && g === 0.0 && b === 1.0) {
|
||||
xPercent = 1.0 - (1.0 - r) * 0.17 - 0.16
|
||||
} else if (r === 0.0 && g <= 1.0 && b === 1.0) {
|
||||
xPercent = 1.0 - (g * 0.17 + 0.33)
|
||||
} else if (r === 0.0 && g === 1.0 && b <= 1.0) {
|
||||
xPercent = 1.0 - (1.0 - b) * 0.26 - 0.5
|
||||
} else if (r <= 1.0 && g === 1.0 && b === 0.0) {
|
||||
xPercent = 1.0 - (r * 0.09 + 0.76)
|
||||
} else if (r === 1.0 && g <= 1.0 && b === 0.0) {
|
||||
xPercent = 1.0 - (1.0 - g) * 0.15 - 0.85
|
||||
} else {
|
||||
xPercent = 0
|
||||
}
|
||||
pickerCursor.x = xPercent * width
|
||||
pickerCursor.y = yPercent * height
|
||||
blackCursor.x = blackPercent * (layout_black.width-12)
|
||||
opacityCursor.x = opacityPercent * (layout_opacity.width-12)
|
||||
}
|
||||
radius: [4,4,4,4]
|
||||
x: colorHandleRadius
|
||||
y: colorHandleRadius
|
||||
width: parent.width - 2 * colorHandleRadius
|
||||
height: parent.height - 2 * colorHandleRadius
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.0; color: "#FF0000" }
|
||||
GradientStop { position: 0.16; color: "#FFFF00" }
|
||||
GradientStop { position: 0.33; color: "#00FF00" }
|
||||
GradientStop { position: 0.5; color: "#00FFFF" }
|
||||
GradientStop { position: 0.76; color: "#0000FF" }
|
||||
GradientStop { position: 0.85; color: "#FF00FF" }
|
||||
GradientStop { position: 1.0; color: "#FF0000" }
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#FFFFFFFF" }
|
||||
GradientStop { position: 0.0; color: "#00000000" }
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors.fill: parent
|
||||
border.width: 1
|
||||
border.color: FluTheme.dividerColor
|
||||
color:"#00000000"
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: pickerCursor
|
||||
Rectangle {
|
||||
width: colorHandleRadius*2; height: colorHandleRadius*2
|
||||
radius: colorHandleRadius
|
||||
border.color: "black"; border.width: 2
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent; anchors.margins: 2;
|
||||
border.color: "white"; border.width: 2
|
||||
radius: width/2
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
x: colorHandleRadius
|
||||
y: colorHandleRadius
|
||||
preventStealing: true
|
||||
function handleMouse(mouse) {
|
||||
if (mouse.buttons & Qt.LeftButton) {
|
||||
pickerCursor.x = Math.max(0,Math.min(mouse.x - colorHandleRadius,width-2*colorHandleRadius));
|
||||
pickerCursor.y = Math.max(0,Math.min(mouse.y - colorHandleRadius,height-2*colorHandleRadius));
|
||||
}
|
||||
}
|
||||
onPositionChanged:(mouse)=> handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
}
|
||||
FluClip{
|
||||
width: 40
|
||||
height: 200
|
||||
anchors{
|
||||
top: layout_sb.top
|
||||
bottom: layout_sb.bottom
|
||||
left: layout_sb.right
|
||||
topMargin: colorHandleRadius
|
||||
bottomMargin: colorHandleRadius
|
||||
leftMargin: 4
|
||||
}
|
||||
radius: [4,4,4,4]
|
||||
Grid {
|
||||
padding: 0
|
||||
id:target_grid_color
|
||||
anchors.fill: parent
|
||||
rows: height/5+1
|
||||
columns: width/5+1
|
||||
Repeater {
|
||||
model: (target_grid_color.columns-1)*(target_grid_color.rows-1)
|
||||
Rectangle {
|
||||
width: 6
|
||||
height: 6
|
||||
color: (model.index%2 == 0) ? "gray" : "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color:layout_color_hue.colorValue
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: FluTheme.dividerColor
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
id:layout_slider_bar
|
||||
spacing: 8
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 18
|
||||
right: parent.right
|
||||
rightMargin: 18
|
||||
top: layout_sb.bottom
|
||||
topMargin: 10
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_black
|
||||
radius: 6
|
||||
height: 12
|
||||
width:parent.width
|
||||
gradient: Gradient {
|
||||
orientation:Gradient.Horizontal
|
||||
GradientStop { position: 0.0; color: "#FF000000" }
|
||||
GradientStop { position: 1.0; color: layout_color_hue.hueColor }
|
||||
}
|
||||
Item {
|
||||
id:blackCursor
|
||||
x:layout_black.width-12
|
||||
Rectangle {
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 6
|
||||
border.color: "black"
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
border.color: "white"
|
||||
border.width: 2
|
||||
radius: width/2
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
function handleMouse(mouse) {
|
||||
if (mouse.buttons & Qt.LeftButton) {
|
||||
blackCursor.x = Math.max(0,Math.min(mouse.x - 6,width-2*6));
|
||||
blackCursor.y = 0
|
||||
}
|
||||
}
|
||||
onPositionChanged:(mouse)=> handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
|
||||
}
|
||||
FluClip{
|
||||
id:layout_opacity
|
||||
height: 12
|
||||
width:parent.width
|
||||
radius: [6,6,6,6]
|
||||
Grid {
|
||||
id:grid_opacity
|
||||
anchors.fill: parent
|
||||
rows: height/4
|
||||
columns: width/4+1
|
||||
clip: true
|
||||
Repeater {
|
||||
model: grid_opacity.columns*grid_opacity.rows
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: 4
|
||||
color: (model.index%2 == 0) ? "gray" : "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.debug(grid_opacity.columns,grid_opacity.rows)
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
orientation:Gradient.Horizontal
|
||||
GradientStop { position: 0.0; color: "#00000000" }
|
||||
GradientStop { position: 1.0; color: layout_color_hue.blackColor }
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id:opacityCursor
|
||||
x:layout_opacity.width-12
|
||||
Rectangle {
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 6
|
||||
border.color: "black"
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
border.color: "white"
|
||||
border.width: 2
|
||||
radius: width/2
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id:mouse_opacity
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
function handleMouse(mouse) {
|
||||
if (mouse.buttons & Qt.LeftButton) {
|
||||
opacityCursor.x = Math.max(0,Math.min(mouse.x - 6,width-2*6));
|
||||
opacityCursor.y = 0
|
||||
}
|
||||
}
|
||||
onPositionChanged:(mouse)=> handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
top: layout_slider_bar.bottom
|
||||
topMargin: 10
|
||||
right: parent.right
|
||||
rightMargin: 20
|
||||
}
|
||||
spacing: 5
|
||||
Item{
|
||||
width: parent.width
|
||||
height: text_box_color.height
|
||||
FluText{
|
||||
text: control.editText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:parent.left
|
||||
}
|
||||
}
|
||||
FluTextBox{
|
||||
id:text_box_color
|
||||
width: 136
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^[0-9A-F]{8}$/
|
||||
}
|
||||
anchors{
|
||||
right: parent.right
|
||||
}
|
||||
leftPadding: 20
|
||||
FluText{
|
||||
text:"#"
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 5
|
||||
}
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
var colorString = text_box_color.text.padStart(8,"0")
|
||||
var c = Qt.rgba(
|
||||
parseInt(colorString.substring(2, 4), 16) / 255,
|
||||
parseInt(colorString.substring(4, 6), 16) / 255,
|
||||
parseInt(colorString.substring(6, 8), 16) / 255,
|
||||
parseInt(colorString.substring(0, 2), 16) / 255)
|
||||
layout_color_hue.colorValue = c
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_r
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
layout_color_hue.updateColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.redText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_g
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
layout_color_hue.updateColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.greenText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_b
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
layout_color_hue.updateColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.blueText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_a
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(100|[1-9]?\d)$/
|
||||
}
|
||||
FluText{
|
||||
id:text_opacity
|
||||
text:"%"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x:Math.min(text_box_a.implicitWidth,text_box_a.width)-38
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
opacityCursor.x = Number(text)/100 * (layout_opacity.width-12)
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.opacityText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
import QtQuick.Templates as T
|
||||
|
||||
T.ComboBox {
|
||||
id: control
|
||||
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)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
font: FluTextStyle.Body
|
||||
leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
|
||||
rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
|
||||
enabled: !disabled
|
||||
delegate: FluItemDelegate {
|
||||
width: ListView.view.width
|
||||
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
|
||||
palette.text: control.palette.text
|
||||
font: control.font
|
||||
palette.highlightedText: control.palette.highlightedText
|
||||
highlighted: control.highlightedIndex === index
|
||||
hoverEnabled: control.hoverEnabled
|
||||
}
|
||||
focusPolicy:Qt.TabFocus
|
||||
indicator: FluIcon {
|
||||
x: control.mirrored ? control.padding : control.width - width - control.padding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
width: 28
|
||||
iconSource:FluentIcons.ChevronDown
|
||||
iconSize: 15
|
||||
opacity: enabled ? 1 : 0.3
|
||||
}
|
||||
contentItem: T.TextField {
|
||||
property bool disabled: !control.editable
|
||||
leftPadding: !control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1
|
||||
rightPadding: control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1
|
||||
topPadding: 6 - control.padding
|
||||
bottomPadding: 6 - control.padding
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
selectedTextColor: color
|
||||
text: control.editable ? control.editText : control.displayText
|
||||
enabled: control.editable
|
||||
autoScroll: control.editable
|
||||
font:control.font
|
||||
readOnly: control.down
|
||||
color: {
|
||||
if(control.disabled) {
|
||||
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
}
|
||||
inputMethodHints: control.inputMethodHints
|
||||
validator: control.validator
|
||||
selectByMouse: true
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
leftInset:1
|
||||
topInset:1
|
||||
bottomInset:1
|
||||
rightInset:1
|
||||
background: FluTextBoxBackground{
|
||||
borderWidth: 0
|
||||
inputItem: contentItem
|
||||
}
|
||||
Component.onCompleted: {
|
||||
forceActiveFocus()
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> handleCommit(event)
|
||||
function handleCommit(event){
|
||||
control.commit(control.editText)
|
||||
accepted()
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 140
|
||||
implicitHeight: 32
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
visible: !control.flat || control.down
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.visualFocus
|
||||
radius:4
|
||||
anchors.margins: -2
|
||||
}
|
||||
color:{
|
||||
if(disabled){
|
||||
return disableColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
|
||||
popup: T.Popup {
|
||||
y: control.height
|
||||
width: control.width
|
||||
height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin)
|
||||
topMargin: 6
|
||||
bottomMargin: 6
|
||||
modal: true
|
||||
contentItem: ListView {
|
||||
clip: true
|
||||
implicitHeight: contentHeight
|
||||
model: control.delegateModel
|
||||
currentIndex: control.highlightedIndex
|
||||
highlightMoveDuration: 0
|
||||
boundsMovement: Flickable.StopAtBounds
|
||||
T.ScrollIndicator.vertical: ScrollIndicator { }
|
||||
}
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
background:Rectangle{
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
radius: 5
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
FluPopup {
|
||||
id: control
|
||||
property string title: ""
|
||||
property string message: ""
|
||||
property string neutralText: qsTr("Close")
|
||||
property string negativeText: qsTr("Cancel")
|
||||
property string positiveText: qsTr("OK")
|
||||
property int messageTextFormart: Text.AutoText
|
||||
property int delayTime: 100
|
||||
property int buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
property var contentDelegate: Component{
|
||||
Item{
|
||||
}
|
||||
}
|
||||
property var onNeutralClickListener
|
||||
property var onNegativeClickListener
|
||||
property var onPositiveClickListener
|
||||
signal neutralClicked
|
||||
signal negativeClicked
|
||||
signal positiveClicked
|
||||
implicitWidth: 400
|
||||
implicitHeight: layout_content.height
|
||||
focus: true
|
||||
Component{
|
||||
id:com_message
|
||||
Flickable{
|
||||
id:sroll_message
|
||||
contentHeight: text_message.height
|
||||
contentWidth: width
|
||||
clip: true
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
width: parent.width
|
||||
height: message === "" ? 0 : Math.min(text_message.height,300)
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
FluText{
|
||||
id:text_message
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
text:message
|
||||
width: parent.width
|
||||
topPadding: 4
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
bottomPadding: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id:layout_content
|
||||
width: parent.width
|
||||
height: layout_column.childrenRect.height
|
||||
color: 'transparent'
|
||||
radius:5
|
||||
ColumnLayout{
|
||||
id:layout_column
|
||||
width: parent.width
|
||||
FluText{
|
||||
id:text_title
|
||||
font: FluTextStyle.Title
|
||||
text:title
|
||||
topPadding: 20
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
wrapMode: Text.WrapAnywhere
|
||||
}
|
||||
FluLoader{
|
||||
sourceComponent: com_message
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: status===Loader.Ready ? item.height : 0
|
||||
}
|
||||
FluLoader{
|
||||
sourceComponent:control.visible ? control.contentDelegate : undefined
|
||||
Layout.fillWidth: true
|
||||
onStatusChanged: {
|
||||
if(status===Loader.Ready){
|
||||
Layout.preferredHeight = item.implicitHeight
|
||||
}else{
|
||||
Layout.preferredHeight = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 60
|
||||
radius: 5
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
RowLayout{
|
||||
anchors
|
||||
{
|
||||
centerIn: parent
|
||||
margins: spacing
|
||||
fill: parent
|
||||
}
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluButton{
|
||||
id:neutral_btn
|
||||
visible: control.buttonFlags&FluContentDialogType.NeutralButton
|
||||
text: neutralText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
if(control.onNeutralClickListener){
|
||||
control.onNeutralClickListener()
|
||||
}else{
|
||||
neutralClicked()
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluButton{
|
||||
id:negative_btn
|
||||
visible: control.buttonFlags&FluContentDialogType.NegativeButton
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
text: negativeText
|
||||
onClicked: {
|
||||
if(control.onNegativeClickListener){
|
||||
control.onNegativeClickListener()
|
||||
}else{
|
||||
negativeClicked()
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluFilledButton{
|
||||
id:positive_btn
|
||||
visible: control.buttonFlags&FluContentDialogType.PositiveButton
|
||||
text: positiveText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
if(control.onPositiveClickListener){
|
||||
control.onPositiveClickListener()
|
||||
}else{
|
||||
positiveClicked()
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluPage {
|
||||
property alias title: text_title.text
|
||||
default property alias content: container.data
|
||||
property int leftPadding: 10
|
||||
property int topPadding: 0
|
||||
property int rightPadding: 10
|
||||
property int bottomPadding: 10
|
||||
property alias color: status_view.color
|
||||
property alias statusMode: status_view.statusMode
|
||||
property alias loadingText: status_view.loadingText
|
||||
property alias emptyText:status_view.emptyText
|
||||
property alias errorText:status_view.errorText
|
||||
property alias errorButtonText:status_view.errorButtonText
|
||||
property alias loadingItem :status_view.loadingItem
|
||||
property alias emptyItem : status_view.emptyItem
|
||||
property alias errorItem :status_view.errorItem
|
||||
signal errorClicked
|
||||
|
||||
id:control
|
||||
FluText{
|
||||
id:text_title
|
||||
visible: text !== ""
|
||||
height: visible ? contentHeight : 0
|
||||
font: FluTextStyle.Title
|
||||
anchors{
|
||||
top: parent.top
|
||||
topMargin: control.topPadding
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: control.leftPadding
|
||||
rightMargin: control.rightPadding
|
||||
}
|
||||
}
|
||||
FluStatusLayout{
|
||||
id:status_view
|
||||
color: "#00000000"
|
||||
statusMode: FluStatusLayoutType.Success
|
||||
onErrorClicked: control.errorClicked()
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: text_title.bottom
|
||||
bottom: parent.bottom
|
||||
leftMargin: control.leftPadding
|
||||
rightMargin: control.rightPadding
|
||||
bottomMargin: control.bottomPadding
|
||||
}
|
||||
Item{
|
||||
clip: true
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import FluentUI
|
||||
import QtQuick.Templates as T
|
||||
|
||||
T.Button {
|
||||
id: control
|
||||
property string contentDescription: ""
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
padding: 0
|
||||
horizontalPadding: 0
|
||||
spacing: 0
|
||||
contentItem: Item{}
|
||||
focusPolicy:Qt.TabFocus
|
||||
background: Item{
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:8
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
TextEdit {
|
||||
property color textColor: FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
id:control
|
||||
color: textColor
|
||||
readOnly: true
|
||||
activeFocusOnTab: false
|
||||
activeFocusOnPress: false
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
padding: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
selectByMouse: true
|
||||
selectedTextColor: color
|
||||
bottomPadding: 0
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
font:FluTextStyle.Body
|
||||
onSelectedTextChanged: {
|
||||
control.forceActiveFocus()
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: control.echoMode !== TextInput.Password && menu.popup()
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
@ -1,415 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property bool showYear: true
|
||||
property var current
|
||||
property string yearText: qsTr("Year")
|
||||
property string monthText: qsTr("Month")
|
||||
property string dayText: qsTr("Day")
|
||||
property string cancelText: qsTr("Cancel")
|
||||
property string okText: qsTr("OK")
|
||||
signal accepted()
|
||||
id:control
|
||||
color: {
|
||||
if(mouse_area.containsMouse){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
height: 30
|
||||
width: 300
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: dividerColor
|
||||
Component.onCompleted: {
|
||||
if(current){
|
||||
const now = current;
|
||||
var year = text_year.text === control.yearText? now.getFullYear() : Number(text_year.text);
|
||||
var month = text_month.text === control.monthText? now.getMonth() + 1 : Number(text_month.text);
|
||||
var day = text_day.text === control.dayText ? now.getDate() : Number(text_day.text);
|
||||
text_year.text = year
|
||||
text_month.text = month
|
||||
text_day.text = day
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property var window: Window.window
|
||||
property bool changeFlag: true
|
||||
property var rowData: ["","",""]
|
||||
visible: false
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_area
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
popup.showPopup()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:divider_1
|
||||
width: 1
|
||||
x: parent.width/3
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
visible: showYear
|
||||
}
|
||||
Rectangle{
|
||||
id:divider_2
|
||||
width: 1
|
||||
x: showYear ? parent.width*2/3 : parent.width/2
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
FluText{
|
||||
id:text_year
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: divider_1.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
visible: showYear
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:control.yearText
|
||||
}
|
||||
FluText{
|
||||
id:text_month
|
||||
anchors{
|
||||
left: showYear ? divider_1.right : parent.left
|
||||
right: divider_2.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:control.monthText
|
||||
}
|
||||
FluText{
|
||||
id:text_day
|
||||
anchors{
|
||||
left: divider_2.right
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:control.dayText
|
||||
}
|
||||
Menu{
|
||||
id:popup
|
||||
modal: true
|
||||
width: container.width
|
||||
height: container.height
|
||||
Overlay.modal: Item {}
|
||||
enter: Transition {
|
||||
reversible: true
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
background:Item{
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
id:container
|
||||
radius: 4
|
||||
width: 300
|
||||
height: 340
|
||||
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
}
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
RowLayout{
|
||||
id:layout_content
|
||||
spacing: 0
|
||||
width: parent.width
|
||||
height: 300
|
||||
Component{
|
||||
id:list_delegate
|
||||
Item{
|
||||
height:38
|
||||
width:getListView().width
|
||||
function getListView(){
|
||||
if(type === 0)
|
||||
return list_view_1
|
||||
if(type === 1)
|
||||
return list_view_2
|
||||
if(type === 2)
|
||||
return list_view_3
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 2
|
||||
anchors.bottomMargin: 2
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
color: {
|
||||
if(getListView().currentIndex === position){
|
||||
return item_mouse.containsMouse ? Qt.lighter(FluTheme.primaryColor,1.1): FluTheme.primaryColor
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
radius: 3
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
getListView().currentIndex = position
|
||||
if(type === 0){
|
||||
text_year.text = model
|
||||
list_view_2.model = generateMonthArray(1,12)
|
||||
text_month.text = list_view_2.model[list_view_2.currentIndex]
|
||||
|
||||
list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex])
|
||||
text_day.text = list_view_3.model[list_view_3.currentIndex]
|
||||
}
|
||||
if(type === 1){
|
||||
text_month.text = model
|
||||
list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex])
|
||||
text_day.text = list_view_3.model[list_view_3.currentIndex]
|
||||
|
||||
}
|
||||
if(type === 2){
|
||||
text_day.text = model
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:model
|
||||
color: {
|
||||
if(getListView().currentIndex === position){
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}else{
|
||||
return FluTheme.dark ? "#FFFFFF" : "#1A1A1A"
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:list_view_1
|
||||
width: 100
|
||||
height: parent.height
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model: generateYearArray(1924,2048)
|
||||
clip: true
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
visible: showYear
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:0
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
ListView{
|
||||
id:list_view_2
|
||||
width: showYear ? 100 : 150
|
||||
height: parent.height
|
||||
clip: true
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:1
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
ListView{
|
||||
id:list_view_3
|
||||
width: showYear ? 100 : 150
|
||||
height: parent.height
|
||||
clip: true
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:2
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: layout_content.bottom
|
||||
color: dividerColor
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
height: 40
|
||||
radius: 5
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
anchors{
|
||||
bottom:parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
Item {
|
||||
id:divider
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
FluButton{
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
rightMargin: 10
|
||||
right: divider.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: control.cancelText
|
||||
onClicked: {
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
FluFilledButton{
|
||||
anchors{
|
||||
right: parent.right
|
||||
left: divider.right
|
||||
rightMargin: 20
|
||||
leftMargin: 10
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: control.okText
|
||||
onClicked: {
|
||||
d.changeFlag = false
|
||||
popup.close()
|
||||
const year = text_year.text
|
||||
const month = text_month.text
|
||||
const day = text_day.text
|
||||
const date = new Date()
|
||||
date.setFullYear(parseInt(year));
|
||||
date.setMonth(parseInt(month) - 1);
|
||||
date.setDate(parseInt(day));
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
current = date
|
||||
control.accepted()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
y:35
|
||||
function showPopup() {
|
||||
d.changeFlag = true
|
||||
d.rowData[0] = text_year.text
|
||||
d.rowData[1] = text_month.text
|
||||
d.rowData[2] = text_day.text
|
||||
const now = new Date();
|
||||
var year = text_year.text === control.yearText? now.getFullYear() : Number(text_year.text);
|
||||
var month = text_month.text === control.monthText? now.getMonth() + 1 : Number(text_month.text);
|
||||
var day = text_day.text === control.dayText ? now.getDate() : Number(text_day.text);
|
||||
list_view_1.currentIndex = list_view_1.model.indexOf(year)
|
||||
text_year.text = year
|
||||
list_view_2.model = generateMonthArray(1,12)
|
||||
list_view_2.currentIndex = list_view_2.model.indexOf(month)
|
||||
text_month.text = month
|
||||
list_view_3.model = generateMonthDaysArray(year,month)
|
||||
list_view_3.currentIndex = list_view_3.model.indexOf(day)
|
||||
text_day.text = day
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.height){
|
||||
popup.y = control.height
|
||||
} else if(pos.y>container.height){
|
||||
popup.y = -container.height
|
||||
} else {
|
||||
popup.y = d.window.height-(pos.y+container.height)
|
||||
}
|
||||
popup.open()
|
||||
}
|
||||
onClosed: {
|
||||
if(d.changeFlag){
|
||||
text_year.text = d.rowData[0]
|
||||
text_month.text = d.rowData[1]
|
||||
text_day.text = d.rowData[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
function generateYearArray(startYear, endYear) {
|
||||
const yearArray = [];
|
||||
for (let year = startYear; year <= endYear; year++) {
|
||||
yearArray.push(year);
|
||||
}
|
||||
return yearArray;
|
||||
}
|
||||
function generateMonthArray(startMonth, endMonth) {
|
||||
const monthArray = [];
|
||||
for (let month = startMonth; month <= endMonth; month++) {
|
||||
monthArray.push(month);
|
||||
}
|
||||
return monthArray;
|
||||
}
|
||||
function generateMonthDaysArray(year, month) {
|
||||
const monthDaysArray = [];
|
||||
const lastDayOfMonth = new Date(year, month, 0).getDate();
|
||||
for (let day = 1; day <= lastDayOfMonth; day++) {
|
||||
monthDaysArray.push(day);
|
||||
}
|
||||
return monthDaysArray;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
id:control
|
||||
property int orientation: Qt.Horizontal
|
||||
property int spacing:0
|
||||
property int size: 1
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isVertical : orientation === Qt.Vertical
|
||||
property int parentHeight: {
|
||||
if(control.parent){
|
||||
return control.parent.height
|
||||
}
|
||||
return control.height
|
||||
}
|
||||
property int parentWidth: {
|
||||
if(control.parent){
|
||||
return control.parent.width
|
||||
}
|
||||
return control.width
|
||||
}
|
||||
}
|
||||
width: d.isVertical ? spacing*2+size : d.parentWidth
|
||||
height: d.isVertical ? d.parentHeight : spacing*2+size
|
||||
FluRectangle{
|
||||
color: FluTheme.dividerColor
|
||||
width: d.isVertical ? size : control.width
|
||||
height: d.isVertical ? control.height : size
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
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(246/255,246/255,246/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
property var window : Window.window
|
||||
default property alias contentData: menu.contentData
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id: control
|
||||
rightPadding:35
|
||||
enabled: !disabled
|
||||
focusPolicy:Qt.TabFocus
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:8
|
||||
}
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
FluIcon{
|
||||
iconSource:FluentIcons.ChevronDown
|
||||
iconSize: 15
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 10
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
iconColor:title.color
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
id:title
|
||||
text: control.text
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: control.textColor
|
||||
}
|
||||
onClicked: {
|
||||
if(menu.count !==0){
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
var containerHeight = menu.count*36
|
||||
if(window.height>pos.y+control.height+containerHeight){
|
||||
menu.y = control.height
|
||||
}else if(pos.y>containerHeight){
|
||||
menu.y = -containerHeight
|
||||
}else{
|
||||
menu.y = window.height-(pos.y+containerHeight)
|
||||
}
|
||||
menu.open()
|
||||
}
|
||||
}
|
||||
FluMenu{
|
||||
id:menu
|
||||
modal:true
|
||||
width: control.width
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property string headerText: ""
|
||||
property bool expand: false
|
||||
property int contentHeight : 300
|
||||
default property alias content: container.data
|
||||
id:control
|
||||
implicitHeight: Math.max((layout_header.height + layout_container.height),layout_header.height)
|
||||
implicitWidth: 400
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flag: false
|
||||
function toggle(){
|
||||
d.flag = true
|
||||
expand = !expand
|
||||
d.flag = false
|
||||
}
|
||||
}
|
||||
clip: true
|
||||
Rectangle{
|
||||
id:layout_header
|
||||
width: parent.width
|
||||
height: 45
|
||||
radius: 4
|
||||
color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1) : Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
MouseArea{
|
||||
id:control_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
d.toggle()
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: headerText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 15
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 15
|
||||
}
|
||||
color:{
|
||||
if(control_mouse.containsMouse || hovered){
|
||||
return FluTheme.dark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(245/255,245/255,245/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
onClicked: {
|
||||
d.toggle()
|
||||
}
|
||||
contentItem: FluIcon{
|
||||
rotation: expand?0:180
|
||||
iconSource:FluentIcons.ChevronUp
|
||||
iconSize: 15
|
||||
Behavior on rotation {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:layout_container
|
||||
anchors{
|
||||
top: layout_header.bottom
|
||||
topMargin: -1
|
||||
left: layout_header.left
|
||||
}
|
||||
visible: contentHeight+container.anchors.topMargin !== 0
|
||||
height: contentHeight+container.anchors.topMargin
|
||||
width: parent.width
|
||||
z:-999
|
||||
Rectangle{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
radius: 4
|
||||
clip: true
|
||||
color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
border.color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
anchors.topMargin: -contentHeight
|
||||
states: [
|
||||
State{
|
||||
name:"expand"
|
||||
when: control.expand
|
||||
PropertyChanges {
|
||||
target: container
|
||||
anchors.topMargin:0
|
||||
}
|
||||
},
|
||||
State{
|
||||
name:"collapsed"
|
||||
when: !control.expand
|
||||
PropertyChanges {
|
||||
target: container
|
||||
anchors.topMargin:-contentHeight
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
to:"expand"
|
||||
NumberAnimation {
|
||||
properties: "anchors.topMargin"
|
||||
duration: FluTheme.enableAnimation && d.flag ? 167 : 0
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
to:"collapsed"
|
||||
NumberAnimation {
|
||||
properties: "anchors.topMargin"
|
||||
duration: FluTheme.enableAnimation && d.flag ? 167 : 0
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color normalColor: FluTheme.primaryColor
|
||||
property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(173/255,173/255,173/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id: control
|
||||
enabled: !disabled
|
||||
focusPolicy:Qt.TabFocus
|
||||
font:FluTextStyle.Body
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.visualFocus
|
||||
radius:4
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.33; color: control.enabled ? control.normalColor : Qt.rgba(0,0,0,0) }
|
||||
GradientStop { position: 1.0; color: control.enabled ? Qt.darker(control.normalColor,1.3) : Qt.rgba(0,0,0,0) }
|
||||
}
|
||||
Rectangle{
|
||||
radius: parent.radius
|
||||
anchors{
|
||||
fill: parent
|
||||
topMargin: control.enabled ? 0 : 0
|
||||
leftMargin: control.enabled ? 1 : 0
|
||||
rightMargin: control.enabled ? 1 : 0
|
||||
bottomMargin: control.enabled ? 2 : 0
|
||||
}
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
font: control.font
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: control.textColor
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
property bool vertical: false
|
||||
default property alias content : swipe.contentData
|
||||
property alias currentIndex: swipe.currentIndex
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flag: true
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onWheel:
|
||||
(wheel)=>{
|
||||
if(!d.flag)
|
||||
return
|
||||
if (wheel.angleDelta.y > 0){
|
||||
btn_start.clicked()
|
||||
}else{
|
||||
btn_end.clicked()
|
||||
}
|
||||
d.flag = false
|
||||
timer.restart()
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer
|
||||
interval: 250
|
||||
onTriggered: {
|
||||
d.flag = true
|
||||
}
|
||||
}
|
||||
SwipeView {
|
||||
id:swipe
|
||||
clip: true
|
||||
interactive: false
|
||||
orientation:control.vertical ? Qt.Vertical : Qt.Horizontal
|
||||
anchors.fill: parent
|
||||
}
|
||||
Button{
|
||||
id:btn_start
|
||||
height: vertical ? 20 : 40
|
||||
width: vertical ? 40 : 20
|
||||
anchors{
|
||||
left: vertical ? undefined : parent.left
|
||||
leftMargin: vertical ? undefined : 2
|
||||
verticalCenter: vertical ? undefined : parent.verticalCenter
|
||||
horizontalCenter: !vertical ? undefined : parent.horizontalCenter
|
||||
top: !vertical ? undefined :parent.top
|
||||
topMargin: !vertical ? undefined :2
|
||||
}
|
||||
background: Rectangle{
|
||||
radius: 4
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
|
||||
}
|
||||
contentItem:FluIcon{
|
||||
iconSource: vertical ? FluentIcons.CaretUpSolid8 : FluentIcons.CaretLeftSolid8
|
||||
width: 10
|
||||
height: 10
|
||||
iconSize: 10
|
||||
iconColor: btn_start.hovered ? FluColors.Grey220 : FluColors.Grey120
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
visible: swipe.currentIndex !==0
|
||||
onClicked: {
|
||||
swipe.currentIndex = Math.max(swipe.currentIndex - 1, 0)
|
||||
}
|
||||
}
|
||||
Button{
|
||||
id:btn_end
|
||||
height: vertical ? 20 : 40
|
||||
width: vertical ? 40 : 20
|
||||
anchors{
|
||||
right: vertical ? undefined : parent.right
|
||||
rightMargin: vertical ? undefined : 2
|
||||
verticalCenter: vertical ? undefined : parent.verticalCenter
|
||||
horizontalCenter: !vertical ? undefined : parent.horizontalCenter
|
||||
bottom: !vertical ? undefined :parent.bottom
|
||||
bottomMargin: !vertical ? undefined :2
|
||||
}
|
||||
background: Rectangle{
|
||||
radius: 4
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
|
||||
}
|
||||
visible: swipe.currentIndex !== swipe.count - 1
|
||||
contentItem:FluIcon{
|
||||
iconSource: vertical ? FluentIcons.CaretDownSolid8 : FluentIcons.CaretRightSolid8
|
||||
width: 10
|
||||
height: 10
|
||||
iconSize: 10
|
||||
iconColor: btn_end.hovered ? FluColors.Grey220 : FluColors.Grey120
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
onClicked: {
|
||||
swipe.currentIndex = Math.min(swipe.currentIndex + 1,swipe.count-1)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int radius: 4
|
||||
id:control
|
||||
anchors.fill: parent
|
||||
Rectangle{
|
||||
width: control.width
|
||||
height: control.height
|
||||
anchors.centerIn: parent
|
||||
color: "#00000000"
|
||||
border.width: 2
|
||||
radius: control.radius
|
||||
border.color: FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
||||
z: 65535
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Text {
|
||||
property int iconSource
|
||||
property int iconSize: 20
|
||||
property color iconColor: FluTheme.dark ? "#FFFFFF" : "#000000"
|
||||
id:control
|
||||
font.family: "Segoe Fluent Icons"
|
||||
font.pixelSize: iconSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: iconColor
|
||||
text: (String.fromCharCode(iconSource).toString(16))
|
||||
FontLoader{
|
||||
source: "../Font/Segoe_Fluent_Icons.ttf"
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
display: Button.IconOnly
|
||||
property int iconSize: 20
|
||||
property int iconSource
|
||||
property bool disabled: false
|
||||
property int radius:4
|
||||
property string contentDescription: ""
|
||||
property color hoverColor: FluTheme.itemHoverColor
|
||||
property color pressedColor: FluTheme.itemPressColor
|
||||
property color normalColor: FluTheme.itemNormalColor
|
||||
property color disableColor: FluTheme.itemNormalColor
|
||||
property Component iconDelegate: com_icon
|
||||
property color color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor : normalColor
|
||||
}
|
||||
property color iconColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(130/255,130/255,130/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(161/255,161/255,161/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
property color textColor: FluTheme.fontPrimaryColor
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id:control
|
||||
focusPolicy:Qt.TabFocus
|
||||
padding: 0
|
||||
verticalPadding: 8
|
||||
horizontalPadding: 8
|
||||
enabled: !disabled
|
||||
font:FluTextStyle.Caption
|
||||
background: Rectangle{
|
||||
implicitWidth: 30
|
||||
implicitHeight: 30
|
||||
radius: control.radius
|
||||
color:control.color
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_icon
|
||||
FluIcon {
|
||||
id:text_icon
|
||||
font.pixelSize: iconSize
|
||||
iconSize: control.iconSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
iconColor: control.iconColor
|
||||
iconSource: control.iconSource
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_row
|
||||
RowLayout{
|
||||
FluLoader{
|
||||
sourceComponent: iconDelegate
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.TextOnly
|
||||
}
|
||||
FluText{
|
||||
text:control.text
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.IconOnly
|
||||
color: control.textColor
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_column
|
||||
ColumnLayout{
|
||||
FluLoader{
|
||||
sourceComponent: iconDelegate
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.TextOnly
|
||||
}
|
||||
FluText{
|
||||
text:control.text
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.IconOnly
|
||||
color: control.textColor
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem:FluLoader{
|
||||
sourceComponent: {
|
||||
if(display === Button.TextUnderIcon){
|
||||
return com_column
|
||||
}
|
||||
return com_row
|
||||
}
|
||||
}
|
||||
FluTooltip{
|
||||
id:tool_tip
|
||||
visible: {
|
||||
if(control.text === ""){
|
||||
return false
|
||||
}
|
||||
if(control.display !== Button.IconOnly){
|
||||
return false
|
||||
}
|
||||
return hovered
|
||||
}
|
||||
text:control.text
|
||||
delay: 1000
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Image {
|
||||
property string errorButtonText: qsTr("Reload")
|
||||
property var clickErrorListener : function(){
|
||||
image.source = ""
|
||||
image.source = control.source
|
||||
}
|
||||
property Component errorItem : com_error
|
||||
property Component loadingItem: com_loading
|
||||
id: control
|
||||
FluLoader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(control.status === Image.Loading){
|
||||
return com_loading
|
||||
}else if(control.status == Image.Error){
|
||||
return com_error
|
||||
}else{
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_loading
|
||||
Rectangle{
|
||||
color: FluTheme.itemHoverColor
|
||||
FluProgressRing{
|
||||
anchors.centerIn: parent
|
||||
visible: control.status === Image.Loading
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_error
|
||||
Rectangle{
|
||||
color: FluTheme.itemHoverColor
|
||||
FluFilledButton{
|
||||
text: control.errorButtonText
|
||||
anchors.centerIn: parent
|
||||
visible: control.status === Image.Error
|
||||
onClicked: clickErrorListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Button{
|
||||
id:control
|
||||
property string normalImage: ""
|
||||
property string hoveredImage: ""
|
||||
property string pushedImage: ""
|
||||
background: Item{
|
||||
implicitHeight: 12
|
||||
implicitWidth: 12
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
source: control.hovered ? (control.pressed ? control.pushedImage : control.hoveredImage ) : control.normalImage
|
||||
}
|
||||
}
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluObject {
|
||||
property var root;
|
||||
property int layoutY: 75
|
||||
id:control
|
||||
FluObject{
|
||||
id:mcontrol
|
||||
property string const_success: "success";
|
||||
property string const_info: "info";
|
||||
property string const_warning: "warning";
|
||||
property string const_error: "error";
|
||||
property int maxWidth: 300;
|
||||
property var screenLayout: null;
|
||||
function create(type,text,duration,moremsg){
|
||||
if(screenLayout){
|
||||
var last = screenLayout.getLastloader();
|
||||
if(last.type === type && last.text === text && moremsg === last.moremsg){
|
||||
last.restart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
initScreenLayout();
|
||||
contentComponent.createObject(screenLayout,{
|
||||
type:type,
|
||||
text:text,
|
||||
duration:duration,
|
||||
moremsg:moremsg,
|
||||
});
|
||||
}
|
||||
function createCustom(itemcomponent,duration){
|
||||
initScreenLayout();
|
||||
if(itemcomponent){
|
||||
contentComponent.createObject(screenLayout,{itemcomponent:itemcomponent,duration:duration});
|
||||
}
|
||||
}
|
||||
function initScreenLayout(){
|
||||
if(screenLayout == null){
|
||||
screenLayout = screenlayoutComponent.createObject(root);
|
||||
screenLayout.y = control.layoutY;
|
||||
screenLayout.z = 100000;
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:screenlayoutComponent
|
||||
Column{
|
||||
parent: Overlay.overlay
|
||||
z:999
|
||||
spacing: 20
|
||||
width: root.width
|
||||
move: Transition {
|
||||
NumberAnimation {
|
||||
properties: "y"
|
||||
easing.type: Easing.OutCubic
|
||||
duration: FluTheme.enableAnimation ? 333 : 0
|
||||
}
|
||||
}
|
||||
onChildrenChanged: if(children.length === 0) destroy();
|
||||
function getLastloader(){
|
||||
if(children.length > 0){
|
||||
return children[children.length - 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:contentComponent
|
||||
Item{
|
||||
id:content;
|
||||
property int duration: 1500
|
||||
property var itemcomponent
|
||||
property string type
|
||||
property string text
|
||||
property string moremsg
|
||||
width: parent.width;
|
||||
height: loader.height;
|
||||
function close(){
|
||||
content.destroy();
|
||||
}
|
||||
function restart(){
|
||||
delayTimer.restart();
|
||||
}
|
||||
Timer {
|
||||
id:delayTimer
|
||||
interval: duration; running: duration > 0; repeat: duration > 0
|
||||
onTriggered: content.close();
|
||||
}
|
||||
FluLoader{
|
||||
id:loader;
|
||||
x:(parent.width - width) / 2;
|
||||
property var _super: content;
|
||||
scale: item ? 1 : 0;
|
||||
asynchronous: true
|
||||
Behavior on scale {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation {
|
||||
easing.type: Easing.OutCubic
|
||||
duration: 167
|
||||
}
|
||||
}
|
||||
sourceComponent:itemcomponent ? itemcomponent : mcontrol.fluent_sytle;
|
||||
}
|
||||
}
|
||||
}
|
||||
property Component fluent_sytle: Rectangle{
|
||||
width: rowlayout.width + (btn_close.visible ? 30 : 48);
|
||||
height: rowlayout.height + 20;
|
||||
color: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(57/255,61/255,27/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(67/255,53/255,25/255,1);
|
||||
case mcontrol.const_info: return Qt.rgba(39/255,39/255,39/255,1);
|
||||
case mcontrol.const_error: return Qt.rgba(68/255,39/255,38/255,1);
|
||||
}
|
||||
return Qt.rgba(255,255,255,1)
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#dff6dd";
|
||||
case mcontrol.const_warning: return "#fff4ce";
|
||||
case mcontrol.const_info: return "#f4f4f4";
|
||||
case mcontrol.const_error: return "#fde7e9";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(56/255,61/255,27/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(66/255,53/255,25/255,1);
|
||||
case mcontrol.const_info: return Qt.rgba(38/255,39/255,39/255,1);
|
||||
case mcontrol.const_error: return Qt.rgba(67/255,39/255,38/255,1);
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#d2e8d0";
|
||||
case mcontrol.const_warning: return "#f0e6c2";
|
||||
case mcontrol.const_info: return "#e6e6e6";
|
||||
case mcontrol.const_error: return "#eed9db";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:rowlayout
|
||||
x:20;
|
||||
y:(parent.height - height) / 2;
|
||||
spacing: 10
|
||||
FluIcon{
|
||||
iconSource:{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return FluentIcons.CompletedSolid;
|
||||
case mcontrol.const_warning: return FluentIcons.InfoSolid;
|
||||
case mcontrol.const_info: return FluentIcons.InfoSolid;
|
||||
case mcontrol.const_error: return FluentIcons.StatusErrorFull;
|
||||
}FluentIcons.StatusErrorFull
|
||||
return FluentIcons.FA_info_circle
|
||||
}
|
||||
iconSize:20
|
||||
iconColor: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1);
|
||||
case mcontrol.const_info: return FluTheme.primaryColor;
|
||||
case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1);
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#0f7b0f";
|
||||
case mcontrol.const_warning: return "#9d5d00";
|
||||
case mcontrol.const_info: return "#0066b4";
|
||||
case mcontrol.const_error: return "#c42b1c";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
spacing: 5
|
||||
FluText{
|
||||
text:_super.text
|
||||
wrapMode: Text.WrapAnywhere
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
FluText{
|
||||
text: _super.moremsg
|
||||
visible: _super.moremsg
|
||||
wrapMode : Text.WrapAnywhere
|
||||
textColor: FluColors.Grey120
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
id:btn_close
|
||||
iconSource: FluentIcons.ChromeClose
|
||||
iconSize: 10
|
||||
y:5
|
||||
visible: _super.duration<=0
|
||||
iconColor: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1);
|
||||
case mcontrol.const_info: return FluTheme.primaryColor;
|
||||
case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1);
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#0f7b0f";
|
||||
case mcontrol.const_warning: return "#9d5d00";
|
||||
case mcontrol.const_info: return "#0066b4";
|
||||
case mcontrol.const_error: return "#c42b1c";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
onClicked: _super.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function showSuccess(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_success,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showInfo(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_info,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showWarning(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_warning,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showError(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_error,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showCustom(itemcomponent,duration=1000){
|
||||
mcontrol.createCustom(itemcomponent,duration);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.ItemDelegate {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
padding: 0
|
||||
verticalPadding: 8
|
||||
horizontalPadding: 10
|
||||
icon.color: control.palette.text
|
||||
contentItem:FluText {
|
||||
text: control.text
|
||||
font: control.font
|
||||
color:{
|
||||
if(control.down){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 30
|
||||
color:{
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(1,1,1,0.05)
|
||||
}else{
|
||||
return Qt.rgba(0,0,0,0.05)
|
||||
}
|
||||
}
|
||||
visible: control.down || control.highlighted || control.visualFocus
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import QtQuick
|
||||
|
||||
Loader {
|
||||
Component.onDestruction: sourceComponent = undefined
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
FluButton {
|
||||
property bool loading: false
|
||||
id: control
|
||||
disabled: loading
|
||||
contentItem: Row{
|
||||
spacing: 6
|
||||
FluText {
|
||||
text: control.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Item{
|
||||
width: control.loading ? 16 : 0
|
||||
height: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: Number(width)!==0
|
||||
clip: true
|
||||
Behavior on width {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
FluProgressRing{
|
||||
width: 16
|
||||
height: 16
|
||||
strokeWidth:3
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.Menu {
|
||||
property bool enableAnimation: true
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
contentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
contentHeight + topPadding + bottomPadding)
|
||||
margins: 0
|
||||
overlap: 1
|
||||
spacing: 0
|
||||
delegate: FluMenuItem { }
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation && control.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation && control.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
contentItem: ListView {
|
||||
implicitHeight: contentHeight
|
||||
model: control.contentModel
|
||||
interactive: Window.window
|
||||
? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
|
||||
: false
|
||||
clip: true
|
||||
currentIndex: control.currentIndex
|
||||
ScrollIndicator.vertical: ScrollIndicator {}
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
implicitHeight: 36
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
radius: 5
|
||||
FluShadow{}
|
||||
}
|
||||
T.Overlay.modal: Rectangle {
|
||||
color: Color.transparent(control.palette.shadow, 0.5)
|
||||
}
|
||||
T.Overlay.modeless: Rectangle {
|
||||
color: Color.transparent(control.palette.shadow, 0.12)
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Templates as T
|
||||
import QtQuick.Controls.impl
|
||||
|
||||
T.MenuBar {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
contentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
contentHeight + topPadding + bottomPadding)
|
||||
delegate: FluMenuBarItem { }
|
||||
contentItem: Row {
|
||||
spacing: control.spacing
|
||||
Repeater {
|
||||
model: control.contentModel
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
implicitHeight: 30
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Templates as T
|
||||
import QtQuick.Controls.impl
|
||||
import FluentUI
|
||||
|
||||
T.MenuBarItem {
|
||||
property bool disabled: false
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(disabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(disabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
id: control
|
||||
enabled: !disabled
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
spacing: 6
|
||||
padding: 6
|
||||
leftPadding: 12
|
||||
rightPadding: 16
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: control.palette.buttonText
|
||||
contentItem: FluText {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: control.text
|
||||
color:control.textColor
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 30
|
||||
implicitHeight: 30
|
||||
radius: 3
|
||||
color: {
|
||||
if(control.highlighted){
|
||||
return FluTheme.itemCheckColor
|
||||
}
|
||||
if(control.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluTheme.itemNormalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.MenuItem {
|
||||
property Component iconDelegate : com_icon
|
||||
property int iconSpacing: 5
|
||||
property int iconSource
|
||||
property int iconSize: 16
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
padding: 6
|
||||
spacing: 6
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: control.palette.windowText
|
||||
height: visible ? implicitHeight : 0
|
||||
font:FluTextStyle.Body
|
||||
Component{
|
||||
id:com_icon
|
||||
FluIcon{
|
||||
id:content_icon
|
||||
iconSize: control.iconSize
|
||||
iconSource:control.iconSource
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
Row{
|
||||
spacing: control.iconSpacing
|
||||
readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0
|
||||
readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: (!control.mirrored ? indicatorPadding : arrowPadding)+5
|
||||
right: parent.right
|
||||
rightMargin: (control.mirrored ? indicatorPadding : arrowPadding)+5
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_icon
|
||||
sourceComponent: iconDelegate
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: status === Loader.Ready
|
||||
}
|
||||
FluText {
|
||||
id:content_text
|
||||
text: control.text
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
indicator: FluIcon {
|
||||
x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
visible: control.checked
|
||||
iconSource: FluentIcons.CheckMark
|
||||
}
|
||||
arrow: FluIcon {
|
||||
x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
visible: control.subMenu
|
||||
iconSource: FluentIcons.ChevronRightMed
|
||||
}
|
||||
background: Item {
|
||||
implicitWidth: 150
|
||||
implicitHeight: 36
|
||||
x: 1
|
||||
y: 1
|
||||
width: control.width - 2
|
||||
height: control.height - 2
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 3
|
||||
radius: 4
|
||||
color:{
|
||||
if(control.highlighted){
|
||||
return FluTheme.itemCheckColor
|
||||
}
|
||||
return FluTheme.itemNormalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.MenuSeparator {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: 188
|
||||
implicitHeight: 1
|
||||
color: FluTheme.dark ? Qt.rgba(60/255,60/255,60/255,1) : Qt.rgba(210/255,210/255,210/255,1)
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextArea{
|
||||
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)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property bool isCtrlEnterForNewline: false
|
||||
id:control
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
padding: 8
|
||||
leftPadding: padding+4
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectedTextColor: color
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
placeholderTextColor: {
|
||||
if(!enabled){
|
||||
return placeholderDisableColor
|
||||
}
|
||||
if(focus){
|
||||
return placeholderFocusColor
|
||||
}
|
||||
return placeholderNormalColor
|
||||
}
|
||||
selectByMouse: true
|
||||
width: 240
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: control
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> d.handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> d.handleCommit(event)
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
if(isCtrlEnterForNewline){
|
||||
if(event.modifiers & Qt.ControlModifier){
|
||||
insert(control.cursorPosition, "\n")
|
||||
return
|
||||
}
|
||||
control.commit(control.text)
|
||||
}else{
|
||||
if(event.modifiers & Qt.ControlModifier){
|
||||
control.commit(control.text)
|
||||
return
|
||||
}
|
||||
insert(control.cursorPosition, "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: {
|
||||
if(control.echoMode === TextInput.Password){
|
||||
return
|
||||
}
|
||||
if(control.readOnly && control.text === ""){
|
||||
return
|
||||
}
|
||||
menu.popup()
|
||||
}
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
default property list<QtObject> children
|
||||
id:control
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int launchMode: FluPageType.SingleTop
|
||||
property bool animDisabled: false
|
||||
property string url : ""
|
||||
signal animationEnd()
|
||||
id: control
|
||||
opacity: visible
|
||||
visible: false
|
||||
StackView.onRemoved: destroy()
|
||||
Behavior on opacity{
|
||||
enabled: !animDisabled && FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
}
|
||||
}
|
||||
transform: Translate {
|
||||
y: control.visible ? 0 : 80
|
||||
Behavior on y{
|
||||
enabled: !animDisabled && FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
visible = true
|
||||
timer.restart()
|
||||
}
|
||||
Timer{
|
||||
id:timer
|
||||
interval: !animDisabled && FluTheme.enableAnimation ? 200 : 0
|
||||
onTriggered: {
|
||||
control.animationEnd()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
signal requestPage(int page,int count)
|
||||
property string previousText: qsTr("<Previous")
|
||||
property string nextText: qsTr("Next>")
|
||||
property int pageCurrent: 0
|
||||
property int itemCount: 0
|
||||
property int pageButtonCount: 5
|
||||
property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0
|
||||
property int __itemPerPage: 10
|
||||
property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1
|
||||
id: control
|
||||
implicitHeight: 40
|
||||
implicitWidth: content.width
|
||||
Row{
|
||||
id: content
|
||||
height: control.height
|
||||
spacing: 10
|
||||
padding: 10
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent<=1
|
||||
text:control.previousText
|
||||
clickListener:function() {
|
||||
control.calcNewPage(control.pageCurrent-1);
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 5
|
||||
FluToggleButton{
|
||||
property int pageNumber:1
|
||||
visible: control.pageCount>0
|
||||
checked: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
clickListener:function() {
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: (control.pageCount>control.pageButtonCount&&
|
||||
control.pageCurrent>control.__pageButtonHalf)
|
||||
text: "..."
|
||||
}
|
||||
Repeater{
|
||||
id: button_repeator
|
||||
model: (control.pageCount<2)?0:(control.pageCount>=control.pageButtonCount)?(control.pageButtonCount-2):(control.pageCount-2)
|
||||
delegate:FluToggleButton{
|
||||
property int pageNumber: {
|
||||
return (control.pageCurrent<=control.__pageButtonHalf)
|
||||
?(2+index)
|
||||
:(control.pageCount-control.pageCurrent<=control.pageButtonCount-control.__pageButtonHalf)
|
||||
?(control.pageCount-button_repeator.count+index)
|
||||
:(control.pageCurrent+2+index-control.__pageButtonHalf)
|
||||
}
|
||||
text:String(pageNumber)
|
||||
checked: pageNumber === control.pageCurrent
|
||||
clickListener:function(){
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: (control.pageCount>control.pageButtonCount&&
|
||||
control.pageCount-control.pageCurrent>control.pageButtonCount-control.__pageButtonHalf)
|
||||
text: "..."
|
||||
}
|
||||
FluToggleButton{
|
||||
property int pageNumber:control.pageCount
|
||||
visible: control.pageCount>1
|
||||
checked: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
clickListener:function(){
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent>=control.pageCount
|
||||
text:control.nextText
|
||||
clickListener:function() {
|
||||
control.calcNewPage(control.pageCurrent+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
function calcNewPage(page)
|
||||
{
|
||||
if(!page)
|
||||
return
|
||||
let page_num=Number(page)
|
||||
if(page_num<1||page_num>control.pageCount||page_num===control.pageCurrent)
|
||||
return
|
||||
control.pageCurrent=page_num
|
||||
control.requestPage(page_num,control.__itemPerPage)
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property var _ext
|
||||
property var _parent
|
||||
property bool visible: true
|
||||
property string title
|
||||
property var url
|
||||
property bool disabled: false
|
||||
property int icon
|
||||
property bool iconVisible: true
|
||||
property Component infoBadge
|
||||
property int count: 0
|
||||
property var onTapListener
|
||||
property Component iconDelegate
|
||||
property Component menuDelegate
|
||||
property Component editDelegate
|
||||
property var extra
|
||||
property bool showEdit
|
||||
signal tap
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property var _ext
|
||||
property var _parent
|
||||
property bool visible: true
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property bool visible: true
|
||||
property string title
|
||||
property var icon
|
||||
property bool disabled: false
|
||||
property bool iconVisible: true
|
||||
property bool isExpand: false
|
||||
property bool showEdit
|
||||
property Component iconDelegate
|
||||
property Component menuDelegate
|
||||
property Component editDelegate
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property bool visible: true
|
||||
property string title
|
||||
property var parent
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property bool visible: true
|
||||
property var parent
|
||||
property real spacing
|
||||
property int size:1
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextField{
|
||||
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)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
id:control
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
padding: 7
|
||||
rightPadding: 40
|
||||
leftPadding: padding+4
|
||||
echoMode:btn_reveal.pressed ? TextField.Normal : TextField.Password
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
selectedTextColor: color
|
||||
placeholderTextColor: {
|
||||
if(!enabled){
|
||||
return placeholderDisableColor
|
||||
}
|
||||
if(focus){
|
||||
return placeholderFocusColor
|
||||
}
|
||||
return placeholderNormalColor
|
||||
}
|
||||
selectByMouse: true
|
||||
width: 240
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: control
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> d.handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> d.handleCommit(event)
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
control.commit(control.text)
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_reveal
|
||||
iconSource:FluentIcons.RevealPasswordMedium
|
||||
iconSize: 10
|
||||
width: 30
|
||||
height: 20
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconColor: FluTheme.dark ? Qt.rgba(222/255,222/255,222/255,1) : Qt.rgba(97/255,97/255,97/255,1)
|
||||
visible: control.text !== ""
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
}
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Page {
|
||||
default property alias content: d.children
|
||||
property alias currentIndex: nav_list.currentIndex
|
||||
property color textNormalColor: FluTheme.dark ? FluColors.Grey120 : FluColors.Grey120
|
||||
property color textHoverColor: FluTheme.dark ? FluColors.Grey10 : FluColors.Black
|
||||
property int textSize: 28
|
||||
property bool textBold: true
|
||||
property int textSpacing: 10
|
||||
property int headerSpacing: 20
|
||||
property int headerHeight: 40
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
implicitHeight: height
|
||||
implicitWidth: width
|
||||
FluObject{
|
||||
id:d
|
||||
property int tabY: control.headerHeight/2+control.textSize/2 + 3
|
||||
}
|
||||
background:Item{}
|
||||
header:ListView{
|
||||
id:nav_list
|
||||
implicitHeight: control.headerHeight
|
||||
implicitWidth: control.width
|
||||
model:d.children
|
||||
spacing: control.headerSpacing
|
||||
interactive: false
|
||||
orientation: ListView.Horizontal
|
||||
highlightMoveDuration: FluTheme.enableAnimation ? 167 : 0
|
||||
highlight: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
height: 3
|
||||
radius: 1.5
|
||||
color: FluTheme.primaryColor
|
||||
width: nav_list.currentItem ? nav_list.currentItem.width : 0
|
||||
y:d.tabY
|
||||
Behavior on width {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: Button{
|
||||
id:item_button
|
||||
width: item_title.width
|
||||
height: nav_list.height
|
||||
focusPolicy:Qt.TabFocus
|
||||
background:Item{
|
||||
FluFocusRectangle{
|
||||
anchors.margins: -4
|
||||
visible: item_button.activeFocus
|
||||
radius:4
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
FluText {
|
||||
id:item_title
|
||||
text: modelData.title
|
||||
anchors.centerIn: parent
|
||||
font.pixelSize: control.textSize
|
||||
font.bold: control.textBold
|
||||
color: {
|
||||
if(item_button.hovered || nav_list.currentIndex === index)
|
||||
return textHoverColor
|
||||
return textNormalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
nav_list.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
Repeater{
|
||||
model:d.children
|
||||
FluLoader{
|
||||
property var argument: modelData.argument
|
||||
anchors.fill: parent
|
||||
sourceComponent: modelData.contentItem
|
||||
visible: nav_list.currentIndex === index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
property string title
|
||||
property Component contentItem
|
||||
property var argument
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Popup {
|
||||
id: control
|
||||
padding: 0
|
||||
modal:true
|
||||
parent: Overlay.overlay
|
||||
x: Math.round((d.parentWidth - width) / 2)
|
||||
y: Math.round((d.parentHeight - height) / 2)
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
from:0
|
||||
to:1
|
||||
}
|
||||
}
|
||||
height:Math.min(implicitHeight,d.parentHeight)
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
from:1
|
||||
to:0
|
||||
}
|
||||
}
|
||||
background: FluRectangle{
|
||||
radius: [5,5,5,5]
|
||||
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property int parentHeight: {
|
||||
if(control.parent){
|
||||
return control.parent.height
|
||||
}
|
||||
return control.height
|
||||
}
|
||||
property int parentWidth: {
|
||||
if(control.parent){
|
||||
return control.parent.width
|
||||
}
|
||||
return control.width
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
ProgressBar{
|
||||
property int duration: 888
|
||||
property real strokeWidth: 6
|
||||
property bool progressVisible: false
|
||||
property color color: FluTheme.primaryColor
|
||||
property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
|
||||
id:control
|
||||
indeterminate : true
|
||||
QtObject{
|
||||
id:d
|
||||
property real _radius: strokeWidth/2
|
||||
}
|
||||
onIndeterminateChanged:{
|
||||
if(!indeterminate){
|
||||
animator_x.duration = 0
|
||||
rect_progress.x = 0
|
||||
animator_x.duration = control.duration
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
implicitHeight: control.strokeWidth
|
||||
color: control.backgroundColor
|
||||
radius: d._radius
|
||||
}
|
||||
contentItem: FluClip {
|
||||
clip: true
|
||||
radius: [d._radius,d._radius,d._radius,d._radius]
|
||||
Rectangle {
|
||||
id:rect_progress
|
||||
width: {
|
||||
if(control.indeterminate){
|
||||
return 0.5 * parent.width
|
||||
}
|
||||
return control.visualPosition * parent.width
|
||||
}
|
||||
height: parent.height
|
||||
radius: d._radius
|
||||
color: control.color
|
||||
PropertyAnimation on x {
|
||||
id:animator_x
|
||||
running: control.indeterminate && control.visible
|
||||
from: -rect_progress.width
|
||||
to:control.width+rect_progress.width
|
||||
loops: Animation.Infinite
|
||||
duration: control.duration
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:(control.visualPosition * 100).toFixed(0) + "%"
|
||||
visible: {
|
||||
if(control.indeterminate){
|
||||
return false
|
||||
}
|
||||
return control.progressVisible
|
||||
}
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: control.width+5
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user