mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-14 08:45:36 +08:00
refs #325, as preparation to reduce loading I need to find out when an info area is visible.
Existing functions visible() / isHidden() are not suitable, as those represent "technical visibility". We need a logical visibility telling us if the user can see / has selected the corresponing dockable widget. * New base class info area (where dockable widgets are placed) * Adjusted derived component (currently 1) * Cleaned up old code in floatAllWidgets
This commit is contained in:
@@ -18,39 +18,17 @@
|
||||
#include <QCloseEvent>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackGui;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Components
|
||||
{
|
||||
CMainInfoAreaComponent::CMainInfoAreaComponent(QWidget *parent) :
|
||||
QMainWindow(parent), ui(new Ui::CMainInfoAreaComponent)
|
||||
CInfoArea(parent), ui(new Ui::CMainInfoAreaComponent)
|
||||
{
|
||||
this->ps_setInfoAreaFloating(this->m_infoAreaFloating);
|
||||
ui->setupUi(this);
|
||||
this->setWindowIcon(CIcons::swift24());
|
||||
|
||||
// after setup, GUI established
|
||||
if (this->m_dockableWidgets.isEmpty())
|
||||
{
|
||||
this->m_dockableWidgets = this->findChildren<CDockWidgetInfoArea *>();
|
||||
Q_ASSERT(!this->m_dockableWidgets.isEmpty());
|
||||
}
|
||||
|
||||
this->ps_setDockArea(Qt::TopDockWidgetArea);
|
||||
this->setMarginsWhenFloating(5, 5, 5, 5); // left, top, right bottom
|
||||
this->setMarginsWhenDocked(1, 1, 1, 1); // top has no effect
|
||||
this->connectAllWidgets();
|
||||
this->setFeaturesForDockableWidgets(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable);
|
||||
this->tabifyAllWidgets();
|
||||
|
||||
// context menu
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &CMainInfoAreaComponent::customContextMenuRequested, this, &CMainInfoAreaComponent::ps_showContextMenu);
|
||||
connect(&CStyleSheetUtility::instance(), &CStyleSheetUtility::styleSheetsChanged, this, &CMainInfoAreaComponent::ps_onStyleSheetChanged);
|
||||
|
||||
// initial style sheet setting
|
||||
this->ps_onStyleSheetChanged();
|
||||
initInfoArea();
|
||||
}
|
||||
|
||||
CMainInfoAreaComponent::~CMainInfoAreaComponent()
|
||||
@@ -58,87 +36,6 @@ namespace BlackGui
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::addToContextMenu(QMenu *menu) const
|
||||
{
|
||||
if (!menu) return;
|
||||
menu->addAction(CIcons::dockTop16(), "Dock all", this, SLOT(dockAllWidgets()));
|
||||
menu->addAction(CIcons::floatAll16(), "Float all", this, SLOT(floatAllWidgets()));
|
||||
menu->addAction(CIcons::floatOne16(), "Dock / float info area", this, SLOT(toggleFloating()));
|
||||
|
||||
bool c = false;
|
||||
if (!this->m_dockableWidgets.isEmpty())
|
||||
{
|
||||
menu->addSeparator();
|
||||
QMenu *subMenuToggleFloat = new QMenu("Toggle Float/Dock", menu);
|
||||
QMenu *subMenuDisplay = new QMenu("Display", menu);
|
||||
|
||||
QSignalMapper *signalMapperToggleFloating = new QSignalMapper(menu);
|
||||
QSignalMapper *signalMapperDisplay = new QSignalMapper(menu);
|
||||
|
||||
for (int i = 0; i < this->m_dockableWidgets.size(); i++)
|
||||
{
|
||||
const CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(i);
|
||||
const QPixmap pm = infoAreaToPixmap(static_cast<InfoArea>(i));
|
||||
const QString t = dw->windowTitleBackup();
|
||||
QAction *checkableMenuAction = new QAction(menu);
|
||||
checkableMenuAction->setObjectName(QString(t).append("ToggleFloatingAction"));
|
||||
checkableMenuAction->setIconText(t);
|
||||
checkableMenuAction->setIcon(pm);
|
||||
checkableMenuAction->setData(QVariant(i));
|
||||
checkableMenuAction->setCheckable(true);
|
||||
checkableMenuAction->setChecked(!dw->isFloating());
|
||||
subMenuToggleFloat->addAction(checkableMenuAction);
|
||||
c = connect(checkableMenuAction, SIGNAL(toggled(bool)), signalMapperToggleFloating, SLOT(map()));
|
||||
Q_ASSERT(c);
|
||||
signalMapperToggleFloating->setMapping(checkableMenuAction, i);
|
||||
|
||||
QAction *displayMenuAction = new QAction(menu);
|
||||
displayMenuAction->setObjectName(QString(t).append("DisplayAction"));
|
||||
displayMenuAction->setIconText(t);
|
||||
displayMenuAction->setIcon(pm);
|
||||
displayMenuAction->setData(QVariant(i));
|
||||
displayMenuAction->setCheckable(false);
|
||||
|
||||
subMenuDisplay->addAction(displayMenuAction);
|
||||
c = connect(displayMenuAction, SIGNAL(triggered(bool)), signalMapperDisplay, SLOT(map()));
|
||||
Q_ASSERT(c);
|
||||
signalMapperDisplay->setMapping(displayMenuAction, i); // action to index
|
||||
}
|
||||
c = connect(signalMapperToggleFloating, SIGNAL(mapped(int)), this, SLOT(toggleFloating(int)));
|
||||
Q_ASSERT(c);
|
||||
|
||||
c = connect(signalMapperDisplay, SIGNAL(mapped(int)), this, SLOT(selectArea(int)));
|
||||
Q_ASSERT(c);
|
||||
|
||||
menu->addMenu(subMenuDisplay);
|
||||
menu->addMenu(subMenuToggleFloat);
|
||||
|
||||
// where and how to display tab
|
||||
menu->addSeparator();
|
||||
QAction *showMenuText = new QAction(menu);
|
||||
showMenuText->setObjectName("ShowDockedWidgetTextAction");
|
||||
showMenuText->setIconText("Show tab text");
|
||||
showMenuText->setIcon(CIcons::headingOne16());
|
||||
showMenuText->setCheckable(true);
|
||||
showMenuText->setChecked(this->m_showTabTexts);
|
||||
menu->addAction(showMenuText);
|
||||
connect(showMenuText, &QAction::toggled, this, &CMainInfoAreaComponent::ps_showTabTexts);
|
||||
|
||||
// auto adjust floating widgets
|
||||
QAction *showTabbar = new QAction(menu);
|
||||
showTabbar->setObjectName("ShowTabBar");
|
||||
showTabbar->setIconText("Show tab bar");
|
||||
showTabbar->setIcon(CIcons::dockBottom16());
|
||||
showTabbar->setCheckable(true);
|
||||
showTabbar->setChecked(this->m_showTabBar);
|
||||
menu->addAction(showTabbar);
|
||||
connect(showTabbar, &QAction::toggled, this, &CMainInfoAreaComponent::ps_showTabBar);
|
||||
|
||||
// tab bar position
|
||||
menu->addAction(CIcons::dockBottom16(), "Toogle tabbar position", this, SLOT(ps_toggleTabBarPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
CAtcStationComponent *CMainInfoAreaComponent::getAtcStationComponent()
|
||||
{
|
||||
return this->ui->comp_AtcStations;
|
||||
@@ -179,230 +76,9 @@ namespace BlackGui
|
||||
return this->ui->comp_TextMessages;
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::dockAllWidgets()
|
||||
{
|
||||
this->tabifyAllWidgets();
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::adjustSizeForAllDockWidgets()
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
dw->adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::floatAllWidgets()
|
||||
{
|
||||
// I fake the double click here, which queues the events in the queue
|
||||
// and hence fires all depending signals in order
|
||||
// if (!this->m_tabBar) return;
|
||||
// for (int i = 0; i < this->m_tabBar->count(); i++)
|
||||
// {
|
||||
// // emit this->m_tabBar->tabBarDoubleClicked(i);
|
||||
// this->toggleFloating(i);
|
||||
// }
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
if (dw->isFloating()) continue;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::toggleFloating()
|
||||
{
|
||||
this->ps_setInfoAreaFloating(!this->m_infoAreaFloating);
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::toggleFloating(CMainInfoAreaComponent::InfoArea infoArea)
|
||||
{
|
||||
CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(static_cast<int>(infoArea));
|
||||
Q_ASSERT(dw);
|
||||
if (!dw) return;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::toggleFloating(int index)
|
||||
{
|
||||
if (index < 0 || index >= this->m_dockableWidgets.size()) return;
|
||||
CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(index);
|
||||
Q_ASSERT(dw);
|
||||
if (!dw) return;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::selectArea(CMainInfoAreaComponent::InfoArea infoArea)
|
||||
{
|
||||
CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(static_cast<int>(infoArea));
|
||||
Q_ASSERT(dw);
|
||||
if (!dw) return;
|
||||
Q_ASSERT(this->m_tabBar);
|
||||
if (m_tabBar->count() < 1) return;
|
||||
|
||||
if (dw->isFloating())
|
||||
{
|
||||
dw->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = this->widgetToTabBarIndex(dw);
|
||||
Q_ASSERT(index >= 0);
|
||||
if (index >= 0 && index < m_tabBar->count())
|
||||
{
|
||||
m_tabBar->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::selectArea(int index)
|
||||
{
|
||||
if (index < 0 || index >= this->m_dockableWidgets.count()) return;
|
||||
this->selectArea(static_cast<InfoArea>(index));
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::selectSettingsTab(int index)
|
||||
{
|
||||
this->selectArea(InfoAreaSettings);
|
||||
this->ui->comp_Settings->setSettingsTab(static_cast<CSettingsComponent::SettingTab>(index));
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_setDockArea(Qt::DockWidgetArea area)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
Qt::DockWidgetAreas newAreas = static_cast<Qt::DockWidgetAreas>(area);
|
||||
Qt::DockWidgetAreas oldAreas = dw->allowedAreas();
|
||||
if (oldAreas == newAreas) continue;
|
||||
dw->setAllowedAreas(newAreas);
|
||||
this->addDockWidget(area, dw);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_setInfoAreaFloating(bool floating)
|
||||
{
|
||||
// float whole info area
|
||||
this->m_infoAreaFloating = floating;
|
||||
if (this->m_infoAreaFloating)
|
||||
{
|
||||
QPoint p = CGuiUtility::mainWindowPosition();
|
||||
this->setWindowFlags(Qt::Dialog);
|
||||
this->move(p.rx() + 20, p.ry() + 20);
|
||||
this->show(); // not working without show
|
||||
}
|
||||
else
|
||||
{
|
||||
// make this compliant as QWidget
|
||||
// https://qt-project.org/forums/viewthread/17519
|
||||
// http://www.qtcentre.org/threads/12569-QMainWindow-as-a-child-of-QMainWindow
|
||||
|
||||
// this->setParent(this->m_originalParent, this->windowFlags() & ~Qt::Window);
|
||||
this->setWindowFlags(this->windowFlags() & ~Qt::Window);
|
||||
this->setVisible(true); // after redocking this is required
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::tabifyAllWidgets()
|
||||
{
|
||||
// this->setDockArea(Qt::LeftDockWidgetArea);
|
||||
this->setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::East);
|
||||
bool init = this->m_tabBar ? false : true;
|
||||
|
||||
if (!this->m_dockableWidgets.isEmpty())
|
||||
{
|
||||
for (int i = 0; i < this->m_dockableWidgets.size(); i++)
|
||||
{
|
||||
CDockWidgetInfoArea *first = i > 0 ? this->m_dockableWidgets.at(i - 1) : nullptr;
|
||||
CDockWidgetInfoArea *after = this->m_dockableWidgets.at(i);
|
||||
Q_ASSERT(after);
|
||||
|
||||
// trick, init widget as floating
|
||||
// this completely initializes the tab bar and all docked widgets
|
||||
if (init)
|
||||
{
|
||||
QPoint offset(i * 25, i * 20);
|
||||
after->setVisible(false);
|
||||
after->setFloating(true);
|
||||
after->setOffsetWhenFloating(offset);
|
||||
after->setPreferredSizeWhenFloating(CMainInfoAreaComponent::getPreferredSizeWhenFloating(static_cast<InfoArea>(i)));
|
||||
after->setFloating(false);
|
||||
after->setVisible(true);
|
||||
after->resetWasAlreadyFLoating();
|
||||
}
|
||||
else
|
||||
{
|
||||
after->setFloating(false);
|
||||
}
|
||||
if (!first) { continue; }
|
||||
this->tabifyDockWidget(first, after);
|
||||
}
|
||||
}
|
||||
|
||||
// as now tabified, now set tab
|
||||
if (!this->m_tabBar)
|
||||
{
|
||||
this->m_tabBar = this->findChild<QTabBar *>();
|
||||
Q_ASSERT(m_tabBar);
|
||||
QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameDockWidgetTab());
|
||||
this->m_tabBar->setStyleSheet(qss);
|
||||
this->m_tabBar->setObjectName("comp_MainInfoAreaDockWidgetTab");
|
||||
this->m_tabBar->setMovable(false);
|
||||
this->m_tabBar->setElideMode(Qt::ElideNone);
|
||||
this->setDocumentMode(true); // did not notice any effect
|
||||
this->setTabPixmaps();
|
||||
|
||||
// East / West does not work (shown, but area itself empty)
|
||||
// South does not have any effect
|
||||
this->m_tabBar->setShape(QTabBar::TriangularSouth);
|
||||
connect(this->m_tabBar, &QTabBar::tabBarDoubleClicked, this, &CMainInfoAreaComponent::ps_tabBarDoubleClicked);
|
||||
}
|
||||
|
||||
if (this->countDockedWidgets() > 0)
|
||||
{
|
||||
this->m_tabBar->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::unTabifyAllWidgets()
|
||||
{
|
||||
if (this->m_dockableWidgets.size() < 2) return;
|
||||
CDockWidgetInfoArea *first = this->m_dockableWidgets.first();
|
||||
for (int i = 1; i < this->m_dockableWidgets.size(); i++)
|
||||
{
|
||||
CDockWidgetInfoArea *after = this->m_dockableWidgets.at(i);
|
||||
Q_ASSERT(after);
|
||||
this->splitDockWidget(first, after, Qt::Horizontal);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::connectAllWidgets()
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
connect(dw, &CDockWidgetInfoArea::widgetTopLevelChanged, this, &CMainInfoAreaComponent::ps_onWidgetTopLevelChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::setMarginsWhenFloating(int left, int top, int right, int bottom)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
//! Margins when window is floating
|
||||
dw->setMarginsWhenFloating(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::setMarginsWhenDocked(int left, int top, int right, int bottom)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
//! Margins when window is docked
|
||||
dw->setMarginsWhenDocked(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
QSize CMainInfoAreaComponent::getPreferredSizeWhenFloating(InfoArea area)
|
||||
QSize CMainInfoAreaComponent::getPreferredSizeWhenFloating(int areaIndex) const
|
||||
{
|
||||
InfoArea area = static_cast<InfoArea>(areaIndex);
|
||||
switch (area)
|
||||
{
|
||||
case InfoAreaAircrafts:
|
||||
@@ -424,9 +100,16 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
const QPixmap &CMainInfoAreaComponent::infoAreaToPixmap(CMainInfoAreaComponent::InfoArea infoArea)
|
||||
void CMainInfoAreaComponent::selectSettingsTab(int index)
|
||||
{
|
||||
switch (infoArea)
|
||||
this->selectArea(InfoAreaSettings);
|
||||
this->ui->comp_Settings->setSettingsTab(static_cast<CSettingsComponent::SettingTab>(index));
|
||||
}
|
||||
|
||||
const QPixmap &CMainInfoAreaComponent::indexToPixmap(int areaIndex) const
|
||||
{
|
||||
InfoArea area = static_cast<InfoArea>(areaIndex);
|
||||
switch (area)
|
||||
{
|
||||
case InfoAreaUsers:
|
||||
return CIcons::appUsers16();
|
||||
@@ -452,140 +135,5 @@ namespace BlackGui
|
||||
return CIcons::empty();
|
||||
}
|
||||
}
|
||||
|
||||
int CMainInfoAreaComponent::countDockedWidgets() const
|
||||
{
|
||||
if (!this->m_tabBar) return 0;
|
||||
return this->m_tabBar->count();
|
||||
}
|
||||
|
||||
CDockWidgetInfoArea *CMainInfoAreaComponent::getDockableWidgetByTabIndex(int tabBarIndex) const
|
||||
{
|
||||
if (tabBarIndex >= this->m_dockableWidgets.count() || tabBarIndex < 0) return nullptr;
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
if (dw->isFloating()) continue; // not in tab bar
|
||||
if (tabBarIndex == 0) return dw;
|
||||
tabBarIndex--;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CMainInfoAreaComponent::widgetToTabBarIndex(const CDockWidgetInfoArea *dockWidget)
|
||||
{
|
||||
if (!dockWidget) return -1;
|
||||
if (dockWidget->isFloating()) return -1;
|
||||
int tabBarIndex = 0;
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
if (dw->isFloating()) continue; // not in tab bar
|
||||
if (dw == dockWidget) return tabBarIndex;
|
||||
tabBarIndex++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::setFeaturesForDockableWidgets(QDockWidget::DockWidgetFeatures features)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
dw->setFeatures(features);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::setTabPixmaps()
|
||||
{
|
||||
if (!this->m_tabBar) return;
|
||||
for (int i = 0; i < this->m_tabBar->count(); i++)
|
||||
{
|
||||
InfoArea area = static_cast<InfoArea>(i);
|
||||
const QPixmap p(infoAreaToPixmap(area));
|
||||
this->m_tabBar->setTabIcon(i, p);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_tabBarDoubleClicked(int tabBarIndex)
|
||||
{
|
||||
CDockWidgetInfoArea *dw = this->getDockableWidgetByTabIndex(tabBarIndex);
|
||||
if (!dw) return;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_onWidgetTopLevelChanged(CDockWidget *widget, bool topLevel)
|
||||
{
|
||||
Q_ASSERT(widget);
|
||||
Q_UNUSED(topLevel);
|
||||
if (!widget) return;
|
||||
|
||||
// fix pixmaps
|
||||
this->setTabPixmaps();
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_onStyleSheetChanged()
|
||||
{
|
||||
QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameMainInfoArea());
|
||||
this->setStyleSheet(qss);
|
||||
if (this->m_tabBar)
|
||||
{
|
||||
QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameDockWidgetTab());
|
||||
this->m_tabBar->setStyleSheet(qss);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_showContextMenu(const QPoint &pos)
|
||||
{
|
||||
QPoint globalPos = this->mapToGlobal(pos);
|
||||
QScopedPointer<QMenu> contextMenu(new QMenu(this));
|
||||
this->addToContextMenu(contextMenu.data());
|
||||
|
||||
QAction *selectedItem = contextMenu.data()->exec(globalPos);
|
||||
Q_UNUSED(selectedItem);
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_showTabTexts(bool show)
|
||||
{
|
||||
if (show == this->m_showTabTexts) return;
|
||||
this->m_showTabTexts = show;
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
dw->showTitleWhenDocked(show);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_showTabBar(bool show)
|
||||
{
|
||||
if (show == this->m_showTabBar) return;
|
||||
this->m_showTabBar = show;
|
||||
if (!this->m_tabBar) return;
|
||||
this->m_tabBar->setVisible(show); // not working, but setting right value will not harm anything
|
||||
this->m_tabBar->setMaximumHeight(show ? 10000 : 0); // does the trick
|
||||
this->adjustSizeForAllDockWidgets();
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_setTabBarPosition(QTabWidget::TabPosition position)
|
||||
{
|
||||
Q_ASSERT(position == QTabWidget::North || position == QTabWidget::South);
|
||||
this->setTabPosition(Qt::TopDockWidgetArea, position);
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::ps_toggleTabBarPosition()
|
||||
{
|
||||
QTabWidget::TabPosition p = (this->tabPosition(Qt::TopDockWidgetArea) == QTabWidget::North) ?
|
||||
QTabWidget::South : QTabWidget::North;
|
||||
this->ps_setTabBarPosition(p);
|
||||
}
|
||||
|
||||
void CMainInfoAreaComponent::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (this->isFloating())
|
||||
{
|
||||
this->toggleFloating();
|
||||
event->setAccepted(false); // refuse -> do not close
|
||||
}
|
||||
else
|
||||
{
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#ifndef BLACKGUI_MAININFOAREACOMPONENT_H
|
||||
#define BLACKGUI_MAININFOAREACOMPONENT_H
|
||||
|
||||
#include "../dockwidgetinfoarea.h"
|
||||
#include "../infoarea.h"
|
||||
#include "atcstationcomponent.h"
|
||||
#include "aircraftcomponent.h"
|
||||
#include "usercomponent.h"
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "flightplancomponent.h"
|
||||
#include "settingscomponent.h"
|
||||
#include "logcomponent.h"
|
||||
#include <QMainWindow>
|
||||
#include <QTabBar>
|
||||
#include <QPixmap>
|
||||
|
||||
@@ -33,7 +32,7 @@ namespace BlackGui
|
||||
{
|
||||
|
||||
//! Main info area
|
||||
class CMainInfoAreaComponent : public QMainWindow
|
||||
class CMainInfoAreaComponent : public BlackGui::CInfoArea
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -42,30 +41,25 @@ namespace BlackGui
|
||||
explicit CMainInfoAreaComponent(QWidget *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
~CMainInfoAreaComponent();
|
||||
virtual ~CMainInfoAreaComponent();
|
||||
|
||||
//! Info areas
|
||||
enum InfoArea
|
||||
{
|
||||
// index must match tab index!
|
||||
InfoAreaAircrafts = 0,
|
||||
InfoAreaAtc = 1,
|
||||
InfoAreaUsers = 2,
|
||||
InfoAreaAircrafts = 0,
|
||||
InfoAreaAtc = 1,
|
||||
InfoAreaUsers = 2,
|
||||
InfoAreaTextMessages = 3,
|
||||
InfoAreaSimulator = 4,
|
||||
InfoAreaFlightPlan = 5,
|
||||
InfoAreaWeather = 6,
|
||||
InfoAreaMappings = 7,
|
||||
InfoAreaLog = 8,
|
||||
InfoAreaSettings = 9
|
||||
InfoAreaSimulator = 4,
|
||||
InfoAreaFlightPlan = 5,
|
||||
InfoAreaWeather = 6,
|
||||
InfoAreaMappings = 7,
|
||||
InfoAreaLog = 8,
|
||||
InfoAreaSettings = 9,
|
||||
InfoAreaNone = -1
|
||||
};
|
||||
|
||||
//! Add items to context menu
|
||||
void addToContextMenu(QMenu *menu) const;
|
||||
|
||||
//! Is this area floating?
|
||||
bool isFloating() const { return this->m_infoAreaFloating; }
|
||||
|
||||
//! ATC stations
|
||||
CAtcStationComponent *getAtcStationComponent();
|
||||
|
||||
@@ -90,119 +84,29 @@ namespace BlackGui
|
||||
//! Text messages
|
||||
CTextMessageComponent *getTextMessageComponent();
|
||||
|
||||
//! Selected area of non floating areas
|
||||
InfoArea getSelectedInfoArea() const { return static_cast<InfoArea>(getSelectedInfoAreaIndex()); }
|
||||
|
||||
public slots:
|
||||
//! Dock all widgets
|
||||
void dockAllWidgets();
|
||||
|
||||
//! Adjust size for all dock widgets
|
||||
void adjustSizeForAllDockWidgets();
|
||||
|
||||
//! All widgets floating
|
||||
void floatAllWidgets();
|
||||
|
||||
//! Toggle dock / floating of the whole info area
|
||||
void toggleFloating();
|
||||
|
||||
//! Toggle floating of given area
|
||||
void toggleFloating(InfoArea infoArea);
|
||||
|
||||
//! Toggle floating of index
|
||||
void toggleFloating(int index);
|
||||
void toggleFloating(InfoArea infoArea) { CInfoArea::toggleFloating(static_cast<int>(infoArea)); }
|
||||
|
||||
//! Select area
|
||||
void selectArea(InfoArea infoArea);
|
||||
|
||||
//! Select area
|
||||
void selectArea(int index);
|
||||
void selectArea(InfoArea infoArea) { CInfoArea::selectArea(static_cast<int>(infoArea)); }
|
||||
|
||||
//! Select settings with given area
|
||||
void selectSettingsTab(int index);
|
||||
|
||||
protected:
|
||||
//! Override close event
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
//! \copydoc CInfoArea::getPreferredSizeWhenFloating
|
||||
virtual QSize getPreferredSizeWhenFloating(int areaIndex) const override;
|
||||
|
||||
//! \copydoc CInfoArea::indexToPixmap
|
||||
virtual const QPixmap &indexToPixmap(int areaIndex) const override;
|
||||
|
||||
private:
|
||||
Ui::CMainInfoAreaComponent *ui = nullptr;
|
||||
QList<CDockWidgetInfoArea *> m_dockableWidgets ;
|
||||
QTabBar *m_tabBar = nullptr;
|
||||
bool m_showTabTexts = true;
|
||||
bool m_infoAreaFloating = false; //!< whole info area floating
|
||||
bool m_showTabBar = true; //!< auto ajdust the floating widgets
|
||||
|
||||
//! Tabify the widgets
|
||||
void tabifyAllWidgets();
|
||||
|
||||
//! Untabify
|
||||
void unTabifyAllWidgets();
|
||||
|
||||
//! The tab bar of the docked widgets
|
||||
QTabBar *tabBarDockedWidgets() const;
|
||||
|
||||
//! Corresponding dockable widgets
|
||||
QList<CDockWidgetInfoArea *> dockableWidgets() const;
|
||||
|
||||
//! Corresponding dockable widget for given tab index
|
||||
CDockWidgetInfoArea *getDockableWidgetByTabIndex(int tabBarIndex) const;
|
||||
|
||||
//! Features of the dockable widgets
|
||||
void setFeaturesForDockableWidgets(QDockWidget::DockWidgetFeatures features);
|
||||
|
||||
//! Number of tabbed widgets
|
||||
int countDockedWidgets() const;
|
||||
|
||||
//! Widget to tab bar index
|
||||
int widgetToTabBarIndex(const CDockWidgetInfoArea *dockWidget);
|
||||
|
||||
//! Set the tab's icons
|
||||
void setTabPixmaps();
|
||||
|
||||
//! Connect all widgets
|
||||
void connectAllWidgets();
|
||||
|
||||
//! Margins for the floating widgets
|
||||
void setMarginsWhenFloating(int left, int top, int right, int bottom);
|
||||
|
||||
//! Margins for the dockable widgets
|
||||
void setMarginsWhenDocked(int left, int top, int right, int bottom);
|
||||
|
||||
//! Set window sizes when floating
|
||||
static QSize getPreferredSizeWhenFloating(InfoArea area);
|
||||
|
||||
//! Info area to icon
|
||||
static const QPixmap &infoAreaToPixmap(InfoArea infoArea);
|
||||
|
||||
private slots:
|
||||
//! Tab bar has been double clicked
|
||||
void ps_tabBarDoubleClicked(int tabBarIndex);
|
||||
|
||||
//! A widget has changed its top level
|
||||
void ps_onWidgetTopLevelChanged(CDockWidget *widget, bool topLevel);
|
||||
|
||||
//! Style sheet has been changed
|
||||
void ps_onStyleSheetChanged();
|
||||
|
||||
//! Context menu
|
||||
void ps_showContextMenu(const QPoint &pos);
|
||||
|
||||
//! Show the tab texts, or just the icons
|
||||
void ps_showTabTexts(bool show);
|
||||
|
||||
//! Show tab bar
|
||||
void ps_showTabBar(bool show);
|
||||
|
||||
//! Tab position for docked widgets tab
|
||||
//! \remarks North or South working, East / West not
|
||||
void ps_setTabBarPosition(QTabWidget::TabPosition position);
|
||||
|
||||
//! Toggle tab position North - South
|
||||
void ps_toggleTabBarPosition();
|
||||
|
||||
//! Set dock area used
|
||||
void ps_setDockArea(Qt::DockWidgetArea area);
|
||||
|
||||
//! Dock / floating of the whole info area
|
||||
void ps_setInfoAreaFloating(bool floating);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,29 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
void CDockWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
// KB: Should give me style sheet compliance, however I did not notice any difference
|
||||
// included for style sheet compliance
|
||||
// QStyleOption opt;
|
||||
// opt.init(this);
|
||||
// QPainter p(this);
|
||||
// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
QDockWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
void CDockWidget::hideEvent(QHideEvent *event)
|
||||
{
|
||||
qDebug() << "hide" << this->objectName() << "v:" << isVisible() << "h:" << isHidden();
|
||||
QDockWidget::hideEvent(event);
|
||||
}
|
||||
|
||||
void CDockWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
qDebug() << "show" << this->objectName() << "v:" << isVisible() << "h:" << isHidden();
|
||||
QDockWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void CDockWidget::addToContextMenu(QMenu *contextMenu) const
|
||||
{
|
||||
if (this->isFloating())
|
||||
@@ -99,15 +122,22 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
void CDockWidget::paintEvent(QPaintEvent *event)
|
||||
void CDockWidget::initalFloating()
|
||||
{
|
||||
// KB: Should give me style sheet compliance, however I did not notice any difference
|
||||
// included for style sheet compliance
|
||||
// QStyleOption opt;
|
||||
// opt.init(this);
|
||||
// QPainter p(this);
|
||||
// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
QDockWidget::paintEvent(event);
|
||||
// for the first time resize
|
||||
if (!this->m_preferredSizeWhenFloating.isNull())
|
||||
{
|
||||
this->resize(this->m_preferredSizeWhenFloating);
|
||||
}
|
||||
|
||||
// and move
|
||||
QPoint mainWindowPos = BlackGui::CGuiUtility::mainWindowPosition();
|
||||
if (!mainWindowPos.isNull())
|
||||
{
|
||||
int x = mainWindowPos.x() + this->m_offsetWhenFloating.x();
|
||||
int y = mainWindowPos.y() + this->m_offsetWhenFloating.y();
|
||||
this->move(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void CDockWidget::ps_onTopLevelChanged(bool topLevel)
|
||||
@@ -122,20 +152,7 @@ namespace BlackGui
|
||||
this->setContentsMargins(this->m_marginsWhenFloating);
|
||||
if (!this->m_wasAlreadyFloating)
|
||||
{
|
||||
// for the first time resize
|
||||
if (!this->m_preferredSizeWhenFloating.isNull())
|
||||
{
|
||||
this->resize(this->m_preferredSizeWhenFloating);
|
||||
}
|
||||
|
||||
// and move
|
||||
QPoint mainWindowPos = BlackGui::CGuiUtility::mainWindowPosition();
|
||||
if (!mainWindowPos.isNull())
|
||||
{
|
||||
int x = mainWindowPos.x() + this->m_offsetWhenFloating.x();
|
||||
int y = mainWindowPos.y() + this->m_offsetWhenFloating.y();
|
||||
this->move(x, y);
|
||||
}
|
||||
this->initalFloating();
|
||||
}
|
||||
this->m_wasAlreadyFloating = true;
|
||||
}
|
||||
@@ -182,7 +199,7 @@ namespace BlackGui
|
||||
Q_UNUSED(selectedItem);
|
||||
}
|
||||
|
||||
void CDockWidget::ps_onStyleSheetsChanged()
|
||||
void CDockWidget::onStyleSheetsChanged()
|
||||
{
|
||||
// void
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2014
|
||||
* Swift Project Community / Contributors
|
||||
* 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,
|
||||
@@ -21,22 +21,27 @@
|
||||
namespace BlackGui
|
||||
{
|
||||
|
||||
//! Our base class for dock widgets, containing some specialized functionality
|
||||
//! \brief Our base class for dockable widgets containing some specialized functionality on top of QWidget.
|
||||
//! \details We currently use dockable widgets either as "info area" or "info bar" dockable widget.
|
||||
//! Info area widgets reside in an info are and represent a larger piece of information (e.g. all ATC stations, all aircrafts in range).
|
||||
//! An info bar is meant to be a small info window displaying information about status, menu state etc.
|
||||
//!
|
||||
//! \sa CInfoArea
|
||||
//! \sa CDockWidgetInfoArea
|
||||
//! \sa CDockWidgetInfoBar
|
||||
class CDockWidget : public QDockWidget
|
||||
{
|
||||
// KB TODO: Make this an interface, IDockWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
explicit CDockWidget(QWidget *parent = nullptr);
|
||||
|
||||
//! Set original title bar
|
||||
void setOriginalTitleBar();
|
||||
|
||||
//! Set empty title bar
|
||||
//! Set empty title bar (empty widget as title bar)
|
||||
void setEmptyTitleBar();
|
||||
|
||||
//! Set null title bar
|
||||
//! Set null (nullptr) title bar
|
||||
void setNullTitleBar();
|
||||
|
||||
//! Margins when window is floating
|
||||
@@ -57,13 +62,16 @@ namespace BlackGui
|
||||
//! Window title when window is docked
|
||||
bool showTitleWhenDocked() const { return this->m_windowTitleWhenDocked; }
|
||||
|
||||
//! Selected when tabbed
|
||||
bool isSelected() const { return this->m_selected; }
|
||||
|
||||
//! Show the window title when docked
|
||||
void showTitleWhenDocked(bool show);
|
||||
|
||||
//! Reset first time floating
|
||||
//! Reset first time floating, marked as never floated before
|
||||
void resetWasAlreadyFLoating() { this->m_wasAlreadyFloating = false; }
|
||||
|
||||
//! Was widget already floating
|
||||
//! Was widget already floating?
|
||||
bool wasAlreadyFloating() const { return this->m_wasAlreadyFloating; }
|
||||
|
||||
//! Size when floating first time
|
||||
@@ -84,14 +92,28 @@ namespace BlackGui
|
||||
void widgetTopLevelChanged(CDockWidget *, bool topLevel);
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
explicit CDockWidget(QWidget *parent = nullptr);
|
||||
|
||||
//! Override close event
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
//! Paint event
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
//! Hide event
|
||||
void hideEvent(QHideEvent *event) override;
|
||||
|
||||
//! Show event
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
//! Contribute to menu
|
||||
virtual void addToContextMenu(QMenu *contextMenu) const;
|
||||
|
||||
//! Paint event
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
//! Widget is initialized by being a floating window for a shot period.
|
||||
//! \details Place where - when overidden - post initializations can take place.
|
||||
//! The GUI is already initialized, so all widget data are available.
|
||||
virtual void initalFloating();
|
||||
|
||||
protected slots:
|
||||
//! Style sheet has changed
|
||||
@@ -105,15 +127,17 @@ namespace BlackGui
|
||||
virtual void ps_showContextMenu(const QPoint &pos);
|
||||
|
||||
private:
|
||||
QWidget *m_emptyTitleBar = nullptr; //!< replacing default title bar
|
||||
QWidget *m_emptyTitleBar = nullptr; //!< replacing default title bar
|
||||
QWidget *m_titleBarOriginal = nullptr; //!< the original title bar
|
||||
QMargins m_marginsWhenFloating; //!< Offsets when window is floating
|
||||
QMargins m_marginsWhenDocked; //!< Offsets when window is floating
|
||||
QString m_windowTitleBackup; //!< original title, even if the widget title is deleted for layout purposes
|
||||
QMargins m_marginsWhenFloating; //!< Offsets when window is floating
|
||||
QMargins m_marginsWhenDocked; //!< Offsets when window is floating
|
||||
QString m_windowTitleBackup; //!< original title, even if the widget title is deleted for layout purposes
|
||||
QSize m_preferredSizeWhenFloating; //!< preferred size men floating 1st time
|
||||
QPoint m_offsetWhenFloating; //!< initial offset to main window when floating first time
|
||||
bool m_windowTitleWhenDocked = true;
|
||||
bool m_wasAlreadyFloating = false;
|
||||
QSize m_preferredSizeWhenFloating; //!< preferred size men floating 1st time
|
||||
QPoint m_offsetWhenFloating; //!< initial offset to main window when floating first time
|
||||
bool m_wasAlreadyFloating = false;
|
||||
bool m_selected = false; //!< selected when tabbed
|
||||
|
||||
|
||||
//! Empty widget with no size
|
||||
void initTitleBarWidgets();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "dockwidgetinfoarea.h"
|
||||
#include "infoarea.h"
|
||||
#include "components/maininfoareacomponent.h"
|
||||
#include "blackmisc/icons.h"
|
||||
|
||||
@@ -15,7 +16,49 @@ using namespace BlackGui::Components;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
CDockWidgetInfoArea::CDockWidgetInfoArea(QWidget *parent) : CDockWidget(parent) { }
|
||||
CDockWidgetInfoArea::CDockWidgetInfoArea(QWidget *parent) : CDockWidget(parent)
|
||||
{
|
||||
// void
|
||||
}
|
||||
|
||||
const CInfoArea *CDockWidgetInfoArea::getParentInfoArea() const
|
||||
{
|
||||
const CInfoArea *ia = dynamic_cast<const CInfoArea *>(this->parent());
|
||||
Q_ASSERT(ia);
|
||||
return ia;
|
||||
}
|
||||
|
||||
CInfoArea *CDockWidgetInfoArea::getParentInfoArea()
|
||||
{
|
||||
CInfoArea *ia = dynamic_cast<CInfoArea *>(this->parent());
|
||||
Q_ASSERT(ia);
|
||||
return ia;
|
||||
}
|
||||
|
||||
bool CDockWidgetInfoArea::isSelectedDockWidget() const
|
||||
{
|
||||
const CInfoArea *ia = getParentInfoArea();
|
||||
if (!ia) return false;
|
||||
return ia->isSelectedInfoArea(this);
|
||||
}
|
||||
|
||||
bool CDockWidgetInfoArea::isVisibleWidget() const
|
||||
{
|
||||
// if the widget is invisible we are done
|
||||
// but if it is visible, there is no guarantee it can be seen by the user
|
||||
if (!this->isVisible()) return false;
|
||||
|
||||
// further checks
|
||||
if (this->isFloating())
|
||||
{
|
||||
if (this->isMinimized()) return false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isSelectedDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
void CDockWidgetInfoArea::addToContextMenu(QMenu *contextMenu) const
|
||||
{
|
||||
@@ -30,4 +73,29 @@ namespace BlackGui
|
||||
contextMenu->addSeparator();
|
||||
mainWidget->addToContextMenu(contextMenu);
|
||||
}
|
||||
|
||||
void CDockWidgetInfoArea::initalFloating()
|
||||
{
|
||||
CDockWidget::initalFloating();
|
||||
QList<CDockWidgetInfoAreaComponent *> infoAreaDockWidgets = this->findEmbeddedDockWidgetInfoAreaComponents();
|
||||
foreach(CDockWidgetInfoAreaComponent * dwia, infoAreaDockWidgets)
|
||||
{
|
||||
dwia->setParentDockableWidget(this);
|
||||
}
|
||||
}
|
||||
|
||||
QList<CDockWidgetInfoAreaComponent *> CDockWidgetInfoArea::findEmbeddedDockWidgetInfoAreaComponents() const
|
||||
{
|
||||
QList<QWidget *> widgets = this->findChildren<QWidget *>();
|
||||
QList<CDockWidgetInfoAreaComponent *> widgetsWithDockWidgetInfoAreaComponent;
|
||||
foreach(QWidget * w, widgets)
|
||||
{
|
||||
CDockWidgetInfoAreaComponent *dwc = dynamic_cast<Components::CDockWidgetInfoAreaComponent *>(w);
|
||||
if (dwc)
|
||||
{
|
||||
widgetsWithDockWidgetInfoAreaComponent.append(dwc);
|
||||
}
|
||||
}
|
||||
return widgetsWithDockWidgetInfoAreaComponent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
//! Forward declarations
|
||||
class CInfoArea;
|
||||
namespace Components { class CDockWidgetInfoAreaComponent; }
|
||||
|
||||
//! Class for dock widgets serving as info bar
|
||||
//! Specialized class for dock widgets serving as info area
|
||||
//! \sa CDockWidgetInfoBar
|
||||
//! \sa CInfoArea
|
||||
class CDockWidgetInfoArea : public CDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -26,9 +31,28 @@ namespace BlackGui
|
||||
//! Constructor
|
||||
explicit CDockWidgetInfoArea(QWidget *parent = nullptr);
|
||||
|
||||
//! The parent info area
|
||||
const CInfoArea *getParentInfoArea() const;
|
||||
|
||||
//! The parent info area
|
||||
CInfoArea *getParentInfoArea();
|
||||
|
||||
//! Is this the selected widget, means it is not floating, and the one selected
|
||||
bool isSelectedDockWidget() const;
|
||||
|
||||
//! Visible widget
|
||||
bool isVisibleWidget() const;
|
||||
|
||||
protected:
|
||||
//! Contribute to menu
|
||||
virtual void addToContextMenu(QMenu *contextMenu) const override;
|
||||
|
||||
//! \copydoc CDockWidget::initalFloating
|
||||
virtual void initalFloating() override;
|
||||
|
||||
private:
|
||||
//! Find all embedded runtime components
|
||||
QList<Components::CDockWidgetInfoAreaComponent *> findEmbeddedDockWidgetInfoAreaComponents() const;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace BlackGui
|
||||
{
|
||||
|
||||
//! Class for dock widgets in the info area, containing some specialized functionality
|
||||
//! \sa CDockWidgetInfoArea
|
||||
//! \sa CInfoArea
|
||||
class CDockWidgetInfoBar : public CDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
477
src/blackgui/infoarea.cpp
Normal file
477
src/blackgui/infoarea.cpp
Normal file
@@ -0,0 +1,477 @@
|
||||
/* 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 "infoarea.h"
|
||||
#include "stylesheetutility.h"
|
||||
#include "guiutility.h"
|
||||
#include "blackmisc/icons.h"
|
||||
#include <QMenu>
|
||||
#include <QListIterator>
|
||||
#include <QSignalMapper>
|
||||
#include <QCloseEvent>
|
||||
|
||||
using namespace BlackMisc;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
CInfoArea::CInfoArea(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
this->ps_setInfoAreaFloating(this->m_infoAreaFloating);
|
||||
this->setWindowIcon(CIcons::swift24());
|
||||
}
|
||||
|
||||
void CInfoArea::initInfoArea()
|
||||
{
|
||||
// after(!) GUI established
|
||||
if (this->m_dockableWidgets.isEmpty())
|
||||
{
|
||||
this->m_dockableWidgets = this->findChildren<CDockWidgetInfoArea *>();
|
||||
Q_ASSERT(!this->m_dockableWidgets.isEmpty());
|
||||
}
|
||||
|
||||
this->ps_setDockArea(Qt::TopDockWidgetArea);
|
||||
this->setMarginsWhenFloating(5, 5, 5, 5); // left, top, right bottom
|
||||
this->setMarginsWhenDocked(1, 1, 1, 1); // top has no effect
|
||||
this->connectAllWidgets();
|
||||
this->setFeaturesForDockableWidgets(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable);
|
||||
this->tabifyAllWidgets();
|
||||
|
||||
// context menu
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &CInfoArea::customContextMenuRequested, this, &CInfoArea::ps_showContextMenu);
|
||||
connect(&CStyleSheetUtility::instance(), &CStyleSheetUtility::styleSheetsChanged, this, &CInfoArea::ps_onStyleSheetChanged);
|
||||
|
||||
// initial style sheet setting
|
||||
this->ps_onStyleSheetChanged();
|
||||
}
|
||||
|
||||
void CInfoArea::addToContextMenu(QMenu *menu) const
|
||||
{
|
||||
if (!menu) return;
|
||||
menu->addAction(CIcons::dockTop16(), "Dock all", this, SLOT(dockAllWidgets()));
|
||||
menu->addAction(CIcons::floatAll16(), "Float all", this, SLOT(floatAllWidgets()));
|
||||
menu->addAction(CIcons::floatOne16(), "Dock / float info area", this, SLOT(toggleFloating()));
|
||||
|
||||
bool c = false;
|
||||
if (!this->m_dockableWidgets.isEmpty())
|
||||
{
|
||||
menu->addSeparator();
|
||||
QMenu *subMenuToggleFloat = new QMenu("Toggle Float/Dock", menu);
|
||||
QMenu *subMenuDisplay = new QMenu("Display", menu);
|
||||
|
||||
QSignalMapper *signalMapperToggleFloating = new QSignalMapper(menu);
|
||||
QSignalMapper *signalMapperDisplay = new QSignalMapper(menu);
|
||||
|
||||
for (int i = 0; i < this->m_dockableWidgets.size(); i++)
|
||||
{
|
||||
const CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(i);
|
||||
const QPixmap pm = indexToPixmap(i);
|
||||
const QString t = dw->windowTitleBackup();
|
||||
QAction *checkableMenuAction = new QAction(menu);
|
||||
checkableMenuAction->setObjectName(QString(t).append("ToggleFloatingAction"));
|
||||
checkableMenuAction->setIconText(t);
|
||||
checkableMenuAction->setIcon(pm);
|
||||
checkableMenuAction->setData(QVariant(i));
|
||||
checkableMenuAction->setCheckable(true);
|
||||
checkableMenuAction->setChecked(!dw->isFloating());
|
||||
subMenuToggleFloat->addAction(checkableMenuAction);
|
||||
c = connect(checkableMenuAction, SIGNAL(toggled(bool)), signalMapperToggleFloating, SLOT(map()));
|
||||
Q_ASSERT(c);
|
||||
signalMapperToggleFloating->setMapping(checkableMenuAction, i);
|
||||
|
||||
QAction *displayMenuAction = new QAction(menu);
|
||||
displayMenuAction->setObjectName(QString(t).append("DisplayAction"));
|
||||
displayMenuAction->setIconText(t);
|
||||
displayMenuAction->setIcon(pm);
|
||||
displayMenuAction->setData(QVariant(i));
|
||||
displayMenuAction->setCheckable(false);
|
||||
|
||||
subMenuDisplay->addAction(displayMenuAction);
|
||||
c = connect(displayMenuAction, SIGNAL(triggered(bool)), signalMapperDisplay, SLOT(map()));
|
||||
Q_ASSERT(c);
|
||||
signalMapperDisplay->setMapping(displayMenuAction, i); // action to index
|
||||
}
|
||||
c = connect(signalMapperToggleFloating, SIGNAL(mapped(int)), this, SLOT(toggleFloating(int)));
|
||||
Q_ASSERT(c);
|
||||
|
||||
c = connect(signalMapperDisplay, SIGNAL(mapped(int)), this, SLOT(selectArea(int)));
|
||||
Q_ASSERT(c);
|
||||
|
||||
menu->addMenu(subMenuDisplay);
|
||||
menu->addMenu(subMenuToggleFloat);
|
||||
|
||||
// where and how to display tab
|
||||
menu->addSeparator();
|
||||
QAction *showMenuText = new QAction(menu);
|
||||
showMenuText->setObjectName("ShowDockedWidgetTextAction");
|
||||
showMenuText->setIconText("Show tab text");
|
||||
showMenuText->setIcon(CIcons::headingOne16());
|
||||
showMenuText->setCheckable(true);
|
||||
showMenuText->setChecked(this->m_showTabTexts);
|
||||
menu->addAction(showMenuText);
|
||||
connect(showMenuText, &QAction::toggled, this, &CInfoArea::ps_showTabTexts);
|
||||
|
||||
// auto adjust floating widgets
|
||||
QAction *showTabbar = new QAction(menu);
|
||||
showTabbar->setObjectName("ShowTabBar");
|
||||
showTabbar->setIconText("Show tab bar");
|
||||
showTabbar->setIcon(CIcons::dockBottom16());
|
||||
showTabbar->setCheckable(true);
|
||||
showTabbar->setChecked(this->m_showTabBar);
|
||||
menu->addAction(showTabbar);
|
||||
connect(showTabbar, &QAction::toggled, this, &CInfoArea::ps_showTabBar);
|
||||
|
||||
// tab bar position
|
||||
menu->addAction(CIcons::dockBottom16(), "Toogle tabbar position", this, SLOT(ps_toggleTabBarPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
int CInfoArea::getSelectedInfoAreaIndex() const
|
||||
{
|
||||
Q_ASSERT(this->m_tabBar);
|
||||
if (!this->m_tabBar || this->m_tabBar->count() < 1) return -1;
|
||||
return this->m_tabBar->currentIndex();
|
||||
}
|
||||
|
||||
bool CInfoArea::isSelectedInfoArea(const CDockWidgetInfoArea *infoArea) const
|
||||
{
|
||||
if (!infoArea) return false;
|
||||
if (infoArea->isFloating()) return false;
|
||||
int i = getSelectedInfoAreaIndex();
|
||||
if (i < 0 || i >= this->m_dockableWidgets.size()) return false;
|
||||
return this->m_dockableWidgets.at(i) == infoArea;
|
||||
}
|
||||
|
||||
void CInfoArea::dockAllWidgets()
|
||||
{
|
||||
this->tabifyAllWidgets();
|
||||
}
|
||||
|
||||
void CInfoArea::adjustSizeForAllDockWidgets()
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
dw->adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::floatAllWidgets()
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
if (dw->isFloating()) continue;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::toggleFloating()
|
||||
{
|
||||
this->ps_setInfoAreaFloating(!this->m_infoAreaFloating);
|
||||
}
|
||||
|
||||
void CInfoArea::toggleFloating(int areaIndex)
|
||||
{
|
||||
if (areaIndex < 0 || areaIndex >= this->m_dockableWidgets.size()) return;
|
||||
CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(areaIndex);
|
||||
Q_ASSERT(dw);
|
||||
if (!dw) return;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
|
||||
void CInfoArea::selectArea(int areaIndex)
|
||||
{
|
||||
CDockWidgetInfoArea *dw = this->m_dockableWidgets.at(areaIndex);
|
||||
Q_ASSERT(dw);
|
||||
if (!dw) return;
|
||||
Q_ASSERT(this->m_tabBar);
|
||||
if (m_tabBar->count() < 1) return;
|
||||
|
||||
if (dw->isFloating())
|
||||
{
|
||||
dw->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = this->widgetToTabBarIndex(dw);
|
||||
Q_ASSERT(index >= 0);
|
||||
if (index >= 0 && index < m_tabBar->count())
|
||||
{
|
||||
m_tabBar->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::ps_setDockArea(Qt::DockWidgetArea area)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
Qt::DockWidgetAreas newAreas = static_cast<Qt::DockWidgetAreas>(area);
|
||||
Qt::DockWidgetAreas oldAreas = dw->allowedAreas();
|
||||
if (oldAreas == newAreas) continue;
|
||||
dw->setAllowedAreas(newAreas);
|
||||
this->addDockWidget(area, dw);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::ps_setInfoAreaFloating(bool floating)
|
||||
{
|
||||
// float whole info area
|
||||
this->m_infoAreaFloating = floating;
|
||||
if (this->m_infoAreaFloating)
|
||||
{
|
||||
QPoint p = CGuiUtility::mainWindowPosition();
|
||||
this->setWindowFlags(Qt::Dialog);
|
||||
this->move(p.rx() + 20, p.ry() + 20);
|
||||
this->show(); // not working without show
|
||||
}
|
||||
else
|
||||
{
|
||||
// make this compliant as QWidget
|
||||
// https://qt-project.org/forums/viewthread/17519
|
||||
// http://www.qtcentre.org/threads/12569-QMainWindow-as-a-child-of-QMainWindow
|
||||
|
||||
// this->setParent(this->m_originalParent, this->windowFlags() & ~Qt::Window);
|
||||
this->setWindowFlags(this->windowFlags() & ~Qt::Window);
|
||||
this->setVisible(true); // after redocking this is required
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::tabifyAllWidgets()
|
||||
{
|
||||
// this->setDockArea(Qt::LeftDockWidgetArea);
|
||||
this->setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::East);
|
||||
bool init = this->m_tabBar ? false : true;
|
||||
|
||||
if (!this->m_dockableWidgets.isEmpty())
|
||||
{
|
||||
for (int i = 0; i < this->m_dockableWidgets.size(); i++)
|
||||
{
|
||||
CDockWidgetInfoArea *first = i > 0 ? this->m_dockableWidgets.at(i - 1) : nullptr;
|
||||
CDockWidgetInfoArea *after = this->m_dockableWidgets.at(i);
|
||||
Q_ASSERT(after);
|
||||
|
||||
// trick, init widget as floating
|
||||
// this completely initializes the tab bar and all docked widgets
|
||||
if (init)
|
||||
{
|
||||
QPoint offset(i * 25, i * 20);
|
||||
after->setVisible(false);
|
||||
after->setFloating(true);
|
||||
after->setOffsetWhenFloating(offset);
|
||||
after->setPreferredSizeWhenFloating(getPreferredSizeWhenFloating(i));
|
||||
after->setFloating(false);
|
||||
after->setVisible(true);
|
||||
after->resetWasAlreadyFLoating();
|
||||
}
|
||||
else
|
||||
{
|
||||
after->setFloating(false);
|
||||
}
|
||||
if (!first) { continue; }
|
||||
this->tabifyDockWidget(first, after);
|
||||
}
|
||||
}
|
||||
|
||||
// as now tabified, now set tab
|
||||
if (!this->m_tabBar)
|
||||
{
|
||||
this->m_tabBar = this->findChild<QTabBar *>();
|
||||
Q_ASSERT(m_tabBar);
|
||||
QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameDockWidgetTab());
|
||||
this->m_tabBar->setStyleSheet(qss);
|
||||
this->m_tabBar->setObjectName("comp_MainInfoAreaDockWidgetTab");
|
||||
this->m_tabBar->setMovable(false);
|
||||
this->m_tabBar->setElideMode(Qt::ElideNone);
|
||||
this->setDocumentMode(true); // did not notice any effect
|
||||
this->setTabPixmaps();
|
||||
|
||||
// East / West does not work (shown, but area itself empty)
|
||||
// South does not have any effect
|
||||
this->m_tabBar->setShape(QTabBar::TriangularSouth);
|
||||
connect(this->m_tabBar, &QTabBar::tabBarDoubleClicked, this, &CInfoArea::ps_tabBarDoubleClicked);
|
||||
}
|
||||
|
||||
if (this->countDockedWidgets() > 0)
|
||||
{
|
||||
this->m_tabBar->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::unTabifyAllWidgets()
|
||||
{
|
||||
if (this->m_dockableWidgets.size() < 2) return;
|
||||
CDockWidgetInfoArea *first = this->m_dockableWidgets.first();
|
||||
for (int i = 1; i < this->m_dockableWidgets.size(); i++)
|
||||
{
|
||||
CDockWidgetInfoArea *after = this->m_dockableWidgets.at(i);
|
||||
Q_ASSERT(after);
|
||||
this->splitDockWidget(first, after, Qt::Horizontal);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::connectAllWidgets()
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
connect(dw, &CDockWidgetInfoArea::widgetTopLevelChanged, this, &CInfoArea::ps_onWidgetTopLevelChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::setMarginsWhenFloating(int left, int top, int right, int bottom)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
//! Margins when window is floating
|
||||
dw->setMarginsWhenFloating(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::setMarginsWhenDocked(int left, int top, int right, int bottom)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
//! Margins when window is docked
|
||||
dw->setMarginsWhenDocked(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
int CInfoArea::countDockedWidgets() const
|
||||
{
|
||||
if (!this->m_tabBar) return 0;
|
||||
return this->m_tabBar->count();
|
||||
}
|
||||
|
||||
CDockWidgetInfoArea *CInfoArea::getDockableWidgetByTabIndex(int tabBarIndex) const
|
||||
{
|
||||
if (tabBarIndex >= this->m_dockableWidgets.count() || tabBarIndex < 0) return nullptr;
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
if (dw->isFloating()) continue; // not in tab bar
|
||||
if (tabBarIndex == 0) return dw;
|
||||
tabBarIndex--;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CInfoArea::widgetToTabBarIndex(const CDockWidgetInfoArea *dockWidget)
|
||||
{
|
||||
if (!dockWidget) return -1;
|
||||
if (dockWidget->isFloating()) return -1;
|
||||
int tabBarIndex = 0;
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
if (dw->isFloating()) continue; // not in tab bar
|
||||
if (dw == dockWidget) return tabBarIndex;
|
||||
tabBarIndex++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CInfoArea::setFeaturesForDockableWidgets(QDockWidget::DockWidgetFeatures features)
|
||||
{
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
dw->setFeatures(features);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::setTabPixmaps()
|
||||
{
|
||||
if (!this->m_tabBar) return;
|
||||
for (int i = 0; i < this->m_tabBar->count(); i++)
|
||||
{
|
||||
const QPixmap p = indexToPixmap(i);
|
||||
this->m_tabBar->setTabIcon(i, p);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::ps_tabBarDoubleClicked(int tabBarIndex)
|
||||
{
|
||||
CDockWidgetInfoArea *dw = this->getDockableWidgetByTabIndex(tabBarIndex);
|
||||
if (!dw) return;
|
||||
dw->toggleFloating();
|
||||
}
|
||||
|
||||
void CInfoArea::ps_onWidgetTopLevelChanged(CDockWidget *widget, bool topLevel)
|
||||
{
|
||||
Q_ASSERT(widget);
|
||||
Q_UNUSED(topLevel);
|
||||
if (!widget) return;
|
||||
|
||||
// fix pixmaps
|
||||
this->setTabPixmaps();
|
||||
}
|
||||
|
||||
void CInfoArea::ps_onStyleSheetChanged()
|
||||
{
|
||||
QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameMainInfoArea());
|
||||
this->setStyleSheet(qss);
|
||||
if (this->m_tabBar)
|
||||
{
|
||||
QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameDockWidgetTab());
|
||||
this->m_tabBar->setStyleSheet(qss);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::ps_showContextMenu(const QPoint &pos)
|
||||
{
|
||||
QPoint globalPos = this->mapToGlobal(pos);
|
||||
QScopedPointer<QMenu> contextMenu(new QMenu(this));
|
||||
this->addToContextMenu(contextMenu.data());
|
||||
|
||||
QAction *selectedItem = contextMenu.data()->exec(globalPos);
|
||||
Q_UNUSED(selectedItem);
|
||||
}
|
||||
|
||||
void CInfoArea::ps_showTabTexts(bool show)
|
||||
{
|
||||
if (show == this->m_showTabTexts) return;
|
||||
this->m_showTabTexts = show;
|
||||
for (CDockWidgetInfoArea *dw : this->m_dockableWidgets)
|
||||
{
|
||||
dw->showTitleWhenDocked(show);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoArea::ps_showTabBar(bool show)
|
||||
{
|
||||
if (show == this->m_showTabBar) return;
|
||||
this->m_showTabBar = show;
|
||||
if (!this->m_tabBar) return;
|
||||
this->m_tabBar->setVisible(show); // not working, but setting right value will not harm anything
|
||||
this->m_tabBar->setMaximumHeight(show ? 10000 : 0); // does the trick
|
||||
this->adjustSizeForAllDockWidgets();
|
||||
}
|
||||
|
||||
void CInfoArea::ps_setTabBarPosition(QTabWidget::TabPosition position)
|
||||
{
|
||||
Q_ASSERT(position == QTabWidget::North || position == QTabWidget::South);
|
||||
this->setTabPosition(Qt::TopDockWidgetArea, position);
|
||||
}
|
||||
|
||||
void CInfoArea::ps_toggleTabBarPosition()
|
||||
{
|
||||
QTabWidget::TabPosition p = (this->tabPosition(Qt::TopDockWidgetArea) == QTabWidget::North) ?
|
||||
QTabWidget::South : QTabWidget::North;
|
||||
this->ps_setTabBarPosition(p);
|
||||
}
|
||||
|
||||
void CInfoArea::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (this->isFloating())
|
||||
{
|
||||
this->toggleFloating();
|
||||
event->setAccepted(false); // refuse -> do not close
|
||||
}
|
||||
else
|
||||
{
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
162
src/blackgui/infoarea.h
Normal file
162
src/blackgui/infoarea.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/* 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_INFOAREA_H
|
||||
#define BLACKGUI_INFOAREA_H
|
||||
|
||||
#include "dockwidgetinfoarea.h"
|
||||
#include <QMainWindow>
|
||||
#include <QTabBar>
|
||||
#include <QPixmap>
|
||||
|
||||
namespace Ui { class CInfoArea; }
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
//! Info area, hosting dockable widgets
|
||||
//! \sa CDockWidgetInfoArea
|
||||
class CInfoArea : public QMainWindow
|
||||
{
|
||||
// KB: TODO, make this an interface, IInfoArea?
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//! Destructor
|
||||
virtual ~CInfoArea() {}
|
||||
|
||||
//! Add items to context menu
|
||||
void addToContextMenu(QMenu *menu) const;
|
||||
|
||||
//! Is the area floating?
|
||||
bool isFloating() const { return this->m_infoAreaFloating; }
|
||||
|
||||
//! Selected area of non floating areas
|
||||
//! \remarks -1 for no area
|
||||
int getSelectedInfoAreaIndex() const;
|
||||
|
||||
//! Is given widget selected. Means it is not floating, and the one selected
|
||||
bool isSelectedInfoArea(const CDockWidgetInfoArea *infoArea) const;
|
||||
|
||||
public slots:
|
||||
//! Dock all widgets
|
||||
void dockAllWidgets();
|
||||
|
||||
//! Adjust size for all dock widgets
|
||||
void adjustSizeForAllDockWidgets();
|
||||
|
||||
//! All widgets floating
|
||||
void floatAllWidgets();
|
||||
|
||||
//! Toggle dock / floating of the whole info area
|
||||
void toggleFloating();
|
||||
|
||||
//! Toggle floating of index
|
||||
void toggleFloating(int areaIndex);
|
||||
|
||||
//! Select area
|
||||
void selectArea(int areaIndex);
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
explicit CInfoArea(QWidget *parent = nullptr);
|
||||
|
||||
//! Override close event
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
//! Preferred size when floating
|
||||
virtual QSize getPreferredSizeWhenFloating(int areaIndex) const = 0;
|
||||
|
||||
//! Info area (index) to icon
|
||||
virtual const QPixmap &indexToPixmap(int areaIndex) const = 0;
|
||||
|
||||
//! Init area after(!) GUI is initialized
|
||||
void initInfoArea();
|
||||
|
||||
private:
|
||||
Ui::CInfoArea *ui = nullptr;
|
||||
QList<CDockWidgetInfoArea *> m_dockableWidgets ;
|
||||
QTabBar *m_tabBar = nullptr;
|
||||
bool m_showTabTexts = true;
|
||||
bool m_infoAreaFloating = false; //!< whole info area floating
|
||||
bool m_showTabBar = true; //!< auto ajdust the floating widgets
|
||||
|
||||
//! Tabify the widgets
|
||||
void tabifyAllWidgets();
|
||||
|
||||
//! Untabify
|
||||
void unTabifyAllWidgets();
|
||||
|
||||
//! The tab bar of the docked widgets
|
||||
QTabBar *tabBarDockedWidgets() const;
|
||||
|
||||
//! Corresponding dockable widgets
|
||||
QList<CDockWidgetInfoArea *> dockableWidgets() const;
|
||||
|
||||
//! Corresponding dockable widget for given tab index
|
||||
CDockWidgetInfoArea *getDockableWidgetByTabIndex(int tabBarIndex) const;
|
||||
|
||||
//! Features of the dockable widgets
|
||||
void setFeaturesForDockableWidgets(QDockWidget::DockWidgetFeatures features);
|
||||
|
||||
//! Number of tabbed widgets
|
||||
int countDockedWidgets() const;
|
||||
|
||||
//! Widget to tab bar index
|
||||
int widgetToTabBarIndex(const CDockWidgetInfoArea *dockWidget);
|
||||
|
||||
//! Set the tab's icons
|
||||
void setTabPixmaps();
|
||||
|
||||
//! Connect all widgets
|
||||
void connectAllWidgets();
|
||||
|
||||
//! Margins for the floating widgets
|
||||
void setMarginsWhenFloating(int left, int top, int right, int bottom);
|
||||
|
||||
//! Margins for the dockable widgets
|
||||
void setMarginsWhenDocked(int left, int top, int right, int bottom);
|
||||
|
||||
private slots:
|
||||
//! Tab bar has been double clicked
|
||||
void ps_tabBarDoubleClicked(int tabBarIndex);
|
||||
|
||||
//! A widget has changed its top level
|
||||
void ps_onWidgetTopLevelChanged(CDockWidget *widget, bool topLevel);
|
||||
|
||||
//! Style sheet has been changed
|
||||
void ps_onStyleSheetChanged();
|
||||
|
||||
//! Context menu
|
||||
void ps_showContextMenu(const QPoint &pos);
|
||||
|
||||
//! Show the tab texts, or just the icons
|
||||
void ps_showTabTexts(bool show);
|
||||
|
||||
//! Show tab bar
|
||||
void ps_showTabBar(bool show);
|
||||
|
||||
//! Tab position for docked widgets tab
|
||||
//! \remarks North or South working, East / West not
|
||||
void ps_setTabBarPosition(QTabWidget::TabPosition position);
|
||||
|
||||
//! Toggle tab position North - South
|
||||
void ps_toggleTabBarPosition();
|
||||
|
||||
//! Set dock area used
|
||||
void ps_setDockArea(Qt::DockWidgetArea area);
|
||||
|
||||
//! Dock / floating of the whole info area
|
||||
void ps_setInfoAreaFloating(bool floating);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // guard
|
||||
Reference in New Issue
Block a user