]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/Tooltips.C
Really dull and boring header shit
[lyx.git] / src / frontends / xforms / Tooltips.C
1 /**
2  * \file Tooltips.C
3  * Read the file COPYING
4  *
5  * \author Angus Leeming 
6  *
7  * Full author contact details are available in file CREDITS
8  */
9
10 /* Tooltips for xforms. xforms 0.89 supports them directly, but 0.88 needs
11  * a bit of jiggery pokery. This class wraps it all up in a neat interface.
12  * Based on code originally in Toolbar_pimpl.C that appears to have been
13  * written by Matthias Ettrich and Jean-Marc Lasgouttes.
14  */
15
16 #include <config.h>
17
18 #ifdef __GNUG__
19 #pragma implementation
20 #endif
21
22 #include "Tooltips.h"
23 #include "xforms_helpers.h" // formatted
24 #include "gettext.h"
25 #include "support/lstrings.h"
26 #include "support/LAssert.h"
27 #include FORMS_H_LOCATION
28
29 #include <boost/bind.hpp>
30
31 bool Tooltips::enabled_ = true;
32
33 boost::signal0<void> Tooltips::toggled;
34
35
36 #if FL_VERSION > 0 || FL_REVISION >= 89
37
38 Tooltips::Tooltips()
39 {
40         toggled.connect(boost::bind(&Tooltips::set, this));
41 }
42
43
44 void Tooltips::toggleEnabled()
45 {
46         enabled_ = !enabled_;
47         toggled();
48 }
49
50
51 void Tooltips::set()
52 {
53         if (tooltipsMap.empty())
54                 // There are no objects with tooltips in this dialog, so
55                 // just go away. Don't change the cursor to a question mark.
56                 return;
57
58         TooltipsMap::iterator it  = tooltipsMap.begin();
59         TooltipsMap::iterator end = tooltipsMap.end();
60         for (; it != end; ++it) {
61                 FL_OBJECT * const ob = it->first;
62                 char const * const c_str = enabled_ ? it->second.c_str() : 0;
63                 fl_set_object_helper(ob, c_str);
64         }
65 }
66
67
68 void Tooltips::init(FL_OBJECT * ob, string const & tip)
69 {
70         lyx::Assert(ob && ob->form);
71
72         // Paranoia check!
73         TooltipsMap::const_iterator it = tooltipsMap.find(ob);
74         if (it != tooltipsMap.end())
75                 return;
76
77         string const str = trim(tip);
78         if (str.empty())
79                 return;
80
81         // Store the tooltip string
82         tooltipsMap[ob] = formatted(str, 400);
83 }
84
85
86 #else // if FL_REVISION < 89
87
88 namespace {
89
90 int TooltipHandler(FL_OBJECT *ob, int event);
91
92 void TooltipTimerCB(FL_OBJECT * timer, long data);
93
94 }
95
96 extern "C" {
97
98 static int C_TooltipHandler(FL_OBJECT * ob, int event,
99                                     FL_Coord, FL_Coord, int, void *)
100 {
101         return TooltipHandler(ob, event);
102 }
103
104
105 static void C_TooltipTimerCB(FL_OBJECT * ob, long data)
106 {
107         TooltipTimerCB(ob, data);
108 }
109
110 }
111
112
113 Tooltips::Tooltips()
114         : tooltip_timer_(0)
115 {
116         toggled.connect(boost::bind(&Tooltips::set, this));
117 }
118
119
120 void Tooltips::toggleEnabled()
121 {
122         enabled_ = !enabled_;
123         toggled();
124 }
125
126
127 void Tooltips::set()
128 {}
129
130
131 void Tooltips::init(FL_OBJECT * ob, string const & tip)
132 {
133         lyx::Assert(ob && ob->form);
134
135         // Paranoia check!
136         TooltipsMap::const_iterator it = tooltipsMap.find(ob);
137         if (it != tooltipsMap.end())
138                 return;
139
140         string const str = trim(tip);
141         if (str.empty())
142                 return;
143
144         // Store the tooltip string
145         tooltipsMap[ob] = formatted(str, 400);
146
147         if (!tooltip_timer_) {
148                 if (fl_current_form && ob->form != fl_current_form)
149                         fl_end_form();
150
151                 bool const open_form = !fl_current_form;
152                 if (open_form)
153                         fl_addto_form(ob->form);
154
155                 tooltip_timer_ = fl_add_timer(FL_HIDDEN_TIMER, 0, 0, 0, 0, "");
156
157                 if (open_form)
158                         fl_end_form();
159         }
160
161         fl_set_object_posthandler(ob, C_TooltipHandler);
162         ob->u_cdata = reinterpret_cast<char *>(tooltip_timer_);
163         tooltip_timer_->u_vdata = this;
164 }
165
166
167 string const Tooltips::get(FL_OBJECT * ob) const
168 {
169         TooltipsMap::const_iterator it = tooltipsMap.find(ob);
170         if (it == tooltipsMap.end())
171                 return string();
172         return it->second;
173 }
174
175
176 namespace {
177
178 void TooltipTimerCB(FL_OBJECT * timer, long data)
179 {
180         FL_OBJECT * ob = reinterpret_cast<FL_OBJECT*>(data);
181         lyx::Assert(ob && ob->form && timer && timer->u_vdata);
182         FL_FORM * form = ob->form;
183         Tooltips * tooltip = static_cast<Tooltips *>(timer->u_vdata);
184
185         string const help = tooltip->get(ob);
186         if (help.empty())
187                 return;
188
189         fl_show_oneliner(help.c_str(),
190                          form->x + ob->x, form->y + ob->y + ob->h);
191 }
192
193
194 // post_handler for tooltip help
195 int TooltipHandler(FL_OBJECT * ob, int event)
196 {
197         if (!Tooltips::enabled())
198                 return 0;
199
200         lyx::Assert(ob);
201         FL_OBJECT * timer = reinterpret_cast<FL_OBJECT *>(ob->u_cdata);
202         lyx::Assert(timer);
203
204         // We do not test for empty help here, since this can never happen
205         if (event == FL_ENTER) {
206                 fl_set_object_callback(timer,
207                                        C_TooltipTimerCB,
208                                        reinterpret_cast<long>(ob));
209                 fl_set_timer(timer, 1);
210         }
211         else if (event != FL_MOTION) {
212                 fl_set_timer(timer, 0);
213                 fl_hide_oneliner();
214         }
215         return 0;
216 }
217
218 } // namespace anon
219
220 #endif // FL_REVISION >= 89