Any example for creating gui clickable button?

Hi!..

I’m look for creating a main menu but i’m a bit confused between PGButton and DirectButton using C++.

Any example will be very grateful.
Thanks.

I would like to draw your attention to the search option, which is available in the upper-right corner.

1 Like

Thanks for answering…
I was already checked that topic and tested what it says, but i’m getting problems with the following line:

Looks like MouseButton::one() is not implemented, intellisense does not detect it…

Oops… forgot #include <mouseButton.h> thanks.

Excuse me…
I did not get this:

framework.define_key(but->get_click_event(MouseButton::one() ), “button press”, button_callback, NULL);

the “button_callback” and NULL parameter are what i did not catch…
What i want to do is when user clicks on a button, a function is called…

Thanks

I think this is what you need.

#include "pandaFramework.h"
#include "pandaSystem.h"
#include "mouseButton.h"
#include <iostream>

void button_callback(const Event* pTheEvent, void* pData) {
    std::cout << "button press!" << std::endl;
}


int main(int argc, char* argv[]) {
    PandaFramework framework;
    framework.open_framework(argc, argv);
    framework.set_window_title("My Panda3D Window");
    WindowFramework* window = framework.open_window();

    PGButton* but;
    but = new PGButton("button");
    but->setup("my button!");
    NodePath butNP = window->get_aspect_2d().attach_new_node(but);
    butNP.set_scale(0.07);

    framework.define_key(but->get_click_event(MouseButton::one()), "button press", button_callback, NULL);


    framework.main_loop();
    framework.close_framework();
    return 0;
}
1 Like

Thank you, I will try…

Sorry, my last comment had an error that i solved later…

The example you quoted works fine… but i want to use a delegate since the button_callback is inside my scnmenu class… so it is scnmenu::button_callback

Creating a pointer to member function did not work for me.
Could you please show me and example?
Thanks again.

I think you need to create a short code to demonstrate your approach.

I have a main menu with three buttons, start, options and exit

the trigger function must be a member function that belongs to the main menu class, in my case is scnmenu, so the trigger function should be scnmenu::on_click_btnstart()

this is what i have:

//scnmenu.h
class scnmenu {
private:
     PointerTo<PGButton> btnStart {nullptr};
     NodePath nbtnStart;

     void on_press_btnStart(const Event* e, void* pData);

public:
     scnmenu();
};

//scnmenu.cpp
scnmenu::scnmenu(){
     btnStart = new PGButton("btnStart");
     btnStart->setup("Start");
     nbtnStart = window->get_aspect_2d().attach_new_node(btnStart);

     framework->define_key(btnStart->get_click_event(MouseButton::one()), "Start Pressed", on_press_btnStart, NULL);
}

void scnmenu::on_press_btnStart(const Event* e, void* pData){
}

on framework->define_key function, i’m very sure that argument 3rd is bad, since on_press_btnStart is not a function else a member function so i need to somehow point to my member function, this to respect OOP.

Cheers

I tried to guess what you wanted.

#include "pandaFramework.h"
#include "pandaSystem.h"
#include "mouseButton.h"
#include <iostream>

void button_callback(const Event* pTheEvent, void* pData) {
	std::cout << "button press1!" << std::endl;
}


class MenuLogic {

public:

	static void button_callback(const Event* pTheEvent, void* pData)
	{
		std::cout << "button press!" << std::endl;
	}
};

class Menu {

public:

	void create(PandaFramework& framework, WindowFramework* window)
	{
		PGButton* but;
		but = new PGButton("button");
		but->setup("my button!");
		NodePath butNP = window->get_aspect_2d().attach_new_node(but);
		butNP.set_scale(0.07);
		framework.define_key(but->get_click_event(MouseButton::one()), "button press", &MenuLogic::button_callback, NULL);

		PGButton* but1;
		but1 = new PGButton("button");
		but1->setup("my button1!");
		NodePath butNP1 = window->get_aspect_2d().attach_new_node(but1);
		butNP1.set_scale(0.07);
		butNP1.set_pos(0, 0, 0.15);
		framework.define_key(but1->get_click_event(MouseButton::one()), "button press", button_callback, NULL);
	}
};

int main(int argc, char* argv[]) {
	PandaFramework framework;
	framework.open_framework(argc, argv);
	framework.set_window_title("My Panda3D Window");
	WindowFramework* window = framework.open_window();

	Menu Menu_create;
	Menu_create.create(framework, window);

	framework.main_loop();
	framework.close_framework();
	return 0;
}

Please note that your example is not code that can be run.

1 Like

I think that they want the callback to references the method defined in their class.

