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

@@ -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"