]> git.tdb.fi Git - libs/gltk.git/commitdiff
Make the List in Dropdown a normal member instead of pointer
authorMikko Rasa <tdb@tdb.fi>
Mon, 13 Oct 2008 19:59:40 +0000 (19:59 +0000)
committerMikko Rasa <tdb@tdb.fi>
Mon, 13 Oct 2008 19:59:40 +0000 (19:59 +0000)
Cache row_height inside of List
Automatically resize the List associated with a Dropdown to fit the number of items in it

source/dropdown.cpp
source/dropdown.h
source/list.cpp
source/list.h
source/widget.h

index 5d8a547bebae925083fb40222e8dde20f8178ab2..a4816d48d593bb430e8b1aa764c35aac131b5744 100644 (file)
@@ -5,10 +5,12 @@ Copyright © 2007  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include <msp/gl/font.h>
 #include "dropdown.h"
 #include "list.h"
 #include "panel.h"
 #include "part.h"
+#include "style.h"
 
 using namespace std;
 
@@ -17,61 +19,69 @@ namespace GLtk {
 
 Dropdown::Dropdown(const Resources &r):
        Widget(r),
-       list(new List(res)),
+       list(r),
        dropped(false),
        list_active(false)
 {
-       list->signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected));
+       list.signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected));
 
        update_style();
 }
 
 Dropdown::~Dropdown()
 {
-       delete list;
 }
 
 void Dropdown::append(const string &item)
 {
-       list->append(item);
+       list.append(item);
+       resize_list();
 }
 
 void Dropdown::insert(unsigned i, const string &v)
 {
-       list->insert(i, v);
+       list.insert(i, v);
+       resize_list();
 }
 
 void Dropdown::remove(unsigned i)
 {
-       list->remove(i);
+       list.remove(i);
+       resize_list();
 }
 
 void Dropdown::clear()
 {
-       list->clear();
+       list.clear();
+       resize_list();
+}
+
+unsigned Dropdown::get_n_items() const
+{
+       return list.get_n_items();
 }
 
 void Dropdown::set_selected_index(int i)
 {
-       list->set_selected_index(i);
+       list.set_selected_index(i);
 }
 
 const string &Dropdown::get_selected() const
 {
-       return list->get_selected();
+       return list.get_selected();
 }
 
 int Dropdown::get_selected_index() const
 {
-       return list->get_selected_index();
+       return list.get_selected_index();
 }
 
 void Dropdown::button_press(int x, int y, unsigned btn)
 {
-       if(list->get_geometry().is_inside(x, y))
+       if(list.get_geometry().is_inside(x, y))
        {
-               const Geometry &lgeom=list->get_geometry();
-               list->button_press(x-lgeom.x, y-lgeom.y, btn);
+               const Geometry &lgeom=list.get_geometry();
+               list.button_press(x-lgeom.x, y-lgeom.y, btn);
                list_active=true;
        }
        else if(dropped)
@@ -97,8 +107,8 @@ void Dropdown::button_release(int x, int y, unsigned btn)
 {
        if(list_active)
        {
-               const Geometry &lgeom=list->get_geometry();
-               list->button_release(x-lgeom.x, y-lgeom.y, btn);
+               const Geometry &lgeom=list.get_geometry();
+               list.button_release(x-lgeom.x, y-lgeom.y, btn);
                list_active=false;
        }
 }
@@ -107,8 +117,8 @@ void Dropdown::pointer_motion(int x, int y)
 {
        if(list_active)
        {
-               const Geometry &lgeom=list->get_geometry();
-               list->pointer_motion(x-lgeom.x, y-lgeom.y);
+               const Geometry &lgeom=list.get_geometry();
+               list.pointer_motion(x-lgeom.x, y-lgeom.y);
        }
 }
 
@@ -116,16 +126,32 @@ void Dropdown::render_special(const Part &part) const
 {
        if(part.get_name()=="text")
        {
-               if(list->get_selected_index()>=0)
-                       render_text(part, list->get_selected());
+               if(list.get_selected_index()>=0)
+                       render_text(part, list.get_selected());
        }
        else if(part.get_name()=="list" && dropped)
-               list->render();
+               list.render();
 }
 
 void Dropdown::on_geometry_change()
 {
-       list->set_geometry(Geometry(0, -100, geom.w, 100));
+       resize_list();
+}
+
+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), 20U)*static_cast<unsigned>((font.get_ascent()-font.get_descent())*font.get_default_size());
+       for(std::list<Part>::const_iterator i=stl.get_parts().begin(); i!=stl.get_parts().end(); ++i)
+               if(i->get_name()=="items")
+               {
+                       const Sides &margin=i->get_margin();
+                       h+=margin.top+margin.bottom;
+               }
+       list.set_geometry(Geometry(0, -h, geom.w, h));
 }
 
 void Dropdown::list_item_selected(unsigned index, const std::string &item)