My C++ is really rusty, but since the callback reference is being passed in from within the class that defines the desired method, would this not be done with the special “this” identifier? Like so:

scnmenu::scnmenu(){
     // Other code omitted for brevity and clarity

     framework->define_key(btnStart->get_click_event(MouseButton::one()), "Start Pressed", this->on_press_btnStart, NULL);
}
1 Like

Perhaps we are talking about creating a constructor class to pass the name of the called function to.

#include "pandaFramework.h"
#include "pandaSystem.h"
#include "mouseButton.h"
#include <iostream>

typedef void (*PF)(const Event* pTheEvent, void* pData);


void button_callback(const Event* pTheEvent, void* pData) {
	std::cout << "button press1!" << std::endl;
}

class MenuLogic {

public:

	static void button_callback(const Event* pTheEvent, void* pData)
	{
		std::cout << "button press!" << std::endl;
	}
};

class Menu {

public:

	void create(PandaFramework& framework, WindowFramework* window, PF& muFun, PF& muFun1)
	{
		PGButton* but;
		but = new PGButton("button");
		but->setup("my button!");
		NodePath butNP = window->get_aspect_2d().attach_new_node(but);
		butNP.set_scale(0.07);
		framework.define_key(but->get_click_event(MouseButton::one()), "button press", muFun1, NULL);

		PGButton* but1;
		but1 = new PGButton("button");
		but1->setup("my button1!");
		NodePath butNP1 = window->get_aspect_2d().attach_new_node(but1);
		butNP1.set_scale(0.07);
		butNP1.set_pos(0, 0, 0.15);
		framework.define_key(but1->get_click_event(MouseButton::one()), "button press", muFun, NULL);
	}
};


int main(int argc, char* argv[]) {
	PandaFramework framework;
	framework.open_framework(argc, argv);
	framework.set_window_title("My Panda3D Window");
	WindowFramework* window = framework.open_window();

	PF muFun = &button_callback;
	PF muFun1 = &MenuLogic::button_callback;

	Menu Menu_create;
	Menu_create.create(framework, window, muFun, muFun1);

	framework.main_loop();
	framework.close_framework();
	return 0;
}

For example.

1 Like

It’s been a long time since I last did much in C++, so things may have changed, or I may be misremembering, but would the following not work?

//scnmenu.h
class scnmenu {
private:
     PointerTo<PGButton> btnStart {nullptr};
     NodePath nbtnStart;

     void on_press_btnStart(const Event* e, void* pData);

public:
     scnmenu();
};

//scnmenu.cpp
scnmenu::scnmenu(){
     btnStart = new PGButton("btnStart");
     btnStart->setup("Start");
     nbtnStart = window->get_aspect_2d().attach_new_node(btnStart);

     framework->define_key(btnStart->get_click_event(MouseButton::one()), "Start Pressed", this->on_press_btnStart, NULL);
}

void scnmenu::on_press_btnStart(const Event* e, void* pData){
}

(It’s the same as the code posted by digimikeh, above, but with “this->” in front of the reference to “on_press_btnStart” in the call to “define_key”.)

1 Like

In fact, both work.

#include "pandaFramework.h"
#include "pandaSystem.h"
#include "mouseButton.h"
#include <iostream>

class Menu {

public:

	void create(PandaFramework& framework, WindowFramework* window)
	{
		PGButton* but;
		but = new PGButton("button");
		but->setup("my button!");
		NodePath butNP = window->get_aspect_2d().attach_new_node(but);
		butNP.set_scale(0.07);
		framework.define_key(but->get_click_event(MouseButton::one()), "button press", &Menu::button_callback, NULL);

		PGButton* but1;
		but1 = new PGButton("button");
		but1->setup("my button1!");
		NodePath butNP1 = window->get_aspect_2d().attach_new_node(but1);
		butNP1.set_scale(0.07);
		butNP1.set_pos(0, 0, 0.15);
		framework.define_key(but1->get_click_event(MouseButton::one()), "button press", this->button_callback, NULL);

	}

private:

	static void button_callback(const Event* pTheEvent, void* pData)
	{
		std::cout << "button press!" << std::endl;
	}

};

int main(int argc, char* argv[]) {
	PandaFramework framework;
	framework.open_framework(argc, argv);
	framework.set_window_title("My Panda3D Window");
	WindowFramework* window = framework.open_window();

	Menu Menu_create;
	Menu_create.create(framework, window);

	framework.main_loop();
	framework.close_framework();
	return 0;
}

The only difference is that the function is static.

good… used this pointer pointing to static function did the job…

Thank you both!

1 Like