mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
introduce FramelessMainWindow
This commit is contained in:
parent
0a2bdc7033
commit
5bc48be5d0
@ -21,6 +21,10 @@ QVector<NotebookTagMgr::TagGraphPair> NotebookTagMgr::stringToTagGraph(const QSt
|
|||||||
QVector<TagGraphPair> tagGraph;
|
QVector<TagGraphPair> tagGraph;
|
||||||
auto pairs = p_text.split(QLatin1Char(';'));
|
auto pairs = p_text.split(QLatin1Char(';'));
|
||||||
for (const auto &pa : pairs) {
|
for (const auto &pa : pairs) {
|
||||||
|
if (pa.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto paCh = pa.split(QLatin1Char('>'));
|
auto paCh = pa.split(QLatin1Char('>'));
|
||||||
if (paCh.size() != 2 || paCh[0].isEmpty() || paCh[1].isEmpty()) {
|
if (paCh.size() != 2 || paCh[0].isEmpty() || paCh[1].isEmpty()) {
|
||||||
qWarning() << "ignore invalid <parent, child> tag pair" << pa;
|
qWarning() << "ignore invalid <parent, child> tag pair" << pa;
|
||||||
|
@ -1 +1 @@
|
|||||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1630643879525" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4410" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M810.666667 512V384h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333V128H213.333333v384h597.333334zM128 512V128a85.333333 85.333333 0 0 1 85.333333-85.333333h444.330667L896 281.002667V512h85.333333v85.333333H42.666667v-85.333333h85.333333z m682.666667 170.666667h85.333333v213.333333a85.333333 85.333333 0 0 1-85.333333 85.333333H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-213.333333h85.333333v213.333333h597.333334v-213.333333zM640 145.664V298.666667h153.002667L640 145.664z" p-id="4411" fill="#000000"></path></svg>
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1634653362644" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2399" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M688 312v-48c0-4.4-3.6-8-8-8H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8zM296 400c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H296z" p-id="2400" fill="#000000"></path><path d="M440 852H208V148h560v344c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V108c0-17.7-14.3-32-32-32H168c-17.7 0-32 14.3-32 32v784c0 17.7 14.3 32 32 32h272c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z" p-id="2401" fill="#000000"></path><path d="M885.7 903.5l-93.3-93.3C814.7 780.7 828 743.9 828 704c0-97.2-78.8-176-176-176s-176 78.8-176 176 78.8 176 176 176c35.8 0 69-10.7 96.8-29l94.7 94.7c1.6 1.6 3.6 2.3 5.6 2.3s4.1-0.8 5.6-2.3l31-31c3.1-3.1 3.1-8.1 0-11.2zM652 816c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z" p-id="2402" fill="#000000"></path></svg>
|
Before Width: | Height: | Size: 918 B After Width: | Height: | Size: 1.1 KiB |
47
src/widgets/framelessmainwindow/framelessmainwindow.cpp
Normal file
47
src/widgets/framelessmainwindow/framelessmainwindow.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "framelessmainwindow.h"
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
|
using namespace vnotex;
|
||||||
|
|
||||||
|
FramelessMainWindow::FramelessMainWindow(bool p_frameless, QWidget *p_parent)
|
||||||
|
: QMainWindow(p_parent),
|
||||||
|
m_frameless(p_frameless),
|
||||||
|
m_defaultFlags(windowFlags())
|
||||||
|
{
|
||||||
|
if (m_frameless) {
|
||||||
|
m_resizeAreaWidth *= devicePixelRatio();
|
||||||
|
|
||||||
|
setWindowFlags(m_defaultFlags | Qt::FramelessWindowHint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FramelessMainWindow::isFrameless() const
|
||||||
|
{
|
||||||
|
return m_frameless;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
QMainWindow::changeEvent(p_event);
|
||||||
|
|
||||||
|
if (p_event->type() == QEvent::WindowStateChange) {
|
||||||
|
m_windowStates = windowState();
|
||||||
|
m_resizable = m_movable = m_windowStates == Qt::WindowNoState;
|
||||||
|
emit windowStateChanged(m_windowStates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FramelessMainWindow::isMaximized() const
|
||||||
|
{
|
||||||
|
return (m_windowStates & Qt::WindowMaximized) && !(m_windowStates & Qt::WindowFullScreen);
|
||||||
|
}
|
47
src/widgets/framelessmainwindow/framelessmainwindow.h
Normal file
47
src/widgets/framelessmainwindow/framelessmainwindow.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef FRAMELESSMAINWINDOW_H
|
||||||
|
#define FRAMELESSMAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QMargins>
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
|
namespace vnotex
|
||||||
|
{
|
||||||
|
// Base class. Use FramelessMainWindowImpl instead.
|
||||||
|
class FramelessMainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FramelessMainWindow(bool p_frameless, QWidget *p_parent);
|
||||||
|
|
||||||
|
bool isFrameless() const;
|
||||||
|
|
||||||
|
void setTitleBar(QWidget *p_titleBar);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void windowStateChanged(Qt::WindowStates p_state);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent(QEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isMaximized() const;
|
||||||
|
|
||||||
|
const bool m_frameless = true;
|
||||||
|
|
||||||
|
int m_resizeAreaWidth = 5;
|
||||||
|
|
||||||
|
bool m_movable = true;
|
||||||
|
|
||||||
|
bool m_resizable = true;
|
||||||
|
|
||||||
|
const Qt::WindowFlags m_defaultFlags;
|
||||||
|
|
||||||
|
QWidget *m_titleBar = nullptr;
|
||||||
|
|
||||||
|
Qt::WindowStates m_windowStates = Qt::WindowNoState;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRAMELESSMAINWINDOW_H
|
15
src/widgets/framelessmainwindow/framelessmainwindowimpl.h
Normal file
15
src/widgets/framelessmainwindow/framelessmainwindowimpl.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef FRAMELESSMAINWINDOWIMPL_H
|
||||||
|
#define FRAMELESSMAINWINDOWIMPL_H
|
||||||
|
|
||||||
|
#include "framelessmainwindowwin.h"
|
||||||
|
|
||||||
|
namespace vnotex
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
typedef FramelessMainWindowWin FramelessMainWindowImpl;
|
||||||
|
#else
|
||||||
|
typedef FramelessMainWindow FramelessMainWindowImpl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRAMELESSMAINWINDOWIMPL_H
|
217
src/widgets/framelessmainwindow/framelessmainwindowwin.cpp
Normal file
217
src/widgets/framelessmainwindow/framelessmainwindowwin.cpp
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
#include "framelessmainwindowwin.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#include <dwmapi.h>
|
||||||
|
#pragma comment (lib,"dwmapi.lib")
|
||||||
|
#pragma comment (lib, "user32.lib")
|
||||||
|
|
||||||
|
using namespace vnotex;
|
||||||
|
|
||||||
|
FramelessMainWindowWin::FramelessMainWindowWin(bool p_frameless, QWidget *p_parent)
|
||||||
|
: FramelessMainWindow(p_frameless, p_parent)
|
||||||
|
{
|
||||||
|
if (m_frameless) {
|
||||||
|
m_redrawTimer = new QTimer(this);
|
||||||
|
m_redrawTimer->setSingleShot(true);
|
||||||
|
m_redrawTimer->setInterval(500);
|
||||||
|
connect(m_redrawTimer, &QTimer::timeout,
|
||||||
|
this, &FramelessMainWindowWin::forceRedraw);
|
||||||
|
|
||||||
|
connect(this, &FramelessMainWindow::windowStateChanged,
|
||||||
|
this, &FramelessMainWindowWin::updateMargins);
|
||||||
|
|
||||||
|
// Enable some window effects on Win, such as snap and maximizing.
|
||||||
|
// It will activate the title bar again. Need to remove it in WM_NCCALCSIZE msg.
|
||||||
|
HWND hwnd = reinterpret_cast<HWND>(winId());
|
||||||
|
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||||
|
::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
|
||||||
|
|
||||||
|
// Leave 1 pixel width of border so OS will draw a window shadow.
|
||||||
|
const MARGINS shadow = {1, 1, 1, 1};
|
||||||
|
DwmExtendFrameIntoClientArea(hwnd, &shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||||
|
bool FramelessMainWindowWin::nativeEvent(const QByteArray &p_eventType, void *p_message, qintptr *p_result)
|
||||||
|
#else
|
||||||
|
bool FramelessMainWindowWin::nativeEvent(const QByteArray &p_eventType, void *p_message, long *p_result)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (!m_frameless) {
|
||||||
|
return FramelessMainWindow::nativeEvent(p_eventType, p_message, p_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_eventType == QStringLiteral("windows_generic_MSG")) {
|
||||||
|
MSG *msg = static_cast<MSG *>(p_message);
|
||||||
|
|
||||||
|
switch (msg->message) {
|
||||||
|
case WM_NCCALCSIZE:
|
||||||
|
*p_result = 0;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case WM_NCHITTEST:
|
||||||
|
{
|
||||||
|
if (m_windowStates & Qt::WindowFullScreen) {
|
||||||
|
*p_result = HTCLIENT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT windowRect;
|
||||||
|
::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;
|
||||||
|
|
||||||
|
*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) {
|
||||||
|
*p_result = HTTOP;
|
||||||
|
} else if (onBottom) {
|
||||||
|
*p_result = HTBOTTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != *p_result) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_titleBar) {
|
||||||
|
if (m_titleBarHeight == 0) {
|
||||||
|
m_titleBarHeight = m_titleBar->height() * devicePixelRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < m_titleBarHeight) {
|
||||||
|
QWidget *child = m_titleBar->childAt(m_titleBar->mapFromGlobal(QCursor::pos()));
|
||||||
|
if (!child) {
|
||||||
|
*p_result = HTCAPTION;
|
||||||
|
if (::GetAsyncKeyState(VK_LBUTTON) < 0 || ::GetAsyncKeyState(VK_RBUTTON) < 0) {
|
||||||
|
m_sizeBeforeMove = size();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_POWERBROADCAST:
|
||||||
|
{
|
||||||
|
if (msg->wParam == PBT_APMSUSPEND) {
|
||||||
|
// Minimize when system is going to sleep to avoid bugs.
|
||||||
|
showMinimized();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_GETMINMAXINFO:
|
||||||
|
{
|
||||||
|
// When maximized, OS will expand the content area. To avoid missing the real contents, set extra margins.
|
||||||
|
if (::IsZoomed(msg->hwnd)) {
|
||||||
|
RECT frame = {0, 0, 0, 0};
|
||||||
|
::AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, false, 0);
|
||||||
|
const int dpiScale = devicePixelRatio();
|
||||||
|
m_maximizedMargins.setLeft(qAbs(frame.left) / dpiScale);
|
||||||
|
// Use bottom as top.
|
||||||
|
m_maximizedMargins.setTop(qAbs(frame.bottom) / dpiScale);
|
||||||
|
m_maximizedMargins.setRight(frame.right / dpiScale);
|
||||||
|
m_maximizedMargins.setBottom(frame.bottom / dpiScale);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (msg->wParam == PBT_APMRESUMESUSPEND) {
|
||||||
|
// Show after resuming from sleep.
|
||||||
|
showNormal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FramelessMainWindow::nativeEvent(p_eventType, p_message, p_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessMainWindowWin::moveEvent(QMoveEvent *p_event)
|
||||||
|
{
|
||||||
|
FramelessMainWindow::moveEvent(p_event);
|
||||||
|
|
||||||
|
if (m_frameless) {
|
||||||
|
if (m_windowStates & Qt::WindowMaximized) {
|
||||||
|
m_redrawTimer->stop();
|
||||||
|
} else {
|
||||||
|
m_redrawTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessMainWindowWin::updateMargins()
|
||||||
|
{
|
||||||
|
if (!m_frameless) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int topMargin = 0;
|
||||||
|
if (isMaximized()) {
|
||||||
|
setContentsMargins(m_maximizedMargins);
|
||||||
|
topMargin = m_maximizedMargins.top();
|
||||||
|
} else {
|
||||||
|
setContentsMargins(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_titleBar) {
|
||||||
|
m_titleBarHeight = (m_titleBar->height() + topMargin) * devicePixelRatio();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessMainWindowWin::forceRedraw()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_frameless);
|
||||||
|
if (m_windowStates & Qt::WindowMaximized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSize sz = size();
|
||||||
|
RECT frame;
|
||||||
|
::GetWindowRect((HWND)winId(), &frame);
|
||||||
|
const int clientWidth = (frame.right - frame.left) / devicePixelRatio();
|
||||||
|
const int clientHeight = (frame.bottom - frame.top) / devicePixelRatio();
|
||||||
|
if (clientWidth != sz.width() || clientHeight != sz.height()) {
|
||||||
|
// resize() may result to "unable to set geometry" warning.
|
||||||
|
// adjustsize() or resize() to another size before could solve this.
|
||||||
|
resize(sz.width() + 1, sz.height() + 1);
|
||||||
|
if (m_sizeBeforeMove.isEmpty()) {
|
||||||
|
resize(clientWidth, clientHeight);
|
||||||
|
} else {
|
||||||
|
resize(m_sizeBeforeMove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
41
src/widgets/framelessmainwindow/framelessmainwindowwin.h
Normal file
41
src/widgets/framelessmainwindow/framelessmainwindowwin.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef FRAMELESSMAINWINDOWWIN_H
|
||||||
|
#define FRAMELESSMAINWINDOWWIN_H
|
||||||
|
|
||||||
|
#include "framelessmainwindow.h"
|
||||||
|
|
||||||
|
namespace vnotex
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
class FramelessMainWindowWin : public FramelessMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FramelessMainWindowWin(bool p_frameless = true, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||||
|
bool nativeEvent(const QByteArray &p_eventType, void *p_message, qintptr *p_result);
|
||||||
|
#else
|
||||||
|
bool nativeEvent(const QByteArray &p_eventType, void *p_message, long *p_result);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void moveEvent(QMoveEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// To fix some unkonwn bugs of the interface.
|
||||||
|
void forceRedraw();
|
||||||
|
|
||||||
|
void updateMargins();
|
||||||
|
|
||||||
|
QTimer *m_redrawTimer = nullptr;
|
||||||
|
|
||||||
|
QSize m_sizeBeforeMove;
|
||||||
|
|
||||||
|
QMargins m_maximizedMargins;
|
||||||
|
|
||||||
|
int m_titleBarHeight = 0;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRAMELESSMAINWINDOWWIN_H
|
@ -58,7 +58,7 @@
|
|||||||
using namespace vnotex;
|
using namespace vnotex;
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *p_parent)
|
MainWindow::MainWindow(QWidget *p_parent)
|
||||||
: QMainWindow(p_parent),
|
: FramelessMainWindowImpl(!ConfigMgr::getInst().getSessionConfig().getSystemTitleBarEnabled(), p_parent),
|
||||||
m_toolBarHelper(this),
|
m_toolBarHelper(this),
|
||||||
m_statusBarHelper(this),
|
m_statusBarHelper(this),
|
||||||
m_dockWidgetHelper(this)
|
m_dockWidgetHelper(this)
|
||||||
@ -393,7 +393,7 @@ void MainWindow::closeEvent(QCloseEvent *p_event)
|
|||||||
|
|
||||||
m_trayIcon->hide();
|
m_trayIcon->hide();
|
||||||
|
|
||||||
QMainWindow::closeEvent(p_event);
|
FramelessMainWindowImpl::closeEvent(p_event);
|
||||||
qApp->exit(exitCode > -1 ? exitCode : 0);
|
qApp->exit(exitCode > -1 ? exitCode : 0);
|
||||||
} else {
|
} else {
|
||||||
hide();
|
hide();
|
||||||
@ -521,16 +521,8 @@ void MainWindow::setupToolBar()
|
|||||||
{
|
{
|
||||||
const int sz = ConfigMgr::getInst().getCoreConfig().getToolBarIconSize();
|
const int sz = ConfigMgr::getInst().getCoreConfig().getToolBarIconSize();
|
||||||
const QSize iconSize(sz, sz);
|
const QSize iconSize(sz, sz);
|
||||||
if (!ConfigMgr::getInst().getSessionConfig().getSystemTitleBarEnabled()) {
|
|
||||||
// Use unified tool bar as title bar.
|
|
||||||
auto framelessFlags = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint
|
|
||||||
| Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint;
|
|
||||||
|
|
||||||
auto winFlags = windowFlags();
|
|
||||||
winFlags |= Qt::CustomizeWindowHint | Qt::FramelessWindowHint;
|
|
||||||
winFlags &= ~framelessFlags;
|
|
||||||
setWindowFlags(winFlags);
|
|
||||||
|
|
||||||
|
if (isFrameless()) {
|
||||||
auto toolBar = new TitleToolBar(tr("Global"), this);
|
auto toolBar = new TitleToolBar(tr("Global"), this);
|
||||||
toolBar->setIconSize(iconSize);
|
toolBar->setIconSize(iconSize);
|
||||||
m_toolBarHelper.setupToolBars(toolBar);
|
m_toolBarHelper.setupToolBars(toolBar);
|
||||||
@ -538,6 +530,9 @@ void MainWindow::setupToolBar()
|
|||||||
ToolBarHelper::generateIcon(QStringLiteral("maximize.svg")),
|
ToolBarHelper::generateIcon(QStringLiteral("maximize.svg")),
|
||||||
ToolBarHelper::generateIcon(QStringLiteral("maximize_restore.svg")),
|
ToolBarHelper::generateIcon(QStringLiteral("maximize_restore.svg")),
|
||||||
ToolBarHelper::generateDangerousIcon(QStringLiteral("close.svg")));
|
ToolBarHelper::generateDangerousIcon(QStringLiteral("close.svg")));
|
||||||
|
setTitleBar(toolBar);
|
||||||
|
connect(this, &FramelessMainWindowImpl::windowStateChanged,
|
||||||
|
toolBar, &TitleToolBar::updateMaximizeAct);
|
||||||
} else {
|
} else {
|
||||||
auto toolBar = new QToolBar(tr("Global"), this);
|
auto toolBar = new QToolBar(tr("Global"), this);
|
||||||
toolBar->setIconSize(iconSize);
|
toolBar->setIconSize(iconSize);
|
||||||
@ -594,7 +589,7 @@ void MainWindow::changeEvent(QEvent *p_event)
|
|||||||
m_windowOldState = eve->oldState();
|
m_windowOldState = eve->oldState();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMainWindow::changeEvent(p_event);
|
FramelessMainWindowImpl::changeEvent(p_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showMainWindow()
|
void MainWindow::showMainWindow()
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include "framelessmainwindow/framelessmainwindowimpl.h"
|
||||||
|
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QBitArray>
|
#include <QBitArray>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
@ -30,7 +31,7 @@ namespace vnotex
|
|||||||
|
|
||||||
enum { RESTART_EXIT_CODE = 1000 };
|
enum { RESTART_EXIT_CODE = 1000 };
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public FramelessMainWindowImpl
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -106,9 +106,9 @@ void TagExplorer::setupTagTree(QWidget *p_parent)
|
|||||||
TreeWidget::showHorizontalScrollbar(m_tagTree);
|
TreeWidget::showHorizontalScrollbar(m_tagTree);
|
||||||
m_tagTree->setDragDropMode(QAbstractItemView::InternalMove);
|
m_tagTree->setDragDropMode(QAbstractItemView::InternalMove);
|
||||||
connect(m_tagTree, &QTreeWidget::currentItemChanged,
|
connect(m_tagTree, &QTreeWidget::currentItemChanged,
|
||||||
timer, QOverload<void>::of(&QTimer::start));
|
timer, QOverload<>::of(&QTimer::start));
|
||||||
connect(m_tagTree, &QTreeWidget::itemClicked,
|
connect(m_tagTree, &QTreeWidget::itemClicked,
|
||||||
timer, QOverload<void>::of(&QTimer::start));
|
timer, QOverload<>::of(&QTimer::start));
|
||||||
connect(m_tagTree, &QTreeWidget::customContextMenuRequested,
|
connect(m_tagTree, &QTreeWidget::customContextMenuRequested,
|
||||||
this, &TagExplorer::handleTagTreeContextMenuRequested);
|
this, &TagExplorer::handleTagTreeContextMenuRequested);
|
||||||
connect(m_tagTree, &TreeWidget::itemMoved,
|
connect(m_tagTree, &TreeWidget::itemMoved,
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#include "titletoolbar.h"
|
#include "titletoolbar.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
|
||||||
#include "propertydefs.h"
|
#include "propertydefs.h"
|
||||||
@ -14,7 +11,6 @@ TitleToolBar::TitleToolBar(QWidget *p_parent)
|
|||||||
m_window(p_parent)
|
m_window(p_parent)
|
||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
m_window->installEventFilter(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleToolBar::TitleToolBar(const QString &p_title, QWidget *p_parent)
|
TitleToolBar::TitleToolBar(const QString &p_title, QWidget *p_parent)
|
||||||
@ -22,51 +18,17 @@ TitleToolBar::TitleToolBar(const QString &p_title, QWidget *p_parent)
|
|||||||
m_window(p_parent)
|
m_window(p_parent)
|
||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
m_window->installEventFilter(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleToolBar::setupUI()
|
void TitleToolBar::setupUI()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleToolBar::mousePressEvent(QMouseEvent *p_event)
|
|
||||||
{
|
|
||||||
QToolBar::mousePressEvent(p_event);
|
|
||||||
m_lastPos = p_event->pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TitleToolBar::mouseDoubleClickEvent(QMouseEvent *p_event)
|
|
||||||
{
|
|
||||||
QToolBar::mouseDoubleClickEvent(p_event);
|
|
||||||
m_ignoreNextMove = true;
|
|
||||||
maximizeRestoreWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TitleToolBar::maximizeRestoreWindow()
|
void TitleToolBar::maximizeRestoreWindow()
|
||||||
{
|
{
|
||||||
m_window->isMaximized() ? m_window->showNormal() : m_window->showMaximized();
|
m_window->isMaximized() ? m_window->showNormal() : m_window->showMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleToolBar::mouseMoveEvent(QMouseEvent *p_event)
|
|
||||||
{
|
|
||||||
auto delta = p_event->pos() - m_lastPos;
|
|
||||||
if (!m_ignoreNextMove && !m_lastPos.isNull() && (qAbs(delta.x()) > 10 || qAbs(delta.y()) > 10)) {
|
|
||||||
if (m_window->isMaximized()) {
|
|
||||||
m_window->showNormal();
|
|
||||||
} else {
|
|
||||||
m_window->move(p_event->globalPos() - m_lastPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QToolBar::mouseMoveEvent(p_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TitleToolBar::mouseReleaseEvent(QMouseEvent *p_event)
|
|
||||||
{
|
|
||||||
QToolBar::mouseReleaseEvent(p_event);
|
|
||||||
m_ignoreNextMove = false;
|
|
||||||
m_lastPos = QPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TitleToolBar::addTitleBarIcons(const QIcon &p_minimizeIcon,
|
void TitleToolBar::addTitleBarIcons(const QIcon &p_minimizeIcon,
|
||||||
const QIcon &p_maximizeIcon,
|
const QIcon &p_maximizeIcon,
|
||||||
const QIcon &p_restoreIcon,
|
const QIcon &p_restoreIcon,
|
||||||
@ -98,16 +60,6 @@ void TitleToolBar::addTitleBarIcons(const QIcon &p_minimizeIcon,
|
|||||||
updateMaximizeAct();
|
updateMaximizeAct();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TitleToolBar::eventFilter(QObject *p_obj, QEvent *p_event)
|
|
||||||
{
|
|
||||||
if (p_obj == m_window) {
|
|
||||||
if (p_event->type() == QEvent::WindowStateChange) {
|
|
||||||
updateMaximizeAct();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QToolBar::eventFilter(p_obj, p_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TitleToolBar::updateMaximizeAct()
|
void TitleToolBar::updateMaximizeAct()
|
||||||
{
|
{
|
||||||
if (m_window->isMaximized()) {
|
if (m_window->isMaximized()) {
|
||||||
|
@ -19,28 +19,13 @@ namespace vnotex
|
|||||||
const QIcon &p_restoreIcon,
|
const QIcon &p_restoreIcon,
|
||||||
const QIcon &p_closeIcon);
|
const QIcon &p_closeIcon);
|
||||||
|
|
||||||
protected:
|
void updateMaximizeAct();
|
||||||
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 mouseDoubleClickEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
void maximizeRestoreWindow();
|
void maximizeRestoreWindow();
|
||||||
|
|
||||||
void updateMaximizeAct();
|
|
||||||
|
|
||||||
QPoint m_lastPos;
|
|
||||||
|
|
||||||
bool m_ignoreNextMove = false;
|
|
||||||
|
|
||||||
QWidget *m_window = nullptr;
|
QWidget *m_window = nullptr;
|
||||||
|
|
||||||
QAction *m_maximizeAct = nullptr;
|
QAction *m_maximizeAct = nullptr;
|
||||||
|
@ -167,8 +167,6 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar
|
|||||||
auto act = tb->addAction(generateIcon("import_menu.svg"), MainWindow::tr("Import"));
|
auto act = tb->addAction(generateIcon("import_menu.svg"), MainWindow::tr("Import"));
|
||||||
|
|
||||||
auto btn = dynamic_cast<QToolButton *>(tb->widgetForAction(act));
|
auto btn = dynamic_cast<QToolButton *>(tb->widgetForAction(act));
|
||||||
Q_ASSERT(btn);
|
|
||||||
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
||||||
btn->setPopupMode(QToolButton::InstantPopup);
|
btn->setPopupMode(QToolButton::InstantPopup);
|
||||||
btn->setProperty(PropertyDefs::c_toolButtonWithoutMenuIndicator, true);
|
btn->setProperty(PropertyDefs::c_toolButtonWithoutMenuIndicator, true);
|
||||||
|
|
||||||
@ -200,12 +198,6 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar
|
|||||||
|
|
||||||
WidgetUtils::addActionShortcut(exportAct,
|
WidgetUtils::addActionShortcut(exportAct,
|
||||||
coreConfig.getShortcut(CoreConfig::Shortcut::Export));
|
coreConfig.getShortcut(CoreConfig::Shortcut::Export));
|
||||||
|
|
||||||
// To hide the shortcut text shown in button.
|
|
||||||
auto toolBtn = dynamic_cast<QToolButton *>(tb->widgetForAction(exportAct));
|
|
||||||
Q_ASSERT(toolBtn);
|
|
||||||
toolBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
||||||
toolBtn->setText(MainWindow::tr("Export"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tb;
|
return tb;
|
||||||
|
@ -58,6 +58,8 @@ SOURCES += \
|
|||||||
$$PWD/dialogs/folderfilesfilterwidget.cpp \
|
$$PWD/dialogs/folderfilesfilterwidget.cpp \
|
||||||
$$PWD/findandreplacewidget.cpp \
|
$$PWD/findandreplacewidget.cpp \
|
||||||
$$PWD/floatingwidget.cpp \
|
$$PWD/floatingwidget.cpp \
|
||||||
|
$$PWD/framelessmainwindow/framelessmainwindow.cpp \
|
||||||
|
$$PWD/framelessmainwindow/framelessmainwindowwin.cpp \
|
||||||
$$PWD/fullscreentoggleaction.cpp \
|
$$PWD/fullscreentoggleaction.cpp \
|
||||||
$$PWD/historypanel.cpp \
|
$$PWD/historypanel.cpp \
|
||||||
$$PWD/itemproxystyle.cpp \
|
$$PWD/itemproxystyle.cpp \
|
||||||
@ -181,6 +183,9 @@ HEADERS += \
|
|||||||
$$PWD/dialogs/folderfilesfilterwidget.h \
|
$$PWD/dialogs/folderfilesfilterwidget.h \
|
||||||
$$PWD/findandreplacewidget.h \
|
$$PWD/findandreplacewidget.h \
|
||||||
$$PWD/floatingwidget.h \
|
$$PWD/floatingwidget.h \
|
||||||
|
$$PWD/framelessmainwindow/framelessmainwindow.h \
|
||||||
|
$$PWD/framelessmainwindow/framelessmainwindowimpl.h \
|
||||||
|
$$PWD/framelessmainwindow/framelessmainwindowwin.h \
|
||||||
$$PWD/fullscreentoggleaction.h \
|
$$PWD/fullscreentoggleaction.h \
|
||||||
$$PWD/historypanel.h \
|
$$PWD/historypanel.h \
|
||||||
$$PWD/itemproxystyle.h \
|
$$PWD/itemproxystyle.h \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user