]> git.tdb.fi Git - libs/gltk.git/commitdiff
Support loading Buttons from datafiles
authorMikko Rasa <tdb@tdb.fi>
Fri, 23 Nov 2007 16:01:17 +0000 (16:01 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 23 Nov 2007 16:01:17 +0000 (16:01 +0000)
Support repeated borders in Graphic
Fix coordinate handling in Root
Use the HOVER state in Button

source/button.cpp
source/button.h
source/graphic.cpp
source/graphic.h
source/panel.cpp
source/root.cpp
source/root.h
source/state.cpp

index 2c8bedb17c17a34e45be58003caac18067e2d843..543782e8306a448e616377b6d435c01ee185b218 100644 (file)
@@ -26,12 +26,26 @@ void Button::button_release(int x, int y, unsigned btn)
 {
        if(btn==1)
        {
-               state=NORMAL;
                if(geom.is_inside(x, y))
+               {
                        signal_clicked.emit();
+                       state=HOVER;
+               }
+               else
+                       state=NORMAL;
        }
 }
 
+void Button::pointer_enter()
+{
+       state=HOVER;
+}
+
+void Button::pointer_leave()
+{
+       state=NORMAL;
+}
+
 void Button::render_part(const Part &part) const
 {
        if(part.get_name()=="text")
@@ -40,5 +54,17 @@ void Button::render_part(const Part &part) const
                Widget::render_part(part);
 }
 
+
+Button::Loader::Loader(Button &btn):
+       Widget::Loader(btn)
+{
+       add("text", &Button::text);
+}
+
+Button &Button::Loader::get_object() const
+{
+       return static_cast<Button &>(wdg);
+}
+
 } // namespace GLtk
 } // namespace Msp
