]> git.tdb.fi Git - libs/gltk.git/blob - source/root.cpp
Allow custom tooltips at empty areas of a Root
[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         Widget(r),
20         Panel(r),
21         window(w),
22         lbl_tooltip(0),
23         tooltip_target(0)
24 {
25         set_geometry(Geometry(0, 0, window.get_width(), window.get_height()));
26
27         update_style();
28
29         window.signal_button_press.connect(sigc::mem_fun(this, &Root::button_press_event));
30         window.signal_button_release.connect(sigc::mem_fun(this, &Root::button_release_event));
31         window.signal_pointer_motion.connect(sigc::mem_fun(this, &Root::pointer_motion_event));
32         window.signal_key_press.connect(sigc::mem_fun(this, &Root::key_press_event));
33         window.signal_key_release.connect(sigc::mem_fun(this, &Root::key_release_event));
34 }
35
36 void Root::tick()
37 {
38         if(tooltip_timeout && Time::now()>tooltip_timeout)
39         {
40                 std::string tip;
41                 if(Widget *wdg=get_descendant_at(pointer_x, pointer_y))
42                 {
43                         tip=wdg->get_tooltip();
44                         tooltip_target=wdg;
45                 }
46                 else
47                 {
48                         tip=signal_tooltip.emit(pointer_x, pointer_y);
49                         tooltip_target=this;
50                 }
51
52                 if(!tip.empty())
53                 {
54                         if(!lbl_tooltip)
55                         {
56                                 lbl_tooltip=new Label(res);
57                                 add(*lbl_tooltip);
58                                 lbl_tooltip->set_style("tooltip");
59                         }
60
61                         lbl_tooltip->set_text(tip);
62                         lbl_tooltip->autosize();
63                         const Geometry &tip_geom=lbl_tooltip->get_geometry();
64                         unsigned x=pointer_x+10;
65                         unsigned y=pointer_y-10-lbl_tooltip->get_geometry().h;
66                         if(x+tip_geom.w>geom.w)
67                         {
68                                 if(pointer_x>static_cast<int>(tip_geom.w+2))
69                                         x=pointer_x-2-tip_geom.w;
70                                 else
71                                         x=geom.w-tip_geom.w;
72                         }
73                         lbl_tooltip->set_position(x, y);
74                         raise(*lbl_tooltip);
75                         lbl_tooltip->set_visible(true);
76                 }
77
78                 tooltip_timeout=Time::TimeStamp();
79         }
80 }
81
82 void Root::button_press_event(int x, int y, unsigned btn, unsigned)
83 {
84         if(visible)
85         {
86                 translate_coords(x, y);
87                 button_press(x, y, btn);
88         }
89 }
90
91 void Root::button_release_event(int x, int y, unsigned btn, unsigned)
92 {
93         if(visible)
94         {
95                 translate_coords(x, y);
96                 button_release(x, y, btn);
97         }
98 }
99
100 void Root::pointer_motion_event(int x, int y)
101 {
102         if(visible)
103         {
104                 translate_coords(x, y);
105                 pointer_motion(x, y);
106
107                 if(!tooltip_target)
108                 {
109                         pointer_x=x;
110                         pointer_y=y;
111                         tooltip_timeout=Time::now()+700*Time::msec;
112                 }
113                 else if(get_descendant_at(x, y)!=tooltip_target)
114                 {
115                         if(lbl_tooltip)
116                                 lbl_tooltip->set_visible(false);
117                         tooltip_target=0;
118                 }
119         }
120 }
121
122 void Root::key_press_event(unsigned key, unsigned mod, wchar_t ch)
123 {
124         if(visible)
125                 key_press(Input::key_from_sys(key), mod, ch);
126 }
127
128 void Root::key_release_event(unsigned key, unsigned mod)
129 {
130         if(visible)
131                 key_release(Input::key_from_sys(key), mod);
132 }
133
134 void Root::translate_coords(int &x, int &y)
135 {
136         x=x*geom.w/window.get_width();
137         y=geom.h-1-y*geom.h/window.get_height();
138 }
139
140 } // namespace GLtk
141 } // namespace Msp