X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flist.cpp;h=f7cc4d73a2e94f6d503aab13cad5447b39838b1e;hb=b92c878a286036af106e969a29b2689876aa5f65;hp=afa7573ecb837a6fd45d04810105e4b85e651bf5;hpb=0af3c2393bd00f39db3bfaf5b78a7a44f0fd5ff1;p=libs%2Fgltk.git diff --git a/source/list.cpp b/source/list.cpp index afa7573..f7cc4d7 100644 --- a/source/list.cpp +++ b/source/list.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -12,6 +12,7 @@ Distributed under the LGPL #include "list.h" #include "part.h" #include "style.h" +#include "text.h" #include "vslider.h" using namespace std; @@ -19,27 +20,78 @@ using namespace std; namespace Msp { namespace GLtk { -List::List(const Resources &r): - Widget(r), - Container(r), +List::List(): sel_index(-1), first(0), n_visible(1), row_height(1), - items_part(0), - slider(res) + items_part(0) { add(slider); slider.set_step(1); slider.signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed)); +} - update_style(); +void List::autosize() +{ + autosize_rows(5); +} + +void List::autosize_rows(unsigned n) +{ + if(!style) + return; + + Widget::autosize(); + + if(items_part) + { + const Sides &margin = items_part->get_margin(); + float font_size = style->get_font()->get_default_size(); + + unsigned max_w = 0; + for(vector::iterator i=items.begin(); i!=items.end(); ++i) + { + unsigned w = static_cast(style->get_font()->get_string_width(*i)*font_size); + max_w = max(max_w, w); + } + + geom.w = max(geom.w, max_w+margin.left+margin.right); + geom.h = max(geom.h, n*row_height+margin.top+margin.bottom); + } + + if(const Part *slider_part = style->get_part("slider")) + { + Geometry sgeom = slider_part->get_geometry(); + if(!sgeom.w || !sgeom.h) + { + slider.autosize(); + if(!sgeom.w) + sgeom.w = slider.get_geometry().w; + if(!sgeom.h) + sgeom.h = slider.get_geometry().h; + } + + const Sides &margin = slider_part->get_margin(); + geom.w = max(geom.w, sgeom.w+margin.left+margin.right); + geom.h = max(geom.h, sgeom.h+margin.top+margin.bottom); + + reposition_slider(); + } + + check_view_range(); +} + +void List::autosize_all() +{ + autosize_rows(items.size()); } void List::append(const string &v) { items.push_back(v); - recalculate_parameters(); + check_view_range(); + signal_autosize_changed.emit(); } void List::insert(unsigned i, const string &v) @@ -48,7 +100,8 @@ void List::insert(unsigned i, const string &v) throw InvalidParameterValue("Index out of range"); items.insert(items.begin()+i, v); - recalculate_parameters(); + check_view_range(); + signal_autosize_changed.emit(); } void List::remove(unsigned i) @@ -62,7 +115,8 @@ void List::remove(unsigned i) else if(sel_index==static_cast(i)) sel_index = -1; - recalculate_parameters(); + check_view_range(); + signal_autosize_changed.emit(); } void List::clear() @@ -70,7 +124,8 @@ void List::clear() items.clear(); sel_index = -1; - recalculate_parameters(); + check_view_range(); + signal_autosize_changed.emit(); } void List::set_selected_index(int i) @@ -94,53 +149,22 @@ const string &List::get_selected() const return items[sel_index]; } -void List::button_press(int x, int y, unsigned btn) -{ - Container::button_press(x, y, btn); - if(!click_focus && btn==1) - { - if(items_part) - y += items_part->get_margin().top; - - unsigned i = (geom.h-1-y)/row_height; - if(iget_font(); - const float font_size = font.get_default_size(); - const GL::Color &color = style->get_font_color(); const Sides &margin = part.get_margin(); - Geometry pgeom = geom; - pgeom.h = row_height; - pgeom.w -= margin.left+margin.right; + pgeom.h = row_height+margin.top+margin.bottom; + + GL::PushMatrix push_mtx; + GL::translate(0, geom.h-pgeom.h, 0); for(unsigned i=0; (i(font.get_string_width(items[first+i])*font_size); - rgeom.h = row_height; - rgeom.x = margin.left; - rgeom.y = geom.h-margin.top-(i+1)*row_height-static_cast(font.get_descent()*font_size); - part.get_alignment().apply(rgeom, pgeom); - - GL::push_matrix(); - GL::translate(rgeom.x, rgeom.y, 0); - GL::scale_uniform(font_size); - GL::Immediate imm((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2)); - imm.color(color.r, color.g, color.b); - font.draw_string(items[first+i], imm); - GL::pop_matrix(); + if(i!=0) + GL::translate(0, -static_cast(row_height), 0); + Text(*style, items[first+i]).render(part, pgeom); } } else if(part.get_name()=="selection") @@ -168,40 +192,63 @@ void List::render_special(const Part &part) const slider.render(); } +void List::button_press(int x, int y, unsigned btn) +{ + Container::button_press(x, y, btn); + if(!click_focus && btn==1) + { + if(items_part) + y += items_part->get_margin().top; + + unsigned i = (geom.h-1-y)/row_height; + if(i::const_iterator i=style->get_parts().begin(); i!=style->get_parts().end(); ++i) - if(i->get_name()=="items") - items_part = &*i; + items_part = style->get_part("items"); const GL::Font &font = *style->get_font(); row_height = static_cast((font.get_ascent()-font.get_descent())*font.get_default_size()); - recalculate_parameters(); + check_view_range(); } void List::reposition_slider() { - for(list::const_iterator i=style->get_parts().begin(); i!=style->get_parts().end(); ++i) - if(i->get_name()=="slider") - { - Geometry sgeom = i->get_geometry(); - i->get_alignment().apply(sgeom, geom, i->get_margin()); - slider.set_geometry(sgeom); - } + if(!style) + return; + + if(const Part *slider_part = style->get_part("slider")) + { + Geometry sgeom = slider_part->get_geometry(); + slider_part->get_alignment().apply(sgeom, geom, slider_part->get_margin()); + slider.set_geometry(sgeom); + } } -void List::recalculate_parameters() +void List::check_view_range() { unsigned h = geom.h; if(items_part) @@ -247,7 +294,7 @@ List::Loader::Loader(List &l): void List::Loader::item(const string &v) { - dynamic_cast(wdg).append(v); + dynamic_cast(obj).append(v); } } // namespace GLtk