X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flist.cpp;h=218b26bd1410b82d7f33fb80c0dd6cbfa3bf86f1;hb=e5da6bc3e1f32342e661893fbb3c1cf873422c2e;hp=672cf4911bbf028e4e3850579959794e9c4f11f2;hpb=91997dd3189b93a67179822ec2fed5f2a7bddb74;p=libs%2Fgltk.git diff --git a/source/list.cpp b/source/list.cpp index 672cf49..218b26b 100644 --- a/source/list.cpp +++ b/source/list.cpp @@ -1,13 +1,5 @@ -/* $Id$ - -This file is part of libmspgltk -Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#include #include -#include +#include #include "graphic.h" #include "list.h" #include "part.h" @@ -33,48 +25,81 @@ List::List(): } void List::autosize() +{ + autosize_rows(5); +} + +void List::autosize_rows(unsigned n) { if(!style) return; - float font_size = style->get_font()->get_default_size(); + Widget::autosize(); - geom.w = 0; - for(vector::iterator i=items.begin(); i!=items.end(); ++i) + if(items_part) { - unsigned w = static_cast(style->get_font()->get_string_width(*i)*font_size); - geom.w = max(geom.w, w); - } + const Sides &margin = items_part->get_margin(); + const GL::Font &font = style->get_font(); + float font_size = style->get_font_size(); - geom.h = items.size()*row_height; + unsigned max_w = 0; + for(vector::iterator i=items.begin(); i!=items.end(); ++i) + { + unsigned w = static_cast(font.get_string_width(*i)*font_size); + max_w = max(max_w, w); + } - if(items_part) + 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")) { - const Sides &margin = items_part->get_margin(); - geom.w += margin.left+margin.right; - geom.h += margin.top+margin.bottom; + 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(); + rebuild(); +} + +void List::autosize_all() +{ + autosize_rows(items.size()); } void List::append(const string &v) { items.push_back(v); - check_view_range(); + items_changed(); } void List::insert(unsigned i, const string &v) { if(i>items.size()) - throw InvalidParameterValue("Index out of range"); + throw out_of_range("List::insert"); items.insert(items.begin()+i, v); - check_view_range(); + items_changed(); } void List::remove(unsigned i) { if(i>items.size()) - throw InvalidParameterValue("Index out of range"); + throw out_of_range("List::remove"); items.erase(items.begin()+i); if(sel_index>static_cast(i)) @@ -82,15 +107,21 @@ void List::remove(unsigned i) else if(sel_index==static_cast(i)) sel_index = -1; - check_view_range(); + items_changed(); } void List::clear() { items.clear(); sel_index = -1; + items_changed(); +} +void List::items_changed() +{ check_view_range(); + signal_autosize_changed.emit(); + rebuild(); } void List::set_selected_index(int i) @@ -101,38 +132,21 @@ void List::set_selected_index(int i) { sel_index = i; signal_item_selected.emit(sel_index, items[sel_index]); + rebuild(); } else - throw InvalidParameterValue("Index out of range"); + throw out_of_range("List::set_selected_index"); } const string &List::get_selected() const { if(sel_index<0) - throw InvalidState("No selection"); + throw logic_error("sel_index<0"); 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(); + cache.texture = &font.get_texture(); + cache.clear_mesh(); + + GL::MeshBuilder bld(*cache.mesh); + 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; (i(row_height), 0); - Text(*style, items[first+i]).render(part, pgeom); + bld.matrix() *= GL::Matrix::translation(0, -static_cast(row_height), 0); + + GL::MatrixStack::Push _pushm(bld.matrix()); + bld.matrix() *= GL::Matrix::scaling(style->get_font_size()); + + style->get_font().build_string(items[first+i], bld); } } else if(part.get_name()=="selection") @@ -165,14 +188,41 @@ void List::render_special(const Part &part) const rgeom.x += margin.left; part.get_alignment().apply(rgeom, pgeom); - GL::push_matrix(); - GL::translate(rgeom.x, rgeom.y, 0); - part.get_graphic(state)->render(rgeom.w, rgeom.h); - GL::pop_matrix(); + cache.texture = part.get_graphic(state)->get_texture(); + cache.clear_mesh(); + + GL::MeshBuilder bld(*cache.mesh); + bld.matrix() *= GL::Matrix::translation(rgeom.x, rgeom.y, 0); + part.get_graphic(state)->build(rgeom.w, rgeom.h, bld); + } + else + cache.texture = 0; + } +} + +void List::render_special(const Part &part, GL::Renderer &renderer) const +{ + if(part.get_name()=="slider") + slider.render(renderer); +} + +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_part("items"); - const GL::Font &font = *style->get_font(); - row_height = static_cast((font.get_ascent()-font.get_descent())*font.get_default_size()); + const GL::Font &font = style->get_font(); + row_height = static_cast((font.get_ascent()-font.get_descent())*style->get_font_size()); check_view_range(); } @@ -247,7 +297,10 @@ void List::check_view_range() void List::slider_value_changed(double value) { if(items.size()>n_visible) + { first = items.size()-n_visible-static_cast(value); + rebuild(); + } } @@ -259,7 +312,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