index 8bd2d315c26cb8439ad3cb9a5cd30a7162f7f7f3..841786c4def84f7795197dbfd623e182ed2a35df 100644 (file)
@@ -10,12 +10,21 @@ namespace GLtk {
 class Button: public Widget
 {
 public:
+       class Loader: public Widget::Loader
+       {
+       public:
+               Loader(Button &);
+               Button &get_object() const;
+       };
+
        sigc::signal<void> signal_clicked;
 
        Button(const Resources &, const std::string & =std::string());
        void set_text(const std::string &);
        void button_press(int, int, unsigned);
        void button_release(int, int, unsigned);
+       void pointer_enter();
+       void pointer_leave();
 private:
        std::string text;
        bool pressed;
index 611cdb4c790c4a4e16ff879260f72972cc37bacc..01bfcdb6a177db0fc16d8acf04498fcb4db47124 100644 (file)
@@ -8,57 +8,72 @@ namespace Msp {
 namespace GLtk {
 
 Graphic::Graphic():
-       texture(0)
+       texture(0),
+       repeat(false)
 { }
 
 void Graphic::render(unsigned wd, unsigned ht) const
 {
-       float x[4];
-       float y[4];
-       float u[4];
-       float v[4];
-
-       x[0]=0.0f-shadow.left;
-       x[1]=x[0]+border.left;
-       x[3]=wd+shadow.right;
-       x[2]=x[3]-border.right;
-
-       y[0]=0.0f-shadow.bottom;
-       y[1]=y[0]+border.bottom;
-       y[3]=ht+shadow.top;
-       y[2]=y[3]-border.top;
-
-       const unsigned twidth=texture->get_width();
-       u[0]=static_cast<float>(slice.x)/twidth;
-       u[1]=static_cast<float>(slice.x+border.left)/twidth;
-       u[2]=static_cast<float>(slice.x+slice.w-border.right)/twidth;
-       u[3]=static_cast<float>(slice.x+slice.w)/twidth;
-
-       const unsigned theight=texture->get_height();
-       v[0]=static_cast<float>(slice.y)/theight;
-       v[1]=static_cast<float>(slice.y+border.bottom)/theight;
-       v[2]=static_cast<float>(slice.y+slice.h-border.top)/theight;
-       v[3]=static_cast<float>(slice.y+slice.h)/theight;
+       GL::VertexArray varr((GL::TEXCOORD2, GL::VERTEX2));
+       RefPtr<GL::VertexArrayBuilder> vab=varr.modify();
+
+       vector<float> x, y;
+       create_coords(0.0f-shadow.left, wd+shadow.right, border.left, border.right, slice.w-border.left-border.right, x);
+       create_coords(0.0f-shadow.bottom, ht+shadow.top, border.bottom, border.top, slice.h-border.bottom-border.top, y);
+
+       vector<float> u, v;
+       create_texcoords(slice.x, slice.x+slice.w, border.left, border.right, texture->get_width(), u);
+       create_texcoords(slice.y, slice.y+slice.h, border.bottom, border.top, texture->get_height(), v);
 
-       texture->bind();
        unsigned xmin=border.left ? 0 : 1;
-       unsigned xmax=border.right ? 3 : 2;
+       unsigned xmax=x.size()-(border.right ? 2 : 3);
        unsigned ymin=border.bottom ? 0 : 1;
-       unsigned ymax=border.top ? 3 : 2;
+       unsigned ymax=y.size()-(border.top ? 2 : 3);
 
+       texture->bind();
        GL::Immediate imm((GL::TEXCOORD2,GL::VERTEX2));
-       for(unsigned i=ymin; i<ymax; ++i)
+       imm.begin(GL::QUADS);
+       for(unsigned i=ymin; i<=ymax; ++i)
        {
-               imm.begin(GL::QUAD_STRIP);
+               unsigned i2=(i==0 ? 0 : i==y.size()-2 ? 2 : 1);
                for(unsigned j=xmin; j<=xmax; ++j)
                {
-                       imm.texcoord(u[j], v[i]);
+                       unsigned j2=(j==0 ? 0 : j==x.size()-2 ? 2 : 1);
+                       imm.texcoord(u[j2], v[i2]);
                        imm.vertex(x[j], y[i]);
-                       imm.texcoord(u[j], v[i+1]);
+                       imm.texcoord(u[j2+1], v[i2]);
+                       imm.vertex(x[j+1], y[i]);
+                       imm.texcoord(u[j2+1], v[i2+1]);
+                       imm.vertex(x[j+1], y[i+1]);
+                       imm.texcoord(u[j2], v[i2+1]);
                        imm.vertex(x[j], y[i+1]);
                }
-               imm.end();
        }
+       imm.end();
+}
+
+void Graphic::create_coords(float low, float high, float brd1, float brd2, float block, vector<float> &coords) const
+{
+       coords.push_back(low);
+       coords.push_back(low+brd1);
+       if(repeat)
+       {
+               float space=high-low-brd1-brd2;
+               unsigned div=max(static_cast<unsigned>(space/block), 1U);
+               float delta=space/div;
+               for(unsigned i=1; i<div; ++i)
+                       coords.push_back(low+brd1+delta*i);
+       }
+       coords.push_back(high-brd2);
+       coords.push_back(high);
+}
+
+void Graphic::create_texcoords(float low, float high, float brd1, float brd2, float scale, vector<float> &coords) const
+{
+       coords.push_back(low/scale);
+       coords.push_back((low+brd1)/scale);
+       coords.push_back((high-brd2)/scale);
+       coords.push_back(high/scale);
 }
 
 
@@ -69,6 +84,7 @@ Graphic::Loader::Loader(Graphic &g, Resources &r):
        add("texture", &Loader::texture);
        add("slice",   &Loader::slice);
        add("border",  &Loader::border);
+       add("repeat",  &Graphic::repeat);
        add("shadow",  &Loader::shadow);
 }
 
index a9722ad97ff3e498187fffae3ff229a4654e66ae..b93111348175874150190c1666c5d6896d6efe61 100644 (file)
@@ -23,6 +23,7 @@ public:
                typedef Resources Collection;
 
                Loader(Graphic &, Resources &);
+               Graphic &get_object() const { return graph; }
        private:
                void texture(const std::string &);
                void slice(unsigned, unsigned, unsigned, unsigned);
@@ -42,6 +43,10 @@ private:
        Sides shadow;
        const GL::Texture2D *texture;
        Geometry slice;
+       bool repeat;
+
+       void create_coords(float, float, float, float, float, std::vector<float> &) const;
+       void create_texcoords(float, float, float, float, float, std::vector<float> &) const;
 };
 
 } // namespace GLtk
index efe857ec6860be568acc50b4e37134cd2f85ec44..c763e6e811afa5cd63926fb1971f047fb37e5c70 100644 (file)
@@ -1,4 +1,5 @@
 #include <msp/core/refptr.h>
+#include "button.h"
 #include "label.h"
 #include "panel.h"
 #include "part.h"
@@ -148,8 +149,9 @@ Panel::Loader::Loader(Panel &p, map<string, Widget *> &m):
        pnl(p),
        wdg_map(m)
 {
-       add("label", &Loader::child<Label>);
-       add("panel", &Loader::panel);
+       add("button", &Loader::child<Button>);
+       add("label",  &Loader::child<Label>);
+       add("panel",  &Loader::panel);
 }
 
 template<typename T>
index 83042a63f3c8a62339d40b7ae5708306fef398da..32cd87940fe22e71abcef2769f2c3b6516181005 100644 (file)
@@ -18,18 +18,27 @@ Root::Root(Resources &r, Window &w):
 
 void Root::button_press_event(int x, int y, unsigned btn, unsigned)
 {
+       translate_coords(x, y);
        button_press(x, y, btn);
 }
 
 void Root::button_release_event(int x, int y, unsigned btn, unsigned)
 {
+       translate_coords(x, y);
        button_release(x, y, btn);
 }
 
 void Root::pointer_motion_event(int x, int y)
 {
+       translate_coords(x, y);
        pointer_motion(x, y);
 }
 
+void Root::translate_coords(int &x, int &y)
+{
+       x=x*geom.w/window.get_width();
+       y=geom.h-1-y*geom.h/window.get_height();
+}
+
 } // namespace GLtk
 } // namespace Msp
index 01153f50c681c56f37cd716740cb42a986616703..809780cf291829720cf328fd5bfe9604cf63b01b 100644 (file)
@@ -20,6 +20,7 @@ private:
        void pointer_motion_event(int, int);
        void key_press_event(unsigned, unsigned, wchar_t);
        void key_release_event(unsigned, unsigned);
+       void translate_coords(int &, int &);
 };
 
 } // namespace GLtk
index bbff03dc9306ef8142935131aba760d75c1d80ee..9e44e14d200ff00a3c9b804baf29d8af59ef94b8 100644 (file)
@@ -9,13 +9,13 @@ istream &operator>>(istream &is, State &state)
 {
        string str;
        is>>str;
-       if(str=="normal")
+       if(str=="NORMAL")
                state=NORMAL;
-       else if(str=="hover")
+       else if(str=="HOVER")
                state=HOVER;
-       else if(str=="active")
+       else if(str=="ACTIVE")
                state=ACTIVE;
-       else if(str=="disabled")
+       else if(str=="DISABLED")
                state=DISABLED;
        else
                is.setstate(ios_base::failbit);