add code.

This commit is contained in:
amass 2024-08-31 12:32:26 +08:00
parent 8b6bce4e3d
commit cbd1b2922f
9 changed files with 387 additions and 1 deletions

View File

@ -20,6 +20,7 @@ qt6_add_qml_module(Fluent
App.h App.cpp
CircularReveal.h CircularReveal.cpp
Colors.h Colors.cpp
FpsItem.h FpsItem.cpp
Frameless.h Frameless.cpp
Icons.h
Rectangle.h Rectangle.cpp
@ -32,6 +33,8 @@ qt6_add_qml_module(Fluent
qml/Button.qml
qml/ContentDialog.qml
qml/ControlBackground.qml
qml/Event.qml
qml/EventBus.qml
qml/FilledButton.qml
qml/FocusRectangle.qml
qml/Icon.qml
@ -42,6 +45,9 @@ qt6_add_qml_module(Fluent
qml/Object.qml
qml/Popup.qml
qml/ProgressRing.qml
qml/RadioButton.qml
qml/RadioButtons.qml
qml/RangeSlider.qml
qml/Router.qml
qml/ScrollBar.qml
qml/Shadow.qml

21
Fluent/FpsItem.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "FpsItem.h"
#include <QTimer>
#include <QQuickWindow>
FpsItem::FpsItem() {
m_fps = 0;
auto *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this] {
fps(_frameCount);
_frameCount = 0;
});
connect(this, &QQuickItem::windowChanged, this, [this] {
if (window()) {
connect(
window(), &QQuickWindow::afterRendering, this, [this] { _frameCount++; },
Qt::DirectConnection);
}
});
timer->start(1000);
}

18
Fluent/FpsItem.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __FPSITEM_H__
#define __FPSITEM_H__
#include "Utilities.h"
#include <QQuickItem>
class FpsItem : public QQuickItem {
Q_OBJECT
QML_ELEMENT
Q_PROPERTY_AUTO(int, fps)
public:
FpsItem();
private:
int _frameCount = 0;
};
#endif // __FPSITEM_H__

15
Fluent/qml/Event.qml Normal file
View File

@ -0,0 +1,15 @@
import QtQuick
import QtQuick.Controls
import FluentUI
QtObject {
id:control
property string name
signal triggered(var data)
Component.onCompleted: {
FluEventBus.register(control)
}
Component.onDestruction: {
FluEventBus.unregister(control)
}
}

24
Fluent/qml/EventBus.qml Normal file
View File

@ -0,0 +1,24 @@
pragma Singleton
import QtQuick
QtObject {
property var events: []
function register(event){
events.push(event)
}
function unregister(event){
var index = events.indexOf(event)
if (index !== -1) {
events.splice(index, 1)
}
}
function post(name,data = {}){
for(var i =0 ;i< events.length; i++){
var item = events[i]
if(item.name === name){
item.triggered(data)
}
}
}
}

View File

@ -0,0 +1,95 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts
import FluentUI
Button {
property string contentDescription: ""
property bool disabled: false
property color borderNormalColor: checked ? FluTheme.primaryColor : FluTheme.dark ? Qt.rgba(161/255,161/255,161/255,1) : Qt.rgba(141/255,141/255,141/255,1)
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(198/255,198/255,198/255,1)
property color normalColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1)
property color hoverColor: checked ? FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)
property color disableColor: checked ? FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(159/255,159/255,159/255,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)
property alias textColor: btn_text.textColor
property real size: 18
property bool textRight: true
property real textSpacing: 6
property var clickListener : function(){
checked = !checked
}
Accessible.role: Accessible.Button
Accessible.name: control.text
Accessible.description: contentDescription
Accessible.onPressAction: control.clicked()
id:control
enabled: !disabled
horizontalPadding:2
verticalPadding: 2
background: Item{
FluFocusRectangle{
visible: control.activeFocus
}
}
focusPolicy:Qt.TabFocus
font:FluTextStyle.Body
onClicked: clickListener()
contentItem: RowLayout{
spacing: control.textSpacing
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
Rectangle{
id:rect_check
width: control.size
height: control.size
radius: size/2
border.width: {
if(checked&&!enabled){
return 3
}
if(pressed){
if(checked){
return 4
}
return 1
}
if(hovered){
if(checked){
return 3
}
return 1
}
return checked ? 4 : 1
}
Behavior on border.width {
enabled: FluTheme.animationEnabled
NumberAnimation{
duration: 167
easing.type: Easing.OutCubic
}
}
border.color: {
if(!enabled){
return borderDisableColor
}
return borderNormalColor
}
color:{
if(!enabled){
return disableColor
}
if(hovered){
return hoverColor
}
return normalColor
}
}
FluText{
id:btn_text
text: control.text
Layout.alignment: Qt.AlignVCenter
font: control.font
visible: text !== ""
}
}
}

View File

