1 // Copyright (C) 2007 Mark Pustjens <pustjens@dds.nl>
2 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
4 // This file is part of CenterIM.
6 // CenterIM 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 // CenterIM 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 CenterIM. If not, see <http://www.gnu.org/licenses/>.
20 /// HorizontalListBox class implementation.
22 /// @ingroup cppconsui
24 #include "HorizontalListBox.h"
31 HorizontalListBox::HorizontalListBox(int w
, int h
)
32 : AbstractListBox(w
, h
), children_width_(0), autosize_children_count_(0)
36 VerticalLine
*HorizontalListBox::insertSeparator(std::size_t pos
)
38 auto l
= new VerticalLine(AUTOSIZE
);
39 insertWidget(pos
, *l
);
43 VerticalLine
*HorizontalListBox::appendSeparator()
45 auto l
= new VerticalLine(AUTOSIZE
);
50 void HorizontalListBox::insertWidget(std::size_t pos
, Widget
&widget
)
52 Container::insertWidget(pos
, widget
, UNSETPOS
, UNSETPOS
);
54 if (!widget
.isVisible())
57 // Calculate the expected width by the widget.
58 int w
= widget
.getWidth();
59 int autosize_change
= 0;
61 w
= widget
.getWishWidth();
68 updateChildren(w
, autosize_change
);
71 void HorizontalListBox::appendWidget(Widget
&widget
)
73 insertWidget(children_
.size(), widget
);
76 void HorizontalListBox::updateArea()
78 int autosize_width
= 1;
79 int autosize_width_extra
= 0;
80 if (autosize_children_count_
&& children_width_
< real_width_
) {
81 int space
= real_width_
- (children_width_
- autosize_children_count_
);
82 autosize_width
= space
/ autosize_children_count_
;
83 autosize_width_extra
= space
% autosize_children_count_
;
87 for (Widget
*widget
: children_
) {
88 bool is_visible
= widget
->isVisible();
90 // Position the widget correctly.
91 widget
->setRealPosition(x
, 0);
93 // Calculate the real width.
94 int w
= widget
->getWidth();
96 w
= widget
->getWishWidth();
99 if (is_visible
&& autosize_width_extra
> 0) {
100 --autosize_width_extra
;
106 // Calculate the real height.
107 int h
= widget
->getHeight();
109 h
= widget
->getWishHeight();
113 if (h
> real_height_
)
116 widget
->setRealSize(w
, h
);
122 // Make sure that the currently focused widget is visible.
126 void HorizontalListBox::onChildMoveResize(
127 Widget
&activator
, const Rect
&oldsize
, const Rect
&newsize
)
130 assert(newsize
.getLeft() == UNSETPOS
&& newsize
.getTop() == UNSETPOS
);
132 if (!activator
.isVisible())
135 int old_width
= oldsize
.getWidth();
136 int new_width
= newsize
.getWidth();
138 if (old_width
== new_width
)
141 int autosize_change
= 0;
142 if (old_width
== AUTOSIZE
) {
143 old_width
= activator
.getWishWidth();
144 if (old_width
== AUTOSIZE
) {
149 if (new_width
== AUTOSIZE
) {
150 new_width
= activator
.getWishWidth();
151 if (new_width
== AUTOSIZE
) {
157 updateChildren(new_width
- old_width
, autosize_change
);
160 void HorizontalListBox::onChildWishSizeChange(
161 Widget
&activator
, const Size
&oldsize
, const Size
&newsize
)
163 if (!activator
.isVisible() || activator
.getWidth() != AUTOSIZE
)
166 // The widget is visible and is autosized.
167 int old_width
= oldsize
.getWidth();
168 int new_width
= newsize
.getWidth();
170 if (old_width
== new_width
)
173 updateChildren(new_width
- old_width
, 0);
176 void HorizontalListBox::onChildVisible(Widget
&activator
, bool visible
)
178 // The widget is being hidden or deleted.
179 int w
= activator
.getWidth();
180 int sign
= visible
? 1 : -1;
181 int autosize_change
= 0;
183 w
= activator
.getWishWidth();
186 autosize_change
= sign
;
189 updateChildren(sign
* w
, autosize_change
);
192 void HorizontalListBox::moveWidget(Widget
&widget
, Widget
&position
, bool after
)
194 Container::moveWidget(widget
, position
, after
);
196 // Reposition all child widgets.
200 void HorizontalListBox::updateChildren(
201 int children_width_change
, int autosize_children_count_change
)
203 // Set new children data.
204 children_width_
+= children_width_change
;
205 assert(children_width_
>= 0);
206 autosize_children_count_
+= autosize_children_count_change
;
207 assert(autosize_children_count_
>= 0);
209 // Reposition all child widgets.
211 signal_children_width_change(*this, children_width_
);
214 } // namespace CppConsUI
216 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: