2021-01-03 21:18:20 +03:00
|
|
|
|
// This code is a part of Qt-Nice-Frameless-Window
|
|
|
|
|
|
// https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window
|
|
|
|
|
|
// Licensed by MIT License - https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window/blob/master/LICENSE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef CFRAMELESSWINDOW_H
|
|
|
|
|
|
#define CFRAMELESSWINDOW_H
|
|
|
|
|
|
#include "qsystemdetection.h"
|
|
|
|
|
|
#include <QObject>
|
|
|
|
|
|
#include <QMainWindow>
|
|
|
|
|
|
|
|
|
|
|
|
//A nice frameless window for both Windows and OS X
|
|
|
|
|
|
//Author: Bringer-of-Light
|
|
|
|
|
|
//Github: https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window
|
|
|
|
|
|
// Usage: use "CFramelessWindow" as base class instead of "QMainWindow", and enjoy
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
#include <QList>
|
|
|
|
|
|
#include <QMargins>
|
|
|
|
|
|
#include <QRect>
|
|
|
|
|
|
class CFramelessWindow : public QMainWindow
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
public:
|
|
|
|
|
|
explicit CFramelessWindow(QWidget *parent = 0);
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
//设置是否可以通过鼠标调整窗口大小
|
|
|
|
|
|
//if resizeable is set to false, then the window can not be resized by mouse
|
|
|
|
|
|
//but still can be resized programtically
|
|
|
|
|
|
void setResizeable(bool resizeable=true);
|
|
|
|
|
|
bool isResizeable(){return m_bResizeable;}
|
|
|
|
|
|
|
|
|
|
|
|
//设置可调整大小区域的宽度,在此区域内,可以使用鼠标调整窗口大小
|
|
|
|
|
|
//set border width, inside this aera, window can be resized by mouse
|
|
|
|
|
|
void setResizeableAreaWidth(int width = 5);
|
|
|
|
|
|
protected:
|
|
|
|
|
|
//设置一个标题栏widget,此widget会被当做标题栏对待
|
|
|
|
|
|
//set a widget which will be treat as SYSTEM titlebar
|
|
|
|
|
|
void setTitleBar(QWidget* titlebar);
|
|
|
|
|
|
|
|
|
|
|
|
//在标题栏控件内,也可以有子控件如标签控件“label1”,此label1遮盖了标题栏,导致不能通过label1拖动窗口
|
|
|
|
|
|
//要解决此问题,使用addIgnoreWidget(label1)
|
|
|
|
|
|
//generally, we can add widget say "label1" on titlebar, and it will cover the titlebar under it
|
|
|
|
|
|
//as a result, we can not drag and move the MainWindow with this "label1" again
|
|
|
|
|
|
//we can fix this by add "label1" to a ignorelist, just call addIgnoreWidget(label1)
|
|
|
|
|
|
void addIgnoreWidget(QWidget* widget);
|
|
|
|
|
|
|
|
|
|
|
|
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
|
|
|
|
|
private slots:
|
|
|
|
|
|
void onTitleBarDestroyed();
|
|
|
|
|
|
public:
|
|
|
|
|
|
void setContentsMargins(const QMargins &margins);
|
|
|
|
|
|
void setContentsMargins(int left, int top, int right, int bottom);
|
|
|
|
|
|
QMargins contentsMargins() const;
|
|
|
|
|
|
QRect contentsRect() const;
|
|
|
|
|
|
void getContentsMargins(int *left, int *top, int *right, int *bottom) const;
|
|
|
|
|
|
public slots:
|
|
|
|
|
|
void showFullScreen();
|
|
|
|
|
|
private:
|
|
|
|
|
|
QWidget* m_titlebar;
|
|
|
|
|
|
QList<QWidget*> m_whiteList;
|
|
|
|
|
|
int m_borderWidth;
|
|
|
|
|
|
|
|
|
|
|
|
QMargins m_margins;
|
|
|
|
|
|
QMargins m_frames;
|
|
|
|
|
|
bool m_bJustMaximized;
|
|
|
|
|
|
|
|
|
|
|
|
bool m_bResizeable;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2021-06-26 23:09:48 +00:00
|
|
|
|
#elif defined Q_OS_MAC || defined Q_OS_LINUX
|
2021-01-03 21:18:20 +03:00
|
|
|
|
#include <QMouseEvent>
|
|
|
|
|
|
#include <QResizeEvent>
|
|
|
|
|
|
#include <QPoint>
|
|
|
|
|
|
class CFramelessWindow : public QMainWindow
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
public:
|
|
|
|
|
|
explicit CFramelessWindow(QWidget *parent = 0);
|
|
|
|
|
|
private:
|
|
|
|
|
|
void initUI();
|
|
|
|
|
|
public:
|
|
|
|
|
|
//设置可拖动区域的高度,在此区域内,可以通过鼠标拖动窗口, 0表示整个窗口都可拖动
|
|
|
|
|
|
//In draggable area, window can be moved by mouse, (height = 0) means that the whole window is draggable
|
|
|
|
|
|
void setDraggableAreaHeight(int height = 0);
|
|
|
|
|
|
|
|
|
|
|
|
//只有OS X10.10及以后系统,才支持OS X原生样式包括:三个系统按钮、窗口圆角、窗口阴影
|
|
|
|
|
|
//类初始化完成后,可以通过此函数查看是否已经启用了原生样式。如果未启动,需要自定义关闭按钮、最小化按钮、最大化按钮
|
|
|
|
|
|
//Native style(three system button/ round corner/ drop shadow) works only on OS X 10.10 or later
|
|
|
|
|
|
//after init, we should check whether NativeStyle is OK with this function
|
|
|
|
|
|
//if NOT ok, we should implement close button/ min button/ max button ourself
|
|
|
|
|
|
bool isNativeStyleOK() {return m_bNativeSystemBtn;}
|
|
|
|
|
|
|
|
|
|
|
|
//如果设置setCloseBtnQuit(false),那么点击关闭按钮后,程序不会退出,而是会隐藏,只有在OS X 10.10 及以后系统中有效
|
|
|
|
|
|
//if setCloseBtnQuit(false), then when close button is clicked, the application will hide itself instead of quit
|
|
|
|
|
|
//be carefull, after you set this to false, you can NOT change it to true again
|
|
|
|
|
|
//this function should be called inside of the constructor function of derived classes, and can NOT be called more than once
|
|
|
|
|
|
//only works for OS X 10.10 or later
|
|
|
|
|
|
void setCloseBtnQuit(bool bQuit = true);
|
|
|
|
|
|
|
|
|
|
|
|
//启用或禁用关闭按钮,只有在isNativeStyleOK()返回true的情况下才有效
|
|
|
|
|
|
//enable or disable Close button, only worked if isNativeStyleOK() returns true
|
|
|
|
|
|
void setCloseBtnEnabled(bool bEnable = true);
|
|
|
|
|
|
|
|
|
|
|
|
//启用或禁用最小化按钮,只有在isNativeStyleOK()返回true的情况下才有效
|
|
|
|
|
|
//enable or disable Miniaturize button, only worked if isNativeStyleOK() returns true
|
|
|
|
|
|
void setMinBtnEnabled(bool bEnable = true);
|
|
|
|
|
|
|
|
|
|
|
|
//启用或禁用zoom(最大化)按钮,只有在isNativeStyleOK()返回true的情况下才有效
|
|
|
|
|
|
//enable or disable Zoom button(fullscreen button), only worked if isNativeStyleOK() returns true
|
|
|
|
|
|
void setZoomBtnEnabled(bool bEnable = true);
|
|
|
|
|
|
|
|
|
|
|
|
bool isCloseBtnEnabled() {return m_bIsCloseBtnEnabled;}
|
|
|
|
|
|
bool isMinBtnEnabled() {return m_bIsMinBtnEnabled;}
|
|
|
|
|
|
bool isZoomBtnEnabled() {return m_bIsZoomBtnEnabled;}
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void mousePressEvent(QMouseEvent *event);
|
|
|
|
|
|
void mouseReleaseEvent(QMouseEvent *event);
|
|
|
|
|
|
void mouseMoveEvent(QMouseEvent *event);
|
|
|
|
|
|
private:
|
|
|
|
|
|
int m_draggableHeight;
|
|
|
|
|
|
bool m_bWinMoving;
|
|
|
|
|
|
bool m_bMousePressed;
|
|
|
|
|
|
QPoint m_MousePos;
|
|
|
|
|
|
QPoint m_WindowPos;
|
|
|
|
|
|
bool m_bCloseBtnQuit;
|
|
|
|
|
|
bool m_bNativeSystemBtn;
|
|
|
|
|
|
bool m_bIsCloseBtnEnabled, m_bIsMinBtnEnabled, m_bIsZoomBtnEnabled;
|
|
|
|
|
|
|
|
|
|
|
|
//===============================================
|
|
|
|
|
|
//TODO
|
|
|
|
|
|
//下面的代码是试验性质的
|
|
|
|
|
|
//tentative code
|
|
|
|
|
|
|
|
|
|
|
|
//窗口从全屏状态恢复正常大小时,标题栏又会出现,原因未知。
|
|
|
|
|
|
//默认情况下,系统的最大化按钮(zoom button)是进入全屏,为了避免标题栏重新出现的问题,
|
|
|
|
|
|
//以上代码已经重新定义了系统zoom button的行为,是其功能变为最大化而不是全屏
|
|
|
|
|
|
//以下代码尝试,每次窗口从全屏状态恢复正常大小时,都再次进行设置,以消除标题栏
|
|
|
|
|
|
//after the window restore from fullscreen mode, the titlebar will show again, it looks like a BUG
|
|
|
|
|
|
//on OS X 10.10 and later, click the system green button (zoom button) will make the app become fullscreen
|
|
|
|
|
|
//so we have override it's action to "maximized" in the CFramelessWindow Constructor function
|
|
|
|
|
|
//but we may try something else such as delete the titlebar again and again...
|
|
|
|
|
|
private:
|
|
|
|
|
|
bool m_bTitleBarVisible;
|
|
|
|
|
|
|
|
|
|
|
|
void setTitlebarVisible(bool bTitlebarVisible = false);
|
|
|
|
|
|
bool isTitlebarVisible() {return m_bTitleBarVisible;}
|
|
|
|
|
|
private slots:
|
|
|
|
|
|
void onRestoreFromFullScreen();
|
|
|
|
|
|
signals:
|
|
|
|
|
|
void restoreFromFullScreen();
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void resizeEvent(QResizeEvent *event);
|
|
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#endif // CFRAMELESSWINDOW_H
|