c++tooltipfltk

Tooltip not appearing in FLTK custom widgets


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:

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.


Solution

  • 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;
    }