21
21
#include " qgslogger.h"
22
22
23
23
#include < QToolButton>
24
- #include < QLayout>
25
- #include < QStyle>
26
24
27
25
26
+ QIcon QgsCollapsibleGroupBox::mCollapseIcon ;
27
+ QIcon QgsCollapsibleGroupBox::mExpandIcon ;
28
+
28
29
QgsCollapsibleGroupBox::QgsCollapsibleGroupBox ( QWidget *parent )
29
- : QGroupBox( parent ), mCollapsed( false )
30
+ : QGroupBox( parent ), mCollapsed( true ), mMarginOffset( 0 )
30
31
{
31
32
init ();
32
33
}
33
34
34
35
QgsCollapsibleGroupBox::QgsCollapsibleGroupBox ( const QString &title,
35
36
QWidget *parent )
36
- : QGroupBox( title, parent ), mCollapsed( false )
37
+ : QGroupBox( title, parent ), mCollapsed( true ), mMarginOffset( 0 )
37
38
{
38
39
init ();
39
40
}
40
41
41
42
void QgsCollapsibleGroupBox::init ()
42
43
{
44
+ /* Top margin fix is to increase the vertical default spacing
45
+ between multiple groupboxes, especially ones without title checkboxes
46
+ may not be necessary on certain platforms */
47
+ mMarginOffset = 0 ; // in pixels; for temporary testing across platforms
43
48
44
- connect ( this , SIGNAL ( toggled ( bool ) ), this , SLOT ( checkboxToggled () ) );
49
+ // init icons
50
+ if ( mCollapseIcon .isNull () )
51
+ {
52
+ mCollapseIcon = QgsApplication::getThemeIcon ( " /mIconCollapse.png" );
53
+ mExpandIcon = QgsApplication::getThemeIcon ( " /mIconExpand.png" );
54
+ }
45
55
56
+ // customize style sheet
57
+ // TODO: move to app stylesheet system, when appropriate
46
58
QString ss;
47
- ss += " QGroupBox {" ;
48
- ss += " margin-top: 28px;" ; // fix for non-checkbox-groupbox spacing
49
- ss += " }" ;
50
- ss += " QGroupBox::title {" ;
59
+ if ( mMarginOffset > 0 )
60
+ {
61
+ ss += " QgsCollapsibleGroupBox {" ;
62
+ ss += QString ( " margin-top: %1px;" ).arg ( mMarginOffset + 8 );
63
+ ss += " }" ;
64
+ }
65
+ ss += " QgsCollapsibleGroupBox::title {" ;
51
66
ss += " subcontrol-origin: margin;" ;
52
67
ss += " subcontrol-position: top left;" ;
68
+ // ss += QString( " font-size: %1";).arg( appFontSize );
53
69
ss += " margin-left: 24px;" ; // offset for disclosure triangle
54
- ss += " margin-top: 10px;" ; // offset to match extra top margin
70
+ if ( mMarginOffset > 0 )
71
+ ss += QString ( " margin-top: %1px;" ).arg ( mMarginOffset );
55
72
ss += " }" ;
56
73
setStyleSheet ( ss );
57
74
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
75
+ // collapse button
76
+ mCollapseButton = new QToolButton ( this );
77
+ mCollapseButton ->setObjectName ( " collapseButton" );
78
+ mCollapseButton ->setAutoRaise ( true );
79
+ mCollapseButton ->setFixedSize ( 16 , 16 );
80
+ // TODO set size (as well as margins) depending on theme
81
+ mCollapseButton ->setIconSize ( QSize ( 12 , 12 ) );
82
+ mCollapseButton ->setIcon ( mExpandIcon );
83
+ if ( mMarginOffset > 0 )
84
+ mCollapseButton ->move ( 0 , mMarginOffset ); // match title offset
85
+
86
+ // clear toolbutton default background and border
87
+ // TODO: move to app stylesheet system, when appropriate
66
88
QString ssd;
67
- ssd + = QString ( " QToolButton#%1 {" ).arg ( mDisclosureName );
68
- ssd += " background-color: rgba(255, 255, 255, 0);" ;
89
+ ssd = QString ( " QgsCollapsibleGroupBox > QToolButton#%1 {" ).arg ( mCollapseButton -> objectName () );
90
+ ssd += " background-color: rgba(255, 255, 255, 0); border: none; " ;
69
91
ssd += " }" ;
70
- mDisclosure ->setStyleSheet ( ssd );
92
+ mCollapseButton ->setStyleSheet ( ssd );
71
93
72
- connect ( mDisclosure , SIGNAL ( clicked () ), this , SLOT ( toggleCollapsed () ) );
94
+ connect ( mCollapseButton , SIGNAL ( clicked () ), this , SLOT ( toggleCollapsed () ) );
95
+ connect ( this , SIGNAL ( clicked ( bool ) ), this , SLOT ( checkClicked () ) );
96
+ connect ( this , SIGNAL ( toggled ( bool ) ), this , SLOT ( checkToggled () ) );
73
97
}
74
98
75
-
76
99
void QgsCollapsibleGroupBox::showEvent ( QShowEvent * event )
77
100
{
78
101
QGroupBox::showEvent ( event );
79
- // collapse if needed - any calls to setCollapsed() before have no effect
80
- setCollapsed ( true );
102
+ // expand if needed - any calls to setCollapsed() before have no effect
103
+ if ( mCollapsed )
104
+ {
105
+ setCollapsed ( mCollapsed );
106
+ }
107
+ else
108
+ {
109
+ /* manually uncollapsing (already default) on show may scroll scroll areas
110
+ still emit signal for connections using uncollapsed state */
111
+ emit collapsedStateChanged ( this );
112
+ }
81
113
}
82
114
83
- void QgsCollapsibleGroupBox::checkboxToggled ()
115
+ void QgsCollapsibleGroupBox::checkClicked ()
84
116
{
85
- mDisclosure ->setEnabled ( true ); // always keep enabled
117
+ mCollapseButton ->setEnabled ( true ); // always keep enabled
118
+ // expand/collapse when clicked
119
+ if ( isChecked () && isCollapsed () )
120
+ setCollapsed ( false );
121
+ else if ( ! isChecked () && ! isCollapsed () )
122
+ setCollapsed ( true );
123
+ }
124
+
125
+ void QgsCollapsibleGroupBox::checkToggled ()
126
+ {
127
+ mCollapseButton ->setEnabled ( true ); // always keep enabled
86
128
}
87
129
88
130
void QgsCollapsibleGroupBox::toggleCollapsed ()
@@ -92,44 +134,42 @@ void QgsCollapsibleGroupBox::toggleCollapsed()
92
134
93
135
void QgsCollapsibleGroupBox::setCollapsed ( bool collapse )
94
136
{
95
- if ( ! isVisible () )
137
+ if ( !isVisible () )
96
138
return ;
97
139
98
140
mCollapsed = collapse;
99
141
142
+ // for consistent look/spacing across platforms when collapsed
100
143
setFlat ( collapse );
101
144
setMaximumHeight ( collapse ? 36 : 16777215 );
102
145
103
146
// if we are collapsing, save hidden widgets in a list
104
147
if ( collapse )
105
148
{
106
- mDisclosure ->setIcon ( QgsApplication::getThemeIcon ( " /mIconExpand.png " ) );
149
+ mCollapseButton ->setIcon ( mExpandIcon );
107
150
mHiddenWidgets .clear ();
108
151
foreach ( QWidget *widget, findChildren<QWidget*>() )
109
152
{
110
- if ( widget->isHidden () && widget->objectName () != mDisclosureName )
153
+ if ( widget->isHidden () && widget->objectName () != mCollapseButton -> objectName () )
111
154
mHiddenWidgets << widget;
112
155
}
113
156
}
114
157
115
158
// show/hide widgets
116
159
foreach ( QWidget *widget, findChildren<QWidget*>() )
117
- if ( widget->objectName () != mDisclosureName )
160
+ if ( widget->objectName () != mCollapseButton -> objectName () )
118
161
widget->setHidden ( collapse );
119
162
120
163
// if we are expanding, re-hide saved hidden widgets
121
164
if ( ! collapse )
122
165
{
123
- mDisclosure ->setIcon ( QgsApplication::getThemeIcon ( " /mIconCollapse.png " ) );
166
+ mCollapseButton ->setIcon ( mCollapseIcon );
124
167
foreach ( QWidget *widget, mHiddenWidgets )
125
168
{
126
169
widget->setHidden ( true );
127
170
}
128
171
}
129
172
130
- if ( mCollapsed )
131
- emit collapsed ( this );
132
- else
133
- emit expanded ( this );
173
+ emit collapsedStateChanged ( this );
134
174
}
135
175
0 commit comments