Skip to content

Commit

Permalink
Updates to QgsCollapsibleGroupBoxBasic
Browse files Browse the repository at this point in the history
- Use title instead of checkbox to define QgsCollapsibleGroupBox offset
- Fix error when group box has form layout with QPushButtons that refuse to fully hide
- Update vertical offsets for Ubuntu
- Add control-click modifier and tool tip for toggling all collapsible group boxes
- Ensure disclosure triangle mirrors enabled state of group box
  • Loading branch information
dakcarto committed Feb 19, 2013
1 parent a86622b commit a645f43
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 19 deletions.
95 changes: 78 additions & 17 deletions src/gui/qgscollapsiblegroupbox.cpp
Expand Up @@ -22,6 +22,7 @@

#include <QToolButton>
#include <QMouseEvent>
#include <QPushButton>
#include <QStyleOptionGroupBox>
#include <QSettings>
#include <QScrollArea>
Expand All @@ -47,7 +48,6 @@ QgsCollapsibleGroupBoxBasic::~QgsCollapsibleGroupBoxBasic()
//QgsDebugMsg( "Entered" );
}


void QgsCollapsibleGroupBoxBasic::init()
{
//QgsDebugMsg( "Entered" );
Expand Down Expand Up @@ -126,6 +126,10 @@ void QgsCollapsibleGroupBoxBasic::showEvent( QShowEvent * event )
// emit signal for connections using collapsed state
emit collapsedStateChanged( isCollapsed() );
}

// verify triangle mirrors groupbox's enabled state
mCollapseButton->setEnabled( isEnabled() );

// set mShown after first setCollapsed call or expanded groupboxes
// will scroll scroll areas when first shown
mShown = true;
Expand All @@ -149,7 +153,7 @@ void QgsCollapsibleGroupBoxBasic::mousePressEvent( QMouseEvent *event )

void QgsCollapsibleGroupBoxBasic::mouseReleaseEvent( QMouseEvent *event )
{
mAltDown = ( event->modifiers() & Qt::AltModifier );
mAltDown = ( event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
mTitleClicked = ( titleRect().contains( event->pos() ) );

// sync group when title is alt-clicked
Expand Down Expand Up @@ -177,6 +181,19 @@ void QgsCollapsibleGroupBoxBasic::changeEvent( QEvent *event )
mCollapseButton->setEnabled( true );
}

void QgsCollapsibleGroupBoxBasic::setSyncGroup( QString grp )
{
mSyncGroup = grp;
if ( !grp.isEmpty() )
{
mCollapseButton->setToolTip( tr( "Ctrl(or Alt)-click to toggle all" ) );
}
else
{
mCollapseButton->setToolTip( QString( "" ) );
}
}

QRect QgsCollapsibleGroupBoxBasic::titleRect() const
{
QStyleOptionGroupBox box;
Expand Down Expand Up @@ -255,20 +272,34 @@ void QgsCollapsibleGroupBoxBasic::updateStyle()
{
setUpdatesEnabled( false );

QSettings settings;
// NOTE: QGIS-Style groupbox styled in app stylesheet
bool usingQgsStyle = settings.value( "qgis/stylesheet/groupBoxCustom", QVariant( false ) ).toBool();

QStyleOptionGroupBox box;
initStyleOption( &box );
QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box,
QStyle::SC_GroupBoxFrame, this );
QRect rectTitle = titleRect();

// margin/offset defaults
int marginLeft = 20; // title margin for disclosure triangle
int marginRight = 5; // a little bit of space on the right, to match space on the left
int offsetLeft = 0; // offset for oxygen theme
int offsetTop = 0;
// int offsetTop2 = 0; // offset for triangle

// starting top offset for custom groupboxes in app stylesheet
QStyleOptionGroupBox box;
initStyleOption( &box );
QRect rectCheckBox = style()->subControlRect( QStyle::CC_GroupBox, &box,
QStyle::SC_GroupBoxCheckBox, this );
int offsetTop2 = rectCheckBox.top(); // offset for triangle
int offsetStyle = QApplication::style()->objectName().contains( "macintosh" ) ? 1 : 0;
int topBuffer = ( usingQgsStyle ? 3 : 1 ) + offsetStyle; // space between top of title or triangle and widget above
int offsetTop = topBuffer;
int offsetTopTri = topBuffer; // offset for triangle

if ( mCollapseButton->height() < rectTitle.height() ) // triangle's height > title text's, offset triangle
{
offsetTopTri += ( rectTitle.height() - mCollapseButton->height() ) / 2 ;
// offsetTopTri += rectTitle.top();
}
else if ( rectTitle.height() < mCollapseButton->height() ) // title text's height < triangle's, offset title
{
offsetTop += ( mCollapseButton->height() - rectTitle.height() ) / 2;
}

// calculate offset if frame overlaps triangle (oxygen theme)
// using an offset of 6 pixels from frame border
Expand All @@ -289,22 +320,27 @@ void QgsCollapsibleGroupBoxBasic::updateStyle()
// if is checkable align with checkbox
offsetTop = ( rectCheckBox.height() / 2 ) -
( mCollapseButton->height() / 2 ) + rectCheckBox.top();
offsetTop2 = offsetTop + 1;
offsetTopTri = offsetTop + 1;
}
else
{
offsetTop = 6 + rectFrame.top();
offsetTop2 = offsetTop;
offsetTopTri = offsetTop;
}
}
}

