3 Copyright (c) 2012 Jakob Leben & Tim Blechmann
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef SCIDE_WIDGETS_UTIL_MULTI_SPLITTER_HPP_INCLUDED
22 #define SCIDE_WIDGETS_UTIL_MULTI_SPLITTER_HPP_INCLUDED
28 class MultiSplitter
: public QSplitter
31 explicit MultiSplitter(QWidget
*parent
= 0):
34 setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Expanding
);
37 void insertWidget( QWidget
*widget
, QWidget
*neighbour
, Qt::Orientation direction
)
39 if (!neighbour
|| !widgetIsChild(neighbour
)) {
40 qWarning("MultiSplitter: neighbour widget invalid");
44 QSplitter
*parentSplitter
= parentSplitterOf(neighbour
);
45 Q_ASSERT(parentSplitter
);
46 int posInParent
= parentSplitter
->indexOf(neighbour
);
47 Q_ASSERT(posInParent
!= -1);
49 if (parentSplitter
->orientation() == direction
) {
50 parentSplitter
->insertWidget(posInParent
+ 1, widget
);
52 else if (parentSplitter
->count() < 2)
54 parentSplitter
->setOrientation(direction
);
55 parentSplitter
->addWidget(widget
);
58 // store parent's current distribution:
59 QList
<int> parentsSizes
= parentSplitter
->sizes();
60 QSplitter
* splitter
= new QSplitter(direction
);
61 // move the neighbour to the new splitter, and add the new widget:
62 splitter
->addWidget(neighbour
);
63 splitter
->addWidget(widget
);
64 // insert the new splitter at the neighbour's old position:
65 parentSplitter
->insertWidget(posInParent
, splitter
);
66 // restore parent's old distribution, affected by operations above:
67 parentSplitter
->setSizes(parentsSizes
);
68 // change the parent to the new splitter, for operations below:
69 parentSplitter
= splitter
;
72 setEqualSizes(parentSplitter
);
75 void removeWidget( QWidget
*widget
)
77 if (!widget
|| !widgetIsChild(widget
)) {
78 qWarning("MultiSplitter: widget invalid");
82 QSplitter
*parent
= parentSplitterOf(widget
);
83 if (parent
== this && parent
->count() < 2) {
84 qWarning("MultiSplitter: can not remove last widget");
90 Q_ASSERT(parent
->count());
92 if (parent
->count() == 1) {
93 QWidget
*neighbour
= parent
->widget(0);
95 // replace parent splitter with it's only child
96 QSplitter
*grandParent
= parentSplitterOf(parent
);
97 QList
<int> grandParentsSizes
= grandParent
->sizes();
98 int posInParent
= grandParent
->indexOf(parent
);
99 Q_ASSERT(posInParent
!= -1);
100 grandParent
->insertWidget(posInParent
, neighbour
);
102 grandParent
->setSizes(grandParentsSizes
);
105 // replace child splitter with it's own children
106 QSplitter
*splitter
= qobject_cast
<QSplitter
*>(neighbour
);
108 QList
<int> childSizes
= splitter
->sizes();
109 Qt::Orientation childOrientation
= splitter
->orientation();
110 int childCount
= splitter
->count();
112 parent
->addWidget(splitter
->widget(0)); // 0 is always another widget
114 parent
->setOrientation(childOrientation
);
115 parent
->setSizes(childSizes
);
121 template<typename T
> T
* findChild()
123 return MultiSplitter::findChild
<T
>(this);
127 template<typename T
> static T
* findChild( QSplitter
* splitter
) {
128 int childCount
= splitter
->count();
129 for (int idx
= 0; idx
< childCount
; ++idx
) {
130 QWidget
*child
= splitter
->widget(idx
);
131 T
* typedChild
= qobject_cast
<T
*>(child
);
134 QSplitter
*childSplitter
= qobject_cast
<QSplitter
*>(child
);
136 typedChild
= findChild
<T
>( childSplitter
);
144 QSplitter
*parentSplitterOf( QWidget
*widget
)
146 return qobject_cast
<QSplitter
*>( widget
->parent() );
149 void setEqualSizes(QSplitter
*splitter
)
151 int widgetCount
= splitter
->count();
152 int splitterSize
= splitter
->orientation() == Qt::Horizontal
?
153 splitter
->size().width() : splitter
->size().height();
154 QList
<int> newWidgetSizes
;
155 int singleWidgetSize
= splitterSize
/ widgetCount
;
156 for( int idx
= 0; idx
< widgetCount
; ++idx
)
157 newWidgetSizes
<< singleWidgetSize
;
158 splitter
->setSizes( newWidgetSizes
);
161 bool widgetIsChild( QWidget
*widget
)
163 QObject
*object
= widget
->parent();
167 object
= object
->parent();
175 #endif // SCIDE_WIDGETS_UTIL_MULTI_SPLITTER_HPP_INCLUDED