X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flist.cpp;h=8c26ef745815ccdfa95540dadba1641a0eabde32;hb=1d84ac50711ce9d23cb1dafd83158d4ffa938a15;hp=218b26bd1410b82d7f33fb80c0dd6cbfa3bf86f1;hpb=371dd319aea53d727a91c64240b942dab983783a;p=libs%2Fgltk.git diff --git a/source/list.cpp b/source/list.cpp index 218b26b..8c26ef7 100644 --- a/source/list.cpp +++ b/source/list.cpp @@ -13,17 +13,41 @@ namespace Msp { namespace GLtk { List::List(): - sel_index(-1), - first(0), - n_visible(1), - row_height(1), - items_part(0) + data(new BasicListData), + own_data(true) { + init(); +} + +List::List(ListData &d): + data(&d), + own_data(false) +{ + init(); +} + +void List::init() +{ + sel_index = -1; + first = 0; + n_visible = 1; + row_height = 1; + items_part = 0; + + observer = new DataObserver(*this); + add(slider); slider.set_step(1); slider.signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed)); } +List::~List() +{ + delete observer; + if(own_data) + delete data; +} + void List::autosize() { autosize_rows(5); @@ -43,9 +67,10 @@ void List::autosize_rows(unsigned n) float font_size = style->get_font_size(); unsigned max_w = 0; - for(vector::iterator i=items.begin(); i!=items.end(); ++i) + unsigned n_items = data->size(); + for(unsigned i=0; i(font.get_string_width(*i)*font_size); + unsigned w = static_cast(font.get_string_width(data->get_string(i))*font_size); max_w = max(max_w, w); } @@ -78,45 +103,22 @@ void List::autosize_rows(unsigned n) void List::autosize_all() { - autosize_rows(items.size()); + autosize_rows(data->size()); } -void List::append(const string &v) +void List::set_data(ListData &d) { - items.push_back(v); - items_changed(); -} - -void List::insert(unsigned i, const string &v) -{ - if(i>items.size()) - throw out_of_range("List::insert"); - - items.insert(items.begin()+i, v); - items_changed(); -} + delete observer; + if(own_data) + delete data; -void List::remove(unsigned i) -{ - if(i>items.size()) - throw out_of_range("List::remove"); - - items.erase(items.begin()+i); - if(sel_index>static_cast(i)) - --sel_index; - else if(sel_index==static_cast(i)) - sel_index = -1; + data = &d; + own_data = false; + observer = new DataObserver(*this); items_changed(); } -void List::clear() -{ - items.clear(); - sel_index = -1; - items_changed(); -} - void List::items_changed() { check_view_range(); @@ -128,24 +130,16 @@ void List::set_selected_index(int i) { if(i<0) sel_index = -1; - else if(i(items.size())) + else if(i(data->size())) { sel_index = i; - signal_item_selected.emit(sel_index, items[sel_index]); + signal_item_selected.emit(sel_index); rebuild(); } else throw out_of_range("List::set_selected_index"); } -const string &List::get_selected() const -{ - if(sel_index<0) - throw logic_error("sel_index<0"); - - return items[sel_index]; -} - void List::rebuild_special(const Part &part, CachedPart &cache) { if(part.get_name()=="items") @@ -162,7 +156,7 @@ void List::rebuild_special(const Part &part, CachedPart &cache) bld.color(style->get_font_color()); bld.matrix() *= GL::Matrix::translation(margin.left, geom.h-pgeom.h-font.get_descent()*style->get_font_size(), 0); - for(unsigned i=0; (isize()); ++i) { if(i!=0) bld.matrix() *= GL::Matrix::translation(0, -static_cast(row_height), 0); @@ -170,7 +164,7 @@ void List::rebuild_special(const Part &part, CachedPart &cache) GL::MatrixStack::Push _pushm(bld.matrix()); bld.matrix() *= GL::Matrix::scaling(style->get_font_size()); - style->get_font().build_string(items[first+i], bld); + style->get_font().build_string(data->get_string(first+i), bld); } } else if(part.get_name()=="selection") @@ -215,11 +209,11 @@ void List::button_press(int x, int y, unsigned btn) y += items_part->get_margin().top; unsigned i = (geom.h-1-y)/row_height; - if(isize()) { sel_index = first+i; - signal_item_selected.emit(sel_index, items[sel_index]); + signal_item_selected.emit(sel_index); rebuild(); } } @@ -274,18 +268,18 @@ void List::check_view_range() n_visible = h/row_height; - if(first+n_visible>items.size()) + if(first+n_visible>data->size()) { - if(items.size()>n_visible) - first = items.size()-n_visible; + if(data->size()>n_visible) + first = data->size()-n_visible; else first = 0; } - if(items.size()>n_visible) + if(data->size()>n_visible) { - slider.set_range(0, items.size()-n_visible); - slider.set_value(items.size()-n_visible-first); + slider.set_range(0, data->size()-n_visible); + slider.set_value(data->size()-n_visible-first); } else { @@ -296,14 +290,53 @@ void List::check_view_range() void List::slider_value_changed(double value) { - if(items.size()>n_visible) + if(data->size()>n_visible) { - first = items.size()-n_visible-static_cast(value); + first = data->size()-n_visible-static_cast(value); rebuild(); } } +List::DataObserver::DataObserver(List &l): + 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)); +} + +void List::DataObserver::item_added(unsigned i) +{ + if(list.sel_index>=static_cast(i)) + ++list.sel_index; + + list.items_changed(); +} + +void List::DataObserver::item_removed(unsigned i) +{ + if(list.sel_index>static_cast(i)) + --list.sel_index; + else if(list.sel_index==static_cast(i)) + list.sel_index = -1; + + list.items_changed(); +} + +void List::DataObserver::cleared() +{ + list.sel_index = -1; + list.items_changed(); +} + +void List::DataObserver::refresh_strings() +{ + list.items_changed(); +} + + List::Loader::Loader(List &l): Widget::Loader(l) { @@ -312,7 +345,7 @@ List::Loader::Loader(List &l): void List::Loader::item(const string &v) { - dynamic_cast(obj).append(v); + dynamic_cast &>(*dynamic_cast(obj).data).append(v); } } // namespace GLtk