QgsDebugMsg( QString( "groupbox: %1 style: %2 offset: left=%3 top=%4 top2=%5" ).arg(
objectName() ).arg( QApplication::style()->objectName() ).arg( offsetLeft ).arg( offsetTop ).arg( offsetTop2 ) );
objectName() ).arg( QApplication::style()->objectName() ).arg( offsetLeft ).arg( offsetTop ).arg( offsetTopTri ) );

// customize style sheet for collapse/expand button and force left-aligned title
// TODO: move to app stylesheet system, when appropriate
QString ss;
if ( usingQgsStyle || QApplication::style()->objectName().contains( "macintosh" ) )
{
ss += "QgsCollapsibleGroupBoxBasic, QgsCollapsibleGroupBox {";
ss += QString( " margin-top: %1px;" ).arg( topBuffer + ( usingQgsStyle ? rectTitle.height() + 5 : rectFrame.top() ) );
ss += "}";
}
ss += "QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title {";
ss += " subcontrol-origin: margin;";
ss += " subcontrol-position: top left;";
Expand All @@ -321,8 +357,8 @@ void QgsCollapsibleGroupBoxBasic::updateStyle()
ssd += " background-color: rgba(255, 255, 255, 0); border: none;";
ssd += "}";
mCollapseButton->setStyleSheet( ssd );
if ( offsetLeft != 0 || offsetTop2 != 0 )
mCollapseButton->move( offsetLeft, offsetTop2 );
if ( offsetLeft != 0 || offsetTopTri != 0 )
mCollapseButton->move( offsetLeft, offsetTopTri );

setUpdatesEnabled( true );
}
Expand All @@ -341,6 +377,31 @@ void QgsCollapsibleGroupBoxBasic::setCollapsed( bool collapse )
// avoid flicker in X11
QApplication::processEvents();

// handle QPushButtons in form layouts that stay visible on collapse (Qt bug)
// set flat on collapse for fix, but preserve button's flat value when expanding
if ( collapse )
{
foreach ( QPushButton* pBtn, findChildren<QPushButton *>() )
{
if ( ! pBtn->isFlat() )
{
if ( ! pBtn->property( "PushButtonFlat" ).isValid() )
pBtn->setProperty( "PushButtonFlat", QVariant( false ) );

pBtn->setFlat( true );
}
}
}
else
{
foreach ( QPushButton* pBtn, findChildren<QPushButton *>() )
{
// restore any previous flat value
if ( pBtn->property( "PushButtonFlat" ).isValid() )
pBtn->setFlat( false );
}
}

// set maximum height to hide contents - does this work in all envs?
// setMaximumHeight( collapse ? 25 : 16777215 );
setMaximumHeight( collapse ? titleRect().bottom() + 6 : 16777215 );
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgscollapsiblegroupbox.h
Expand Up @@ -45,7 +45,7 @@ class QgsGroupBoxCollapseButton: public QToolButton
protected:
void mouseReleaseEvent( QMouseEvent *event )
{
mAltDown = ( event->modifiers() & Qt::AltModifier );
mAltDown = ( event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
QToolButton::mouseReleaseEvent( event );
}

Expand Down Expand Up @@ -79,7 +79,7 @@ class GUI_EXPORT QgsCollapsibleGroupBoxBasic : public QGroupBox

/** Named group which synchronizes collapsing action when triangle is clicked while holding alt modifier key */
QString syncGroup() const { return mSyncGroup; }
void setSyncGroup( QString grp ) { mSyncGroup = grp; }
void setSyncGroup( QString grp );

//! set this to false to not automatically scroll parent QScrollArea to this widget's contents when expanded
void setScrollOnExpand( bool scroll ) { mScrollOnExpand = scroll; }
Expand Down

0 comments on commit a645f43

Please sign in to comment.