]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/list.cpp
Add method to get a Part by name
[libs/gltk.git] / source / list.cpp
index 4f8b27c649a909ddd8fabd7ce7c7db1f273d2c30..59d13dcc7236a358b18c19d29ed40602ec9a9b80 100644 (file)
@@ -1,10 +1,11 @@
 /* $Id$
 
 This file is part of libmspgltk
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2009  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include <msp/gl/immediate.h>
 #include <msp/gl/matrix.h>
 #include <msp/gl/transform.h>
 #include "graphic.h"
@@ -20,24 +21,21 @@ namespace GLtk {
 
 List::List(const Resources &r):
        Widget(r),
+       Container(r),
        sel_index(-1),
        first(0),
        n_visible(1),
+       row_height(1),
        items_part(0),
-       slider(new VSlider(res)),
-       slider_active(false)
+       slider(res)
 {
-       slider->set_step(1);
-       slider->signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed));
+       add(slider);
+       slider.set_step(1);
+       slider.signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed));
 
        update_style();
 }
 
-List::~List()
-{
-       delete slider;
-}
-
 void List::append(const string &v)
 {
        items.push_back(v);
@@ -62,7 +60,7 @@ void List::remove(unsigned i)
        if(sel_index>static_cast<int>(i))
                --sel_index;
        else if(sel_index==static_cast<int>(i))
-               sel_index=-1;
+               sel_index = -1;
 
        recalculate_parameters();
 }
@@ -70,7 +68,22 @@ void List::remove(unsigned i)
 void List::clear()
 {
        items.clear();
-       sel_index=-1;
+       sel_index = -1;
+
+       recalculate_parameters();
+}
+
+void List::set_selected_index(int i)
+{
+       if(i<0)
+               sel_index = -1;
+       else if(i<static_cast<int>(items.size()))
+       {
+               sel_index = i;
+               signal_item_selected.emit(sel_index, items[sel_index]);
+       }
+       else
+               throw InvalidParameterValue("Index out of range");
 }
 
 const string &List::get_selected() const
@@ -83,73 +96,50 @@ const string &List::get_selected() const
 
 void List::button_press(int x, int y, unsigned btn)
 {
-       if(slider->get_geometry().is_inside(x, y))
-       {
-               const Geometry &sgeom=slider->get_geometry();
-               slider->button_press(x-sgeom.x, y-sgeom.y, btn);
-               slider_active=true;
-       }
-       else if(btn==1)
+       Container::button_press(x, y, btn);
+       if(!click_focus && btn==1)
        {
-               const GL::Font *const font=style->get_font();
-               const unsigned row_height=static_cast<unsigned>(font->get_default_size());
-
                if(items_part)
-                       y+=items_part->get_margin().top;
+                       y += items_part->get_margin().top;
 
-               unsigned i=(geom.h-1-y)/row_height;
-               if(i<n_visible)
+               unsigned i = (geom.h-1-y)/row_height;
+               if(i<n_visible && first+i<items.size())
                {
-                       sel_index=first+i;
+                       sel_index = first+i;
 
                        signal_item_selected.emit(sel_index, items[sel_index]);
                }
        }
 }
 
-void List::button_release(int x, int y, unsigned btn)
-{
-       if(slider_active)
-       {
-               const Geometry &sgeom=slider->get_geometry();
-               slider->button_release(x-sgeom.x, y-sgeom.y, btn);
-               slider_active=false;
-       }
-}
-
-void List::pointer_motion(int x, int y)
-{
-       if(slider_active)
-       {
-               const Geometry &sgeom=slider->get_geometry();
-               slider->pointer_motion(x-sgeom.x, y-sgeom.y);
-       }
-}
-
 void List::render_special(const Part &part) const
 {
        if(part.get_name()=="items")
        {
-               const GL::Font *const font=style->get_font();
-               const float font_size=font->get_default_size();
-               const unsigned row_height=static_cast<unsigned>(font_size);
-               const Sides &margin=part.get_margin();
+               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;
+               Geometry pgeom = geom;
+               pgeom.h = row_height;
+               pgeom.w -= margin.left+margin.right;
 
                for(unsigned i=0; (i<n_visible && first+i<items.size()); ++i)
                {
                        Geometry rgeom;
-                       rgeom.w=static_cast<unsigned>(font->get_string_width(items[first+i])*font_size);
-                       rgeom.h=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
-                       rgeom.y=geom.h-margin.top-(i+1)*row_height-static_cast<int>(font->get_descent()*font_size);
+                       rgeom.w = static_cast<unsigned>(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<int>(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);
-                       font->draw_string(items[first+i]);
+                       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();
                }
        }
@@ -157,18 +147,15 @@ void List::render_special(const Part &part) const
        {
                if(sel_index>=static_cast<int>(first) && sel_index<static_cast<int>(first+n_visible))
                {
-                       const GL::Font *const font=style->get_font();
-                       const float font_size=font->get_default_size();
-                       const unsigned row_height=static_cast<unsigned>(font_size);
-                       const Sides &margin=part.get_margin();
-
-                       Geometry pgeom=geom;
-                       pgeom.h=row_height;
-                       pgeom.w-=margin.left+margin.right;
-
-                       Geometry rgeom=part.get_geometry();
-                       rgeom.y+=geom.h-margin.top-row_height*(sel_index-first+1);
-                       rgeom.x+=margin.left;
+                       const Sides &margin = part.get_margin();
+
+                       Geometry pgeom = geom;
+                       pgeom.h = row_height;
+                       pgeom.w -= margin.left+margin.right;
+
+                       Geometry rgeom = part.get_geometry();
+                       rgeom.y += geom.h-margin.top-row_height*(sel_index-first+1);
+                       rgeom.x += margin.left;
                        part.get_alignment().apply(rgeom, pgeom);
 
                        GL::push_matrix();
@@ -178,7 +165,7 @@ void List::render_special(const Part &part) const
                }
        }
        else if(part.get_name()=="slider")
-               slider->render();
+               slider.render();
 }
 
 void List::on_geometry_change()
@@ -192,62 +179,59 @@ void List::on_style_change()
 {
        reposition_slider();
 
-       items_part=0;
-       for(list<Part>::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<unsigned>((font.get_ascent()-font.get_descent())*font.get_default_size());
 
        recalculate_parameters();
 }
 
 void List::reposition_slider()
 {
-       for(list<Part>::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(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()
 {
-       const GL::Font *font=style->get_font();
-       unsigned row_height=static_cast<unsigned>(font->get_default_size());
-
-       unsigned h=geom.h;
+       unsigned h = geom.h;
        if(items_part)
        {
-               const Sides &margin=items_part->get_margin();
-               h-=margin.top+margin.bottom;
+               const Sides &margin = items_part->get_margin();
+               h -= margin.top+margin.bottom;
        }
 
-       n_visible=h/row_height;
+       n_visible = h/row_height;
 
        if(first+n_visible>items.size())
        {
                if(items.size()>n_visible)
-                       first=items.size()-n_visible;
+                       first = items.size()-n_visible;
                else
-                       first=0;
+                       first = 0;
        }
 
        if(items.size()>n_visible)
        {
-               slider->set_range(0, items.size()-n_visible);
-               slider->set_value(items.size()-n_visible-first);
+               slider.set_range(0, items.size()-n_visible);
+               slider.set_value(items.size()-n_visible-first);
        }
        else
        {
-               slider->set_range(0, 0);
-               slider->set_value(0);
+               slider.set_range(0, 0);
+               slider.set_value(0);
        }
 }
 
 void List::slider_value_changed(double value)
 {
-       first=items.size()-n_visible-static_cast<unsigned>(value);
+       if(items.size()>n_visible)
+               first = items.size()-n_visible-static_cast<unsigned>(value);
 }
 
 
@@ -259,7 +243,7 @@ List::Loader::Loader(List &l):
 
 void List::Loader::item(const string &v)
 {
-       static_cast<List &>(wdg).append(v);
+       dynamic_cast<List &>(wdg).append(v);
 }
 
 } // namespace GLtk