Added demos.

This commit is contained in:
2025-12-30 23:34:28 +01:00
parent 26069dc4e4
commit 0b67f4c166
24 changed files with 2784 additions and 6 deletions

View File

@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 18.0.1, 2025-12-30T23:32:00. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{350f6538-4791-42f9-b43d-6ea1a7b22b7b}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.LineEndingBehavior">1</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">16</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
<value type="int" key="RcSync">0</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="bool" key="HasPerBcDcs">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.10.1 MinGW 64-bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.10.1 MinGW 64-bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6101.win64_mingw_kit</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\syncMePlease\projects.now\claude_fluent_light\build\Desktop_Qt_6_10_1_MinGW_64_bit-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/syncMePlease/projects.now/claude_fluent_light/build/Desktop_Qt_6_10_1_MinGW_64_bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/syncMePlease/projects.now/claude_fluent_light/claude_fluent_light.pro</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/syncMePlease/projects.now/claude_fluent_light/claude_fluent_light.pro</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@@ -0,0 +1,26 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
fluentwidget.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
fluentwidget.h \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

View File

@@ -0,0 +1,2 @@
#include "fluentwidget.h"

View File

@@ -0,0 +1,466 @@
// FluentWidget.h
#ifndef FLUENTWIDGET_H
#define FLUENTWIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QPainter>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QGraphicsDropShadowEffect>
#include <QLineEdit>
#include <QSlider>
#include <QCheckBox>
#include <QDebug>
// Fluent Card Widget mit Hover-Effekt
class FluentCard : public QWidget {
Q_OBJECT
Q_PROPERTY(qreal elevationFactor READ elevationFactor WRITE setElevationFactor)
public:
FluentCard(const QString& title, const QString& subtitle,
const QColor& accentColor, QWidget* parent = nullptr)
: QWidget(parent), m_title(title), m_subtitle(subtitle),
m_accentColor(accentColor), m_elevationFactor(0.0) {
setFixedSize(280, 140);
setMouseTracking(true);
}
qreal elevationFactor() const { return m_elevationFactor; }
void setElevationFactor(qreal factor)
{
qDebug() << " --- set: " << factor;
m_elevationFactor = factor;
update();
}
protected:
void paintEvent(QPaintEvent*) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// Draw shadow manually (multiple layers for smooth shadow)
int shadowSize = 2 + m_elevationFactor * 10;
int shadowOffset = m_elevationFactor * 4;
for (int i = shadowSize; i > 0; i--) {
int alpha = 15 * (1.0 - i / (qreal)shadowSize);
QColor shadowColor(0, 0, 0, alpha);
painter.setPen(Qt::NoPen);
painter.setBrush(shadowColor);
painter.drawRoundedRect(
rect().adjusted(-i, -i + shadowOffset, i, i + shadowOffset),
8 + i, 8 + i
);
}
// Card background
painter.setBrush(QColor(43, 43, 43)); // Dark surface
painter.setPen(QPen(QColor(63, 63, 63), 1)); // Border
painter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 8, 8);
// Accent icon circle
QColor iconBg = m_accentColor;
iconBg.setAlpha(40);
painter.setBrush(iconBg);
painter.setPen(Qt::NoPen);
painter.drawEllipse(20, 20, 48, 48);
// Icon (simplified)
painter.setPen(m_accentColor);
QFont iconFont = font();
iconFont.setPointSize(24);
iconFont.setBold(true);
painter.setFont(iconFont);
painter.drawText(QRect(20, 20, 48, 48), Qt::AlignCenter, "📄");
// Title
painter.setPen(Qt::white);
QFont titleFont = font();
titleFont.setPointSize(12);
titleFont.setWeight(QFont::DemiBold);
painter.setFont(titleFont);
painter.drawText(QRect(20, 80, width() - 40, 25),
Qt::AlignLeft | Qt::AlignVCenter, m_title);
// Subtitle
painter.setPen(QColor(176, 176, 176));
QFont subFont = font();
subFont.setPointSize(9);
painter.setFont(subFont);
painter.drawText(QRect(20, 105, width() - 40, 20),
Qt::AlignLeft | Qt::AlignVCenter, m_subtitle);
}
void enterEvent(QEnterEvent*) override {
QPropertyAnimation* anim = new QPropertyAnimation(this, "elevationFactor");
anim->setDuration(200);
anim->setEasingCurve(QEasingCurve::OutCubic);
anim->setStartValue(m_elevationFactor);
anim->setEndValue(1.0);
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
void leaveEvent(QEvent*) override {
QPropertyAnimation* anim = new QPropertyAnimation(this, "elevationFactor");
anim->setDuration(200);
anim->setEasingCurve(QEasingCurve::OutCubic);
anim->setStartValue(m_elevationFactor);
anim->setEndValue(0.0);
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
private:
QString m_title;
QString m_subtitle;
QColor m_accentColor;
qreal m_elevationFactor;
};
// Fluent Button mit Acrylic-Style
class FluentButton : public QPushButton {
Q_OBJECT
public:
enum ButtonStyle { Primary, Secondary, Accent };
FluentButton(const QString& text, ButtonStyle style = Secondary,
QWidget* parent = nullptr)
: QPushButton(text, parent), m_style(style), m_pressed(false) {
setMinimumHeight(32);
setCursor(Qt::PointingHandCursor);
updateStyle();
}
protected:
void enterEvent(QEnterEvent*) override {
updateStyle(true);
}
void leaveEvent(QEvent*) override {
updateStyle(false);
}
void mousePressEvent(QMouseEvent* e) override {
m_pressed = true;
QPushButton::mousePressEvent(e);
}
void mouseReleaseEvent(QMouseEvent* e) override {
m_pressed = false;
QPushButton::mouseReleaseEvent(e);
}
private:
void updateStyle(bool hovered = false) {
QString style;
switch (m_style) {
case Primary:
if (hovered) {
style = "QPushButton { background-color: #106EBE; color: white; "
"border: none; border-radius: 4px; font-size: 9pt; "
"padding: 6px 16px; font-weight: 500; }";
} else {
style = "QPushButton { background-color: #0078D4; color: white; "
"border: none; border-radius: 4px; font-size: 9pt; "
"padding: 6px 16px; font-weight: 500; }";
}
break;
case Secondary:
if (hovered) {
style = "QPushButton { background-color: #3A3A3A; color: white; "
"border: 1px solid #5A5A5A; border-radius: 4px; "
"font-size: 9pt; padding: 6px 16px; font-weight: 500; }";
} else {
style = "QPushButton { background-color: #2B2B2B; color: white; "
"border: 1px solid #3F3F3F; border-radius: 4px; "
"font-size: 9pt; padding: 6px 16px; font-weight: 500; }";
}
break;
case Accent:
if (hovered) {
style = "QPushButton { background-color: rgba(0, 120, 212, 0.15); "
"color: #60CDFF; border: none; border-radius: 4px; "
"font-size: 9pt; padding: 6px 16px; font-weight: 500; }";
} else {
style = "QPushButton { background-color: transparent; "
"color: #60CDFF; border: none; border-radius: 4px; "
"font-size: 9pt; padding: 6px 16px; font-weight: 500; }";
}
break;
}
setStyleSheet(style);
}
ButtonStyle m_style;
bool m_pressed;
};
// Fluent Toggle Switch
class FluentToggle : public QWidget {
Q_OBJECT
Q_PROPERTY(int position READ position WRITE setPosition)
public:
FluentToggle(QWidget* parent = nullptr)
: QWidget(parent), m_checked(false), m_position(2) {
setFixedSize(44, 20);
setCursor(Qt::PointingHandCursor);
}
bool isChecked() const { return m_checked; }
void setChecked(bool checked) {
if (m_checked != checked) {
m_checked = checked;
animateToggle();
emit toggled(m_checked);
}
}
int position() const { return m_position; }
void setPosition(int pos) {
m_position = pos;
update();
}
signals:
void toggled(bool checked);
protected:
void paintEvent(QPaintEvent*) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// Track
QColor trackColor = m_checked ? QColor("#0078D4") : QColor("#3F3F3F");
painter.setPen(Qt::NoPen);
painter.setBrush(trackColor);
painter.drawRoundedRect(rect(), 10, 10);
// Thumb
painter.setBrush(Qt::white);
painter.drawEllipse(m_position, 2, 16, 16);
}
void mousePressEvent(QMouseEvent*) override {
setChecked(!m_checked);
}
private:
void animateToggle() {
QPropertyAnimation* anim = new QPropertyAnimation(this, "position");
anim->setDuration(150);
anim->setEasingCurve(QEasingCurve::InOutQuad);
anim->setEndValue(m_checked ? 26 : 2);
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
bool m_checked;
int m_position;
};
// Main Fluent Widget
class FluentWidget : public QWidget {
Q_OBJECT
public:
FluentWidget(QWidget* parent = nullptr) : QWidget(parent) {
setupUI();
applyFluentDarkTheme();
}
private:
void setupUI() {
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
// Title Bar
QWidget* titleBar = createTitleBar();
mainLayout->addWidget(titleBar);
// Content Area
QWidget* content = new QWidget();
content->setStyleSheet("background-color: #202020;");
QVBoxLayout* contentLayout = new QVBoxLayout(content);
contentLayout->setContentsMargins(40, 40, 40, 40);
contentLayout->setSpacing(32);
// Header
QLabel* titleLabel = new QLabel("Fluent Design System");
titleLabel->setStyleSheet("color: white; font-size: 28pt; font-weight: 600;");
contentLayout->addWidget(titleLabel);
QLabel* subtitleLabel = new QLabel("Modern Windows 11 inspired UI components");
subtitleLabel->setStyleSheet("color: #B0B0B0; font-size: 11pt;");
contentLayout->addWidget(subtitleLabel);
contentLayout->addSpacing(20);
// Cards Grid
QWidget* cardsWidget = new QWidget();
QGridLayout* cardsLayout = new QGridLayout(cardsWidget);
cardsLayout->setSpacing(20);
cardsLayout->addWidget(new FluentCard("Documents", "128 files",
QColor("#0078D4")), 0, 0);
cardsLayout->addWidget(new FluentCard("Photos", "1,234 items",
QColor("#8764B8")), 0, 1);
cardsLayout->addWidget(new FluentCard("Music", "89 songs",
QColor("#00B7C3")), 0, 2);
cardsLayout->addWidget(new FluentCard("Videos", "24 clips",
QColor("#E3008C")), 1, 0);
cardsLayout->addWidget(new FluentCard("Downloads", "45 items",
QColor("#00CC6A")), 1, 1);
cardsLayout->addWidget(new FluentCard("Projects", "12 folders",
QColor("#FF8C00")), 1, 2);
contentLayout->addWidget(cardsWidget);
contentLayout->addSpacing(20);
// Controls Section
QWidget* controlsPanel = createControlsPanel();
contentLayout->addWidget(controlsPanel);
contentLayout->addStretch();
mainLayout->addWidget(content);
}
QWidget* createTitleBar() {
QWidget* titleBar = new QWidget();
titleBar->setFixedHeight(48);
titleBar->setStyleSheet("background-color: #2B2B2B; border-bottom: 1px solid #3F3F3F;");
QHBoxLayout* layout = new QHBoxLayout(titleBar);
layout->setContentsMargins(16, 0, 16, 0);
// App Icon
QLabel* iconLabel = new QLabel("💎");
iconLabel->setStyleSheet("font-size: 20pt;");
layout->addWidget(iconLabel);
QLabel* appName = new QLabel("Fluent Demo");
appName->setStyleSheet("color: white; font-size: 10pt; font-weight: 600;");
layout->addWidget(appName);
layout->addStretch();
// Action Buttons
QPushButton* searchBtn = new QPushButton("🔍");
searchBtn->setFixedSize(32, 32);
searchBtn->setStyleSheet("QPushButton { background: transparent; color: white; "
"border: none; border-radius: 4px; font-size: 14pt; }"
"QPushButton:hover { background: #3A3A3A; }");
layout->addWidget(searchBtn);
QPushButton* notifBtn = new QPushButton("🔔");
notifBtn->setFixedSize(32, 32);
notifBtn->setStyleSheet("QPushButton { background: transparent; color: white; "
"border: none; border-radius: 4px; font-size: 14pt; }"
"QPushButton:hover { background: #3A3A3A; }");
layout->addWidget(notifBtn);
QPushButton* userBtn = new QPushButton("👤");
userBtn->setFixedSize(32, 32);
userBtn->setStyleSheet("QPushButton { background: transparent; color: white; "
"border: none; border-radius: 4px; font-size: 14pt; }"
"QPushButton:hover { background: #3A3A3A; }");
layout->addWidget(userBtn);
return titleBar;
}
QWidget* createControlsPanel() {
QWidget* panel = new QWidget();
panel->setStyleSheet("background-color: #2B2B2B; border: 1px solid #3F3F3F; "
"border-radius: 8px;");
QVBoxLayout* layout = new QVBoxLayout(panel);
layout->setContentsMargins(24, 24, 24, 24);
layout->setSpacing(24);
// Section Title
QLabel* sectionTitle = new QLabel("Controls");
sectionTitle->setStyleSheet("color: white; font-size: 16pt; font-weight: 600;");
layout->addWidget(sectionTitle);
// Buttons Demo
QLabel* btnLabel = new QLabel("Buttons");
btnLabel->setStyleSheet("color: #B0B0B0; font-size: 10pt; font-weight: 600;");
layout->addWidget(btnLabel);
QHBoxLayout* btnLayout = new QHBoxLayout();
btnLayout->setSpacing(12);
btnLayout->addWidget(new FluentButton("Primary", FluentButton::Primary));
btnLayout->addWidget(new FluentButton("Secondary", FluentButton::Secondary));
btnLayout->addWidget(new FluentButton("Accent", FluentButton::Accent));
btnLayout->addStretch();
layout->addLayout(btnLayout);
// Slider Demo
QLabel* sliderLabel = new QLabel("Slider");
sliderLabel->setStyleSheet("color: #B0B0B0; font-size: 10pt; font-weight: 600;");
layout->addWidget(sliderLabel);
QSlider* slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 100);
slider->setValue(50);
slider->setStyleSheet(
"QSlider::groove:horizontal { background: #3F3F3F; height: 4px; "
"border-radius: 2px; }"
"QSlider::handle:horizontal { background: #0078D4; width: 16px; "
"height: 16px; margin: -6px 0; border-radius: 8px; }"
"QSlider::add-page:horizontal { background: #3F3F3F; }"
"QSlider::sub-page:horizontal { background: #0078D4; }"
);
layout->addWidget(slider);
// Toggle Demo
QLabel* toggleLabel = new QLabel("Toggles");
toggleLabel->setStyleSheet("color: #B0B0B0; font-size: 10pt; font-weight: 600;");
layout->addWidget(toggleLabel);
QStringList toggleTexts = {"Enable notifications", "Dark mode", "Auto-save"};
for (const QString& text : toggleTexts) {
QHBoxLayout* toggleRow = new QHBoxLayout();
QLabel* label = new QLabel(text);
label->setStyleSheet("color: white; font-size: 10pt;");
toggleRow->addWidget(label);
toggleRow->addStretch();
FluentToggle* toggle = new FluentToggle();
if (text == "Dark mode") {
toggle->setChecked(true);
}
toggleRow->addWidget(toggle);
layout->addLayout(toggleRow);
}
return panel;
}
void applyFluentDarkTheme() {
setStyleSheet("QWidget { font-family: 'Segoe UI', 'Noto Sans', sans-serif; }");
}
};
#endif // FLUENTWIDGET_H

View File

@@ -0,0 +1,37 @@
// main.cpp
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QPainter>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QGraphicsDropShadowEffect>
#include <QLineEdit>
#include <QSlider>
#include <QCheckBox>
#include "FluentWidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Set font
QFont font;
font.setFamily("Segoe UI");
font.setPointSize(9);
app.setFont(font);
FluentWidget window;
window.setWindowTitle("Fluent Design Demo");
window.resize(1000, 800);
window.show();
return app.exec();
}

View File

@@ -0,0 +1,9 @@
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi(this);
}
MainWindow::~MainWindow() {}

View File

@@ -0,0 +1,16 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_mainwindow.h"
#include <QMainWindow>
class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>18</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>