some work on a better widget layouting and more usable splitters in combination with CollapsibleWidgets

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1915 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-12-14 01:03:28 +00:00
parent 7e7b5924a6
commit ee58a2db6b
8 changed files with 235 additions and 101 deletions

View File

@@ -1,10 +1,20 @@
2008-12-14 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* src/core/main.cpp:
* include/fluiq/collapsible_widget.h:
* include/fluiq/splitter.h:
* include/fluiq/workspace.h:
* src/gui/fluiq/collapsible_widget.cpp:
* src/gui/fluiq/splitter.cpp:
* src/gui/fluiq/widget_container.cpp:
* src/gui/fluiq/workspace.cpp:
some work on a better widget layouting and more usable splitters in
combination with CollapsibleWidgets
* src/core/config_mgr.cpp:
* src/core/main.cpp:
* src/core/mmp.cpp:
* src/gui/main_window.cpp:
* src/gui/about_dialog.cpp:
* src/gui/main_window.cpp:
* lmmsversion.h.in:
* CMakeLists.txt:
moved version information into separate header file to avoid

View File

@@ -52,6 +52,7 @@ public:
virtual QSize sizeHint( void ) const;
static const int MinimalHeight = 20;
protected:
virtual void enterEvent( QEvent * _ev );
@@ -92,21 +93,16 @@ public:
void addWidget( QWidget * _w );
void insertWidget( int _idx, QWidget * _w );
inline QString labelText( void ) const
{
return m_header->windowTitle();
}
inline void setLabelText( const QString & _text )
{
m_header->setWindowTitle( _text );
}
inline Qt::Orientation orientation( void ) const
{
return m_orientation;
}
inline bool isCollapsed( void ) const
{
return m_header->isCollapsed();
}
public slots:
void expand( void );
@@ -115,6 +111,8 @@ public slots:
private:
Qt::Orientation m_orientation;
QSize m_origMinSize;
QSize m_origMaxSize;
QBoxLayout * m_masterLayout;
CollapsibleWidgetHeader * m_header;

View File

