From 47f5b25877a2977d0ab55436b98b52766e002316 Mon Sep 17 00:00:00 2001 From: Steffen Baranowsky Date: Tue, 26 Jan 2016 00:08:26 +0100 Subject: [PATCH 1/2] Add a new window decoration to MDISubWindows --- data/themes/default/close.png | Bin 0 -> 232 bytes data/themes/default/maximize.png | Bin 0 -> 163 bytes data/themes/default/minimize.png | Bin 0 -> 150 bytes data/themes/default/restore.png | Bin 0 -> 186 bytes data/themes/default/style.css | 38 ++++- include/SubWindow.h | 46 ++++-- src/gui/SubWindow.cpp | 234 +++++++++++++++++++++++++++++-- 7 files changed, 294 insertions(+), 24 deletions(-) create mode 100644 data/themes/default/close.png create mode 100644 data/themes/default/maximize.png create mode 100644 data/themes/default/minimize.png create mode 100644 data/themes/default/restore.png diff --git a/data/themes/default/close.png b/data/themes/default/close.png new file mode 100644 index 0000000000000000000000000000000000000000..0dc87670dbb90f4da2f827e0f6942e1b79ec5a98 GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn1|+R>-G2cowj^(N7l!{JxM1({$v_d#0*}aI zppNSx%;=;sy8 zo3&$kjymh&6<6~ginejE^|r>HY}S{V6ZBu#fmu1hXy?S3=>q5D6kAz1CjAz=#4tIh zr{VOP+pDKtVy+dP&^RsY0mIe-G2cowj^(N7l!{JxM1({$v_d#0*}aI zppNSx%;=;sy8-G2cowj^(N7l!{JxM1({$v_d#0*}aI zppNSx%;=;sy8Er|n*2M`T6PP6?TK)$D m|1EBAZad-G2cowj^(N7l!{JxM1({$v_d#0*}aI zppNSx%;=;sy8Er~7um-{DNB#rBZ^j@)7^RyDi6X~G<}4G~VF?=PtNteC{sX2!s9 X;GhCml4JO5ppguou6{1-oD!M QLabel { + color: rgb( 255, 255, 255 ); + font-size: 12px; + font-style: normal; + } + +/*SubWindow titlebar button */ +SubWindow > QPushButton { + background-color: rgba( 255, 255, 255, 0% ); + border-width: 0px; + border-color: none; + border-style: none; + } + +SubWindow > QPushButton:hover{ + background-color: rgba( 255, 255, 255, 15% ); + border-width: 1px; + border-color: rgba( 0, 0, 0, 20% ); + border-style: solid; + border-radius: 2px; + } + + /* Plugins */ TripleOscillatorView Knob { diff --git a/include/SubWindow.h b/include/SubWindow.h index 821e0a76201..f7446cea421 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -23,18 +23,19 @@ * Boston, MA 02110-1301 USA. * */ - - #ifndef SUBWINDOW_H #define SUBWINDOW_H - +#include +#include #include -#include +#include +#include +#include +#include #include "export.h" - class QMoveEvent; class QResizeEvent; class QWidget; @@ -43,16 +44,43 @@ class QWidget; class EXPORT SubWindow : public QMdiSubWindow { Q_OBJECT + Q_PROPERTY( QBrush activeColor READ activeColor WRITE setActiveColor ) + Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor ) + Q_PROPERTY( QColor borderColor READ borderColor WRITE setBorderColor ) + public: - SubWindow(QWidget *parent=NULL, Qt::WindowFlags windowFlags=0); + SubWindow( QWidget *parent = NULL, Qt::WindowFlags windowFlags = 0 ); // same as QWidet::normalGeometry, but works properly under X11 (see https://bugreports.qt.io/browse/QTBUG-256) QRect getTrueNormalGeometry() const; + QBrush activeColor() const; + QColor textShadowColor() const; + QColor borderColor() const; + void setActiveColor( const QBrush & b ); + void setTextShadowColor( const QColor &c ); + void setBorderColor( const QColor &c ); + protected: // hook the QWidget move/resize events to update the tracked geometry - virtual void moveEvent(QMoveEvent * event); - virtual void resizeEvent(QResizeEvent * event); + virtual void moveEvent( QMoveEvent * event ); + virtual void resizeEvent( QResizeEvent * event ); + virtual void paintEvent( QPaintEvent * pe ); + private: + const QSize m_buttonSize; + const int m_titleBarHeight; + QPushButton * m_closeBtn; + QPushButton * m_minimizeBtn; + QPushButton * m_maximizeBtn; + QPushButton * m_restoreBtn; + QBrush m_activeColor; + QColor m_textShadowColor; + QColor m_borderColor; + QPoint m_position; QRect m_trackedNormalGeom; + QLabel * m_windowTitle; + QGraphicsDropShadowEffect* m_shadow; + + static void elideText( QLabel *label, QString text ); }; -#endif \ No newline at end of file +#endif diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index cc29962534b..fc78e28a1e6 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -1,4 +1,4 @@ -/* +/* * SubWindow.cpp - Implementation of QMdiSubWindow that correctly tracks * the geometry that windows should be restored to. * Workaround for https://bugreports.qt.io/browse/QTBUG-256 @@ -26,42 +26,250 @@ #include "SubWindow.h" +#include #include #include -#include +#include "embed.h" -SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) - : QMdiSubWindow(parent, windowFlags) + +SubWindow::SubWindow( QWidget *parent, Qt::WindowFlags windowFlags ) : + QMdiSubWindow( parent, windowFlags ), + m_buttonSize( 17, 17 ), + m_titleBarHeight( 24 ) { // initialize the tracked geometry to whatever Qt thinks the normal geometry currently is. // this should always work, since QMdiSubWindows will not start as maximized m_trackedNormalGeom = normalGeometry(); + + // inits the colors + m_activeColor = Qt::SolidPattern; + m_textShadowColor = Qt::black; + m_borderColor = Qt::black; + + //close, minimize, maximize and restore(after minimize) buttons + m_closeBtn = new QPushButton( embed::getIconPixmap( "close" ), QString::null, this ); + m_closeBtn->resize( m_buttonSize ); + m_closeBtn->setFocusPolicy( Qt::NoFocus ); + m_closeBtn->setToolTip(tr( "Close" )); + connect( m_closeBtn, SIGNAL( clicked( bool ) ), this, SLOT( close() ) ); + + m_maximizeBtn = new QPushButton( embed::getIconPixmap( "maximize" ), QString::null, this ); + m_maximizeBtn->resize( m_buttonSize ); + m_maximizeBtn->setFocusPolicy( Qt::NoFocus ); + m_maximizeBtn->setToolTip( tr( "Maximize" ) ); + connect( m_maximizeBtn, SIGNAL( clicked( bool ) ), this, SLOT( showMaximized() ) ); + + m_minimizeBtn = new QPushButton( embed::getIconPixmap( "minimize" ), QString::null, this ); + m_minimizeBtn->resize( m_buttonSize ); + m_minimizeBtn->setFocusPolicy( Qt::NoFocus ); + m_minimizeBtn->setToolTip( tr( "Minimize" ) ); + connect( m_minimizeBtn, SIGNAL( clicked( bool ) ), this, SLOT( showMinimized() ) ); + + m_restoreBtn = new QPushButton( embed::getIconPixmap( "restore" ), QString::null, this ); + m_restoreBtn->resize( m_buttonSize ); + m_restoreBtn->setFocusPolicy( Qt::NoFocus ); + m_restoreBtn->setToolTip( tr( "Restore" ) ); + connect( m_restoreBtn, SIGNAL( clicked( bool ) ), this, SLOT( showNormal() ) ); + + // QLabel for window title and shadow effect + m_shadow = new QGraphicsDropShadowEffect(); + m_shadow->setColor( m_textShadowColor ); + m_shadow->setXOffset( 1 ); + m_shadow->setYOffset( 1 ); + + m_windowTitle = new QLabel( this ); + m_windowTitle->setFocusPolicy( Qt::NoFocus ); + m_windowTitle->setGraphicsEffect( m_shadow ); +} + + + + +void SubWindow::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + QRect rect( 0, 0, width(), m_titleBarHeight ); + bool isActive = SubWindow::mdiArea()->activeSubWindow() == this; + + p.fillRect( rect, isActive ? activeColor() : p.pen().brush() ); + + // window border + p.setPen( borderColor() ); + + // bottom, left, and right lines + p.drawLine( 0, height() - 1, width(), height() - 1 ); + p.drawLine( 0, m_titleBarHeight, 0, height() - 1 ); + p.drawLine( width() - 1, m_titleBarHeight, width() - 1, height() - 1 ); + + //window icon + QPixmap winicon( widget()->windowIcon().pixmap( m_buttonSize ) ); + p.drawPixmap( 3, 3, m_buttonSize.width(), m_buttonSize.height(), winicon ); +} + + + + +void SubWindow::elideText( QLabel *label, QString text ) +{ + QFontMetrics metrix( label->font() ); + int width = label->width() - 2; + QString clippedText = metrix.elidedText( text, Qt::ElideRight, width ); + label->setText( clippedText ); } + + + QRect SubWindow::getTrueNormalGeometry() const { return m_trackedNormalGeom; } -void SubWindow::moveEvent(QMoveEvent * event) + + + +QBrush SubWindow::activeColor() const +{ + return m_activeColor; +} + + + + +QColor SubWindow::textShadowColor() const +{ + return m_textShadowColor; +} + + + + +QColor SubWindow::borderColor() const { - QMdiSubWindow::moveEvent(event); + return m_borderColor; +} + + + + +void SubWindow::setActiveColor( const QBrush & b ) +{ + m_activeColor = b; +} + + + + +void SubWindow::setTextShadowColor( const QColor & c ) +{ + m_textShadowColor = c; +} + + + + +void SubWindow::setBorderColor( const QColor &c ) +{ + m_borderColor = c; +} + + + + +void SubWindow::moveEvent( QMoveEvent * event ) +{ + QMdiSubWindow::moveEvent( event ); // if the window was moved and ISN'T minimized/maximized/fullscreen, // then save the current position - if (!isMaximized() && !isMinimized() && !isFullScreen()) + if( !isMaximized() && !isMinimized() && !isFullScreen() ) { - m_trackedNormalGeom.moveTopLeft(event->pos()); + m_trackedNormalGeom.moveTopLeft( event->pos() ); } } -void SubWindow::resizeEvent(QResizeEvent * event) + + + +void SubWindow::resizeEvent( QResizeEvent * event ) { - QMdiSubWindow::resizeEvent(event); + /* button adjustments*/ + m_minimizeBtn->hide(); + m_maximizeBtn->hide(); + m_restoreBtn->hide(); + + const int rightSpace = 3; + const int buttonGap = 1; + const int menuButtonSpace = 24; + + QPoint rightButtonPos( width() - rightSpace - m_buttonSize.width() , 3 ); + QPoint middleButtonPos( width() - rightSpace - ( 2 * m_buttonSize.width() ) - buttonGap, 3 ); + QPoint leftButtonPos( width() - rightSpace - ( 3 * m_buttonSize.width() ) - ( 2 * buttonGap ), 3 ); + + //The buttonBarWidth relates on the count of button. + //We need it to calculate the width of window title label + int buttonBarWidth = rightSpace + m_buttonSize.width(); + + //set the buttons on their positions. + //the close button is ever needed and on the rightButtonPos + m_closeBtn->move( rightButtonPos ); + + //here we ask: is the Subwindow maximizable and/or minimizable + //then we set the buttons and show them if needed + if( windowFlags() & Qt::WindowMaximizeButtonHint ) + { + buttonBarWidth = buttonBarWidth + m_buttonSize.width() + buttonGap; + m_maximizeBtn->move( middleButtonPos ); + m_maximizeBtn->show(); + } + if( windowFlags() & Qt::WindowMinimizeButtonHint ) + { + buttonBarWidth = buttonBarWidth + m_buttonSize.width() + buttonGap; + if( m_maximizeBtn->isHidden() ) + { + m_minimizeBtn->move( middleButtonPos ); + } + else + { + m_minimizeBtn->move( leftButtonPos ); + } + m_minimizeBtn->show(); + m_restoreBtn->hide(); + if( isMinimized() ) + { + if( m_maximizeBtn->isHidden() ) + { + m_restoreBtn->move( middleButtonPos ); + } + else + { + m_restoreBtn->move( leftButtonPos ); + } + m_restoreBtn->show(); + m_minimizeBtn->hide(); + } + } + + // title QLabel adjustments + m_windowTitle->setAlignment( Qt::AlignHCenter ); + m_windowTitle->setFixedWidth( widget()->width() - ( menuButtonSpace + buttonBarWidth ) ); + m_windowTitle->move( menuButtonSpace, ( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 ); + // if minimized we can't use widget()->width(). We have to set the width hard coded + // the width of all minimized windows is the same. + if( isMinimized() ) + { + m_windowTitle->setFixedWidth( 120 ); + } + // for truncate the Label String if the window is to small. Adds "..." + elideText( m_windowTitle, widget()->windowTitle() ); + m_windowTitle->setTextInteractionFlags( Qt::NoTextInteraction ); + m_windowTitle->adjustSize(); + + QMdiSubWindow::resizeEvent( event ); // if the window was resized and ISN'T minimized/maximized/fullscreen, // then save the current size - if (!isMaximized() && !isMinimized() && !isFullScreen()) + if( !isMaximized() && !isMinimized() && !isFullScreen() ) { - m_trackedNormalGeom.setSize(event->size()); + m_trackedNormalGeom.setSize( event->size() ); } -} \ No newline at end of file +} From 4fd8fce60d423ce795e8191567b254d2e22cc16f Mon Sep 17 00:00:00 2001 From: Umcaruje Date: Mon, 2 May 2016 17:19:36 +0200 Subject: [PATCH 2/2] Styling changes for the subwindow decoration --- data/themes/default/style.css | 16 +++++++------- include/SubWindow.h | 2 +- src/gui/SubWindow.cpp | 39 ++++++++++++++++++++--------------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 7df202e4917..2bc7b8ca312 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -409,8 +409,8 @@ QToolButton#stopButton { /* all tool buttons */ QToolButton:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #c0cdd3, stop:1 #71797d); - color: white; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #c0cdd3, stop:1 #71797d); + color: white; } QToolButton:pressed { @@ -540,7 +540,7 @@ BBTCOView { qproperty-textColor: rgb( 255, 255, 255 ); } -/* subwindows in MDI-Area */ +/* Subwindows in MDI-Area */ SubWindow { color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4b525c, stop: 1.0 #31363d); @@ -550,20 +550,20 @@ SubWindow { qproperty-borderColor: rgb( 0, 0, 0 ); } -/*SubWindow Title Text */ +/* Subwindow title text */ SubWindow > QLabel { color: rgb( 255, 255, 255 ); font-size: 12px; font-style: normal; - } +} -/*SubWindow titlebar button */ +/* SubWindow titlebar button */ SubWindow > QPushButton { background-color: rgba( 255, 255, 255, 0% ); border-width: 0px; border-color: none; border-style: none; - } +} SubWindow > QPushButton:hover{ background-color: rgba( 255, 255, 255, 15% ); @@ -571,7 +571,7 @@ SubWindow > QPushButton:hover{ border-color: rgba( 0, 0, 0, 20% ); border-style: solid; border-radius: 2px; - } +} /* Plugins */ diff --git a/include/SubWindow.h b/include/SubWindow.h index f7446cea421..9e43e334530 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -78,7 +78,7 @@ class EXPORT SubWindow : public QMdiSubWindow QPoint m_position; QRect m_trackedNormalGeom; QLabel * m_windowTitle; - QGraphicsDropShadowEffect* m_shadow; + QGraphicsDropShadowEffect * m_shadow; static void elideText( QLabel *label, QString text ); }; diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index fc78e28a1e6..fb01a10ae76 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -47,11 +47,11 @@ SubWindow::SubWindow( QWidget *parent, Qt::WindowFlags windowFlags ) : m_textShadowColor = Qt::black; m_borderColor = Qt::black; - //close, minimize, maximize and restore(after minimize) buttons + // close, minimize, maximize and restore (after minimizing) buttons m_closeBtn = new QPushButton( embed::getIconPixmap( "close" ), QString::null, this ); m_closeBtn->resize( m_buttonSize ); m_closeBtn->setFocusPolicy( Qt::NoFocus ); - m_closeBtn->setToolTip(tr( "Close" )); + m_closeBtn->setToolTip( tr( "Close" ) ); connect( m_closeBtn, SIGNAL( clicked( bool ) ), this, SLOT( close() ) ); m_maximizeBtn = new QPushButton( embed::getIconPixmap( "maximize" ), QString::null, this ); @@ -72,7 +72,7 @@ SubWindow::SubWindow( QWidget *parent, Qt::WindowFlags windowFlags ) : m_restoreBtn->setToolTip( tr( "Restore" ) ); connect( m_restoreBtn, SIGNAL( clicked( bool ) ), this, SLOT( showNormal() ) ); - // QLabel for window title and shadow effect + // QLabel for the window title and the shadow effect m_shadow = new QGraphicsDropShadowEffect(); m_shadow->setColor( m_textShadowColor ); m_shadow->setXOffset( 1 ); @@ -102,7 +102,7 @@ void SubWindow::paintEvent( QPaintEvent * ) p.drawLine( 0, m_titleBarHeight, 0, height() - 1 ); p.drawLine( width() - 1, m_titleBarHeight, width() - 1, height() - 1 ); - //window icon + // window icon QPixmap winicon( widget()->windowIcon().pixmap( m_buttonSize ) ); p.drawPixmap( 3, 3, m_buttonSize.width(), m_buttonSize.height(), winicon ); } @@ -181,7 +181,7 @@ void SubWindow::moveEvent( QMoveEvent * event ) { QMdiSubWindow::moveEvent( event ); // if the window was moved and ISN'T minimized/maximized/fullscreen, - // then save the current position + // then save the current position if( !isMaximized() && !isMinimized() && !isFullScreen() ) { m_trackedNormalGeom.moveTopLeft( event->pos() ); @@ -193,7 +193,7 @@ void SubWindow::moveEvent( QMoveEvent * event ) void SubWindow::resizeEvent( QResizeEvent * event ) { - /* button adjustments*/ + // button adjustments m_minimizeBtn->hide(); m_maximizeBtn->hide(); m_restoreBtn->hide(); @@ -206,22 +206,23 @@ void SubWindow::resizeEvent( QResizeEvent * event ) QPoint middleButtonPos( width() - rightSpace - ( 2 * m_buttonSize.width() ) - buttonGap, 3 ); QPoint leftButtonPos( width() - rightSpace - ( 3 * m_buttonSize.width() ) - ( 2 * buttonGap ), 3 ); - //The buttonBarWidth relates on the count of button. - //We need it to calculate the width of window title label + // the buttonBarWidth depends on the number of buttons. + // we need it to calculate the width of window title label int buttonBarWidth = rightSpace + m_buttonSize.width(); - //set the buttons on their positions. - //the close button is ever needed and on the rightButtonPos + // set the buttons on their positions. + // the close button is always needed and on the rightButtonPos m_closeBtn->move( rightButtonPos ); - //here we ask: is the Subwindow maximizable and/or minimizable - //then we set the buttons and show them if needed + // here we ask: is the Subwindow maximizable and/or minimizable + // then we set the buttons and show them if needed if( windowFlags() & Qt::WindowMaximizeButtonHint ) { buttonBarWidth = buttonBarWidth + m_buttonSize.width() + buttonGap; m_maximizeBtn->move( middleButtonPos ); m_maximizeBtn->show(); } + if( windowFlags() & Qt::WindowMinimizeButtonHint ) { buttonBarWidth = buttonBarWidth + m_buttonSize.width() + buttonGap; @@ -253,21 +254,25 @@ void SubWindow::resizeEvent( QResizeEvent * event ) // title QLabel adjustments m_windowTitle->setAlignment( Qt::AlignHCenter ); m_windowTitle->setFixedWidth( widget()->width() - ( menuButtonSpace + buttonBarWidth ) ); - m_windowTitle->move( menuButtonSpace, ( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 ); - // if minimized we can't use widget()->width(). We have to set the width hard coded - // the width of all minimized windows is the same. + m_windowTitle->move( menuButtonSpace, + ( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 ); + + // if minimized we can't use widget()->width(). We have to hard code the width, + // as the width of all minimized windows is the same. if( isMinimized() ) { m_windowTitle->setFixedWidth( 120 ); } - // for truncate the Label String if the window is to small. Adds "..." + + // truncate the label string if the window is to small. Adds "..." elideText( m_windowTitle, widget()->windowTitle() ); m_windowTitle->setTextInteractionFlags( Qt::NoTextInteraction ); m_windowTitle->adjustSize(); QMdiSubWindow::resizeEvent( event ); + // if the window was resized and ISN'T minimized/maximized/fullscreen, - // then save the current size + // then save the current size if( !isMaximized() && !isMinimized() && !isFullScreen() ) { m_trackedNormalGeom.setSize( event->size() );