From: Mikko Rasa Date: Fri, 12 Nov 2010 20:43:38 +0000 (+0000) Subject: Implement autosize for List and use it from Dropdown X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=deb15ee122f963ca41121e8358d5845401ac43ca;p=libs%2Fgltk.git Implement autosize for List and use it from Dropdown Rename List::recalculate_parameters to check_view_range Use Text for rendering List items Check view range of multiline entries in more places --- diff --git a/source/dropdown.cpp b/source/dropdown.cpp index 5901414..d120c85 100644 --- a/source/dropdown.cpp +++ b/source/dropdown.cpp @@ -112,17 +112,9 @@ void Dropdown::on_geometry_change() void Dropdown::resize_list() { - // XXX This is a hack. - unsigned n_items = list.get_n_items(); - const Style &stl = list.get_style(); - const GL::Font &font = *stl.get_font(); - unsigned h = min(max(n_items, 1U), 10U)*static_cast((font.get_ascent()-font.get_descent())*font.get_default_size()); - if(const Part *items_part = stl.get_part("items")) - { - const Sides &margin = items_part->get_margin(); - h += margin.top+margin.bottom; - } - list.set_geometry(Geometry(0, -h, geom.w, h)); + list.autosize(); + const Geometry &lgeom = list.get_geometry(); + list.set_geometry(Geometry(0, -lgeom.h, max(geom.w, lgeom.w), lgeom.h)); } void Dropdown::list_item_selected(unsigned index, const std::string &item) diff --git a/source/entry.cpp b/source/entry.cpp index 1439d42..8853ad7 100644 --- a/source/entry.cpp +++ b/source/entry.cpp @@ -39,18 +39,25 @@ void Entry::set_text(const string &t) { text = t; edit_pos = text.size(); + + if(multiline) + check_view_range(); } void Entry::set_multiline(bool m) { multiline = m; - if(multiline && !slider) + if(multiline) { - slider = new VSlider(res); - add(*slider); - slider->set_step(1); - slider->signal_value_changed.connect(sigc::mem_fun(this, &Entry::slider_value_changed)); - reposition_slider(); + if(!slider) + { + slider = new VSlider(res); + add(*slider); + slider->set_step(1); + slider->signal_value_changed.connect(sigc::mem_fun(this, &Entry::slider_value_changed)); + reposition_slider(); + } + check_view_range(); } } @@ -145,6 +152,9 @@ void Entry::render_special(const Part &part) const void Entry::on_geometry_change() { reposition_slider(); + + if(multiline) + check_view_range(); } void Entry::on_style_change() @@ -153,6 +163,9 @@ void Entry::on_style_change() text.set_style(style); reposition_slider(); + + if(multiline) + check_view_range(); } void Entry::reposition_slider() diff --git a/source/list.cpp b/source/list.cpp index 59d13dc..113871e 100644 --- a/source/list.cpp +++ b/source/list.cpp @@ -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; @@ -36,10 +37,31 @@ List::List(const Resources &r): update_style(); } +void List::autosize() +{ + float font_size = style->get_font()->get_default_size(); + + geom.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); + geom.w = max(geom.w, w); + } + + geom.h = items.size()*row_height; + + if(items_part) + { + const Sides &margin = items_part->get_margin(); + geom.w += margin.left+margin.right; + geom.h += margin.top+margin.bottom; + } +} + void List::append(const string &v) { items.push_back(v); - recalculate_parameters(); + check_view_range(); } void List::insert(unsigned i, const string &v) @@ -48,7 +70,7 @@ 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(); } void List::remove(unsigned i) @@ -62,7 +84,7 @@ void List::remove(unsigned i) else if(sel_index==static_cast(i)) sel_index = -1; - recalculate_parameters(); + check_view_range(); } void List::clear() @@ -70,7 +92,7 @@ void List::clear() items.clear(); sel_index = -1; - recalculate_parameters(); + check_view_range(); } void List::set_selected_index(int i) @@ -116,31 +138,18 @@ void List::render_special(const Part &part) const { if(part.get_name()=="items") { - const GL::Font &font = *style->get_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") @@ -172,7 +181,7 @@ void List::on_geometry_change() { reposition_slider(); - recalculate_parameters(); + check_view_range(); } void List::on_style_change() @@ -184,7 +193,7 @@ void List::on_style_change() 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() @@ -197,7 +206,7 @@ void List::reposition_slider() } } -void List::recalculate_parameters() +void List::check_view_range() { unsigned h = geom.h; if(items_part) diff --git a/source/list.h b/source/list.h index dee57ed..426d309 100644 --- a/source/list.h +++ b/source/list.h @@ -46,6 +46,8 @@ public: List(const Resources &); + virtual void autosize(); + void append(const std::string &); void insert(unsigned, const std::string &); void remove(unsigned); @@ -65,7 +67,7 @@ private: virtual void on_geometry_change(); virtual void on_style_change(); void reposition_slider(); - void recalculate_parameters(); + void check_view_range(); void slider_value_changed(double); };