index 1ff69be7c6150354983a736e64496b2e389f33fb..ecba9753cb5cace6957f74fa52162887703e202e 100644 (file)
@@ -9,6 +9,7 @@ Distributed under the LGPL
 #define MSP_GLTK_DROPDOWN_H_
 
 #include <sigc++/signal.h>
+#include "list.h"
 #include "widget.h"
 
 namespace Msp {
@@ -28,7 +29,7 @@ public:
        };
 
 private:
-       List *list;
+       List list;
        bool dropped;
        bool list_active;
 
@@ -42,6 +43,7 @@ public:
        void insert(unsigned, const std::string &);
        void remove(unsigned);
        void clear();
+       unsigned get_n_items() const;
 
        void set_selected_index(int);
        const std::string &get_selected() const;
@@ -56,6 +58,7 @@ private:
        virtual void render_special(const Part &) const;
 
        virtual void on_geometry_change();
+       void resize_list();
 
        void list_item_selected(unsigned, const std::string &);
 };
index 924cfb55d37b68f99e2091c844db7e91aafd6b90..5bef36732e601ebd4a30023d04e51a9f14f2db78 100644 (file)
@@ -24,6 +24,7 @@ List::List(const Resources &r):
        sel_index(-1),
        first(0),
        n_visible(1),
+       row_height(1),
        items_part(0),
        slider(new VSlider(res)),
        slider_active(false)
@@ -107,9 +108,6 @@ void List::button_press(int x, int y, unsigned btn)
        }
        else if(btn==1)
        {
-               const GL::Font *const font=style->get_font();
-               const unsigned row_height=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font->get_default_size());
-
                if(items_part)
                        y+=items_part->get_margin().top;
 
@@ -146,10 +144,9 @@ 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 GL::Font &font=*style->get_font();
+               const float font_size=font.get_default_size();
                const GL::Color &color=style->get_font_color();
-               const unsigned row_height=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
                const Sides &margin=part.get_margin();
 
                Geometry pgeom=geom;
@@ -159,10 +156,10 @@ void List::render_special(const Part &part) const
                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.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);
+                       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();
@@ -170,7 +167,7 @@ void List::render_special(const Part &part) const
                        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);
+                       font.draw_string(items[first+i], imm);
                        GL::pop_matrix();
                }
        }
@@ -178,9 +175,6 @@ 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->get_ascent()-font->get_descent())*font_size);
                        const Sides &margin=part.get_margin();
 
                        Geometry pgeom=geom;
@@ -218,6 +212,9 @@ void List::on_style_change()
                if(i->get_name()=="items")
                        items_part=&*i;
 
+       const GL::Font &font=*style->get_font();
+       row_height=static_cast<unsigned>((font.get_ascent()-font.get_descent())*font.get_default_size());
+
        recalculate_parameters();
 }
 
@@ -234,9 +231,6 @@ void List::reposition_slider()
 
 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;
        if(items_part)
        {
index a13de52db627468bca5da9d9fd0c35c7996f13ef..770cc2f4517366a0b777d3e33df26f7f86b1a31f 100644 (file)
@@ -36,6 +36,7 @@ private:
        int sel_index;
        unsigned first;
        unsigned n_visible;
+       unsigned row_height;
 
        const Part *items_part;
 
@@ -52,6 +53,7 @@ public:
        void insert(unsigned, const std::string &);
        void remove(unsigned);
        void clear();
+       unsigned get_n_items() const { return items.size(); }
 
        void set_selected_index(int);
        const std::string &get_selected() const;
index 86638149c8640bdf57b95715cb5cab4b06fc6e25..8cf67d439b7c7e2a27c2b360623d21b5aa607751 100644 (file)
@@ -62,6 +62,7 @@ public:
        the widget class and the style name with a dash.
        */
        void set_style(const std::string &);
+       const Style &get_style() const { return *style; }
 
        void set_visible(bool);
        void set_focus();