Commit aba99267 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD #254] generic action titlebar for dock widgets

parent 8e612e85
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include "../WQt4Gui.h"
#include "../WMainWindow.h"
#include "WQtDockTitleWidget.h"
#include "WQtDockTitleWidget.moc"
WQtDockTitleWidget::WQtDockTitleWidget( QDockWidget* parent ):
QWidget( parent ),
dockParent( parent )
{
construct();
}
void WQtDockTitleWidget::setupButton( QToolButton* btn )
{
btn->setToolButtonStyle( Qt::ToolButtonIconOnly );
btn->setContentsMargins( 0, 0, 0, 0 );
btn->setFixedHeight( 24 );
btn->setAutoRaise( true );
btn->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
}
void WQtDockTitleWidget::construct()
{
// create titlebar widget and its layout
QHBoxLayout* titleWidgetLayout = new QHBoxLayout( this );
titleWidgetLayout->setMargin( 0 );
titleWidgetLayout->setSpacing( 0 );
setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed ) );
// title
m_title = new WScaleLabel( " " + dockParent->windowTitle(), 3, this );
m_title->setTextInteractionFlags( Qt::NoTextInteraction );
// close Btn
m_closeBtn = new QToolButton( this );
QAction* closeAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "popup_close" ), "Close", this );
connect( closeAction, SIGNAL( triggered( bool ) ), dockParent, SLOT( close() ) );
m_closeBtn->setDefaultAction( closeAction );
setupButton( m_closeBtn );
m_closeBtn->setMinimumSize( 24, 24 );
m_closeBtn->setMaximumSize( 24, 24 );
// create the container for the actions shown in the titlebar directly
m_tools = new QWidget( this );
m_toolsLayout = new QHBoxLayout( m_tools );
m_tools->setLayout( m_toolsLayout );
m_tools->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
m_toolsLayout->setMargin( 0 );
m_toolsLayout->setSpacing( 0 );
m_tools->setContentsMargins( 0, 0, 0, 0 );
m_tools->setMinimumSize( 1, 24 );
// create the container for the actions dropped out the titlebar to save some space
m_toolsMenu = new QWidget( this );
m_toolsMenuLayout = new QHBoxLayout( m_toolsMenu );
m_toolsMenu->setLayout( m_toolsMenuLayout );
m_toolsMenuLayout->setMargin( 0 );
m_toolsMenuLayout->setSpacing( 0 );
m_toolsMenu->setContentsMargins( 0, 0, 0, 0 );
// create a button that shows the m_toolsMenu container widget
m_moreBtn = new QToolButton( this );
m_moreBtn->setHidden( true );
setupButton( m_moreBtn );
m_moreBtn->setPopupMode( QToolButton::InstantPopup );
m_moreBtn->setIcon( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "popup_more" ) );
QMenu* moreMenu = new QMenu();
QWidgetAction* moreAction = new QWidgetAction( m_toolsMenu );
moreAction->setDefaultWidget( m_toolsMenu );
moreMenu->addAction( moreAction );
m_moreBtn->setMenu( moreMenu );
// fill layout
titleWidgetLayout->addWidget( m_title );
titleWidgetLayout->addStretch( 100000 );
titleWidgetLayout->addWidget( m_tools );
titleWidgetLayout->addWidget( m_moreBtn );
titleWidgetLayout->addWidget( m_closeBtn );
}
void WQtDockTitleWidget::resizeEvent( QResizeEvent* event )
{
updateLayouts( event->size().width() );
}
void WQtDockTitleWidget::addTitleAction( QAction* action, bool instantPopup )
{
QToolButton* actionBtn = new QToolButton( this );
actionBtn->setDefaultAction( action );
setupButton( actionBtn );
if( instantPopup )
{
actionBtn->setPopupMode( QToolButton::InstantPopup );
}
// we keep track of the widgets:
m_titleActionWidgets.push_back( actionBtn );
// update the layouts
updateLayouts( width() );
}
void WQtDockTitleWidget::removeTitleAction( QAction* action )
{
// find the widget for this action
QToolButton* btn = NULL;
for( QList< QWidget* >::iterator i = m_titleActionWidgets.begin(); i != m_titleActionWidgets.end(); ++i )
{
QToolButton* btnCandidate = dynamic_cast< QToolButton* >( *i );
if( btnCandidate && ( btnCandidate->defaultAction() == action ) )
{
btn = btnCandidate;
}
}
// found?
if( btn )
{
m_toolsLayout->removeWidget( btn );
m_toolsMenuLayout->removeWidget( btn );
m_titleActionWidgets.removeAll( btn );
// update the layouts
updateLayouts( width() );
}
}
void WQtDockTitleWidget::addTitleSeperator()
{
// use a qframe
QFrame* line = new QFrame();
line->setFrameShape( QFrame::VLine );
line->setFrameShadow( QFrame::Sunken );
// add it
m_titleActionWidgets.push_back( line );
// update the layouts
updateLayouts( width() );
}
void WQtDockTitleWidget::updateLayouts( int width )
{
// calc the size of widgets and the title and the mandatory close button
int minRequired = m_title->calculateSize( m_title->text().length() ) + m_moreBtn->sizeHint().width() + m_closeBtn->sizeHint().width();
// check and move items
int curWidth = minRequired;
QList< QWidget* > visible;
QList< QWidget* > hidden;
QList< QWidget* >* currentList = &visible;
for( QList< QWidget* >::iterator i = m_titleActionWidgets.begin(); i != m_titleActionWidgets.end(); ++i )
{
if( curWidth > width )
{
// we reached the size limit.
currentList = &hidden;
}
currentList->push_back( *i );
curWidth += ( *i )->sizeHint().width();
}
// move all visible items to the m_toolsLayout
for( QList< QWidget* >::iterator i = visible.begin(); i != visible.end(); ++i )
{
m_toolsMenuLayout->removeWidget( *i );
m_toolsLayout->addWidget( *i );
}
// move all visible items to the m_toolsMenuLayout
for( QList< QWidget* >::iterator i = hidden.begin(); i != hidden.end(); ++i )
{
m_toolsLayout->removeWidget( *i );
m_toolsMenuLayout->addWidget( *i );
}
// hide more button if nothing needs to be hiden
m_moreBtn->setHidden( !( hidden.size() ) );
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WQTDOCKTITLEWIDGET_H
#define WQTDOCKTITLEWIDGET_H
#include <QtGui/QDockWidget>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QToolButton>
#include <QtGui/QLabel>
#include <QtGui/QResizeEvent>
#include <QtGui/QWidgetAction>
#include "WScaleLabel.h"
/**
* Class for managing dock widget title bars.
*/
class WQtDockTitleWidget: public QWidget
{
Q_OBJECT
public:
/**
* Constructor.
*
* \param parent the parent
*/
WQtDockTitleWidget( QDockWidget* parent );
/**
* Add the given action to the titlebar. It gets added after the previously added ones.
*
* \param action the action to add.
* \param instantPopup if true, the button does not trigger an action. Instead, it directly opens the menu.
*/
virtual void addTitleAction( QAction* action, bool instantPopup = false );
/**
* Remove the given action from the list
*
* \param action the action to add
*/
virtual void removeTitleAction( QAction* action );
/**
* Add a separator.
*/
virtual void addTitleSeperator();
protected:
/**
* Called upon resize. Used to switch between the more menu and the tools widget
*
* \param event the event
*/
virtual void resizeEvent( QResizeEvent* event );
/**
* Apply default settings for dock widget title buttons.
*
* \param btn the button to setup
*/
virtual void setupButton( QToolButton* btn );
private:
/**
* Construct the title and configure the widget.
*/
void construct();
/**
* Updates the layouts according to the new width
*
* \param width the new width.
*/
void updateLayouts( int width );
/**
* The tools buttons
*/
QWidget* m_tools;
/**
* The tool inside the menu
*/
QWidget* m_toolsMenu;
/**
* Layout containing the tools
*/
QHBoxLayout* m_toolsLayout;
/**
* The tool button used when shrinking the title bar too much
*/
QToolButton* m_moreBtn;
/**
* LAyout of the items in the moreBtn menu
*/
QHBoxLayout* m_toolsMenuLayout;
/**
* Title label
*/
WScaleLabel* m_title;
/**
* Close button
*/
QToolButton* m_closeBtn;
/**
* The parent as dock pointer
*/
QDockWidget* dockParent;
/**
* We keep track of the widgets that we add
*/
QList< QWidget* > m_titleActionWidgets;
};
#endif // WQTDOCKTITLEWIDGET_H
......@@ -25,19 +25,33 @@
#include "../WQt4Gui.h"
#include "../WMainWindow.h"
#include "WQtDockTitleWidget.h"
#include "WQtDockWidget.h"
#include "WQtDockWidget.moc"
WQtDockWidget::WQtDockWidget( const QString& title, QWidget* parent, Qt::WindowFlags flags ):
QDockWidget( title, parent, flags )
{
construct();
// thats it. we now have the title bar
m_titleBar = new WQtDockTitleWidget( this );
setTitleBarWidget( m_titleBar );
// some standard dock features
setAllowedAreas( Qt::AllDockWidgetAreas );
setFeatures( QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
}
WQtDockWidget::WQtDockWidget( QWidget* parent, Qt::WindowFlags flags ):
QDockWidget( parent, flags )
{
construct();
// thats it. we now have the title bar
m_titleBar = new WQtDockTitleWidget( this );
setTitleBarWidget( m_titleBar );
// some standard dock features
setAllowedAreas( Qt::AllDockWidgetAreas );
setFeatures( QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
}
WQtDockWidget::~WQtDockWidget()
......@@ -45,79 +59,17 @@ WQtDockWidget::~WQtDockWidget()
// cleanup
}
void WQtDockWidget::setupButton( QToolButton* btn )
void WQtDockWidget::addTitleAction( QAction* action, bool instantPopup )
{
btn->setToolButtonStyle( Qt::ToolButtonIconOnly );
btn->setContentsMargins( 0, 0, 0, 0 );
btn->setFixedHeight( 24 );
btn->setAutoRaise( true );
btn->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
m_titleBar->addTitleAction( action, instantPopup );
}
void WQtDockWidget::construct()
void WQtDockWidget::removeTitleAction( QAction* action )
{
// some standard dock features
setAllowedAreas( Qt::AllDockWidgetAreas );
setFeatures( QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
// create titlebar widget and its layout
m_titleWidget = new QWidget( this );
QHBoxLayout* titleWidgetLayout = new QHBoxLayout( m_titleWidget );
titleWidgetLayout->setMargin( 0 );
titleWidgetLayout->setSpacing( 0 );
m_titleWidget->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed ) );
// title
m_title = new WScaleLabel( " " + windowTitle(), 3, m_titleWidget );
m_title->setTextInteractionFlags( Qt::NoTextInteraction );
// close Btn
m_closeBtn = new QToolButton( m_titleWidget );
QAction* closeAction = new QAction( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "popup_close" ), "Close", m_titleWidget );
connect( closeAction, SIGNAL( triggered( bool ) ), this, SLOT( close() ) );
m_closeBtn->setDefaultAction( closeAction );
setupButton( m_closeBtn );
m_closeBtn->setMinimumSize( 24, 24 );
m_closeBtn->setMaximumSize( 24, 24 );
// create the container for the actions shown in the titlebar directly
m_tools = new QWidget( m_titleWidget );
m_toolsLayout = new QHBoxLayout( m_tools );
m_tools->setLayout( m_toolsLayout );
m_tools->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
m_toolsLayout->setMargin( 0 );
m_toolsLayout->setSpacing( 0 );
m_tools->setContentsMargins( 0, 0, 0, 0 );
m_tools->setMinimumSize( 1, 24 );
// create the container for the actions dropped out the titlebar to save some space
m_toolsMenu = new QWidget( m_titleWidget );
QHBoxLayout* toolsMenuLayout = new QHBoxLayout( m_toolsMenu );
m_toolsMenu->setLayout( toolsMenuLayout );
toolsMenuLayout->setMargin( 0 );
toolsMenuLayout->setSpacing( 0 );
m_toolsMenu->setContentsMargins( 0, 0, 0, 0 );
// create a button that shows the m_toolsMenu container widget
m_moreBtn = new QToolButton( m_titleWidget );
m_moreBtn->setHidden( true );
setupButton( m_moreBtn );
m_moreBtn->setPopupMode( QToolButton::InstantPopup );
m_moreBtn->setIcon( WQt4Gui::getMainWindow()->getIconManager()->getIcon( "popup_more" ) );
QMenu* moreMenu = new QMenu();
QWidgetAction* moreAction = new QWidgetAction( m_toolsMenu );
moreAction->setDefaultWidget( m_toolsMenu );
moreMenu->addAction( moreAction );
m_moreBtn->setMenu( moreMenu );
// fill layout
titleWidgetLayout->addWidget( m_title );
titleWidgetLayout->addStretch( 100000 );
titleWidgetLayout->addWidget( m_tools );
titleWidgetLayout->addWidget( m_moreBtn );
titleWidgetLayout->addWidget( m_closeBtn );
// thats it. we now have the title bar
setTitleBarWidget( m_titleWidget );
m_titleBar->removeTitleAction( action );
}
void WQtDockWidget::addTitleSeperator()
{
m_titleBar->addTitleSeperator();
}
......@@ -35,6 +35,11 @@
#include "WScaleLabel.h"
/**
* Used for the title bar.
*/
class WQtDockTitleWidget;
/**
* Advanced QDockWidget. This class allows you to add actions to the titlebar of the dock widget
*/
......@@ -64,54 +69,32 @@ public:
*/
virtual ~WQtDockWidget();
protected:
/**
* Apply default settings for dock widget title buttons.
* Add the given action to the titlebar. It gets added after the previously added ones.
*
* \param btn the button to setup
*/
virtual void setupButton( QToolButton* btn );
private:
/**
* Construct the title and configure the widget.
*/
void construct();
/**
* The title of this dock
* \param action the action to add.
* \param instantPopup if true, the button does not trigger an action. Instead, it directly opens the menu.
*/
QWidget* m_titleWidget;
virtual void addTitleAction( QAction* action, bool instantPopup = false );
/**
* The tools buttons
*/
QWidget* m_tools;
/**
* The tool inside the menu
*/
QWidget* m_toolsMenu;
/**
* Layout containing the tools
*/
QHBoxLayout* m_toolsLayout;
/**
* The tool button used when shrinking the title bar too much
* Remove the given action from the list
*
* \param action the action to add
*/
QToolButton* m_moreBtn;
virtual void removeTitleAction( QAction* action );
/**
* Title label
* Add a separator.
*/
WScaleLabel* m_title;
virtual void addTitleSeperator();
protected:
private:
/**
* Close button
* Title widget.
*/
QToolButton* m_closeBtn;
WQtDockTitleWidget* m_titleBar;
};
#endif // WQTDOCKWIDGET_H
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment