Avoid use of curses subpads
[centerim5.git] / cppconsui / HorizontalListBox.cpp
blob02d1dafeecd901947e767f591d76c61c3717b1ce
1 /*
2 * Copyright (C) 2007 by Mark Pustjens <pustjens@dds.nl>
3 * Copyright (C) 2010-2013 by CenterIM developers
5 * This file is part of CenterIM.
7 * CenterIM is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * CenterIM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /**
23 * @file
24 * HorizontalListBox class implementation.
26 * @ingroup cppconsui
29 #include "HorizontalListBox.h"
31 #include <algorithm>
32 #include <cassert>
34 namespace CppConsUI
37 HorizontalListBox::HorizontalListBox(int w, int h)
38 : AbstractListBox(w, h), children_width(0), autosize_children_count(0)
42 VerticalLine *HorizontalListBox::insertSeparator(size_t pos)
44 VerticalLine *l = new VerticalLine(AUTOSIZE);
45 insertWidget(pos, *l);
46 return l;
49 VerticalLine *HorizontalListBox::appendSeparator()
51 VerticalLine *l = new VerticalLine(AUTOSIZE);
52 appendWidget(*l);
53 return l;
56 void HorizontalListBox::insertWidget(size_t pos, Widget& widget)
58 Container::insertWidget(pos, widget, UNSETPOS, UNSETPOS);
60 if (!widget.isVisible())
61 return;
63 // calculate the expected width by the widget
64 int w = widget.getWidth();
65 int autosize_change = 0;
66 if (w == AUTOSIZE) {
67 w = widget.getWishWidth();
68 if (w == AUTOSIZE) {
69 w = 1;
70 autosize_change = 1;
74 updateChildren(w, autosize_change);
77 void HorizontalListBox::appendWidget(Widget& widget)
79 insertWidget(children.size(), widget);
82 void HorizontalListBox::updateArea()
84 int autosize_width = 1;
85 int autosize_width_extra = 0;
86 if (autosize_children_count && children_width < real_width) {
87 int space = real_width - (children_width - autosize_children_count);
88 autosize_width = space / autosize_children_count;
89 autosize_width_extra = space % autosize_children_count;
92 int x = 0;
93 for (Children::iterator i = children.begin(); i != children.end(); i++) {
94 Widget *widget = *i;
95 bool is_visible = widget->isVisible();
97 // position the widget correctly
98 widget->setRealPosition(x, 0);
100 // calculate the real width
101 int w = widget->getWidth();
102 if (w == AUTOSIZE) {
103 w = widget->getWishWidth();
104 if (w == AUTOSIZE) {
105 w = autosize_width;
106 if (is_visible && autosize_width_extra) {
107 autosize_width_extra--;
108 w++;
113 // calculate the real height
114 int h = widget->getHeight();
115 if (h == AUTOSIZE) {
116 h = widget->getWishHeight();
117 if (h == AUTOSIZE)
118 h = real_height;
120 if (h > real_height)
121 h = real_height;
123 widget->setRealSize(w, h);
125 if (is_visible)
126 x += w;
129 // make sure that the currently focused widget is visible
130 updateScroll();
133 void HorizontalListBox::onChildMoveResize(Widget& activator,
134 const Rect& oldsize, const Rect& newsize)
136 // sanity check
137 assert(newsize.getLeft() == UNSETPOS && newsize.getTop() == UNSETPOS);
139 if (!activator.isVisible())
140 return;
142 int old_width = oldsize.getWidth();
143 int new_width = newsize.getWidth();
145 if (old_width == new_width)
146 return;
148 int autosize_change = 0;
149 if (old_width == AUTOSIZE) {
150 old_width = activator.getWishWidth();
151 if (old_width == AUTOSIZE) {
152 old_width = 1;
153 autosize_change--;
156 if (new_width == AUTOSIZE) {
157 new_width = activator.getWishWidth();
158 if (new_width == AUTOSIZE) {
159 new_width = 1;
160 autosize_change++;
164 updateChildren(new_width - old_width, autosize_change);
167 void HorizontalListBox::onChildWishSizeChange(Widget& activator,
168 const Size& oldsize, const Size& newsize)
170 if (!activator.isVisible() || activator.getWidth() != AUTOSIZE)
171 return;
173 // the widget is visible and is autosized
174 int old_width = oldsize.getWidth();
175 int new_width = newsize.getWidth();
177 if (old_width == new_width)
178 return;
180 updateChildren(new_width - old_width, 0);
183 void HorizontalListBox::onChildVisible(Widget& activator, bool visible)
185 // the widget is being hidden or deleted
186 int w = activator.getWidth();
187 int sign = visible ? 1 : -1;
188 int autosize_change = 0;
189 if (w == AUTOSIZE) {
190 w = activator.getWishWidth();
191 if (w == AUTOSIZE) {
192 w = 1;
193 autosize_change = sign;
196 updateChildren(sign * w, autosize_change);
199 void HorizontalListBox::updateChildren(int children_width_change,
200 int autosize_children_count_change)
202 // set new children data
203 children_width += children_width_change;
204 assert(children_width >= 0);
205 autosize_children_count += autosize_children_count_change;
206 assert(autosize_children_count >= 0);
208 // reposition all child widgets
209 updateArea();
210 signal_children_width_change(*this, children_width);
213 } // namespace CppConsUI
215 /* vim: set tabstop=2 shiftwidth=2 textwidth=78 expandtab : */