Compare commits

...

14 Commits
1.1.6 ... 1.1.8

Author SHA1 Message Date
6391fc8dc6 update 2023-04-01 21:51:59 +08:00
9cf4b4b1af update 2023-04-01 21:42:32 +08:00
32c0b4ccd6 update 2023-04-01 21:37:07 +08:00
b2bfdd17da update 2023-04-01 21:06:39 +08:00
27db8160d4 update 2023-04-01 21:01:46 +08:00
ed0c9048b0 update 2023-04-01 10:22:05 +08:00
de2c891912 Create License 2023-04-01 09:31:18 +08:00
16daeb5268 update 2023-03-31 22:54:23 +08:00
0b37ddcb6e update 2023-03-31 22:05:25 +08:00
d2e3e6dd4b update 2023-03-31 18:11:55 +08:00
1e5bd75123 update 2023-03-31 17:59:20 +08:00
1b97b197a4 update 2023-03-31 13:03:36 +08:00
936a310ca6 update 2023-03-31 11:58:15 +08:00
3236be8a7f update 2023-03-30 23:25:48 +08:00
41 changed files with 883 additions and 545 deletions

View File

@ -35,7 +35,7 @@ jobs:
version: ${{ matrix.qt_ver }}
cached: 'false'
arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools'
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
- uses: actions/checkout@v2
with:
fetch-depth: 1

View File

@ -30,7 +30,7 @@ jobs:
version: ${{ matrix.qt_ver }}
cached: 'false'
arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools'
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
- name: ubuntu install GL library
run: sudo apt-get install -y libglew-dev libglfw3-dev qml-module-qtquick-controls qml-module-qtquick-controls2
- uses: actions/checkout@v2

View File

@ -38,7 +38,7 @@ jobs:
version: ${{ matrix.qt_ver }}
arch: ${{ matrix.qt_arch }}
cached: 'false'
modules: 'qt5compat qtmultimedia qtshadertools'
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
# 拉取代码
- uses: actions/checkout@v2
with:

3
.gitignore vendored
View File

@ -32,4 +32,5 @@ target_wrapper.*
CMakeLists.txt.user*
src/build-preset/plugins.qmltypes
bin
bin
.DS_Store

4
CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)
project(FluentUI VERSION 0.1 LANGUAGES CXX)
add_subdirectory(src)
add_subdirectory(example)

