]> git.tdb.fi Git - libs/gltk.git/blob - source/button.cpp
b881b3f97fd8b52394b2e6bf9be1bd9869621598
[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, CachedPart &cache)
60 {
61         if(part.get_name()=="text")
62                 text.build(part, geom, cache);
63         if(part.get_name()=="icon")
64         {
65                 cache.texture = icon;
66                 if(icon)
67                 {
68                         Geometry rgeom;
69                         rgeom.w = icon->get_width();
70                         rgeom.h = icon->get_height();
71                         part.get_alignment().apply(rgeom, geom, part.get_margin());
72
73                         cache.clear_mesh();
74
75                         GL::MeshBuilder bld(*cache.mesh);
76                         bld.color(1.0f, 1.0f, 1.0f);
77                         bld.begin(GL::QUADS);
78                         bld.texcoord(0, 0);
79                         bld.vertex(rgeom.x, rgeom.y);
80                         bld.texcoord(1, 0);
81                         bld.vertex(rgeom.x+rgeom.w, rgeom.y);
82                         bld.texcoord(1, 1);
83                         bld.vertex(rgeom.x+rgeom.w, rgeom.y+rgeom.h);
84                         bld.texcoord(0, 1);
85                         bld.vertex(rgeom.x, rgeom.y+rgeom.h);
86                         bld.end();
87                 }
88         }
89 }
90
91 void Button::button_press(int, int, unsigned btn)
92 {
93         if(btn==1)
94         {
95                 pressed = true;
96                 set_state(ACTIVE);
97         }
98 }
99
100 void Button::button_release(int x, int y, unsigned btn)
101 {
102         if(pressed && btn==1)
103         {
104                 clear_state(ACTIVE);
105                 pressed = false;
106
107                 if(geom.is_inside_relative(x, y))
108                         signal_clicked.emit();
109         }
110 }
111
112 void Button::pointer_motion(int x, int y)
113 {
114         if(pressed)
115         {
116                 if(!geom.is_inside_relative(x, y))
117                         clear_state(ACTIVE);
118                 else
119                         set_state(ACTIVE);
120         }
121 }
122
123 void Button::on_style_change()
124 {
125         text.set_style(style);
126 }
127
128
129 Button::Loader::Loader(Button &btn):
130         DataFile::DerivedObjectLoader<Button, Widget::Loader>(btn)
131 {
132         add("text", &Loader::text);
133 }
134
135 void Button::Loader::text(const std::string &t)
136 {
137         obj.text = t;
138 }
139
140 } // namespace GLtk
141 } // namespace Msp