]> git.tdb.fi Git - libs/gltk.git/blob - source/button.cpp
Improve widget part caching
[libs/gltk.git] / source / button.cpp
1 #include <msp/gl/meshbuilder.h>
2 #include "button.h"
3 #include "part.h"
4 #include "style.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GLtk {
10
11 Button::Button(const std::string &t):
12         text(),
13         icon(0),
14         pressed(false)
15 {
16         set_text(t);
17 }
18
19 void Button::autosize()
20 {
21         if(!style)
22                 return;
23
24         Widget::autosize();
25
26         if(const Part *text_part = style->get_part("text"))
27         {
28                 const Sides &margin = text_part->get_margin();
29                 geom.w = max(geom.w, text.get_width()+margin.left+margin.right);
30                 geom.h = max(geom.h, text.get_height()+margin.top+margin.bottom);
31         }
32
33         if(icon)
34         {
35                 if(const Part *icon_part = style->get_part("icon"))
36                 {
37                         const Sides &margin = icon_part->get_margin();
38                         geom.w = max(geom.w, icon->get_width()+margin.left+margin.right);
39                         geom.h = max(geom.h, icon->get_height()+margin.top+margin.bottom);
40                 }
41         }
42
43         rebuild();
44 }
45
46 void Button::set_text(const std::string &t)
47 {
48         text = t;
49         signal_autosize_changed.emit();
50         rebuild();
51 }
52
53 void Button::set_icon(const GL::Texture2D *i)
54 {
55         icon = i;
56         rebuild();
57 }
58
59 void Button::rebuild_special(const Part &part)
60 {
61         if(part.get_name()=="text")
62                 text.build(part, geom, part_cache);
63         if(part.get_name()=="icon")
64         {
65                 if(icon)
66                 {
67                         Geometry rgeom;
68                         rgeom.w = icon->get_width();
69                         rgeom.h = icon->get_height();
70                         part.get_alignment().apply(rgeom, geom, part.get_margin());
71
72                         GL::MeshBuilder bld(part_cache.create_mesh(part, *icon));
73                         bld.color(1.0f, 1.0f, 1.0f);
74                         bld.begin(GL::QUADS);
75                         bld.texcoord(0, 0);
76                         bld.vertex(rgeom.x, rgeom.y);
77                         bld.texcoord(1, 0);
78                         bld.vertex(rgeom.x+rgeom.w, rgeom.y);
79                         bld.texcoord(1, 1);
80                         bld.vertex(rgeom.x+rgeom.w, rgeom.y+rgeom.h);
81                         bld.texcoord(0, 1);
82                         bld.vertex(rgeom.x, rgeom.y+rgeom.h);
83                         bld.end();
84                 }
85         }
86 }
87
88 void Button::button_press(int, int, unsigned btn)
89 {
90         if(btn==1)
91         {
92                 pressed = true;
93                 set_state(ACTIVE);
94         }
95 }
96
97 void Button::button_release(int x, int y, unsigned btn)
98 {
99         if(pressed && btn==1)
100         {
101                 clear_state(ACTIVE);
102                 pressed = false;
103
104                 if(geom.is_inside_relative(x, y))
105                         signal_clicked.emit();
106         }
107 }
108
109 void Button::pointer_motion(int x, int y)
110 {
111         if(pressed)
112         {
113                 if(!geom.is_inside_relative(x, y))
114                         clear_state(ACTIVE);
115                 else
116                         set_state(ACTIVE);
117         }
118 }
119
120 void Button::on_style_change()
121 {
122         text.set_style(style);
123 }
124
125
126 Button::Loader::Loader(Button &btn):
127         DataFile::DerivedObjectLoader<Button, Widget::Loader>(btn)
128 {
129         add("text", &Loader::text);
130 }
131
132 void Button::Loader::text(const std::string &t)
133 {
134         obj.text = t;
135 }
136
137 } // namespace GLtk
138 } // namespace Msp