21
License Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 zhuzichu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -2,11 +2,14 @@
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import QtMultimedia
import FluentUI
Window {
id:app
color: "#00000000"
//初始化一个MediaPlayer解决macos切换到T_MediaPalyer页面崩溃问题
MediaPlayer{}
Component.onCompleted: {
FluApp.init(app,properties)
FluTheme.frameless = ("windows" === Qt.platform.os)
@ -16,6 +19,7 @@ Window {
"/about":"qrc:/page/AboutPage.qml",
"/login":"qrc:/page/LoginPage.qml",
"/chat":"qrc:/page/ChatPage.qml",
"/media":"qrc:/page/MediaPage.qml",
}
FluApp.initialRoute = "/"
FluApp.run()

69
example/CMakeLists.txt Normal file
View File

@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 3.16)
project(example)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED)
set(SOURCES
ChatController.cpp
main.cpp
)
set(HEADERS
ChatController.h
)
set(RESOURCES
qml.qrc
)
set(RC_ICONS
favicon.ico
)
qt_add_resources(QT_RESOURCES ${RESOURCES})
if(WIN32)
if(QT_ARCH EQUAL 32)
set(COPYDLL ${CMAKE_CURRENT_SOURCE_DIR}/../third/Win_x86/*.dll ${DESTDIR})
else()
set(COPYDLL ${CMAKE_CURRENT_SOURCE_DIR}/../third/Win_x64/*.dll ${DESTDIR})
endif()
if(QMAKE_CC STREQUAL "cl")
set(QMAKE_PRE_LINK "${QMAKE_COPY} ${COPYDLL}")
else()
set(QMAKE_PRE_LINK "${QMAKE_COPY} ${COPYDLL}")
endif()
endif()
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QT_RESOURCES} ${RC_ICONS})
target_compile_definitions(${PROJECT_NAME} PRIVATE
QT_DEPRECATED_WARNINGS
QT_NO_WARNING_OUTPUT
)
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Core
Qt6::Quick
Qt6::QuickControls2
Qt6::Concurrent
Qt6::Network
Qt6::Multimedia
)
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE WIN32 _WINDOWS)
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
endif()
if(APPLE)
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST Info.plist
)
endif()

View File

@ -129,7 +129,7 @@ FluScrollablePage{
id:item_mouse
anchors.fill: parent
hoverEnabled: true
onWheel: {
onWheel: (wheel)=>{
if (wheel.angleDelta.y > 0) scrollbar_header.decrease()
else scrollbar_header.increase()
}
@ -142,20 +142,6 @@ FluScrollablePage{
}
}
ListModel{
id:model_added
Component.onCompleted: {
append(ItemsOriginal.getRecentlyAddedData())
}
}
ListModel{
id:model_update
Component.onCompleted: {
append(ItemsOriginal.getRecentlyUpdatedData())
}
}
Component{
id:com_item
Item{
@ -187,7 +173,7 @@ FluScrollablePage{
id:item_icon
height: 40
width: 40
source: model.image
source: modelData.image
anchors{
left: parent.left
leftMargin: 20
@ -197,7 +183,7 @@ FluScrollablePage{
FluText{
id:item_title
text:model.title
text:modelData.title
fontStyle: FluText.BodyStrong
anchors{
left: item_icon.right
@ -208,7 +194,7 @@ FluScrollablePage{
FluText{
id:item_desc
text:model.desc
text:modelData.desc
color:FluColors.Grey120
wrapMode: Text.WrapAnywhere
elide: Text.ElideRight
@ -241,7 +227,7 @@ FluScrollablePage{
anchors.fill: parent
hoverEnabled: true
onClicked: {
ItemsOriginal.startPageByItem(model)
ItemsOriginal.startPageByItem(modelData)
}
}
}
@ -260,7 +246,7 @@ FluScrollablePage{
implicitHeight: contentHeight
cellHeight: 120
cellWidth: 320
model:model_added
model:ItemsOriginal.getRecentlyAddedData()
interactive: false
delegate: com_item
}
@ -278,7 +264,7 @@ FluScrollablePage{
cellHeight: 120
cellWidth: 320
interactive: false
model: model_update
model: ItemsOriginal.getRecentlyUpdatedData()
delegate: com_item
}

View File

@ -31,11 +31,26 @@ FluScrollablePage{
}
FluMediaPlayer{
id:player
// source:"http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4"
source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
// source:"http://video.chinanews.com/flv/2019/04/23/400/111773_web.mp4"
}
}
}
FluArea{
width: parent.width
height: 68
Layout.topMargin: 20
paddings: 10
FluButton{
text:"跳转到视频播放器窗口"
anchors.verticalCenter: parent.verticalCenter
onClicked:{
FluApp.navigate("/media",{source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"})
}
}
}
}

View File

@ -17,7 +17,7 @@ FluScrollablePage{
Layout.preferredWidth: 300
disabled:toggle_switch.selected
}
FluMultiLineTextBox{
FluMultilineTextBox{
Layout.topMargin: 20
Layout.preferredWidth: 300
placeholderText: "多行输入框"

View File

@ -1,5 +1,5 @@
QT += quick quickcontrols2 concurrent network multimedia
CONFIG += c++11
QT += quick quickcontrols2 concurrent network multimedia
CONFIG += c++17
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
HEADERS += \

View File

@ -16,224 +16,222 @@ FluObject{
}
}
FluPaneItemHeader{
title:"Inputs"
}
FluPaneItemExpander{
title:"Basic input"
icon:FluentIcons.CheckboxComposite
FluPaneItem{
title:"Buttons"
image:"qrc:/res/image/control/Button.png"
recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event."
onTap:{
navigationView.push("qrc:/T_Buttons.qml")
FluPaneItem{
title:"Buttons"
image:"qrc:/res/image/control/Button.png"
recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event."
onTap:{
navigationView.push("qrc:/T_Buttons.qml")
}
}
FluPaneItem{
title:"Slider"
image:"qrc:/res/image/control/Slider.png"
recentlyUpdated:true
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
onTap:{
navigationView.push("qrc:/T_Slider.qml")
}
}
FluPaneItem{
title:"CheckBox"
image:"qrc:/res/image/control/Checkbox.png"
recentlyUpdated:true
desc:"A control that a user can select or clear."
onTap:{
navigationView.push("qrc:/T_CheckBox.qml")
}
}
FluPaneItem{
title:"ToggleSwitch"
onTap:{
navigationView.push("qrc:/T_ToggleSwitch.qml")
}
}
}
FluPaneItem{
title:"Slider"
image:"qrc:/res/image/control/Slider.png"
recentlyUpdated:true
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
onTap:{
navigationView.push("qrc:/T_Slider.qml")
}
}
FluPaneItem{
title:"CheckBox"
image:"qrc:/res/image/control/Checkbox.png"
recentlyUpdated:true
desc:"A control that a user can select or clear."
onTap:{
navigationView.push("qrc:/T_CheckBox.qml")
}
}
FluPaneItem{
title:"ToggleSwitch"
onTap:{
navigationView.push("qrc:/T_ToggleSwitch.qml")
}
}
FluPaneItemHeader{
FluPaneItemExpander{
title:"Form"
}
FluPaneItem{
title:"TextBox"
onTap:{
navigationView.push("qrc:/T_TextBox.qml")
icon:FluentIcons.GridView
FluPaneItem{
title:"TextBox"
onTap:{
navigationView.push("qrc:/T_TextBox.qml")
}
}
FluPaneItem{
title:"TimePicker"
onTap:{
navigationView.push("qrc:/T_TimePicker.qml")
}
}
FluPaneItem{
title:"DatePicker"
onTap:{
navigationView.push("qrc:/T_DatePicker.qml")
}
}
FluPaneItem{
title:"CalendarPicker"
onTap:{
navigationView.push("qrc:/T_CalendarPicker.qml")
}
}
FluPaneItem{
title:"ColorPicker"
onTap:{
navigationView.push("qrc:/T_ColorPicker.qml")
}
}
}
FluPaneItem{
title:"TimePicker"
onTap:{
navigationView.push("qrc:/T_TimePicker.qml")
}
}
FluPaneItem{
title:"DatePicker"
onTap:{
navigationView.push("qrc:/T_DatePicker.qml")
}
}
FluPaneItem{
title:"CalendarPicker"
onTap:{
navigationView.push("qrc:/T_CalendarPicker.qml")
}
}
FluPaneItem{
title:"ColorPicker"
onTap:{
navigationView.push("qrc:/T_ColorPicker.qml")
}
}
FluPaneItemHeader{
FluPaneItemExpander{
title:"Surface"
}
icon:FluentIcons.SurfaceHub
FluPaneItem{
title:"InfoBar"
image:"qrc:/res/image/control/InfoBar.png"
recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information."
onTap:{
navigationView.push("qrc:/T_InfoBar.qml")
FluPaneItem{
title:"InfoBar"
image:"qrc:/res/image/control/InfoBar.png"
recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information."
onTap:{
navigationView.push("qrc:/T_InfoBar.qml")
}
}
}
FluPaneItem{
title:"Progress"
onTap:{
navigationView.push("qrc:/T_Progress.qml")
FluPaneItem{
title:"Progress"
onTap:{
navigationView.push("qrc:/T_Progress.qml")
}
}
}
FluPaneItem{
title:"Badge"
onTap:{
navigationView.push("qrc:/T_Badge.qml")
FluPaneItem{
title:"Badge"
onTap:{
navigationView.push("qrc:/T_Badge.qml")
}
}
}
FluPaneItem{
title:"Rectangle"
onTap:{
navigationView.push("qrc:/T_Rectangle.qml")
FluPaneItem{
title:"Rectangle"
onTap:{
navigationView.push("qrc:/T_Rectangle.qml")
}
}
}
FluPaneItem{
title:"Carousel"
onTap:{
navigationView.push("qrc:/T_Carousel.qml")
FluPaneItem{
title:"Carousel"
onTap:{
navigationView.push("qrc:/T_Carousel.qml")
}
}
}
FluPaneItem{
title:"Expander"
onTap:{
navigationView.push("qrc:/T_Expander.qml")
FluPaneItem{
title:"Expander"
onTap:{
navigationView.push("qrc:/T_Expander.qml")
}
}
}
FluPaneItemHeader{
FluPaneItemExpander{
title:"Popus"
}
icon:FluentIcons.ButtonMenu
FluPaneItem{
title:"Dialog"
onTap:{
navigationView.push("qrc:/T_Dialog.qml")
}
}
FluPaneItem{
title:"Dialog"
onTap:{
navigationView.push("qrc:/T_Dialog.qml")
FluPaneItem{
title:"Tooltip"
onTap:{
navigationView.push("qrc:/T_Tooltip.qml")
}
}
FluPaneItem{
title:"Menu"
onTap:{
navigationView.push("qrc:/T_Menu.qml")
}
}
}
FluPaneItem{
title:"Tooltip"
onTap:{
navigationView.push("qrc:/T_Tooltip.qml")
}
}
FluPaneItem{
title:"Menu"
onTap:{
navigationView.push("qrc:/T_Menu.qml")
}
}
FluPaneItemHeader{
FluPaneItemExpander{
title:"Navigation"
}
FluPaneItem{
title:"TabView"
image:"qrc:/res/image/control/TabView.png"
recentlyAdded:true
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
onTap:{
navigationView.push("qrc:/T_TabView.qml")
icon:FluentIcons.AllApps
FluPaneItem{
title:"TabView"
image:"qrc:/res/image/control/TabView.png"
recentlyAdded:true
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
onTap:{
navigationView.push("qrc:/T_TabView.qml")
}
}
FluPaneItem{
title:"TreeView"
onTap:{
navigationView.push("qrc:/T_TreeView.qml")
}
}
}
FluPaneItem{
title:"TreeView"
onTap:{
navigationView.push("qrc:/T_TreeView.qml")
FluPaneItem{
title:"MultiWindow"
onTap:{
navigationView.push("qrc:/T_MultiWindow.qml")
}
}
}
FluPaneItem{
title:"MultiWindow"
onTap:{
navigationView.push("qrc:/T_MultiWindow.qml")
}
}
FluPaneItemHeader{
FluPaneItemExpander{
title:"Theming"
}
icon:FluentIcons.Brightness
FluPaneItem{
title:"Theme"
onTap:{
navigationView.push("qrc:/T_Theme.qml")
}
}
FluPaneItem{
title:"Theme"
onTap:{
navigationView.push("qrc:/T_Theme.qml")
FluPaneItem{
title:"Awesome"
onTap:{
navigationView.push("qrc:/T_Awesome.qml")
}
}
FluPaneItem{
title:"Typography"
onTap:{
navigationView.push("qrc:/T_Typography.qml")
}
}
}
FluPaneItem{
title:"Awesome"
onTap:{
navigationView.push("qrc:/T_Awesome.qml")
}
}
FluPaneItem{
title:"Typography"
onTap:{
navigationView.push("qrc:/T_Typography.qml")
}
}
FluPaneItemHeader{
FluPaneItemExpander{
title:"Media"
}
FluPaneItem{
title:"MediaPlayer"
image:"qrc:/res/image/control/MediaPlayerElement.png"
recentlyAdded:true
desc:"A control to display video and image content."
onTap:{
navigationView.push("qrc:/T_MediaPlayer.qml")
icon:FluentIcons.Media
FluPaneItem{
title:"MediaPlayer"
image:"qrc:/res/image/control/MediaPlayerElement.png"
recentlyAdded:true
desc:"A control to display video and image content."
onTap:{
navigationView.push("qrc:/T_MediaPlayer.qml")
}
}
}
@ -244,14 +242,23 @@ FluObject{
if(item instanceof FluPaneItem && item.recentlyAdded){
arr.push(item)
}
if(item instanceof FluPaneItemExpander){
for(var j=0;j<item.children.length;j++){
var itemChild = item.children[j]
if(itemChild instanceof FluPaneItem && itemChild.recentlyAdded){
arr.push(itemChild)
}
}
}
}
return arr
}
function getRecentlyUpdatedData(){
var arr = []
for(var i=0;i<children.length;i++){
var item = children[i]
var items = navigationView.getItems();
for(var i=0;i<items.length;i++){
var item = items[i]
if(item instanceof FluPaneItem && item.recentlyUpdated){
arr.push(item)
}
@ -261,8 +268,9 @@ FluObject{
function getSearchData(){
var arr = []
for(var i=0;i<children.length;i++){
var item = children[i]
var items = navigationView.getItems();
for(var i=0;i<items.length;i++){
var item = items[i]
if(item instanceof FluPaneItem){
arr.push({title:item.title,key:item.key})
}
@ -270,14 +278,19 @@ FluObject{
return arr
}
function startPageByItem(item){
for(var i=0;i<children.length;i++){
if(children[i].key === item.key){
function startPageByItem(data){
var items = navigationView.getItems();
for(var i=0;i<items.length;i++){
var item = items[i]
if(item.key === data.key){
if(navigationView.getCurrentIndex() === i){
return
}
children[i].tap()
item.tap()
navigationView.setCurrentIndex(i)
if(item.parent){
item.parent.isExpand = true
}
return
}
}

View File

@ -18,7 +18,6 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationName("ZhuZiChu");
QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io");
QCoreApplication::setApplicationName("FluentUI");
// QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
QQuickStyle::setStyle("Basic");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;

View File

@ -36,7 +36,7 @@ FluWindow {
fontStyle: FluText.Title
}
FluText{
text:"v1.1.6"
text:"v1.1.8"
fontStyle: FluText.Body
Layout.alignment: Qt.AlignBottom
}

View File

@ -1,5 +1,6 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import FluentUI
FluWindow {

View File

@ -20,7 +20,6 @@ FluWindow {
width:parent.width
}
FluNavigationView{
id:nav_view
anchors.fill: parent

View File

@ -0,0 +1,37 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
FluWindow {
width: 640
height: 480
minimumWidth: 640
minimumHeight: 480
title:"视频播放器"
onInitArgument:
(argument)=>{
player.source = argument.source
}
FluAppBar{
id:appbar
title:"视频播放器"
width:parent.width
}
FluMediaPlayer{
id:player
anchors{
left: parent.left
right: parent.right
top: appbar.bottom
bottom: parent.bottom
}
}
}

View File

@ -152,5 +152,6 @@
<file>global/ItemsOriginal.qml</file>
<file>global/qmldir</file>
<file>global/ItemsFooter.qml</file>
<file>page/MediaPage.qml</file>
</qresource>
</RCC>

67
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.16)
project(FluentUI)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 COMPONENTS Core Quick Svg REQUIRED)
set(QT_INSTALL_QML ${Qt6Core_DIR}/../../../qml)
set(TARGET_TYPE SHARED)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
set(TARGET_RESOURCES res.qrc)
set(TARGET_SOURCES
Def.cpp
FluApp.cpp
FluColorSet.cpp
FluColors.cpp
FluRegister.cpp
FluTheme.cpp
Fluent.cpp
FluentUI.cpp
WindowHelper.cpp
qml_plugin.cpp
)
set(TARGET_HEADERS
Def.h
FluApp.h
FluColorSet.h
FluColors.h
FluRegister.h
FluTheme.h
Fluent.h
FluentUI.h
FramelessView.h
WindowHelper.h
qml_plugin.h
stdafx.h
)
if(WIN32)
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_win.cpp)
else()
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_unix.cpp)
endif()
add_library(${PROJECT_NAME} ${TARGET_TYPE} ${TARGET_SOURCES} ${TARGET_HEADERS} ${TARGET_RESOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
target_compile_definitions(${PROJECT_NAME} PRIVATE VERSION_IN=\\\"1.0.0\\\" URI_STR=\\\"FluentUI\\\")
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
else()
endif()
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick Qt6::Svg)
if(WIN32)
include(build_windows.cmake)
else()
include(build_macos.cmake)
endif()

View File

@ -22,7 +22,7 @@ Fluent *Fluent::getInstance()
QString Fluent::version() const
{
return QStringLiteral(VERSION_IN);
return QStringLiteral("1.0.0");
}
void Fluent::registerTypes(const char *uri){
@ -32,6 +32,8 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper");
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemExpander.qml"),uri,major,minor,"FluPaneItemExpander");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTabView.qml"),uri,major,minor,"FluTabView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluArea.qml"),uri,major,minor,"FluArea");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluBadge.qml"),uri,major,minor,"FluBadge");
@ -57,7 +59,7 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextButton.qml"),uri,major,minor,"FluTextButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultiLineTextBox.qml"),uri,major,minor,"FluMultiLineTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultilineTextBox.qml"),uri,major,minor,"FluMultilineTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTooltip.qml"),uri,major,minor,"FluTooltip");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDivider.qml"),uri,major,minor,"FluDivider");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIcon.qml"),uri,major,minor,"FluIcon");

View File

@ -1,5 +1,5 @@
QT += qml quick svg
CONFIG += plugin c++11
CONFIG += plugin c++17
TEMPLATE = lib
TARGET = FluentUI
TARGET = $$qtLibraryTarget($$TARGET)

32
src/build_macos.cmake Normal file
View File

@ -0,0 +1,32 @@
set(OUTP ${CMAKE_BINARY_DIR}/bin/FluentUI/)
add_definitions(-DMACOS)
set(CMAKE_INSTALL_PREFIX ${OUTP})
set(CMAKE_INSTALL_DESTDIR ${OUTP})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(QMAKE_MOC_OPTIONS -Muri=${uri})
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND chmod -R 777 ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh
)
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh PRESET ${CMAKE_CURRENT_SOURCE_DIR}/ ${OUTP}
)
if(${TARGET_TYPE} STREQUAL "SHARED")
set(INST_QMLPATH ${QT_INSTALL_QML}/FluentUI)
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/ ${OUTP} ${INST_QMLPATH}
)
endif()

27
src/build_windows.cmake Normal file
View File

@ -0,0 +1,27 @@
set(OUTP "${CMAKE_BINARY_DIR}/bin/FluentUI")
set(BUILDBIN_PATH "${OUTP}")
set(QTQMLFLUENT_PATH "${QT_INSTALL_QML}/FluentUI")
set(PRESET_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build-preset")
set(SOLIBFILE_PATH "${CMAKE_BINARY_DIR}/libFluentUI.so")
set(ANDROID NO)
if (ANDROID)
set(ANDROID YES)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTP})
else()
set(CMAKE_INSTALL_PREFIX "${OUTP}")
endif()
set(SHAREDSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/win_install.bat SHARED ${CMAKE_CURRENT_SOURCE_DIR} ${PRESET_PATH} ${BUILDBIN_PATH} ${QTQMLFLUENT_PATH} ${ANDROID} ${SOLIBFILE_PATH})
set(STATICSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/win_install.bat STATIC ${CMAKE_CURRENT_SOURCE_DIR} ${PRESET_PATH} ${BUILDBIN_PATH} ${QTQMLFLUENT_PATH} ${ANDROID} ${SOLIBFILE_PATH})
string(REPLACE "/" "\\" SHAREDSCRIPT "${SHAREDSCRIPT}")
string(REPLACE "/" "\\" STATICSCRIPT "${STATICSCRIPT}")
if (${TARGET_TYPE} STREQUAL "SHARED")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${SHAREDSCRIPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
else()
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${STATICSCRIPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endif()

View File

@ -1,5 +1,8 @@
OUTP = $$OUT_PWD/../bin/FluentUI
BUILDBIN_PATH = $$replace(OUTP, src/../bin, bin)
message("----------------->")
message($$OUTP)
message($$BUILDBIN_PATH)
QTQMLFLUENT_PATH = $$[QT_INSTALL_QML]/FluentUI
PRESET_PATH = $$PWD/build-preset
SOLIBFILE_PATH = $$OUT_PWD/libFluentUI.so
@ -15,6 +18,8 @@ android{
SHAREDSCRIPT = "$$PWD\win_install.bat" SHARED "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
STATICSCRIPT = "$$PWD\win_install.bat" STATIC "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
message("-------------------------")
message($$SHAREDSCRIPT)
CONFIG(sharedlib){
QMAKE_POST_LINK *= $$replace(SHAREDSCRIPT, /, \\)
}

View File

@ -30,10 +30,10 @@ Item {
pickerCursor.y = Math.max(0, Math.min(height, mouse.y)-cursorHeight)
}
}
onPositionChanged: {
onPositionChanged:(mouse)=> {
handleMouse(mouse)
}
onPressed: handleMouse(mouse)
onPressed:(mouse)=> handleMouse(mouse)
}
function setValue(val) {

View File

@ -7,23 +7,35 @@ import FluentUI
Rectangle{
property string title: ""
property string darkText : "夜间模式"
property string minimizeText : "最小化"
property string restoreText : "向下还原"
property string maximizeText : "最大化"
property string closeText : "关闭"
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
property color minimizeNormalColor: Qt.rgba(0,0,0,0)
property color minimizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
property color maximizeNormalColor: Qt.rgba(0,0,0,0)
property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
property color closeNormalColor: Qt.rgba(0,0,0,0)
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
property bool showDark: false
property bool showFps: false
property var window: Window.window
property color borerlessColor : FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
property bool resizable: {
if(window == null){
return false
}
return !(window.minimumHeight === window.maximumHeight && window.maximumWidth === window.minimumWidth)
Item{
id:d
property var win: Window.window
property bool isRestore: win && Window.Maximized === win.visibility
property bool resizable: win && !(win.minimumHeight === win.maximumHeight && win.maximumWidth === win.minimumWidth)
}
id:root
color: Qt.rgba(0,0,0,0)
visible: FluTheme.frameless
height: visible ? 30 : 0
clip: true
opacity: visible
z: 65535
TapHandler {
@ -34,7 +46,7 @@ Rectangle{
DragHandler {
target: null
grabPermissions: TapHandler.CanTakeOverFromAnything
onActiveChanged: if (active) { window.startSystemMove(); }
onActiveChanged: if (active) { d.win.startSystemMove(); }
}
FluText {
@ -55,13 +67,6 @@ Rectangle{
height: root.height
spacing: 0
TFpsMonitor{
Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: 20
Layout.topMargin: 5
color:root.textColor
visible: showFps
}
RowLayout{
Layout.alignment: Qt.AlignVCenter
@ -69,7 +74,7 @@ Rectangle{
visible: showDark
spacing: 5
FluText{
text:"夜间模式"
text:darkText
color:root.textColor
}
FluToggleSwitch{
@ -86,53 +91,24 @@ Rectangle{
iconSource : FluentIcons.ChromeMinimize
Layout.alignment: Qt.AlignVCenter
iconSize: 11
text:"最小化"
text:minimizeText
radius: 0
textColor: root.textColor
color:{
if(FluTheme.dark){
if(hovered){
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(hovered){
return Qt.rgba(0,0,0,0.06)
}
return Qt.rgba(0,0,0,0)
}
}
color: hovered ? minimizeHoverColor : minimizeNormalColor
onClicked: {
window.showMinimized()
d.win.showMinimized()
}
}
FluIconButton{
width: 40
height: 30
property bool isRestore:{
if(window == null)
return false
return Window.Maximized === window.visibility
}
iconSource : isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
color:{
if(FluTheme.dark){
if(hovered){
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(hovered){
return Qt.rgba(0,0,0,0.06)
}
return Qt.rgba(0,0,0,0)
}
}
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
color: hovered ? maximizeHoverColor : maximizeNormalColor
Layout.alignment: Qt.AlignVCenter
visible: resizable
visible: d.resizable
radius: 0
textColor: root.textColor
text:isRestore?"向下还原":"最大化"
text:d.isRestore?restoreText:maximizeText
iconSize: 11
onClicked: {
toggleMaximized()
@ -141,26 +117,26 @@ Rectangle{
FluIconButton{
iconSource : FluentIcons.ChromeClose
Layout.alignment: Qt.AlignVCenter
text:"关闭"
text:closeText
width: 40
height: 30
radius: 0
iconSize: 10
textColor: hovered ? Qt.rgba(1,1,1,1) : root.textColor
color:hovered ? Qt.rgba(251/255,115/255,115/255,1) : "#00000000"
color:hovered ? closeHoverColor : closeNormalColor
onClicked: {
Window.window.close()
d.win.close()
}
}
}
function toggleMaximized() {
if(!resizable)
if(!d.resizable)
return
if (window.visibility === Window.Maximized) {
window.showNormal();
if (d.win.visibility === Window.Maximized) {
d.win.showNormal();
} else {
window.showMaximized();
d.win.showMaximized();
}
}

View File

@ -6,34 +6,40 @@ TextField{
property var items:[]
property int fontStyle: FluText.Body
property string emptyText: "没有找到结果"
property int pixelSize : FluTheme.textSize
property int iconSource: 0
property bool disabled: false
signal itemClicked(var data)
signal handleClicked
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)
QtObject{
id:d
property bool flagVisible: true
}
id:input
id:control
width: 300
enabled: !disabled
color: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return disableColor
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
return normalColor
}
selectionColor: FluTheme.primaryColor.lightest
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
placeholderTextColor: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return placeholderDisableColor
}
if(focus){
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
return placeholderFocusColor
}
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
return placeholderNormalColor
}
rightPadding: icon_right.visible ? 50 : 30
selectByMouse: true
@ -92,27 +98,25 @@ TextField{
width: 20
height: 20
opacity: 0.5
visible: input.text !== ""
visible: control.text !== ""
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: icon_right.visible ? 25 : 5
}
onClicked:{
input.text = ""
control.text = ""
}
}
background: FluTextBoxBackground{
inputItem: input
inputItem: control
FluIcon{
id:icon_right
iconSource: input.iconSource
iconSource: control.iconSource
iconSize: 15
opacity: 0.5
visible: input.iconSource != 0
visible: control.iconSource != 0
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
@ -122,18 +126,18 @@ TextField{
}
Component.onCompleted: {
searchData()
loadData()
}
Popup{
id:input_popup
y:input.height
id:control_popup
y:control.height
focus: false
enter: Transition {
NumberAnimation {
property: "y"
from:0
to:input_popup.y
to:control_popup.y
duration: 150
}
NumberAnimation {
@ -149,7 +153,7 @@ TextField{
}
}
background: Rectangle{
width: input.width
width: control.width
radius: 4
FluShadow{
radius: 4
@ -163,11 +167,11 @@ TextField{
currentIndex: -1
ScrollBar.vertical: FluScrollBar {}
header: Item{
width: input.width
width: control.width
height: visible ? 38 : 0
visible: list_view.count === 0
FluText{
text:"没有找到结果"
text:emptyText
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
@ -176,7 +180,7 @@ TextField{
}
}
delegate:Control{
width: input.width
width: control.width
padding:10
background: Rectangle{
color: {
@ -192,7 +196,7 @@ TextField{
id:mouse_area
anchors.fill: parent
Connections{
target: input
target: control
function onHandleClicked(){
if((list_view.currentIndex === index)){
handleClick(modelData)
@ -223,72 +227,41 @@ TextField{
}
}
}
onTextChanged: {
loadData()
if(d.flagVisible){
control_popup.visible = true
}
}
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluTextBoxMenu{
id:menu
inputItem: control
}
function handleClick(modelData){
input_popup.visible = false
input.itemClicked(modelData)
control_popup.visible = false
control.itemClicked(modelData)
updateText(modelData.title)
}
function updateText(text){
d.flagVisible = false
input.text = text
control.text = text
d.flagVisible = true
}
onTextChanged: {
searchData()
if(d.flagVisible){
input_popup.visible = true
}
}
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: input.echoMode !== TextInput.Password && menu.popup()
}
FluMenu{
id:menu
focus: false
FluMenuItem{
text: "剪切"
visible: input.text !== ""
onClicked: {
input.cut()
}
}
FluMenuItem{
text: "复制"
visible: input.selectedText !== ""
onClicked: {
input.copy()
}
}
FluMenuItem{
text: "粘贴"
visible: input.canPaste
onClicked: {
input.paste()
}
}
FluMenuItem{
text: "全选"
visible: input.text !== ""
onClicked: {
input.selectAll()
}
}
}
function searchData(){
function loadData(){
var result = []
if(items==null){
list_view.model = result
return
}
items.map(function(item){
if(item.title.indexOf(input.text)!==-1){
if(item.title.indexOf(control.text)!==-1){
result.push(item)
}
})

View File

@ -9,9 +9,10 @@ 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: "请选择日期"
property var window : Window.window
id:root
id:control
color: {
if(mouse_area.containsMouse){
return hoverColor
@ -44,7 +45,7 @@ Rectangle {
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text:"请选择日期"
text:control.text
}
FluIcon{
@ -95,15 +96,15 @@ Rectangle {
}
background: Item{}
function showPopup() {
var pos = root.mapToItem(null, 0, 0)
if(window.height>pos.y+root.height+popup.height){
popup.y = root.height
var pos = control.mapToItem(null, 0, 0)
if(window.height>pos.y+control.height+popup.height){
popup.y = control.height
} else if(pos.y>popup.height){
popup.y = -popup.height
} else {
popup.y = window.height-(pos.y+popup.height)
}
popup.x = -(popup.width-root.width)/2
popup.x = -(popup.width-control.width)/2
popup.open()
}
}

View File

@ -28,7 +28,9 @@ Rectangle {
property bool autoSeek:true
source: control.source
videoOutput: video_output
audioOutput:audio_output
audioOutput: AudioOutput{
id:audio_output
}
onErrorChanged:
(error)=> {
console.debug(error)
@ -41,10 +43,9 @@ Rectangle {
onMediaStatusChanged:
(status)=> {
if(status===2){
mediaplayer.play()
}else if(status===5){
slider.maxValue = mediaplayer.duration
showControl = true
mediaplayer.play()
}
}
}
@ -53,10 +54,6 @@ Rectangle {
slider.seek(0)
}
AudioOutput{
id:audio_output
}
VideoOutput {
id:video_output
anchors.fill: parent
@ -66,21 +63,23 @@ Rectangle {
height: 100
y:showControl ? control.height - 110 : control.height
anchors{
left: parent.left
right: parent.right
leftMargin: 10
rightMargin: 10
horizontalCenter: parent.horizontalCenter
}
width: 460
opacity: showControl
MouseArea{
anchors.fill: parent
}
Behavior on opacity{
NumberAnimation{
duration: 150
}
}
Behavior on y{
NumberAnimation{
duration: 150
}
}
Rectangle{
anchors.fill: parent
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
@ -102,13 +101,11 @@ Rectangle {
mediaplayer.autoSeek = true
mediaplayer.play()
}
onValueChanged: {
if(mediaplayer.autoSeek == false){
mediaplayer.position = value*mediaplayer.duration/slider.maxValue
}
}
onLineClickFunc:function(val){
mediaplayer.position = val*mediaplayer.duration/slider.maxValue
}
@ -170,11 +167,10 @@ Rectangle {
}
}
FluIconButton{
id:btn_volume
iconSize: 17
iconSource: audio_output.volume ? FluentIcons.Volume : FluentIcons.Mute
iconSource: audio_output.muted ? FluentIcons.Mute : FluentIcons.Volume
anchors{
left: parent.left
leftMargin: 5
@ -182,7 +178,7 @@ Rectangle {
bottomMargin: 10
}
onClicked: {
audio_output.volume = !audio_output.volume
audio_output.muted = !audio_output.muted
}
}
@ -200,7 +196,6 @@ Rectangle {
audio_output.volume = value/100
}
}
}
function formatDuration(duration) {

View File

@ -7,31 +7,32 @@ TextArea{
property int fontStyle: FluText.Body
property int pixelSize : FluTheme.textSize
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)
id:input
id:control
width: 300
enabled: !disabled
color: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return disableColor
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
return normalColor
}
enabled: !disabled
wrapMode: Text.WrapAnywhere
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectByMouse: true
selectionColor: FluTheme.primaryColor.lightest
background: FluTextBoxBackground{
inputItem: input
}
placeholderTextColor: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return placeholderDisableColor
}
if(focus){
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
return placeholderFocusColor
}
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
return placeholderNormalColor
}
font.bold: {
switch (fontStyle) {
@ -73,40 +74,15 @@ TextArea{
return text.pixelSize * 1.0
}
}
selectByMouse: true
background: FluTextBoxBackground{ inputItem: control }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: input.echoMode !== TextInput.Password && menu.popup()
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluMenu{
FluTextBoxMenu{
id:menu
focus: false
FluMenuItem{
text: "剪切"
visible: input.text !== ""
onClicked: {
input.cut()
}
}
FluMenuItem{
text: "复制"
visible: input.selectedText !== ""
onClicked: {
input.copy()
}
}
FluMenuItem{
text: "粘贴"
visible: input.canPaste
onClicked: {
input.paste()
}
}
FluMenuItem{
text: "全选"
visible: input.text !== ""
onClicked: {
input.selectAll()
}
}
inputItem: control
}
}

View File

@ -48,14 +48,34 @@ Item {
id:com_panel_item_separatorr
FluDivider{
width: nav_list.width
height: 1
height: {
if(model.parent){
return model.parent.isExpand ? 1 : 0
}
return 1
}
Behavior on height {
NumberAnimation{
duration: 150
}
}
}
}
Component{
id:com_panel_item_header
Item{
height: 30
height: {
if(model.parent){
return model.parent.isExpand ? 30 : 0
}
return 30
}
Behavior on height {
NumberAnimation{
duration: 150
}
}
width: nav_list.width
FluText{
text:model.title
@ -70,11 +90,131 @@ Item {
}
Component{
id:com_panel_item
id:com_panel_item_expander
Item{
height: 38
width: nav_list.width
Rectangle{
radius: 4
anchors{
top: parent.top
bottom: parent.bottom
left: parent.left
right: parent.right
topMargin: 2
bottomMargin: 2
leftMargin: 6
rightMargin: 6
}
Rectangle{
width: 3
height: 18
radius: 1.5
color: FluTheme.primaryColor.dark
visible: {
for(var i=0;i<model.children.length;i++){
var item = model.children[i]
if(item.idx === nav_list.currentIndex && !model.isExpand){
return true
}
}
return false
}
anchors{
verticalCenter: parent.verticalCenter
}
}
FluIcon{
rotation: model.isExpand?0:180
iconSource:FluentIcons.ChevronUp
iconSize: 15
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: 12
}
Behavior on rotation {
NumberAnimation{
duration: 150
}
}
}
MouseArea{
id:item_mouse
hoverEnabled: true
anchors.fill: parent
onClicked: {
model.isExpand = !model.isExpand
}
}
color: {
if(FluTheme.dark){
if(item_mouse.containsMouse){
return Qt.rgba(1,1,1,0.03)
}
if((nav_list.currentIndex === position)&&type===0){
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(item_mouse.containsMouse){
return Qt.rgba(0,0,0,0.03)
}
if(nav_list.currentIndex === position&&type===0){
return Qt.rgba(0,0,0,0.06)
}
return Qt.rgba(0,0,0,0)
}
}
FluIcon{
id:item_icon
iconSource: {
if(model.icon){
return model.icon
}
return 0
}
width: 30
height: 30
iconSize: 15
anchors{
verticalCenter: parent.verticalCenter
left:parent.left
leftMargin: 3
}
}
FluText{
id:item_title
text:model.title
anchors{
verticalCenter: parent.verticalCenter
left:item_icon.right
}
}
}
}
}
Component{
id:com_panel_item
Item{
Behavior on height {
NumberAnimation{
duration: 150
}
}
clip: true
height: {
if(model.parent){
return model.parent.isExpand ? 38 : 0
}
return 38
}
width: nav_list.width
Rectangle{
radius: 4
anchors{
@ -330,11 +470,7 @@ Item {
}
ScrollBar.vertical: FluScrollBar {}
model:{
if(items){
return items.children
}
}
model:handleItems()
delegate: Loader{
property var model: modelData
property var position: index
@ -349,6 +485,9 @@ Item {
if(modelData instanceof FluPaneItemSeparator){
return com_panel_item_separatorr
}
if(modelData instanceof FluPaneItemExpander){
return com_panel_item_expander
}
}
}
}
@ -383,6 +522,33 @@ Item {
}
}
function handleItems(){
var idx = 0
var data = []
if(items){
for(var i=0;i<items.children.length;i++){
var item = items.children[i]
item.idx = idx
data.push(item)
idx++
if(item instanceof FluPaneItemExpander){
for(var j=0;j<item.children.length;j++){
var itemChild = item.children[j]
itemChild.parent = item
itemChild.idx = idx
data.push(itemChild)
idx++
}
}
}
}
return data
}
function getItems(){
return nav_list.model
}
function push(url){
nav_swipe.push(url)
}

View File

@ -3,12 +3,15 @@ import FluentUI
QtObject {
readonly property string key : FluApp.uuid()
readonly property int flag : 0
property string title
property int icon
property bool recentlyAdded: false
property bool recentlyUpdated: false
property string desc
property var image
property var parent
property int idx
signal tap
signal repTap
}

View File

@ -0,0 +1,14 @@
import QtQuick
import FluentUI
FluObject {
readonly property int flag : 3
readonly property string key : FluApp.uuid()
property string title
property int icon
property bool isExpand: false
property var parent
property int idx
signal tap
signal repTap
}

View File

@ -1,6 +1,9 @@
import QtQuick
QtObject {
readonly property int flag : 1
readonly property string key : FluApp.uuid()
property string title
property var parent
property int idx
}

View File

@ -1,5 +1,8 @@
import QtQuick
QtObject {
readonly property int flag : 2
readonly property string key : FluApp.uuid()
property var parent
property int idx
}

View File

@ -131,7 +131,7 @@ Item {
drag.target: item_container
drag.axis: Drag.XAxis
onWheel: {
onWheel: (wheel)=>{
if (wheel.angleDelta.y > 0) scroll_nav.decrease()
else scroll_nav.increase()
}
@ -198,7 +198,7 @@ Item {
}
}
function updatePosition(pos){
var idx = tab_nav.indexAt(pos.x+tab_nav.contentX, pos.y)
var idx = tab_nav.indexAt(pos.x+tab_nav.contentX+1, pos.y)
var firstIdx = tab_nav.indexAt(tab_nav.contentX+1, pos.y)
var lastIdx = tab_nav.indexAt(tab_nav.width+tab_nav.contentX-1, pos.y)
if(lastIdx === -1){

View File

@ -7,26 +7,31 @@ TextField{
property int fontStyle: FluText.Body
property int pixelSize : FluTheme.textSize
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)
id:input
id:control
width: 300
enabled: !disabled
color: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return disableColor
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
return normalColor
}
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTheme.primaryColor.lightest
placeholderTextColor: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return placeholderDisableColor
}
if(focus){
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
return placeholderFocusColor
}
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
return placeholderNormalColor
}
font.bold: {
switch (fontStyle) {
@ -69,44 +74,14 @@ TextField{
}
}
selectByMouse: true
background: FluTextBoxBackground{
inputItem: input
}
background: FluTextBoxBackground{ inputItem: control }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: input.echoMode !== TextInput.Password && menu.popup()
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluMenu{
FluTextBoxMenu{
id:menu
focus: false
FluMenuItem{
text: "剪切"
visible: input.text !== ""
onClicked: {
input.cut()
}
}
FluMenuItem{
text: "复制"
visible: input.selectedText !== ""
onClicked: {
input.copy()
}
}
FluMenuItem{
text: "粘贴"
visible: input.canPaste
onClicked: {
input.paste()
}
}
FluMenuItem{
text: "全选"
visible: input.text !== ""
onClicked: {
input.selectAll()
}
}
inputItem: control
}
}

View File

@ -0,0 +1,40 @@
import QtQuick
import FluentUI
FluMenu{
property string cutText : "剪切"
property string copyText : "复制"
property string pasteText : "粘贴"
property string selectAllText : "全选"
property var inputItem
id:menu
focus: false
FluMenuItem{
text: cutText
visible: inputItem.text !== ""
onClicked: {
inputItem.cut()
}
}
FluMenuItem{
text: copyText
visible: inputItem.selectedText !== ""
onClicked: {
inputItem.copy()
}
}
FluMenuItem{
text: pasteText
visible: inputItem.canPaste
onClicked: {
inputItem.paste()
}
}
FluMenuItem{
text: selectAllText
visible: inputItem.text !== ""
onClicked: {
inputItem.selectAll()
}
}
}

View File

@ -1,71 +0,0 @@
import QtQuick
import FluentUI
Item {
readonly property alias fps: _private.fps;
readonly property alias fpsAvg: _private.fpsAvg;
property color color: "#C0C0C0"
property Component contentItem: contentComponent;
id: control
width: contentItemLoader.width + 5;
height: contentItemLoader.height + 5;
Component{
id:contentComponent
FluText{
color:control.color
text: " Avg " + fpsAvg + " | " + fps + " Fps";
}
}
FluObject{
id:_private;
property int frameCounter: 0
property int frameCounterAvg: 0
property int counter: 0
property int fps: 0
property int fpsAvg: 0
}
Rectangle {
id: monitor
radius: 3
width: 6
height: width
opacity: 0;
NumberAnimation on rotation {
from:0
to: 360
duration: 800
loops: Animation.Infinite
}
onRotationChanged: _private.frameCounter++;
}
Loader{
id:contentItemLoader
sourceComponent: contentItem
}
Timer {
interval: 2000
repeat: true
running: visible
onTriggered: {
_private.frameCounterAvg += _private.frameCounter;
_private.fps = _private.frameCounter/2;
_private.counter++;
_private.frameCounter = 0;
if (_private.counter >= 3) {
_private.fpsAvg = _private.frameCounterAvg/(2 * _private.counter)
_private.frameCounterAvg = 0;
_private.counter = 0;
}
}
}
}

View File

@ -1,4 +1,4 @@
<RCC>
<RCC>
<qresource prefix="/com.zhuzichu">
<file>controls/FluButton.qml</file>
<file>controls/FluFilledButton.qml</file>
@ -22,9 +22,7 @@
<file>controls/FluIcon.qml</file>
<file>controls/FluDivider.qml</file>
<file>controls/FluTooltip.qml</file>
<file>controls/TFpsMonitor.qml</file>
<file>controls/FluTextBoxBackground.qml</file>
<file>controls/FluMultiLineTextBox.qml</file>
<file>controls/FluWindowResize.qml</file>
<file>controls/FluScrollBar.qml</file>
<file>controls/FluMenu.qml</file>
@ -60,5 +58,8 @@
<file>controls/FluMediaPlayer.qml</file>
<file>controls/FluTabView.qml</file>
<file>controls/FluItem.qml</file>
<file>controls/FluPaneItemExpander.qml</file>
<file>controls/FluTextBoxMenu.qml</file>
<file>controls/FluMultilineTextBox.qml</file>
</qresource>
</RCC>