main
zhuzihcu 2023-03-09 11:50:40 +08:00
parent d43e661388
commit 88b15b92ea
15 changed files with 155 additions and 224 deletions

View File

@ -6,8 +6,11 @@ FluWindow {
width: 500
height: 600
minimumWidth: 300
minimumHeight: 400
minimumWidth: 500
minimumHeight: 600
maximumWidth: 500
maximumHeight: 600
title:"关于"
FluAppBar{

View File

@ -18,7 +18,6 @@ FluWindow {
id:appbar
title: "FluentUI"
showDark: true
showFps: true
}
ListModel{

View File

@ -127,6 +127,30 @@ Item {
text:"Disabled"
}
}
FluDivider{
Layout.fillWidth: true ; height:1
}
RowLayout{
Layout.topMargin: 20
width: parent.width
FluCheckBox{
disabled:icon_button_check.checked
}
Item{
height: 1
Layout.fillWidth: true
}
FluToggleSwitch{
id:icon_button_check
Layout.alignment: Qt.AlignRight
}
FluText{
text:"Disabled"
}
}
FluDivider{
Layout.fillWidth: true ; height:1
}
}
}
}

View File

@ -59,6 +59,17 @@ Item {
FluTheme.isDark = !FluTheme.isDark
}
}
FluText{
text:"无边框"
fontStyle: FluText.Subtitle
Layout.topMargin: 20
}
FluToggleSwitch{
checked: FluTheme.isFrameless
onClickFunc:function(){
FluTheme.isFrameless = !FluTheme.isFrameless
}
}
}
}
}

View File

@ -16,5 +16,6 @@ FluTheme::FluTheme(QObject *parent)
: QObject{parent}
{
primaryColor(FluColors::getInstance()->Blue());
isFrameless(true);
isDark(false);
}

View File

@ -9,6 +9,7 @@ class FluTheme : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(FluColorSet*,primaryColor)
Q_PROPERTY_AUTO(bool,isFrameless);
Q_PROPERTY_AUTO(bool,isDark);
public:
explicit FluTheme(QObject *parent = nullptr);

View File

@ -38,13 +38,8 @@ win32 {
SOURCES += \
FramelessView_win.cpp
} else {
macos {
SOURCES += \
FramelessView_mac.cpp
}else{
SOURCES += \
FramelessView_unix.cpp
}
}
DEFINES += VERSION_IN=\\\"1.0.0\\\"

View File

