Compare commits

...

15 Commits
1.0.6 ... 1.0.9

Author SHA1 Message Date
f2a66221e6 updaet 2023-03-16 22:06:08 +08:00
2de9d78f41 update 2023-03-16 18:11:03 +08:00
96355b0a97 update 2023-03-16 14:34:20 +08:00
47597471dd Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-03-15 20:40:30 +08:00
184f52c896 update 2023-03-15 20:40:09 +08:00
31b2b0b004 update 2023-03-15 18:45:14 +08:00
1e4f939de7 update 2023-03-15 14:49:33 +08:00
926132a285 update 2023-03-15 14:48:48 +08:00
9e245fb533 update 2023-03-15 00:36:49 +08:00
8bfbfd63fb update 2023-03-15 00:33:38 +08:00
51a206e583 update 2023-03-14 18:23:12 +08:00
ee3ddf7732 update 2023-03-13 21:32:29 +08:00
6d238871ee update 2023-03-13 21:28:35 +08:00
9d3de073c0 update 2023-03-13 21:18:51 +08:00
7282a6f8d1 update 2023-03-13 18:23:46 +08:00
50 changed files with 781 additions and 125 deletions

View File

@ -57,12 +57,17 @@
|FluTooltip|tooltip提示框||
|FluTreeView|树控件||
|FluTheme|主题设置|支持主题颜色切换,夜间模式|
|FluCarousel|轮播图组件|支持无限轮播|
|FluTimePicker|时间选择器||
|FluDatePicker|日期选择器||
|FluMenu|菜单Popup||
|FluNavigationView|响应式导航布局||
# 部分效果预览
## 主页
## 各种Button按钮
![](doc/preview/main.png)
![](doc/preview/buttons.png)
## 主题颜色切换、夜间模式
@ -72,10 +77,14 @@
![](doc/preview/treeview.png)
## Toast组件
## 轮播图组件
![](doc/preview/carousel.png)
## InfoBar提示框组件
![](doc/preview/infobar.png)
## Rectangle组件
## 多窗口路由跳转
![](doc/preview/rectangle.png)
![](doc/preview/multiwindow.png)

BIN
doc/preview/buttons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
doc/preview/carousel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

BIN
doc/preview/multiwindow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -12,9 +12,9 @@ Window {
FluApp.init(app,properties)
FluTheme.isDark = false
FluApp.routes = {
"/":"qrc:/MainPage.qml",
"/Setting":"qrc:/SettingPage.qml",
"/About":"qrc:/AboutPage.qml",
"/":"qrc:/page/MainPage.qml",
"/about":"qrc:/page/AboutPage.qml",
"/login":"qrc:/page/LoginPage.qml",
}
FluApp.initialRoute = "/"
FluApp.run()

View File

@ -1,29 +0,0 @@
import QtQuick 2.15
import FluentUI 1.0
FluWindow {
width: 500
height: 600
title:"设置"
FluAppBar{
id:appbar
title:"设置"
}
FluText{
text:"设置"
fontStyle: FluText.Display
anchors.centerIn: parent
MouseArea{
anchors.fill: parent
onClicked: {
FluApp.navigate("/About")
}
}
}
}

View File

@ -115,6 +115,49 @@ FluScrollablePage{
}
}
FluArea{
width: parent.width
height: 68
paddings: 10
FluDropDownButton{
disabled:drop_down_button_switch.selected
text:"DropDownButton"
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
items:[
FluMenuItem{
text:"Menu_1"
},
FluMenuItem{
text:"Menu_2"
},
FluMenuItem{
text:"Menu_3"
},
FluMenuItem{
text:"Menu_4"
}
]
}
Row{
spacing: 5
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
}
FluToggleSwitch{
id:drop_down_button_switch
Layout.alignment: Qt.AlignRight
}
FluText{
text:"Disabled"
}
}
}
FluArea{
width: parent.width
height: 100
@ -189,4 +232,6 @@ FluScrollablePage{
}
}
}
}

36
example/T_Carousel.qml Normal file
View File

