]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/dropdown.cpp
Rework how widget ownership works in Container
[libs/gltk.git] / source / dropdown.cpp
index 84f6af30422203d8ff26ecd9f3db0d111898fc42..ab00c4c3f0c7bd06c0edc453d18c0315ebf36063 100644 (file)
@@ -25,11 +25,13 @@ Dropdown::Dropdown(ListData &d):
 
 void Dropdown::init()
 {
-       dropped = false;
+       input_type = INPUT_NAVIGATION;
 
        add(list);
+       list.set_visible(false);
        list.set_view_all();
        list.signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected));
+       list.signal_selection_cleared.connect(sigc::mem_fun(this, &Dropdown::list_selection_cleared));
        list.signal_autosize_changed.connect(sigc::mem_fun(this, &Dropdown::list_autosize_changed));
 }
 
@@ -49,7 +51,7 @@ void Dropdown::autosize_special(const Part &part, Geometry &ageom) const
 
                unsigned max_w = 0;
                const ListData &data = list.get_data();
-               for(unsigned i=0; i<data.size(); ++i)
+               for(size_t i=0; i<data.size(); ++i)
                {
                        unsigned w = static_cast<unsigned>(font.get_string_width(data.get_string(i))*font_size);
                        max_w = max(max_w, w);
@@ -61,13 +63,6 @@ void Dropdown::autosize_special(const Part &part, Geometry &ageom) const
        }
 }
 
-void Dropdown::set_selected_index(int index)
-{
-       list.set_selected_index(index);
-       if(index<0)
-               text.set(string());
-}
-
 void Dropdown::rebuild_special(const Part &part)
 {
        if(part.get_name()=="text")
@@ -88,34 +83,64 @@ void Dropdown::button_press(int x, int y, unsigned btn)
        {
                Container::button_press(x, y, btn);
                if(!click_focus)
-               {
-                       dropped = false;
-                       clear_state(ACTIVE);
-                       signal_ungrab_pointer.emit();
-               }
+                       close_list();
        }
        else if(btn==1)
+               open_list();
+}
+
+bool Dropdown::navigate(Navigation nav)
+{
+       if(dropped)
        {
-               dropped = true;
-               set_state(ACTIVE);
-               signal_grab_pointer.emit();
+               if(nav==NAV_CANCEL)
+                       close_list();
+               else
+                       list.navigate(nav);
        }
+       else if(nav==NAV_ACTIVATE)
+               open_list();
+       else
+               return false;
+
+       return true;
 }
 
-void Dropdown::on_geometry_change()
+void Dropdown::on_size_change()
 {
-       resize_list();
+       if(dropped)
+               resize_list();
 }
 
 void Dropdown::on_style_change()
 {
        text.set_style(style);
+       if(dropped)
+               resize_list();
+}
+
+void Dropdown::open_list()
+{
+       dropped = true;
+       list.set_visible(true);
        resize_list();
+       set_state(ACTIVE);
+       set_input_focus(&list);
+       signal_grab_pointer.emit();
+}
+
+void Dropdown::close_list()
+{
+       dropped = false;
+       list.set_visible(false);
+       clear_state(ACTIVE);
+       signal_ungrab_pointer.emit();
 }
 
 void Dropdown::list_autosize_changed()
 {
-       resize_list();
+       if(dropped)
+               resize_list();
        signal_autosize_changed.emit();
 }
 
@@ -136,7 +161,10 @@ void Dropdown::resize_list()
                {
                        const Geometry &rgeom = root->get_geometry();
                        if(lgeom.h*2>rgeom.h)
+                       {
                                lgeom.h = rgeom.h/2;
+                               lgeom.y = -lgeom.h;
+                       }
                        if(root_y+lgeom.y<0)
                                lgeom.y = -root_y;
                        if(root_y+lgeom.y+lgeom.h>rgeom.h)
@@ -149,7 +177,7 @@ void Dropdown::resize_list()
        list.set_geometry(lgeom);
 }
 
-void Dropdown::list_item_selected(unsigned index)
+void Dropdown::list_item_selected(size_t index)
 {
        if(dropped)
        {
@@ -161,7 +189,12 @@ void Dropdown::list_item_selected(unsigned index)
        text.set(list.get_data().get_string(index));
 
        signal_item_selected.emit(index);
-       rebuild();
+       mark_rebuild();
+}
+
+void Dropdown::list_selection_cleared()
+{
+       text.set(string());
 }