Search code examples
c++heap-memoryfltkstack-memory

where to declare object to use it (fltk)


I am having a problem accessing an object or its methods in fltk. I have a Class named MyWindow which is a child class of Fl_Window. so basically i would like to use an object which is either declared int the main or Mywindow in private section. My problem is that I can't use it that way. It only lets me to use the object if it is declared global. Can i somehow put it on the heap like this: Classname *pointer = new Classname(); ? IF i can where do I do that? How would the callback function work if i need that object or its functions in the callback? Should i use a pointer to it in the callback arguements? lets say i want to click on the button and I need it to do something with the object and change a value. lots of questions I know, I am really lost. Can someone just point me to the right direction? Thank you! :)


Solution

  • Simple case for passing data to the GUI

    class MyData
    {
        // The data model
    };
    
    class MyWindow: public FL_Window
    {
        MyData* m_data;
    public:
        void Data(MyData* data) { m_data = data; }
        ...
    };
    
    int main()
    {
        MyWindow gui;
        MyData data;
    
        // Tell the gui about the data
        gui.Data(data);
        ...
        // Setup the dialog
        gui.begin();
        ...
        gui.end();
        gui.show();
        return FL::run();
    }
    

    For the callbacks, do it in two stages

    class NeedingACallback
    {
    public:
        void Setup()
        {
            ...
            FL_xxx* w = new FL_xxx(xpos, ypos, wid, hgt, name);
            ...
            //                    v Pass the instance to the static
            w->callback(_EventCB, this);
        }
    
        // The callback
        static void _EventCB(FL_Widget* w, void* client)
        {
            // Convert the void* back to the instance
            NeedingACallback* self = reinterpret_cast<NeedingACallback*>(client);
            self->EventCB();
        }
    
        // Make life simple so you don't have to put self-> in front of
        // all the instance data accessed
        void EventCB()
        {
            // Callback for this instance of the class
        }
    };
    

    EDIT It sounds like you're having multiple instances of data. An alternative technique is to have data as a reference. This must be done in the constructor. This way, m_data and the data in main both refer to the same area of memory.

    class MyWindow: public FL_Window
    {
        MyData& m_data;
    public:
        MyWindow(int wid, int hgt, MyData& data, const char* title=0)
       : FL_Window(wid,hgt,title)
       , m_data(data)
        {
        ...
        }
    };
    
    int main()
    {
        MyData data;
        MyWindow gui(100, 100, data, "Call me Mr");
    
        ...
        // Setup the dialog
        gui.begin();
        ...
        gui.end();
        gui.show();
        return FL::run();
    }