Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

listbox_generic.cpp

Go to the documentation of this file.
00001 /*
00002         ClanGUI, copyrights by various people. Have a look in the CREDITS file.
00003         
00004         This sourcecode is distributed using the Library GNU Public Licence,
00005         version 2 or (at your option) any later version. Please read LICENSE
00006         for details.
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 // Construction:
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         // Fetch items
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         // Create client area (which is the main listbox)
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         // Create a scrollbar
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 // Attributes:
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 // Operations:
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         // TODO: Run some update here
00219         max_visible_items = count;
00220 }
00221 
00222 void CL_ListBox_Generic::set_top_item(int index)
00223 {
00224         // TODO: Check range
00225         scroll_offset = index;
00226 }
00227 
00229 // Callbacks:
00230 
00231 void CL_ListBox_Generic::on_key_down(CL_Component *comp, CL_InputDevice *device, CL_Key key)
00232 {
00233         // TODO: This is NOT nice...find a better way:
00234 //      if (device != CL_Input::pointers[0] || key.id != 0) return;
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)     // Left side
00251                 rect_clientarea.x1 = rect_child.x2 + 2;
00252         else
00253                 rect_clientarea.x2 = rect_child.x1 - 2;
00254 /*
00255         if(rect_child.y2 < rect_clientarea.get_height() / 2)    // Top side
00256                 rect_clientarea.y1 = rect_child.y2;
00257         else
00258                 rect_clientarea.y2 = rect_child.y1;
00259 */
00260         client_area->set_position(rect_clientarea);
00261 }
00262 
00263 void CL_ListBox_Generic::on_child_remove(CL_Component *child)
00264 {
00265 }

Generated at Wed Apr 4 19:54:01 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001