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