zenilib: zenilib/jni/external/zenilib/zeni_rest/Widget.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Widget.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2 * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3 *
4 * zenilib is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * zenilib is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <zeni_rest.h>
19
20 #include <list>
21
22 #include <Zeni/Define.h>
23
24 #if defined(_DEBUG) && defined(_WINDOWS)
25 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
26 #define new DEBUG_NEW
27 #endif
28
29 namespace Zeni {
30
31 Widget::~Widget() {
32 if(delete_m_renderer)
33 delete m_renderer;
34 }
35
36 void Widget::set_editable(const bool &editable_) {
37 m_editable = editable_;
38 }
39
40 void Widget::render_impl() const {
41 if(m_renderer)
42 m_renderer->render_to(*this);
43 }
44
45 void Widget_Rectangle::set_upper_left(const Point2f &upper_left_) {
46 m_upper_left = upper_left_;
47 }
48
49 void Widget_Rectangle::set_lower_right(const Point2f &lower_right_) {
50 m_lower_right = lower_right_;
51 }
52
53 void Widget_Renderer_Text::render_to(const Widget &widget) {
54 const Widget_Rectangle * const wrr = dynamic_cast<const Widget_Rectangle *>(&widget);
55
56 if(!wrr)
57 throw Widget_Renderer_Wrong_Type();
58
59 const Font &font = get_Fonts()[font_name];
60
61 const Point2f center = wrr->get_center();
62 const float x = center.x;
63 const float y = center.y - 0.5f * font.get_text_height();
64 font.render_text(text, Point2f(x, y), color, ZENI_CENTER);
65 }
66
67 Widget_Renderer_Text * Widget_Renderer_Text::get_duplicate() const {
68 return new Widget_Renderer_Text(*this);
69 }
70
71 void Widget_Renderer_Color::render_to(const Widget &widget) {
72 const Widget_Rectangle * const wrr = dynamic_cast<const Widget_Rectangle *>(&widget);
73
74 if(!wrr)
75 throw Widget_Renderer_Wrong_Type();
76
77 const Quadrilateral<Vertex2f_Color> quad(Vertex2f_Color(wrr->get_upper_left(), color),
78 Vertex2f_Color(wrr->get_lower_left(), color),
79 Vertex2f_Color(wrr->get_lower_right(), color),
80 Vertex2f_Color(wrr->get_upper_right(), color));
81
82 get_Video().render(quad);
83 }
84
85 Widget_Renderer_Color * Widget_Renderer_Color::get_duplicate() const {
86 return new Widget_Renderer_Color(*this);
87 }
88
89 void Widget_Renderer_Texture::render_to(const Widget &widget) {
90 const Widget_Rectangle * const wrr = dynamic_cast<const Widget_Rectangle *>(&widget);
91
92 if(!wrr)
93 throw Widget_Renderer_Wrong_Type();
94
95 Quadrilateral<Vertex2f_Texture> quad(Vertex2f_Texture(wrr->get_upper_left(), tex_coord_ul),
96 Vertex2f_Texture(wrr->get_lower_left(), tex_coord_ll),
97 Vertex2f_Texture(wrr->get_lower_right(), tex_coord_lr),
98 Vertex2f_Texture(wrr->get_upper_right(), tex_coord_ur));
99 Material mat(texture);
100 quad.lend_Material(&mat);
101
102 get_Video().render(quad);
103 }
104
105 Widget_Renderer_Texture * Widget_Renderer_Texture::get_duplicate() const {
106 return new Widget_Renderer_Texture(*this);
107 }
108
109 void Widget_Renderer_Tricolor::render_to(const Widget &widget) {
110 const Widget_Button * const wbr = dynamic_cast<const Widget_Button *>(&widget);
111 Widget_Renderer_Text * const wrtr = dynamic_cast< Widget_Renderer_Text *>(const_cast< Widget *>(&widget));
112
113 if(!wbr || !wrtr)
114 throw Widget_Renderer_Wrong_Type();
115
116 switch(wbr->get_State()) {
117 case Widget_Button::NORMAL:
118 case Widget_Button::UNACTIONABLE:
119 color = bg_normal;
120 wrtr->color = text_normal;
121 break;
122
123 case Widget_Button::CLICKED:
124 color = bg_clicked;
125 wrtr->color = text_clicked;
126 break;
127
128 case Widget_Button::HOVERED:
129 case Widget_Button::STRAYED:
130 color = bg_hovered_strayed;
131 wrtr->color = text_hovered_strayed;
132 break;
133
134 default:
135 break;
136 }
137
138 Widget_Renderer_Color::render_to(widget);
139 wrtr->render_to(widget);
140 }
141
142 Widget_Renderer_Tricolor * Widget_Renderer_Tricolor::get_duplicate() const {
143 return new Widget_Renderer_Tricolor(*this);
144 }
145
146 void Widget_Renderer_Check_Box::render_to(const Widget &widget) {
147 const Check_Box * const cbr = dynamic_cast<const Check_Box *>(&widget);
148
149 if(!cbr)
150 throw Widget_Renderer_Wrong_Type();
151
152 Video &vr = get_Video();
153
154 Vertex2f_Color ul(cbr->get_upper_left(), border_color);
155 Vertex2f_Color ll(cbr->get_lower_left(), border_color);
156 Vertex2f_Color lr(cbr->get_lower_right(), border_color);
157 Vertex2f_Color ur(cbr->get_upper_right(), border_color);
158
159 Line_Segment<Vertex2f_Color> line_seg(ul, ll);
160 vr.render(line_seg);
161
162 line_seg.a = lr;
163 vr.render(line_seg);
164
165 line_seg.b = ur;
166 vr.render(line_seg);
167
168 line_seg.a = ul;
169 vr.render(line_seg);
170
171 if(cbr->is_checked() || cbr->is_toggling()) {
172 Color cc = check_color;
173 if(cbr->is_toggling()) {
174 if(cbr->is_checked())
175 cc.a /= 3.0f;
176 else
177 cc.a *= 2.0f / 3.0f;
178 }
179
180 ul.set_Color(cc);
181 ll.set_Color(cc);
182 lr.set_Color(cc);
183 ur.set_Color(cc);
184
185 line_seg.a = ul;
186 line_seg.b = lr;
187 vr.render(line_seg);
188
189 line_seg.a = ll;
190 line_seg.b = ur;
191 vr.render(line_seg);
192 }
193 }
194
195 Widget_Renderer_Check_Box * Widget_Renderer_Check_Box::get_duplicate() const {
196 return new Widget_Renderer_Check_Box(*this);
197 }
198
199 void Widget_Renderer_Slider::render_to(const Widget &widget) {
200 const Slider * const sr = dynamic_cast<const Slider *>(&widget);
201
202 if(!sr)
203 throw Widget_Renderer_Wrong_Type();
204
205 Video &vr = get_Video();
206
207 const Point3f p0(sr->get_end_point_a());
208 const Point3f p1(sr->get_end_point_b());
209 const Vector3f v = p1 - p0;
210 const Vector3f n(-v.j, v.i, 0.0f); // or (v.j, -v.i, 0.0f)
211
212 const Point3f &midpt = p0 + sr->get_slider_position() * v;
213 const Vector3f &n2 = sr->get_slider_radius() * n.normalized();
214
215 Line_Segment<Vertex2f_Color> line_seg(Vertex2f_Color(Point2f(midpt - n2), slider_color),
216 Vertex2f_Color(Point2f(midpt + n2), slider_color));
217
218 vr.render(line_seg);
219
220 line_seg.a.position = Point3f(p0);
221 line_seg.a.set_Color(line_color);
222 line_seg.b.position = Point3f(p1);
223 line_seg.b.set_Color(line_color);
224
225 vr.render(line_seg);
226 }
227
228 Widget_Renderer_Slider * Widget_Renderer_Slider::get_duplicate() const {
229 return new Widget_Renderer_Slider(*this);
230 }
231
232 void Widget_Button::on_mouse_button(const Point2i &pos, const bool &down, const int &button) {
233 #ifndef ANDROID
234 if(!is_editable() || button != SDL_BUTTON_LEFT)
235 return;
236
237 const bool inside = is_inside(pos);
238
239 if(down)
240 if(inside) {
241 m_state = CLICKED;
242 on_click();
243
244 set_busy(true);
245 }
246 else {
247 m_state = UNACTIONABLE;
248
249 set_busy(false);
250 }
251 else {
252 if(inside) {
253 if(m_state == CLICKED) {
254 m_state = HOVERED;
255 on_accept();
256 on_mouse_motion(pos);
257 }
258 else
259 m_state = HOVERED;
260 }
261 else {
262 if(m_state == CLICKED) {
263 m_state = NORMAL;
264 on_reject();
265 }
266 else
267 m_state = NORMAL;
268 }
269
270 set_busy(false);
271 }
272 #endif
273 }
274
275 void Widget_Button::on_mouse_motion(const Point2i &pos) {
276 #ifndef ANDROID
277 if(!is_editable())
278 return;
279
280 if(m_state == UNACTIONABLE && !get_Game().get_mouse_button_state(SDL_BUTTON_LEFT))
281 m_state = NORMAL;
282
283 const bool inside = is_inside(pos);
284
285 if(m_state != UNACTIONABLE) {
286 if(inside) {
287 if(m_state == STRAYED) {
288 m_state = CLICKED;
289 on_unstray();
290 }
291 else if(m_state == NORMAL) {
292 m_state = HOVERED;
293 on_hover();
294 }
295 }
296 else {
297 if(m_state == CLICKED) {
298 m_state = STRAYED;
299 on_stray();
300 }
301 else if(m_state == HOVERED) {
302 m_state = NORMAL;
303 on_unhover();
304 }
305 }
306 }
307 #endif
308 }
309
310 #if SDL_VERSION_ATLEAST(2,0,0)
311 void Widget_Button::on_mouse_wheel(const Zeni::Point2i &, const int &) {
312 }
313 #endif
314
315 void Check_Box::on_accept() {
316 m_checked = !m_checked;
317 m_toggling = false;
318 }
319
320 void Check_Box::on_click() {
321 m_toggling = true;
322 }
323
324 void Check_Box::on_unstray() {
325 m_toggling = true;
326 }
327
328 void Check_Box::on_reject() {
329 m_toggling = false;
330 }
331
332 void Check_Box::on_stray() {
333 m_toggling = false;
334 }
335
336 void Radio_Button::on_accept() {
337 if(is_checked())
338 Check_Box::on_reject();
339 else {
340 Check_Box::on_accept();
341
342 m_radio_button_set->accept(*this);
343 }
344 }
345
346 void Radio_Button_Set::on_mouse_button(const Point2i &pos, const bool &down, const int &button) {
347 if(!is_editable())
348 return;
349
350 for(std::set<Radio_Button *>::iterator it = m_radio_buttons.begin(); it != m_radio_buttons.end(); ++it)
351 (*it)->on_mouse_button(pos, down, button);
352 }
353
354 void Radio_Button_Set::on_mouse_motion(const Point2i &pos) {
355 if(!is_editable())
356 return;
357
358 for(std::set<Radio_Button *>::iterator it = m_radio_buttons.begin(); it != m_radio_buttons.end(); ++it)
359 (*it)->on_mouse_motion(pos);
360 }
361
362 void Radio_Button_Set::render_impl() const {
363 for(std::set<Radio_Button *>::const_iterator it = m_radio_buttons.begin(); it != m_radio_buttons.end(); ++it)
364 (*it)->render_impl();
365 }
366
367 Slider::Slider(const Point2f &end_point_a_, const Point2f &end_point_b_,
368 const float &slider_radius_,
369 const float &slider_position_)
370 : m_line_segment(Point3f(end_point_a_), Point3f(end_point_b_)),
371 m_slider_radius(slider_radius_),
372 m_mouse_wheel_inverted(false),
373 m_mouse_wheel_continuous_rate(0.01f),
374 m_slider_position(slider_position_),
375 m_down(false)
376 {
377 give_Renderer(new Widget_Renderer_Slider(get_Colors()["default_button_bg_normal"], get_Colors()["default_button_bg_normal"]));
378 }
379
380 void Slider::on_mouse_button(const Zeni::Point2i &pos, const bool &down, const int &button) {
381 #ifndef ANDROID
382 if(!is_editable() || button != SDL_BUTTON_LEFT)
383 return;
384
385 if(down) {
386 const Point3f mouse_pos(float(pos.x), float(pos.y), 0.0f);
387
388 const std::pair<float, float> test = m_line_segment.nearest_point(mouse_pos);
389 if(test.first < m_slider_radius) {
390 m_down = true;
391 m_backup_position = m_slider_position;
392 m_slider_position = test.second;
393 on_slide();
394
395 set_busy(true);
396 }
397 else
398 m_down = false;
399 }
400 else {
401 if(m_down)
402 on_accept();
403
404 set_busy(false);
405 }
406 #endif
407 }
408
409 void Slider::on_mouse_motion(const Zeni::Point2i &pos) {
410 if(m_down) {
411 const Point3f mouse_pos(float(pos.x), float(pos.y), 0.0f);
412
413 const std::pair<float, float> test = m_line_segment.nearest_point(mouse_pos);
414 if(test.first < m_slider_radius) {
415 m_slider_position = test.second;
416 on_slide();
417 }
418 else {
419 m_slider_position = m_backup_position;
420 on_slide();
421 }
422 }
423 }
424
425 #if SDL_VERSION_ATLEAST(2,0,0)
426 void Slider::on_mouse_wheel(const Zeni::Point2i &pos, const int &up) {
427 if(!m_down) {
428 const Point3f mouse_pos(float(pos.x), float(pos.y), 0.0f);
429 const int up_ = is_mouse_wheel_inverted() ? -up : up;
430
431 const std::pair<float, float> test = get_line_segment().nearest_point(mouse_pos);
432 if(test.first < get_slider_radius()) {
433 m_slider_position = std::max(0.0f, std::min(1.0f, m_slider_position + m_mouse_wheel_continuous_rate * up_));
434
435 on_slide();
436 }
437 }
438 }
439 #endif
440
441 void Slider::on_slide() {
442 }
443
444 void Slider::on_accept() {
445 m_down = false;
446 }
447
448 Slider_Int::Slider_Int(const Range &range,
449 const Point2f &end_point_a_, const Point2f &end_point_b_,
450 const float &slider_radius_,
451 const float &slider_position_)
452 : Slider(end_point_a_, end_point_b_, slider_radius_, slider_position_),
453 m_range(range)
454 {
455 assert(range.first <= range.second);
456 set_value(get_value());
457 }
458
459 #if SDL_VERSION_ATLEAST(2,0,0)
460 void Slider_Int::on_mouse_wheel(const Zeni::Point2i &pos, const int &up) {
461 Slider::on_mouse_wheel(pos, up);
462
463 const int up_ = is_mouse_wheel_inverted() ? -up : up;
464 #else
465 void Slider_Int::on_mouse_button(const Zeni::Point2i &pos, const bool &down, const int &button) {
466 Slider::on_mouse_button(pos, down, button);
467
468 if(down || (button != SDL_BUTTON_WHEELDOWN && button != SDL_BUTTON_WHEELUP))
469 return;
470
471 const int up_ = (button == (is_mouse_wheel_inverted() ? SDL_BUTTON_WHEELDOWN : SDL_BUTTON_WHEELUP)) ? 1 : -1;
472 #endif
473
474 #ifndef ANDROID
475 if(!is_editable() || is_busy())
476 return;
477
478 const Point3f mouse_pos(float(pos.x), float(pos.y), 0.0f);
479
480 const std::pair<float, float> test = get_line_segment().nearest_point(mouse_pos);
481 if(test.first < get_slider_radius()) {
482 set_value(std::max(get_range().first, std::min(get_range().second, get_value() + up_)));
483
484 on_slide();
485 }
486 #endif
487 }
488
489 void Slider_Int::on_slide() {
490 Slider::on_slide();
491 set_value(get_value());
492 }
493
494 Selector::Normal_Button::Normal_Button(Selector &selector,
495 const Point2f &upper_left_,
496 const Point2f &lower_right_)
497 : Text_Button(upper_left_, lower_right_, selector.m_font, ""),
498 m_selector(&selector)
499 {
500 lend_Renderer(selector.m_button_renderer);
501 }
502
503 void Selector::Normal_Button::on_accept() {
504 m_selector->decide_visible(m_selector->m_option);
505 m_selector->m_selected = true;
506
507 m_selector->set_busy(true);
508 m_selector->set_layer(-0.5f);
509 }
510
511 Selector::Selector_Button::Selector_Button(Selector &selector,
512 const String &option,
513 const Point2f &upper_left_,
514 const Point2f &lower_right_)
515 : Text_Button(upper_left_, lower_right_, selector.m_font, option),
516 m_selector(&selector)
517 {
518 lend_Renderer(selector.m_button_renderer);
519 }
520
521 void Selector::Selector_Button::on_accept() {
522 m_selector->on_accept(text);
523 m_selector->m_selected = false;
524 }
525
526 Selector::Selector_Slider::Selector_Slider(Selector &selector,
527 const float &slider_radius_,
528 const std::pair<float, float> &bg_coordinates_)
529 : Widget_Rectangle(Point2f(bg_coordinates_.first, 0.0f),
530 Point2f(bg_coordinates_.second, 0.0f)),
531 Slider_Int(Range(0u, 1u),
532 Point2f(), Point2f(),
533 slider_radius_),
534 m_selector(&selector)
535 {
536 lend_Renderer(selector.m_slider_renderer);
537 }
538
539 void Selector::Selector_Slider::set_end_points(const Point2f &end_point_a_, const Point2f &end_point_b_) {
540 set_upper_left(Point2f(get_upper_left().x, end_point_a_.y - get_slider_radius()));
541 set_lower_right(Point2f(get_lower_right().x, end_point_b_.y + get_slider_radius()));
542
543 Slider_Int::set_end_points(end_point_a_, end_point_b_);
544 }
545
546 void Selector::Selector_Slider::on_slide() {
547 Slider_Int::on_slide();
548 m_selector->decide_visible(size_t(get_value()));
549 }
550
551 void Selector::Selector_Slider::render_impl() const {
552 m_selector->m_slider_bg_renderer->render_to(*this);
553 Widget::render_impl();
554 }
555
556 Selector::Selector(const Point2f &upper_left_, const Point2f &lower_right_,
557 const Point2f &expanded_upper_left_, const Point2f &expanded_lower_right_,
558 const String &font_)
559 #ifdef _WINDOWS
560 #pragma warning( push )
561 #pragma warning( disable : 4355 )
562 #endif
563 : m_button_renderer(new Widget_Renderer_Tricolor),
564 delete_m_button_renderer(true),
565 m_slider_renderer(new Widget_Renderer_Slider(get_Colors()["default_button_text_normal"], get_Colors()["default_button_text_normal"])),
566 delete_m_slider_renderer(true),
567 m_slider_bg_renderer(new Widget_Renderer_Color(get_Colors()["default_button_bg_normal"])),
568 delete_m_slider_bg_renderer(true),
569 m_font(font_),
570 m_expanded(expanded_upper_left_, expanded_lower_right_),
571 m_option(0u),
572 m_selected(false),
573 m_normal_button(*this, upper_left_, lower_right_),
574 m_selector_slider(*this,
575 0.5f * (expanded_lower_right_.x - lower_right_.x),
576 std::make_pair(lower_right_.x, expanded_lower_right_.x))
577 #ifdef _WINDOWS
578 #pragma warning( pop )
579 #endif
580 {
581 m_selector_slider.invert_mouse_wheel(true);
582
583 m_normal_button.lend_Renderer(m_button_renderer);
584 m_selector_slider.lend_Renderer(m_slider_renderer);
585 }
586
587 Selector::~Selector() {
588 clear();
589
590 if(delete_m_button_renderer)
591 delete m_button_renderer;
592 if(delete_m_slider_renderer)
593 delete m_slider_renderer;
594 if(delete_m_slider_bg_renderer)
595 delete m_slider_bg_renderer;
596 }
597
598 const Selector::Options & Selector::get_options() const {
599 return m_options;
600 }
601
602 void Selector::add_option(const String &option) {
603 if(m_options.empty())
604 m_option = 0u;
605 m_options.push_back(option);
606
607 add_selector_button(option);
608 }
609
610 void Selector::remove_option(const String &option) {
611 Options::iterator it = std::find(m_options.begin(), m_options.end(), option);
612 if(it != m_options.end())
613 m_options.erase(it);
614
615 build_selector_buttons();
616 }
617
618 String Selector::get_selected() const {
619 if(!m_options.empty())
620 return m_options[m_option];
621 return "";
622 }
623
624 void Selector::select_option(const String &option) {
625 Options::iterator it = std::find(m_options.begin(), m_options.end(), option);
626 if(it != m_options.end())
627 m_option = size_t(it - m_options.begin());
628
629 m_normal_button.text = m_options[m_option];
630 }
631
632 void Selector::on_mouse_button(const Point2i &pos, const bool &down, const int &button) {
633 #ifndef ANDROID
634 if(!is_editable())
635 return;
636
637 if(!m_selected)
638 m_normal_button.on_mouse_button(pos, down, button);
639 else {
640 const std::pair<Point2f, Point2f> v = visible_region();
641
642 if(pos.x < v.first.x || pos.x > v.second.x || pos.y < v.first.y || pos.y > v.second.y) {
643 if(button == SDL_BUTTON_LEFT) {
644 m_selected = false;
645
646 set_busy(false);
647 set_layer(0.0f);
648 }
649 }
650 else {
651 const Point2i offset_pos(pos.x, int(pos.y + vertical_offset()));
652 for(size_t i = view_start; i != view_end; ++i)
653 m_selector_buttons[i]->on_mouse_button(offset_pos, down, button);
654
655 if(view_hidden) {
656 #if !SDL_VERSION_ATLEAST(2,0,0)
657 if(button == SDL_BUTTON_WHEELDOWN || button == SDL_BUTTON_WHEELUP) {
658 const Point2f &a = m_selector_slider.get_end_point_a();
659 m_selector_slider.on_mouse_button(Point2i(int(a.x), int(a.y)), down, button);
660 }
661 else
662 #endif
663 m_selector_slider.on_mouse_button(pos, down, button);
664 }
665 }
666 }
667 #endif
668 }
669
670 #if SDL_VERSION_ATLEAST(2,0,0)
671 void Selector::on_mouse_wheel(const Zeni::Point2i &pos, const int &up) {
672 #ifndef ANDROID
673 if(!is_editable())
674 return;
675
676 if(!m_selected)
677 m_normal_button.on_mouse_wheel(pos, up);
678 else {
679 const std::pair<Point2f, Point2f> v = visible_region();
680
681 if(pos.x >= v.first.x && pos.x <= v.second.x && pos.y >= v.first.y && pos.y <= v.second.y) {
682 const Point2i offset_pos(pos.x, int(pos.y + vertical_offset()));
683 for(size_t i = view_start; i != view_end; ++i)
684 m_selector_buttons[i]->on_mouse_wheel(offset_pos, up);
685
686 if(view_hidden) {
687 const Point2f &a = m_selector_slider.get_end_point_a();
688 m_selector_slider.on_mouse_wheel(Point2i(int(a.x), int(a.y)), up);
689 }
690 }
691 }
692 #endif
693 }
694 #endif
695
696 void Selector::on_mouse_motion(const Point2i &pos) {
697 if(!is_editable())
698 return;
699
700 if(!m_selected)
701 m_normal_button.on_mouse_motion(pos);
702 else {
703 const Point2i offset_pos(pos.x, int(pos.y + vertical_offset()));
704 for(size_t i = view_start; i != view_end; ++i)
705 m_selector_buttons[i]->on_mouse_motion(offset_pos);
706
707 if(view_hidden)
708 m_selector_slider.on_mouse_motion(pos);
709 }
710 }
711
712 void Selector::on_accept(const String &option) {
713 select_option(option);
714
715 set_busy(false);
716 set_layer(0.0f);
717 }
718
719 void Selector::render_impl() const {
720 if(!m_selected)
721 m_normal_button.render_impl();
722 else {
723 Video &vr = get_Video();
724 vr.push_world_stack();
725 vr.translate_scene(Vector3f(0.0f, -vertical_offset(), 0.0f));
726
727 for(size_t i = view_start; i != view_end; ++i)
728 m_selector_buttons[i]->render_impl();
729
730 vr.pop_world_stack();
731
732 if(view_hidden)
733 m_selector_slider.render_impl();
734 }
735 }
736
737 float Selector::button_height() const {
738 const Point2f &ul = m_normal_button.get_upper_left();
739 const Point2f &lr = m_normal_button.get_lower_right();
740 return lr.y - ul.y;
741 }
742
743 float Selector::vertical_offset() const {
744 return float(view_offset) * button_height();
745 }
746
747 void Selector::decide_visible(const size_t &centered) {
748 const Point2f &nul = m_normal_button.get_upper_left();
749 const Point2f &nlr = m_normal_button.get_lower_right();
750 const Point2f &eul = m_expanded.get_upper_left();
751 const Point2f &elr = m_expanded.get_lower_right();
752
753 const size_t slots_above = size_t((nul.y - eul.y) / button_height());
754 const size_t slots_below = size_t((elr.y - nlr.y) / button_height());
755 size_t needed_above = centered;
756 size_t needed_below = m_options.size() - centered - 1u;
757
758 view_start = centered - std::min(slots_above, needed_above);
759 view_end = centered + std::min(slots_below, needed_below) + 1u;
760 view_offset = centered;
761
762 // Shift up as needed and possible
763 while(needed_above < slots_above && needed_below > slots_below) {
764 ++needed_above;
765 --needed_below;
766 ++view_end;
767 ++view_offset;
768 }
769
770 // Shift down as needed and possible
771 while(needed_below < slots_below && needed_above > slots_above) {
772 --needed_above;
773 ++needed_below;
774 --view_start;
775 --view_offset;
776 }
777
779
780 view_hidden = 0u;
781 if(needed_above > slots_above)
782 view_hidden += needed_above - slots_above;
783 if(needed_below > slots_below)
784 view_hidden += needed_below - slots_below;
785
786 if(view_hidden) {
787 const std::pair<Point2f, Point2f> v = visible_region();
788 const float r = m_selector_slider.get_slider_radius();
789 const float hx = 0.5f * (m_normal_button.get_lower_right().x + m_expanded.get_lower_right().x);
790
791 m_selector_slider.set_end_points(Point2f(hx, v.first.y + r), Point2f(hx, v.second.y - r));
792 m_selector_slider.set_range(std::make_pair(int(view_offset - needed_above + slots_above),
793 int(view_offset + needed_below - slots_below)));
794 m_selector_slider.set_value(int(view_offset));
795 }
796 }
797
798 std::pair<Point2f, Point2f> Selector::visible_region() const {
799 const Point2f &ul = m_normal_button.get_upper_left();
800 const Point2f &lr = m_normal_button.get_lower_right();
801 const float bh = button_height();
802 const float ex = view_hidden ? 2.0f * m_selector_slider.get_slider_radius() : 0.0f;
803 return std::make_pair(Point2f(ul.x, ul.y - bh * float(view_offset - view_start)),
804 Point2f(lr.x + ex, ul.y + bh * float(view_end - view_offset)));
805 }
806
807 void Selector::add_selector_button(const String &option) {
808 const Point2f &ul = m_normal_button.get_upper_left();
809 const Point2f &lr = m_normal_button.get_lower_right();
810 const float vertical_offset = float(m_selector_buttons.size()) * (lr.y - ul.y);
811 m_selector_buttons.push_back(new Selector_Button(*this, option,
812 Point2f(ul.x, ul.y + vertical_offset),
813 Point2f(lr.x, lr.y + vertical_offset)));
814 }
815
816 void Selector::build_selector_buttons() {
817 clear();
818
819 for(Options::const_iterator it = m_options.begin(); it != m_options.end(); ++it)
820 add_selector_button(*it);
821 }
822
823 void Selector::clear() {
824 for(std::vector<Selector_Button *>::const_iterator it = m_selector_buttons.begin(); it != m_selector_buttons.end(); ++it)
825 delete *it;
826 m_selector_buttons.clear();
827 }
828
829 Text_Box::Text_Box(const Point2f &upper_left_, const Point2f &lower_right_,
830 const String &font_name_, const String &text_, const Color &text_color_,
831 const bool &editable_, const JUSTIFY &justify_, const int &tab_spaces_)
832 : Widget_Button(upper_left_, lower_right_),
833 m_bg_renderer(new Widget_Renderer_Color(get_Colors()["default_button_bg_normal"])),
834 m_text(font_name_, clean_string(text_), text_color_),
835 m_edit_pos(-1),
836 m_last_seek(0),
837 m_justify(justify_),
838 m_tab_spaces(tab_spaces_),
839 m_cursor_index(-1, -1)
840 {
841 Fonts::remove_post_reinit(&g_reinit);
842
843 Fonts &fr = get_Fonts();
844
845 set_editable(editable_);
846 format();
847
848 get_text_boxes().insert(this);
849
850 fr.lend_post_reinit(&g_reinit);
851 }
852
853 Text_Box::~Text_Box() {
854 get_text_boxes().erase(this);
855
856 if(delete_m_bg_renderer)
857 delete m_bg_renderer;
858 }
859
860 #ifndef ANDROID
861 void Text_Box::on_key(const SDL_Keysym &keysym, const bool &down) {
862 if(down && m_edit_pos != -1) {
863 Game &gr = get_Game();
864 const bool mod_alt = gr.get_key_state(SDLK_LALT) || gr.get_key_state(SDLK_RALT);
865 const bool mod_ctrl = gr.get_key_state(SDLK_LCTRL) || gr.get_key_state(SDLK_RCTRL);
866 #if SDL_VERSION_ATLEAST(1,3,0)
867 const bool mod_gui = gr.get_key_state(SDLK_LGUI) || gr.get_key_state(SDLK_RGUI);
868 #else
869 const bool mod_gui = gr.get_key_state(SDLK_LMETA) || gr.get_key_state(SDLK_RMETA) ||
870 gr.get_key_state(SDLK_LSUPER) || gr.get_key_state(SDLK_RSUPER);
871 #endif
872 const bool mod_shift = gr.get_key_state(SDLK_LSHIFT) || gr.get_key_state(SDLK_RSHIFT);
873 const bool mod_none = !mod_alt && !mod_ctrl && !mod_gui && !mod_shift;
874 const bool mod_ctrl_only = !mod_alt && mod_ctrl && !mod_gui && !mod_shift;
875 const bool mod_shift_only = !mod_alt && !mod_ctrl && !mod_gui && mod_shift;
876
877 switch(keysym.sym) {
878 case SDLK_BACKSPACE:
879 if(mod_none)
880 {
881 const String &t = get_text();
882
883 if(m_edit_pos > 0) {
884 String t0 = t.substr(0u, m_edit_pos - 1u);
885 String t1 = t.substr(size_t(m_edit_pos), t.size() - m_edit_pos);
886
887 m_text.text = t0 + t1;
888 format();
889 seek(m_edit_pos - 1);
890
891 on_change();
892 }
893 }
894 break;
895 case SDLK_DELETE:
896 if(mod_none)
897 {
898 const String &t = get_text();
899
900 if(m_edit_pos < int(t.size())) {
901 String t0 = t.substr(0u, size_t(m_edit_pos));
902 String t1 = t.substr(m_edit_pos + 1u, t.size() - m_edit_pos - 1);
903
904 m_text.text = t0 + t1;
905 format();
906 seek(m_edit_pos);
907
908 on_change();
909 }
910 }
911 break;
912 case SDLK_HOME:
913 if(mod_none || mod_ctrl_only)
914 {
915 if(mod_ctrl)
916 seek_cursor(0);
917 else if(m_cursor_index.x) {
918 int cursor_pos = get_cursor_pos() - m_cursor_index.x;
919 if(m_lines[size_t(m_cursor_index.y)].endled)
920 ++cursor_pos;
921
922 seek_cursor(cursor_pos);
923 }
924 }
925 break;
926 case SDLK_END:
927 if(mod_none || mod_ctrl_only)
928 {
929 int cursor_pos = mod_ctrl ?
930 get_max_cursor_seek() :
931 get_cursor_pos() - m_cursor_index.x + int(m_lines[size_t(m_cursor_index.y)].unformatted.size());
932
933 seek_cursor(cursor_pos);
934 }
935 break;
936 case SDLK_LEFT:
937 if(mod_none)
938 seek(m_edit_pos - 1);
939 break;
940 case SDLK_RIGHT:
941 if(mod_none)
942 seek(m_edit_pos + 1);
943 break;
944 case SDLK_UP:
945 if(mod_none)
946 if(m_cursor_index.y) {
947 size_t count = 0u;
948 for(size_t i = 0u, iend = m_cursor_index.y - 1u; i != iend; ++i)
949 count += m_lines[i].unformatted.size();
950 count += std::min(size_t(m_cursor_index.x), m_lines[m_cursor_index.y - 1u].unformatted.size());
951
952 seek(int(count));
953 }
954 break;
955 case SDLK_DOWN:
956 if(mod_none)
957 if(m_cursor_index.y + 1 < int(m_lines.size())) {
958 size_t count = 0u;
959 for(size_t i = 0u, iend = m_cursor_index.y + 1u; i != iend; ++i)
960 count += m_lines[i].unformatted.size();
961 count += std::min(size_t(m_cursor_index.x), m_lines[m_cursor_index.y + 1u].unformatted.size());
962
963 seek(int(count));
964 }
965 break;
966 default:
967 if(mod_none || mod_shift_only)
968 {
969 const char c = Gamestate_Base::to_char(keysym);
970 const String &t = get_text();
971 String t0 = t.substr(0u, size_t(m_edit_pos));
972 String t1 = t.substr(size_t(m_edit_pos), t.size() - m_edit_pos);
973 String next = clean_string(t0 + c + t1);
974
975 if(next.size() != t.size()) {
976 m_text.text = next;
977 format();
978 seek(m_edit_pos + 1);
979
980 on_change();
981 }
982 }
983 break;
984 }
985 }
986 }
987 #endif
988
989 void Text_Box::on_mouse_button(const Point2i &pos, const bool &down, const int &button) {
990 #ifndef ANDROID
991 if(button != SDL_BUTTON_LEFT)
992 return;
993
994 m_cursor_pos.x = int(pos.x - get_upper_left().x);
995 m_cursor_pos.y = int(pos.y - get_upper_left().y);
996
997 const bool was_focused = m_edit_pos != -1;
998 invalidate_edit_pos();
999
1000 Widget_Button::on_mouse_button(pos, down, button);
1001
1002 if(m_edit_pos == -1) {
1003 if(was_focused)
1004 on_unfocus();
1005 }
1006 else {
1007 if(!was_focused)
1008 on_focus();
1009 }
1010 #endif
1011 }
1012
1013 void Text_Box::on_accept() {
1014 size_t j = 0, jend = m_lines.size();
1015 for(; j != jend && m_cursor_pos.y > m_lines[j].glyph_top; ++j);
1016 --j;
1017
1019
1020 const Font &f = get_Font();
1021
1022 float x_pos;
1023 if(m_justify == ZENI_LEFT)
1024 x_pos = 0.0f;
1025 else if(m_justify == ZENI_RIGHT)
1026 x_pos = get_lower_right().x - get_upper_left().x;
1027 else
1028 x_pos = (get_lower_right().x - get_upper_left().x) / 2.0f;
1029
1030 if(m_justify == ZENI_RIGHT)
1031 x_pos -= f.get_text_width(m_lines[j].formatted);
1032 else if(m_justify == ZENI_CENTER)
1033 x_pos -= f.get_text_width(m_lines[j].formatted) / 2.0f;
1034
1036
1037 int i = 0, iend = int(m_lines[j].unformatted_glyph_sides.size());
1038 for(; i != iend && m_cursor_pos.x > x_pos + m_lines[j].unformatted_glyph_sides[size_t(i)]; ++i);
1039 if(i) // Can be negative if using ZENI_CENTER or ZENI_RIGHT justification
1040 --i;
1041
1043 if(i + 1 != iend && m_cursor_pos.x > x_pos + (0.2f * m_lines[j].unformatted_glyph_sides[size_t(i)] +
1044 0.8f * m_lines[j].unformatted_glyph_sides[i + 1u]))
1045 ++i;
1046
1047 m_cursor_index.x = Sint32(i);
1048 m_cursor_index.y = Sint32(j);
1049 m_edit_pos = i;
1050 for(size_t k = 0; k < j; ++k)
1051 m_edit_pos += int(m_lines[k].unformatted.size());
1052
1053 #ifdef _DEBUG
1054 {
1055 const size_t size = get_text().size();
1056 size_t count = 0u;
1057 for(size_t m = 0u, mend = m_lines.size(); m != mend; ++m)
1058 count += m_lines[m].unformatted.size();
1059
1060 assert(size == count);
1061 }
1062
1063 seek(m_edit_pos);
1064 #endif
1065 }
1066
1067 void Text_Box::on_focus() {
1068 }
1069
1070 void Text_Box::on_unfocus() {
1071 }
1072
1073 void Text_Box::on_change() {
1074 }
1075
1076 void Text_Box::render_impl() const {
1077 m_bg_renderer->render_to(*this);
1078
1079 Video &vr = get_Video();
1080
1081 const Font &f = get_Font();
1082 const Color &c = m_text.color;
1083
1084 float x_pos;
1085 if(m_justify == ZENI_LEFT)
1086 x_pos = get_upper_left().x;
1087 else if(m_justify == ZENI_RIGHT)
1088 x_pos = get_lower_right().x;
1089 else
1090 x_pos = (get_upper_left().x + get_lower_right().x) / 2.0f;
1091
1092 const float &y_offset = get_upper_left().y;
1093 for(size_t i = 0u, iend = m_lines.size(); i != iend; ++i)
1094 f.render_text(m_lines[i].formatted, Point2f(x_pos, y_offset + m_lines[i].glyph_top), c, m_justify);
1095
1096 if(m_cursor_index.x != -1 && m_cursor_index.y != -1
1097 && !((get_Timer().get_time().get_ticks_since(m_last_seek) / SDL_DEFAULT_REPEAT_DELAY) & 1) // HACK: render every other second
1098 )
1099 {
1100 Point2f p0(x_pos + m_lines[size_t(m_cursor_index.y)].unformatted_glyph_sides[size_t(m_cursor_index.x)],
1101 get_upper_left().y + m_lines[size_t(m_cursor_index.y)].glyph_top);
1102 if(m_justify == ZENI_RIGHT)
1103 p0.x -= f.get_text_width(m_lines[size_t(m_cursor_index.y)].formatted);
1104 else if(m_justify == ZENI_CENTER)
1105 p0.x -= f.get_text_width(m_lines[size_t(m_cursor_index.y)].formatted) / 2.0f;
1106
1107 const Point2f p1(p0.x, p0.y + f.get_text_height());
1108 const float epsilon = f.get_text_height() * ZENI_TEXT_CURSOR_WIDTH / 2.0f;
1109
1110 const Vertex2f_Color v0(Point2f(p0.x - epsilon, p0.y), c);
1111 const Vertex2f_Color v1(Point2f(p1.x - epsilon, p1.y), c);
1112 const Vertex2f_Color v2(Point2f(p1.x + epsilon, p1.y), c);
1113 const Vertex2f_Color v3(Point2f(p0.x + epsilon, p0.y), c);
1114
1115 const Quadrilateral<Vertex2f_Color> visible_cursor(v0, v1, v2, v3);
1116 vr.render(visible_cursor);
1117 }
1118 }
1119
1120 void Text_Box::format() {
1121 m_lines.clear();
1122 m_lines.push_back(Line());
1123
1124 const String t = get_text();
1125 const Font &f = get_Font();
1126 const float mll = max_line_width();
1127
1128 if(t.empty())
1129 return;
1130
1131 std::list<Word> words;
1132 Word next_word;
1133
1134 for(unsigned int i = 0, iend = static_cast<unsigned int>(t.size()); i != iend; ++i) {
1135 const Word::Type type = isspace(t[i]) ? Word::SPACE : Word::WORD;
1136
1137 if(next_word.type) {
1138 if(next_word.type != type || t[i] == '\n') {
1139 words.push_back(next_word);
1140 next_word = Word(type);
1141 }
1142 }
1143 else
1144 next_word.type = type;
1145
1146 next_word.unformatted += t[i];
1147
1148 const float next_width = get_text_width(f, next_word.unformatted);
1149 next_word.unformatted_glyph_sides.push_back(next_width);
1150 if(type != Word::SPACE && next_width > mll)
1151 next_word.splittable = true;
1152 }
1153 if(next_word.type != Word::NONSENSE)
1154 words.push_back(next_word);
1155
1156 for(std::list<Word>::iterator it = words.begin(); it != words.end(); ++it)
1157 append_word(*it);
1158
1159 float glyph_top = 0.0f;
1160 for(std::vector<Line>::iterator it = m_lines.begin(); it != m_lines.end(); ++it) {
1161 it->formatted = untablinebreak(it->unformatted);
1162 if(it->fpsplit)
1163 it->formatted += "-";
1164 it->glyph_top = glyph_top;
1165 if(!it->unformatted.empty() && it->unformatted[0] == '\n')
1166 it->endled = true;
1167
1168 glyph_top += f.get_text_height();
1169 }
1170 }
1171
1172 void Text_Box::append_word(const Word &word) {
1173 const Font &f = get_Font();
1174 const float mll = max_line_width();
1175
1176 if(!word.unformatted.empty() && word.unformatted[0] == '\n')
1177 m_lines.push_back(Line());
1178
1179 Line &l = *m_lines.rbegin();
1180 float next_sum = get_text_width(f, l.unformatted + word.unformatted);
1181
1182 if(word.type != Word::SPACE && next_sum > mll && !word.fpsplit) {
1183 if(word.splittable) {
1184 size_t i = 0u, iend = word.unformatted.size();
1185 for(; i != iend && get_text_width(f, l.unformatted + word.unformatted.substr(0u, i) + "-") < mll; ++i);
1186 if(!l.unformatted.empty())
1187 --i;
1188 if(i != 0u && i != size_t(-1)) {
1189 {
1190 Word first_word(word.type);
1191 first_word.unformatted = word.unformatted.substr(0, i);
1192 for(size_t j = 1u, jend = first_word.unformatted.size(); j <= jend; ++j)
1193 first_word.unformatted_glyph_sides.push_back(get_text_width(f, first_word.unformatted.substr(0u, j)));
1194 first_word.fpsplit = true;
1195 append_word(first_word);
1196 }
1197
1198 {
1199 Word second_word(word.type);
1200 second_word.unformatted = word.unformatted.substr(i, word.unformatted.size() - i);
1201 for(size_t j = 1u, jend = second_word.unformatted.size(); j <= jend; ++j)
1202 second_word.unformatted_glyph_sides.push_back(get_text_width(f, second_word.unformatted.substr(0u, j)));
1203 second_word.splittable = get_text_width(f, second_word.unformatted) > mll;
1204 append_word(second_word);
1205 }
1206 }
1207 else {
1208 Word only_word(word);
1209 only_word.fpsplit = l.unformatted.empty();
1210 m_lines.push_back(Line());
1211 append_word(only_word);
1212 return;
1213 }
1214 }
1215 else {
1216 m_lines.push_back(Line());
1217 append_word(word);
1218 }
1219 }
1220 else {
1221 for(unsigned int i = 0u, iend = static_cast<unsigned int>(word.unformatted.size()); i != iend; ++i) {
1222 l.unformatted += word.unformatted[i];
1223 l.unformatted_glyph_sides.push_back(get_text_width(f, l.unformatted));
1224 }
1225
1226 l.fpsplit = word.fpsplit;
1227 }
1228 }
1229
1230 void Text_Box::set_editable(const bool &editable_) {
1231 Widget::set_editable(editable_);
1232 format();
1233 invalidate_edit_pos();
1234 }
1235
1236 void Text_Box::set_upper_left(const Point2f &upper_left_) {
1237 Widget_Rectangle::set_upper_left(upper_left_);
1238 format();
1239 seek(get_edit_pos());
1240 }
1241
1242 void Text_Box::set_lower_right(const Point2f &lower_right_) {
1243 Widget_Rectangle::set_lower_right(lower_right_);
1244 format();
1245 seek(get_edit_pos());
1246 }
1247
1248 const int & Text_Box::get_edit_pos() const {
1249 return m_edit_pos;
1250 }
1251
1252 int Text_Box::get_cursor_pos() const {
1253 size_t count = size_t(m_cursor_index.x);
1254 for(size_t j = 0u, jend = size_t(m_cursor_index.y); j != jend; ++j)
1255 count += m_lines[j].unformatted_glyph_sides.size();
1256 return int(count);
1257 }
1258
1259 int Text_Box::get_max_seek() const {
1260 return int(get_text().size());
1261 }
1262
1263 int Text_Box::get_max_cursor_seek() const {
1264 if(!m_lines.empty()) {
1265 size_t count = 0u;
1266 for(std::vector<Line>::const_iterator it = m_lines.begin(); it != m_lines.end(); ++it)
1267 count += it->unformatted_glyph_sides.size();
1268 return int(count);
1269 }
1270 else
1271 return -1;
1272 }
1273
1274 void Text_Box::seek(const int &edit_pos) {
1275 if(!is_editable())
1276 return;
1277
1278 const String t = get_text();
1279
1280 if(edit_pos < 0 ||
1281 edit_pos > int(t.size()))
1282 return;
1283
1284 m_edit_pos = edit_pos;
1285 size_t j = 0u, jend = m_lines.size();
1286 int count = 0, i = -1, iend;
1287 for(; j != jend; ++j) {
1288 iend = int(m_lines[j].unformatted.size());
1289
1290 if(count + iend < edit_pos) {
1291 count += iend;
1292 continue;
1293 }
1294
1295 i = edit_pos - count;
1296 break;
1297 }
1298
1299 m_cursor_index.x = Sint32(i);
1300 m_cursor_index.y = Sint32(j);
1301
1302 m_last_seek = get_Timer().get_time();
1303 }
1304
1305 void Text_Box::seek_cursor(const int &cursor_pos) {
1306 if(!is_editable() || cursor_pos < 0)
1307 return;
1308
1309 size_t j = 0u, jend = m_lines.size();
1310 int edit_count = 0, count = 0, i = -1, iend;
1311 for(; j != jend; ++j) {
1312 iend = int(m_lines[j].unformatted_glyph_sides.size());
1313
1314 if(count + iend <= cursor_pos) {
1315 count += iend;
1316 edit_count += int(m_lines[j].unformatted.size());
1317 continue;
1318 }
1319
1320 i = cursor_pos - count;
1321 edit_count += i;
1322 break;
1323 }
1324
1325 if(i != -1) {
1326 m_edit_pos = edit_count;
1327 m_cursor_index.x = Sint32(i);
1328 m_cursor_index.y = Sint32(j);
1329 }
1330
1331 m_last_seek = get_Timer().get_time();
1332 }
1333
1334 void Text_Box::set_focus(const bool &value) {
1335 if(!is_editable())
1336 return;
1337
1338 if(value) {
1339 const bool was_focused = m_edit_pos != -1;
1340 seek(get_max_seek());
1341 if(!was_focused)
1342 on_focus();
1343 }
1344 else {
1345 const bool was_focused = m_edit_pos != -1;
1346 invalidate_edit_pos();
1347 if(was_focused)
1348 on_unfocus();
1349 }
1350 }
1351
1352 String Text_Box::clean_string(const String &unclean_string) const {
1353 String cleaned;
1354 for(String::const_iterator it = unclean_string.begin(); it != unclean_string.end(); ++it)
1355 if(*it >= 0x20 ||
1356 *it == '\n' || *it == '\t')
1357 cleaned += *it;
1358 return cleaned;
1359 }
1360
1361 String Text_Box::untablinebreak(const String &tabbed_text) const {
1362 String untabbed_text;
1363
1364 for(String::const_iterator it = tabbed_text.begin(); it != tabbed_text.end(); ++it) {
1365 if(*it != '\t') {
1366 if(*it > 0x1F)
1367 untabbed_text += *it;
1368 }
1369 else
1370 for(int i = m_tab_spaces; i; --i)
1371 untabbed_text += ' ';
1372 }
1373
1374 return untabbed_text;
1375 }
1376
1377 float Text_Box::get_text_width(const Font &font, const String &text) {
1378 const String untabbed_text = untablinebreak(text);
1379
1380 if(font.get_text_width(" "))
1381 return font.get_text_width(untabbed_text);
1382
1383 String fake_text;
1384 for(String::const_iterator it = untabbed_text.begin(); it != untabbed_text.end(); ++it)
1385 if(*it != ' ')
1386 fake_text += *it;
1387 else
1388 fake_text += '.';
1389
1390 return font.get_text_width(fake_text);
1391 }
1392
1393 float Text_Box::max_line_width() const {
1394 return get_lower_right().x - get_upper_left().x;
1395 }
1396
1397 void Text_Box::reformat_all() {
1398 std::set<Text_Box *> &text_boxes = get_text_boxes();
1399
1400 for(std::set<Text_Box *>::iterator it = text_boxes.begin(); it != text_boxes.end(); ++it) {
1401 (*it)->format();
1402 (*it)->seek((*it)->get_edit_pos());
1403 }
1404 }
1405
1406 std::set<Text_Box *> & Text_Box::get_text_boxes() {
1407 static std::set<Text_Box *> text_boxes;
1408 return text_boxes;
1409 }
1410
1411 #ifndef ANDROID
1412 void Widget_Input_Repeater::on_key(const SDL_Keysym &keysym, const bool &down) {
1413 if(!is_editable())
1414 return;
1415
1416 m_keysym = keysym;
1417 m_down = down;
1418
1419 m_last_repeated = get_Timer().get_time();
1420 m_active = true;
1421 m_delay_finished = false;
1422
1423 m_widget->on_key(m_keysym, m_down);
1424
1425 set_busy(m_widget->is_busy());
1426 }
1427 #endif
1428
1429 void Widget_Input_Repeater::on_mouse_button(const Point2i &pos, const bool &down, const int &button) {
1430 if(!is_editable())
1431 return;
1432
1433 m_active = false;
1434
1435 m_widget->on_mouse_button(pos, down, button);
1436
1437 set_busy(m_widget->is_busy());
1438 }
1439
1440 void Widget_Input_Repeater::on_mouse_motion(const Point2i &pos) {
1441 if(!is_editable())
1442 return;
1443
1444 m_widget->on_mouse_motion(pos);
1445
1446 set_busy(m_widget->is_busy());
1447 }
1448
1449 void Widget_Input_Repeater::perform_logic() {
1450 #ifndef ANDROID
1451 if(!m_active)
1452 return;
1453
1454 const Time current_time = get_Timer().get_time();
1455 const int ticks = int(current_time.get_ticks_since(m_last_repeated));
1456
1457 if((m_delay_finished && ticks > m_repeat_interval) ||
1458 (!m_delay_finished && ticks > m_repeat_delay))
1459 {
1460 m_delay_finished = true;
1461 m_last_repeated = current_time;
1462 m_widget->on_key(m_keysym, m_down);
1463 }
1464 #endif
1465 }
1466
1467 void Widget_Input_Repeater::render_impl() const {
1468 m_widget->render();
1469 }
1470
1471 static bool widget_layer_less(const Widget * const &lhs, const Widget * const &rhs) {
1472 return lhs->get_layer() < rhs->get_layer();
1473 }
1474
1475 #ifndef ANDROID
1476 void Widgets::on_key(const SDL_Keysym &keysym, const bool &down) {
1477 if(!is_editable())
1478 return;
1479
1480 if(m_busy_one) {
1481 m_busy_one->on_key(keysym, down);
1482
1483 if(!m_busy_one->is_busy()) {
1484 m_busy_one = 0;
1485 set_busy(false);
1486 }
1487 }
1488 else {
1489 std::sort(m_widgets.begin(), m_widgets.end(), &widget_layer_less);
1490
1491 for(std::vector<Widget *>::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it) {
1492 (*it)->on_key(keysym, down);
1493
1494 if(!m_busy_one && (*it)->is_busy()) {
1495 m_busy_one = *it;
1496 set_busy(true);
1497 }
1498 }
1499 }
1500 }
1501 #endif
1502
1503 void Widgets::on_mouse_button(const Point2i &pos, const bool &down, const int &button) {
1504 if(!is_editable())
1505 return;
1506
1507 if(m_busy_one) {
1508 m_busy_one->on_mouse_button(pos, down, button);
1509
1510 if(!m_busy_one->is_busy()) {
1511 m_busy_one = 0;
1512 set_busy(false);
1513 }
1514 }
1515 else {
1516 std::sort(m_widgets.begin(), m_widgets.end(), &widget_layer_less);
1517
1518 for(std::vector<Widget *>::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it) {
1519 (*it)->on_mouse_button(pos, down, button);
1520
1521 if(!m_busy_one && (*it)->is_busy()) {
1522 m_busy_one = *it;
1523 set_busy(true);
1524 }
1525 }
1526 }
1527 }
1528
1529 void Widgets::on_mouse_motion(const Point2i &pos) {
1530 if(!is_editable())
1531 return;
1532
1533 if(m_busy_one) {
1534 m_busy_one->on_mouse_motion(pos);
1535
1536 if(!m_busy_one->is_busy()) {
1537 m_busy_one = 0;
1538 set_busy(false);
1539 }
1540 }
1541 else {
1542 std::sort(m_widgets.begin(), m_widgets.end(), &widget_layer_less);
1543
1544 for(std::vector<Widget *>::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it) {
1545 (*it)->on_mouse_motion(pos);
1546
1547 if(!m_busy_one && (*it)->is_busy()) {
1548 m_busy_one = *it;
1549 set_busy(true);
1550 }
1551 }
1552 }
1553 }
1554
1555 #if SDL_VERSION_ATLEAST(2,0,0)
1556 void Widgets::on_mouse_wheel(const Zeni::Point2i &pos, const int &up) {
1557 if(!is_editable())
1558 return;
1559
1560 if(m_busy_one) {
1561 m_busy_one->on_mouse_wheel(pos, up);
1562
1563 if(!m_busy_one->is_busy()) {
1564 m_busy_one = 0;
1565 set_busy(false);
1566 }
1567 }
1568 else {
1569 std::sort(m_widgets.begin(), m_widgets.end(), &widget_layer_less);
1570
1571 for(std::vector<Widget *>::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it) {
1572 (*it)->on_mouse_wheel(pos, up);
1573
1574 if(!m_busy_one && (*it)->is_busy()) {
1575 m_busy_one = *it;
1576 set_busy(true);
1577 }
1578 }
1579 }
1580 }
1581 #endif
1582
1583 void Widgets::perform_logic() {
1584 std::sort(m_widgets.begin(), m_widgets.end(), &widget_layer_less);
1585
1586 for(std::vector<Widget *>::const_reverse_iterator it = m_widgets.rbegin(), iend = m_widgets.rend(); it != iend; ++it)
1587 (*it)->perform_logic();
1588 }
1589
1590 void Widgets::render_impl() const {
1591 std::sort(m_widgets.begin(), m_widgets.end(), &widget_layer_less);
1592
1593 for(std::vector<Widget *>::const_reverse_iterator it = m_widgets.rbegin(), iend = m_widgets.rend(); it != iend; ++it)
1594 (*it)->render();
1595 }
1596
1597 Text_Box::Reinit Text_Box::g_reinit;
1598
1599 }
Zeni::Slider_Int::on_slide
virtual void on_slide()
Definition: Widget.cpp:489
Zeni::Font::get_text_width
virtual float get_text_width(const String &text) const =0
Get the width of text rendering using this font. Approximately text_height * text.length() / 2.0f.
Zeni::Point2i::y
Sint32 y
Definition: Coordinate.h:94
Zeni::widget_layer_less
static bool widget_layer_less(const Widget *const &lhs, const Widget *const &rhs)
Definition: Widget.cpp:1471
Zeni::Selector::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)
Definition: Widget.cpp:696
Zeni::Widget_Button::HOVERED
Definition: Widget.h:459
Zeni::Widget_Renderer_Check_Box::render_to
virtual void render_to(const Widget &widget)
rect must be of type Check_Box
Definition: Widget.cpp:146
Zeni::Widget::~Widget
virtual ~Widget()
Definition: Widget.cpp:31
v1
GLfloat GLfloat v1
Definition: glew.h:1838
t0
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition: glew.h:11582
Zeni::Widget_Renderer_Tricolor::Widget_Renderer_Tricolor
Widget_Renderer_Tricolor()
Definition: Widget.hxx:274
Sint32
int32_t Sint32
A signed 32-bit integer type.
Definition: SDL_stdinc.h:141
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
SDLK_RCTRL
Definition: SDL_keycode.h:277
SDLK_LSHIFT
Definition: SDL_keycode.h:274
Zeni::Widget_Renderer_Color::Widget_Renderer_Color
Widget_Renderer_Color(const Color &color_)
Definition: Widget.hxx:247
Zeni::Widget_Renderer_Text::text
String text
Definition: Widget.h:346
Zeni::Slider::get_end_point_b
Point2f get_end_point_b() const
Definition: Widget.hxx:391
color
GLuint color
Definition: glew.h:7185
Zeni::Line_Segment
An Abstraction of a Line.
Definition: Line_Segment.h:36
Zeni::Slider::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)
Definition: Widget.cpp:409
Zeni::Check_Box::on_accept
virtual void on_accept()
Called when the cursor is released inside the button.
Definition: Widget.cpp:315
Zeni::Video
The Video Rendering Singleton.
Definition: Video.h:71
Zeni::Slider::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:380
Zeni::Widget::is_editable
const bool & is_editable() const
Definition: Widget.hxx:52
Zeni::Vertex2f_Color
An Abstraction of a Vertex in 2-space, colored.
Definition: Vertex2f.h:80
Zeni::get_Colors
Colors & get_Colors()
Get access to the singleton.
Definition: Colors.cpp:51
f
GLclampf f
Definition: glew.h:3390
Zeni::Check_Box
A Check Box.
Definition: Widget.h:501
Zeni::Widget_Rectangle::get_center
Point2f get_center() const
Definition: Widget.hxx:172
Zeni::Widget_Button::on_accept
virtual void on_accept()
Called when the cursor is released inside the button.
Definition: Widget.h:484
Zeni::Text_Box::get_Font
const Font & get_Font() const
Definition: Widget.hxx:540
SDLK_DELETE
Definition: SDL_keycode.h:145
Zeni::Text_Box::on_focus
virtual void on_focus()
Definition: Widget.cpp:1067
Zeni::Game::get_key_state
bool get_key_state(const int &key) const
Get the state of a key.
Definition: Game.cpp:287
k
int32_t k
Definition: e_log.c:102
Zeni::Fonts
A Font database read in from a file.
Definition: Fonts.h:51
Zeni::Widget::lend_Renderer
void lend_Renderer(const Widget_Render_Function *const &renderer)
Set the current Widget_Render_Function, giving the Widget no ownership.
Definition: Widget.hxx:133
n
GLclampd n
Definition: glew.h:7287
Zeni::Widget::render
void render() const
Definition: Widget.hxx:111
SDLK_BACKSPACE
Definition: SDL_keycode.h:53
Zeni::String::empty
bool empty() const
Definition: String.cpp:325
Zeni::Widget::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)=0
Zeni::Widget_Renderer_Tricolor::text_clicked
Color text_clicked
Definition: Widget.h:398
Zeni::Widget_Renderer_Tricolor::text_hovered_strayed
Color text_hovered_strayed
Definition: Widget.h:399
x
EGLSurface EGLint x
Definition: eglext.h:293
Zeni::Widget::get_layer
const float & get_layer() const
Definition: Widget.hxx:56
Zeni::Text_Box::on_key
virtual void on_key(const SDL_Keysym &keysym, const bool &down)
Definition: Widget.cpp:861
t
GLdouble GLdouble t
Definition: glew.h:1384
Zeni::Material
An Abstraction of a Material.
Definition: Material.h:56
Zeni::Widget_Rectangle::get_lower_left
Point2f get_lower_left() const
Definition: Widget.hxx:152
Zeni::Widget_Renderer_Tricolor
Definition: Widget.h:383
j
int32_t j
Definition: e_log.c:102
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: glew.h:1846
zeni_rest.h
Zeni::Text_Box::reformat_all
static void reformat_all()
Reformat all Text_Box instances.
Definition: Widget.cpp:1397
Zeni::Slider::on_slide
virtual void on_slide()
Definition: Widget.cpp:441
Zeni::Widget_Rectangle::get_upper_right
Point2f get_upper_right() const
Definition: Widget.hxx:160
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
Zeni::Widget::give_Renderer
void give_Renderer(Widget_Render_Function *const &renderer)
Set the current Widget_Render_Function, giving the Widget ownership.
Definition: Widget.hxx:126
SDL_DEFAULT_REPEAT_DELAY
#define SDL_DEFAULT_REPEAT_DELAY
Definition: SDL.h:6
Zeni::Widget_Renderer_Texture::render_to
virtual void render_to(const Widget &widget)
rect must be of type Widget_Rectangle
Definition: Widget.cpp:89
Zeni::Text_Box::render_impl
virtual void render_impl() const
Definition: Widget.cpp:1076
SDL_Keysym
The SDL keysym structure, used in key events.
Definition: SDL_keyboard.h:47
Zeni::Quadrilateral
An Abstraction of a Quadrilateral.
Definition: Quadrilateral.h:37
Zeni::Radio_Button_Set::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)
Definition: Widget.cpp:354
Zeni::Widget_Renderer_Tricolor::bg_hovered_strayed
Color bg_hovered_strayed
Definition: Widget.h:396
Zeni::Time::get_ticks_since
Tick_Type get_ticks_since(const Time &time) const
Get the number of clock ticks passed between &#39;time&#39; and this Time.
Definition: Timer.hxx:40
assert
#define assert(x)
Definition: SDL_malloc.c:1234
Zeni::Widget_Button::on_unhover
virtual void on_unhover()
Called when the cursor leaves the button without clicking.
Definition: Widget.h:474
Zeni::Widget_Renderer_Check_Box::get_duplicate
virtual Widget_Renderer_Check_Box * get_duplicate() const
Definition: Widget.cpp:195
Zeni::Slider_Int::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:465
Type
Type
Definition: SDL_dxjoystick_c.h:115
Zeni::Slider_Int::get_range
const Range & get_range() const
Definition: Widget.hxx:440
Zeni::Widget_Rectangle::set_upper_left
virtual void set_upper_left(const Point2f &upper_left_)
Definition: Widget.cpp:45
Zeni::Singleton< Fonts >::remove_post_reinit
static void remove_post_reinit(Event::Handler *const &handler)
Zeni::JUSTIFY
JUSTIFY
Definition: Font.h:68
Zeni::Widget_Button::CLICKED
Definition: Widget.h:459
Zeni::Slider::get_slider_position
const float & get_slider_position() const
Definition: Widget.hxx:399
Zeni::Singleton::lend_post_reinit
void lend_post_reinit(Event::Handler *const &handler)
Definition: Singleton.hxx:76
Zeni::Widgets::on_key
virtual void on_key(const SDL_Keysym &keysym, const bool &down)
Definition: Widget.cpp:1476
Zeni::get_Game
Game & get_Game()
Get access to the singleton.
Definition: Game.cpp:58
Zeni::Game
The Gamestate Stack.
Definition: Game.h:71
Zeni::Widgets::render_impl
virtual void render_impl() const
Definition: Widget.cpp:1590
Zeni::ZENI_CENTER
Definition: Font.h:68
Zeni::String::substr
String substr(size_t pos=0, size_t n=npos) const
Definition: String.cpp:510
Zeni::Widget_Renderer_Text::get_duplicate
virtual Widget_Renderer_Text * get_duplicate() const
Definition: Widget.cpp:67
SDLK_LEFT
Definition: SDL_keycode.h:149
Zeni::Gamestate_Base::to_char
static char to_char(const SDL_Keysym &ks)
Returns a character key corresponding to the current combination of keys pressed or the null characte...
Definition: Gamestate.cpp:184
Zeni::String
Definition: String.h:29
Zeni::Check_Box::on_click
virtual void on_click()
Called when the cursor downclicks the button.
Definition: Widget.cpp:320
Zeni::Point3f
A 3D Point represented with floats.
Definition: Coordinate.h:133
get_time
static long get_time(void)
Definition: test_bbox.c:16
Zeni::Widget_Renderer_Texture::tex_coord_ul
Point2f tex_coord_ul
Definition: Widget.h:377
SDLK_END
Definition: SDL_keycode.h:146
Zeni::Widget_Renderer_Slider
Definition: Widget.h:416
range
GLenum GLint * range
Definition: glew.h:3391
t1
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition: glew.h:11582
Zeni::Check_Box::on_stray
virtual void on_stray()
Called when the cursor is dragged off the button after being clicked.
Definition: Widget.cpp:332
SDLK_HOME
Definition: SDL_keycode.h:143
Zeni::Selector::add_option
void add_option(const String &option)
Definition: Widget.cpp:602
Zeni::Widget_Input_Repeater::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
on_mouse_button deactivates the repeater (if active) and then passes input to the Widget ...
Definition: Widget.cpp:1429
Zeni::Point2f::y
float y
Definition: Coordinate.h:117
option
GLuint GLenum option
Definition: glew.h:3180
Zeni::Widget_Renderer_Color::color
Color color
Definition: Widget.h:359
Zeni::Widget_Renderer_Texture::tex_coord_ur
Point2f tex_coord_ur
Definition: Widget.h:380
Zeni::get_Timer
Timer & get_Timer()
Get access to the singleton.
Definition: Timer.cpp:73
Zeni::Vector3f
A Featureful 3-Space Vector Class.
Definition: Vector3f.h:58
Zeni::ZENI_RIGHT
Definition: Font.h:68
Zeni::Widget_Renderer_Texture::Widget_Renderer_Texture
Widget_Renderer_Texture(const String &texture_)
Definition: Widget.hxx:252
Zeni::Widget_Button::UNACTIONABLE
Definition: Widget.h:459
u
ALuint u
Definition: alMain.h:58
Zeni::Widget_Renderer_Check_Box::border_color
Color border_color
Definition: Widget.h:412
first
GLint first
Definition: gl2ext.h:1011
Zeni::Text_Box::set_upper_left
virtual void set_upper_left(const Point2f &upper_left_)
Definition: Widget.cpp:1236
v
const GLdouble * v
Definition: glew.h:1377
Zeni::Widget_Renderer_Tricolor::bg_normal
Color bg_normal
Definition: Widget.h:394
SDLK_RSHIFT
Definition: SDL_keycode.h:278
Zeni::Widget_Renderer_Tricolor::render_to
virtual void render_to(const Widget &widget)
rect must be of type Widget_Button and Widget_Renderer_Text
Definition: Widget.cpp:109
Zeni::Widget_Renderer_Tricolor::text_normal
Color text_normal
Definition: Widget.h:397
Zeni::Text_Box::set_lower_right
virtual void set_lower_right(const Point2f &lower_right_)
Definition: Widget.cpp:1242
SDLK_LGUI
Definition: SDL_keycode.h:276
int
int
Definition: SDL_systhread.c:37
Zeni::String::end
iterator end()
Definition: String.cpp:301
Zeni::Selector
Definition: Widget.h:660
SDL_BUTTON_LEFT
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:204
Define.h
Zeni::Widget_Button::on_hover
virtual void on_hover()
Called when the cursor passes over the button.
Definition: Widget.h:472
Zeni::Text_Box::set_editable
virtual void set_editable(const bool &editable_)
Definition: Widget.cpp:1230
Zeni::Radio_Button::on_accept
virtual void on_accept()
Called when the cursor is released inside the button.
Definition: Widget.cpp:336
Zeni::Video::pop_world_stack
virtual void pop_world_stack()=0
Pop a model view matrix off the stack.
Zeni::Color::a
float a
Definition: Color.h:69
Zeni::Video::render
virtual void render(const Renderable &renderable)=0
Render a Renderable.
Zeni::Slider::set_end_points
void set_end_points(const Point2f &end_point_a_, const Point2f &end_point_b_)
Definition: Widget.hxx:403
Zeni::Widget::on_key
virtual void on_key(const SDL_Keysym &, const bool &)
Definition: Widget.h:271
Zeni::Slider::get_line_segment
const Collision::Line_Segment & get_line_segment() const
Definition: Widget.hxx:436
count
GLint GLsizei count
Definition: gl2ext.h:1011
Zeni::Text_Box::~Text_Box
~Text_Box()
Definition: Widget.cpp:853
Zeni::Slider_Int::set_value
void set_value(const int &value)
Definition: Widget.hxx:453
Zeni::Widget_Renderer_Text::color
Color color
Definition: Widget.h:347
Zeni::Text_Box::on_accept
virtual void on_accept()
Called when the cursor is released inside the button.
Definition: Widget.cpp:1013
c
const GLfloat * c
Definition: glew.h:14913
v0
GLfloat v0
Definition: glew.h:1834
Zeni::Widget_Renderer_Text::render_to
virtual void render_to(const Widget &widget)
rect must be of type Widget_Rectangle
Definition: Widget.cpp:53
Zeni::Widget_Renderer_Check_Box::Widget_Renderer_Check_Box
Widget_Renderer_Check_Box()
Definition: Widget.hxx:297
Zeni::Widget_Renderer_Slider::Widget_Renderer_Slider
Widget_Renderer_Slider()
Definition: Widget.hxx:309
Zeni::Widget_Renderer_Texture::tex_coord_ll
Point2f tex_coord_ll
Definition: Widget.h:378
Zeni::String::const_iterator
Definition: String.h:89
Zeni::Timer::get_time
Time get_time()
Get the current Time.
Definition: Timer.hxx:69
Zeni::Widget
The Widget base class.
Definition: Widget.h:243
SDLK_LALT
Definition: SDL_keycode.h:275
format
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
Zeni::Check_Box::on_reject
virtual void on_reject()
Called when the cursor is released outside the button.
Definition: Widget.cpp:328
Zeni::Font
Font Abstraction.
Definition: Font.h:70
Zeni::String::begin
iterator begin()
Definition: String.cpp:298
Zeni::Selector::get_options
const Options & get_options() const
Definition: Widget.cpp:598
Zeni::Selector::remove_option
void remove_option(const String &option)
Definition: Widget.cpp:610
Zeni::Line_Segment::b
VERTEX b
Definition: Line_Segment.h:67
Zeni::Widget_Button
A Button Widget.
Definition: Widget.h:454
Zeni::Widget_Renderer_Check_Box::check_color
Color check_color
Definition: Widget.h:413
Zeni::Selector::select_option
void select_option(const String &option)
Definition: Widget.cpp:624
Zeni::Widget_Renderer_Slider::render_to
virtual void render_to(const Widget &widget)
rect must be of type Slider
Definition: Widget.cpp:199
Zeni::Selector::get_selected
String get_selected() const
Definition: Widget.cpp:618
Zeni::Point2f::x
float x
Definition: Coordinate.h:117
Zeni::Text_Box::on_change
virtual void on_change()
Definition: Widget.cpp:1073
Zeni::Widget_Renderer_Slider::get_duplicate
virtual Widget_Renderer_Slider * get_duplicate() const
Definition: Widget.cpp:228
Zeni::Line_Segment::a
VERTEX a
Definition: Line_Segment.h:66
Zeni::Widgets::perform_logic
virtual void perform_logic()
Definition: Widget.cpp:1583
Zeni::Widget_Renderer_Text::Widget_Renderer_Text
Widget_Renderer_Text(const String &font_name_, const String &text_, const Color &color_)
Definition: Widget.hxx:240
Zeni::Widget_Rectangle::get_lower_right
const Point2f & get_lower_right() const
Definition: Widget.hxx:156
Zeni::Slider_Int::Range
std::pair< int, int > Range
Definition: Widget.h:629
Zeni::Widget_Button::on_click
virtual void on_click()
Called when the cursor downclicks the button.
Definition: Widget.h:477
Zeni::Text_Box::get_max_cursor_seek
int get_max_cursor_seek() const
Definition: Widget.cpp:1263
Zeni::Text_Button
A Text Button Widget.
Definition: Widget.h:492
Zeni::Selector::render_impl
virtual void render_impl() const
Definition: Widget.cpp:719
Zeni::Widget_Renderer_Color::render_to
virtual void render_to(const Widget &widget)
rect must be of type Widget_Rectangle
Definition: Widget.cpp:71
Zeni::Video::push_world_stack
virtual void push_world_stack()=0
Push a model view matrix onto the stack.
Zeni::Widget_Rectangle::set_lower_right
virtual void set_lower_right(const Point2f &lower_right_)
Definition: Widget.cpp:49
SDLK_DOWN
Definition: SDL_keycode.h:150
Zeni::Text_Box::get_cursor_pos
int get_cursor_pos() const
Definition: Widget.cpp:1252
Zeni::Widget::render_impl
virtual void render_impl() const
Definition: Widget.cpp:40
Zeni::Slider_Int::get_value
int get_value() const
Definition: Widget.hxx:449
Zeni::Widget_Input_Repeater::render_impl
virtual void render_impl() const
Definition: Widget.cpp:1467
Zeni::Check_Box::is_toggling
const bool & is_toggling() const
Definition: Widget.hxx:352
y
EGLSurface EGLint EGLint y
Definition: eglext.h:293
texture
GLenum GLenum GLuint texture
Definition: gl2ext.h:850
hx
int32_t hx
Definition: e_log.c:102
l
GLdouble l
Definition: glew.h:8383
Zeni::Widget_Renderer_Texture
Definition: Widget.h:362
SDLK_LCTRL
Definition: SDL_keycode.h:273
Zeni::Radio_Button_Set::render_impl
virtual void render_impl() const
Definition: Widget.cpp:362
Zeni::Widget_Renderer_Color::get_duplicate
virtual Widget_Renderer_Color * get_duplicate() const
Definition: Widget.cpp:85
SDLK_UP
Definition: SDL_keycode.h:151
Zeni::Widget_Button::NORMAL
Definition: Widget.h:459
value
EGLSurface EGLint void ** value
Definition: eglext.h:301
Zeni::Widget_Button::get_State
const State & get_State() const
Get the State of the button.
Definition: Widget.hxx:327
Zeni::Video::translate_scene
virtual void translate_scene(const Vector3f &direction)=0
Translate the scene.
Zeni::Widget_Input_Repeater::perform_logic
virtual void perform_logic()
Call this function in your perform_logic function to get this Widget to actually do its job...
Definition: Widget.cpp:1449
Zeni::Vertex2f_Texture
An Abstraction of a Vertex in 2-space, textured.
Definition: Vertex2f.h:115
Zeni::Widget::set_layer
void set_layer(const float &layer_=0.0f)
Definition: Widget.hxx:64
Zeni::Widgets::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:1503
Zeni::Radio_Button_Set::accept
void accept(Radio_Button &radio_button)
Definition: Widget.hxx:368
SDLK_RGUI
Definition: SDL_keycode.h:280
Zeni::Slider
A Slider.
Definition: Widget.h:576
SDLK_RALT
Definition: SDL_keycode.h:279
Zeni::Point2i::x
Sint32 x
Definition: Coordinate.h:94
Zeni::Widget_Render_Function::render_to
virtual void render_to(const Widget &widget)=0
Zeni::Collision::Line_Segment::nearest_point
std::pair< float, float > nearest_point(const Line_Segment &rhs) const
Returns &lt;distance, interpolation value [0.0f, 1.0f]&gt;
Definition: Collision.cpp:387
Zeni::Selector::on_accept
virtual void on_accept(const String &option)
Definition: Widget.cpp:712
Zeni::Slider::get_end_point_a
Point2f get_end_point_a() const
Definition: Widget.hxx:387
Zeni::Widget_Renderer_Texture::tex_coord_lr
Point2f tex_coord_lr
Definition: Widget.h:379
Zeni::Widget_Input_Repeater::on_key
virtual void on_key(const SDL_Keysym &keysym, const bool &down)
on_key input is repeated
Definition: Widget.cpp:1412
Zeni::Text_Box::get_edit_pos
const int & get_edit_pos() const
Definition: Widget.cpp:1248
Zeni::Widgets::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)
Definition: Widget.cpp:1529
Zeni::Widget_Renderer_Wrong_Type
Definition: Widget.h:1064
Zeni::String::size
size_t size() const
Definition: String.cpp:310
Zeni::Widget_Renderer_Slider::line_color
Color line_color
Definition: Widget.h:426
SDL_Keysym::sym
SDL_Keycode sym
Definition: SDL_keyboard.h:50
Zeni::Slider::on_accept
virtual void on_accept()
Definition: Widget.cpp:444
Zeni::Selector::Options
std::vector< String > Options
Definition: Widget.h:715
Zeni::Text_Box::get_text
const String & get_text() const
Definition: Widget.hxx:544
r
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
Zeni::Widget::is_busy
const bool & is_busy() const
Definition: Widget.hxx:48
Zeni::Text_Box::seek_cursor
void seek_cursor(const int &cursor_pos)
Definition: Widget.cpp:1305
Zeni::Selector::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:632
Zeni::Widget_Button::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:232
Zeni::ZENI_LEFT
Definition: Font.h:68
Zeni::Widget::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)=0
Zeni::Widget_Renderer_Text
Definition: Widget.h:336
Zeni::Widget_Renderer_Slider::slider_color
Color slider_color
Definition: Widget.h:427
Zeni::Widget_Button::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)
Definition: Widget.cpp:275
Zeni::Widget_Rectangle::is_inside
bool is_inside(const Point2i &pos) const
Definition: Widget.hxx:177
Zeni::Widget_Button::on_stray
virtual void on_stray()
Called when the cursor is dragged off the button after being clicked.
Definition: Widget.h:479
Zeni::Widget_Renderer_Check_Box
Definition: Widget.h:402
Zeni::get_Fonts
Fonts & get_Fonts()
Get access to the singleton.
Definition: Fonts.cpp:60
Zeni::Check_Box::is_checked
const bool & is_checked() const
Definition: Widget.hxx:350
Zeni::Widget::set_editable
virtual void set_editable(const bool &editable_)
Definition: Widget.cpp:36
Zeni::get_Video
Video & get_Video()
Get access to the singleton.
Definition: Video.cpp:149
Zeni::Widget_Input_Repeater::on_mouse_motion
virtual void on_mouse_motion(const Point2i &pos)
on_mouse_motion input is simply passed through
Definition: Widget.cpp:1440
Zeni::Text_Box::seek
void seek(const int &edit_pos)
Definition: Widget.cpp:1274
min
#define min(x, y)
Definition: os.h:75
Zeni::Font::get_text_height
float get_text_height() const
Get the height of the font. The width is usually half the height, by default.
Definition: Font.hxx:29
Zeni::Selector::~Selector
~Selector()
Definition: Widget.cpp:587
i
int i
Definition: pngrutil.c:1377
Zeni::Widget::set_busy
void set_busy(const bool &busy_)
Definition: Widget.hxx:60
Zeni::Check_Box::on_unstray
virtual void on_unstray()
Called when the cursor is dragged back onto the button without releasing the clicker.
Definition: Widget.cpp:324
Zeni::Widget_Button::on_unstray
virtual void on_unstray()
Called when the cursor is dragged back onto the button without releasing the clicker.
Definition: Widget.h:481
Zeni::Text_Box::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:989
Zeni::Slider::get_slider_radius
const float & get_slider_radius() const
Definition: Widget.hxx:395
Zeni::Renderable::lend_Material
void lend_Material(const Material *const &material)
Set the Material, giving the Renderable no ownership.
Definition: Renderable.cpp:41
max
#define max(x, y)
Definition: os.h:79
Zeni::Slider::is_mouse_wheel_inverted
const bool & is_mouse_wheel_inverted() const
Definition: Widget.hxx:420
Zeni::Text_Box::get_max_seek
int get_max_seek() const
Definition: Widget.cpp:1259
Zeni::Widget_Renderer_Tricolor::get_duplicate
virtual Widget_Renderer_Tricolor * get_duplicate() const
Definition: Widget.cpp:142
SDLK_RIGHT
Definition: SDL_keycode.h:148
Zeni::Widget_Button::on_reject
virtual void on_reject()
Called when the cursor is released outside the button.
Definition: Widget.h:486
Zeni::Text_Box::on_unfocus
virtual void on_unfocus()
Definition: Widget.cpp:1070
Zeni::Text_Box::set_focus
void set_focus(const bool &value)
Definition: Widget.cpp:1334
Zeni::Point2f
A 2D Point represented with floats.
Definition: Coordinate.h:98
m
#define m(i, j)
Zeni::Widget_Renderer_Color
Definition: Widget.h:350
Zeni::Widget_Button::STRAYED
Definition: Widget.h:459
Zeni::Widget_Rectangle::get_upper_left
const Point2f & get_upper_left() const
Definition: Widget.hxx:148
Zeni::Vector3f::normalized
Vector3f normalized() const
Get the normalized vector.
Definition: Vector3f.cpp:58
Zeni::Widget_Renderer_Tricolor::bg_clicked
Color bg_clicked
Definition: Widget.h:395
Zeni::Radio_Button_Set::on_mouse_button
virtual void on_mouse_button(const Point2i &pos, const bool &down, const int &button)
Definition: Widget.cpp:346
Zeni::Widget_Rectangle
Rectangle positioning.
Definition: Widget.h:430
false
#define false
Definition: ftrandom.c:50
Zeni::Color
Color.
Definition: Color.h:41
v2
GLfloat GLfloat GLfloat v2
Definition: glew.h:1842
Zeni::Widget_Renderer_Texture::get_duplicate
virtual Widget_Renderer_Texture * get_duplicate() const
Definition: Widget.cpp:105
Zeni::Font::render_text
virtual void render_text(const String &text, const Point2f &position, const Color &color, const JUSTIFY &justify=ZENI_DEFAULT_JUSTIFY) const =0
Render text at screen position (x, y), with justification JUSTIFY.
size_t
unsigned int size_t
Definition: SDL_config_windows.h:67
Zeni::Time
A Snapshot of the Timer.
Definition: Timer.h:63
size
GLsizei size
Definition: gl2ext.h:1467
Zeni::Widget_Renderer_Text::font_name
String font_name
Definition: Widget.h:345
m
const GLdouble * m
Definition: glew.h:8385
Zeni::Point2i
A 2D Point represented with integers.
Definition: Coordinate.h:85
ZENI_TEXT_CURSOR_WIDTH
#define ZENI_TEXT_CURSOR_WIDTH
Definition: Define.h:69