Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
b83e70ba24 | |||
e29cb7433e | |||
9545175445 | |||
a447b260e7 | |||
8eb7e1df4a | |||
c622f80659 | |||
c0ed9cb41c | |||
e5a24ec642 | |||
6553584c3d | |||
1ea043ee13 | |||
0d6b0d9d25 | |||
5f71ad57d0 | |||
c789d53d6a | |||
f2bbbd5250 | |||
4e95923847 | |||
5fadb582c9 | |||
6b54401371 | |||
28b65e2f33 | |||
0689c3b9d9 | |||
9c121c6ba9 | |||
f2a66221e6 | |||
2de9d78f41 | |||
96355b0a97 | |||
47597471dd | |||
184f52c896 | |||
31b2b0b004 | |||
1e4f939de7 | |||
926132a285 | |||
9e245fb533 | |||
8bfbfd63fb | |||
51a206e583 |
11
.gitignore
vendored
@ -1,14 +1,3 @@
|
|||||||
# C++ objects and libs
|
|
||||||
*.slo
|
|
||||||
*.lo
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.la
|
|
||||||
*.lai
|
|
||||||
*.so
|
|
||||||
*.dll
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Qt-es
|
# Qt-es
|
||||||
object_script.*.Release
|
object_script.*.Release
|
||||||
object_script.*.Debug
|
object_script.*.Debug
|
||||||
|
23
README.md
@ -57,12 +57,21 @@
|
|||||||
|FluTooltip|tooltip提示框||
|
|FluTooltip|tooltip提示框||
|
||||||
|FluTreeView|树控件||
|
|FluTreeView|树控件||
|
||||||
|FluTheme|主题设置|支持主题颜色切换,夜间模式|
|
|FluTheme|主题设置|支持主题颜色切换,夜间模式|
|
||||||
|
|FluCarousel|轮播图组件|支持无限轮播|
|
||||||
|
|FluTimePicker|时间选择器||
|
||||||
|
|FluDatePicker|日期选择器||
|
||||||
|
|FluMenu|菜单Popup||
|
||||||
|
|FluNavigationView|响应式导航布局||
|
||||||
|
|
||||||
# 部分效果预览
|
# 部分效果预览
|
||||||
|
|
||||||
## 主页
|
## 一个聊天Demo,调用了ChatGPT的接口
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## 各种Button按钮
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## 主题颜色切换、夜间模式
|
## 主题颜色切换、夜间模式
|
||||||
|
|
||||||
@ -72,10 +81,14 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Toast组件
|
## 轮播图组件
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## InfoBar提示框组件
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Rectangle组件
|
## 多窗口路由跳转
|
||||||
|
|
||||||

|

