]> git.tdb.fi Git - libs/gltk.git/blob - source/button.cpp
Add protected functions for manipulating widget state
[libs/gltk.git] / source / button.cpp
1 #include <msp/gl/immediate.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
44 void Button::set_text(const std::string &t)
45 {
46         text = t;
47         signal_autosize_changed.emit();
48 }
49
50 void Button::set_icon(const GL::Texture2D *i)
51 {
52         icon = i;
53 }
54
55 void Button::render_special(const Part &part) const
56 {
57         if(part.get_name()=="text")
58                 text.render(part, geom);
59         if(part.get_name()=="icon" && icon)
60         {
61                 Geometry rgeom;
62                 rgeom.w = icon->get_width();
63                 rgeom.h = icon->get_height();
64                 part.get_alignment().apply(rgeom, geom, part.get_margin());
65
66                 icon->bind();
67                 GL::Immediate imm((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2));
68                 imm.color(1.0f, 1.0f, 1.0f);
69                 imm.begin(GL::QUADS);
70                 imm.texcoord(0, 0);
71                 imm.vertex(rgeom.x, rgeom.y);
72                 imm.texcoord(1, 0);
73                 imm.vertex(rgeom.x+rgeom.w, rgeom.y);
74                 imm.texcoord(1, 1);
75                 imm.vertex(rgeom.x+rgeom.w, rgeom.y+rgeom.h);
76                 imm.texcoord(0, 1);
77                 imm.vertex(rgeom.x, rgeom.y+rgeom.h);
78                 imm.end();
79                 GL::Texture::unbind();
80         }
81 }
82
83 void Button::button_press(int, int, unsigned btn)
84 {
85         if(btn==1)
86         {
87                 pressed = true;
88                 set_state(ACTIVE);
89         }
90 }
91
92 void Button::button_release(int x, int y, unsigned btn)
93 {
94         if(pressed && btn==1)
95         {
96                 clear_state(ACTIVE);
97                 pressed = false;
98
99                 if(geom.is_inside_relative(x, y))
100                         signal_clicked.emit();
101         }
102 }
103
104 void Button::pointer_motion(int x, int y)
105 {
106         if(pressed)
107         {
108                 if(!geom.is_inside_relative(x, y))
109                         clear_state(ACTIVE);
110                 else
111                         set_state(ACTIVE);
112         }
113 }
114
115 void Button::on_style_change()
116 {
117         text.set_style(style);
118 }
119
120
121 Button::Loader::Loader(Button &btn):
122         Widget::Loader(btn)
123 {
124         add("text", &Loader::text);
125 }
126
127 void Button::Loader::text(const std::string &t)
128 {
129         static_cast<Button &>(obj).text = t;
130 }
131
132 } // namespace GLtk
133 } // namespace Msp