Adds a new event FL_TOOLTIP_EVENT...
... and Fl_Tootip::override_text() to allow users to dynamically generate tooltips.
This commit is contained in:
parent
cb86a37676
commit
b7189192e2
@ -414,7 +414,11 @@ enum Fl_Event { // events
|
||||
/** A zoom event (ctrl/+/-/0/ or cmd/+/-/0/) was processed.
|
||||
Use Fl::add_handler() to be notified of this event.
|
||||
*/
|
||||
FL_ZOOM_EVENT = 27
|
||||
FL_ZOOM_EVENT = 27,
|
||||
/** A tooltip is about to pop up for this widget. The mouse coordinates are
|
||||
available in Fl::event_x() and Fl::event_y(). Change the widget tooltip
|
||||
as needed. */
|
||||
FL_TOOLTIP_EVENT = 28
|
||||
// DEV NOTE: Keep this list in sync with FL/names.h
|
||||
};
|
||||
|
||||
|
||||
@ -95,6 +95,8 @@ public:
|
||||
static void wrap_width(int v) { wrap_width_ = v; }
|
||||
/** Returns the window that is used for tooltips */
|
||||
static Fl_Window* current_window(void);
|
||||
/** \brief Temporarily Override Tooltip Text during an FL_TOOLTIP_EVENT. */
|
||||
static int override_text(const char *new_text);
|
||||
|
||||
// These should not be public, but Fl_Widget::tooltip() needs them...
|
||||
// fabien: made it private with only a friend function access
|
||||
@ -104,6 +106,7 @@ private:
|
||||
static void enter_(Fl_Widget* w);
|
||||
static void exit_(Fl_Widget *w);
|
||||
static void set_enter_exit_once_();
|
||||
static void tooltip_timeout_(void*);
|
||||
|
||||
private:
|
||||
static float delay_; //!< delay before a tooltip is shown
|
||||
@ -118,6 +121,7 @@ private:
|
||||
static int margin_height_; //!< distance around tooltip text top+bottom
|
||||
static int wrap_width_; //!< maximum width of tooltip text before it word wraps
|
||||
static const int draw_symbols_; // 1 = draw @-symbols in tooltips, 0 = no
|
||||
static char *override_text_; //!< a copy of the last text for an overridden tooltip
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -73,9 +73,10 @@ const char * const fl_eventnames[] =
|
||||
"FL_FULLSCREEN",
|
||||
"FL_ZOOM_GESTURE",
|
||||
"FL_ZOOM_EVENT",
|
||||
"FL_EVENT_28", // not yet defined, just in case it /will/ be defined ...
|
||||
"FL_TOOLTIP_EVENT",
|
||||
"FL_EVENT_29", // not yet defined, just in case it /will/ be defined ...
|
||||
"FL_EVENT_30" // not yet defined, just in case it /will/ be defined ...
|
||||
"FL_EVENT_30", // not yet defined, just in case it /will/ be defined ...
|
||||
"FL_EVENT_31" // not yet defined, just in case it /will/ be defined ...
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define DEBUG
|
||||
|
||||
float Fl_Tooltip::delay_ = 1.0f;
|
||||
float Fl_Tooltip::hidedelay_ = 12.0f;
|
||||
float Fl_Tooltip::hoverdelay_ = 0.2f;
|
||||
@ -38,6 +41,7 @@ int Fl_Tooltip::margin_width_ = 3;
|
||||
int Fl_Tooltip::margin_height_ = 3;
|
||||
int Fl_Tooltip::wrap_width_ = 400;
|
||||
const int Fl_Tooltip::draw_symbols_ = 1;
|
||||
char *Fl_Tooltip::override_text_ = nullptr;
|
||||
|
||||
static const char* tip;
|
||||
|
||||
@ -154,14 +158,49 @@ static void tooltip_hide_timeout(void*) {
|
||||
recent_tooltip = 0;
|
||||
}
|
||||
|
||||
static void tooltip_timeout(void*) {
|
||||
/**
|
||||
Use this method to temporarily change the tooltip text before it is displayed.
|
||||
|
||||
When FLTK sends an FL_TOOLTIP_EVENT to the widget under the mouse pointer,
|
||||
you can handle this event to modify the tooltip text dynamically. The
|
||||
provided text will be copied into a local buffer. To apply the override,
|
||||
the event handler must return 1.
|
||||
|
||||
To disable the tooltip for the current event, set the override text to nullptr
|
||||
or an empty string ("") and return 1.
|
||||
|
||||
\param[in] new_text a C string that will be copied into a buffer
|
||||
\return always 1, so this call can finish the FL_TOOLTIP_EVENT handling.
|
||||
|
||||
\see void Fl_Widget::tooltip(const char *text).
|
||||
|
||||
\see `test/color_chooser.cxx` for a usage example.
|
||||
*/
|
||||
int Fl_Tooltip::override_text(const char *new_text) {
|
||||
if (new_text != override_text_) {
|
||||
if (window && window->label()==override_text_)
|
||||
((Fl_Widget *) window)->label(nullptr);
|
||||
if (override_text_)
|
||||
::free(override_text_);
|
||||
override_text_ = nullptr;
|
||||
if (new_text)
|
||||
override_text_ = ::strdup(new_text);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Fl_Tooltip::tooltip_timeout_(void*) {
|
||||
#ifdef DEBUG
|
||||
puts("tooltip_timeout();");
|
||||
puts("tooltip_timeout_();");
|
||||
#endif // DEBUG
|
||||
|
||||
if (recursion) return;
|
||||
recursion = 1;
|
||||
if (!top_win_iconified_()) { // no tooltip if top win iconified (STR #3157)
|
||||
if (Fl_Tooltip::current()) {
|
||||
if (Fl_Tooltip::current()->handle(FL_TOOLTIP_EVENT))
|
||||
tip = Fl_Tooltip::override_text_;
|
||||
}
|
||||
if (!tip || !*tip) {
|
||||
if (window) window->hide();
|
||||
Fl::remove_timeout(tooltip_hide_timeout);
|
||||
@ -253,7 +292,7 @@ void Fl_Tooltip::exit_(Fl_Widget *w) {
|
||||
|
||||
if (!widget_ || (w && w == window)) return;
|
||||
widget_ = 0;
|
||||
Fl::remove_timeout(tooltip_timeout);
|
||||
Fl::remove_timeout(tooltip_timeout_);
|
||||
Fl::remove_timeout(recent_timeout);
|
||||
if (window && window->visible()) {
|
||||
window->hide();
|
||||
@ -298,7 +337,7 @@ void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char*
|
||||
}
|
||||
// do nothing if it is the same:
|
||||
if (wid==widget_ /*&& x==X && y==currentTooltipY && w==W && h==currentTooltipH*/ && t==tip) return;
|
||||
Fl::remove_timeout(tooltip_timeout);
|
||||
Fl::remove_timeout(tooltip_timeout_);
|
||||
Fl::remove_timeout(recent_timeout);
|
||||
// remember it:
|
||||
widget_ = wid; currentTooltipY = y; currentTooltipH = h; tip = t;
|
||||
@ -308,7 +347,7 @@ void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char*
|
||||
window->hide();
|
||||
Fl::remove_timeout(tooltip_hide_timeout);
|
||||
}
|
||||
Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout);
|
||||
Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout_);
|
||||
} else if (Fl_Tooltip::delay() < .1) {
|
||||
// possible fix for the Windows titlebar, it seems to want the
|
||||
// window to be destroyed, moving it messes up the parenting:
|
||||
@ -316,13 +355,13 @@ void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char*
|
||||
window->hide();
|
||||
Fl::remove_timeout(tooltip_hide_timeout);
|
||||
}
|
||||
tooltip_timeout(0);
|
||||
tooltip_timeout_(nullptr);
|
||||
} else {
|
||||
if (window && window->visible()) {
|
||||
window->hide();
|
||||
Fl::remove_timeout(tooltip_hide_timeout);
|
||||
}
|
||||
Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout);
|
||||
Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout_);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -341,19 +380,25 @@ void Fl_Tooltip::set_enter_exit_once_() {
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the current tooltip text.
|
||||
Sets the Tooltip Text for a Widget.
|
||||
|
||||
Sets a string of text to display in a popup tooltip window when the user
|
||||
hovers the mouse over the widget. The string is <I>not</I> copied, so
|
||||
make sure any formatted string is stored in a static, global,
|
||||
or allocated buffer. If you want a copy made and managed for you,
|
||||
use the copy_tooltip() method, which will manage the tooltip string
|
||||
automatically.
|
||||
Assigns a tooltip string that appears in a popup when the user hovers over
|
||||
the widget. The provided string is not copied. The caller must eensure it
|
||||
remains valid by storing it in a static, global, or dynamically allocated
|
||||
buffer. If you need the tooltip string to be copied and managed automatically,
|
||||
use copy_tooltip().
|
||||
|
||||
By default, a widget inherits the tooltip of its parent if none is explicitly
|
||||
set. If you assign a tooltip to a group but not to its child widgets, the
|
||||
child widgets will display the group’s tooltip. To prevent inheritance, set
|
||||
the child’s tooltip to an empty string ("").
|
||||
|
||||
Tooltips can be updated dynamically before they are displayed. When a tooltip
|
||||
is about to be shown, FLTK sends an `FL_TOOLTIP_EVENT` to the widget’s
|
||||
`handle()` method. Developers can override the tooltip text temporarily
|
||||
using `Fl_Tooltip::override_text(const char* new_text)` and returning 1 from
|
||||
`handle()` to apply the change.
|
||||
|
||||
If no tooltip is set, the tooltip of the parent is inherited. Setting a
|
||||
tooltip for a group and setting no tooltip for a child will show the
|
||||
group's tooltip instead. To avoid this behavior, you can set the child's
|
||||
tooltip to an empty string ("").
|
||||
\param[in] text New tooltip text (no copy is made)
|
||||
\see copy_tooltip(const char*), tooltip()
|
||||
*/
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <FL/fl_show_colormap.H>
|
||||
#include <FL/Fl_Color_Chooser.H>
|
||||
#include <FL/Fl_Image.H>
|
||||
#include <FL/Fl_Tooltip.H>
|
||||
#include <FL/platform.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
@ -84,6 +85,22 @@ void cb2(Fl_Widget *, void *v) {
|
||||
bx->parent()->redraw();
|
||||
}
|
||||
|
||||
class Image_Box: public Fl_Box {
|
||||
public:
|
||||
Image_Box(int x, int y, int w, int h, const char *label = nullptr)
|
||||
: Fl_Box(x, y, w, h, label) { }
|
||||
int handle(int event) {
|
||||
if (event == FL_TOOLTIP_EVENT) {
|
||||
const char *color_name_lut[] = { "blue", "green", "black", "red" };
|
||||
int quadrant = (Fl::event_x() < x()+w()/2) + 2*(Fl::event_y() < y()+h()/2);
|
||||
char buf[80];
|
||||
::snprintf(buf, 79, "Color %s at x=%d, y=%d", color_name_lut[quadrant], Fl::event_x(), Fl::event_y());
|
||||
return Fl_Tooltip::override_text(buf);
|
||||
}
|
||||
return Fl_Box::handle(event);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
Fl::set_color(fullcolor_cell,145,159,170);
|
||||
Fl_Window window(400,400);
|
||||
@ -98,7 +115,8 @@ int main(int argc, char ** argv) {
|
||||
b1.callback(cb1,&box);
|
||||
Fl_Button b2(120,120,180,30,"fl_color_chooser()");
|
||||
b2.callback(cb2,&box);
|
||||
Fl_Box image_box(160,190,width,height,0);
|
||||
Image_Box image_box(160,190,width,height,0);
|
||||
image_box.tooltip("Image Box");
|
||||
make_image();
|
||||
(new Fl_RGB_Image(image, width, height))->label(&image_box);
|
||||
Fl_Box b(160,310,120,30,"Example of fl_draw_image()");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user