1 #include "Widget.hh"
2 
3 #include "Config.hh"
4 
set_available_area(Box2f area)5 void Widget::set_available_area(Box2f area)
6 {
7     V2f s = area.size();
8     float area_aspect = s.x/s.y;
9 
10 
11     if (area_aspect >= this->aspect) {
12         // area wider than widget
13         extent.min.y = area.min.y;
14         extent.max.y = area.max.y;
15 
16         float w = area.size().y * this->aspect;
17 
18         extent.min.x = area.center().x - w/2;
19         extent.max.x = area.center().x + w/2;
20 
21     } else {
22         // area higher than widget
23         extent.min.x = area.min.x;
24         extent.max.x = area.max.x;
25 
26         float h = area.size().x / this->aspect;
27 
28         extent.min.y = area.center().y - h/2;
29         extent.max.y = area.center().y + h/2;
30     }
31 }
32 
Button(string texture_file)33 Button::Button(string texture_file)
34     : Widget(1.0),
35       texture(texture_file.c_str())
36 {
37     V2u s = texture.get_size();
38 
39     aspect = (float)s.x / (float)s.y;
40 }
41 
area_clicked(V2f pos)42 void Button::area_clicked(V2f pos)
43 {
44     if (extent.intersects(pos)) {
45         signal_clicked.emit();
46         //cout << "Button clicked at " << pos << "." << endl;
47     }
48 }
49 
draw(void)50 void Button::draw(void)
51 {
52 
53     glDisable(GL_DEPTH_TEST);
54 
55     glEnable(GL_BLEND);
56     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
57     glBlendEquation(GL_FUNC_ADD);
58     glEnable(GL_TEXTURE_2D);
59 
60     glDisable(GL_LIGHTING);
61 
62     texture.bind(GL_TEXTURE0);
63 
64     glColor4f(1,1,1,1);
65     glBegin(GL_QUADS);
66 
67     glTexCoord2f(0, 0);
68     glVertex2f(extent.min.x, extent.min.y);
69     glTexCoord2f(1, 0);
70     glVertex2f(extent.max.x, extent.min.y);
71     glTexCoord2f(1, 1);
72     glVertex2f(extent.max.x, extent.max.y);
73     glTexCoord2f(0, 1);
74     glVertex2f(extent.min.x, extent.max.y);
75 
76     glEnd();
77 
78     glDisable(GL_BLEND);
79 
80     texture.unbind(GL_TEXTURE0);
81 
82     //glEnable(GL_LIGHTING);
83 
84     glEnable(GL_DEPTH_TEST);
85 }
86 
TextArea(string initial_text,Config * config,Color4f bgcolor)87 TextArea::TextArea(string initial_text, Config* config, Color4f bgcolor)
88     : Widget(1.0),
89       text(initial_text), bgcolor(bgcolor)
90 {
91     int face_size = 72;
92 
93     font = new FTBufferFont((config->resource_dir + "fonts/dijkstra.ttf").c_str());
94 
95     if (font->Error()) {
96         cerr << "Something went wrong with loading the font." << endl;
97     }
98 
99     font->FaceSize(face_size);
100 
101     FTBBox ftbbox = font->BBox(initial_text.c_str());
102     Box2f bbox(V2f(ftbbox.Lower().X(), ftbbox.Lower().Y()),
103                V2f(ftbbox.Upper().X(), ftbbox.Upper().Y()));
104 
105     // bbox.min.y = 0;
106     // bbox.max.y = face_size;
107 
108     aspect = bbox.size().x / bbox.size().y;
109 }
110 
set_available_area(Box2f area)111 void TextArea::set_available_area(Box2f area)
112 {
113     Widget::set_available_area(area);
114 
115     bgarea = area;
116 
117     font->FaceSize((int)extent.size().y);
118 }
119 
~TextArea()120 TextArea::~TextArea()
121 {
122     delete font;
123 }
124 
125 
126 
set_text(string text)127 void TextArea::set_text(string text)
128 {
129     this->text = text;
130 }
131 
area_clicked(V2f pos)132 void TextArea::area_clicked(V2f pos)
133 {
134     if (extent.intersects(pos)) {
135         signal_clicked.emit();
136         //cout << "Button clicked at " << pos << "." << endl;
137     }
138 }
139 
draw(void)140 void TextArea::draw(void)
141 {
142     FTBBox ftbbox = font->BBox(text.c_str());
143     Box2f bbox(V2f(ftbbox.Lower().X(), ftbbox.Lower().Y()),
144                V2f(ftbbox.Upper().X(), ftbbox.Upper().Y()));
145 
146     bbox.min.y = 0;
147     bbox.max.y = 72;
148 
149     glEnable(GL_BLEND);
150     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
151     glBlendEquation(GL_FUNC_ADD);
152     glDisable(GL_DEPTH_TEST);
153 
154     // glColor(bgcolor);
155 
156     // glBegin(GL_QUADS);
157 
158     // glTexCoord2f(0, 0);
159     // glVertex2f(bgarea.min.x, bgarea.min.y);
160     // glTexCoord2f(1, 0);
161     // glVertex2f(bgarea.max.x, bgarea.min.y);
162     // glTexCoord2f(1, 1);
163     // glVertex2f(bgarea.max.x, bgarea.max.y);
164     // glTexCoord2f(0, 1);
165     // glVertex2f(bgarea.min.x, bgarea.max.y);
166 
167     // glEnd();
168 
169     glPushMatrix();
170 
171 
172     glTranslatef(extent.center().x - bbox.center().x,
173                  extent.center().y - bbox.center().y,
174                  0);
175 
176     glTranslatef(bbox.center().x, bbox.center().y, 0);
177     glScalef(0.7f, 0.7f, 0.7f);
178     glTranslatef(-bbox.center().x, -bbox.center().y, 0);
179 
180     glDisable(GL_LIGHTING);
181     glColor4f(255/255.f,134/255.f,255/255.f,1);
182 
183     font->Render(text.c_str());
184 
185     glPopMatrix();
186 
187     glDisable(GL_BLEND);
188 
189 }
190 
add_widget(Widget * widget,Box2f rel_pos)191 void SimpleLayout::add_widget(Widget* widget, Box2f rel_pos)
192 {
193     widgets[widget] = rel_pos;
194 
195     set_available_area(own_size);
196 }
197 
remove_widget(Widget * widget)198 void SimpleLayout::remove_widget(Widget* widget)
199 {
200     widgets.erase(widget);
201 }
202 
set_available_area(Box2f area)203 void SimpleLayout::set_available_area(Box2f area)
204 {
205     own_size = area;
206 
207     for (map<Widget*, Box2f>::iterator i = widgets.begin();
208          i != widgets.end(); ++i) {
209         V2f t_min = i->second.min,
210             t_max = i->second.max;
211 
212         Box2f new_widget_area = Box2f((t_min * area.max) + ((V2f(1,1)-t_min) * area.min),
213                                       (t_max * area.max) + ((V2f(1,1)-t_max) * area.min));
214         i->first->set_available_area(new_widget_area);
215     }
216 }
217 
area_clicked(V2f pos)218 void SimpleLayout::area_clicked(V2f pos)
219 {
220     for (map<Widget*, Box2f>::iterator i = widgets.begin();
221          i != widgets.end(); ++i) {
222         i->first->area_clicked(pos);
223     }
224 }
225 
draw(void)226 void SimpleLayout::draw(void)
227 {
228     for (map<Widget*, Box2f>::iterator i = widgets.begin();
229          i != widgets.end(); ++i) {
230         // glPushMatrix();
231         // glTranslatef(own_size.min.x, own_size.min.y, 0);
232         // glScalef(own_size.size().x, own_size.size().y,1);
233         // V2f p1 = i->second.min,
234         //     p2 = i->second.max;
235         // glColor3f(1,1,0);
236         // glLineWidth(2.0);
237         // glBegin(GL_LINE_LOOP);
238         // glVertex2f(p1.x, p1.y);
239         // glVertex2f(p2.x, p1.y);
240         // glVertex2f(p2.x, p2.y);
241         // glVertex2f(p1.x, p2.y);
242         // glEnd();
243         // glLineWidth(1.0);
244         // glPopMatrix();
245 
246         i->first->draw();
247     }
248 }
249 
Slider(Config * config)250 Slider::Slider(Config* config)
251     : Widget(1.0),
252       up_button(config->resource_dir + "textures/up.png"),
253       down_button(config->resource_dir + "textures/down.png")
254 {
255     up_button.on_click()
256         .connect(sigc::bind(sigc::mem_fun(this, &Slider::change), 1));
257     down_button.on_click()
258         .connect(sigc::bind(sigc::mem_fun(this, &Slider::change),-1));
259 }
260 
change(int dir)261 void Slider::change(int dir)
262 {
263     signal_clicked.emit(dir);
264 }
265 
set_available_area(Box2f area)266 void Slider::set_available_area(Box2f area)
267 {
268     extent = area;
269 
270     up_button.set_available_area(Box2f(V2f(area.min.x,area.center().y),
271                                        area.max));
272     down_button.set_available_area(Box2f(area.min,
273                                          V2f(area.max.x,area.center().y)));
274 }
275 
area_clicked(V2f pos)276 void Slider::area_clicked(V2f pos)
277 {
278     if (extent.intersects(pos)) {
279         up_button.area_clicked(pos);
280         down_button.area_clicked(pos);
281     }
282 }
283 
draw(void)284 void Slider::draw(void)
285 {
286     up_button.draw();
287     down_button.draw();
288 }
289