mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-07 02:35:33 +08:00
refs #347, CMainWindow for frameless main windows
This commit is contained in:
committed by
Roland Winklmeier
parent
facbefeeea
commit
42a4e0b48b
116
src/blackgui/enableforframelesswindow.cpp
Normal file
116
src/blackgui/enableforframelesswindow.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/* Copyright (C) 2014
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "enableforframelesswindow.h"
|
||||
#include "blackmisc/icons.h"
|
||||
#include <QSizeGrip>
|
||||
#include <QStatusBar>
|
||||
#include <QPushButton>
|
||||
|
||||
using namespace BlackMisc;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
|
||||
CEnableForFramelessWindow::CEnableForFramelessWindow(CEnableForFramelessWindow::WindowMode mode, bool isMainApplicationWindow, QWidget *correspondingWidget) :
|
||||
m_windowMode(mode), m_mainApplicationWindow(isMainApplicationWindow), m_widget(correspondingWidget)
|
||||
{
|
||||
Q_ASSERT(correspondingWidget);
|
||||
this->setWindowAttributes(mode);
|
||||
}
|
||||
|
||||
void CEnableForFramelessWindow::setMode(CEnableForFramelessWindow::WindowMode mode)
|
||||
{
|
||||
if (mode == this->m_windowMode) { return; }
|
||||
this->m_widget->setWindowFlags(modeToWindowFlags(mode));
|
||||
this->setWindowAttributes(mode);
|
||||
this->m_widget->show();
|
||||
this->m_windowMode = mode;
|
||||
}
|
||||
|
||||
void CEnableForFramelessWindow::setFrameless(bool frameless)
|
||||
{
|
||||
setMode(frameless ? WindowFrameless : WindowNormal);
|
||||
}
|
||||
|
||||
void CEnableForFramelessWindow::setWindowAttributes(CEnableForFramelessWindow::WindowMode mode)
|
||||
{
|
||||
bool frameless = (mode == WindowFrameless);
|
||||
// http://stackoverflow.com/questions/18316710/frameless-and-transparent-window-qt5
|
||||
this->m_widget->setAttribute(Qt::WA_NoSystemBackground, frameless);
|
||||
this->m_widget->setAttribute(Qt::WA_TranslucentBackground, frameless);
|
||||
this->m_widget->setProperty("frameless", frameless);
|
||||
}
|
||||
|
||||
bool CEnableForFramelessWindow::handleMouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_ASSERT(this->m_widget);
|
||||
if (this->m_windowMode == WindowFrameless && event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
this->m_widget->move(event->globalPos() - this->m_framelessDragPosition);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEnableForFramelessWindow::handleMousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_ASSERT(this->m_widget);
|
||||
if (this->m_windowMode == WindowFrameless && event->button() == Qt::LeftButton)
|
||||
{
|
||||
this->m_framelessDragPosition = event->globalPos() - this->m_widget->frameGeometry().topLeft();
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CEnableForFramelessWindow::addFramelessSizeGrip(QStatusBar *statusBar)
|
||||
{
|
||||
if (!statusBar) { return; }
|
||||
QSizeGrip *grip = new QSizeGrip(this->m_widget);
|
||||
grip->setObjectName("sg_FramelessSizeGrip");
|
||||
statusBar->addPermanentWidget(grip);
|
||||
}
|
||||
|
||||
QHBoxLayout *CEnableForFramelessWindow::addFramelessCloseButton(QMenuBar *menuBar)
|
||||
{
|
||||
Q_ASSERT(isFrameless());
|
||||
Q_ASSERT(menuBar);
|
||||
Q_ASSERT(this->m_widget);
|
||||
|
||||
if (!m_framelessCloseButton)
|
||||
{
|
||||
m_framelessCloseButton = new QPushButton(this->m_widget);
|
||||
m_framelessCloseButton->setObjectName("pb_FramelessCloseButton");
|
||||
m_framelessCloseButton->setIcon(CIcons::close16());
|
||||
QObject::connect(m_framelessCloseButton, &QPushButton::clicked, this->m_widget, &QWidget::close);
|
||||
}
|
||||
|
||||
QHBoxLayout *menuBarLayout = new QHBoxLayout;
|
||||
menuBarLayout->setObjectName("hl_MenuBar");
|
||||
menuBarLayout->addWidget(menuBar, 0, Qt::AlignTop | Qt::AlignLeft);
|
||||
menuBarLayout->addWidget(m_framelessCloseButton, 0, Qt::AlignTop | Qt::AlignRight);
|
||||
return menuBarLayout;
|
||||
}
|
||||
|
||||
Qt::WindowFlags CEnableForFramelessWindow::modeToWindowFlags(CEnableForFramelessWindow::WindowMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case WindowFrameless:
|
||||
return (Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||||
case WindowNormal:
|
||||
default:
|
||||
return (Qt::Tool | Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
85
src/blackgui/enableforframelesswindow.h
Normal file
85
src/blackgui/enableforframelesswindow.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 2014
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKGUI_ENABLEFORFRAMLESSWINDOW_H
|
||||
#define BLACKGUI_ENABLEFORFRAMLESSWINDOW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QStatusBar>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMenuBar>
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
|
||||
//! Main window which can be frameless
|
||||
//! \details QMainWindows cannot be promoted. Hence a derived class does not work properly here.
|
||||
//! Furthermore frameless functionality is also required for CDockWidgets as well.
|
||||
class CEnableForFramelessWindow
|
||||
{
|
||||
public:
|
||||
//! Window modes
|
||||
enum WindowMode
|
||||
{
|
||||
WindowFrameless,
|
||||
WindowNormal
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
CEnableForFramelessWindow(WindowMode mode, bool isMainApplicationWindow, QWidget *correspondingWidget);
|
||||
|
||||
//! Window mode
|
||||
void setMode(WindowMode mode);
|
||||
|
||||
//! Framless
|
||||
void setFrameless(bool frameless);
|
||||
|
||||
//! Frameless?
|
||||
bool isFrameless() const { return this->m_windowMode == WindowFrameless; }
|
||||
|
||||
//! The main application
|
||||
bool isMainApplicationWindow() const { return m_mainApplicationWindow; }
|
||||
|
||||
//! Corresponding QMainWindow
|
||||
QWidget *getWidget() const { return m_widget; }
|
||||
|
||||
protected:
|
||||
//! Resize grip handle
|
||||
void addFramelessSizeGrip(QStatusBar *statusBar);
|
||||
|
||||
//! Attributes
|
||||
void setWindowAttributes(WindowMode mode);
|
||||
|
||||
//! Close button for frameless windows
|
||||
QHBoxLayout *addFramelessCloseButton(QMenuBar *menuBar);
|
||||
|
||||
//! Translate mode
|
||||
static Qt::WindowFlags modeToWindowFlags(WindowMode mode);
|
||||
|
||||
QPoint m_framelessDragPosition; //!< position, if moving is handled with frameless window */
|
||||
QPushButton *m_framelessCloseButton = nullptr; //!< close button
|
||||
WindowMode m_windowMode = WindowNormal; //!< Window mode, \sa WindowMode
|
||||
bool m_mainApplicationWindow = false; //!< is the main application window (only 1)
|
||||
QWidget *m_widget = nullptr; //!< corresponding main window or dock widget
|
||||
|
||||
//! Mouse press, required for frameless window
|
||||
bool handleMousePressEvent(QMouseEvent *event);
|
||||
|
||||
//! Mouse moving, required for frameless window
|
||||
bool handleMouseMoveEvent(QMouseEvent *event);
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
@@ -14,25 +14,23 @@
|
||||
namespace BlackGui
|
||||
{
|
||||
|
||||
QMainWindow *CGuiUtility::mainWindow()
|
||||
CEnableForFramelessWindow *CGuiUtility::mainApplicationWindow()
|
||||
{
|
||||
QWidgetList tlw = topLevelApplicationWidgetsWithName();
|
||||
foreach(QWidget * w, tlw)
|
||||
{
|
||||
QMainWindow *mw = qobject_cast<QMainWindow *>(w);
|
||||
CEnableForFramelessWindow *mw = dynamic_cast<CEnableForFramelessWindow *>(w);
|
||||
if (!mw) { continue; }
|
||||
QString n = mw->objectName().toLower();
|
||||
if (n.contains("main") && n.contains("window")) return mw;
|
||||
if (mw->isMainApplicationWindow()) return mw;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CGuiUtility::isMainWindowFrameless()
|
||||
{
|
||||
QMainWindow *mw = mainWindow();
|
||||
CEnableForFramelessWindow *mw = mainApplicationWindow();
|
||||
Q_ASSERT(mw); // there should be a main window
|
||||
if (!mw) return false;
|
||||
return (mw->windowFlags() & Qt::FramelessWindowHint);
|
||||
return (mw && mw->isFrameless());
|
||||
}
|
||||
|
||||
QWidgetList CGuiUtility::topLevelApplicationWidgetsWithName()
|
||||
@@ -41,7 +39,7 @@ namespace BlackGui
|
||||
QWidgetList rl;
|
||||
foreach(QWidget * w, tlw)
|
||||
{
|
||||
if (w->objectName().isEmpty()) continue;
|
||||
if (w->objectName().isEmpty()) { continue; }
|
||||
rl.append(w);
|
||||
}
|
||||
return rl;
|
||||
@@ -49,8 +47,8 @@ namespace BlackGui
|
||||
|
||||
QPoint CGuiUtility::mainWindowPosition()
|
||||
{
|
||||
QMainWindow *mw = mainWindow();
|
||||
return (mw) ? mw->pos() : QPoint();
|
||||
CEnableForFramelessWindow *mw = mainApplicationWindow();
|
||||
return (mw) ? mw->getWidget()->pos() : QPoint();
|
||||
}
|
||||
|
||||
QPoint CGuiUtility::introWindowPosition()
|
||||
@@ -59,7 +57,7 @@ namespace BlackGui
|
||||
foreach(QWidget * w, tlw)
|
||||
{
|
||||
QString n = w->objectName().toLower();
|
||||
if (n.contains("intro")) return w->pos();
|
||||
if (n.contains("intro")) { return w->pos(); }
|
||||
}
|
||||
return QPoint(0, 0);
|
||||
}
|
||||
@@ -73,7 +71,7 @@ namespace BlackGui
|
||||
QString CGuiUtility::replaceTabCountValue(const QString &oldName, int count)
|
||||
{
|
||||
const QString v = QString("(").append(QString::number(count)).append(")");
|
||||
if (oldName.isEmpty()) {return v; }
|
||||
if (oldName.isEmpty()) { return v; }
|
||||
int index = oldName.lastIndexOf('(');
|
||||
if (index == 0) { return v; }
|
||||
if (index < 0) { return QString(oldName).append(" ").append(v); }
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define BLACKGUI_GUIUTILITY_H
|
||||
|
||||
#include <QWidgetList>
|
||||
#include <QMainWindow>
|
||||
#include "enableforframelesswindow.h"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
@@ -24,7 +24,7 @@ namespace BlackGui
|
||||
public:
|
||||
|
||||
//! Main application window
|
||||
static QMainWindow *mainWindow();
|
||||
static CEnableForFramelessWindow *mainApplicationWindow();
|
||||
|
||||
//! Is main window frameless?
|
||||
static bool isMainWindowFrameless();
|
||||
|
||||
@@ -25,7 +25,8 @@ using namespace BlackMisc;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
CInfoArea::CInfoArea(QWidget *parent) : QMainWindow(parent)
|
||||
CInfoArea::CInfoArea(QWidget *parent) :
|
||||
QMainWindow(parent), CEnableForFramelessWindow(CEnableForFramelessWindow::WindowNormal, false, this)
|
||||
{
|
||||
this->ps_setInfoAreaFloating(this->m_infoAreaFloating);
|
||||
this->setWindowIcon(CIcons::swift24());
|
||||
@@ -39,7 +40,7 @@ namespace BlackGui
|
||||
// after(!) GUI is setup
|
||||
if (this->m_dockWidgetInfoAreas.isEmpty())
|
||||
{
|
||||
this->m_dockWidgetInfoAreas = this->initOwnDockWidgetInfoAreas();
|
||||
this->m_dockWidgetInfoAreas = this->findOwnDockWidgetInfoAreas();
|
||||
Q_ASSERT(!this->m_dockWidgetInfoAreas.isEmpty());
|
||||
}
|
||||
|
||||
@@ -401,13 +402,19 @@ namespace BlackGui
|
||||
// this completely initializes the tab bar and all docked widgets
|
||||
if (init)
|
||||
{
|
||||
// float
|
||||
QPoint offset(i * 25, i * 20);
|
||||
after->setVisible(false);
|
||||
after->setFloating(true);
|
||||
after->setOffsetWhenFloating(offset);
|
||||
after->setPreferredSizeWhenFloating(this->getPreferredSizeWhenFloating(i));
|
||||
QSize floatingSize = this->getPreferredSizeWhenFloating(i);
|
||||
after->setPreferredSizeWhenFloating(floatingSize);
|
||||
|
||||
// dock again
|
||||
after->setFloating(false);
|
||||
after->setVisible(true);
|
||||
|
||||
// reset floating flag
|
||||
after->resetWasAlreadyFLoating();
|
||||
}
|
||||
else
|
||||
@@ -497,7 +504,7 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
QList<CDockWidgetInfoArea *> CInfoArea::initOwnDockWidgetInfoAreas()
|
||||
QList<CDockWidgetInfoArea *> CInfoArea::findOwnDockWidgetInfoAreas() const
|
||||
{
|
||||
QList<CDockWidgetInfoArea *> infoAreas = this->findChildren<CDockWidgetInfoArea *>();
|
||||
if (infoAreas.isEmpty()) { return infoAreas; }
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define BLACKGUI_INFOAREA_H
|
||||
|
||||
#include "dockwidgetinfoarea.h"
|
||||
#include "enableforframelesswindow.h"
|
||||
#include <QMainWindow>
|
||||
#include <QTabBar>
|
||||
#include <QPixmap>
|
||||
@@ -22,7 +23,7 @@ namespace BlackGui
|
||||
{
|
||||
//! Info area, hosting dockable widgets
|
||||
//! \sa CDockWidgetInfoArea
|
||||
class CInfoArea : public QMainWindow
|
||||
class CInfoArea : public QMainWindow, CEnableForFramelessWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -182,11 +183,11 @@ namespace BlackGui
|
||||
void setMarginsWhenDocked(int left, int top, int right, int bottom);
|
||||
|
||||
//! Nested info areas
|
||||
QList<CInfoArea *> getChildInfoAreas() { return this->findChildren<CInfoArea *>(); }
|
||||
QList<CInfoArea *> getChildInfoAreas() const { return this->findChildren<CInfoArea *>(); }
|
||||
|
||||
//! Direct dock widget areas, not the nested dock widget areas
|
||||
//! \remarks result stored in m_dockableWidgets
|
||||
QList<CDockWidgetInfoArea *> initOwnDockWidgetInfoAreas();
|
||||
QList<CDockWidgetInfoArea *> findOwnDockWidgetInfoAreas() const;
|
||||
|
||||
private slots:
|
||||
//! Tab bar has been double clicked
|
||||
|
||||
@@ -11,8 +11,8 @@ Used dynamic properties
|
||||
mainframeless (infobar.qss)
|
||||
**/
|
||||
|
||||
/** putting background here works for framed, but not for frameless window **/
|
||||
#MainWindow {
|
||||
/** Main window **/
|
||||
QMainWindow {
|
||||
background-image: url(:/textures/icons/textures/texture-outer.jpg);
|
||||
background-color: darkslategray;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user