gtkmm – example 21

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create a popup menu (right click contextual menu) inside a drawing Widget (with Cairo). This code can easily be extended to other widgets.

capture

Download


Source code

main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;
	
	// Create the drawing
	DrawingArea Dwg;
	// Insert the drawing in the window
	window.add(Dwg);
	// Resize the window
	window.resize(250,250);
	// Set the window title
	window.set_title("Popup menu");
	// Show the drawing
	Dwg.show();
	
	// Start main loop
	return app->run(window);
}

drawingarea.h

#ifndef DRAWINGAREA_H
#define DRAWINGAREA_H

#include 
#include 


class DrawingArea : public Gtk::DrawingArea
{
public:
	DrawingArea();

protected:
	// Override default signal handler:
	virtual bool                on_draw(const Cairo::RefPtr& cr);

	// Override mouse events
	bool                        on_button_press_event(GdkEventButton *event);

	// Signal handlers (run when a popup item is clicked)
	void                        on_action1_event();
	void                        on_action2_event();

private:

	// Image displayed
	Glib::RefPtr   image;

	// Scale of the image
	double                      scale;

	// Popup menu and submenus
	Gtk::Menu                   m_Menu_Popup;
	Gtk::MenuItem               MenuItem1;
	Gtk::MenuItem               MenuItem2;

};
#endif // DRAWINGAREA_H

drawingarea.cpp

#include "drawingarea.h"



DrawingArea::DrawingArea()
{
	// Load the image
	image = Gdk::Pixbuf::create_from_file("gtk.png");

	// Set masks for mouse events
	add_events(Gdk::BUTTON_PRESS_MASK);

	// ::: Create popup menu :::

	// Add and connect action 1
	MenuItem1.set_label("Action 1");
	MenuItem1.signal_activate().connect(sigc::mem_fun(*this,&DrawingArea::on_action1_event));
	m_Menu_Popup.append(MenuItem1);

	// Add and connect action 2
	MenuItem2.set_label("Action 2");
	MenuItem2.signal_activate().connect(sigc::mem_fun(*this,&DrawingArea::on_action2_event));
	m_Menu_Popup.append(MenuItem2);

	// Show the menu
	m_Menu_Popup.show_all();

	// Connect the menu to this Widget
	m_Menu_Popup.accelerate(*this);
}


// Signal handlers for acion 1
void DrawingArea::on_action1_event()
{
	std::cout << "Action 1 selected" << std::endl;
}


// Signal handlers for acion 2
void DrawingArea::on_action2_event()
{
	std::cout << "Action 2 selected" << std::endl;
}


// Mouse button press event
bool DrawingArea::on_button_press_event(GdkEventButton *event)
{
	// Check if the event is a right button click.
	if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
	{
		// Display the popup menu
		m_Menu_Popup.popup(event->button, event->time);
		// The event has been handled.
		return true;
	}

	// Propagate the event further.
	return false;
}


// Call when the display need to be updated
bool DrawingArea::on_draw(const Cairo::RefPtr& cr)
{
	// Place the image at the center of the window
	Gdk::Cairo::set_source_pixbuf(cr, image, 0,0);
	// Update the whole drawing area
	cr->rectangle(0, 0, image->get_width(), image->get_height());
	// Fill the area with the image
	cr->fill();
	// The event has been handled.
	return true;
}

Leave a Reply

Your email address will not be published. Required fields are marked *