Commit 163ce245 authored by Victor Yacovlev's avatar Victor Yacovlev

Implemented column layout option for MainWindow

parent 678db3c0
This diff is collapsed.
This diff is collapsed.
......@@ -17,9 +17,10 @@ set(SOURCES
aboutdialog.cpp
statusbar.cpp
debuggerview.cpp
row.cpp
side.cpp
switchworkspacedialog.cpp
systemopenfilesettings.cpp
guisettingspage.cpp
)
set(EXTRA_LIBS
......@@ -46,9 +47,10 @@ set(MOC_HEADERS
tabwidgetelement.h
statusbar.h
debuggerview.h
row.h
side.h
switchworkspacedialog.h
systemopenfilesettings.h
guisettingspage.h
)
set(FORMS
......@@ -56,6 +58,7 @@ set(FORMS
aboutdialog.ui
switchworkspacedialog.ui
systemopenfilesettings.ui
guisettingspage.ui
)
set(RESOURCES
......
#include "guisettingspage.h"
#include "ui_guisettingspage.h"
namespace CoreGUI {
const QString GUISettingsPage::LayoutKey = "MainWindowLayout";
const QString GUISettingsPage::RowsFirstValue = "RowsFirst";
const QString GUISettingsPage::ColumnsFirstValue = "ColumnsFirst";
GUISettingsPage::GUISettingsPage(ExtensionSystem::SettingsPtr settings, QWidget *parent)
: settings_(settings)
, QWidget(parent)
, ui(new Ui::GUISettingsPage)
{
ui->setupUi(this);
ui->lblRowsFirst->setPixmap(QPixmap(":/coregui/layout-rows-first.png"));
ui->lblColumnsFirst->setPixmap(QPixmap(":/coregui/layout-columns-first.png"));
ui->gridLayout_2->setAlignment(ui->lblColumnsFirst, Qt::AlignHCenter|Qt::AlignBottom);
ui->gridLayout_2->setAlignment(ui->lblRowsFirst, Qt::AlignHCenter|Qt::AlignBottom);
ui->gridLayout_2->setAlignment(ui->btnColumnsFirst, Qt::AlignHCenter|Qt::AlignTop);
ui->gridLayout_2->setAlignment(ui->btnRowsFirst, Qt::AlignHCenter|Qt::AlignTop);
init();
}
void GUISettingsPage::init()
{
const QString layoutValue = settings_->value(LayoutKey, RowsFirstValue).toString();
if (layoutValue == ColumnsFirstValue) {
ui->btnColumnsFirst->setChecked(true);
}
else {
ui->btnRowsFirst->setChecked(true);
}
}
void GUISettingsPage::accept()
{
const QString layoutValue = settings_->value(LayoutKey, RowsFirstValue).toString();
if (ui->btnColumnsFirst->isChecked()) {
settings_->setValue(LayoutKey, ColumnsFirstValue);
}
else {
settings_->setValue(LayoutKey, RowsFirstValue);
}
if (layoutValue != settings_->value(LayoutKey, RowsFirstValue).toString()) {
emit settingsChanged(QStringList() << LayoutKey);
}
}
void GUISettingsPage::resetToDefaults()
{
const QString layoutValue = settings_->value(LayoutKey, RowsFirstValue).toString();
ui->btnRowsFirst->setChecked(true);
settings_->setValue(LayoutKey, RowsFirstValue);
if (layoutValue != settings_->value(LayoutKey, RowsFirstValue).toString()) {
emit settingsChanged(QStringList() << LayoutKey);
}
}
GUISettingsPage::~GUISettingsPage()
{
delete ui;
}
} // namespace CoreGUI
#ifndef COREGUI_GUISETTINGSPAGE_H
#define COREGUI_GUISETTINGSPAGE_H
#include <extensionsystem/settings.h>
#include <QWidget>
namespace CoreGUI {
namespace Ui {
class GUISettingsPage;
}
class GUISettingsPage : public QWidget
{
Q_OBJECT
public:
static const QString LayoutKey /* = "MainWindowLayout" */;
static const QString RowsFirstValue /* = "RowsFirst" */;
static const QString ColumnsFirstValue /* = "ColumnsFirst" */;
explicit GUISettingsPage(ExtensionSystem::SettingsPtr settings, QWidget *parent = 0);
~GUISettingsPage();
public slots:
void accept();
void init();
void resetToDefaults();
signals:
void settingsChanged(const QStringList & keys);
private:
Ui::GUISettingsPage *ui;
ExtensionSystem::SettingsPtr settings_;
};
} // namespace CoreGUI
#endif // COREGUI_GUISETTINGSPAGE_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CoreGUI::GUISettingsPage</class>
<widget class="QWidget" name="CoreGUI::GUISettingsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>396</width>
<height>252</height>
</rect>
</property>
<property name="windowTitle">
<string>User Interface</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Docking layout</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>10</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="lblRowsFirst">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>155</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblColumnsFirst">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="btnRowsFirst">
<property name="text">
<string>Rows first</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="btnColumnsFirst">
<property name="text">
<string>Columns first</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
#include "mainwindow.h"
#include "row.h"
#include "side.h"
#include "ui_mainwindow.h"
#include "tabwidgetelement.h"
#include "extensionsystem/pluginmanager.h"
......@@ -9,6 +9,7 @@
#include "statusbar.h"
#include "tabwidget.h"
#include "systemopenfilesettings.h"
#include "guisettingspage.h"
#include <algorithm>
#include <QSharedPointer>
......@@ -25,49 +26,28 @@ MainWindow::MainWindow(Plugin * p) :
tabWidget_(0),
prevBottomSize_(DefaultConsoleHeight)
{
ui->setupUi(this);
connect(ui->splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(handleSplitterMoved(int,int)));
QWidget * centralContainer = new QWidget;
centralRow_ = new Row(this, "MainWindow/CentralRow");
bottomRow_ = new Row(this, "MainWindow/BottomRow");
connect(bottomRow_, SIGNAL(visiblityRequest()), this, SLOT(ensureBottomVisible()));
centralContainer->setLayout(new QVBoxLayout);
centralContainer->layout()->addWidget(centralRow_);
centralContainer->layout()->setContentsMargins(0, 0, 0, 0);
#ifdef Q_OS_MAC
centralContainer->layout()->setContentsMargins(0, 8, 0, 0);
#endif
ui->splitter->addWidget(centralContainer);
ui->splitter->addWidget(bottomRow_);
debuggerWindow_ = 0;
ui->setupUi(this);
tabWidget_ = new TabWidget(this);
centralRow_->addComponent(tabWidget_, true);
helpAndCourcesPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/HelpDockPlace");
centralRow_->addComponent(helpAndCourcesPlace_, false);
connect(helpAndCourcesPlace_, SIGNAL(visiblityRequest(bool,QSize)),
centralRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
helpAndCoursesPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/HelpDockPlace");
debuggerPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/DebuggerDockPlace");
bottomRow_->addComponent(debuggerPlace_, false);
connect(debuggerPlace_, SIGNAL(visiblityRequest(bool,QSize)),
bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
consolePlace_ = new Widgets::DockWindowPlace(this, "MainWindow/ConsoleDockPlace");
actorsPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/ActorsDockPlace");
consoleAndCourcesPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/ConsoleDockPlace");
bottomRow_->addComponent(consoleAndCourcesPlace_, true);
connect(consoleAndCourcesPlace_, SIGNAL(visiblityRequest(bool,QSize)),
bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
centralSide_ = new Side(this, "MainWindow/CentralRow");
secondarySide_ = new Side(this, "MainWindow/BottomRow");
actorsPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/ActorsDockPlace");
bottomRow_->addComponent(actorsPlace_, false);
connect(actorsPlace_, SIGNAL(visiblityRequest(bool,QSize)),
bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(secondarySide_, SIGNAL(visiblityRequest()), this, SLOT(ensureBottomVisible()));
connect(ui->actionShow_Console_Pane, SIGNAL(triggered(bool)), this, SLOT(setConsoleVisible(bool)));
// centralContainer->setLayout(new QVBoxLayout);
// centralContainer->layout()->addWidget(centralSide_);
// centralContainer->layout()->setContentsMargins(0, 0, 0, 0);
//#ifdef Q_OS_MAC
// centralContainer->layout()->setContentsMargins(0, 8, 0, 0);
//#endif
connect(ui->actionShow_Console_Pane, SIGNAL(triggered(bool)), this, SLOT(setBottomVisible(bool)));
setStatusBar(statusBar_);
setMinimumHeight(380);
......@@ -243,6 +223,213 @@ void MainWindow::changeFocusOnMenubar()
}
}
void MainWindow::prepareLayoutChange()
{
helpAndCoursesPlace_->disconnect(SIGNAL(visiblityRequest(bool,QSize)));
debuggerPlace_->disconnect(SIGNAL(visiblityRequest(bool,QSize)));
consolePlace_->disconnect(SIGNAL(visiblityRequest(bool,QSize)));
actorsPlace_->disconnect(SIGNAL(visiblityRequest(bool,QSize)));
centralSide_->disconnect(SIGNAL(splitterMoved(int,int)), this, SLOT(checkForConsoleHiddenBySplitter(int,int)));
ui->splitter->disconnect(SIGNAL(splitterMoved(int,int)), this, SLOT(checkForConsoleHiddenBySplitter(int,int)));
helpAndCoursesPlace_->setParent(0);
debuggerPlace_->setParent(0);
consolePlace_->setParent(0);
actorsPlace_->setParent(0);
centralSide_->setParent(0);
secondarySide_->setParent(0);
}
QMap<QWidget*,QSize> MainWindow::saveSizes() const
{
QMap<QWidget*,QSize> result;
if (helpAndCoursesPlace_->isVisible())
result[helpAndCoursesPlace_] = helpAndCoursesPlace_->size();
if (debuggerPlace_->isVisible())
result[debuggerPlace_] = debuggerPlace_->size();
if (consolePlace_->isVisible())
result[consolePlace_] = consolePlace_->size();
if (actorsPlace_->isVisible())
result[actorsPlace_] = actorsPlace_->size();
return result;
}
void MainWindow::restoreSizes(const QMap<QWidget *, QSize> &sizes, const Qt::Orientation o)
{
const int W = centralWidget()->width();
const int H = centralWidget()->height();
if (o == Qt::Vertical) {
// Rows first
int bottomH = sizes.contains(consolePlace_)
? sizes[consolePlace_].height() : 0;
if (sizes.contains(debuggerPlace_))
bottomH = qMax(bottomH, sizes[debuggerPlace_].height());
if (sizes.contains(actorsPlace_))
bottomH = qMax(bottomH, sizes[actorsPlace_].height());
QList<int> centralRowSizes, bottomRowSizes;
if (sizes.contains(helpAndCoursesPlace_)) {
centralRowSizes << 0 << sizes[helpAndCoursesPlace_].width();
centralRowSizes[0] = W - centralRowSizes[1] - centralSide_->handleWidth();
}
else {
centralRowSizes << W << 0;
}
int bottomSplitters = 0;
bottomRowSizes << 0 << 0 << 0;
if (sizes.contains(debuggerPlace_)) {
bottomSplitters ++;
bottomRowSizes[0] = sizes[debuggerPlace_].width();
}
if (sizes.contains(actorsPlace_)) {
bottomSplitters ++;
bottomRowSizes[2] = sizes[actorsPlace_].width();
}
bottomRowSizes[1] = W - bottomRowSizes[0] - bottomRowSizes[2] - bottomSplitters * secondarySide_->handleWidth();
QList<int> mainSizes; mainSizes << 0 << 0;
if (!sizes.contains(helpAndCoursesPlace_) && sizes.contains(actorsPlace_)) {
if (sizes.contains(consolePlace_) && consolePlace_->height() > 0)
bottomH = consolePlace_->height();
else
bottomH = H / 2;
}
mainSizes[1] = bottomH;
mainSizes[0] = H - bottomH - ui->splitter->handleWidth();
centralSide_->setSizes(centralRowSizes);
secondarySide_->setSizes(bottomRowSizes);
ui->splitter->setSizes(mainSizes);
}
else {
// Columns first
int rightW = sizes.contains(helpAndCoursesPlace_)
? sizes[helpAndCoursesPlace_].width() : 0;
QList<int> centralColSizes, rightColSizes;
centralColSizes << 0 << 0;
if (sizes.contains(consolePlace_)) {
centralColSizes[1] = sizes[consolePlace_].height();
centralColSizes[0] = H - centralColSizes[1] - centralSide_->handleWidth();
}
else {
centralColSizes[0] = H - centralSide_->handleWidth();
}
rightColSizes << 0 << 0;
if (sizes.contains(actorsPlace_)) {
rightColSizes[1] = sizes[actorsPlace_].height();
rightColSizes[0] = H - secondarySide_->handleWidth() - rightColSizes[1];
rightW = qMax(rightW, sizes[actorsPlace_].width());
}
else {
rightColSizes[1] = sizes[actorsPlace_].height();
}
QList<int> mainSizes; mainSizes << 0 << 0;
if (rightW > 0) {
mainSizes[1] = rightW;
mainSizes[0] = W - rightW - ui->splitter->handleWidth();
}
else {
mainSizes[0] = W;
}
ui->splitter->setSizes(mainSizes);
centralSide_->setSizes(centralColSizes);
secondarySide_->setSizes(rightColSizes);
}
}
void MainWindow::switchToRowFirstLayout()
{
QMap<QWidget*,QSize> visibleSizes = saveSizes();
prepareLayoutChange();
ui->splitter->setOrientation(Qt::Vertical);
centralSide_->setOrientation(Qt::Horizontal);
secondarySide_->setOrientation(Qt::Horizontal);
debuggerWindow_->changeDockPlace(debuggerPlace_);
ui->splitter->addWidget(centralSide_);
ui->splitter->addWidget(secondarySide_);
centralSide_->addComponent(tabWidget_, true);
centralSide_->addComponent(helpAndCoursesPlace_, false);
secondarySide_->addComponent(debuggerPlace_, false);
secondarySide_->addComponent(consolePlace_, true);
secondarySide_->addComponent(actorsPlace_, false);
connect(helpAndCoursesPlace_, SIGNAL(visiblityRequest(bool,QSize)),
centralSide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(debuggerPlace_, SIGNAL(visiblityRequest(bool,QSize)),
secondarySide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(consolePlace_, SIGNAL(visiblityRequest(bool,QSize)),
secondarySide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(actorsPlace_, SIGNAL(visiblityRequest(bool,QSize)),
secondarySide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(ui->splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(checkForConsoleHiddenBySplitter(int,int)));
restoreSizes(visibleSizes, Qt::Vertical);
}
void MainWindow::switchToColumnFirstLayout()
{
QMap<QWidget*,QSize> visibleSizes = saveSizes();
prepareLayoutChange();
ui->splitter->setOrientation(Qt::Horizontal);
centralSide_->setOrientation(Qt::Vertical);
secondarySide_->setOrientation(Qt::Vertical);
debuggerWindow_->changeDockPlace(helpAndCoursesPlace_);
ui->splitter->addWidget(centralSide_);
ui->splitter->addWidget(secondarySide_);
centralSide_->addComponent(tabWidget_, true);
centralSide_->addComponent(consolePlace_, true);
// secondarySide_->addComponent(debuggerPlace_, false);
secondarySide_->addComponent(helpAndCoursesPlace_, false);
secondarySide_->addComponent(actorsPlace_, false);
connect(helpAndCoursesPlace_, SIGNAL(visiblityRequest(bool,QSize)),
secondarySide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(debuggerPlace_, SIGNAL(visiblityRequest(bool,QSize)),
secondarySide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(consolePlace_, SIGNAL(visiblityRequest(bool,QSize)),
centralSide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(actorsPlace_, SIGNAL(visiblityRequest(bool,QSize)),
secondarySide_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(centralSide_, SIGNAL(splitterMoved(int,int)), this, SLOT(checkForConsoleHiddenBySplitter(int,int)));
restoreSizes(visibleSizes, Qt::Horizontal);
}
QSize MainWindow::minimumSizeHint() const
{
int minW = statusBar_->minimumSizeHint().width() + 10;
......@@ -1077,6 +1264,16 @@ void MainWindow::updateSettings(SettingsPtr settings, const QStringList & keys)
void MainWindow::loadSettings(const QStringList & keys)
{
if (keys.contains(GUISettingsPage::LayoutKey)) {
const QString layoutChoice =
settings_->value(GUISettingsPage::LayoutKey, GUISettingsPage::RowsFirstValue).toString();
if (layoutChoice == GUISettingsPage::ColumnsFirstValue) {
switchToColumnFirstLayout();
}
else {
switchToRowFirstLayout();
}
}
QRect r = settings_->value(Plugin::MainWindowGeometryKey,
QRect(QPoint(-1, -1), QSize(940, 540))).toRect();
if (r.width()>0 &&
......@@ -1097,8 +1294,13 @@ void MainWindow::loadSettings(const QStringList & keys)
}
move(ps);
}
centralRow_->updateSettings(settings_, keys);
bottomRow_->updateSettings(settings_, keys);
if (keys.size() == 1 && "MainWindowLayout" == keys[0]) {
// do nothing on hot layout change
}
else {
centralSide_->updateSettings(settings_, keys);
secondarySide_->updateSettings(settings_, keys);
}
if (keys.contains(Plugin::MainWindowSplitterStateKey+"0") || keys.isEmpty()) {
QList<int> sizes;
sizes << 0 << 0;
......@@ -1126,8 +1328,8 @@ void MainWindow::saveSettings()
settings_->setValue(Plugin::MainWindowSplitterStateKey+"0", sizes[0]);
settings_->setValue(Plugin::MainWindowSplitterStateKey+"1", sizes[1]);
settings_->setValue("SavedBottomSize", prevBottomSize_);
centralRow_->save();
bottomRow_->save();
centralSide_->save();
secondarySide_->save();
}
void MainWindow::restoreSession()
......@@ -1371,41 +1573,76 @@ void MainWindow::fileOpen()
}
}
void MainWindow::ensureBottomVisible()
{
ui->actionShow_Console_Pane->setChecked(true);
setBottomVisible(true);
setConsoleVisible(true);
}
void MainWindow::handleSplitterMoved(int, int)
void MainWindow::checkForConsoleHiddenBySplitter(int, int)
{
ui->actionShow_Console_Pane->setChecked(ui->splitter->sizes()[1] > 0);
QSplitter * splitter = qobject_cast<QSplitter*>(sender());
int sz = splitter->sizes()[1];
ui->actionShow_Console_Pane->setChecked(sz > 0);
}
void MainWindow::setBottomVisible(bool v)
void MainWindow::setConsoleVisible(bool v)
{
if (v) {
int top = ui->splitter->sizes()[0];
int bottom = ui->splitter->sizes()[1];
int minTopH = ui->splitter->widget(0)->minimumSizeHint().height();
if (prevBottomSize_ == 0)