]> git.tdb.fi Git - libs/gltk.git/commitdiff
Refactor widget autosizing
authorMikko Rasa <tdb@tdb.fi>
Wed, 26 Jun 2013 16:17:54 +0000 (19:17 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Jun 2013 16:17:54 +0000 (19:17 +0300)
Widget::autosize is no longer virtual.  Instead there's autosize_special,
which handles one part at a time.  This way all the important checks and
finalisations are done in one place.

26 files changed:
source/button.cpp
source/button.h
source/dropdown.cpp
source/dropdown.h
source/entry.cpp
source/entry.h
source/hslider.cpp
source/hslider.h
source/image.cpp
source/image.h
source/label.cpp
source/label.h
source/layout.cpp
source/layout.h
source/list.cpp
source/list.h
source/panel.cpp
source/panel.h
source/text.cpp
source/text.h
source/toggle.cpp
source/toggle.h
source/vslider.cpp
source/vslider.h
source/widget.cpp
source/widget.h

index 5582230f95985fc05be05869fa1961c718fc22b2..58fc134cde2a9d551c80ad9b303bcd7773423304 100644 (file)
@@ -16,31 +16,16 @@ Button::Button(const std::string &t):
        set_text(t);
 }
 
-void Button::autosize()
+void Button::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *text_part = style->get_part("text"))
-       {
-               const Sides &margin = text_part->get_margin();
-               geom.w = max(geom.w, text.get_width()+margin.left+margin.right);
-               geom.h = max(geom.h, text.get_height()+margin.top+margin.bottom);
-       }
-
-       if(icon)
+       if(part.get_name()=="text")
+               text.autosize(part, ageom);
+       else if(part.get_name()=="icon" && icon)
        {
-               if(const Part *icon_part = style->get_part("icon"))
-               {
-                       const Sides &margin = icon_part->get_margin();
-                       geom.w = max(geom.w, icon->get_width()+margin.left+margin.right);
-                       geom.h = max(geom.h, icon->get_height()+margin.top+margin.bottom);
-               }
+               const Sides &margin = part.get_margin();
+               ageom.w = max(ageom.w, icon->get_width()+margin.left+margin.right);
+               ageom.h = max(ageom.h, icon->get_height()+margin.top+margin.bottom);
        }
-
-       rebuild();
 }
 
 void Button::set_text(const std::string &t)
index e75ba9f33a53db37669b0ec34f6433d7ee0b8331..edf0b62bf94e2c7198f7cc5ab567b6f6246f11f7 100644 (file)
@@ -36,8 +36,10 @@ public:
 
        virtual const char *get_class() const { return "button"; }
 
-       virtual void autosize();
+private:
+       virtual void autosize_special(const Part &, Geometry &);
 
+public:
        void set_text(const std::string &);
        void set_icon(const GL::Texture2D *);
 
index ce0ba71f642c45ca7f672e4bf8e80f78d8fb60ed..2aac55ec511dc184b5d7952901ebc7bbe5b6ece0 100644 (file)
@@ -33,18 +33,16 @@ void Dropdown::init()
        list.signal_autosize_changed.connect(sigc::mem_fun(this, &Dropdown::list_autosize_changed));
 }
 
-void Dropdown::autosize()
+void Dropdown::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-       list.autosize();
-       geom.w = max(geom.w, list.get_geometry().w);
-
-       if(const Part *text_part = style->get_part("text"))
+       if(part.get_name()=="list")
+       {
+               list.autosize();
+               ageom.w = max(ageom.w, list.get_geometry().w);
+       }
+       else if(part.get_name()=="text")
        {
-               const Sides &margin = text_part->get_margin();
+               const Sides &margin = part.get_margin();
                const GL::Font &font = style->get_font();
                float font_size = style->get_font_size();
 
@@ -55,10 +53,10 @@ void Dropdown::autosize()
                        unsigned w = static_cast<unsigned>(font.get_string_width(data.get_string(i))*font_size);
                        max_w = max(max_w, w);
                }
-               geom.w = max(geom.w, max_w+margin.left+margin.right);
+               ageom.w = max(ageom.w, max_w+margin.left+margin.right);
 
                unsigned line_height = static_cast<unsigned>((font.get_ascent()-font.get_descent())*font_size);
-               geom.h = max(geom.h, line_height+margin.top+margin.bottom);
+               ageom.h = max(ageom.h, line_height+margin.top+margin.bottom);
        }
 
        rebuild();
index 43bde103590abac7c1f3a19c634a4776e1196d86..eaa29c193c2260288a185bb2131c693ffeecdfdd 100644 (file)
@@ -38,8 +38,10 @@ private:
 public:
        virtual const char *get_class() const { return "dropdown"; }
 