@ -0,0 +1,36 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
import FluentUI 1.0
FluScrollablePage{
title:"Carousel"
FluArea{
width: parent.width
height: 370
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left:parent.left
}
FluText{
text:"轮播图支持无限轮播无限滑动用ListView实现的组件"
}
FluCarousel{
id:carousel
Layout.topMargin: 20
Layout.leftMargin: 5
Component.onCompleted: {
carousel.setData([{url:"qrc:/res/image/banner_1.jpg"},{url:"qrc:/res/image/banner_2.jpg"},{url:"qrc:/res/image/banner_3.jpg"}])
}
}
}
}
}

54
example/T_Menu.qml Normal file
View File

@ -0,0 +1,54 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
import FluentUI 1.0
FluScrollablePage{
title:"Menu"
FluButton{
text:"左击菜单"
Layout.topMargin: 20
Layout.leftMargin: 15
onClicked:{
menu.popup()
}
}
FluButton{
text:"右击菜单"
Layout.topMargin: 20
Layout.leftMargin: 15
onClicked: {
showSuccess("请按鼠标右击")
}
MouseArea{
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
menu.popup()
}
}
}
FluMenu{
id:menu
FluMenuItem{
text:"删除"
onClicked: {
showError("删除")
}
}
FluMenuItem{
text:"修改"
onClicked: {
showError("修改")
}
}
}
}

77
example/T_MultiWindow.qml Normal file
View File

@ -0,0 +1,77 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import FluentUI 1.0
FluScrollablePage{
title:"MultiWindow"
property string password: ""
property var loginPageRegister: registerForPageResult("/login")
Connections{
target: loginPageRegister
function onResult(data)
{
password = data.password
}
}
FluArea{
width: parent.width
height: 100
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"页面跳转,不携带任何参数"
}
FluButton{
text:"点击跳转"
onClicked: {
FluApp.navigate("/about")
}
}
}
}
FluArea{
width: parent.width
height: 130
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"页面跳转并携带参数用户名zhuzichu"
}
FluButton{
text:"点击跳转到登录"
onClicked: {
loginPageRegister.launch({username:"zhuzichu"})
}
}
FluText{
text:"登录窗口返回过来的密码->"+password
}
}
}
}

View File

@ -8,6 +8,8 @@ SOURCES += \
RESOURCES += qml.qrc
RC_ICONS = favicon.ico
#qnx: target.path = /tmp/$${TARGET}/bin
#else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target

BIN
example/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

View File

@ -34,7 +34,7 @@ FluWindow {
fontStyle: FluText.Title
}
FluText{
text:"v1.0.6"
text:"v1.0.9"
fontStyle: FluText.Body
Layout.alignment: Qt.AlignBottom
}

View File

