3 * Copyright 2002 the LyX Team
4 * Read the file COPYING
6 * \author Angus Leeming, a.leeming@ic.ac.uk
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.
18 #pragma implementation
23 #include "xforms_helpers.h" // formatted
25 #include "support/lstrings.h"
26 #include "support/LAssert.h"
31 bool Tooltips::enabled_ = false;
33 SigC::Signal0<void> Tooltips::toggled;
40 static bool first = true;
43 Dialogs::toggleTooltips.connect(slot(&Tooltips::toggleEnabled));
45 toggled.connect(slot(this, &Tooltips::set));
49 void Tooltips::toggleEnabled()
58 if (tooltipsMap.empty())
59 // There are no objects with tooltips in this dialog, so
60 // just go away. Don't change the cursor to a question mark.
63 TooltipsMap::iterator it = tooltipsMap.begin();
64 TooltipsMap::iterator end = tooltipsMap.end();
65 for (; it != end; ++it) {
66 FL_OBJECT * const ob = it->first;
67 char const * const c_str = enabled_ ? it->second.c_str() : 0;
68 fl_set_object_helper(ob, c_str);
71 FL_OBJECT * const ob = tooltipsMap.begin()->first;
73 // The dialog is not visible
74 if (!ob->form->window)
77 // Set the cursor to a question mark or back to the default.
78 int const cursor = enabled_ ? XC_question_arrow : FL_DEFAULT_CURSOR;
79 fl_set_cursor(ob->form->window, cursor);
83 void Tooltips::init(FL_OBJECT * ob, string const & tip)
85 lyx::Assert(ob && ob->form);
88 TooltipsMap::const_iterator it = tooltipsMap.find(ob);
89 if (it != tooltipsMap.end())
92 string const str = strip(frontStrip(tip));
96 // Store the tooltip string
97 tooltipsMap[ob] = formatted(_(str), 400);
101 #else // if FL_REVISION < 89
105 int TooltipHandler(FL_OBJECT *ob, int event);
107 void TooltipTimerCB(FL_OBJECT * timer, long data);
113 static int C_TooltipHandler(FL_OBJECT * ob, int event,
114 FL_Coord, FL_Coord, int, void *)
116 return TooltipHandler(ob, event);
120 static void C_TooltipTimerCB(FL_OBJECT * ob, long data)
122 TooltipTimerCB(ob, data);
131 static bool first = true;
134 Dialogs::toggleTooltips.connect(slot(&Tooltips::toggleEnabled));
136 toggled.connect(slot(this, &Tooltips::set));
140 void Tooltips::toggleEnabled()
142 enabled_ = !enabled_;
149 if (tooltipsMap.empty())
150 // There are no objects with tooltips in this dialog, so
151 // just go away. Don't change the cursor to a question mark.
154 FL_OBJECT * const ob = tooltipsMap.begin()->first;
156 // The dialog is not visible
157 if (!ob->form->window)
160 // Set the cursor to a question mark or back to the default.
161 int const cursor = enabled_ ? XC_question_arrow : FL_DEFAULT_CURSOR;
162 fl_set_cursor(ob->form->window, cursor);
166 void Tooltips::init(FL_OBJECT * ob, string const & tip)
168 lyx::Assert(ob && ob->form);
171 TooltipsMap::const_iterator it = tooltipsMap.find(ob);
172 if (it != tooltipsMap.end())
175 string const str = strip(frontStrip(tip));
179 // Store the tooltip string
180 tooltipsMap[ob] = formatted(_(str), 400);
182 if (!tooltip_timer_) {
183 if (fl_current_form && ob->form != fl_current_form)
186 bool const open_form = !fl_current_form;
188 fl_addto_form(ob->form);
190 tooltip_timer_ = fl_add_timer(FL_HIDDEN_TIMER, 0, 0, 0, 0, "");
196 fl_set_object_posthandler(ob, C_TooltipHandler);
197 ob->u_cdata = reinterpret_cast<char *>(tooltip_timer_);
198 tooltip_timer_->u_vdata = this;
202 string const Tooltips::get(FL_OBJECT * ob) const
204 TooltipsMap::const_iterator it = tooltipsMap.find(ob);
205 if (it == tooltipsMap.end())
213 void TooltipTimerCB(FL_OBJECT * timer, long data)
215 FL_OBJECT * ob = reinterpret_cast<FL_OBJECT*>(data);
216 lyx::Assert(ob && ob->form && timer && timer->u_vdata);
217 FL_FORM * form = ob->form;
218 Tooltips * tooltip = static_cast<Tooltips *>(timer->u_vdata);
220 string const help = tooltip->get(ob);
224 fl_show_oneliner(help.c_str(),
225 form->x + ob->x, form->y + ob->y + ob->h);
229 // post_handler for tooltip help
230 int TooltipHandler(FL_OBJECT * ob, int event)
232 if (!Tooltips::enabled())
236 FL_OBJECT * timer = reinterpret_cast<FL_OBJECT *>(ob->u_cdata);
239 // We do not test for empty help here, since this can never happen
240 if (event == FL_ENTER) {
241 fl_set_object_callback(timer,
243 reinterpret_cast<long>(ob));
244 fl_set_timer(timer, 1);
246 else if (event != FL_MOTION) {
247 fl_set_timer(timer, 0);
255 #endif // FL_REVISION >= 89