-       virtual void autosize();
+private:
+       virtual void autosize_special(const Part &, Geometry &);
 
+public:
        void set_data(ListData &d) { list.set_data(d); }
        ListData &get_data() { return list.get_data(); }
        const ListData &get_data() const { return list.get_data(); }
index a635101404423e9b64524ad7dfee6b9471b53c24..9129e1b0ebbdd90bef2b641629b271a9fe618f0b 100644 (file)
@@ -28,55 +28,40 @@ Entry::Entry(const string &t):
        set_text(t);
 }
 
-void Entry::autosize()
+void Entry::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(text_part)
+       if(part.get_name()=="text")
        {
-               const Sides &margin = text_part->get_margin();
+               const Sides &margin = part.get_margin();
                const GL::Font &font = style->get_font();
                unsigned en_width = static_cast<unsigned>(font.get_string_width("n")*style->get_font_size());
-               geom.w = max(geom.w, edit_width*en_width+margin.left+margin.right);
+               ageom.w = max(ageom.w, edit_width*en_width+margin.left+margin.right);
 
                unsigned line_height = static_cast<unsigned>((font.get_ascent()-font.get_descent())*style->get_font_size());
                if(multiline)
                {
                        unsigned line_spacing = style->get_font_size()*6/5;
-                       geom.h = max(geom.h, line_height+line_spacing*(edit_height-1)+margin.top+margin.bottom);
+                       ageom.h = max(ageom.h, line_height+line_spacing*(edit_height-1)+margin.top+margin.bottom);
                }
                else
-                       geom.h = max(geom.h, line_height+margin.top+margin.bottom);
+                       ageom.h = max(ageom.h, line_height+margin.top+margin.bottom);
        }
-
-       if(multiline)
+       else if(part.get_name()=="slider" && multiline)
        {
-               if(const Part *slider_part = style->get_part("slider"))
+               Geometry sgeom = part.get_geometry();
+               if(!sgeom.w || !sgeom.h)
                {
-                       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();
+                       slider->autosize();
+                       if(!sgeom.w)
+                               sgeom.w = slider->get_geometry().w;
+                       if(!sgeom.h)
+                               sgeom.h = slider->get_geometry().h;
                }
 
-               check_view_range();
+               const Sides &margin = part.get_margin();
+               ageom.w = max(ageom.w, sgeom.w+margin.left+margin.right);
+               ageom.h = max(ageom.h, sgeom.h+margin.top+margin.bottom);
        }
-
-       rebuild();
 }
 
 void Entry::set_text(const string &t)
index edea4c3a2a1b4ad8b04e32520fc84ace645dc04a..1594c68d8e7bb883eebdb04362a6b4db552fa26f 100644 (file)
@@ -41,8 +41,10 @@ public:
 
        virtual const char *get_class() const { return "entry"; }
 
-       virtual void autosize();
+private:
+       virtual void autosize_special(const Part &, Geometry &);
 
+public:
        void set_text(const std::string &);
        const std::string &get_text() const { return text.get(); }
 
index 837b2ba5c2dae4a0344da91665661079c7e427ef..35d0a411d36ce2eb26936e66597627a0a3c6bea2 100644 (file)
@@ -12,19 +12,14 @@ HSlider::HSlider():
        slider_size(1)
 { }
 
-void HSlider::autosize()
+void HSlider::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *slider_part = style->get_part("slider"))
+       if(part.get_name()=="slider")
        {
-               const Sides &margin = slider_part->get_margin();
-               const Geometry &pgeom = slider_part->get_geometry();
-               geom.w = std::max(geom.w, pgeom.w*3/2+margin.left+margin.right);
-               geom.h = std::max(geom.h, pgeom.h+margin.top+margin.bottom);
+               const Sides &margin = part.get_margin();
+               const Geometry &pgeom = part.get_geometry();
+               ageom.w = std::max(ageom.w, pgeom.w*3/2+margin.left+margin.right);
+               ageom.h = std::max(ageom.h, pgeom.h+margin.top+margin.bottom);
        }
 }
 
index cb0252731c80660235b70c45cc8e4917ecd7c307..cadae5941d09c1974c1c701396d85c28813f7ff2 100644 (file)
@@ -20,9 +20,8 @@ public:
 
        virtual const char *get_class() const { return "hslider"; }
 
-       virtual void autosize();
-
 private:
+       virtual void autosize_special(const Part &, Geometry &);
        virtual void rebuild_special(const Part &);
 
 public:
