2 * Copyright (C) 2007 by Mark Pustjens <pustjens@dds.nl>
3 * Copyright (C) 2010-2012 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/>.
24 * ListBox class implementation.
34 ListBox::ListBox(int w
, int h
)
35 : AbstractListBox(w
, h
), children_height(0), autosize_children(0)
36 , autosize_height(0), reposition_widgets(false)
38 // allow fast focus changing (paging) using PageUp/PageDown keys
45 // set virtual scroll area width
47 SetScrollWidth(screen_area
->getmaxx());
50 reposition_widgets
= true;
51 ProceedUpdateVirtualArea();
54 // scrollpane will clear the screen (real) area
55 AbstractListBox::Draw();
59 if (reposition_widgets
) {
61 int autosize_height_extra
= 0;
62 int realh
= area
->getmaxy();
63 if (autosize_children
&& children_height
< realh
) {
64 int space
= realh
- (children_height
- autosize_children
);
65 autosize_height
= space
/ autosize_children
;
66 autosize_height_extra
= space
% autosize_children
;
68 autosize_extra
.clear();
71 for (Children::iterator i
= children
.begin(); i
!= children
.end(); i
++) {
72 Widget
*widget
= i
->widget
;
73 if (!widget
->IsVisible())
76 int h
= widget
->GetHeight();
79 if (autosize_height_extra
) {
80 autosize_extra
.insert(widget
);
81 autosize_height_extra
--;
85 // make sure the area is updated
92 reposition_widgets
= false;
95 // make sure that currently focused widget is visible
97 int h
= focus_child
->GetHeight();
100 if (autosize_extra
.find(focus_child
) != autosize_extra
.end())
104 MakeVisible(focus_child
->GetLeft(), focus_child
->GetTop(), 1, h
);
107 AbstractListBox::Draw();
110 HorizontalLine
*ListBox::InsertSeparator(size_t pos
)
112 HorizontalLine
*l
= new HorizontalLine(AUTOSIZE
);
113 InsertWidget(pos
, *l
);
117 HorizontalLine
*ListBox::AppendSeparator()
119 HorizontalLine
*l
= new HorizontalLine(AUTOSIZE
);
124 void ListBox::InsertWidget(size_t pos
, Widget
& widget
)
126 if (widget
.IsVisible()) {
127 int h
= widget
.GetHeight();
132 children_height
+= h
;
133 UpdateScrollHeight();
136 // note: widget is moved to a correct position in Draw() method
137 ScrollPane::InsertWidget(pos
, widget
, 0, 0);
138 reposition_widgets
= true;
140 if (widget
.IsVisible())
141 signal_children_height_change(*this, children_height
);
144 void ListBox::AppendWidget(Widget
& widget
)
146 InsertWidget(children
.size(), widget
);
149 Curses::Window
*ListBox::GetSubPad(const Widget
& child
, int begin_x
,
150 int begin_y
, int ncols
, int nlines
)
153 if (nlines
== AUTOSIZE
) {
154 nlines
= autosize_height
;
155 if (autosize_extra
.find(&child
) != autosize_extra
.end())
159 return AbstractListBox::GetSubPad(child
, begin_x
, begin_y
, ncols
, nlines
);
162 void ListBox::OnChildMoveResize(Widget
& /*activator*/, const Rect
& oldsize
,
165 int old_height
= oldsize
.GetHeight();
166 int new_height
= newsize
.GetHeight();
167 if (old_height
!= new_height
) {
168 if (old_height
== AUTOSIZE
) {
172 if (new_height
== AUTOSIZE
) {
176 children_height
+= new_height
- old_height
;
177 reposition_widgets
= true;
178 UpdateScrollHeight();
180 signal_children_height_change(*this, children_height
);
184 void ListBox::OnChildVisible(Widget
& activator
, bool visible
)
186 // the widget is being hidden or deleted
187 int height
= activator
.GetHeight();
188 int sign
= visible
? 1 : -1;
189 if (height
== AUTOSIZE
) {
190 autosize_children
+= sign
;
193 children_height
+= sign
* height
;
194 reposition_widgets
= true;
195 UpdateScrollHeight();
197 signal_children_height_change(*this, children_height
);
200 void ListBox::UpdateScrollHeight()
204 realh
= screen_area
->getmaxy();
206 SetScrollHeight(MAX(realh
, children_height
));
209 } // namespace CppConsUI
211 /* vim: set tabstop=2 shiftwidth=2 textwidth=78 expandtab : */