0

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! :)

trincot
  • 317,000
  • 35
  • 244
  • 286
firax
  • 5
  • 5

1 Answers1

0

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();
}
cup
  • 7,589
  • 4
  • 19
  • 42
  • thank you very much!!! it works!!!! the only problem is that it is a little bit ugly looking code:D . but i guess it is because FLTK is more C than C++. Thank you for all your help and code and time. It really helps me a lot!! – firax Apr 28 '15 at 11:52
  • the only problem is that if I change something with the functions, it does not save the changes. So i can do the functions but nothing gets saved. for example i setup the players and they get a mark X or O which is pushed back in a vector, but when i call the getMark function it returns a random character, so I think it makes a copy of the object and does the function it is asked for and then deletes the object. Why is it so simple with globals and so hard when done properly? – firax Apr 28 '15 at 13:52
  • Are you passing the data by value, by reference or by pointer? – cup Apr 28 '15 at 14:36
  • I think i tried all of them but not sure if i was doing it right. I tried with your method first, to setup a pointer pointing to the object in main. class MyWindow: public FL_Window { MyData* m_data; public: void Data(MyData* data) { m_data = data; } ... }; then I tried like this void Data(MyData &data) {m_data = data} then I tried this void Data(MyData data) { m_data = data} none of them worked. I think i am doing something wrong – firax Apr 28 '15 at 15:10
  • I think you've got two instances of the data. Have a look at the edit on an alternative technique – cup Apr 28 '15 at 20:19
  • it is going to be a stupid question but if i set up the constructor like that, what do i do with this constructor ? MyWindow(int width, int height, const char* title=0) : Fl_Window(width,height,title) { – firax Apr 29 '15 at 09:59
  • Add the data before the title. I have edited the example accordingly – cup Apr 29 '15 at 10:19