@ -0,0 +1,90 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts
import FluentUI
Item{
id:control
default property list<QtObject> buttons
property int currentIndex : -1
property int spacing: 8
property int orientation: Qt.Vertical
property bool disabled: false
property bool manuallyDisabled: false
QtObject{
id: d
function updateChecked(){
if(buttons.length === 0){
return
}
for(var i = 0;i<buttons.length;i++){
buttons[i].checked = false
}
if(currentIndex>=0 && currentIndex<buttons.length){
buttons[currentIndex].checked = true
}
}
function refreshButtonStatus() {
for(var i = 0;i<buttons.length;i++){
if(!manuallyDisabled) buttons[i].enabled = !disabled
}
}
}
implicitWidth: childrenRect.width
implicitHeight: childrenRect.height
onCurrentIndexChanged: {
d.updateChecked()
}
onDisabledChanged: {
d.refreshButtonStatus()
}
onManuallyDisabledChanged: {
d.refreshButtonStatus()
}
Component{
id:com_vertical
ColumnLayout {
data: control.buttons
spacing: control.spacing
Component.onCompleted: {
for(var i = 0;i<control.buttons.length;i++){
control.buttons[i].clickListener = function(){
for(var i = 0;i<control.buttons.length;i++){
var button = control.buttons[i]
if(this === button){
control.currentIndex = i
}
}
}
}
d.updateChecked()
d.refreshButtonStatus()
}
}
}
Component{
id:com_horizontal
RowLayout {
data: control.buttons
spacing: control.spacing
Component.onCompleted: {
for(var i = 0;i<control.buttons.length;i++){
control.buttons[i].clickListener = function(){
for(var i = 0;i<control.buttons.length;i++){
var button = control.buttons[i]
if(this === button){
control.currentIndex = i
}
}
}
}
d.updateChecked()
d.refreshButtonStatus()
}
}
}
FluLoader{
sourceComponent: control.orientation === Qt.Vertical ? com_vertical : com_horizontal
}
}

117
Fluent/qml/RangeSlider.qml Normal file
View File

@ -0,0 +1,117 @@
import QtQuick as Quick
import QtQuick.Controls.impl
import QtQuick.Templates as T
import Fluent
T.RangeSlider {
id: control
property bool tooltipEnabled: true
property bool isTipInt: true
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
first.implicitHandleWidth + leftPadding + rightPadding,
second.implicitHandleWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
first.implicitHandleHeight + topPadding + bottomPadding,
second.implicitHandleHeight + topPadding + bottomPadding)
padding: 6
first.value: 0
second.value: 100
stepSize: 1
from: 0
to:100
snapMode: RangeSlider.SnapAlways
first.handle: Quick.Rectangle {
x: control.leftPadding + (control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height))
implicitWidth: 20
implicitHeight: 20
radius: width / 2
color:Theme.dark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
Shadow{
radius: 10
}
Icon{
width: 10
height: 10
iconSource: Icons.FullCircleMask
iconSize: 10
scale:{
if(control.first.pressed){
return 0.9
}
return control.first.hovered ? 1.2 : 1
}
iconColor: Theme.primaryColor
anchors.centerIn: parent
Quick.Behavior on scale{
Quick.NumberAnimation{
duration: 167
easing.type: Quick.Easing.OutCubic
}
}
}
}
second.handle: Quick.Rectangle {
x: control.leftPadding + (control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height))
implicitWidth: 20
implicitHeight: 20
radius: width / 2
color:Theme.dark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
Shadow{
radius: 10
}
Icon{
width: 10
height: 10
iconSource: Icons.FullCircleMask
iconSize: 10
scale:{
if(control.second.pressed){
return 0.9
}
return control.second.hovered ? 1.2 : 1
}
iconColor: Theme.primaryColor
anchors.centerIn: parent
Quick.Behavior on scale{
Quick.NumberAnimation{
duration: 167
easing.type: Quick.Easing.OutCubic
}
}
}
}
background: Quick.Item {
x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2)
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0)
implicitWidth: control.horizontal ? 180 : 6
implicitHeight: control.horizontal ? 6 : 180
width: control.horizontal ? control.availableWidth : implicitWidth
height: control.horizontal ? implicitHeight : control.availableHeight
scale: control.horizontal && control.mirrored ? -1 : 1
Quick.Rectangle{
anchors.fill: parent
anchors.margins: 1
radius: 2
color:Theme.dark ? Qt.rgba(162/255,162/255,162/255,1) : Qt.rgba(138/255,138/255,138/255,1)
}
Quick.Rectangle {
x: control.horizontal ? control.first.position * parent.width + 3 : 0
y: control.horizontal ? 0 : control.second.visualPosition * parent.height + 3
width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 6 : 6
height: control.horizontal ? 6 : control.second.position * parent.height - control.first.position * parent.height - 6
color: Theme.primaryColor
}
}
Tooltip{
parent: control.first.handle
visible: control.tooltipEnabled && (control.first.pressed || control.first.hovered)
text:String(isTipInt?Math.round(control.first.value):control.first.value)
}
Tooltip{
parent: control.second.handle
visible: control.tooltipEnabled && (control.second.pressed || control.second.hovered)
text:String(isTipInt?Math.round(control.second.value):control.second.value)
}
}

View File

@ -18,7 +18,7 @@ Quick.Window {
property alias effect: frameless.effect
readonly property alias effective: frameless.effective
readonly property var availableEffects: frameless.availableEffects
property Quick.Item appBar: AppBar {
property AppBar appBar: AppBar {
title: window.title
height: 30
showDark: window.showDark