@@ -25,36 +25,42 @@
#ifndef _FLUIQ_SPLITTER_H
#define _FLUIQ_SPLITTER_H
#include <QtGui/QSplitter>
#include <QtGui/QWidget>
class QBoxLayout;
namespace FLUIQ
{
class Splitter : public QSplitter
class Splitter : public QWidget
{
Q_OBJECT
public:
Splitter( Qt::Orientation _o, QWidget * _parent = NULL );
virtual ~Splitter();
void addWidget( QWidget * _widget );
protected:
QSplitterHandle * createHandle( void );
int indexOf( QWidget * _widget ) const;
QWidget * widget( int _idx );
} ;
int count( void ) const
{
return m_children.count();
}
Qt::Orientation orientation( void ) const
{
return m_orientation;
}
class SplitterHandle : public QSplitterHandle
{
public:
SplitterHandle( Qt::Orientation _o, QSplitter * _parent );
virtual ~SplitterHandle();
protected:
void paintEvent( QPaintEvent * _event );
private:
Qt::Orientation m_orientation;
QList<QWidget *> m_children;
QBoxLayout * m_mainLayout;
} ;

View File

@@ -43,7 +43,6 @@ public:
virtual ~Workspace();
void addWidget( QWidget * _w );
void addWidgetToExistingRow( QWidget * _w );
private:

View File

@@ -28,14 +28,13 @@
#include <QtGui/QPainter>
#include "fluiq/collapsible_widget.h"
#include "fluiq/splitter.h"
#include "embed.h"
// implementation of FLUIQ::CollapsibleWidgetHeader
const int HEADER_MIN_HEIGHT = 20;
FLUIQ::CollapsibleWidgetHeader::CollapsibleWidgetHeader(
CollapsibleWidget * _parent ) :
Widget( _parent ),
@@ -55,11 +54,11 @@ FLUIQ::CollapsibleWidgetHeader::CollapsibleWidgetHeader(
if( m_parent->orientation() == Qt::Horizontal )
{
setFixedWidth( HEADER_MIN_HEIGHT );
setFixedWidth( MinimalHeight );
}
else
{
setFixedHeight( HEADER_MIN_HEIGHT );
setFixedHeight( MinimalHeight );
}
}
@@ -89,12 +88,14 @@ QSize FLUIQ::CollapsibleWidgetHeader::sizeHint( void ) const
{
if( m_parent->orientation() == Qt::Horizontal )
{
return QSize( HEADER_MIN_HEIGHT,
HEADER_MIN_HEIGHT +
fontMetrics().width( windowTitle() ) );
return QSize( MinimalHeight,
MinimalHeight +
fontMetrics().width(
m_parent->windowTitle() ) );
}
return QSize( HEADER_MIN_HEIGHT + fontMetrics().width( windowTitle() ),
HEADER_MIN_HEIGHT );
return QSize( MinimalHeight +
fontMetrics().width( m_parent->windowTitle() ),
MinimalHeight );
}
@@ -131,7 +132,7 @@ void FLUIQ::CollapsibleWidgetHeader::mousePressEvent( QMouseEvent * _ev )
Qt::SizeVerCursor : Qt::SizeHorCursor );
m_pressed = true;
m_moved = false;
m_origMousePos = _ev->pos();
m_origMousePos = _ev->globalPos();
update();
_ev->accept();
}
@@ -150,20 +151,72 @@ void FLUIQ::CollapsibleWidgetHeader::mouseMoveEvent( QMouseEvent * _event )
{
m_moved = true;
QSize ms = m_parent->minimumSize();
QPoint pos = _event->globalPos();
if( m_parent->orientation() == Qt::Vertical )
Splitter * s = NULL;
if( m_parent->parentWidget() &&
( s = qobject_cast<Splitter *>
( m_parent->parentWidget() ) ) )
{
const int dy = _event->y() - m_origMousePos.y();
ms.setHeight( qMax( 0, ms.height() + dy ) );
int idx = s->indexOf( m_parent );
QWidget * sibling = NULL;
CollapsibleWidget * collapsibleSibling;
// look whether we have expanded left-hand siblings
while( idx > 0 && sibling == NULL )
{
--idx;
sibling = s->widget( idx );
collapsibleSibling =
qobject_cast<CollapsibleWidget *>(
sibling );
if( collapsibleSibling &&
collapsibleSibling->isCollapsed() )
{
sibling = NULL;
}
}
// found one?
if( sibling )
{
QSize minSizeHint = sibling->minimumSizeHint();
QSize sizeHint = sibling->sizeHint();
QSize minSize = sibling->size();
QSize maxSize = sibling->maximumSize();
// then increase size according to orientation
if( m_parent->orientation() == Qt::Vertical )
{
const int dy = pos.y() - m_origMousePos.y();
minSize.setHeight( qMax( minSizeHint.height(), minSize.height() + dy ) );
// implement snapping when reaching size hint
if( dy < 0 && ( ( minSize.height() < sizeHint.height() &&
sizeHint.height() - minSize.height() < 20 )
|| ( sibling->size().height() == minSize.height() ) ) )
{
return;
}
maxSize.setHeight( minSize.height() );
}
else
{
const int dx = pos.x() - m_origMousePos.x();
minSize.setWidth( qMax( minSizeHint.width(), minSize.width() + dx ) );
// implement snapping when reaching size hint
if( dx < 0 && ( ( minSize.width() < sizeHint.width() &&
sizeHint.width() - minSize.width() < 20 )
|| ( sibling->size().width() == minSize.width() ) ) )
{
return;
}
maxSize.setWidth( minSize.width() );
}
sibling->setMinimumSize( minSize );
sibling->setMaximumSize( maxSize );
s->updateGeometry();
}
m_origMousePos = pos;
}
else
{
const int dx = _event->x() - m_origMousePos.x();
ms.setWidth( qMax( 0, ms.width() + dx ) );
}
m_parent->setMinimumSize( ms );
m_origMousePos = _event->pos();
}
}
@@ -226,7 +279,8 @@ void FLUIQ::CollapsibleWidgetHeader::paintEvent( QPaintEvent * _ev )
p.setPen( palette().color( QPalette::Text ) );
p.drawPixmap( 8, 5, m_collapsed ? m_arrowCollapsed : m_arrowExpanded );
p.drawText( 20, 10+r.height()-p.fontMetrics().height(), windowTitle() );
p.drawText( 20, 10+r.height()-p.fontMetrics().height(),
m_parent->windowTitle() );
}
@@ -241,6 +295,8 @@ FLUIQ::CollapsibleWidget::CollapsibleWidget( Qt::Orientation _or,
Widget * _parent ) :
Widget( _parent ),
m_orientation( _or ),
m_origMinSize(),
m_origMaxSize(),
m_masterLayout( NULL )
{
if( m_orientation == Qt::Horizontal )
@@ -253,10 +309,12 @@ FLUIQ::CollapsibleWidget::CollapsibleWidget( Qt::Orientation _or,
}
m_masterLayout->setMargin( 0 );
m_masterLayout->setSpacing( 0 );
setSizePolicy( QSizePolicy::Expanding,
QSizePolicy::Expanding );
m_header = new CollapsibleWidgetHeader( this );
m_masterLayout->addWidget( m_header );
m_masterLayout->insertStretch( 100, 0 );
connect( m_header, SIGNAL( expanded() ),
this, SLOT( expand() ) );
@@ -276,7 +334,7 @@ FLUIQ::CollapsibleWidget::~CollapsibleWidget()
void FLUIQ::CollapsibleWidget::addWidget( QWidget * _w )
{
m_masterLayout->addWidget( _w );
m_masterLayout->insertWidget( m_masterLayout->count()-1, _w, 1 );
}
@@ -284,7 +342,7 @@ void FLUIQ::CollapsibleWidget::addWidget( QWidget * _w )
void FLUIQ::CollapsibleWidget::insertWidget( int _idx, QWidget * _w )
{
m_masterLayout->insertWidget( _idx, _w );
m_masterLayout->insertWidget( _idx, _w, 1 );
}
@@ -295,7 +353,7 @@ void FLUIQ::CollapsibleWidget::expand( void )
m_header->setCollapsed( false );
// set size properties
setMaximumSize( QSize( 1 << 16, 1 << 16 ) );
setMaximumSize( m_origMaxSize );
// show all children
foreach( QWidget * w, findChildren<QWidget *>() )
@@ -305,15 +363,37 @@ void FLUIQ::CollapsibleWidget::expand( void )
w->show();
}
}
setMinimumSize( sizeHint() );
// parent has gotten smaller while we were collapsed?
if( m_orientation == Qt::Horizontal )
{
// then re-adjust height
if( m_origMinSize.height() > sizeHint().height() )
{
m_origMinSize.setHeight( sizeHint().height() );
}
}
else
{
// then re-adjust width
if( m_origMinSize.width() > sizeHint().width() )
{
m_origMinSize.setWidth( sizeHint().width() );
}
}
setMinimumSize( m_origMinSize );
}
void FLUIQ::CollapsibleWidget::collapse( void )
{
m_header->setCollapsed( true );
m_origMinSize = minimumSize();
m_origMaxSize = maximumSize();
// hide all children
foreach( QWidget * w, findChildren<QWidget *>() )
{
@@ -324,6 +404,7 @@ void FLUIQ::CollapsibleWidget::collapse( void )
}
// set size properties
const QSize origSize = size();
const QSize headerSize = m_header->sizeHint();
if( m_orientation == Qt::Vertical )
{
@@ -334,6 +415,49 @@ void FLUIQ::CollapsibleWidget::collapse( void )
setMaximumSize( QSize( headerSize.width(), 1 << 16 ) );
}
setMinimumSize( headerSize );
/* // now try to redistribute freed space amongst sibling widgets
Splitter * s = NULL;
if( parentWidget() &&
( s = qobject_cast<Splitter *>( parentWidget() ) ) )
{
int numExpanded = 0;
for( int i = 0; i < s->count(); ++i )
{
CollapsibleWidget * cw =
qobject_cast<CollapsibleWidget *>(
s->widget( i ) );
if( cw && cw->isCollapsed() == false )
{
++numExpanded;
}
}
if( numExpanded == 0 )
{
return;
}
QSize addSizePerSibling = ( origSize - size() ) / numExpanded;
if( m_orientation == Qt::Vertical )
{
addSizePerSibling.setWidth( 0 );
}
else
{
addSizePerSibling.setHeight( 0 );
}
for( int i = 0; i < s->count(); ++i )
{
CollapsibleWidget * cw =
qobject_cast<CollapsibleWidget *>(
s->widget( i ) );
if( cw && cw->isCollapsed() == false )
{
cw->setMaximumSize( cw->maximumSize() +
addSizePerSibling );
}
}
}*/
}