index 2735ab611e6a059e73faccae8aa079a0c47e8876..8e14328c84b85aa073661cdb2dede39806715f20 100644 (file)
@@ -15,29 +15,22 @@ Image::Image(const GL::Texture2D *i):
        focusable = false;
 }
 
-void Image::autosize()
+void Image::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *image_part = style->get_part("image"))
+       if(part.get_name()=="image")
        {
-               const Sides &margin = image_part->get_margin();
+               const Sides &margin = part.get_margin();
                if(image)
                {
-                       geom.w = max(geom.w, image->get_width()+margin.left+margin.right);
-                       geom.h = max(geom.h, image->get_height()+margin.top+margin.bottom);
+                       ageom.w = max(ageom.w, image->get_width()+margin.left+margin.right);
+                       ageom.h = max(ageom.h, image->get_height()+margin.top+margin.bottom);
                }
                else
                {
-                       geom.w = max(geom.w, margin.left+margin.right);
-                       geom.h = max(geom.h, margin.top+margin.bottom);
+                       ageom.w = max(ageom.w, margin.left+margin.right);
+                       ageom.h = max(ageom.h, margin.top+margin.bottom);
                }
        }
-
-       rebuild();
 }
 
 void Image::set_image(const GL::Texture2D *i)
index 234f19f100c81848a25643f6514c8f7f9d81aa0c..8c5a9d5bc8ff40e8e6858ffca8e4dd27fcceaeda 100644 (file)
@@ -21,8 +21,10 @@ public:
 
        virtual const char *get_class() const { return "image"; }
 
-       virtual void autosize();
+private:
+       virtual void autosize_special(const Part &, Geometry &);
 
+public:
        void set_image(const GL::Texture2D *);
        void set_keep_aspect(bool);
 
index f42646709a3f90e43786742790df4f9e19eb2775..e6b7efb0192b460185df5ac4d11a870ceb20e339 100644 (file)
@@ -13,23 +13,6 @@ Label::Label(const string &t)
        set_text(t);
 }
 
-void Label::autosize()
-{
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *text_part = style->get_part("text"))
-       {
-               const Sides &margin = text_part->get_margin();
-               geom.w = max(geom.w, text.get_width()+margin.left+margin.right);
-               geom.h = max(geom.h, text.get_height()+margin.top+margin.bottom);
-       }
-
-       rebuild();
-}
-
 void Label::set_text(const string &t)
 {
        text = t;
@@ -37,6 +20,12 @@ void Label::set_text(const string &t)
        rebuild();
 }
 
+void Label::autosize_special(const Part &part, Geometry &ageom)
+{
+       if(part.get_name()=="text")
+               text.autosize(part, ageom);
+}
+
 void Label::rebuild_special(const Part &part)
 {
        if(part.get_name()=="text")
index 3e753dd0d92f97a64c69f1c6f46ea1a29421261d..f2279340adabf37555c683b01686814b3f6d9b82 100644 (file)
@@ -29,10 +29,10 @@ public:
 
        virtual const char *get_class() const { return "label"; }
 
-       virtual void autosize();
        void set_text(const std::string &);
 
 private:
+       virtual void autosize_special(const Part &, Geometry &);
        virtual void rebuild_special(const Part &);
 
        virtual void on_style_change();
index 743b30ebf3263b7246659191aeca349906623513..7902902abf2541082b0d455de9a185145545a84c 100644 (file)
@@ -317,12 +317,13 @@ void Layout::update()
                (*i)->widget.set_geometry((*i)->geom);
 }
 
-void Layout::autosize()
+void Layout::autosize(Geometry &geom)
 {
        solve_constraints(HORIZONTAL, AUTOSIZE);
        solve_constraints(VERTICAL, AUTOSIZE);
 
-       container->set_size(autosize_geom.w, autosize_geom.h);
+       geom.w = max(geom.w, autosize_geom.w);
+       geom.h = max(geom.h, autosize_geom.h);
 }
 
 void Layout::solve_constraints(int dir, SolveMode mode)
index a8ea3bf25b7f819492d14eb34c30a24380ba1f76..38d45ba4957100938e2bdc9fb5ca9aafe2781124 100644 (file)
@@ -226,7 +226,7 @@ public:
        void set_ghost(Widget &, bool);
 
        void update();
-       void autosize();
+       void autosize(Geometry &);
 
 private:
        void solve_constraints(int, SolveMode);
index c74af90d4541cb2185f2afc1f0d7a1bff8f6c172..b969ec038994bbe9d9609bf558b4d0b732e57ca4 100644 (file)
@@ -47,16 +47,11 @@ List::~List()
                delete data;
 }
 
