mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
FramelessMainWindowLinux
This commit is contained in:
parent
5bc48be5d0
commit
810438b5e5
@ -21,6 +21,12 @@ NotebookMgr::NotebookMgr(QObject *p_parent)
|
||||
{
|
||||
}
|
||||
|
||||
void NotebookMgr::close()
|
||||
{
|
||||
m_notebooks.clear();
|
||||
m_currentNotebookId = -1;
|
||||
}
|
||||
|
||||
void NotebookMgr::init()
|
||||
{
|
||||
initVersionControllerServer();
|
||||
|
@ -32,6 +32,8 @@ namespace vnotex
|
||||
|
||||
void init();
|
||||
|
||||
void close();
|
||||
|
||||
QSharedPointer<INotebookFactory> getBundleNotebookFactory() const;
|
||||
|
||||
QList<QSharedPointer<INotebookFactory>> getAllNotebookFactories() const;
|
||||
|
@ -10,8 +10,6 @@ FramelessMainWindow::FramelessMainWindow(bool p_frameless, QWidget *p_parent)
|
||||
m_defaultFlags(windowFlags())
|
||||
{
|
||||
if (m_frameless) {
|
||||
m_resizeAreaWidth *= devicePixelRatio();
|
||||
|
||||
setWindowFlags(m_defaultFlags | Qt::FramelessWindowHint);
|
||||
}
|
||||
}
|
||||
@ -27,7 +25,6 @@ void FramelessMainWindow::setTitleBar(QWidget *p_titleBar)
|
||||
Q_ASSERT(!m_titleBar && m_frameless);
|
||||
|
||||
m_titleBar = p_titleBar;
|
||||
m_titleBar->installEventFilter(this);
|
||||
}
|
||||
|
||||
void FramelessMainWindow::changeEvent(QEvent *p_event)
|
||||
@ -36,7 +33,8 @@ void FramelessMainWindow::changeEvent(QEvent *p_event)
|
||||
|
||||
if (p_event->type() == QEvent::WindowStateChange) {
|
||||
m_windowStates = windowState();
|
||||
m_resizable = m_movable = m_windowStates == Qt::WindowNoState;
|
||||
m_resizable = m_windowStates == Qt::WindowNoState;
|
||||
m_movable = m_windowStates == Qt::WindowNoState;
|
||||
emit windowStateChanged(m_windowStates);
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ namespace vnotex
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FramelessMainWindow(bool p_frameless, QWidget *p_parent);
|
||||
FramelessMainWindow(bool p_frameless, QWidget *p_parent = nullptr);
|
||||
|
||||
bool isFrameless() const;
|
||||
|
||||
void setTitleBar(QWidget *p_titleBar);
|
||||
virtual void setTitleBar(QWidget *p_titleBar);
|
||||
|
||||
signals:
|
||||
void windowStateChanged(Qt::WindowStates p_state);
|
||||
@ -30,8 +30,6 @@ namespace vnotex
|
||||
|
||||
const bool m_frameless = true;
|
||||
|
||||
int m_resizeAreaWidth = 5;
|
||||
|
||||
bool m_movable = true;
|
||||
|
||||
bool m_resizable = true;
|
||||
|
@ -2,13 +2,14 @@
|
||||
#define FRAMELESSMAINWINDOWIMPL_H
|
||||
|
||||
#include "framelessmainwindowwin.h"
|
||||
#include "framelessmainwindowlinux.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
typedef FramelessMainWindowWin FramelessMainWindowImpl;
|
||||
#else
|
||||
typedef FramelessMainWindow FramelessMainWindowImpl;
|
||||
typedef FramelessMainWindowLinux FramelessMainWindowImpl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
233
src/widgets/framelessmainwindow/framelessmainwindowlinux.cpp
Normal file
233
src/widgets/framelessmainwindow/framelessmainwindowlinux.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
#include "framelessmainwindowlinux.h"
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include <QHoverEvent>
|
||||
#include <QGuiApplication>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
FramelessMainWindowLinux::FramelessMainWindowLinux(bool p_frameless, QWidget *p_parent)
|
||||
: FramelessMainWindow(p_frameless, p_parent)
|
||||
{
|
||||
if (m_frameless) {
|
||||
// installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool FramelessMainWindowLinux::eventFilter(QObject *p_obj, QEvent *p_event)
|
||||
{
|
||||
if (!m_frameless) {
|
||||
return FramelessMainWindow::eventFilter(p_obj, p_event);
|
||||
}
|
||||
|
||||
if (p_obj == m_titleBar) {
|
||||
const auto type = p_event->type();
|
||||
if (type == QEvent::MouseButtonDblClick
|
||||
|| type == QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
if (!(m_windowStates & Qt::WindowFullScreen)) {
|
||||
if (m_windowStates & Qt::WindowMaximized) {
|
||||
showNormal();
|
||||
} else {
|
||||
showMaximized();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (p_obj == this) {
|
||||
doResize(p_event);
|
||||
}
|
||||
|
||||
return FramelessMainWindow::eventFilter(p_obj, p_event);
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::setTitleBar(QWidget *p_titleBar)
|
||||
{
|
||||
FramelessMainWindow::setTitleBar(p_titleBar);
|
||||
|
||||
m_titleBar->installEventFilter(this);
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::mousePressEvent(QMouseEvent *p_event)
|
||||
{
|
||||
FramelessMainWindow::mousePressEvent(p_event);
|
||||
|
||||
if (m_frameless) {
|
||||
recordMousePress(p_event->pos());
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::recordMousePress(const QPoint &p_pos)
|
||||
{
|
||||
m_mousePressed = true;
|
||||
m_mousePressPoint = p_pos;
|
||||
m_rectOnMousePress = geometry();
|
||||
m_mousePressArea = hitArea(m_mousePressPoint);
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::mouseReleaseEvent(QMouseEvent *p_event)
|
||||
{
|
||||
FramelessMainWindow::mouseReleaseEvent(p_event);
|
||||
|
||||
if (m_frameless) {
|
||||
// setCursor(Qt::ArrowCursor);
|
||||
m_mousePressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::mouseMoveEvent(QMouseEvent *p_event)
|
||||
{
|
||||
FramelessMainWindow::mouseMoveEvent(p_event);
|
||||
|
||||
if (m_frameless) {
|
||||
Q_ASSERT(m_mousePressed);
|
||||
if (m_movable && m_mousePressArea == Area::Caption) {
|
||||
const auto delta = p_event->pos() - m_mousePressPoint;
|
||||
move(pos() + delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::doResize(QEvent *p_event)
|
||||
{
|
||||
Q_UNUSED(p_event);
|
||||
#if 0
|
||||
static bool needResetCursor = false;
|
||||
|
||||
switch (p_event->type()) {
|
||||
case QEvent::HoverMove:
|
||||
{
|
||||
if (!m_resizable) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto eve = static_cast<QHoverEvent *>(p_event);
|
||||
const auto evePos = eve->pos();
|
||||
const auto area = hitArea(evePos);
|
||||
if (!m_mousePressed && area != Area::None && area != Area::Caption) {
|
||||
// Mouse press event may be blocked by the children of QMainWindow.
|
||||
if (QGuiApplication::mouseButtons() != Qt::NoButton) {
|
||||
recordMousePress(evePos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mousePressed) {
|
||||
const auto delta = evePos - m_mousePressPoint;
|
||||
switch (m_mousePressArea) {
|
||||
case Area::Left:
|
||||
{
|
||||
int newWidth = m_rectOnMousePress.width() - delta.x();
|
||||
qDebug() << newWidth << minimumWidth();
|
||||
if (minimumWidth() <= newWidth) {
|
||||
setGeometry(m_rectOnMousePress.x() + delta.x(),
|
||||
m_rectOnMousePress.y(),
|
||||
newWidth,
|
||||
m_rectOnMousePress.height());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (area) {
|
||||
case Area::Left:
|
||||
Q_FALLTHROUGH();
|
||||
case Area::Right:
|
||||
needResetCursor = true;
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
|
||||
case Area::Top:
|
||||
Q_FALLTHROUGH();
|
||||
case Area::Bottom:
|
||||
needResetCursor = true;
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
|
||||
case Area::TopLeft:
|
||||
Q_FALLTHROUGH();
|
||||
case Area::BottomRight:
|
||||
needResetCursor = true;
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
|
||||
case Area::TopRight:
|
||||
Q_FALLTHROUGH();
|
||||
case Area::BottomLeft:
|
||||
needResetCursor = true;
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (needResetCursor) {
|
||||
needResetCursor = false;
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
FramelessMainWindowLinux::Area FramelessMainWindowLinux::hitArea(const QPoint &p_pos) const
|
||||
{
|
||||
const int x = p_pos.x();
|
||||
const int y = p_pos.y();
|
||||
Area area = Area::None;
|
||||
if (x < m_resizeAreaWidth) {
|
||||
// Left.
|
||||
if (y < m_resizeAreaWidth) {
|
||||
// Top.
|
||||
area = Area::TopLeft;
|
||||
} else if (y > height() - m_resizeAreaWidth) {
|
||||
// Bottom.
|
||||
area = Area::BottomLeft;
|
||||
} else {
|
||||
area = Area::Left;
|
||||
}
|
||||
} else if (x > width() - m_resizeAreaWidth) {
|
||||
// Right.
|
||||
if (y < m_resizeAreaWidth) {
|
||||
// Top.
|
||||
area = Area::TopRight;
|
||||
} else if (y > height() - m_resizeAreaWidth) {
|
||||
// Bottom.
|
||||
area = Area::BottomRight;
|
||||
} else {
|
||||
area = Area::Right;
|
||||
}
|
||||
} else if (y < m_resizeAreaWidth) {
|
||||
// Top.
|
||||
area = Area::Top;
|
||||
} else if (y > height() - m_resizeAreaWidth) {
|
||||
// Bottom.
|
||||
area = Area::Bottom;
|
||||
} else if (y < m_titleBarHeight) {
|
||||
area = Area::Caption;
|
||||
}
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
void FramelessMainWindowLinux::showEvent(QShowEvent *p_event)
|
||||
{
|
||||
FramelessMainWindow::showEvent(p_event);
|
||||
|
||||
if (m_frameless && m_titleBarHeight == 0 && m_titleBar) {
|
||||
m_titleBarHeight = m_titleBar->height();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
71
src/widgets/framelessmainwindow/framelessmainwindowlinux.h
Normal file
71
src/widgets/framelessmainwindow/framelessmainwindowlinux.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef FRAMELESSMAINWINDOWLINUX_H
|
||||
#define FRAMELESSMAINWINDOWLINUX_H
|
||||
|
||||
#include "framelessmainwindow.h"
|
||||
|
||||
#include <QRect>
|
||||
#include <QVector>
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
#ifndef Q_OS_WIN
|
||||
class FramelessMainWindowLinux : public FramelessMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FramelessMainWindowLinux(bool p_frameless, QWidget *p_parent = nullptr);
|
||||
|
||||
void setTitleBar(QWidget *p_titleBar) Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
enum Area
|
||||
{
|
||||
Left = 0,
|
||||
TopLeft,
|
||||
Top,
|
||||
TopRight,
|
||||
Right,
|
||||
BottomRight,
|
||||
Bottom,
|
||||
BottomLeft,
|
||||
Caption,
|
||||
None
|
||||
};
|
||||
|
||||
Area hitArea(const QPoint &p_pos) const;
|
||||
|
||||
void doResize(QEvent *p_event);
|
||||
|
||||
void recordMousePress(const QPoint &p_pos);
|
||||
|
||||
const int m_resizeAreaWidth = 6;
|
||||
|
||||
int m_titleBarHeight = 0;
|
||||
|
||||
Area m_mousePressArea = Area::None;
|
||||
|
||||
QPoint m_mousePressPoint;
|
||||
|
||||
bool m_mousePressed = false;
|
||||
|
||||
QRect m_rectOnMousePress;
|
||||
};
|
||||
#else
|
||||
class FramelessMainWindowLinuxDummy
|
||||
{
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // FRAMELESSMAINWINDOWLINUX_H
|
@ -18,6 +18,8 @@ FramelessMainWindowWin::FramelessMainWindowWin(bool p_frameless, QWidget *p_pare
|
||||
: FramelessMainWindow(p_frameless, p_parent)
|
||||
{
|
||||
if (m_frameless) {
|
||||
m_resizeAreaWidth *= devicePixelRatio();
|
||||
|
||||
m_redrawTimer = new QTimer(this);
|
||||
m_redrawTimer->setSingleShot(true);
|
||||
m_redrawTimer->setInterval(500);
|
||||
@ -68,31 +70,36 @@ bool FramelessMainWindowWin::nativeEvent(const QByteArray &p_eventType, void *p_
|
||||
::GetWindowRect(msg->hwnd, &windowRect);
|
||||
|
||||
// x and y could not be compared with width() and height() in hidpi case.
|
||||
int x = static_cast<int>(GET_X_LPARAM(msg->lParam) - windowRect.left);
|
||||
int y = static_cast<int>(GET_Y_LPARAM(msg->lParam) - windowRect.top);
|
||||
|
||||
bool onLeft = x < m_resizeAreaWidth;
|
||||
bool onRight = x > windowRect.right - windowRect.left - m_resizeAreaWidth;
|
||||
bool onTop = y < m_resizeAreaWidth;
|
||||
bool onBottom = y > windowRect.bottom - windowRect.top - m_resizeAreaWidth;
|
||||
const int x = static_cast<int>(GET_X_LPARAM(msg->lParam) - windowRect.left);
|
||||
const int y = static_cast<int>(GET_Y_LPARAM(msg->lParam) - windowRect.top);
|
||||
|
||||
*p_result = 0;
|
||||
if (m_resizable) {
|
||||
if (onLeft && onTop) {
|
||||
*p_result = HTTOPLEFT;
|
||||
} else if (onLeft && onBottom) {
|
||||
*p_result = HTBOTTOMLEFT;
|
||||
} else if (onRight && onTop) {
|
||||
*p_result = HTTOPRIGHT;
|
||||
} else if (onRight && onBottom) {
|
||||
*p_result = HTBOTTOMRIGHT;
|
||||
} else if (onLeft) {
|
||||
*p_result = HTLEFT;
|
||||
} else if (onRight) {
|
||||
*p_result = HTRIGHT;
|
||||
} else if (onTop) {
|
||||
if (x < m_resizeAreaWidth) {
|
||||
// Left.
|
||||
if (y < m_resizeAreaWidth) {
|
||||
// Top.
|
||||
*p_result = HTTOPLEFT;
|
||||
} else if (y > windowRect.bottom - windowRect.top - m_resizeAreaWidth) {
|
||||
// Bottom.
|
||||
*p_result = HTBOTTOMLEFT;
|
||||
} else {
|
||||
*p_result = HTLEFT;
|
||||
}
|
||||
} else if (x > windowRect.right - windowRect.left - m_resizeAreaWidth) {
|
||||
// Right.
|
||||
if (y < m_resizeAreaWidth) {
|
||||
// Top.
|
||||
*p_result = HTTOPRIGHT;
|
||||
} else if (y > windowRect.bottom - windowRect.top - m_resizeAreaWidth) {
|
||||
// Bottom.
|
||||
*p_result = HTBOTTOMRIGHT;
|
||||
} else {
|
||||
*p_result = HTRIGHT;
|
||||
}
|
||||
} else if (y < m_resizeAreaWidth) {
|
||||
*p_result = HTTOP;
|
||||
} else if (onBottom) {
|
||||
} else if (y > windowRect.bottom - windowRect.top - m_resizeAreaWidth) {
|
||||
*p_result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace vnotex
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FramelessMainWindowWin(bool p_frameless = true, QWidget *p_parent = nullptr);
|
||||
FramelessMainWindowWin(bool p_frameless, QWidget *p_parent = nullptr);
|
||||
|
||||
protected:
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
@ -27,6 +27,8 @@ namespace vnotex
|
||||
|
||||
void updateMargins();
|
||||
|
||||
int m_resizeAreaWidth = 6;
|
||||
|
||||
QTimer *m_redrawTimer = nullptr;
|
||||
|
||||
QSize m_sizeBeforeMove;
|
||||
@ -35,6 +37,10 @@ namespace vnotex
|
||||
|
||||
int m_titleBarHeight = 0;
|
||||
};
|
||||
#else
|
||||
class FramelessMainWindowWinDummy
|
||||
{
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -547,6 +547,8 @@ void MainWindow::closeOnQuit()
|
||||
{
|
||||
// No user interaction is available.
|
||||
emit mainWindowClosedOnQuit();
|
||||
|
||||
VNoteX::getInst().getNotebookMgr().close();
|
||||
}
|
||||
|
||||
void MainWindow::setupShortcuts()
|
||||
|
@ -59,6 +59,7 @@ SOURCES += \
|
||||
$$PWD/findandreplacewidget.cpp \
|
||||
$$PWD/floatingwidget.cpp \
|
||||
$$PWD/framelessmainwindow/framelessmainwindow.cpp \
|
||||
$$PWD/framelessmainwindow/framelessmainwindowlinux.cpp \
|
||||
$$PWD/framelessmainwindow/framelessmainwindowwin.cpp \
|
||||
$$PWD/fullscreentoggleaction.cpp \
|
||||
$$PWD/historypanel.cpp \
|
||||
@ -185,6 +186,7 @@ HEADERS += \
|
||||
$$PWD/floatingwidget.h \
|
||||
$$PWD/framelessmainwindow/framelessmainwindow.h \
|
||||
$$PWD/framelessmainwindow/framelessmainwindowimpl.h \
|
||||
$$PWD/framelessmainwindow/framelessmainwindowlinux.h \
|
||||
$$PWD/framelessmainwindow/framelessmainwindowwin.h \
|
||||
$$PWD/fullscreentoggleaction.h \
|
||||
$$PWD/historypanel.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user