You want real tooltips too? You got 'em. See the ChangeLog for how to use.

Works with both xforms 0.88 and 0.89.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3489 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2002-02-05 17:25:16 +00:00
parent 828fe3bc12
commit a1b36fec35
3 changed files with 159 additions and 23 deletions

View File

@ -1,3 +1,10 @@
2002-02-05 Angus Leeming <a.leeming@ic.ac.uk>
* FormBase.[Ch]: You want tooltips too? You got 'em. Verified as
working with both xforms 0.88 and 0.89. Use by invoking
setTooltipHandler(ob) and by providing a method getTooltip(ob) in this
derived class to provide the required string.
2002-02-05 Angus Leeming <a.leeming@ic.ac.uk> 2002-02-05 Angus Leeming <a.leeming@ic.ac.uk>
* FormBase.[Ch]: make it really easy to set up and use a prehandler * FormBase.[Ch]: make it really easy to set up and use a prehandler

View File

@ -21,6 +21,34 @@
#include "xformsBC.h" #include "xformsBC.h"
#include "support/LAssert.h" #include "support/LAssert.h"
#if FL_REVISION < 89
namespace {
int TooltipHandler(FL_OBJECT *ob, int event);
void TooltipTimerCB(FL_OBJECT * timer, long data);
}
extern "C" {
static int C_FormBaseTooltipHandler(FL_OBJECT * ob, int event,
FL_Coord, FL_Coord, int, void *)
{
return TooltipHandler(ob, event);
}
static void C_FormBaseTooltipTimerCB(FL_OBJECT * ob, long data)
{
TooltipTimerCB(ob, data);
}
}
#endif // FL_REVISION < 89
extern "C" { extern "C" {
// Callback function invoked by xforms when the dialog is closed by the // Callback function invoked by xforms when the dialog is closed by the
@ -39,7 +67,11 @@ FormBase::FormBase(ControlButtons & c, string const & t, bool allowResize)
: ViewBC<xformsBC>(c), minw_(0), minh_(0), allow_resize_(allowResize), : ViewBC<xformsBC>(c), minw_(0), minh_(0), allow_resize_(allowResize),
title_(t), warning_posted_(false) title_(t), warning_posted_(false)
{} {
#if FL_REVISION < 89
tooltip_timer_ = 0;
#endif
}
void FormBase::redraw() void FormBase::redraw()
@ -144,6 +176,28 @@ void FormBase::FeedbackCB(FL_OBJECT * ob, int event)
} }
void FormBase::setTooltipHandler(FL_OBJECT * ob)
{
lyx::Assert(ob);
#if FL_REVISION < 89
if (!tooltip_timer_) {
fl_addto_form(form());
tooltip_timer_ = fl_add_timer(FL_HIDDEN_TIMER, 0, 0, 0, 0, "");
fl_end_form();
}
fl_set_object_posthandler(ob, C_FormBaseTooltipHandler);
ob->u_cdata = reinterpret_cast<char *>(tooltip_timer_);
#else
string const help(getTooltip(ob));
if (!help.empty())
fl_set_object_helper(ob, help.c_str());
#endif // FL_REVISION < 89
}
void FormBase::setPrehandler(FL_OBJECT * ob) void FormBase::setPrehandler(FL_OBJECT * ob)
{ {
lyx::Assert(ob); lyx::Assert(ob);
@ -157,6 +211,16 @@ void FormBase::setWarningPosted(bool warning)
} }
#if FL_REVISION < 89
string const FormBase::getTooltipCB(FL_OBJECT * ob)
{
return getTooltip(ob);
}
#endif // FL_REVISION < 89
namespace { namespace {
FormBase * GetForm(FL_OBJECT * ob) FormBase * GetForm(FL_OBJECT * ob)
@ -171,16 +235,6 @@ FormBase * GetForm(FL_OBJECT * ob)
extern "C" { extern "C" {
static int C_FormBaseWMHideCB(FL_FORM * form, void *)
{
// Close the dialog cleanly, even if the WM is used to do so.
lyx::Assert(form && form->u_vdata);
FormBase * pre = static_cast<FormBase *>(form->u_vdata);
pre->CancelButton();
return FL_CANCEL;
}
void C_FormBaseApplyCB(FL_OBJECT * ob, long) void C_FormBaseApplyCB(FL_OBJECT * ob, long)
{ {
GetForm(ob)->ApplyButton(); GetForm(ob)->ApplyButton();
@ -212,6 +266,16 @@ void C_FormBaseInputCB(FL_OBJECT * ob, long d)
} }
static int C_FormBaseWMHideCB(FL_FORM * form, void *)
{
// Close the dialog cleanly, even if the WM is used to do so.
lyx::Assert(form && form->u_vdata);
FormBase * pre = static_cast<FormBase *>(form->u_vdata);
pre->CancelButton();
return FL_CANCEL;
}
static int C_FormBasePrehandler(FL_OBJECT * ob, int event, static int C_FormBasePrehandler(FL_OBJECT * ob, int event,
FL_Coord, FL_Coord, int key, void *) FL_Coord, FL_Coord, int key, void *)
{ {
@ -240,5 +304,50 @@ static int C_FormBasePrehandler(FL_OBJECT * ob, int event,
return 0; return 0;
} }
} // extern "C" } // extern "C"
#if FL_REVISION < 89
namespace {
void TooltipTimerCB(FL_OBJECT * timer, long data)
{
FL_OBJECT * ob = reinterpret_cast<FL_OBJECT*>(data);
lyx::Assert(ob && ob->form);
string const help = GetForm(timer)->getTooltipCB(ob);
if (help.empty())
return;
fl_show_oneliner(help.c_str(),
ob->form->x + ob->x,
ob->form->y + ob->y + ob->h);
}
// post_handler for bubble-help (Matthias)
int TooltipHandler(FL_OBJECT *ob, int event)
{
lyx::Assert(ob);
FL_OBJECT * timer = reinterpret_cast<FL_OBJECT *>(ob->u_cdata);
lyx::Assert(timer);
// We do not test for empty help here, since this can never happen
if (event == FL_ENTER){
fl_set_object_callback(timer,
C_FormBaseTooltipTimerCB,
reinterpret_cast<long>(ob));
fl_set_timer(timer, 1);
}
else if (event != FL_MOTION){
fl_set_timer(timer, 0);
fl_hide_oneliner();
}
return 0;
}
} // namespace anon
#endif // FL_REVISION < 89

View File

@ -27,6 +27,7 @@
class xformsBC; class xformsBC;
/** This class is an XForms GUI base class. /** This class is an XForms GUI base class.
*/ */
class FormBase : public ViewBC<xformsBC> class FormBase : public ViewBC<xformsBC>
@ -37,12 +38,17 @@ public:
/// ///
virtual ~FormBase() {} virtual ~FormBase() {}
/// input callback function /** input callback function.
Invoked only by C_FormBaseInputCB and by C_FormBasePrehandler */
void InputCB(FL_OBJECT *, long); void InputCB(FL_OBJECT *, long);
/// feedback callback function, invoked only by C_FormBasePrehandler
/// feedback callback function
void FeedbackCB(FL_OBJECT *, int event); void FeedbackCB(FL_OBJECT *, int event);
#if FL_REVISION < 89
/// invoked only by TooltipTimerCB
string const getTooltipCB(FL_OBJECT *);
#endif
protected: protected:
/// Build the dialog /// Build the dialog
virtual void build() = 0; virtual void build() = 0;
@ -50,19 +56,21 @@ protected:
void hide(); void hide();
/// Create the dialog if necessary, update it and display it. /// Create the dialog if necessary, update it and display it.
void show(); void show();
/** Set a prehandler for ob to:
1. display feedback as the mouse moves over it /// Prepare the way to produce a tooltip when the mouse is over ob.
void setTooltipHandler(FL_OBJECT * ob);
/** Prepare the way to:
1. display feedback as the mouse moves over ob. This feedback will
typically be rather more verbose than just a tooltip.
2. activate the button controller after a paste with the middle 2. activate the button controller after a paste with the middle
mouse button */ mouse button */
void setPrehandler(FL_OBJECT * ob); void setPrehandler(FL_OBJECT * ob);
/// post feedback for ob. Defaults to nothing
virtual void feedback(FL_OBJECT * /* ob */) {}
/// clear the feedback message
virtual void clear_feedback() {}
/** Flag that the message is a warning and should not be removed /** Flag that the message is a warning and should not be removed
when the mouse is no longer over the object */ when the mouse is no longer over the object.
Used in conjunction with setPrehandler(ob) and with feedback(ob),
clear_feedback(). */
void setWarningPosted(bool); void setWarningPosted(bool);
private: private:
@ -75,6 +83,14 @@ private:
that the xform colors have been re-mapped). */ that the xform colors have been re-mapped). */
virtual void redraw(); virtual void redraw();
///
virtual string const getTooltip(FL_OBJECT *) { return string(); }
/// post feedback for ob. Defaults to nothing
virtual void feedback(FL_OBJECT * /* ob */) {}
/// clear the feedback message
virtual void clear_feedback() {}
/// The dialog's minimum allowable dimensions. /// The dialog's minimum allowable dimensions.
int minw_; int minw_;
/// ///
@ -86,6 +102,10 @@ private:
/** Variable used to decide whether to remove the existing feedback /** Variable used to decide whether to remove the existing feedback
message or not (if it is infact a warning) */ message or not (if it is infact a warning) */
bool warning_posted_; bool warning_posted_;
/// Enables tooltips for crappy GUI libraries...
#if FL_REVISION < 89
FL_OBJECT * tooltip_timer_;
#endif
}; };