View File

@@ -23,6 +23,7 @@
*/
#include <QtGui/QLayout>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
@@ -30,11 +31,20 @@
FLUIQ::Splitter::Splitter( Qt::Orientation _o, QWidget * _parent ) :
QSplitter( _o, _parent )
QWidget( _parent ),
m_orientation( _o )
{
setChildrenCollapsible( false );
setSizePolicy( QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding );
if( m_orientation == Qt::Horizontal )
{
m_mainLayout = new QHBoxLayout( this );
}
else
{
m_mainLayout = new QVBoxLayout( this );
}
m_mainLayout->setMargin( 0 );
m_mainLayout->setSpacing( 0 );
m_mainLayout->insertStretch( 100, 0 );
}
@@ -47,52 +57,38 @@ FLUIQ::Splitter::~Splitter()
QSplitterHandle * FLUIQ::Splitter::createHandle( void )
void FLUIQ::Splitter::addWidget( QWidget * _w )
{
return new FLUIQ::SplitterHandle( orientation(), this );
m_mainLayout->insertWidget( m_children.size(), _w, 1 );
m_children << _w;
}
FLUIQ::SplitterHandle::SplitterHandle( Qt::Orientation _o,
QSplitter * _parent ) :
QSplitterHandle( _o, _parent )
int FLUIQ::Splitter::indexOf( QWidget * _widget ) const
{
}
FLUIQ::SplitterHandle::~SplitterHandle()
{
}
void FLUIQ::SplitterHandle::paintEvent( QPaintEvent * _event )
{
QPainter painter( this );
QLinearGradient gradient;
gradient.setColorAt( 0, QColor( 128, 128, 128 ) );
gradient.setColorAt( 1, QColor( 32, 32, 32 ) );
if( orientation() == Qt::Horizontal )
int i = 0;
foreach( QWidget * w , m_children )
{
gradient.setStart( rect().left(), rect().height()/2 );
gradient.setFinalStop( rect().right(), rect().height()/2 );
if( w == _widget )
{
return i;
}
++i;
}
else
{
gradient.setStart( rect().width()/2, rect().top() );
gradient.setFinalStop( rect().width()/2, rect().bottom() );
}
painter.fillRect( _event->rect(), QBrush( gradient ) );
return -1;
}
QWidget * FLUIQ::Splitter::widget( int _idx )
{
return m_children[_idx];
}
#include "fluiq/moc_splitter.cxx"

View File

@@ -46,6 +46,16 @@ FLUIQ::WidgetContainer::WidgetContainer( Qt::Orientation _o,
m_scrollArea->setWidgetResizable( true );
m_scrollArea->setFrameStyle( QFrame::NoFrame );
/* if( _o == Qt::Horizontal )
{
m_scrollArea->setVerticalScrollBarPolicy(
Qt::ScrollBarAlwaysOff );
}
else
{
m_scrollArea->setHorizontalScrollBarPolicy(
Qt::ScrollBarAlwaysOff );
}*/
myLayout->addWidget( m_scrollArea );
m_splitter = new Splitter( m_orientation );

View File

@@ -52,21 +52,12 @@ FLUIQ::Workspace::~Workspace()
void FLUIQ::Workspace::addWidget( QWidget * _w )
{
m_currentSplitter = new Splitter( Qt::Horizontal, this );
m_masterLayout->addWidget( m_currentSplitter );
m_currentSplitter->addWidget( _w );
}
void FLUIQ::Workspace::addWidgetToExistingRow( QWidget * _w )
{
m_currentSplitter->addWidget( _w );
}
#include "fluiq/moc_workspace.cxx"