00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "precomp.h"
00010 #include "listbox_generic.h"
00011 #include "API/GUI/listbox.h"
00012 #include "API/GUI/scrollbar.h"
00013 #include "API/GUI/component.h"
00014 #include "API/GUI/component_options.h"
00015 #include "API/GUI/stylemanager.h"
00016 #include "API/Display/Input/input.h"
00017
00019
00020
00021 CL_ComponentOptions CL_ListBox_Generic::create_options(
00022 const CL_Rect &pos)
00023 {
00024 CL_ComponentOptions options;
00025
00026 options.add_option_as_int("x", pos.x1);
00027 options.add_option_as_int("y", pos.y1);
00028 options.add_option_as_int("width", pos.get_width());
00029 options.add_option_as_int("height", pos.get_height());
00030
00031 return options;
00032 }
00033
00034 CL_ListBox_Generic::CL_ListBox_Generic(CL_ListBox *self, const CL_ComponentOptions &options, CL_StyleManager *style)
00035 :
00036 listbox(self)
00037 {
00038 highlighted_item = -1;
00039 item_height = 16;
00040 max_visible_items = 18;
00041 scroll_offset = 0;
00042 has_scrollbar = true;
00043
00044
00045 int item_count = options.count("item");
00046 for (int i = 0; i < item_count; i++)
00047 items.push_back(options.get_value("item", i));
00048
00049
00050 CL_Rect rect(4, 4, listbox->get_width() - 4, listbox->get_height() - 4);
00051 client_area = new CL_Component(rect, listbox, style);
00052
00053
00054 rect = CL_Rect(listbox->get_width() - 19, 3, listbox->get_width() - 3, listbox->get_height() - 3);
00055 int range = get_count() - max_visible_items;
00056 scrollbar = new CL_ScrollBar(rect, 0, range, false, listbox, style);
00057 update_scrollbar();
00058
00059 slot_on_key_down = client_area->sig_key_down().connect(
00060 CL_CreateSlot(this, &CL_ListBox_Generic::on_key_down));
00061 slot_child_add = listbox->sig_child_add().connect(
00062 CL_CreateSlot(this, &CL_ListBox_Generic::on_child_add));
00063 slot_child_remove = listbox->sig_child_remove().connect(
00064 CL_CreateSlot(this, &CL_ListBox_Generic::on_child_remove));
00065 slot_on_scroll_change = scrollbar->sig_value_changed().connect(
00066 CL_CreateSlot(this, &CL_ListBox_Generic::on_scroll_change));
00067 }
00068
00069 void CL_ListBox_Generic::update_scrollbar()
00070 {
00071 if (get_count() > max_visible_items)
00072 {
00073 if(has_scrollbar == false)
00074 {
00075 has_scrollbar = true;
00076 listbox->add_child(scrollbar, true);
00077 }
00078
00079 scrollbar->set_max_value(get_count() - max_visible_items);
00080 }
00081 else {
00082 if(has_scrollbar)
00083 {
00084 has_scrollbar = false;
00085 listbox->remove_child(scrollbar);
00086 }
00087 }
00088 }
00089
00091
00092
00093 int CL_ListBox_Generic::get_count() const
00094 {
00095 return items.size();
00096 }
00097
00098 std::list<std::string> &CL_ListBox_Generic::get_items()
00099 {
00100 return items;
00101 }
00102
00103 std::string CL_ListBox_Generic::get_text(int index) const
00104 {
00105 int pos = 0;
00106 std::list<std::string>::const_iterator it;
00107 for(it = items.begin(); it != items.end(); it++, pos++)
00108 if(pos == index)
00109 return (*it);
00110
00111 return "";
00112 }
00113
00114 std::string CL_ListBox_Generic::get_current_text() const
00115 {
00116 return get_text(highlighted_item);
00117 }
00118
00119 int CL_ListBox_Generic::get_current_item() const
00120 {
00121 return highlighted_item;
00122 }
00123
00124 bool CL_ListBox_Generic::is_selected(int index) const
00125 {
00126 return (highlighted_item == index);
00127 }
00128
00129 int CL_ListBox_Generic::get_item_height() const
00130 {
00131 return item_height;
00132 }
00133
00134 int CL_ListBox_Generic::get_top_item() const
00135 {
00136 return scroll_offset;
00137 }
00138
00140
00141
00142 int CL_ListBox_Generic::insert_item(const std::string &item, int index)
00143 {
00144 if(index < 0)
00145 items.push_back(item);
00146 else
00147 throw CL_Error("CL_ListBox::insert_item() using index is not implemented");
00148
00149 update_scrollbar();
00150
00151 return items.size() - 1;
00152 }
00153
00154 void CL_ListBox_Generic::remove_item(int index)
00155 {
00156 if(index < 0 || index > get_count())
00157 return;
00158
00159 int pos = 0;
00160 std::list<std::string>::iterator it;
00161 for (it = items.begin(); it != items.end(); ++it, ++pos)
00162 {
00163 if(pos == index)
00164 {
00165 items.erase(it);
00166 break;
00167 }
00168 }
00169
00170 if(highlighted_item >= get_count())
00171 highlighted_item = -1;
00172
00173 if(get_count() - scroll_offset < max_visible_items)
00174 scroll_offset = 0;
00175
00176 update_scrollbar();
00177 }
00178
00179 void CL_ListBox_Generic::change_item(const std::string &text, int index)
00180 {
00181 throw CL_Error("CL_ListBox::change_item() is not implemented");
00182 }
00183
00184 void CL_ListBox_Generic::set_current_item(int index)
00185 {
00186 if(index < 0 || index >= get_count())
00187 return;
00188
00189 highlighted_item = index;
00190 sig_activated(highlighted_item);
00191 }
00192
00193 void CL_ListBox_Generic::clear_selection()
00194 {
00195 highlighted_item = -1;
00196 }
00197
00198 void CL_ListBox_Generic::set_item_height(int height)
00199 {
00200 item_height = height;
00201 }
00202
00203 void CL_ListBox_Generic::sort(bool ascending)
00204 {
00205 throw CL_Error("CL_ListBox::sort() is not implemented");
00206 }
00207
00208 void CL_ListBox_Generic::clear()
00209 {
00210 items.clear();
00211 highlighted_item = -1;
00212
00213 update_scrollbar();
00214 }
00215
00216 void CL_ListBox_Generic::set_max_visible_items(int count)
00217 {
00218
00219 max_visible_items = count;
00220 }
00221
00222 void CL_ListBox_Generic::set_top_item(int index)
00223 {
00224
00225 scroll_offset = index;
00226 }
00227
00229
00230
00231 void CL_ListBox_Generic::on_key_down(CL_Component *comp, CL_InputDevice *device, CL_Key key)
00232 {
00233
00234
00235
00236 int index = (int)(key.y / item_height + scroll_offset);
00237 set_current_item(index);
00238 }
00239
00240 void CL_ListBox_Generic::on_scroll_change(int new_offset)
00241 {
00242 set_top_item(new_offset);
00243 }
00244
00245 void CL_ListBox_Generic::on_child_add(CL_Component *child)
00246 {
00247 CL_Rect rect_child = child->get_position();
00248 CL_Rect rect_clientarea = client_area->get_position();
00249
00250 if(rect_child.x2 < rect_clientarea.get_width() / 2)
00251 rect_clientarea.x1 = rect_child.x2 + 2;
00252 else
00253 rect_clientarea.x2 = rect_child.x1 - 2;
00254
00255
00256
00257
00258
00259
00260 client_area->set_position(rect_clientarea);
00261 }
00262
00263 void CL_ListBox_Generic::on_child_remove(CL_Component *child)
00264 {
00265 }