I am creating a tool for a project using Fl_Tabs and some custom widget, which encompasses some other custom classes.
I would like to have a tooltip appearing when the mouse is hoovering on the custom widgets, but this actually is not happening.
I tried to check the solution in several ways, but I failed and I think I am missing something:
I thought that the tooltip is freed when the pointer is destroyed, per the help:
The internal copy will automatically be freed whenever you assign a new tooltip or when the widget is destroyed.
and since the pointers are within a Fl_Group I believed that the tooltip is freed: but this is not case, as one can see in the code below.
Since I am overriding the handle
function, this may interfere with the tooltip behaviour: but I am check just the FL_PUSH
event, and I let the others to be managed by FLTK.
Down below once can find a code snippet1 reproducing the issues that I have: it is a little bit long, but I wanted to put all the elements that I have in my case. I am working with FLTK 1.3.5, clang 14.0.0 on a MacBookPro equipped with Monterey OS (12.6.1).
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
#include <iostream>
class Action{
public:
Action(std::string name, int cInit){
_name = name;
_counter = cInit;
};
void increment(){
_counter++;
};
std::string message(){
increment();
return _name + " Counter: " + std::to_string(_counter);
};
private:
std::string _name;
int _counter;
};
class MyButton: public Fl_Box{
public:
MyButton(int X, int Y, int W, int H, Action* A, Fl_Box* mb, const char* L=0):Fl_Box(X,Y,W,H,L){
box(FL_UP_BOX);
_mb = mb;
_A = A;
}
int handle(int event){
switch(event) {
case FL_PUSH:
sendMessage();
return 0;
default:
return Fl_Widget::handle(event);
}
};
void sendMessage(){
_mb->copy_label(_A->message().c_str());
};
private:
Fl_Box* _mb;
Action* _A;
};
int main(int argc, char *argv[]) {
Fl_Window *win = new Fl_Window(500,300,"Tabs Example");
{
Action* A = new Action("Trees",42);
Fl_Box* B = new Fl_Box(10,210,150,50);
B -> box(FL_UP_BOX);
Fl_Tabs *tabs = new Fl_Tabs(10,10,500-20,200-20);
{
// Aaa tab
Fl_Group *aaa = new Fl_Group(10,35,500-20,200-45,"Aaa");
{
MyButton *b1 = new MyButton(50, 60,90,25,A,B,"Button A1"); b1->color(88+1);
Fl_Box *b2 = new Fl_Box(50, 90,90,25,"Button A2"); b2->box(FL_UP_BOX); b2->color(88+2);
Fl_Button *b3 = new Fl_Button(50,120,90,25,"Button A3"); b3->color(88+3);
b1 -> copy_tooltip("b1: is it there?");
b2 -> copy_tooltip("b2: is it there?");
b3 -> copy_tooltip("b3: is it there?");
}
aaa->end();
// Bbb tab
Fl_Group *bbb = new Fl_Group(10,35,500-10,200-35,"Bbb");
{
Fl_Button *b1 = new Fl_Button( 50,60,90,25,"Button B1"); b1->color(88+1);
Fl_Button *b2 = new Fl_Button(150,60,90,25,"Button B2"); b2->color(88+3);
Fl_Button *b3 = new Fl_Button(250,60,90,25,"Button B3"); b3->color(88+5);
Fl_Button *b4 = new Fl_Button( 50,90,90,25,"Button B4"); b4->color(88+2);
Fl_Button *b5 = new Fl_Button(150,90,90,25,"Button B5"); b5->color(88+4);
Fl_Button *b6 = new Fl_Button(250,90,90,25,"Button B6"); b6->color(88+6);
}
bbb->end();
}
tabs->end();
}
win->end();
win->show();
return(Fl::run());
}
1 This example is hugely inspired by one of the examples in Erco's cheat page.
You can try changing the super call from return Fl_Widget::handle(event);
to return Fl_Box::handle(event);
.
MyButton
derives from Fl_Box
, and even though you could call any of the ancestors such as Fl_Widget
, Fl_Box
does handle hovering (FL_ENTER
and FL_LEAVE
). You can check the FLTK source code:
int Fl_Box::handle(int event) {
if (event == FL_ENTER || event == FL_LEAVE) return 1;
else return 0;
}
vs:
int Fl_Widget::handle(int) {
return 0;
}