-void List::autosize()
+void List::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *items_part = style->get_part("items"))
+       if(part.get_name()=="items")
        {
-               const Sides &margin = items_part->get_margin();
+               const Sides &margin = part.get_margin();
 
                unsigned max_w = 0;
                unsigned total_h = 0;
@@ -72,12 +67,9 @@ void List::autosize()
                if(!items.empty() && items.size()<view_size)
                        total_h = total_h*view_size/items.size();
 
-               geom.w = max(geom.w, max_w+margin.left+margin.right);
-               geom.h = max(geom.h, total_h+margin.top+margin.bottom);
+               ageom.w = max(ageom.w, max_w+margin.left+margin.right);
+               ageom.h = max(ageom.h, total_h+margin.top+margin.bottom);
        }
-
-       check_view_range();
-       rebuild();
 }
 
 void List::set_data(ListData &d)
@@ -313,18 +305,16 @@ void List::DataObserver::refresh_strings()
 }
 
 
-void List::Item::autosize()
+void List::Item::autosize_special(const Part &part, Geometry &ageom)
 {
-       Widget::autosize();
-
-       if(const Part *part = style->get_part("children"))
+       if(part.get_name()=="children")
        {
-               const Sides &margin = part->get_margin();
+               const Sides &margin = part.get_margin();
                for(list<Child *>::const_iterator i=children.begin(); i!=children.end(); ++i)
                {
                        const Geometry &cgeom = (*i)->widget->get_geometry();
-                       geom.w = max(geom.w, cgeom.x+cgeom.w+margin.right);
-                       geom.h = max(geom.h, cgeom.y+cgeom.h+margin.top);
+                       ageom.w = max(ageom.w, cgeom.x+cgeom.w+margin.right);
+                       ageom.h = max(ageom.h, cgeom.y+cgeom.h+margin.top);
                }
        }
 }
index dd44f3b57738e9bd2dbf19cfc87592d0d9bf6b67..1032db7e551229368ff57bc83ccb43e649cc9279 100644 (file)
@@ -47,7 +47,9 @@ protected:
        public:
                virtual const char *get_class() const { return "listitem"; }
 
-               virtual void autosize();
+       protected:
+               virtual void autosize_special(const Part &, Geometry &);
+       public:
                void set_active(bool);
 
                virtual void render_special(const Part &, GL::Renderer &) const;
@@ -91,8 +93,10 @@ public:
 
        virtual const char *get_class() const { return "list"; }
 
-       virtual void autosize();
+private:
+       virtual void autosize_special(const Part &, Geometry &);
 
+public:
        void set_data(ListData &);
        ListData &get_data() { return *data; }
        const ListData &get_data() const { return *data; }
index f9ea0d4b830a45b690b3134c496f0c1e110c4928..ab8f54fb0cc5471e6a1415ff17add966d51c02a5 100644 (file)
@@ -39,10 +39,10 @@ void Panel::set_layout(Layout *l)
        layout = l;
 }
 
-void Panel::autosize()
+void Panel::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(layout)
-               layout->autosize();
+       if(part.get_name()=="children" && layout)
+               layout->autosize(ageom);
 }
 
 void Panel::render_special(const Part &part, GL::Renderer &renderer) const
index ee2859c1e12423ab0fd6dc009cae09e6868f80f6..8d83b66334bac182cdb80320df3e2b1e8227333c 100644 (file)
@@ -65,9 +65,9 @@ public:
        virtual const char *get_class() const { return "panel"; }
 
        void set_layout(Layout *);
-       virtual void autosize();
 
 protected:
+       virtual void autosize_special(const Part &, Geometry &);
        virtual void render_special(const Part &, GL::Renderer &) const;
 
        virtual void on_geometry_change();
index 4d80ad548004f57276ce202ffa4e82fcbdc04daf..a0f53c238c12b88eca6df4f5b28135839163d804 100644 (file)
@@ -66,6 +66,13 @@ unsigned Text::get_height() const
        return line_height+(lines.size()-1)*line_spacing;
 }
 
+void Text::autosize(const Part &part, Geometry &geom) const
+{
+       const Sides &margin = part.get_margin();
+       geom.w = max(geom.w, get_width()+margin.left+margin.right);
+       geom.h = max(geom.h, get_height()+margin.top+margin.bottom);
+}
+
 void Text::set(const string &t)
 {
        text = t;
index 03cc787bb741151bff97e264ed6998022b354694..db58b2462621aad9dcd0e66db32baa7195d1ae36 100644 (file)
@@ -40,6 +40,7 @@ public:
 
        unsigned get_width() const;
        unsigned get_height() const;
+       void autosize(const Part &, Geometry &) const;
 
        void set(const std::string &);
        void erase(unsigned, unsigned);
index 451926956d12520de95ff4ba6aff7e9049556249..fe6518dda722b57fc6ffda3c2481d4e42ae63047 100644 (file)
@@ -17,21 +17,10 @@ Toggle::Toggle(const string &t):
        set_text(t);
 }
 
