refs #512, GUI improvements

* menu widget to correct margin
* optimized stylesheet by adding dynamic properties for CDockWidget widgets (allows better qss selection)
This commit is contained in:
Klaus Basan
2016-06-01 23:05:08 +02:00
parent a25a0d1c0c
commit 67512d9d1f
7 changed files with 353 additions and 38 deletions

View File

@@ -308,12 +308,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Toggle COM 1 standby/active</string>
</property>
@@ -368,12 +362,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Toggle COM 2 standby/active</string>
</property>

View File

@@ -0,0 +1,75 @@
/* Copyright (C) 2016
* 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 "marginsinput.h"
#include "ui_marginsinput.h"
#include <QIntValidator>
namespace BlackGui
{
namespace Components
{
CMarginsInput::CMarginsInput(QWidget *parent) :
QFrame(parent),
ui(new Ui::CMarginsInput)
{
ui->setupUi(this);
connect(ui->pb_Ok, &QPushButton::clicked, this, &CMarginsInput::ps_Confirmed);
connect(ui->le_Bottom, &QLineEdit::returnPressed, this, &CMarginsInput::ps_Confirmed);
connect(ui->le_Left, &QLineEdit::returnPressed, this, &CMarginsInput::ps_Confirmed);
connect(ui->le_Right, &QLineEdit::returnPressed, this, &CMarginsInput::ps_Confirmed);
connect(ui->le_Top, &QLineEdit::returnPressed, this, &CMarginsInput::ps_Confirmed);
QIntValidator *v = new QIntValidator(0, 100, this);
ui->le_Bottom->setValidator(v);
ui->le_Left->setValidator(v);
ui->le_Right->setValidator(v);
ui->le_Top->setValidator(v);
this->setMargins(QMargins());
}
CMarginsInput::~CMarginsInput()
{ }
void CMarginsInput::setMargins(const QMargins &margins)
{
ui->le_Left->setText(QString::number(margins.left()));
ui->le_Right->setText(QString::number(margins.right()));
ui->le_Top->setText(QString::number(margins.top()));
ui->le_Bottom->setText(QString::number(margins.bottom()));
}
QMargins CMarginsInput::getMargins() const
{
int t = 0, b = 0, l = 0, r = 0;
const QString sl(ui->le_Left->text().trimmed());
const QString st(ui->le_Top->text().trimmed());
const QString sr(ui->le_Right->text().trimmed());
const QString sb(ui->le_Bottom->text().trimmed());
bool ok = false;
l = sl.toInt(&ok);
l = ok ? l : 0;
r = sr.toInt(&ok);
r = ok ? r : 0;
b = sb.toInt(&ok);
b = ok ? b : 0;
t = st.toInt(&ok);
t = ok ? t : 0;
const QMargins m(l, t, r, b);
return m;
}
void CMarginsInput::ps_Confirmed()
{
const QMargins m(this->getMargins());
emit this->changedMargins(m);
}
} // ns
} // ns

View File

@@ -0,0 +1,59 @@
/* Copyright (C) 2016
* 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_COMPONENTS_MARGINSINPUT_H
#define BLACKGUI_COMPONENTS_MARGINSINPUT_H
#include <QFrame>
#include <QMargins>
#include <QScopedPointer>
namespace Ui { class CMarginsInput; }
namespace BlackGui
{
namespace Components
{
/*!
* Widget alows to enter margins
*/
class CMarginsInput : public QFrame
{
Q_OBJECT
public:
//! Constructor
explicit CMarginsInput(QWidget *parent = nullptr);
//! Destructor
~CMarginsInput();
//! Set margins
void setMargins(const QMargins &margins);
//! Current values of margins
QMargins getMargins() const;
signals:
//! Margins changed
void changedMargins(const QMargins &margins);
private slots:
//! Ok
void ps_Confirmed();
private:
QScopedPointer<Ui::CMarginsInput> ui;
};
} // ns
} // ns
#endif // guard

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMarginsInput</class>
<widget class="QFrame" name="CMarginsInput">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>285</width>
<height>82</height>
</rect>
</property>
<property name="windowTitle">
<string>Margins input</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QGridLayout" name="gl_MarginsInput">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<property name="horizontalSpacing">
<number>4</number>
</property>
<item row="2" column="1">
<widget class="QLineEdit" name="le_Bottom">
<property name="maxLength">
<number>4</number>
</property>
<property name="placeholderText">
<string>bottom</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pb_Ok">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="le_Top">
<property name="maxLength">
<number>4</number>
</property>
<property name="placeholderText">
<string>top</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="le_Right">
<property name="placeholderText">
<string>right</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="le_Left">
<property name="placeholderText">
<string>left</string>
</property>
</widget>
</item>
<item row="1" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -62,29 +62,30 @@ QFileDialog QToolButton {
3) Borders between this widget and the inner child is the margin in gui.ini
*/
BlackGui--CDockWidgetInfoArea {
background-color: green; /* I use green here so I can adjust the borders in gui.ini */
background-color: green; /* Use green or red here to adjust the borders */
}
BlackGui--CDockWidgetInfoArea > QWidget {
/* outer widget in dock widget */
BlackGui--CDockWidgetInfoArea > QWidget[dockwidget="outerwidget"] {
background: black; /* background is background color here */
background-image: url(:/textures/icons/textures/texture-inner.jpg);
}
/* this is the first widget in the dock area */
/* all dock widgets shall have this QWidget as container */
BlackGui--CDockWidgetInfoArea[framelessDockWidget="true"] > QWidget > QFrame {
BlackGui--CDockWidgetInfoArea[framelessDockWidget="true"] > QWidget > QFrame[dockwidget="innerwidget"] {
margin: 0px;
padding: 3px;
border: 2px solid green;
border-radius: 10px;
}
/* fix the menu, which is overridden by the above QWidget */
BlackGui--CDockWidgetInfoArea > QMenu {
border: 1px solid darkslategray; /* reserve space for selection border */
background: lightgray;
color: black; /* text color */
padding: 3px; /* some space for border needed */
BlackGui--CDockWidgetInfoArea[framelessDockWidget="false"] > QWidget > QFrame[dockwidget="innerwidget"] {
}
BlackGui--CDockWidgetInfoArea > QMenu > QMenuWidget {
border: 0px; /* reserve space for selection border */
}
/* required when info area is not floating */

View File

@@ -7,6 +7,7 @@
* contained in the LICENSE file.
*/
#include "blackgui/components/marginsinput.h"
#include "blackgui/dockwidget.h"
#include "blackgui/guiapplication.h"
#include "blackgui/guiutility.h"
@@ -26,11 +27,14 @@
#include <QStyle>
#include <QVBoxLayout>
#include <QVariant>
#include <QWidgetAction>
#include <QWidget>
#include <Qt>
#include <QtGlobal>
using namespace BlackMisc;
using namespace BlackGui::Components;
using namespace BlackGui::Settings;
namespace BlackGui
{
@@ -43,8 +47,14 @@ namespace BlackGui
this->initTitleBarWidgets();
// context menu
CMarginsInput *mi = new CMarginsInput(this);
mi->setMaximumWidth(150);
this->m_marginMenuAction = new QWidgetAction(this);
this->m_marginMenuAction->setDefaultWidget(mi);
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &CDockWidget::customContextMenuRequested, this, &CDockWidget::ps_showContextMenu);
connect(mi, &CMarginsInput::changedMargins, this, &CDockWidget::ps_menuChangeMargins);
// connect
connect(this, &QDockWidget::topLevelChanged, this, &CDockWidget::ps_onTopLevelChanged);
@@ -77,31 +87,40 @@ namespace BlackGui
void CDockWidget::setMarginsWhenFloating(const QMargins &margins)
{
this->m_marginsWhenFloating = margins;
CSettingsDockWidget s = this->getSettings();
s.setFloatingMargins(margins);
this->setSettings(s);
}
void CDockWidget::setMarginsWhenFloating(int left, int top, int right, int bottom)
{
this->setMarginsWhenFloating(QMargins(left, top, right, bottom));
}
void CDockWidget::setMarginsWhenFramelessFloating(const QMargins &margins)
{
this->m_marginsWhenFramelessFloating = margins;
}
void CDockWidget::setMarginsWhenFloating(int left, int top, int right, int bottom)
{
this->m_marginsWhenFloating = QMargins(left, top, right, bottom);
CSettingsDockWidget s = this->getSettings();
s.setFloatingFramelessMargins(margins);
this->setSettings(s);
}
void CDockWidget::setMarginsWhenFramelessFloating(int left, int top, int right, int bottom)
{
this->m_marginsWhenFramelessFloating = QMargins(left, top, right, bottom);
this->setMarginsWhenFramelessFloating(QMargins(left, top, right, bottom));
}
void CDockWidget::setMarginsWhenDocked(const QMargins &margins)
{
this->m_marginsWhenDocked = margins;
CSettingsDockWidget s = this->getSettings();
s.setDockedMargins(margins);
this->setSettings(s);
}
void CDockWidget::setMarginsWhenDocked(int left, int top, int right, int bottom)
{
this->m_marginsWhenDocked = QMargins(left, top, right, bottom);
this->setMarginsWhenDocked(QMargins(left, top, right, bottom));
}
bool CDockWidget::isWidgetVisible() const
@@ -189,6 +208,18 @@ namespace BlackGui
this->forceStyleSheetUpdate(); // force style sheet reload
}
const QString &CDockWidget::propertyOuterWidget()
{
static const QString s("outerwidget");
return s;
}
const QString &CDockWidget::propertyInnerWidget()
{
static const QString s("innerwidget");
return s;
}
void CDockWidget::toggleFloating()
{
bool floating = !this->isFloating();
@@ -253,28 +284,34 @@ namespace BlackGui
{
if (this->isFloating())
{
contextMenu->addAction(BlackMisc::CIcons::dockTop16(), "Dock", this, SLOT(toggleFloating()));
contextMenu->addAction(BlackMisc::CIcons::dockTop16(), "Dock", this, &CDockWidget::toggleFloating);
if (this->isFrameless())
{
contextMenu->addAction(BlackMisc::CIcons::tableSheet16(), "Normal window", this, SLOT(toggleFrameless()));
contextMenu->addAction(BlackMisc::CIcons::tableSheet16(), "Normal window", this, &CDockWidget::toggleFrameless);
}
else
{
contextMenu->addAction(BlackMisc::CIcons::tableSheet16(), "Frameless", this, SLOT(toggleFrameless()));
contextMenu->addAction(BlackMisc::CIcons::tableSheet16(), "Frameless", this, &CDockWidget::toggleFrameless);
}
contextMenu->addAction(BlackMisc::CIcons::refresh16(), "Redraw", this, SLOT(update()));
}
else
{
contextMenu->addAction(BlackMisc::CIcons::floatOne16(), "Float", this, SLOT(toggleFloating()));
contextMenu->addAction(BlackMisc::CIcons::floatOne16(), "Float", this, &CDockWidget::toggleFloating);
}
// Margin action
if (this->isFloating())
{
contextMenu->addAction(BlackMisc::CIcons::tableSheet16(), "Margins", this, &CDockWidget::ps_dummy);
contextMenu->addAction(this->m_marginMenuAction);
}
}
void CDockWidget::initialFloating()
{
// init status bar, as we have now all structures set
this->initStatusBar();
this->initStatusBarAndProperties();
// for the first time resize
if (!this->m_preferredSizeWhenFloating.isNull())
@@ -400,14 +437,12 @@ namespace BlackGui
this->setTitleBarWidget(this->m_titleBarWidgetEmpty);
}
void CDockWidget::initStatusBar()
void CDockWidget::initStatusBarAndProperties()
{
if (this->m_statusBar.getStatusBar()) { return; }
if (!this->m_allowStatusBar) { return; }
this->m_statusBar.initStatusBar();
// Typical reasons for asserts here
// 1) Check the structwe, we expect the following hierarchy
// 1) Check the structure, we expect the following hierarchy:
// QDockWidget (CDockWidget/CDockWidgetInfoArea) -> QWidget (outer widget) -> QFrame (inner widget)
// Structure used for frameless floating windows
// 2) Check if the "floating" flag is accidentally set for the dock widget in the GUI builder
@@ -415,6 +450,8 @@ namespace BlackGui
QWidget *outerWidget = this->widget(); // the outer widget containing the layout
Q_ASSERT_X(outerWidget, "CDockWidget::initStatusBar", "No outer widget");
if (!outerWidget) { return; }
outerWidget->setProperty("dockwidget", propertyOuterWidget());
Q_ASSERT_X(outerWidget->layout(), "CDockWidget::initStatusBar", "No outer widget layout");
if (!outerWidget->layout()) { return; }
Q_ASSERT_X(outerWidget->layout()->itemAt(0) && outerWidget->layout()->itemAt(0)->widget(), "CDockWidget::initStatusBar", "No outer widget layout item");
@@ -424,6 +461,13 @@ namespace BlackGui
QFrame *innerWidget = qobject_cast<QFrame *>(outerWidget->layout()->itemAt(0)->widget()); // the inner widget containing the layout
Q_ASSERT_X(innerWidget, "CDockWidget::initStatusBar", "No inner widget");
if (!innerWidget) { this->m_allowStatusBar = false; return; }
innerWidget->setProperty("dockwidget", propertyInnerWidget());
// status bar
if (!this->m_allowStatusBar) { return; }
this->m_statusBar.initStatusBar();
// layout
QVBoxLayout *vLayout = qobject_cast<QVBoxLayout *>(innerWidget->layout());
Q_ASSERT_X(vLayout, "CDockWidget::initStatusBar", "No outer widget layout");
if (!vLayout) { this->m_allowStatusBar = false; return; }
@@ -453,6 +497,38 @@ namespace BlackGui
this->m_dockWidgetVisible = visible;
}
void CDockWidget::ps_menuChangeMargins(const QMargins &margins)
{
const bool frameless = this->isFrameless();
const bool floating = this->isFloating();
if (floating)
{
if (frameless)
{
this->setMarginsWhenFramelessFloating(margins);
}
else
{
this->setMarginsWhenFloating(margins);
}
}
else
{
this->setMarginsWhenDocked(margins);
}
this->setContentsMargins(margins);
}
void CDockWidget::ps_settingsChanged()
{
// void
}
void CDockWidget::ps_dummy()
{
// void
}
void CDockWidget::ps_onStyleSheetsChanged()
{
// style sheet changes go here

View File

@@ -30,6 +30,7 @@ class QMenu;
class QMouseEvent;
class QPaintEvent;
class QWidget;
class QWidgetAction;
namespace BlackGui
{
@@ -116,6 +117,12 @@ namespace BlackGui
//! \copydoc CEnableForFramelessWindow::setFrameless
virtual void setFrameless(bool frameless) override;
//! Value for dynamic property "dockwidget"
static const QString &propertyOuterWidget();
//! Value for dynamic property "dockwidget"
static const QString &propertyInnerWidget();
public slots:
//! Toggle floating
void toggleFloating();
@@ -180,9 +187,19 @@ namespace BlackGui
//! Visibility has changed
void ps_onVisibilityChanged(bool visible);
//! Change margins
void ps_menuChangeMargins(const QMargins &margins);
//! Changed settings
void ps_settingsChanged();
//! Dummy slot for QAction
void ps_dummy();
private:
QWidget *m_titleBarWidgetEmpty = nullptr; //!< replacing default title bar
QWidget *m_titleBarWidgetOriginal = nullptr; //!< the original title bar
QWidgetAction *m_marginMenuAction = nullptr; //!< menu action for margins
QMargins m_marginsWhenFloating; //!< Offsets when window is floating
QMargins m_marginsWhenFramelessFloating; //!< Offsets when window is frameless floating
QMargins m_marginsWhenDocked; //!< Offsets when window is docked
@@ -203,7 +220,7 @@ namespace BlackGui
void initTitleBarWidgets();
//! Init status bar
void initStatusBar();
void initStatusBarAndProperties();
//! Force a style sheet update
void forceStyleSheetUpdate();