# shape drawing with menu [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 4
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 4

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"

// layout
constexpr int xmax = 600;
constexpr int ymax = 400;

{
Quad_center(Point center, int w, int h)
{
add(Point(center.x - w / 2, center.y - h / 2));
add(Point(center.x + w / 2, center.y - h / 2));
add(Point(center.x + w / 2, center.y + h / 2));
add(Point(center.x - w / 2, center.y + h / 2));

}

void draw_lines() const;
};

{
fl_color(FL_BLACK);
Closed_polyline::draw_lines();
}

// TRIANGLE
struct Triangle : Closed_polyline
{
Triangle(Point origin, int edge_length)
{
int h = sqrt(3) / 2 * edge_length;

Point p(origin.x - edge_length / 2, origin.y + edge_length / 2);
add(Point(p.x + edge_length / 2, p.y - h));
}

void draw_lines() const;
};

void Triangle::draw_lines() const
{
fl_color(FL_BLACK);
Closed_polyline::draw_lines();
}

// HEXAGON
struct Hexagon : Closed_polyline
{
{
int n = 6;
for (int i = 0; i < n; i++) {
add(Point(origin.x + radius * cos(2 * M_PI * i / n), origin.y + radius * sin(2 * M_PI * i / n)));
}
}

void draw_lines() const;
};

void Hexagon::draw_lines() const
{
fl_color(FL_BLACK);
Closed_polyline::draw_lines();
}

// DRAW SHAPES WINDOW
struct Shapes_window : Window {
Shapes_window(Point xy, int w, int h, const string& title);
private:
// data
enum Shapes
{
circle, square, triangle , hexagon
};

Vector_ref<Shape> s;

// widgets
Button quit_button;	// end program
In_box draw_pos_x;
In_box draw_pos_y;
Out_box xy_out;

// actions invoked by callbacks
void draw_shape(Shapes s);
void quit();

// callback functions
};

Shapes_window::Shapes_window(Point xy, int w, int h, const string& title)
:Window(xy, w, h, title),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
draw_pos_x(Point(x_max() - 310, 0), 50, 20, "pos x:"),
draw_pos_y(Point(x_max() - 210, 0), 50, 20, "pos y:"),
xy_out(Point(100, 0), 100, 20, "drawn at (x,y):"),
{
attach(quit_button);
attach(draw_pos_x);
attach(draw_pos_y);
attach(xy_out);

xy_out.put("no shape");

shape_menu.attach(new Button(Point(0, 0), 0, 0, "circle", cb_circle));
shape_menu.attach(new Button(Point(0, 0), 0, 0, "square", cb_square));
shape_menu.attach(new Button(Point(0, 0), 0, 0, "triangle", cb_triangle));
shape_menu.attach(new Button(Point(0, 0), 0, 0, "hexagon", cb_hexagon));

}

void Shapes_window::draw_shape(Shapes shape)
{

if (draw_pos_x.get_int() == -999999)
{
xy_out.put("enter position");
}
else {

int x = draw_pos_x.get_int();
int y = draw_pos_y.get_int();

switch (shape)
{
case circle: { s.push_back(new Circle(Point(x, y), 20)); break; }
case square: { s.push_back(new Quad_center(Point(x, y), 40, 40)); break; }
case triangle: { s.push_back(new Triangle(Point(x, y), 40)); break; }
case hexagon: { s.push_back(new Hexagon(Point(x, y), 20)); break; }
}

ostringstream ss;
ss << '(' << x << ',' << y << ')';
xy_out.put(ss.str());

attach(s[s.size() - 1]);
redraw();
}
}

void Shapes_window::quit()
{
hide();
}

{
reference_to<Shapes_window>(pw).draw_shape(circle);
}

{
reference_to<Shapes_window>(pw).draw_shape(square);
}

{
reference_to<Shapes_window>(pw).draw_shape(triangle);
}

{
reference_to<Shapes_window>(pw).draw_shape(hexagon);
}

{
}

{
reference_to<Shapes_window>(pw).quit();
}

int main()
try
{
Shapes_window win(Point(100, 100), xmax, ymax, "lines");
return gui_main();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}

catch (...) {
cerr << "Unknown exception!\n";
keep_window_open();
return 2;
}
```

This site uses Akismet to reduce spam. Learn how your comment data is processed.