|
BIN
doc/preview/buttons.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
doc/preview/carousel.png
Normal file
After Width: | Height: | Size: 383 KiB |
BIN
doc/preview/chatgpt.png
Normal file
After Width: | Height: | Size: 382 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 119 KiB |
BIN
doc/preview/multiwindow.png
Normal file
After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 703 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 101 KiB |
@ -15,6 +15,7 @@ Window {
|
|||||||
"/":"qrc:/page/MainPage.qml",
|
"/":"qrc:/page/MainPage.qml",
|
||||||
"/about":"qrc:/page/AboutPage.qml",
|
"/about":"qrc:/page/AboutPage.qml",
|
||||||
"/login":"qrc:/page/LoginPage.qml",
|
"/login":"qrc:/page/LoginPage.qml",
|
||||||
|
"/chat":"qrc:/page/ChatPage.qml",
|
||||||
}
|
}
|
||||||
FluApp.initialRoute = "/"
|
FluApp.initialRoute = "/"
|
||||||
FluApp.run()
|
FluApp.run()
|
||||||
|
56
example/ChatController.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "ChatController.h"
|
||||||
|
|
||||||
|
ChatController::ChatController(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
isLoading(false);
|
||||||
|
networkManager = new QNetworkAccessManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ChatController::sendMessage(const QString& text){
|
||||||
|
isLoading(true);
|
||||||
|
QUrl apiUrl("https://api.openai.com/v1/chat/completions");
|
||||||
|
QNetworkRequest request(apiUrl);
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
request.setRawHeader("Authorization", QString::fromStdString("Bearer %1").arg(QString::fromUtf8(QByteArray::fromBase64(baseKey.toUtf8()))).toUtf8());
|
||||||
|
QJsonObject requestData;
|
||||||
|
requestData.insert("model", "gpt-3.5-turbo");
|
||||||
|
messages.append(createMessage("user",text));
|
||||||
|
requestData.insert("messages", messages);
|
||||||
|
QJsonDocument requestDoc(requestData);
|
||||||
|
QByteArray requestDataBytes = requestDoc.toJson();
|
||||||
|
QNetworkReply* reply = networkManager->post(request, requestDataBytes);
|
||||||
|
connect(reply, &QNetworkReply::finished,this, [=]() {
|
||||||
|
if (reply->error() == QNetworkReply::NoError) {
|
||||||
|
QString responseString = QString::fromUtf8(reply->readAll());
|
||||||
|
qDebug() << responseString;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(responseString.toUtf8());
|
||||||
|
QJsonObject jsonObj = doc.object();
|
||||||
|
QString text = jsonObj.value("choices").toArray().at(0).toObject().value("message").toObject().value("content").toString();
|
||||||
|
if(text.isEmpty()){
|
||||||
|
text = "响应错误:content为空数据";
|
||||||
|
}else{
|
||||||
|
messages.append(createMessage("assistant",text));
|
||||||
|
}
|
||||||
|
responseData(text.trimmed());
|
||||||
|
} else {
|
||||||
|
responseData("网络错误:"+reply->errorString());
|
||||||
|
}
|
||||||
|
isLoading(false);
|
||||||
|
reply->deleteLater();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject ChatController::createMessage(const QString& role,const QString& content){
|
||||||
|
QJsonObject message;
|
||||||
|
message.insert("role",role);
|
||||||
|
message.insert("content",content);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatController::clipText(const QString& text){
|
||||||
|
qDebug()<<text;
|
||||||
|
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||||
|
clipboard->setText(text);
|
||||||
|
}
|
35
example/ChatController.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef CHATCONTROLLER_H
|
||||||
|
#define CHATCONTROLLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QFile>
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
class ChatController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY_AUTO(bool,isLoading)
|
||||||
|
Q_PROPERTY_AUTO(QString,responseData);
|
||||||
|
public:
|
||||||
|
explicit ChatController(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
Q_INVOKABLE void sendMessage(const QString& text);
|
||||||
|
Q_INVOKABLE void clipText(const QString& text);
|
||||||
|
private:
|
||||||
|
QJsonObject createMessage(const QString& role,const QString& content);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNetworkAccessManager* networkManager;
|
||||||
|
QJsonArray messages;
|
||||||
|
QString baseKey = "c2stbXgxWm5MQkZ5TzhNYzNmRWl6eDZUM0JsYmtGSnNBWjNiakJjSXB6WGN3QW9KSk11";
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHATCONTROLLER_H
|
101
example/T_Badge.qml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
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:"Badge"
|
||||||
|
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: parent.width
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 106
|
||||||
|
paddings: 10
|
||||||
|
|
||||||
|
Column{
|
||||||
|
spacing: 15
|
||||||
|
anchors{
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
FluText{
|
||||||
|
text:"一般出现在通知图标或头像的右上角,用于显示需要处理的消息条数"
|
||||||
|
}
|
||||||
|
|
||||||
|
Row{
|
||||||
|
spacing: 20
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
count:0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
count:5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
count:50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
count:100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
isDot:true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
count:99
|
||||||
|
color: Qt.rgba(250/255,173/255,20/255,1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(191/255,191/255,191/255,1)
|
||||||
|
FluBadge{
|
||||||
|
count:99
|
||||||
|
color: Qt.rgba(82/255,196/255,26/255,1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -40,8 +40,6 @@ FluScrollablePage{
|
|||||||
FluToggleSwitch{
|
FluToggleSwitch{
|
||||||
id:button_switch
|
id:button_switch
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
}
|
|
||||||
FluText{
|
|
||||||
text:"Disabled"
|
text:"Disabled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,8 +71,6 @@ FluScrollablePage{
|
|||||||
FluToggleSwitch{
|
FluToggleSwitch{
|
||||||
id:filled_button_switch
|
id:filled_button_switch
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
}
|
|
||||||
FluText{
|
|
||||||
text:"Disabled"
|
text:"Disabled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,8 +104,47 @@ FluScrollablePage{
|
|||||||
FluToggleSwitch{
|
FluToggleSwitch{
|
||||||
id:icon_button_switch
|
id:icon_button_switch
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text:"Disabled"
|
||||||
}
|
}
|
||||||
FluText{
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
text:"Disabled"
|
text:"Disabled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,8 +186,6 @@ FluScrollablePage{
|
|||||||
FluToggleSwitch{
|
FluToggleSwitch{
|
||||||
id:radio_button_switch
|
id:radio_button_switch
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
}
|
|
||||||
FluText{
|
|
||||||
text:"Disabled"
|
text:"Disabled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,10 +216,10 @@ FluScrollablePage{
|
|||||||
FluToggleSwitch{
|
FluToggleSwitch{
|
||||||
id:check_box_switch
|
id:check_box_switch
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
}
|
|
||||||
FluText{
|
|
||||||
text:"Disabled"
|
text:"Disabled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
36
example/T_Carousel.qml
Normal 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"}])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,17 +13,26 @@ FluScrollablePage{
|
|||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
placeholderText: "单行输入框"
|
placeholderText: "单行输入框"
|
||||||
Layout.preferredWidth: 300
|
Layout.preferredWidth: 300
|
||||||
|
disabled:toggle_switch.selected
|
||||||
}
|
}
|
||||||
FluMultiLineTextBox{
|
FluMultiLineTextBox{
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
Layout.preferredWidth: 300
|
Layout.preferredWidth: 300
|
||||||
placeholderText: "多行输入框"
|
placeholderText: "多行输入框"
|
||||||
|
disabled:toggle_switch.selected
|
||||||
}
|
}
|
||||||
FluAutoSuggestBox{
|
FluAutoSuggestBox{
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
values:generateRandomNames(100)
|
values:generateRandomNames(100)
|
||||||
placeholderText: "AutoSuggestBox"
|
placeholderText: "AutoSuggestBox"
|
||||||
Layout.preferredWidth: 300
|
Layout.preferredWidth: 300
|
||||||
|
disabled:toggle_switch.selected
|
||||||
|
}
|
||||||
|
|
||||||
|
FluToggleSwitch{
|
||||||
|
id:toggle_switch
|
||||||
|
text:"Disabled"
|
||||||
|
Layout.topMargin: 20
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateRandomNames(numNames) {
|
function generateRandomNames(numNames) {
|
||||||
|
@ -12,4 +12,8 @@ FluScrollablePage{
|
|||||||
FluToggleSwitch{
|
FluToggleSwitch{
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
}
|
}
|
||||||
|
FluToggleSwitch{
|
||||||
|
Layout.topMargin: 20
|
||||||
|
text:"Disabled"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
75
example/T_Tooltip.qml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtGraphicalEffects 1.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Tooltip"
|
||||||
|
|
||||||
|
FluText{
|
||||||
|
Layout.topMargin: 20
|
||||||
|
text:"鼠标悬停不动,弹出Tooltip"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: parent.width
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 68
|
||||||
|
paddings: 10
|
||||||
|
|
||||||
|
Column{
|
||||||
|
spacing: 5
|
||||||
|
anchors{
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
FluText{
|
||||||
|
text:"FluIconButton的text属性自带Tooltip效果"
|
||||||
|
}
|
||||||
|
FluIconButton{
|
||||||
|
iconSource:FluentIcons.ChromeCloseContrast
|
||||||
|
iconSize: 15
|
||||||
|
text:"删除"
|
||||||
|
onClicked:{
|
||||||
|
showSuccess("点击IconButton")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: parent.width
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 68
|
||||||
|
paddings: 10
|
||||||
|
|
||||||
|
Column{
|
||||||
|
spacing: 5
|
||||||
|
anchors{
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
FluText{
|
||||||
|
text:"给一个Button添加Tooltip效果"
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
id:button_1
|
||||||
|
text:"删除"
|
||||||
|
onClicked:{
|
||||||
|
showSuccess("点击一个Button")
|
||||||
|
}
|
||||||
|
FluTooltip{
|
||||||
|
visible: button_1.hovered
|
||||||
|
text:button_1.text
|
||||||
|
delay: 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,13 +1,16 @@
|
|||||||
QT += quick concurrent
|
QT += quick concurrent network
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
|
||||||
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
|
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
ChatController.cpp \
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
RESOURCES += qml.qrc
|
RESOURCES += qml.qrc
|
||||||
|
|
||||||
|
RC_ICONS = favicon.ico
|
||||||
|
|
||||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
#!isEmpty(target.path): INSTALLS += target
|
#!isEmpty(target.path): INSTALLS += target
|
||||||
@ -22,3 +25,27 @@ CONFIG(debug,debug|release) {
|
|||||||
} else {
|
} else {
|
||||||
DESTDIR = $$absolute_path($${_PRO_FILE_PWD_}/../bin/release)
|
DESTDIR = $$absolute_path($${_PRO_FILE_PWD_}/../bin/release)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
win32 {
|
||||||
|
|
||||||
|
contains(QT_ARCH, i386) {
|
||||||
|
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/Win_x86/*.dll) $$DESTDIR
|
||||||
|
contains(QMAKE_CC, cl) {
|
||||||
|
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, \\)
|
||||||
|
} else {
|
||||||
|
QMAKE_PRE_LINK += $$QMAKE_COPY $$COPYDLL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/Win_x64/*.dll) $$DESTDIR
|
||||||
|
contains(QMAKE_CC, cl) {
|
||||||
|
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, \\)
|
||||||
|
} else {
|
||||||
|
QMAKE_PRE_LINK += $$QMAKE_COPY $$COPYDLL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
ChatController.h
|
||||||
|
BIN
example/favicon.ico
Normal file
After Width: | Height: | Size: 272 KiB |
@ -4,6 +4,7 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include "ChatController.h"
|
||||||
|
|
||||||
QMap<QString, QVariant> properties(){
|
QMap<QString, QVariant> properties(){
|
||||||
QMap<QString, QVariant> map;
|
QMap<QString, QVariant> map;
|
||||||
@ -20,6 +21,9 @@ int main(int argc, char *argv[])
|
|||||||
// QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
|
// QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
qmlRegisterType<ChatController>("Controller",1,0,"ChatController");
|
||||||
|
|
||||||
QMapIterator<QString, QVariant> iterator(properties());
|
QMapIterator<QString, QVariant> iterator(properties());
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
iterator.next();
|
iterator.next();
|
||||||
|
@ -34,7 +34,7 @@ FluWindow {
|
|||||||
fontStyle: FluText.Title
|
fontStyle: FluText.Title
|
||||||
}
|
}
|
||||||
FluText{
|
FluText{
|
||||||
text:"v1.0.7"
|
text:"v1.1.1"
|
||||||
fontStyle: FluText.Body
|
fontStyle: FluText.Body
|
||||||
Layout.alignment: Qt.AlignBottom
|
Layout.alignment: Qt.AlignBottom
|
||||||
}
|
}
|
||||||
|
261
example/page/ChatPage.qml
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import Controller 1.0
|
||||||
|
import QtQuick.Dialogs 1.3
|
||||||
|
|
||||||
|
FluWindow {
|
||||||
|
|
||||||
|
width: 680
|
||||||
|
height: 600
|
||||||
|
minimumWidth: 500
|
||||||
|
minimumHeight: 600
|
||||||
|
|
||||||
|
title:"ChatGPT"
|
||||||
|
|
||||||
|
onInitArgument:
|
||||||
|
(argument)=>{
|
||||||
|
scrollview.focus = true
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatController{
|
||||||
|
id:controller
|
||||||
|
|
||||||
|
onResponseDataChanged: {
|
||||||
|
appendMessage(false,responseData)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{
|
||||||
|
id:model_message
|
||||||
|
ListElement{
|
||||||
|
isMy:false
|
||||||
|
text:"欢迎使用ChatGPT"
|
||||||
|
}
|
||||||
|
ListElement{
|
||||||
|
isMy:true
|
||||||
|
text:"好的,3Q"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluAppBar{
|
||||||
|
id:appbar
|
||||||
|
title:"ChatGPT"
|
||||||
|
}
|
||||||
|
|
||||||
|
Component{
|
||||||
|
id:com_text
|
||||||
|
TextEdit {
|
||||||
|
id:item_text
|
||||||
|
text: message
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
readOnly: true
|
||||||
|
selectByMouse: true
|
||||||
|
selectByKeyboard: true
|
||||||
|
selectedTextColor: Qt.rgba(51,153,255,1)
|
||||||
|
color:FluColors.Black
|
||||||
|
selectionColor: {
|
||||||
|
if(FluTheme.isDark){
|
||||||
|
return FluTheme.primaryColor.lighter
|
||||||
|
}else{
|
||||||
|
return FluTheme.primaryColor.dark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width: Math.min(list_message.width-200,600,implicitWidth)
|
||||||
|
TapHandler{
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onTapped: {
|
||||||
|
menu_item.showMenu(item_text.selectedText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
id:layout_content
|
||||||
|
anchors{
|
||||||
|
top: appbar.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: layout_bottom.top
|
||||||
|
margins: 10
|
||||||
|
}
|
||||||
|
color: FluTheme.isDark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(245/255,245/255,245/255,1)
|
||||||
|
ListView{
|
||||||
|
id:list_message
|
||||||
|
anchors.fill: parent
|
||||||
|
model:model_message
|
||||||
|
clip: true
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
header:Item{
|
||||||
|
width: list_message.width
|
||||||
|
height:20
|
||||||
|
}
|
||||||
|
footer:Item{
|
||||||
|
width: list_message.width
|
||||||
|
height:20
|
||||||
|
}
|
||||||
|
delegate: Item{
|
||||||
|
width: ListView.view.width
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
FluRectangle{
|
||||||
|
id:item_avatar
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
radius:[15,15,15,15]
|
||||||
|
anchors{
|
||||||
|
right: isMy ? parent.right : undefined
|
||||||
|
rightMargin: isMy ? 20 : undefined
|
||||||
|
left: isMy ? undefined : parent.left
|
||||||
|
leftMargin: isMy ? undefined : 20
|
||||||
|
top:parent.top
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
asynchronous: true
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceSize: Qt.size(100,100)
|
||||||
|
source: isMy ? "qrc:/res/svg/avatar_2.svg" : "qrc:/res/image/logo_openai.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
id:item_layout_content
|
||||||
|
color: isMy ? "#FF95EC69" : "#FFFFFF"
|
||||||
|
width: item_msg_loader.width+10
|
||||||
|
height: item_msg_loader.height+10
|
||||||
|
radius: 3
|
||||||
|
anchors{
|
||||||
|
top: item_avatar.top
|
||||||
|
right: isMy ? item_avatar.left : undefined
|
||||||
|
rightMargin: isMy ? 10 : undefined
|
||||||
|
left: isMy ? undefined : item_avatar.right
|
||||||
|
leftMargin: isMy ? undefined : 10
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader{
|
||||||
|
id:item_msg_loader
|
||||||
|
property var message: model.text
|
||||||
|
anchors.centerIn: parent
|
||||||
|
sourceComponent: com_text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item{
|
||||||
|
id:item_layout_bottom
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: item_layout_content.bottom
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
id:layout_bottom
|
||||||
|
height: 90
|
||||||
|
anchors{
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: 10
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
leftMargin: 10
|
||||||
|
rightMargin: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScrollView{
|
||||||
|
id:scrollview
|
||||||
|
anchors{
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: button_send.left
|
||||||
|
bottomMargin: 10
|
||||||
|
leftMargin: 10
|
||||||
|
rightMargin: 10
|
||||||
|
}
|
||||||
|
height: Math.min(textbox.implicitHeight,64)
|
||||||
|
FluMultiLineTextBox{
|
||||||
|
id:textbox
|
||||||
|
focus:true
|
||||||
|
placeholderText: "请输入消息"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluFilledButton{
|
||||||
|
id:button_send
|
||||||
|
text:controller.isLoading ? timer_loading.loadingText :"发送"
|
||||||
|
anchors{
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: parent.right
|
||||||
|
bottomMargin: 10
|
||||||
|
rightMargin: 10
|
||||||
|
}
|
||||||
|
width: 60
|
||||||
|
disabled: controller.isLoading
|
||||||
|
onClicked:{
|
||||||
|
var text = textbox.text
|
||||||
|
appendMessage(true,text)
|
||||||
|
controller.sendMessage(text)
|
||||||
|
textbox.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id:timer_loading
|
||||||
|
property int count : 0
|
||||||
|
property string loadingText : ""
|
||||||
|
interval: 500
|
||||||
|
running: controller.isLoading
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
switch(count%3){
|
||||||
|
case 0:
|
||||||
|
loadingText = "."
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
loadingText = ".."
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
loadingText = "..."
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
loadingText = ""
|
||||||
|
break
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluMenu{
|
||||||
|
id:menu_item
|
||||||
|
focus: false
|
||||||
|
property string selectedText: ""
|
||||||
|
FluMenuItem{
|
||||||
|
text:"复制"
|
||||||
|
onClicked: {
|
||||||
|
controller.clipText(menu_item.selectedText)
|
||||||
|
showSuccess("复制成功")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function showMenu(text){
|
||||||
|
menu_item.selectedText = text
|
||||||
|
menu_item.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendMessage(isMy,text){
|
||||||
|
model_message.append({isMy:isMy,text:text})
|
||||||
|
list_message.positionViewAtEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,6 @@ FluWindow {
|
|||||||
title: "FluentUI"
|
title: "FluentUI"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FluObject{
|
FluObject{
|
||||||
id:original_items
|
id:original_items
|
||||||
|
|
||||||
@ -59,13 +58,6 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FluPaneItem{
|
|
||||||
title:"Menu"
|
|
||||||
onTap:{
|
|
||||||
nav_view.push("qrc:/T_Menu.qml")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TimePicker"
|
title:"TimePicker"
|
||||||
onTap:{
|
onTap:{
|
||||||
@ -97,12 +89,28 @@ FluWindow {
|
|||||||
nav_view.push("qrc:/T_Progress.qml")
|
nav_view.push("qrc:/T_Progress.qml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluPaneItem{
|
||||||
|
title:"Badge"
|
||||||
|
onTap:{
|
||||||
|
nav_view.push("qrc:/T_Badge.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Rectangle"
|
title:"Rectangle"
|
||||||
onTap:{
|
onTap:{
|
||||||
nav_view.push("qrc:/T_Rectangle.qml")
|
nav_view.push("qrc:/T_Rectangle.qml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluPaneItem{
|
||||||
|
title:"Carousel"
|
||||||
|
onTap:{
|
||||||
|
nav_view.push("qrc:/T_Carousel.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Expander"
|
title:"Expander"
|
||||||
onTap:{
|
onTap:{
|
||||||
@ -114,7 +122,6 @@ FluWindow {
|
|||||||
title:"Popus"
|
title:"Popus"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Dialog"
|
title:"Dialog"
|
||||||
onTap:{
|
onTap:{
|
||||||
@ -122,6 +129,20 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluPaneItem{
|
||||||
|
title:"Tooltip"
|
||||||
|
onTap:{
|
||||||
|
nav_view.push("qrc:/T_Tooltip.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluPaneItem{
|
||||||
|
title:"Menu"
|
||||||
|
onTap:{
|
||||||
|
nav_view.push("qrc:/T_Menu.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluPaneItemHeader{
|
FluPaneItemHeader{
|
||||||
title:"Navigation"
|
title:"Navigation"
|
||||||
}
|
}
|
||||||
@ -196,6 +217,35 @@ FluWindow {
|
|||||||
items:original_items
|
items:original_items
|
||||||
footerItems:footer_items
|
footerItems:footer_items
|
||||||
|
|
||||||
|
actions:[
|
||||||
|
Image {
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
Layout.preferredWidth: 30
|
||||||
|
Layout.preferredHeight: 30
|
||||||
|
sourceSize: Qt.size(60,60)
|
||||||
|
source: "qrc:/res/image/logo_openai.png"
|
||||||
|
Layout.rightMargin: 5
|
||||||
|
MouseArea{
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
FluApp.navigate("/chat")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FluText{
|
||||||
|
text:"夜间模式"
|
||||||
|
fontStyle: FluText.Body
|
||||||
|
},
|
||||||
|
FluToggleSwitch{
|
||||||
|
selected: FluTheme.isDark
|
||||||
|
clickFunc:function(){
|
||||||
|
FluTheme.isDark = !FluTheme.isDark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
nav_view.setCurrentIndex(1)
|
nav_view.setCurrentIndex(1)
|
||||||
nav_view.push("qrc:/T_Buttons.qml")
|
nav_view.push("qrc:/T_Buttons.qml")
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
|
|
||||||
<file>App.qml</file>
|
<file>App.qml</file>
|
||||||
|
|
||||||
<file>res/image/image_huoyin.webp</file>
|
<file>res/image/image_huoyin.webp</file>
|
||||||
<file>res/svg/avatar_1.svg</file>
|
<file>res/svg/avatar_1.svg</file>
|
||||||
<file>res/svg/avatar_2.svg</file>
|
<file>res/svg/avatar_2.svg</file>
|
||||||
@ -16,11 +14,9 @@
|
|||||||
<file>res/svg/avatar_10.svg</file>
|
<file>res/svg/avatar_10.svg</file>
|
||||||
<file>res/svg/avatar_11.svg</file>
|
<file>res/svg/avatar_11.svg</file>
|
||||||
<file>res/svg/avatar_12.svg</file>
|
<file>res/svg/avatar_12.svg</file>
|
||||||
|
|
||||||
<file>page/AboutPage.qml</file>
|
<file>page/AboutPage.qml</file>
|
||||||
<file>page/MainPage.qml</file>
|
<file>page/MainPage.qml</file>
|
||||||
<file>page/LoginPage.qml</file>
|
<file>page/LoginPage.qml</file>
|
||||||
|
|
||||||
<file>T_ToggleSwitch.qml</file>
|
<file>T_ToggleSwitch.qml</file>
|
||||||
<file>T_Typography.qml</file>
|
<file>T_Typography.qml</file>
|
||||||
<file>T_Awesome.qml</file>
|
<file>T_Awesome.qml</file>
|
||||||
@ -38,5 +34,13 @@
|
|||||||
<file>T_DatePicker.qml</file>
|
<file>T_DatePicker.qml</file>
|
||||||
<file>T_MultiWindow.qml</file>
|
<file>T_MultiWindow.qml</file>
|
||||||
<file>T_Menu.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>
|
||||||
|
<file>res/image/logo_openai.png</file>
|
||||||
|
<file>page/ChatPage.qml</file>
|
||||||
|
<file>T_Tooltip.qml</file>
|
||||||
|
<file>T_Badge.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
BIN
example/res/image/banner_1.jpg
Normal file
After Width: | Height: | Size: 300 KiB |
BIN
example/res/image/banner_2.jpg
Normal file
After Width: | Height: | Size: 298 KiB |
BIN
example/res/image/banner_3.jpg
Normal file
After Width: | Height: | Size: 130 KiB |
BIN
example/res/image/logo_openai.png
Normal file
After Width: | Height: | Size: 22 KiB |
@ -17,7 +17,7 @@ function Main() {
|
|||||||
|
|
||||||
New-Item -ItemType Directory $archiveName
|
New-Item -ItemType Directory $archiveName
|
||||||
# 拷贝exe
|
# 拷贝exe
|
||||||
Copy-Item bin\release\$targetName $archiveName\
|
Copy-Item bin\release\* $archiveName\
|
||||||
# 拷贝依赖
|
# 拷贝依赖
|
||||||
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
|
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
|
||||||
# 删除不必要的文件
|
# 删除不必要的文件
|
||||||
|
@ -27,7 +27,7 @@ function Main() {
|
|||||||
|
|
||||||
New-Item -ItemType Directory $archiveName
|
New-Item -ItemType Directory $archiveName
|
||||||
# 拷贝exe
|
# 拷贝exe
|
||||||
Copy-Item bin\release\$targetName $archiveName\
|
Copy-Item bin\release\* $archiveName\
|
||||||
# 拷贝依赖
|
# 拷贝依赖
|
||||||
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
|
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
|
||||||
# 删除不必要的文件
|
# 删除不必要的文件
|
||||||
|
@ -35,6 +35,7 @@ void Fluent::registerTypes(const char *uri){
|
|||||||
|
|
||||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluArea.qml"),uri,major,minor,"FluArea");
|
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluArea.qml"),uri,major,minor,"FluArea");
|
||||||
|
|
||||||
|
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluBadge.qml"),uri,major,minor,"FluBadge");
|
||||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentPage.qml"),uri,major,minor,"FluContentPage");
|
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentPage.qml"),uri,major,minor,"FluContentPage");
|
||||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollablePage.qml"),uri,major,minor,"FluScrollablePage");
|
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollablePage.qml"),uri,major,minor,"FluScrollablePage");
|
||||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemHeader.qml"),uri,major,minor,"FluPaneItemHeader");
|
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemHeader.qml"),uri,major,minor,"FluPaneItemHeader");
|
||||||
@ -47,6 +48,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/FluDatePicker.qml"),uri,major,minor,"FluDatePicker");
|
||||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTimePicker.qml"),uri,major,minor,"FluTimePicker");
|
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/FluAutoSuggestBox.qml"),uri,major,minor,"FluAutoSuggestBox");
|
||||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluExpander.qml"),uri,major,minor,"FluExpander");
|
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluExpander.qml"),uri,major,minor,"FluExpander");
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
#include <QQuickView>
|
#include <QQuickView>
|
||||||
#include <QRegion>
|
#include <QRegion>
|
||||||
|
|
||||||
//无边框窗口,主要用来实现自定义标题栏。
|
|
||||||
//Windows平台支持拖动和改变大小,支持Aero效果
|
|
||||||
//非Windows平台,去掉边框,不做其它处理。由Qml模拟resize和拖动。
|
|
||||||
class FramelessViewPrivate;
|
class FramelessViewPrivate;
|
||||||
class FramelessView : public QQuickView
|
class FramelessView : public QQuickView
|
||||||
{
|
{
|
||||||
|
@ -8,11 +8,18 @@ TextField{
|
|||||||
property int fontStyle: FluText.Body
|
property int fontStyle: FluText.Body
|
||||||
property int pixelSize : FluTheme.textSize
|
property int pixelSize : FluTheme.textSize
|
||||||
property int iconSource: 0
|
property int iconSource: 0
|
||||||
|
property bool disabled: false
|
||||||
signal itemClicked(string data)
|
signal itemClicked(string data)
|
||||||
|
|
||||||
id:input
|
id:input
|
||||||
width: 300
|
width: 300
|
||||||
color: FluTheme.isDark ? "#FFFFFF" : "#1A1A1A"
|
enabled: !disabled
|
||||||
|
color: {
|
||||||
|
if(disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||||
|
}
|
||||||
|
return FluTheme.isDark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||||
|
}
|
||||||
selectionColor: {
|
selectionColor: {
|
||||||
if(FluTheme.isDark){
|
if(FluTheme.isDark){
|
||||||
return FluTheme.primaryColor.lighter
|
return FluTheme.primaryColor.lighter
|
||||||
@ -22,6 +29,9 @@ TextField{
|
|||||||
}
|
}
|
||||||
renderType: FluTheme.isNativeText ? Text.NativeRendering : Text.QtRendering
|
renderType: FluTheme.isNativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
placeholderTextColor: {
|
placeholderTextColor: {
|
||||||
|
if(disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||||
|
}
|
||||||
if(focus){
|
if(focus){
|
||||||
return FluTheme.isDark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
return FluTheme.isDark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||||
}
|
}
|
||||||
@ -152,6 +162,7 @@ TextField{
|
|||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
clip: true
|
clip: true
|
||||||
currentIndex: -1
|
currentIndex: -1
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
header: Item{
|
header: Item{
|
||||||
width: input.width
|
width: input.width
|
||||||
height: visible ? 38 : 0
|
height: visible ? 38 : 0
|
||||||
@ -165,7 +176,6 @@ TextField{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScrollBar.vertical: ScrollBar { }
|
|
||||||
delegate:Control{
|
delegate:Control{
|
||||||
width: input.width
|
width: input.width
|
||||||
padding:10
|
padding:10
|
||||||
|
77
src/controls/FluBadge.qml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
|
||||||
|
property bool isDot: false
|
||||||
|
property bool showZero: true
|
||||||
|
property int count: 0
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
visible: {
|
||||||
|
if(showZero)
|
||||||
|
return true
|
||||||
|
return count!==0
|
||||||
|
}
|
||||||
|
anchors{
|
||||||
|
right: {
|
||||||
|
if(parent)
|
||||||
|
return parent.right
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
top: {
|
||||||
|
if(parent)
|
||||||
|
return parent.top
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
rightMargin: {
|
||||||
|
if(isDot){
|
||||||
|
return -2.5
|
||||||
|
}
|
||||||
|
return -(control.width/2)
|
||||||
|
}
|
||||||
|
topMargin: {
|
||||||
|
if(isDot){
|
||||||
|
return -2.5
|
||||||
|
}
|
||||||
|
return -10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: Qt.rgba(1,1,1,1)
|
||||||
|
visible: !isDot
|
||||||
|
text:{
|
||||||
|
if(count<100)
|
||||||
|
return count
|
||||||
|
return count+"+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -36,7 +36,6 @@ Button {
|
|||||||
}
|
}
|
||||||
contentItem: FluText {
|
contentItem: FluText {
|
||||||
text: control.text
|
text: control.text
|
||||||
anchors.centerIn: parent
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
color: {
|
color: {
|
||||||
|
136
src/controls/FluCarousel.qml
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -202,9 +202,12 @@ Rectangle {
|
|||||||
width: 100
|
width: 100
|
||||||
height: parent.height
|
height: parent.height
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
ScrollBar.vertical: ScrollBar { }
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
model: generateYearArray(1924,2048)
|
model: generateYearArray(1924,2048)
|
||||||
clip: true
|
clip: true
|
||||||
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
visible: showYear
|
visible: showYear
|
||||||
delegate: Loader{
|
delegate: Loader{
|
||||||
property var model: modelData
|
property var model: modelData
|
||||||
@ -212,11 +215,6 @@ Rectangle {
|
|||||||
property int position:index
|
property int position:index
|
||||||
sourceComponent: list_delegate
|
sourceComponent: list_delegate
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
|
||||||
if(currentIndex!==-1){
|
|
||||||
list_view_1.positionViewAtIndex(currentIndex, ListView.NoPosition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
width: 1
|
width: 1
|
||||||
@ -228,7 +226,10 @@ Rectangle {
|
|||||||
width: showYear ? 100 : 150
|
width: showYear ? 100 : 150
|
||||||
height: parent.height
|
height: parent.height
|
||||||
clip: true
|
clip: true
|
||||||
ScrollBar.vertical: ScrollBar { }
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
delegate: Loader{
|
delegate: Loader{
|
||||||
property var model: modelData
|
property var model: modelData
|
||||||
@ -236,11 +237,6 @@ Rectangle {
|
|||||||
property int position:index
|
property int position:index
|
||||||
sourceComponent: list_delegate
|
sourceComponent: list_delegate
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
|
||||||
if(currentIndex!==-1){
|
|
||||||
list_view_2.positionViewAtIndex(currentIndex, ListView.NoPosition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
width: 1
|
width: 1
|
||||||
@ -252,7 +248,10 @@ Rectangle {
|
|||||||
width: showYear ? 100 : 150
|
width: showYear ? 100 : 150
|
||||||
height: parent.height
|
height: parent.height
|
||||||
clip: true
|
clip: true
|
||||||
ScrollBar.vertical: ScrollBar { }
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
delegate: Loader{
|
delegate: Loader{
|
||||||
@ -261,9 +260,6 @@ Rectangle {
|
|||||||
property int position:index
|
property int position:index
|
||||||
sourceComponent: list_delegate
|
sourceComponent: list_delegate
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
|
||||||
list_view_3.positionViewAtIndex(currentIndex, ListView.NoPosition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,10 +344,12 @@ Rectangle {
|
|||||||
text_day.text = day
|
text_day.text = day
|
||||||
|
|
||||||
var pos = root.mapToItem(null, 0, 0)
|
var pos = root.mapToItem(null, 0, 0)
|
||||||
if(window.height>pos.y+35+340){
|
if(window.height>pos.y+root.height+popup.height){
|
||||||
popup.y = 35
|
popup.y = root.height
|
||||||
|
} else if(pos.y>popup.height){
|
||||||
|
popup.y = -popup.height
|
||||||
} else {
|
} else {
|
||||||
popup.y = window.height-(pos.y+340)
|
popup.y = window.height-(pos.y+popup.height)
|
||||||
}
|
}
|
||||||
popup.open()
|
popup.open()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,89 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
import FluentUI 1.0
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,27 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
|
import QtGraphicalEffects 1.15
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
id: popup
|
id: popup
|
||||||
default property alias content: container.data
|
default property alias content: container.data
|
||||||
|
|
||||||
background: Rectangle {
|
width: 140
|
||||||
implicitWidth: 140
|
height: container.height
|
||||||
implicitHeight: container.height
|
|
||||||
color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1)
|
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
|
radius: 5
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: GaussianBlur {
|
||||||
|
radius: 8
|
||||||
|
samples: 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluShadow{
|
FluShadow{
|
||||||
radius: 5
|
radius: 5
|
||||||
@ -19,6 +30,7 @@ Menu {
|
|||||||
spacing: 5
|
spacing: 5
|
||||||
topPadding: 5
|
topPadding: 5
|
||||||
bottomPadding: 5
|
bottomPadding: 5
|
||||||
|
width: popup.width
|
||||||
id:container
|
id:container
|
||||||
function closePopup(){
|
function closePopup(){
|
||||||
popup.close()
|
popup.close()
|
||||||
|
@ -4,7 +4,12 @@ import QtQuick.Controls 2.15
|
|||||||
Item {
|
Item {
|
||||||
|
|
||||||
id:root
|
id:root
|
||||||
width: 140
|
width: {
|
||||||
|
if(root.parent){
|
||||||
|
return root.parent.width
|
||||||
|
}
|
||||||
|
return 140
|
||||||
|
}
|
||||||
height: 32
|
height: 32
|
||||||
|
|
||||||
property string text: "MenuItem"
|
property string text: "MenuItem"
|
||||||
@ -12,14 +17,21 @@ Item {
|
|||||||
|
|
||||||
Rectangle{
|
Rectangle{
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 100
|
width: root.width-40
|
||||||
height: 32
|
height: 32
|
||||||
radius: 4
|
radius: 4
|
||||||
color:{
|
color:{
|
||||||
|
if(FluTheme.isDark){
|
||||||
if(mouse_area.containsMouse){
|
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)
|
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{
|
FluText{
|
||||||
|
@ -6,10 +6,17 @@ TextArea{
|
|||||||
|
|
||||||
property int fontStyle: FluText.Body
|
property int fontStyle: FluText.Body
|
||||||
property int pixelSize : FluTheme.textSize
|
property int pixelSize : FluTheme.textSize
|
||||||
|
property bool disabled: false
|
||||||
|
|
||||||
id:input
|
id:input
|
||||||
width: 300
|
width: 300
|
||||||
color: FluTheme.isDark ? "#FFFFFF" : "#1A1A1A"
|
color: {
|
||||||
|
if(disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||||
|
}
|
||||||
|
return FluTheme.isDark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||||
|
}
|
||||||
|
enabled: !disabled
|
||||||
wrapMode: Text.WrapAnywhere
|
wrapMode: Text.WrapAnywhere
|
||||||
renderType: FluTheme.isNativeText ? Text.NativeRendering : Text.QtRendering
|
renderType: FluTheme.isNativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
@ -24,6 +31,9 @@ TextArea{
|
|||||||
inputItem: input
|
inputItem: input
|
||||||
}
|
}
|
||||||
placeholderTextColor: {
|
placeholderTextColor: {
|
||||||
|
if(disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||||
|
}
|
||||||
if(focus){
|
if(focus){
|
||||||
return FluTheme.isDark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
return FluTheme.isDark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@ Item {
|
|||||||
|
|
||||||
property bool displaMinimalNav : false
|
property bool displaMinimalNav : false
|
||||||
|
|
||||||
|
property alias actions: layout_actions.data
|
||||||
|
|
||||||
onDisplayModeChanged: {
|
onDisplayModeChanged: {
|
||||||
if(displayMode === FluNavigationView.Minimal){
|
if(displayMode === FluNavigationView.Minimal){
|
||||||
anim_navi.enabled = false
|
anim_navi.enabled = false
|
||||||
@ -135,12 +137,11 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id:nav_app_bar
|
id:nav_app_bar
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 38
|
height: 38
|
||||||
|
z:999
|
||||||
RowLayout{
|
RowLayout{
|
||||||
height:parent.height
|
height:parent.height
|
||||||
spacing: 0
|
spacing: 0
|
||||||
@ -173,22 +174,13 @@ Item {
|
|||||||
|
|
||||||
|
|
||||||
RowLayout{
|
RowLayout{
|
||||||
|
id:layout_actions
|
||||||
anchors{
|
anchors{
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: 14
|
rightMargin: 14
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
spacing: 5
|
spacing: 5
|
||||||
FluText{
|
|
||||||
text:"夜间模式"
|
|
||||||
fontStyle: FluText.Body
|
|
||||||
}
|
|
||||||
FluToggleSwitch{
|
|
||||||
selected: FluTheme.isDark
|
|
||||||
clickFunc:function(){
|
|
||||||
FluTheme.isDark = !FluTheme.isDark
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +224,7 @@ Item {
|
|||||||
id:layout_list
|
id:layout_list
|
||||||
width: 300
|
width: 300
|
||||||
anchors{
|
anchors{
|
||||||
top: nav_app_bar.bottom
|
top: parent.top
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
x: {
|
x: {
|
||||||
@ -264,6 +256,7 @@ Item {
|
|||||||
Item{
|
Item{
|
||||||
id:layout_header
|
id:layout_header
|
||||||
width: layout_list.width
|
width: layout_list.width
|
||||||
|
y:nav_app_bar.height
|
||||||
height: 50
|
height: 50
|
||||||
|
|
||||||
FluAutoSuggestBox{
|
FluAutoSuggestBox{
|
||||||
@ -322,6 +315,8 @@ Item {
|
|||||||
stackIndex.push(currentIndex)
|
stackIndex.push(currentIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
|
||||||
model:{
|
model:{
|
||||||
if(items){
|
if(items){
|
||||||
return items.children
|
return items.children
|
||||||
@ -375,11 +370,8 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function push(url){
|
function push(url){
|
||||||
nav_swipe.push(url)
|
nav_swipe.push(url)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ Button {
|
|||||||
if(selected&&disabled){
|
if(selected&&disabled){
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
if(hovered){
|
if(pressed){
|
||||||
if(selected){
|
if(selected){
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ Button {
|
|||||||
}
|
}
|
||||||
Behavior on border.width {
|
Behavior on border.width {
|
||||||
NumberAnimation{
|
NumberAnimation{
|
||||||
duration: 100
|
duration: 150
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
border.color: {
|
border.color: {
|
||||||
|
@ -6,10 +6,8 @@ Item{
|
|||||||
id:root
|
id:root
|
||||||
property var radius:[0,0,0,0]
|
property var radius:[0,0,0,0]
|
||||||
property color color : "#FFFFFF"
|
property color color : "#FFFFFF"
|
||||||
property color borderColor:"red"
|
|
||||||
property int borderWidth: 1
|
|
||||||
property bool shadow: true
|
property bool shadow: true
|
||||||
default property alias contentItem: container.children
|
default property alias contentItem: container.data
|
||||||
|
|
||||||
Rectangle{
|
Rectangle{
|
||||||
id:container
|
id:container
|
||||||
|
@ -17,10 +17,13 @@ Item {
|
|||||||
fontStyle: FluText.TitleLarge
|
fontStyle: FluText.TitleLarge
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView{
|
Flickable{
|
||||||
clip: true
|
clip: true
|
||||||
width: parent.width
|
width: parent.width
|
||||||
contentWidth: parent.width
|
contentWidth: parent.width
|
||||||
|
contentHeight: container.height
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
ScrollBar.vertical: ScrollBar { }
|
||||||
anchors{
|
anchors{
|
||||||
top: text_title.bottom
|
top: text_title.bottom
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
|
@ -4,9 +4,9 @@ Item {
|
|||||||
id:root
|
id:root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: -4
|
anchors.margins: -4
|
||||||
property color color: FluTheme.isDark ? "#FFFFFF" : "#000000"
|
property color color: FluTheme.isDark ? "#FFFFFF" : "#999999"
|
||||||
|
|
||||||
property var radius: 4
|
property int radius: 4
|
||||||
|
|
||||||
Rectangle{
|
Rectangle{
|
||||||
width: root.width
|
width: root.width
|
||||||
|
@ -6,10 +6,17 @@ TextField{
|
|||||||
|
|
||||||
property int fontStyle: FluText.Body
|
property int fontStyle: FluText.Body
|
||||||
property int pixelSize : FluTheme.textSize
|
property int pixelSize : FluTheme.textSize
|
||||||
|
property bool disabled: false
|
||||||
|
|
||||||
id:input
|
id:input
|
||||||
width: 300
|
width: 300
|
||||||
color: FluTheme.isDark ? "#FFFFFF" : "#1A1A1A"
|
enabled: !disabled
|
||||||
|
color: {
|
||||||
|
if(disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||||
|
}
|
||||||
|
return FluTheme.isDark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||||
|
}
|
||||||
renderType: FluTheme.isNativeText ? Text.NativeRendering : Text.QtRendering
|
renderType: FluTheme.isNativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
selectionColor: {
|
selectionColor: {
|
||||||
if(FluTheme.isDark){
|
if(FluTheme.isDark){
|
||||||
@ -19,6 +26,9 @@ TextField{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
placeholderTextColor: {
|
placeholderTextColor: {
|
||||||
|
if(disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||||
|
}
|
||||||
if(focus){
|
if(focus){
|
||||||
return FluTheme.isDark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
return FluTheme.isDark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,13 @@ Rectangle{
|
|||||||
radius: 4
|
radius: 4
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
color: {
|
color: {
|
||||||
if(input.focus){
|
if(inputItem.disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
|
||||||
|
}
|
||||||
|
if(inputItem.focus){
|
||||||
return FluTheme.isDark ? Qt.rgba(36/255,36/255,36/255,1) : Qt.rgba(1,1,1,1)
|
return FluTheme.isDark ? Qt.rgba(36/255,36/255,36/255,1) : Qt.rgba(1,1,1,1)
|
||||||
}
|
}
|
||||||
if(input.hovered){
|
if(inputItem.hovered){
|
||||||
return FluTheme.isDark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
return FluTheme.isDark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||||
}
|
}
|
||||||
return FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(1,1,1,1)
|
return FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(1,1,1,1)
|
||||||
@ -25,16 +28,22 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(238/255,238/255,238/255,1)
|
border.color: {
|
||||||
|
if(inputItem.disabled){
|
||||||
|
return FluTheme.isDark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(237/255,237/255,237/255,1)
|
||||||
|
}
|
||||||
|
return FluTheme.isDark ? Qt.rgba(76/255,76/255,76/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||||
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: input.focus ? 3 : 1
|
height: inputItem.focus ? 3 : 1
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
visible: !inputItem.disabled
|
||||||
color: {
|
color: {
|
||||||
if(FluTheme.isDark){
|
if(FluTheme.isDark){
|
||||||
input.focus ? FluTheme.primaryColor.lighter : Qt.rgba(166/255,166/255,166/255,1)
|
inputItem.focus ? FluTheme.primaryColor.lighter : Qt.rgba(166/255,166/255,166/255,1)
|
||||||
}else{
|
}else{
|
||||||
return input.focus ? FluTheme.primaryColor.dark : Qt.rgba(183/255,183/255,183/255,1)
|
return inputItem.focus ? FluTheme.primaryColor.dark : Qt.rgba(183/255,183/255,183/255,1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Behavior on height{
|
Behavior on height{
|
||||||
|
@ -201,7 +201,10 @@ Rectangle {
|
|||||||
width: isH ? 100 : 150
|
width: isH ? 100 : 150
|
||||||
height: parent.height
|
height: parent.height
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
ScrollBar.vertical: ScrollBar { }
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
model: isH ? generateArray(1,12) : generateArray(0,23)
|
model: isH ? generateArray(1,12) : generateArray(0,23)
|
||||||
clip: true
|
clip: true
|
||||||
delegate: Loader{
|
delegate: Loader{
|
||||||
@ -210,9 +213,6 @@ Rectangle {
|
|||||||
property int position:index
|
property int position:index
|
||||||
sourceComponent: list_delegate
|
sourceComponent: list_delegate
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
|
||||||
list_view_1.positionViewAtIndex(currentIndex, ListView.NoPosition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
width: 1
|
width: 1
|
||||||
@ -225,7 +225,10 @@ Rectangle {
|
|||||||
height: parent.height
|
height: parent.height
|
||||||
model: generateArray(0,59)
|
model: generateArray(0,59)
|
||||||
clip: true
|
clip: true
|
||||||
ScrollBar.vertical: ScrollBar { }
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
delegate: Loader{
|
delegate: Loader{
|
||||||
property var model: modelData
|
property var model: modelData
|
||||||
@ -233,9 +236,6 @@ Rectangle {
|
|||||||
property int position:index
|
property int position:index
|
||||||
sourceComponent: list_delegate
|
sourceComponent: list_delegate
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
|
||||||
list_view_2.positionViewAtIndex(currentIndex, ListView.NoPosition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
width: 1
|
width: 1
|
||||||
@ -250,7 +250,10 @@ Rectangle {
|
|||||||
model: ["上午","下午"]
|
model: ["上午","下午"]
|
||||||
clip: true
|
clip: true
|
||||||
visible: isH
|
visible: isH
|
||||||
ScrollBar.vertical: ScrollBar { }
|
preferredHighlightBegin: 0
|
||||||
|
preferredHighlightEnd: 0
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
delegate: Loader{
|
delegate: Loader{
|
||||||
@ -259,9 +262,6 @@ Rectangle {
|
|||||||
property int position:index
|
property int position:index
|
||||||
sourceComponent: list_delegate
|
sourceComponent: list_delegate
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
|
||||||
list_view_3.positionViewAtIndex(currentIndex, ListView.NoPosition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,10 +358,12 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pos = root.mapToItem(null, 0, 0)
|
var pos = root.mapToItem(null, 0, 0)
|
||||||
if(window.height>pos.y+35+340){
|
if(window.height>pos.y+root.height+popup.height){
|
||||||
popup.y = 35
|
popup.y = root.height
|
||||||
|
} else if(pos.y>popup.height){
|
||||||
|
popup.y = -popup.height
|
||||||
} else {
|
} else {
|
||||||
popup.y = window.height-(pos.y+340)
|
popup.y = window.height-(pos.y+popup.height)
|
||||||
}
|
}
|
||||||
popup.open()
|
popup.open()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtQuick.Controls 2.0
|
import QtQuick.Controls 2.0
|
||||||
import FluentUI 1.0
|
import FluentUI 1.0
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
|
|
||||||
@ -8,10 +9,8 @@ Button {
|
|||||||
property var clickFunc
|
property var clickFunc
|
||||||
|
|
||||||
id: control
|
id: control
|
||||||
width: 40
|
|
||||||
implicitWidth: 40
|
|
||||||
height: 20
|
height: 20
|
||||||
implicitHeight: 20
|
implicitHeight: height
|
||||||
focusPolicy:Qt.TabFocus
|
focusPolicy:Qt.TabFocus
|
||||||
Keys.onSpacePressed: control.visualFocus&&clicked()
|
Keys.onSpacePressed: control.visualFocus&&clicked()
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@ -21,10 +20,18 @@ Button {
|
|||||||
}
|
}
|
||||||
selected = !selected
|
selected = !selected
|
||||||
}
|
}
|
||||||
background : Rectangle {
|
|
||||||
width: control.width
|
contentItem: Item{}
|
||||||
|
|
||||||
|
background : RowLayout{
|
||||||
|
spacing: 0
|
||||||
|
Rectangle {
|
||||||
|
id:control_backgound
|
||||||
|
width: 40
|
||||||
height: control.height
|
height: control.height
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
|
smooth: true
|
||||||
|
antialiasing: true
|
||||||
FluFocusRectangle{
|
FluFocusRectangle{
|
||||||
visible: control.visualFocus
|
visible: control.visualFocus
|
||||||
radius: 20
|
radius: 20
|
||||||
@ -51,17 +58,30 @@ Button {
|
|||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: selected ? Qt.lighter(FluTheme.primaryColor.dark,1.2) : "#666666"
|
border.color: selected ? Qt.lighter(FluTheme.primaryColor.dark,1.2) : "#666666"
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x: selected ? control.implicitWidth - width - 4 : 4
|
x: selected ? control_backgound.width - width - 4 : 4
|
||||||
width: control.height - 8
|
width: control.height - 8
|
||||||
height: control.height - 8
|
height: control.height - 8
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
|
antialiasing: true
|
||||||
scale: hovered ? 1.2 : 1.0
|
scale: hovered ? 1.2 : 1.0
|
||||||
|
smooth: true
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: selected ? "#FFFFFF" : "#666666"
|
color: selected ? "#FFFFFF" : "#666666"
|
||||||
Behavior on x {
|
Behavior on x {
|
||||||
NumberAnimation { duration: 200 }
|
NumberAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: 150 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluText{
|
||||||
|
text: control.text
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
visible: text !== ""
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -276,8 +276,8 @@ Item {
|
|||||||
model: tree_model
|
model: tree_model
|
||||||
flickableDirection: Flickable.HorizontalAndVerticalFlick
|
flickableDirection: Flickable.HorizontalAndVerticalFlick
|
||||||
clip: true
|
clip: true
|
||||||
ScrollBar.vertical: ScrollBar { }
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
ScrollBar.horizontal: ScrollBar { }
|
ScrollBar.horizontal: FluScrollBar { }
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateData(items){
|
function updateData(items){
|
||||||
|
@ -47,5 +47,7 @@
|
|||||||
<file>controls/FluCalenderView.qml</file>
|
<file>controls/FluCalenderView.qml</file>
|
||||||
<file>controls/FluCalendarDatePicker.qml</file>
|
<file>controls/FluCalendarDatePicker.qml</file>
|
||||||
<file>controls/FluFocusRectangle.qml</file>
|
<file>controls/FluFocusRectangle.qml</file>
|
||||||
|
<file>controls/FluCarousel.qml</file>
|
||||||
|
<file>controls/FluBadge.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|