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