]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/list.cpp
Retain position when autosizing widget
[libs/gltk.git] / source / list.cpp
index ec3f9942d458eece47a62f4eb2ee2b233c5d54b7..eaab9e0e5ed8857a0bdaea7e779374577efbf7da 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/debug/demangle.h>
 #include <msp/gl/matrix.h>
 #include <msp/gl/meshbuilder.h>
 #include "graphic.h"
@@ -12,6 +13,11 @@ using namespace std;
 namespace Msp {
 namespace GLtk {
 
+incompatible_data::incompatible_data(const type_info &ti):
+       logic_error("expected "+Debug::demangle(ti.name()))
+{ }
+
+
 List::List():
        data(new BasicListData<string>),
        own_data(true)
@@ -28,6 +34,7 @@ List::List(ListData &d):
 
 void List::init()
 {
+       item_factory = 0;
        sel_index = -1;
        first = 0;
        max_scroll = 0;
@@ -42,6 +49,7 @@ void List::init()
 
 List::~List()
 {
+       delete item_factory;
        delete observer;
        if(own_data)
                delete data;
@@ -74,6 +82,9 @@ void List::autosize_special(const Part &part, Geometry &ageom)
 
 void List::set_data(ListData &d)
 {
+       if(item_factory)
+               item_factory->set_data(d);
+
        delete observer;
        if(own_data)
                delete data;
@@ -105,7 +116,10 @@ void List::items_changed()
 
 List::Item *List::create_item(unsigned index)
 {
-       return new BasicItem(data->get_string(index));
+       if(item_factory)
+               return item_factory->create_item(index);
+       else
+               return new BasicItem(data->get_string(index));
 }
 
 void List::set_view_size(unsigned s)
@@ -121,7 +135,7 @@ void List::set_view_all()
 
 void List::set_selected_index(int i)
 {
-       if(i>static_cast<int>(data->size()))
+       if(i>=static_cast<int>(data->size()))
                throw out_of_range("List::set_selected_index");
 
        if(sel_index>=0)
@@ -275,7 +289,7 @@ List::DataObserver::DataObserver(List &l):
        list.data->signal_item_added.connect(sigc::mem_fun(this, &DataObserver::item_added));
        list.data->signal_item_removed.connect(sigc::mem_fun(this, &DataObserver::item_removed));
        list.data->signal_cleared.connect(sigc::mem_fun(this, &DataObserver::cleared));
-       list.data->signal_refresh_strings.connect(sigc::mem_fun(this, &DataObserver::refresh_strings));
+       list.data->signal_refresh_item.connect(sigc::mem_fun(this, &DataObserver::refresh_item));
 }
 
 void List::DataObserver::item_added(unsigned i)
@@ -310,8 +324,10 @@ void List::DataObserver::cleared()
        list.items_changed();
 }
 
-void List::DataObserver::refresh_strings()
+void List::DataObserver::refresh_item(unsigned i)
 {
+       delete list.items[i];
+       list.items[i] = list.create_item(i);
        list.items_changed();
 }