@ -21,6 +21,7 @@ public:
void closeDeleteLater();
bool isMax() const;
bool isFull() const;
void refreshWindow();
QQuickItem *titleItem() const;
static QMap<WId,FramelessView*> *windowCache;
@ -38,6 +39,7 @@ signals:
protected:
void showEvent(QShowEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
bool event(QEvent *ev) override;
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
# else

View File

@ -1,109 +0,0 @@
#include "FramelessView.h"
#include <QGuiApplication>
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
class FramelessViewPrivate
{
public:
bool m_isMax = false;
bool m_isFull = false;
bool m_deleteLater = false;
QQuickItem *m_titleItem = nullptr;
};
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
{
// setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
setResizeMode(SizeRootObjectToView);
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
(void)state;
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
});
}
FramelessView::~FramelessView()
{
delete d;
}
void FramelessView::showEvent(QShowEvent *e)
{
Super::showEvent(e);
}
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
{
int w = normalSize.width();
int h = normalSize.height();
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
if (screenGeo.width() < w) {
x = screenGeo.x();
w = screenGeo.width();
}
if (screenGeo.height() < h) {
y = screenGeo.y();
h = screenGeo.height();
}
return { x, y, w, h };
}
void FramelessView::moveToScreenCenter()
{
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
setMinimumSize(geo.size());
}
setGeometry(geo);
update();
}
void FramelessView::closeDeleteLater(){
d->m_deleteLater = true;
}
bool FramelessView::isMax() const
{
return d->m_isMax;
}
bool FramelessView::isFull() const
{
return d->m_isFull;
}
QQuickItem *FramelessView::titleItem() const
{
return d->m_titleItem;
}
void FramelessView::setIsMax(bool isMax)
{
if (d->m_isMax == isMax)
return;
d->m_isMax = isMax;
emit isMaxChanged(d->m_isMax);
}
void FramelessView::setIsFull(bool isFull)
{
if(d->m_isFull == isFull)
return;
d->m_isFull = isFull;
emit isFullChanged(d->m_isFull);
}
void FramelessView::setTitleItem(QQuickItem *item)
{
d->m_titleItem = item;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#else
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
#endif
{
return Super::nativeEvent(eventType, message, result);
}
void FramelessView::resizeEvent(QResizeEvent *e)
{
Super::resizeEvent(e);
}

View File

@ -3,6 +3,7 @@
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
#include <FluTheme.h>
class FramelessViewPrivate
{
@ -12,10 +13,10 @@ public:
bool m_deleteLater = false;
QQuickItem *m_titleItem = nullptr;
};
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
{
// setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
setResizeMode(SizeRootObjectToView);
refreshWindow();
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
@ -23,15 +24,31 @@ FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessVi
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
});
connect(FluTheme::getInstance(),&FluTheme::isFramelessChanged,this,[=](){
refreshWindow();
});
}
void FramelessView::refreshWindow(){
if(FluTheme::getInstance()->isFrameless()){
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
}else{
setFlags(Qt::Window);
}
setResizeMode(SizeViewToRootObject);
setResizeMode(SizeRootObjectToView);
}
FramelessView::~FramelessView()
{
delete d;
}
void FramelessView::showEvent(QShowEvent *e)
{
Super::showEvent(e);
}
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
{
int w = normalSize.width();
@ -46,9 +63,9 @@ QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSi
y = screenGeo.y();
h = screenGeo.height();
}
return { x, y, w, h };
}
void FramelessView::moveToScreenCenter()
{
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
@ -58,6 +75,7 @@ void FramelessView::moveToScreenCenter()
setGeometry(geo);
update();
}
void FramelessView::closeDeleteLater(){
d->m_deleteLater = true;
}
@ -66,14 +84,17 @@ bool FramelessView::isMax() const
{
return d->m_isMax;
}
bool FramelessView::isFull() const
{
return d->m_isFull;
}
QQuickItem *FramelessView::titleItem() const
{
return d->m_titleItem;
}
void FramelessView::setIsMax(bool isMax)
{
if (d->m_isMax == isMax)
@ -82,6 +103,7 @@ void FramelessView::setIsMax(bool isMax)
d->m_isMax = isMax;
emit isMaxChanged(d->m_isMax);
}
void FramelessView::setIsFull(bool isFull)
{
if(d->m_isFull == isFull)
@ -90,6 +112,7 @@ void FramelessView::setIsFull(bool isFull)
d->m_isFull = isFull;
emit isFullChanged(d->m_isFull);
}
void FramelessView::setTitleItem(QQuickItem *item)
{
d->m_titleItem = item;
@ -107,3 +130,15 @@ void FramelessView::resizeEvent(QResizeEvent *e)
{
Super::resizeEvent(e);
}
bool FramelessView::event(QEvent *ev)
{
if (ev->type() == QEvent::Close) {
if(d->m_deleteLater){
deleteLater();
ev->setAccepted(false);
}
}
return QQuickWindow::event(ev);
}

View File

@ -3,27 +3,7 @@
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
#include <VersionHelpers.h>
#include <WinUser.h>
#include <dwmapi.h>
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
#include <windows.h>
#include <windowsx.h>
#include <wtypes.h>
#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Gdi32.lib")
static bool isMaxWin(QWindow* win)
{
return win->windowState() == Qt::WindowMaximized;
}
static bool isFullWin(QQuickView* win)
{
return win->windowState() == Qt::WindowFullScreen;
}
#include <FluTheme.h>
class FramelessViewPrivate
{
@ -33,10 +13,10 @@ public:
bool m_deleteLater = false;
QQuickItem *m_titleItem = nullptr;
};
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
{
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
setResizeMode(SizeRootObjectToView);
refreshWindow();
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
@ -44,15 +24,31 @@ FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessVi
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
});
connect(FluTheme::getInstance(),&FluTheme::isFramelessChanged,this,[=](){
refreshWindow();
});
}
void FramelessView::refreshWindow(){
if(FluTheme::getInstance()->isFrameless()){
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
}else{
setFlags(Qt::Window);
}
setResizeMode(SizeViewToRootObject);
setResizeMode(SizeRootObjectToView);
}
FramelessView::~FramelessView()
{
delete d;
}
void FramelessView::showEvent(QShowEvent *e)
{
Super::showEvent(e);
}
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
{
int w = normalSize.width();
@ -67,9 +63,9 @@ QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSi
y = screenGeo.y();
h = screenGeo.height();
}
return { x, y, w, h };
}
void FramelessView::moveToScreenCenter()
{
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
@ -79,6 +75,7 @@ void FramelessView::moveToScreenCenter()
setGeometry(geo);
update();
}
void FramelessView::closeDeleteLater(){
d->m_deleteLater = true;
}
@ -87,14 +84,17 @@ bool FramelessView::isMax() const
{
return d->m_isMax;
}
bool FramelessView::isFull() const
{
return d->m_isFull;
}
QQuickItem *FramelessView::titleItem() const
{
return d->m_titleItem;
}
void FramelessView::setIsMax(bool isMax)
{
if (d->m_isMax == isMax)
@ -103,6 +103,7 @@ void FramelessView::setIsMax(bool isMax)
d->m_isMax = isMax;
emit isMaxChanged(d->m_isMax);
}
void FramelessView::setIsFull(bool isFull)
{
if(d->m_isFull == isFull)
@ -111,6 +112,7 @@ void FramelessView::setIsFull(bool isFull)
d->m_isFull = isFull;
emit isFullChanged(d->m_isFull);
}
void FramelessView::setTitleItem(QQuickItem *item)
{
d->m_titleItem = item;
@ -121,44 +123,6 @@ bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qint
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
#endif
{
#if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1))
// Work-around a bug caused by typo which only exists in Qt 5.11.1
const auto msg = *reinterpret_cast<MSG**>(message);
#else
const auto msg = static_cast<LPMSG>(message);
#endif
if (!msg || !msg->hwnd)
{
return false;
}
switch (msg->message)
{
case WM_NCCALCSIZE: {
const auto mode = static_cast<BOOL>(msg->wParam);
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
if (mode == TRUE)
{
*result = WVR_REDRAW;
//规避 拖动border进行resize时界面闪烁
if (!isMaxWin(this) && !isFullWin(this))
{
if (clientRect->top != 0)
{
clientRect->top -= 0.1;
}
}
else
{
if (clientRect->top != 0)
{
clientRect->top += 0.1;
}
}
return true;
}
break;
}
}
return Super::nativeEvent(eventType, message, result);
}
@ -166,3 +130,15 @@ void FramelessView::resizeEvent(QResizeEvent *e)
{
Super::resizeEvent(e);
}
bool FramelessView::event(QEvent *ev)
{
if (ev->type() == QEvent::Close) {
if(d->m_deleteLater){
deleteLater();
ev->setAccepted(false);
}
}
return QQuickWindow::event(ev);
}

View File

@ -13,8 +13,8 @@ Rectangle{
return borerlessColor
return Window.window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1)
}
property bool isMacos: Qt.platform.os === "osx"
height: isMacos ? 0 : 50
visible: FluTheme.isFrameless
height: visible ? 50 : 0
width: {
if(parent==null)
return 200

View File

@ -62,9 +62,8 @@ Rectangle {
id:button_mouse
anchors.fill: parent
hoverEnabled: true
enabled: !disabled
onClicked: {
if(disabled)
return
button.clicked()
}
}

View File

@ -9,9 +9,23 @@ Item {
property string text: "Check Box"
property var checkClicked
property bool hovered: mouse_area.containsMouse
property bool disabled: false
width: childrenRect.width
height: childrenRect.height
property color borderNormalColor: FluTheme.isDark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1)
property color borderCheckedColor: FluTheme.isDark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
property color borderHoverColor: FluTheme.isDark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1)
property color normalColor: FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1)
property color checkedColor: FluTheme.isDark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
property color hoverColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(244/255,244/255,244/255,1)
property color checkedHoverColor: FluTheme.isDark ? Qt.darker(checkedColor,1.1) : Qt.lighter(checkedColor,1.1)
RowLayout{
spacing: 4
Rectangle{
@ -19,46 +33,26 @@ Item {
height: 22
radius: 4
border.color: {
if(FluTheme.isDark){
if(checked){
return FluTheme.primaryColor.lighter
}
return Qt.rgba(160/255,160/255,160/255,1)
}else{
if(checked){
if(mouse_area.containsMouse){
return Qt.rgba(25/255,117/255,187/255,1)
}
return FluTheme.primaryColor.dark
}
return Qt.rgba(136/255,136/255,136/255,1)
if(checked){
return borderCheckedColor
}
if(hovered){
return borderHoverColor
}
return borderNormalColor
}
border.width: 1
color: {
if(FluTheme.isDark){
if(checked){
if(mouse_area.containsMouse){
return Qt.rgba(74/255,149/255,207/255,1)
}
return FluTheme.primaryColor.lighter
if(checked){
if(hovered){
return checkedHoverColor
}
if(mouse_area.containsMouse){
return Qt.rgba(62/255,62/255,62/255,1)
}
return Qt.rgba(45/255,45/255,45/255,1)
}else{
if(checked){
if(mouse_area.containsMouse){
return Qt.rgba(25/255,117/255,187/255,1)
}
return FluTheme.primaryColor.dark
}
if(mouse_area.containsMouse){
return Qt.rgba(244/255,244/255,244/255,1)
}
return Qt.rgba(247/255,247/255,247/255,1)
return checkedColor
}
if(hovered){
return hoverColor
}
return normalColor
}
FluIcon {
@ -79,6 +73,7 @@ Item {
id:mouse_area
anchors.fill: parent
hoverEnabled: true
enabled: !disabled
onClicked: {
if(checkClicked){
checkClicked()

View File

@ -21,10 +21,8 @@ Item {
property int minimumHeight
property int maximumHeight
property bool isMacos: Qt.platform.os === "osx"
property int borderless:{
if(isMacos){
if(!FluTheme.isFrameless){
return 0
}
if(window === null)
@ -34,6 +32,7 @@ Item {
}
return 4
}
default property alias content: container.data
FluWindowResize{
@ -51,7 +50,7 @@ Item {
color: {
if(window === null)
return borerlessColor
return window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1)
return window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1)
}
border.width: 1
anchors.fill: parent