]> git.tdb.fi Git - libs/gltk.git/blob - source/root.cpp
Strip copyright messages and id tags from individual files
[libs/gltk.git] / source / root.cpp
1 #include <msp/gl/blend.h>
2 #include <msp/input/keys.h>
3 #include <msp/time/units.h>
4 #include <msp/time/utils.h>
5 #include "label.h"
6 #include "style.h"
7 #include "root.h"
8
9 namespace Msp {
10 namespace GLtk {
11
12 Root::Root(const Resources &r, Graphics::Window &w):
13         resources(r),
14         window(w),
15         lbl_tooltip(0),
16         tooltip_target(0)
17 {
18         set_geometry(Geometry(0, 0, window.get_width(), window.get_height()));
19
20         update_style();
21
22         window.signal_button_press.connect(sigc::mem_fun(this, &Root::button_press_event));
23         window.signal_button_release.connect(sigc::mem_fun(this, &Root::button_release_event));
24         window.signal_pointer_motion.connect(sigc::mem_fun(this, &Root::pointer_motion_event));
25         window.signal_key_press.connect(sigc::mem_fun(this, &Root::key_press_event));
26         window.signal_key_release.connect(sigc::mem_fun(this, &Root::key_release_event));
27 }
28
29 void Root::tick()
30 {
31         if(tooltip_timeout && Time::now()>tooltip_timeout)
32         {
33                 std::string tip;
34                 if(Widget *wdg = get_descendant_at(pointer_x, pointer_y))
35                 {
36                         tip = wdg->get_tooltip();
37                         tooltip_target = wdg;
38                 }
39                 else
40                 {
41                         tip = signal_tooltip.emit(pointer_x, pointer_y);
42                         tooltip_target = this;
43                 }
44
45                 if(!tip.empty())
46                 {
47                         if(!lbl_tooltip)
48                         {
49                                 lbl_tooltip = new Label;
50                                 add(*lbl_tooltip);
51                                 lbl_tooltip->set_style("tooltip");
52                         }
53
54                         lbl_tooltip->set_text(tip);
55                         lbl_tooltip->autosize();
56                         const Geometry &tip_geom = lbl_tooltip->get_geometry();
57                         unsigned x = pointer_x+10;
58                         unsigned y = pointer_y-10-lbl_tooltip->get_geometry().h;
59                         if(x+tip_geom.w>geom.w)
60                         {
61                                 if(pointer_x>static_cast<int>(tip_geom.w+2))
62                                         x = pointer_x-2-tip_geom.w;
63                                 else
64                                         x = geom.w-tip_geom.w;
65                         }
66                         lbl_tooltip->set_position(x, y);
67                         raise(*lbl_tooltip);
68                         lbl_tooltip->set_visible(true);
69                 }
70
71                 tooltip_timeout = Time::TimeStamp();
72         }
73 }
74
75 void Root::render() const
76 {
77         GL::MatrixStack::projection() = GL::Matrix::ortho_bottomleft(geom.w, geom.h);
78         GL::MatrixStack::modelview() = GL::Matrix();
79         GL::Bind bind_blend(GL::Blend::alpha());
80
81         Widget::render();
82 }
83
84 void Root::button_press_event(int x, int y, unsigned btn, unsigned mod)
85 {
86         if(visible)
87         {
88                 Widget *old_focus = pointer_focus;
89
90                 translate_coords(x, y);
91                 button_press(x, y, btn);
92
93                 if(!pointer_focus && !old_focus)
94                         signal_button_press.emit(x, geom.h-1-y, btn, mod);
95         }
96 }
97
98 void Root::button_release_event(int x, int y, unsigned btn, unsigned mod)
99 {
100         if(visible)
101         {
102                 Widget *old_focus = pointer_focus;
103
104                 translate_coords(x, y);
105                 button_release(x, y, btn);
106
107                 if(!pointer_focus && !old_focus)
108                         signal_button_release.emit(x, geom.h-1-y, btn, mod);
109         }
110 }
111
112 void Root::pointer_motion_event(int x, int y)
113 {
114         if(visible)
115         {
116                 translate_coords(x, y);
117                 pointer_motion(x, y);
118
119                 if(!tooltip_target)
120                 {
121                         pointer_x = x;
122                         pointer_y = y;
123                         tooltip_timeout = Time::now()+700*Time::msec;
124                 }
125                 else if(get_descendant_at(x, y)!=tooltip_target)
126                 {
127                         if(lbl_tooltip)
128                                 lbl_tooltip->set_visible(false);
129                         tooltip_target = 0;
130                 }
131
132                 if(!pointer_focus)
133                         signal_pointer_motion.emit(x, geom.h-1-y);
134         }
135 }
136
137 void Root::key_press_event(unsigned key, unsigned mod, wchar_t ch)
138 {
139         if(visible)
140         {
141                 Widget *old_focus = input_focus;
142
143                 key_press(Input::key_from_sys(key), mod, ch);
144
145                 if(!input_focus && !old_focus)
146                         signal_key_press.emit(key, mod, ch);
147         }
148 }
149
150 void Root::key_release_event(unsigned key, unsigned mod)
151 {
152         if(visible)
153         {
154                 Widget *old_focus = input_focus;
155
156                 key_release(Input::key_from_sys(key), mod);
157
158                 if(!input_focus && !old_focus)
159                         signal_key_release.emit(key, mod);
160         }
161 }
162
163 void Root::translate_coords(int &x, int &y)
164 {
165         x = x*geom.w/window.get_width();
166         y = geom.h-1-y*geom.h/window.get_height();
167 }
168
169 } // namespace GLtk
170 } // namespace Msp