Skip to content

Commit

Permalink
Add a new window decoration to MDISubWindows
Browse files Browse the repository at this point in the history
  • Loading branch information
BaraMGB committed May 2, 2016
1 parent baaed6a commit 47f5b25
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 24 deletions.
Binary file added data/themes/default/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/themes/default/maximize.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/themes/default/minimize.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/themes/default/restore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 36 additions & 2 deletions data/themes/default/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -540,6 +540,40 @@ BBTCOView {
qproperty-textColor: rgb( 255, 255, 255 );
}

/* subwindows in MDI-Area */
SubWindow {
color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #4b525c, stop: 1.0 #31363d);
qproperty-activeColor: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #33383e, stop: 1.0 #1a1c20);
qproperty-textShadowColor: rgb( 0, 0, 0 );
qproperty-borderColor: rgb( 0, 0, 0 );
}

/*SubWindow Title Text */
SubWindow > 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 {
Expand Down
46 changes: 37 additions & 9 deletions include/SubWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@
* Boston, MA 02110-1301 USA.
*
*/


#ifndef SUBWINDOW_H
#define SUBWINDOW_H


#include <QEvent>
#include <QGraphicsDropShadowEffect>
#include <QMdiSubWindow>
#include <QRect>
#include <QLabel>
#include <QPainter>
#include <QPushButton>
#include <QString>

#include "export.h"


class QMoveEvent;
class QResizeEvent;
class QWidget;
Expand All @@ -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
#endif
234 changes: 221 additions & 13 deletions src/gui/SubWindow.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -26,42 +26,250 @@

#include "SubWindow.h"

#include <QMdiArea>
#include <QMoveEvent>
#include <QResizeEvent>
#include <QWidget>

#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() );
}
}
}

0 comments on commit 47f5b25

Please sign in to comment.