@ -0,0 +1,72 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import FluentUI 1.0
FluWindow {
id:window
width: 400
height: 400
minimumWidth: 400
minimumHeight: 400
maximumWidth: 400
maximumHeight: 400
modality:2
title:"登录"
onInitArgument:
(argument)=>{
textbox_uesrname.text = argument.username
textbox_password.focus = true
}
FluAppBar{
id:appbar
title:"登录"
}
ColumnLayout{
anchors{
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
FluAutoSuggestBox{
id:textbox_uesrname
values:["Admin","User"]
placeholderText: "请输入账号"
Layout.preferredWidth: 260
Layout.alignment: Qt.AlignHCenter
}
FluTextBox{
id:textbox_password
Layout.topMargin: 20
Layout.preferredWidth: 260
placeholderText: "请输入密码"
echoMode:TextInput.Password
Layout.alignment: Qt.AlignHCenter
}
FluFilledButton{
text:"登录"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 20
onClicked:{
if(textbox_password.text === ""){
showError("请随便输入一个密码")
return
}
onResult({password:textbox_password.text})
window.close()
}
}
}
}

View File

@ -9,7 +9,7 @@ import FluentUI 1.0
FluWindow {
id:rootwindow
width: 860
height: 680
height: 600
title: "FluentUI"
minimumWidth: 500
minimumHeight: 400
@ -19,7 +19,6 @@ FluWindow {
title: "FluentUI"
}
FluObject{
id:original_items
@ -90,12 +89,22 @@ FluWindow {
nav_view.push("qrc:/T_Progress.qml")
}
}
FluPaneItem{
title:"Rectangle"
onTap:{
nav_view.push("qrc:/T_Rectangle.qml")
}
}
FluPaneItem{
title:"Carousel"
onTap:{
nav_view.push("qrc:/T_Carousel.qml")
}
}
FluPaneItem{
title:"Expander"
onTap:{
@ -107,7 +116,6 @@ FluWindow {
title:"Popus"
}
FluPaneItem{
title:"Dialog"
onTap:{
@ -115,6 +123,13 @@ FluWindow {
}
}
FluPaneItem{
title:"Menu"
onTap:{
nav_view.push("qrc:/T_Menu.qml")
}
}
FluPaneItemHeader{
title:"Navigation"
}
@ -126,6 +141,14 @@ FluWindow {
}
}
FluPaneItem{
title:"MultiWindow"
onTap:{
nav_view.push("qrc:/T_MultiWindow.qml")
}
}
FluPaneItemHeader{
title:"Theming"
}
@ -164,7 +187,7 @@ FluWindow {
FluPaneItem{
title:"关于"
onTap:{
FluApp.navigate("/About")
FluApp.navigate("/about")
}
}
}

View File

@ -1,15 +1,6 @@
<RCC>
<qresource prefix="/">
<file>T_ToggleSwitch.qml</file>
<file>T_Typography.qml</file>
<file>App.qml</file>
<file>SettingPage.qml</file>
<file>AboutPage.qml</file>
<file>T_Buttons.qml</file>
<file>T_Rectangle.qml</file>
<file>T_InfoBar.qml</file>
<file>T_Progress.qml</file>
<file>T_Slider.qml</file>
<file>res/image/image_huoyin.webp</file>
<file>res/svg/avatar_1.svg</file>
<file>res/svg/avatar_2.svg</file>
@ -23,14 +14,29 @@
<file>res/svg/avatar_10.svg</file>
<file>res/svg/avatar_11.svg</file>
<file>res/svg/avatar_12.svg</file>
<file>page/AboutPage.qml</file>
<file>page/MainPage.qml</file>
<file>page/LoginPage.qml</file>
<file>T_ToggleSwitch.qml</file>
<file>T_Typography.qml</file>
<file>T_Awesome.qml</file>
<file>T_Buttons.qml</file>
<file>T_Rectangle.qml</file>
<file>T_InfoBar.qml</file>
<file>T_Progress.qml</file>
<file>T_Slider.qml</file>
<file>T_TextBox.qml</file>
<file>T_Theme.qml</file>
<file>T_Dialog.qml</file>
<file>T_TreeView.qml</file>
<file>T_Expander.qml</file>
<file>MainPage.qml</file>
<file>T_TimePicker.qml</file>
<file>T_DatePicker.qml</file>
<file>T_MultiWindow.qml</file>
<file>T_Menu.qml</file>
<file>T_Carousel.qml</file>
<file>res/image/banner_1.jpg</file>
<file>res/image/banner_2.jpg</file>
<file>res/image/banner_3.jpg</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -33,14 +33,18 @@ void FluApp::run(){
navigate(initialRoute());
}
void FluApp::navigate(const QString& route){
void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegister* fluRegister){
if(!routes().contains(route)){
qErrnoWarning("没有找到当前路由");
return;
}
bool isAppWindow = route == initialRoute();
FramelessView *view = new FramelessView();
if(fluRegister){
fluRegister->to(view);
view->setProperty("pageRegister",QVariant::fromValue(fluRegister));
}
view->setProperty("argument",argument);
QMapIterator<QString, QVariant> iterator(properties);
while (iterator.hasNext()) {
iterator.next();
@ -59,7 +63,6 @@ void FluApp::navigate(const QString& route){
view->setSource((routes().value(route).toString()));
if(isAppWindow){
QObject::connect(view->engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
// QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view](){view->setSource({});});
}else{
view->closeDeleteLater();
}

View File

@ -7,6 +7,7 @@
#include <QQmlContext>
#include <QJsonObject>
#include <QQmlEngine>
#include "FluRegister.h"
#include "FramelessView.h"
#include "stdafx.h"
@ -24,7 +25,7 @@ public:
Q_INVOKABLE void run();
Q_INVOKABLE void navigate(const QString& route);
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
Q_INVOKABLE void init(QWindow *window,QMap<QString, QVariant> properties);
@ -37,9 +38,8 @@ public:
Q_INVOKABLE void clipText(const QString& text);
private:
static FluApp* m_instance;
QMap<QString, QVariant> properties;
static FluApp* m_instance;
QWindow *appWindow;
};

20
src/FluRegister.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "FluRegister.h"
#include "FluApp.h"
#include <QCoreApplication>
FluRegister::FluRegister(QObject *parent)
: QObject{parent}
{
from(nullptr);
to(nullptr);
path("");
}
void FluRegister::launch(const QJsonObject& argument){
FluApp::getInstance()->navigate(path(),argument,this);
}
void FluRegister::onResult(const QJsonObject& data){
Q_EMIT result(data);
}

24
src/FluRegister.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef FLUREGISTER_H
#define FLUREGISTER_H
#include <QObject>
#include <FramelessView.h>
#include <QJsonObject>
#include "stdafx.h"
class FluRegister : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(FramelessView*,from)
Q_PROPERTY_AUTO(FramelessView*,to)
Q_PROPERTY_AUTO(QString,path);
public:
explicit FluRegister(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 // FLUREGISTER_H

View File

@ -47,6 +47,7 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDatePicker.qml"),uri,major,minor,"FluDatePicker");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTimePicker.qml"),uri,major,minor,"FluTimePicker");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluCarousel.qml"),uri,major,minor,"FluCarousel");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluAutoSuggestBox.qml"),uri,major,minor,"FluAutoSuggestBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluExpander.qml"),uri,major,minor,"FluExpander");
@ -91,7 +92,7 @@ void Fluent::initializeEngine(QQmlEngine *engine, const char *uri)
QFont font;
font.setFamily("Microsoft YaHei");
QGuiApplication::setFont(font);
// QQuickWindow::setTextRenderType(QQuickWindow::NativeTextRendering);
// QQuickWindow::setTextRenderType(QQuickWindow::NativeTextRendering);
#endif
QFontDatabase::addApplicationFont(":/com.zhuzichu/res/font/Segoe_Fluent_Icons.ttf");
FluApp* app = FluApp::getInstance();

View File

@ -15,6 +15,7 @@ HEADERS += \
FluApp.h \
FluColorSet.h \
FluColors.h \
FluRegister.h \
FluTheme.h \
Fluent.h \
FluentUI.h \
@ -28,6 +29,7 @@ SOURCES += \
FluApp.cpp \
FluColorSet.cpp \
FluColors.cpp \
FluRegister.cpp \
FluTheme.cpp \
Fluent.cpp \
FluentUI.cpp \

View File

@ -1,5 +1,7 @@
#include "WindowHelper.h"
#include "FluRegister.h"
WindowHelper::WindowHelper(QObject *parent)
: QObject{parent}
{
@ -10,11 +12,18 @@ void WindowHelper::setTitle(const QString& text){
window->setTitle(text);
}
void WindowHelper::initWindow(FramelessView* window){
this->window = window;
}
QJsonObject WindowHelper::getArgument(){
return window->property("argument").toJsonObject();
}
QVariant WindowHelper::getPageRegister(){
return window->property("pageRegister");
}
void WindowHelper::setMinimumWidth(int width){
this->window->setMinimumWidth(width);
}
@ -27,3 +36,25 @@ void WindowHelper::setMinimumHeight(int height){
void WindowHelper::setMaximumHeight(int height){
this->window->setMaximumHeight(height);
}
void WindowHelper::updateWindow(){
this->window->setFlag(Qt::Window,false);
this->window->setFlag(Qt::Window,true);
}
void WindowHelper::setModality(int type){
if(type == 0){
this->window->setModality(Qt::NonModal);
}else if(type == 1){
this->window->setModality(Qt::WindowModal);
}else if(type == 2){
this->window->setModality(Qt::ApplicationModal);
}else{
this->window->setModality(Qt::NonModal);
}
}
QVariant WindowHelper::createRegister(const QString& path){
FluRegister *p = new FluRegister(this->window);
p->from(this->window);
p->path(path);
return QVariant::fromValue(p);
}

View File

@ -5,6 +5,7 @@
#include <QQuickWindow>
#include <QQuickItem>
#include <QWindow>
#include <QJsonObject>
#include "FramelessView.h"
class WindowHelper : public QObject
@ -20,6 +21,11 @@ public:
Q_INVOKABLE void setMaximumWidth(int width);
Q_INVOKABLE void setMinimumHeight(int height);
Q_INVOKABLE void setMaximumHeight(int height);
Q_INVOKABLE QJsonObject getArgument();
Q_INVOKABLE QVariant getPageRegister();
Q_INVOKABLE void updateWindow();
Q_INVOKABLE void setModality(int type);
Q_INVOKABLE QVariant createRegister(const QString& path);
private:
FramelessView* window;

View File

@ -7,7 +7,7 @@ TextField{
property var values:[]
property int fontStyle: FluText.Body
property int pixelSize : FluTheme.textSize
property int iconSource: -1
property int iconSource: 0
signal itemClicked(string data)
id:input
@ -112,7 +112,7 @@ TextField{
iconSource: input.iconSource
iconSize: 15
opacity: 0.5
visible: input.iconSource != -1
visible: input.iconSource != 0
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
@ -152,6 +152,7 @@ TextField{
boundsBehavior: ListView.StopAtBounds
clip: true
currentIndex: -1
ScrollBar.vertical: FluScrollBar {}
header: Item{
width: input.width
height: visible ? 38 : 0
@ -165,7 +166,6 @@ TextField{
}
}
}
ScrollBar.vertical: ScrollBar { }
delegate:Control{
width: input.width
padding:10

View File

@ -36,7 +36,6 @@ Button {
}
contentItem: FluText {
text: control.text
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: {

View File

@ -0,0 +1,136 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import FluentUI 1.0
Item {
property bool flagXChanged: true
property int radius : 5
property int loopTime: 2000
property bool showIndicator: true
id:control
width: 400
height: 300
ListModel{
id:content_model
}
FluRectangle{
anchors.fill: parent
radius: [control.radius,control.radius,control.radius,control.radius]
FluShadow{
radius:control.radius
}
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
orientation : ListView.Horizontal
delegate: Item{
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
}
Image {
anchors.fill: parent
source: model.url
fillMode:Image.PreserveAspectCrop
}
}
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
}
flagXChanged = false
timer_run.start()
}
onMovementStarted: {
flagXChanged = true
timer_run.stop()
}
onContentXChanged: {
if(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
}
}
}
}
}
function setData(data){
content_model.clear()
content_model.append(data[data.length-1])
content_model.append(data)
content_model.append(data[0])
list_view.currentIndex = 1
timer_run.restart()
}
Row{
spacing: 10
anchors{
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 20
}
visible: showIndicator
Repeater{
model: list_view.count
Rectangle{
width: 8
height: 8
radius: 4
visible: {
if(index===0 || index===list_view.count-1)
return false
return true
}
layer.samples: 4
layer.enabled: true
layer.smooth: true
border.width: 1
border.color: FluColors.Grey100
color: list_view.currentIndex === index ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.5)
}
}
}
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: true
onTriggered: {
list_view.highlightMoveDuration = 250
list_view.currentIndex = list_view.currentIndex+1
timer_anim.start()
}
}
}

View File

@ -202,9 +202,12 @@ Rectangle {
width: 100
height: parent.height
boundsBehavior:Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar { }
ScrollBar.vertical: FluScrollBar {}
model: generateYearArray(1924,2048)
clip: true
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
visible: showYear
delegate: Loader{
property var model: modelData
@ -212,11 +215,6 @@ Rectangle {
property int position:index
sourceComponent: list_delegate
}
onCurrentIndexChanged: {
if(currentIndex!==-1){
list_view_1.positionViewAtIndex(currentIndex, ListView.NoPosition)
}
}
}
Rectangle{
width: 1
@ -228,7 +226,10 @@ Rectangle {
width: showYear ? 100 : 150
height: parent.height
clip: true
ScrollBar.vertical: ScrollBar { }
ScrollBar.vertical: FluScrollBar {}
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
boundsBehavior:Flickable.StopAtBounds
delegate: Loader{
property var model: modelData
@ -236,11 +237,6 @@ Rectangle {
property int position:index
sourceComponent: list_delegate
}
onCurrentIndexChanged: {
if(currentIndex!==-1){
list_view_2.positionViewAtIndex(currentIndex, ListView.NoPosition)
}
}
}
Rectangle{
width: 1
@ -252,7 +248,10 @@ Rectangle {
width: showYear ? 100 : 150
height: parent.height
clip: true
ScrollBar.vertical: ScrollBar { }
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
ScrollBar.vertical: FluScrollBar {}
Layout.alignment: Qt.AlignVCenter
boundsBehavior:Flickable.StopAtBounds
delegate: Loader{
@ -261,9 +260,6 @@ Rectangle {
property int position:index
sourceComponent: list_delegate
}
onCurrentIndexChanged: {
list_view_3.positionViewAtIndex(currentIndex, ListView.NoPosition)
}
}
}
@ -348,10 +344,12 @@ Rectangle {
text_day.text = day
var pos = root.mapToItem(null, 0, 0)
if(window.height>pos.y+35+340){
popup.y = 35
}else{
popup.y = window.height-(pos.y+340)
if(window.height>pos.y+root.height+popup.height){
popup.y = root.height
} else if(pos.y>popup.height){
popup.y = -popup.height
} else {
popup.y = window.height-(pos.y+popup.height)
}
popup.open()
}

View File

@ -1,6 +1,89 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import FluentUI 1.0
Item {
Button {
property bool disabled: false
property color normalColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
property color hoverColor: FluTheme.isDark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
property color disableColor: FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
id: control
topPadding:5
bottomPadding:5
leftPadding:15
rightPadding:35
enabled: !disabled
focusPolicy:Qt.TabFocus
property var window : Window.window
property alias items: menu.content
Keys.onSpacePressed: control.visualFocus&&clicked()
background: Rectangle{
border.color: FluTheme.isDark ? "#505050" : "#DFDFDF"
border.width: 1
radius: 4
FluFocusRectangle{
visible: control.visualFocus
radius:8
}
color:{
if(disabled){
return disableColor
}
return hovered ? hoverColor :normalColor
}
FluIcon{
iconSource:FluentIcons.ChevronDown
iconSize: 15
anchors{
right: parent.right
rightMargin: 10
verticalCenter: parent.verticalCenter
}
color:title.color
}
}
contentItem: FluText {
id:title
text: control.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: {
if(FluTheme.isDark){
if(disabled){
return Qt.rgba(131/255,131/255,131/255,1)
}
return Qt.rgba(1,1,1,1)
}else{
if(disabled){
return Qt.rgba(160/255,160/255,160/255,1)
}
return Qt.rgba(0,0,0,1)
}
}
}
onClicked: {
var pos = control.mapToItem(null, 0, 0)
if(window.height>pos.y+control.height+menu.height){
menu.y = control.height
}else if(pos.y>menu.height){
menu.y = -menu.height
}else{
popup.y = window.height-(pos.y+menu.height)
}
menu.open()
}
FluMenu{
id:menu
width: control.width
}
}

View File

@ -1,16 +1,27 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
Popup {
Menu {
id: popup
default property alias content: container.children
default property alias content: container.data
background: Rectangle {
implicitWidth: 140
implicitHeight: container.height
color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1)
radius: 5
width: 140
height: container.height
background: Item {
Rectangle{
anchors.fill: parent
color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
radius: 5
layer.enabled: true
layer.effect: GaussianBlur {
radius: 8
samples: 16
}
}
FluShadow{
radius: 5
@ -19,6 +30,7 @@ Popup {
spacing: 5
topPadding: 5
bottomPadding: 5
width: popup.width
id:container
function closePopup(){
popup.close()

View File

@ -4,7 +4,12 @@ import QtQuick.Controls 2.15
Item {
id:root
width: 140
width: {
if(root.parent){
return root.parent.width
}
return 140
}
height: 32
property string text: "MenuItem"
@ -12,14 +17,21 @@ Item {
Rectangle{
anchors.centerIn: parent
width: 100
width: root.width-40
height: 32
radius: 4
color:{
if(mouse_area.containsMouse){
return FluTheme.isDark ? Qt.rgba(56/255,56/255,56/255,1) : Qt.rgba(230/255,230/255,230/255,1)
if(FluTheme.isDark){
if(mouse_area.containsMouse){
return Qt.rgba(1,1,1,0.05)
}
return Qt.rgba(0,0,0,0)
}else{
if(mouse_area.containsMouse){
return Qt.rgba(0,0,0,0.05)
}
return Qt.rgba(0,0,0,0)
}
return FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1)
}
FluText{

View File

@ -135,12 +135,11 @@ Item {
}
}
Item {
id:nav_app_bar
width: parent.width
height: 38
z:999
RowLayout{
height:parent.height
spacing: 0
@ -232,7 +231,7 @@ Item {
id:layout_list
width: 300
anchors{
top: nav_app_bar.bottom
top: parent.top
bottom: parent.bottom
}
x: {
@ -264,6 +263,7 @@ Item {
Item{
id:layout_header
width: layout_list.width
y:nav_app_bar.height
height: 50
FluAutoSuggestBox{
@ -322,6 +322,8 @@ Item {
stackIndex.push(currentIndex)
}
}
ScrollBar.vertical: FluScrollBar {}
model:{
if(items){
return items.children

View File

@ -32,7 +32,7 @@ Button {
if(selected&&disabled){
return 3
}
if(hovered){
if(pressed){
if(selected){
return 5
}
@ -48,7 +48,7 @@ Button {
}
Behavior on border.width {
NumberAnimation{
duration: 100
duration: 150
}
}
border.color: {

View File

@ -9,7 +9,7 @@ Item{
property color borderColor:"red"
property int borderWidth: 1
property bool shadow: true
default property alias contentItem: container.children
default property alias contentItem: container.data
Rectangle{
id:container

View File

@ -17,10 +17,13 @@ Item {
fontStyle: FluText.TitleLarge
}
ScrollView{
Flickable{
clip: true
width: parent.width
contentWidth: parent.width
contentHeight: container.height
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar { }
anchors{
top: text_title.bottom
bottom: parent.bottom

View File

@ -6,7 +6,7 @@ Item {
anchors.margins: -4
property color color: FluTheme.isDark ? "#FFFFFF" : "#000000"
property var radius: 4
property int radius: 4
Rectangle{
width: root.width

View File

@ -201,7 +201,10 @@ Rectangle {
width: isH ? 100 : 150
height: parent.height
boundsBehavior:Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar { }
ScrollBar.vertical: FluScrollBar {}
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
model: isH ? generateArray(1,12) : generateArray(0,23)
clip: true
delegate: Loader{
@ -210,9 +213,6 @@ Rectangle {
property int position:index
sourceComponent: list_delegate
}
onCurrentIndexChanged: {
list_view_1.positionViewAtIndex(currentIndex, ListView.NoPosition)
}
}
Rectangle{
width: 1
@ -225,7 +225,10 @@ Rectangle {
height: parent.height
model: generateArray(0,59)
clip: true
ScrollBar.vertical: ScrollBar { }
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
ScrollBar.vertical: FluScrollBar {}
boundsBehavior:Flickable.StopAtBounds
delegate: Loader{
property var model: modelData
@ -233,9 +236,6 @@ Rectangle {
property int position:index
sourceComponent: list_delegate
}
onCurrentIndexChanged: {
list_view_2.positionViewAtIndex(currentIndex, ListView.NoPosition)
}
}
Rectangle{
width: 1
@ -250,7 +250,10 @@ Rectangle {
model: ["上午","下午"]
clip: true
visible: isH
ScrollBar.vertical: ScrollBar { }
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 0
ScrollBar.vertical: FluScrollBar {}
Layout.alignment: Qt.AlignVCenter
boundsBehavior:Flickable.StopAtBounds
delegate: Loader{
@ -259,9 +262,6 @@ Rectangle {
property int position:index
sourceComponent: list_delegate
}
onCurrentIndexChanged: {
list_view_3.positionViewAtIndex(currentIndex, ListView.NoPosition)
}
}
}
@ -358,10 +358,12 @@ Rectangle {
}
var pos = root.mapToItem(null, 0, 0)
if(window.height>pos.y+35+340){
popup.y = 35
}else{
popup.y = window.height-(pos.y+340)
if(window.height>pos.y+root.height+popup.height){
popup.y = root.height
} else if(pos.y>popup.height){
popup.y = -popup.height
} else {
popup.y = window.height-(pos.y+popup.height)
}
popup.open()
}

View File

@ -61,6 +61,9 @@ Button {
Behavior on x {
NumberAnimation { duration: 200 }
}
Behavior on scale {
NumberAnimation { duration: 150 }
}
}
}

View File

@ -276,8 +276,8 @@ Item {
model: tree_model
flickableDirection: Flickable.HorizontalAndVerticalFlick
clip: true
ScrollBar.vertical: ScrollBar { }
ScrollBar.horizontal: ScrollBar { }
ScrollBar.vertical: FluScrollBar {}
ScrollBar.horizontal: FluScrollBar { }
}
function updateData(items){

View File

@ -26,6 +26,11 @@ Item {
property int maximumWidth
property int minimumHeight
property int maximumHeight
property int modality:0
signal initArgument(var argument)
property var pageRegister
property int borderless:{
if(!FluTheme.isFrameless){
@ -76,8 +81,10 @@ Item {
target: FluApp
function onWindowReady(view){
if(FluApp.equalsWindow(view,window)){
helper.initWindow(view);
helper.setTitle(title);
helper.initWindow(view)
initArgument(helper.getArgument())
pageRegister = helper.getPageRegister()
helper.setTitle(title)
if(minimumWidth){
helper.setMinimumWidth(minimumWidth)
}
@ -90,6 +97,8 @@ Item {
if(maximumHeight){
helper.setMaximumHeight(maximumHeight)
}
helper.setModality(root.modality);
helper.updateWindow()
}
}
}
@ -106,17 +115,31 @@ Item {
function showSuccess(text,duration,moremsg){
infoBar.showSuccess(text,duration,moremsg);
}
function showInfo(text,duration,moremsg){
infoBar.showInfo(text,duration,moremsg);
}
function showWarning(text,duration,moremsg){
infoBar.showWarning(text,duration,moremsg);
}
function showError(text,duration,moremsg){
infoBar.showError(text,duration,moremsg);
}
function close(){
window.close()
}
function registerForPageResult(path){
return helper.createRegister(path)
}
function onResult(data){
if(pageRegister){
pageRegister.onResult(data)
}
}
}

0
src/macos_install.sh Executable file → Normal file
View File

View File

@ -47,5 +47,6 @@
<file>controls/FluCalenderView.qml</file>
<file>controls/FluCalendarDatePicker.qml</file>
<file>controls/FluFocusRectangle.qml</file>
<file>controls/FluCarousel.qml</file>
</qresource>
</RCC>