-void Toggle::autosize()
+void Toggle::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *text_part = style->get_part("text"))
-       {
-               const Sides &margin = text_part->get_margin();
-               geom.w = max(geom.w, text.get_width()+margin.left+margin.right);
-               geom.h = max(geom.h, text.get_height()+margin.top+margin.bottom);
-       }
-
-       rebuild();
+       if(part.get_name()=="text")
+               text.autosize(part, ageom);
 }
 
 void Toggle::set_text(const string &t)
index de8c5d2a71e91a9c193ddbbcbb01a0cdc6ecb0d7..9bba26863a42b281aa4b8b1eba3d67b4f701663e 100644 (file)
@@ -36,8 +36,10 @@ public:
 
        virtual const char *get_class() const { return "toggle"; }
 
-       virtual void autosize();
+private:
+       virtual void autosize_special(const Part &, Geometry &);
 
+public:
        void set_text(const std::string &);
        void set_exclusive(bool);
        bool get_exclusive() const { return exclusive; }
index 6a21c5301ad6eb45a51d2ff201ababb271a02f21..53c8f511db5060816972a1c5f21fe5ae974361f9 100644 (file)
@@ -12,19 +12,14 @@ VSlider::VSlider():
        slider_size(1)
 { }
 
-void VSlider::autosize()
+void VSlider::autosize_special(const Part &part, Geometry &ageom)
 {
-       if(!style)
-               return;
-
-       Widget::autosize();
-
-       if(const Part *slider_part = style->get_part("slider"))
+       if(part.get_name()=="slider")
        {
-               const Sides &margin = slider_part->get_margin();
-               const Geometry &pgeom = slider_part->get_geometry();
-               geom.w = std::max(geom.w, pgeom.w+margin.left+margin.right);
-               geom.h = std::max(geom.h, pgeom.h*3/2+margin.top+margin.bottom);
+               const Sides &margin = part.get_margin();
+               const Geometry &pgeom = part.get_geometry();
+               ageom.w = std::max(ageom.w, pgeom.w+margin.left+margin.right);
+               ageom.h = std::max(ageom.h, pgeom.h*3/2+margin.top+margin.bottom);
        }
 }
 
index 854b075d76e3e3218cbe50daa6d1e4f69a1750e9..a994aac88f53a66825f43ff1b478c255916eca50 100644 (file)
@@ -16,9 +16,8 @@ public:
 
        virtual const char *get_class() const { return "vslider"; }
 
-       virtual void autosize();
-
 private:
+       virtual void autosize_special(const Part &, Geometry &);
        virtual void rebuild_special(const Part &);
 
 public:
index f642004e07c3825fc1a79432f7a3acc237c1dadc..7496f8bdda1e849c3f35768d2d2ca6f29a11f503 100644 (file)
@@ -43,17 +43,22 @@ void Widget::autosize()
        if(!style)
                return;
 
-       geom.w = 0;
-       geom.h = 0;
+       Geometry ageom;
        const Style::PartSeq &parts = style->get_parts();
        for(Style::PartSeq::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+       {
                if(i->get_name().empty())
                {
                        const Geometry &pgeom = i->get_geometry();
                        const Sides &pmargin = i->get_margin();
-                       geom.w = max(geom.w, pgeom.w+pmargin.left+pmargin.right);
-                       geom.h = max(geom.h, pgeom.h+pmargin.top+pmargin.bottom);
+                       ageom.w = max(ageom.w, pgeom.w+pmargin.left+pmargin.right);
+                       ageom.h = max(ageom.h, pgeom.h+pmargin.top+pmargin.bottom);
                }
+               else
+                       autosize_special(*i, ageom);
+       }
+
+       set_geometry(ageom);
 }
 
 void Widget::set_geometry(const Geometry &g)
index 50e3279e3b5c3d753373246d88d13f7e3a0800e0..5c81b8056e6f409641095b2303513a95eff4d3ae 100644 (file)
@@ -61,7 +61,10 @@ public:
 
        void set_position(int, int);
        void set_size(unsigned, unsigned);
-       virtual void autosize();
+       void autosize();
+protected:
+       virtual void autosize_special(const Part &, Geometry &) { }
+public:
        void set_geometry(const Geometry &);
        const Geometry &get_geometry() const { return geom; }