Simple Graphics in C++ on Linux with GTK+

Follow the steps below to implement a simple graphics application in C++ on Linux with GTK+. When run, the program will display a small window containing a rectangle of random size, color, and location.

UPDATE 2017/03/29 – I have updated the code and scripts in this post to fix a few errors, like re-adding an accidentally omitted #include directive, and rearranging the order of some arguments in the linker step. Also, please note that these instructions assume that GCC and GTK+ are already installed on the target system. For more details on this installation process, see the previous post, which should be automatically linked below.

GTKGraphicsTest

1. In any convenient location, create a new directory named “GTKGraphicsTest”.

2. In the newly created GTKGraphicsTest directory, create a new text file named “GTKGraphicsTest.cpp”, containing the following text.


#include <gtkmm.h>
using namespace std;
using namespace Gtk;

// class definitions

class MathHelper
{
	public: static void seedRandomizer()
	{
		srand(time(NULL));
	}

	public: static double random()
	{
		return ((double)rand()) / RAND_MAX;
	}
};

class Color
{
	public: 
		double red;
		double green;
		double blue;

	public: Color() {}

	public: Color(double redIn, double greenIn, double blueIn)
	{
		red = redIn;
		green = greenIn;
		blue = blueIn;
	}

	public: Color* random()
	{
		red = MathHelper::random();
		green = MathHelper::random();
		blue = MathHelper::random();

		return this;
	}
};

class Coords
{
	// variables

	public: double x;
	public: double y;

	// constructor

	public: Coords(int xIn, int yIn)
	{
		this->x = xIn;
		this->y = yIn;
	}

	// methods

	public: Coords* multiply(Coords* other)
	{
		this->x *= other->x;
		this->y *= other->y;
		return this;
	}

	public: Coords* random()
	{
		this->x = MathHelper::random();
		this->y = MathHelper::random();
		return this;
	}
};

class Rectangle
{
	public: Color* color;
	public: Coords* pos;
	public: Coords* size;

	public: Rectangle(Color* colorIn, Coords* posIn, Coords* sizeIn)
	{
		this->color = colorIn;
		this->pos = posIn;
		this->size = sizeIn;
	}
	
};

class DisplayHelper
{
	// variables

	private: Coords* viewSizeInPixels;
	private: Cairo::RefPtr graphics;

	// constructors

	public: DisplayHelper() {}

	// methods

	public: void initialize(Coords* viewSizeInPixelsIn, DrawingArea* drawingArea)
	{
		viewSizeInPixels = viewSizeInPixelsIn;
		drawingArea->set_size_request
		(
			viewSizeInPixels->x,
			viewSizeInPixels->y
		);	
		graphics = drawingArea->get_window()->create_cairo_context();
	}

	public: void drawRectangle(Rectangle* rectangle)
	{
		Color* color = rectangle->color;
		graphics->set_source_rgba
		(
			color->red,
			color->green,
			color->blue,
			1 // alpha
		);

		Coords* pos = rectangle->pos;
		Coords* size = rectangle->size;
		graphics->rectangle(pos->x, pos->y, size->x, size->y);
		graphics->fill();
	}
};

// program
class GTKGraphicsTest : public Window
{
	// controls

	protected: DrawingArea drawingArea;

	// methods

	public: GTKGraphicsTest()
	{
		MathHelper::seedRandomizer();

		set_border_width(10);

		// drawingArea
		drawingArea.signal_expose_event().connect
		(
			sigc::mem_fun
			(
				*this, 
				&GTKGraphicsTest::drawingAreaExposed
			)
		);
		add(drawingArea);
		drawingArea.show();
	}

	// events

	protected: bool drawingAreaExposed(GdkEventExpose* event)
	{
		Coords* viewSize = new Coords(100, 100);

		DisplayHelper* displayHelper = new DisplayHelper();
		displayHelper->initialize(viewSize, &drawingArea);
		
		Rectangle* rectangle = new Rectangle
		(
			(new Color())->random(),
			(new Coords(0, 0))->random()->multiply(viewSize),
			(new Coords(0, 0))->random()->multiply(viewSize)
		);

		displayHelper->drawRectangle
		(
			rectangle
		);
	}
};

// main

int main (int argc, char *argv[])
{
	Main kit(argc, argv);
	GTKGraphicsTest GTKGraphicsTest;
	Main::run(GTKGraphicsTest);
	return 0;
}

3. Still in the same directory, create a new text file named “CompileAndRun.sh”, containing the following text. If using a version of GTK+ other than 2.4, substitute the version number in the appropriate places.

PROGRAM_NAME=GTKGraphicsTest
g++ `pkg-config gtkmm-2.4 --cflags --libs` -c $PROGRAM_NAME.cpp
g++ $PROGRAM_NAME.o -o $PROGRAM_NAME.elf `pkg-config gtkmm-2.4 --cflags --libs`
rm -rf $PROGRAM_NAME.o
./$PROGRAM_NAME.elf
rm -rf $PROGRAM_NAME.elf

4. Run the newly created CompileAndRun.sh.

Advertisements
This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s