2020#include " qgsapplication.h"
2121#include " qgslogger.h"
2222
23- #include < QStyleOptionGroupBox>
24- #include < QStylePainter>
23+ #include < QToolButton>
2524#include < QLayout>
26- #include < QProxyStyle >
25+ #include < QStyle >
2726
28- class QgsCollapsibleGroupBoxStyle : public QProxyStyle
29- {
30- public:
31- QgsCollapsibleGroupBoxStyle ( QStyle * style = 0 ) : QProxyStyle( style ) {}
32-
33- void drawPrimitive ( PrimitiveElement element, const QStyleOption *option,
34- QPainter *painter, const QWidget *widget ) const
35- {
36- if ( element == PE_IndicatorCheckBox )
37- {
38- const QgsCollapsibleGroupBox* groupBox =
39- dynamic_cast <const QgsCollapsibleGroupBox*>( widget );
40- if ( groupBox )
41- {
42- return drawPrimitive ( groupBox->isCollapsed () ?
43- PE_IndicatorArrowRight : PE_IndicatorArrowDown,
44- option, painter, widget );
45- }
46- }
47- return QProxyStyle::drawPrimitive ( element, option, painter, widget );
48- }
49- };
5027
5128QgsCollapsibleGroupBox::QgsCollapsibleGroupBox ( QWidget *parent )
5229 : QGroupBox( parent ), mCollapsed( false )
@@ -63,16 +40,54 @@ QgsCollapsibleGroupBox::QgsCollapsibleGroupBox( const QString &title,
6340
6441void QgsCollapsibleGroupBox::init ()
6542{
66- setStyle ( new QgsCollapsibleGroupBoxStyle ( QApplication::style () ) );
67- connect ( this , SIGNAL ( toggled ( bool ) ), this , SLOT ( setToggled ( bool ) ) );
43+
44+ connect ( this , SIGNAL ( toggled ( bool ) ), this , SLOT ( checkboxToggled () ) );
45+
46+ QString ss;
47+ ss += " QGroupBox {" ;
48+ ss += " margin-top: 28px;" ; // fix for non-checkbox-groupbox spacing
49+ ss += " }" ;
50+ ss += " QGroupBox::title {" ;
51+ ss += " subcontrol-origin: margin;" ;
52+ ss += " subcontrol-position: top left;" ;
53+ ss += " margin-left: 24px;" ; // offset for disclosure triangle
54+ ss += " margin-top: 10px;" ; // offset to match extra top margin
55+ ss += " }" ;
56+ setStyleSheet ( ss );
57+
58+ mDisclosure = new QToolButton ( this );
59+ mDisclosureName = QString ( " grpboxDisclosure" );
60+ mDisclosure ->setObjectName ( mDisclosureName );
61+ mDisclosure ->setFixedSize ( 16 , 16 );
62+ mDisclosure ->move ( 0 , 10 ); // match title offset
63+ mDisclosure ->setIconSize ( QSize ( 16 , 16 ) );
64+
65+ // get rid of toolbutton background
66+ QString ssd;
67+ ssd += QString ( " QToolButton#%1 {" ).arg ( mDisclosureName );
68+ ssd += " background-color: rgba(255, 255, 255, 0);" ;
69+ ssd += " }" ;
70+ mDisclosure ->setStyleSheet ( ssd );
71+
72+ connect ( mDisclosure , SIGNAL ( clicked () ), this , SLOT ( toggleCollapsed () ) );
6873}
6974
75+
7076void QgsCollapsibleGroupBox::showEvent ( QShowEvent * event )
7177{
7278 QGroupBox::showEvent ( event );
7379 // collapse if needed - any calls to setCollapsed() before have no effect
74- if ( isCheckable () && ! isChecked () && ! isCollapsed () )
75- setCollapsed ( true );
80+ setCollapsed ( true );
81+ }
82+
83+ void QgsCollapsibleGroupBox::checkboxToggled ()
84+ {
85+ mDisclosure ->setEnabled ( true ); // always keep enabled
86+ }
87+
88+ void QgsCollapsibleGroupBox::toggleCollapsed ()
89+ {
90+ setCollapsed ( !mCollapsed );
7691}
7792
7893void QgsCollapsibleGroupBox::setCollapsed ( bool collapse )
@@ -82,41 +97,30 @@ void QgsCollapsibleGroupBox::setCollapsed( bool collapse )
8297
8398 mCollapsed = collapse;
8499
85- // minimize layout margins and save for subsequent restore
86- if ( collapse )
87- {
88- if ( layout () )
89- {
90- mMargins = layout ()->contentsMargins ();
91- layout ()->setContentsMargins ( 1 , 1 , 1 , 1 );
92- }
93- }
94- else
95- {
96- if ( layout () )
97- {
98- layout ()->setContentsMargins ( mMargins );
99- }
100- }
100+ setFlat ( collapse );
101+ setMaximumHeight ( collapse ? 36 : 16777215 );
101102
102103 // if we are collapsing, save hidden widgets in a list
103104 if ( collapse )
104105 {
106+ mDisclosure ->setIcon ( QgsApplication::getThemeIcon ( " /mIconExpand.png" ) );
105107 mHiddenWidgets .clear ();
106108 foreach ( QWidget *widget, findChildren<QWidget*>() )
107109 {
108- if ( widget->isHidden () )
110+ if ( widget->isHidden () && widget-> objectName () != mDisclosureName )
109111 mHiddenWidgets << widget;
110112 }
111113 }
112114
113115 // show/hide widgets
114116 foreach ( QWidget *widget, findChildren<QWidget*>() )
115- widget->setHidden ( collapse );
117+ if ( widget->objectName () != mDisclosureName )
118+ widget->setHidden ( collapse );
116119
117120 // if we are expanding, re-hide saved hidden widgets
118121 if ( ! collapse )
119122 {
123+ mDisclosure ->setIcon ( QgsApplication::getThemeIcon ( " /mIconCollapse.png" ) );
120124 foreach ( QWidget *widget, mHiddenWidgets )
121125 {
122126 widget->setHidden ( true );
0 commit comments