update
1
3rdparty/framelesshelper
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 27fcd913b4b21b51d5cca307e47e93d1ae75e1bb
|
@ -13,8 +13,8 @@ FluWindow {
|
|||||||
|
|
||||||
id:window
|
id:window
|
||||||
title: "FluentUI"
|
title: "FluentUI"
|
||||||
width: 1000
|
width: 960
|
||||||
height: 640
|
height: 600
|
||||||
minimumWidth: 520
|
minimumWidth: 520
|
||||||
minimumHeight: 200
|
minimumHeight: 200
|
||||||
launchMode: FluWindowType.SingleTask
|
launchMode: FluWindowType.SingleTask
|
||||||
|
@ -16,8 +16,8 @@ FluWindow {
|
|||||||
|
|
||||||
id:window
|
id:window
|
||||||
title: "FluentUI"
|
title: "FluentUI"
|
||||||
width: 1000
|
width: 960
|
||||||
height: 640
|
height: 600
|
||||||
minimumWidth: 520
|
minimumWidth: 520
|
||||||
minimumHeight: 200
|
minimumHeight: 200
|
||||||
launchMode: FluWindowType.SingleTask
|
launchMode: FluWindowType.SingleTask
|
||||||
|
@ -1,137 +1,6 @@
|
|||||||
#include "FluFrameless.h"
|
#include "FluFrameless.h"
|
||||||
|
|
||||||
#include "FluFrameless.h"
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QScreen>
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#pragma comment(lib, "dwmapi.lib")
|
|
||||||
#pragma comment(lib, "user32.lib")
|
|
||||||
#pragma comment(lib, "shcore.lib")
|
|
||||||
#pragma comment(lib, "Gdi32.lib")
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <windowsx.h>
|
|
||||||
#include <winuser.h>
|
|
||||||
#include <dwmapi.h>
|
|
||||||
#include <codecvt>
|
|
||||||
#include <cmath>
|
|
||||||
static inline QByteArray qtNativeEventType()
|
|
||||||
{
|
|
||||||
static const auto result = "windows_generic_MSG";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FramelessEventFilter::FramelessEventFilter(QQuickWindow* window){
|
|
||||||
_window = window;
|
|
||||||
_current = window->winId();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if ((eventType != qtNativeEventType()) || !message || !result || !_window) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto msg = static_cast<const MSG *>(message);
|
|
||||||
const HWND hWnd = msg->hwnd;
|
|
||||||
if (!hWnd) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const qint64 wid = reinterpret_cast<qint64>(hWnd);
|
|
||||||
if(wid != _current){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const UINT uMsg = msg->message;
|
|
||||||
if (!msg || !msg->hwnd)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const LPARAM lParam = msg->lParam;
|
|
||||||
const int borderPadding = 8;
|
|
||||||
if (uMsg == WM_NCCALCSIZE) {
|
|
||||||
if (_window->visibility() == QWindow::FullScreen) {
|
|
||||||
NCCALCSIZE_PARAMS* sz = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
|
|
||||||
sz->rgrc[0].left += borderPadding;
|
|
||||||
sz->rgrc[0].top += borderPadding;
|
|
||||||
sz->rgrc[0].right -= borderPadding;
|
|
||||||
sz->rgrc[0].bottom -= borderPadding;
|
|
||||||
*result = WVR_REDRAW;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
NCCALCSIZE_PARAMS* sz = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
|
|
||||||
if ( _window->visibility() == QWindow::Maximized) {
|
|
||||||
sz->rgrc[0].top += borderPadding;
|
|
||||||
} else {
|
|
||||||
sz->rgrc[0].top += 0;
|
|
||||||
}
|
|
||||||
sz->rgrc[0].right -= borderPadding;
|
|
||||||
sz->rgrc[0].bottom -= borderPadding;
|
|
||||||
sz->rgrc[0].left -= -borderPadding;
|
|
||||||
*result = WVR_REDRAW;
|
|
||||||
return true;
|
|
||||||
}else if (uMsg == WM_NCHITTEST){
|
|
||||||
const bool isResizable = !(_window->height()==_window->maximumHeight()&&_window->height()==_window->minimumHeight()&&_window->width()==_window->maximumWidth()&&_window->width()==_window->minimumWidth());
|
|
||||||
RECT winrect;
|
|
||||||
GetWindowRect(msg->hwnd, &winrect);
|
|
||||||
long x = GET_X_LPARAM(msg->lParam);
|
|
||||||
long y = GET_Y_LPARAM(msg->lParam);
|
|
||||||
if (x >= winrect.left && x < winrect.left + borderPadding &&
|
|
||||||
y < winrect.bottom && y >= winrect.bottom - borderPadding && isResizable) {
|
|
||||||
*result = HTBOTTOMLEFT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (x < winrect.right && x >= winrect.right - borderPadding &&
|
|
||||||
y < winrect.bottom && y >= winrect.bottom - borderPadding && isResizable) {
|
|
||||||
*result = HTBOTTOMRIGHT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (x >= winrect.left && x < winrect.left + borderPadding &&
|
|
||||||
y >= winrect.top && y < winrect.top + borderPadding && isResizable) {
|
|
||||||
*result = HTTOPLEFT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (x < winrect.right && x >= winrect.right - borderPadding &&
|
|
||||||
y >= winrect.top && y < winrect.top + borderPadding && isResizable) {
|
|
||||||
*result = HTTOPRIGHT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (x >= winrect.left && x < winrect.left + borderPadding && isResizable) {
|
|
||||||
*result = HTLEFT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (x < winrect.right && x >= winrect.right - borderPadding && isResizable) {
|
|
||||||
*result = HTRIGHT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (y < winrect.bottom && y >= winrect.bottom - borderPadding && isResizable) {
|
|
||||||
*result = HTBOTTOM;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (y >= winrect.top && y < winrect.top + borderPadding && isResizable) {
|
|
||||||
*result = HTTOP;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}else if(uMsg == WM_COMMAND){
|
|
||||||
SendMessage(msg->hwnd, WM_SYSCOMMAND, msg->wParam, msg->lParam);
|
|
||||||
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
|
||||||
return true;
|
|
||||||
}else if(uMsg == WM_WINDOWPOSCHANGING){
|
|
||||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(msg->lParam);
|
|
||||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
|
||||||
{
|
|
||||||
wp->flags |= SWP_NOCOPYBITS;
|
|
||||||
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FluFrameless::FluFrameless(QObject *parent)
|
FluFrameless::FluFrameless(QObject *parent)
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
@ -141,18 +10,7 @@ FluFrameless::FluFrameless(QObject *parent)
|
|||||||
void FluFrameless::classBegin(){
|
void FluFrameless::classBegin(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void FluFrameless::refresLayout(){
|
void FluFrameless::updateCursor(int edges){
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if(!_window.isNull()){
|
|
||||||
HWND hWnd = reinterpret_cast<HWND>(_window->winId());
|
|
||||||
RECT rect;
|
|
||||||
GetWindowRect(hWnd, &rect);
|
|
||||||
SetWindowPos(hWnd, nullptr, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |SWP_FRAMECHANGED);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluFrameless::updateCursor(Qt::Edges edges){
|
|
||||||
switch (edges) {
|
switch (edges) {
|
||||||
case 0:
|
case 0:
|
||||||
_window->setCursor(Qt::ArrowCursor);
|
_window->setCursor(Qt::ArrowCursor);
|
||||||
@ -177,20 +35,27 @@ void FluFrameless::updateCursor(Qt::Edges edges){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){
|
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){
|
||||||
if (_window->flags()& Qt::FramelessWindowHint) {
|
if (!_window.isNull() && _window->flags()& Qt::FramelessWindowHint) {
|
||||||
static Qt::Edges edges = Qt::Edges();
|
static int edges = 0;
|
||||||
const int margin = 8;
|
const int margin = 8;
|
||||||
switch (ev->type()) {
|
switch (ev->type()) {
|
||||||
case QEvent::MouseButtonPress:
|
case QEvent::MouseButtonPress:
|
||||||
updateCursor(edges);
|
if(edges!=0){
|
||||||
_window->startSystemResize(edges);
|
updateCursor(edges);
|
||||||
|
_window->startSystemResize(Qt::Edges(edges));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case QEvent::MouseButtonRelease:
|
case QEvent::MouseButtonRelease:
|
||||||
qDebug() << Q_FUNC_INFO << ev;
|
|
||||||
edges = Qt::Edges();
|
edges = Qt::Edges();
|
||||||
updateCursor(edges);
|
updateCursor(edges);
|
||||||
break;
|
break;
|
||||||
case QEvent::MouseMove: {
|
case QEvent::MouseMove: {
|
||||||
|
if(_window->visibility() == QWindow::Maximized || _window->visibility() == QWindow::FullScreen){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(_window->width() == _window->maximumWidth() && _window->width() == _window->minimumWidth() && _window->height() == _window->maximumHeight() && _window->height() == _window->minimumHeight()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
edges = Qt::Edges();
|
edges = Qt::Edges();
|
||||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||||
QPoint p =
|
QPoint p =
|
||||||
@ -227,37 +92,20 @@ void FluFrameless::componentComplete(){
|
|||||||
_window = (QQuickWindow*)o;
|
_window = (QQuickWindow*)o;
|
||||||
o = o->parent();
|
o = o->parent();
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if(!_window.isNull()){
|
|
||||||
_nativeEvent =new FramelessEventFilter(_window);
|
|
||||||
qApp->installNativeEventFilter(_nativeEvent);
|
|
||||||
// MARGINS margins[2]{{0, 0, 0, 0}, {0, 0, 1, 0}};
|
|
||||||
// HWND hWnd = reinterpret_cast<HWND>(_window->winId());
|
|
||||||
// DwmExtendFrameIntoClientArea(hWnd, &margins[false]);
|
|
||||||
refresLayout();
|
|
||||||
connect(_window,&QWindow::visibilityChanged,this,[=](QWindow::Visibility visibility){ refresLayout(); });
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
if(!_window.isNull()){
|
if(!_window.isNull()){
|
||||||
_window->setFlag(Qt::FramelessWindowHint,true);
|
_window->setFlag(Qt::FramelessWindowHint,true);
|
||||||
|
_window->update();
|
||||||
|
QGuiApplication::processEvents();
|
||||||
_window->installEventFilter(this);
|
_window->installEventFilter(this);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FluFrameless::~FluFrameless(){
|
FluFrameless::~FluFrameless(){
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (_nativeEvent) {
|
|
||||||
delete _nativeEvent;
|
|
||||||
_nativeEvent = nullptr;
|
|
||||||
refresLayout();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
if (!_window.isNull()) {
|
if (!_window.isNull()) {
|
||||||
_window->removeEventFilter(this);
|
|
||||||
_window->setFlag(Qt::FramelessWindowHint,false);
|
_window->setFlag(Qt::FramelessWindowHint,false);
|
||||||
|
_window->update();
|
||||||
|
QGuiApplication::processEvents();
|
||||||
|
_window->removeEventFilter(this);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -7,24 +7,6 @@
|
|||||||
#include <QAbstractNativeEventFilter>
|
#include <QAbstractNativeEventFilter>
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
|
||||||
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
|
||||||
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
|
||||||
#else
|
|
||||||
using QT_NATIVE_EVENT_RESULT_TYPE = long;
|
|
||||||
using QT_ENTER_EVENT_TYPE = QEvent;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class FramelessEventFilter : public QAbstractNativeEventFilter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FramelessEventFilter(QQuickWindow* window);
|
|
||||||
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
|
||||||
public:
|
|
||||||
QQuickWindow* _window = nullptr;
|
|
||||||
qint64 _current = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FluFrameless : public QObject, public QQmlParserStatus
|
class FluFrameless : public QObject, public QQmlParserStatus
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -34,14 +16,12 @@ public:
|
|||||||
~FluFrameless();
|
~FluFrameless();
|
||||||
void classBegin() override;
|
void classBegin() override;
|
||||||
void componentComplete() override;
|
void componentComplete() override;
|
||||||
Q_INVOKABLE void refresLayout();
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
private:
|
private:
|
||||||
void updateCursor(Qt::Edges edges);
|
void updateCursor(int edges);
|
||||||
private:
|
private:
|
||||||
QPointer<QQuickWindow> _window = nullptr;
|
QPointer<QQuickWindow> _window = nullptr;
|
||||||
FramelessEventFilter* _nativeEvent = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FLUFRAMELESS_H
|
#endif // FLUFRAMELESS_H
|
||||||
|
@ -74,14 +74,16 @@ Rectangle{
|
|||||||
property bool isRestore: win && Window.Maximized === win.visibility
|
property bool isRestore: win && Window.Maximized === win.visibility
|
||||||
property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
|
property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
|
||||||
}
|
}
|
||||||
TapHandler {
|
MouseArea{
|
||||||
onTapped: if (tapCount === 2 && d.resizable) btn_maximize.clicked()
|
anchors.fill: parent
|
||||||
gesturePolicy: TapHandler.DragThreshold
|
onPositionChanged: {
|
||||||
}
|
d.win.startSystemMove()
|
||||||
DragHandler {
|
}
|
||||||
target: null
|
onDoubleClicked: {
|
||||||
grabPermissions: TapHandler.CanTakeOverFromAnything
|
if(d.resizable){
|
||||||
onActiveChanged: if (active) { d.win.startSystemMove(); }
|
btn_maximize.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Row{
|
Row{
|
||||||
anchors{
|
anchors{
|
||||||
@ -105,6 +107,49 @@ Rectangle{
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component{
|
||||||
|
id:com_mac_buttons
|
||||||
|
RowLayout{
|
||||||
|
FluImageButton{
|
||||||
|
Layout.preferredHeight: 12
|
||||||
|
Layout.preferredWidth: 12
|
||||||
|
normalImage: "../Image/btn_close_normal.png"
|
||||||
|
hoveredImage: "../Image/btn_close_hovered.png"
|
||||||
|
pushedImage: "../Image/btn_close_pushed.png"
|
||||||
|
visible: showClose
|
||||||
|
onClicked: closeClickListener()
|
||||||
|
}
|
||||||
|
FluImageButton{
|
||||||
|
Layout.preferredHeight: 12
|
||||||
|
Layout.preferredWidth: 12
|
||||||
|
normalImage: "../Image/btn_min_normal.png"
|
||||||
|
hoveredImage: "../Image/btn_min_hovered.png"
|
||||||
|
pushedImage: "../Image/btn_min_pushed.png"
|
||||||
|
onClicked: minClickListener()
|
||||||
|
visible: showMinimize
|
||||||
|
}
|
||||||
|
FluImageButton{
|
||||||
|
Layout.preferredHeight: 12
|
||||||
|
Layout.preferredWidth: 12
|
||||||
|
normalImage: "../Image/btn_max_normal.png"
|
||||||
|
hoveredImage: "../Image/btn_max_hovered.png"
|
||||||
|
pushedImage: "../Image/btn_max_pushed.png"
|
||||||
|
onClicked: maxClickListener()
|
||||||
|
visible: d.resizable && showMaximize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluLoader{
|
||||||
|
anchors{
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 10
|
||||||
|
}
|
||||||
|
sourceComponent: isMac ? com_mac_buttons : undefined
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout{
|
RowLayout{
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
height: control.height
|
height: control.height
|
||||||
|
18
src/Qt5/imports/FluentUI/Controls/FluImageButton.qml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
|
||||||
|
Button{
|
||||||
|
id:control
|
||||||
|
property string normalImage: ""
|
||||||
|
property string hoveredImage: ""
|
||||||
|
property string pushedImage: ""
|
||||||
|
background: Item{
|
||||||
|
implicitHeight: 12
|
||||||
|
implicitWidth: 12
|
||||||
|
BorderImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: control.hovered ? (control.pressed ? control.pushedImage : control.hoveredImage ) : control.normalImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -37,8 +37,9 @@ Window {
|
|||||||
property bool showMinimize: true
|
property bool showMinimize: true
|
||||||
property bool showMaximize: true
|
property bool showMaximize: true
|
||||||
property bool showStayTop: true
|
property bool showStayTop: true
|
||||||
flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
|
|
||||||
property bool autoMaximize: false
|
property bool autoMaximize: false
|
||||||
|
property color resizeBorderColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
|
||||||
|
property int resizeBorderWidth: 1
|
||||||
property var closeListener: function(event){
|
property var closeListener: function(event){
|
||||||
if(closeDestory){
|
if(closeDestory){
|
||||||
destoryOnClose()
|
destoryOnClose()
|
||||||
@ -126,18 +127,18 @@ Window {
|
|||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
}
|
}
|
||||||
|
height: {
|
||||||
|
if(FluApp.useSystemAppBar){
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return window.fitsAppBarWindows ? 0 : window.appBar.height
|
||||||
|
}
|
||||||
sourceComponent: FluApp.useSystemAppBar ? undefined : com_app_bar
|
sourceComponent: FluApp.useSystemAppBar ? undefined : com_app_bar
|
||||||
}
|
}
|
||||||
Component{
|
Component{
|
||||||
id:com_app_bar
|
id:com_app_bar
|
||||||
Item{
|
Item{
|
||||||
data: window.appBar
|
data: window.appBar
|
||||||
height: {
|
|
||||||
if(FluApp.useSystemAppBar){
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return window.fitsAppBarWindows ? 0 : childrenRect.height
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item{
|
Item{
|
||||||
@ -225,27 +226,19 @@ Window {
|
|||||||
WindowLifecycle{
|
WindowLifecycle{
|
||||||
id:lifecycle
|
id:lifecycle
|
||||||
}
|
}
|
||||||
FluLoader{
|
Rectangle{
|
||||||
id:loader_window_border
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z:999
|
color:"transparent"
|
||||||
sourceComponent: FluApp.useSystemAppBar ? undefined : com_window_border
|
border.width: window.resizeBorderWidth
|
||||||
}
|
border.color: window.resizeBorderColor
|
||||||
Component{
|
visible: {
|
||||||
id:com_window_border
|
if(FluApp.useSystemAppBar){
|
||||||
Item{
|
return false
|
||||||
Rectangle{
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Qt.rgba(0,0,0,0)
|
|
||||||
border.width: 1
|
|
||||||
visible: FluTools.isLinux()
|
|
||||||
border.color: {
|
|
||||||
if(window.active){
|
|
||||||
return Qt.rgba(51/255,51/255,51/255,1)
|
|
||||||
}
|
|
||||||
return Qt.rgba(153/255,153/255,153/255,1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function destoryOnClose(){
|
function destoryOnClose(){
|
||||||
|
BIN
src/Qt5/imports/FluentUI/Image/btn_close_hovered.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_close_normal.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_close_pushed.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_max_hovered.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_max_normal.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_max_pushed.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_min_hovered.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_min_normal.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
src/Qt5/imports/FluentUI/Image/btn_min_pushed.png
Normal file
After Width: | Height: | Size: 10 KiB |
@ -97,5 +97,15 @@
|
|||||||
<file>FluentUI/Controls/FluClip.qml</file>
|
<file>FluentUI/Controls/FluClip.qml</file>
|
||||||
<file>FluentUI/Controls/FluLoader.qml</file>
|
<file>FluentUI/Controls/FluLoader.qml</file>
|
||||||
<file>FluentUI/Controls/FluShortcutPicker.qml</file>
|
<file>FluentUI/Controls/FluShortcutPicker.qml</file>
|
||||||
|
<file>FluentUI/Image/btn_close_hovered.png</file>
|
||||||
|
<file>FluentUI/Image/btn_close_normal.png</file>
|
||||||
|
<file>FluentUI/Image/btn_close_pushed.png</file>
|
||||||
|
<file>FluentUI/Image/btn_max_hovered.png</file>
|
||||||
|
<file>FluentUI/Image/btn_max_normal.png</file>
|
||||||
|
<file>FluentUI/Image/btn_max_pushed.png</file>
|
||||||
|
<file>FluentUI/Image/btn_min_hovered.png</file>
|
||||||
|
<file>FluentUI/Image/btn_min_normal.png</file>
|
||||||
|
<file>FluentUI/Image/btn_min_pushed.png</file>
|
||||||
|
<file>FluentUI/Controls/FluImageButton.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -74,14 +74,16 @@ Rectangle{
|
|||||||
property bool isRestore: win && Window.Maximized === win.visibility
|
property bool isRestore: win && Window.Maximized === win.visibility
|
||||||
property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
|
property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
|
||||||
}
|
}
|
||||||
TapHandler {
|
MouseArea{
|
||||||
onTapped: if (tapCount === 2 && d.resizable) btn_maximize.clicked()
|
anchors.fill: parent
|
||||||
gesturePolicy: TapHandler.DragThreshold
|
onPositionChanged: {
|
||||||
}
|
d.win.startSystemMove()
|
||||||
DragHandler {
|
}
|
||||||
target: null
|
onDoubleClicked: {
|
||||||
grabPermissions: TapHandler.CanTakeOverFromAnything
|
if(d.resizable){
|
||||||
onActiveChanged: if (active) { d.win.startSystemMove(); }
|
btn_maximize.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Row{
|
Row{
|
||||||
anchors{
|
anchors{
|
||||||
@ -105,6 +107,49 @@ Rectangle{
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component{
|
||||||
|
id:com_mac_buttons
|
||||||
|
RowLayout{
|
||||||
|
FluImageButton{
|
||||||
|
Layout.preferredHeight: 12
|
||||||
|
Layout.preferredWidth: 12
|
||||||
|
normalImage: "../Image/btn_close_normal.png"
|
||||||
|
hoveredImage: "../Image/btn_close_hovered.png"
|
||||||
|
pushedImage: "../Image/btn_close_pushed.png"
|
||||||
|
visible: showClose
|
||||||
|
onClicked: closeClickListener()
|
||||||
|
}
|
||||||
|
FluImageButton{
|
||||||
|
Layout.preferredHeight: 12
|
||||||
|
Layout.preferredWidth: 12
|
||||||
|
normalImage: "../Image/btn_min_normal.png"
|
||||||
|
hoveredImage: "../Image/btn_min_hovered.png"
|
||||||
|
pushedImage: "../Image/btn_min_pushed.png"
|
||||||
|
onClicked: minClickListener()
|
||||||
|
visible: showMinimize
|
||||||
|
}
|
||||||
|
FluImageButton{
|
||||||
|
Layout.preferredHeight: 12
|
||||||
|
Layout.preferredWidth: 12
|
||||||
|
normalImage: "../Image/btn_max_normal.png"
|
||||||
|
hoveredImage: "../Image/btn_max_hovered.png"
|
||||||
|
pushedImage: "../Image/btn_max_pushed.png"
|
||||||
|
onClicked: maxClickListener()
|
||||||
|
visible: d.resizable && showMaximize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluLoader{
|
||||||
|
anchors{
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 10
|
||||||
|
}
|
||||||
|
sourceComponent: isMac ? com_mac_buttons : undefined
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout{
|
RowLayout{
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
height: control.height
|
height: control.height
|
||||||
|
18
src/Qt6/imports/FluentUI/Controls/FluImageButton.qml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
|
||||||
|
Button{
|
||||||
|
id:control
|
||||||
|
property string normalImage: ""
|
||||||
|
property string hoveredImage: ""
|
||||||
|
property string pushedImage: ""
|
||||||
|
background: Item{
|
||||||
|
implicitHeight: 12
|
||||||
|
implicitWidth: 12
|
||||||
|
BorderImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: control.hovered ? (control.pressed ? control.pushedImage : control.hoveredImage ) : control.normalImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -36,8 +36,9 @@ Window {
|
|||||||
property bool showMinimize: true
|
property bool showMinimize: true
|
||||||
property bool showMaximize: true
|
property bool showMaximize: true
|
||||||
property bool showStayTop: true
|
property bool showStayTop: true
|
||||||
flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
|
|
||||||
property bool autoMaximize: false
|
property bool autoMaximize: false
|
||||||
|
property color resizeBorderColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
|
||||||
|
property int resizeBorderWidth: 1
|
||||||
property var closeListener: function(event){
|
property var closeListener: function(event){
|
||||||
if(closeDestory){
|
if(closeDestory){
|
||||||
destoryOnClose()
|
destoryOnClose()
|
||||||
@ -125,18 +126,18 @@ Window {
|
|||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
}
|
}
|
||||||
|
height: {
|
||||||
|
if(FluApp.useSystemAppBar){
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return window.fitsAppBarWindows ? 0 : window.appBar.height
|
||||||
|
}
|
||||||
sourceComponent: FluApp.useSystemAppBar ? undefined : com_app_bar
|
sourceComponent: FluApp.useSystemAppBar ? undefined : com_app_bar
|
||||||
}
|
}
|
||||||
Component{
|
Component{
|
||||||
id:com_app_bar
|
id:com_app_bar
|
||||||
Item{
|
Item{
|
||||||
data: window.appBar
|
data: window.appBar
|
||||||
height: {
|
|
||||||
if(FluApp.useSystemAppBar){
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return window.fitsAppBarWindows ? 0 : childrenRect.height
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item{
|
Item{
|
||||||
@ -224,27 +225,19 @@ Window {
|
|||||||
WindowLifecycle{
|
WindowLifecycle{
|
||||||
id:lifecycle
|
id:lifecycle
|
||||||
}
|
}
|
||||||
FluLoader{
|
Rectangle{
|
||||||
id:loader_window_border
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z:999
|
color:"transparent"
|
||||||
sourceComponent: FluApp.useSystemAppBar ? undefined : com_window_border
|
border.width: window.resizeBorderWidth
|
||||||
}
|
border.color: window.resizeBorderColor
|
||||||
Component{
|
visible: {
|
||||||
id:com_window_border
|
if(FluApp.useSystemAppBar){
|
||||||
Item{
|
return false
|
||||||
Rectangle{
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Qt.rgba(0,0,0,0)
|
|
||||||
border.width: 1
|
|
||||||
visible: FluTools.isLinux()
|
|
||||||
border.color: {
|
|
||||||
if(window.active){
|
|
||||||
return Qt.rgba(51/255,51/255,51/255,1)
|
|
||||||
}
|
|
||||||
return Qt.rgba(153/255,153/255,153/255,1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function destoryOnClose(){
|
function destoryOnClose(){
|
||||||
|
BIN
src/Qt6/imports/FluentUI/Image/btn_close_hovered.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_close_normal.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_close_pushed.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_max_hovered.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_max_normal.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_max_pushed.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_min_hovered.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_min_normal.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
src/Qt6/imports/FluentUI/Image/btn_min_pushed.png
Normal file
After Width: | Height: | Size: 10 KiB |