3 * Copyright 2002 the LyX Team
4 * Read the file COPYING
6 * \author Angus Leeming, a.leeming@ic.ac.uk
11 * Tooltips for xforms. xforms 0.89 supports them directly, but 0.88 needs
12 * a bit of jiggery pokery. This class wraps it all up in a neat interface.
13 * Based on code originally in Toolbar_pimpl.C that appears to have been
14 * written by Matthias Ettrich and Jean-Marc Lasgouttes.
20 #pragma implementation
25 #include "xforms_helpers.h" // formatted
27 #include "support/lstrings.h"
28 #include "support/LAssert.h"
33 bool Tooltips::enabled_ = false;
35 SigC::Signal0<void> Tooltips::tooltipsToggled;
42 static bool first = true;
45 Dialogs::toggleTooltips.connect(slot(&Tooltips::toggleEnabled));
47 tooltipsToggled.connect(slot(this, &Tooltips::toggleTooltips));
51 void Tooltips::toggleEnabled()
58 void Tooltips::toggleTooltips()
60 if (tooltipsMap.empty())
61 // There are no objects with tooltips in this dialog, so
62 // just go away. Don't change the cursor to a question mark.
65 TooltipsMap::iterator it = tooltipsMap.begin();
66 TooltipsMap::iterator end = tooltipsMap.end();
67 for (; it != end; ++it) {
68 FL_OBJECT * const ob = it->first;
69 char const * const c_str = enabled_ ? it->second.c_str() : 0;
70 fl_set_object_helper(ob, c_str);
73 FL_OBJECT * const ob = tooltipsMap.begin()->first;
75 // The dialog is not visible
76 if (!ob->form->window)
79 // Set the cursor to a question mark or back to the default.
80 int const cursor = enabled_ ? XC_question_arrow : FL_DEFAULT_CURSOR;
81 fl_set_cursor(ob->form->window, cursor);
85 void Tooltips::initTooltip(FL_OBJECT * ob, string const & tip)
87 lyx::Assert(ob && ob->form);
90 TooltipsMap::const_iterator it = tooltipsMap.find(ob);
91 if (it != tooltipsMap.end())
94 string const str = strip(frontStrip(tip));
98 // Store the tooltip string
99 tooltipsMap[ob] = formatted(_(str), 400);
101 // Set the initial state of the tooltips
102 char const * const c_str = enabled_ ? str.c_str() : 0;
103 fl_set_object_helper(ob, c_str);
107 #else // if FL_REVISION < 89
111 int TooltipHandler(FL_OBJECT *ob, int event);
113 void TooltipTimerCB(FL_OBJECT * timer, long data);
119 static int C_TooltipHandler(FL_OBJECT * ob, int event,
120 FL_Coord, FL_Coord, int, void *)
122 return TooltipHandler(ob, event);
126 static void C_TooltipTimerCB(FL_OBJECT * ob, long data)
128 TooltipTimerCB(ob, data);
137 static bool first = true;
140 Dialogs::toggleTooltips.connect(slot(&Tooltips::toggleEnabled));
142 tooltipsToggled.connect(slot(this, &Tooltips::toggleTooltips));
146 void Tooltips::toggleEnabled()
148 enabled_ = !enabled_;
153 void Tooltips::toggleTooltips()
155 if (tooltipsMap.empty())
156 // There are no objects with tooltips in this dialog, so
157 // just go away. Don't change the cursor to a question mark.
160 FL_OBJECT * const ob = tooltipsMap.begin()->first;
162 // The dialog is not visible
163 if (!ob->form->window)
166 // Set the cursor to a question mark or back to the default.
167 int const cursor = enabled_ ? XC_question_arrow : FL_DEFAULT_CURSOR;
168 fl_set_cursor(ob->form->window, cursor);
172 void Tooltips::initTooltip(FL_OBJECT * ob, string const & tip)
174 lyx::Assert(ob && ob->form);
177 TooltipsMap::const_iterator it = tooltipsMap.find(ob);
178 if (it != tooltipsMap.end())
181 string const str = strip(frontStrip(tip));
185 // Store the tooltip string
186 tooltipsMap[ob] = formatted(_(str), 400);
188 if (!tooltip_timer_) {
189 if (fl_current_form && ob->form != fl_current_form)
192 bool const open_form = !fl_current_form;
194 fl_addto_form(ob->form);
196 tooltip_timer_ = fl_add_timer(FL_HIDDEN_TIMER, 0, 0, 0, 0, "");
202 fl_set_object_posthandler(ob, C_TooltipHandler);
203 ob->u_cdata = reinterpret_cast<char *>(tooltip_timer_);
204 tooltip_timer_->u_vdata = this;
208 string const Tooltips::getTooltip(FL_OBJECT * ob) const
210 TooltipsMap::const_iterator it = tooltipsMap.find(ob);
211 if (it == tooltipsMap.end())
219 void TooltipTimerCB(FL_OBJECT * timer, long data)
221 FL_OBJECT * ob = reinterpret_cast<FL_OBJECT*>(data);
222 lyx::Assert(ob && ob->form && timer && timer->u_vdata);
223 FL_FORM * form = ob->form;
224 Tooltips * tooltip = static_cast<Tooltips *>(timer->u_vdata);
226 string const help = tooltip->getTooltip(ob);
230 fl_show_oneliner(help.c_str(),
231 form->x + ob->x, form->y + ob->y + ob->h);
235 // post_handler for tooltip help
236 int TooltipHandler(FL_OBJECT * ob, int event)
238 if (!Tooltips::enabled())
242 FL_OBJECT * timer = reinterpret_cast<FL_OBJECT *>(ob->u_cdata);
245 // We do not test for empty help here, since this can never happen
246 if (event == FL_ENTER) {
247 fl_set_object_callback(timer,
249 reinterpret_cast<long>(ob));
250 fl_set_timer(timer, 1);
252 else if (event != FL_MOTION) {
253 fl_set_timer(timer, 0);
261 #endif // FL_REVISION >= 89