button changing random location on click [fltk]

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

```Output:

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

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

inline int rand_int(int min, int max)
{
static default_random_engine ran;
return uniform_int_distribution<>(min, max)(ran);
}

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

struct My_window : Window {
My_window(Point xy, int w, int h, const string& title)
: Window(xy, w, h, title),
next_button_pushed(false),
next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
quit_button_pushed(false),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
{
attach(next_button);
attach(quit_button);
}

void wait_for_button()
{
while (!next_button_pushed) Fl::wait();
next_button_pushed = false;
Fl::redraw();
}

Button next_button;
Button quit_button;

private:
bool next_button_pushed;
bool quit_button_pushed;

{
}

{
}

void next() { next_button_pushed = true; }
void quit() { hide(); }
};

struct Random_button_win : My_window
{
Random_button_win(Point xy, int w, int h, const string& title, const string& url)
:My_window(xy, w, h, title),
url(url),
rand_button(Point(xmax/2, ymax/2), 40, 40, "", cb_rand),
button_image(Point(xmax / 2, ymax / 2), url)
{
attach(rand_button);
button_image.set_mask(Point(xmax / 2, ymax / 2), 40, 40);
attach(button_image);
}

Button rand_button;
Image button_image;

private:
string url;

{
}

void change_button_pos()
{
rand_button.hide();

int current_x = rand_button.loc.x;
int current_y = rand_button.loc.y;

int new_x = rand_int(0, xmax - 40) - current_x;
int new_y = rand_int(20, ymax - 40) - current_y;

rand_button.move(new_x, new_y);
button_image.move(new_x, new_y);
redraw();
}
};

int main()
try
{
Random_button_win win(Point(100, 100), xmax, ymax + 20, "random buttons window", "Data/supercell.jpg");
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;
}
```

checker board square buttons [fltk]

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

```Output:

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

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

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

struct My_window : Window {
My_window(Point xy, int w, int h, const string& title)
: Window(xy, w, h, title),
next_button_pushed(false),
next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
quit_button_pushed(false),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
{
attach(next_button);
attach(quit_button);
}

void wait_for_button()
// modified event loop
// handle all events (as per default), but quit when button_pushed becomes true
// this allows graphics without control inversion
{
while (!next_button_pushed) Fl::wait();
next_button_pushed = false;
Fl::redraw();
}

Button next_button;
Button quit_button;

private:
bool next_button_pushed;
bool quit_button_pushed;

//	{ reference_to<Simple_window>(addr).next(); }
{
}

//	{ reference_to<Simple_window>(addr).quit(); }
{
}

void next() { next_button_pushed = true; }
void quit() { hide(); }
};

struct cheker_board_buttons : My_window
{
cheker_board_buttons(Point xy, int w, int h, const string& title)
:My_window(xy, w, h, title)
{
int x_size = xmax / 4;
int y_size = ymax / 4;

// initialize buttons
buttons.push_back(new Button(Point(0, 20), x_size, y_size, "b0", cb_change_0));
buttons.push_back(new Button(Point(x_size, 20), x_size, y_size, "b1", cb_change_1));
buttons.push_back(new Button(Point(x_size * 2, 20), x_size, y_size, "b2", cb_change_2));
buttons.push_back(new Button(Point(x_size * 3, 20), x_size, y_size, "b3", cb_change_3));
buttons.push_back(new Button(Point(0, y_size + 20), x_size, y_size, "b4", cb_change_4));
buttons.push_back(new Button(Point(x_size, y_size + 20), x_size, y_size, "b5", cb_change_5));
buttons.push_back(new Button(Point(x_size * 2, y_size + 20), x_size, y_size, "b6", cb_change_6));
buttons.push_back(new Button(Point(x_size * 3, y_size + 20), x_size, y_size, "b7", cb_change_7));
buttons.push_back(new Button(Point(0, y_size * 2 + 20), x_size, y_size, "b8", cb_change_8));
buttons.push_back(new Button(Point(x_size, y_size * 2 + 20), x_size, y_size, "b9", cb_change_9));
buttons.push_back(new Button(Point(x_size * 2, y_size * 2 + 20), x_size, y_size, "b10", cb_change_10));
buttons.push_back(new Button(Point(x_size * 3, y_size * 2 + 20), x_size, y_size, "b11", cb_change_11));
buttons.push_back(new Button(Point(0, y_size * 3 + 20), x_size, y_size, "b12", cb_change_12));
buttons.push_back(new Button(Point(x_size, y_size * 3 + 20), x_size, y_size, "b13", cb_change_13));
buttons.push_back(new Button(Point(x_size * 2, y_size * 3 + 20), x_size, y_size, "b14", cb_change_14));
buttons.push_back(new Button(Point(x_size * 3, y_size * 3 + 20), x_size, y_size, "b15", cb_change_15));

// attach buttons
for (int i = 0; i < buttons.size(); i++) { attach(buttons[i]); }
}

// button setup
Vector_ref<Button> buttons;
int last = 16;
void reset_button() { if(last != 16) { buttons[last].show(); } }

// button behaviour
void change_b0() { reset_button(); last = 0; buttons[0].hide(); };
void change_b1() { reset_button(); last = 1; buttons[1].hide(); };
void change_b2() { reset_button(); last = 2; buttons[2].hide(); };
void change_b3() { reset_button(); last = 3; buttons[3].hide(); };
void change_b4() { reset_button(); last = 4; buttons[4].hide(); };
void change_b5() { reset_button(); last = 5; buttons[5].hide(); };
void change_b6() { reset_button(); last = 6; buttons[6].hide(); };
void change_b7() { reset_button(); last = 7; buttons[7].hide(); };
void change_b8() { reset_button(); last = 8; buttons[8].hide(); };
void change_b9() { reset_button(); last = 9; buttons[9].hide(); };
void change_b10() { reset_button(); last = 10; buttons[10].hide(); };
void change_b11() { reset_button(); last = 11; buttons[11].hide(); };
void change_b12() { reset_button(); last = 12; buttons[12].hide(); };
void change_b13() { reset_button(); last = 13; buttons[13].hide(); };
void change_b14() { reset_button(); last = 14; buttons[14].hide(); };
void change_b15() { reset_button(); last = 15; buttons[15].hide(); };

private:
vector<bool> pressed;

// call back functions
};

int main()
try
{
cheker_board_buttons win(Point(100, 100), xmax, ymax + 20, "checker board buttons");
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;
}
```

exploring the window class [fltk]

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

```Output:

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

#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;

struct My_window : Window {
My_window(Point xy, int w, int h, const string& title)
: Window(xy, w, h, title),
next_button_pushed(false),
next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
quit_button_pushed(false),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
{
attach(next_button);
attach(quit_button);
}

void wait_for_button()
// modified event loop
// handle all events (as per default), but quit when button_pushed becomes true
// this allows graphics without control inversion
{
while (!next_button_pushed) Fl::wait();
next_button_pushed = false;
Fl::redraw();
}

Button next_button;
Button quit_button;

private:
bool next_button_pushed;
bool quit_button_pushed;

//	{ reference_to<Simple_window>(addr).next(); }
{
}

//	{ reference_to<Simple_window>(addr).quit(); }
{
}

void next() { next_button_pushed = true; }
void quit() { hide(); }
};

int main()
try
{
My_window win(Point(100, 100), xmax, ymax, "quit+next");
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;
}
```

line drawing program + color & linestyle menu [fltk]

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

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Drill 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;

struct Lines_window : Window {
Lines_window(Point xy, int w, int h, const string& title);
private:
// data
Open_polyline lines;

// widgets
Button next_button;	// add (next_x, next_y) to lines
Button quit_button;	// end program
In_box next_x;
In_box next_y;
Out_box xy_out;

void change_color(Color c) { lines.set_color(c); }

// line style menu
void change_line_style(Line_style ls) { lines.set_style(ls); }

// actions invoked by callbacks
void red_pressed() { change_color(Color::red); hide_color_menu(); }
void blue_pressed() { change_color(Color::blue); hide_color_menu(); }
void black_pressed() { change_color(Color::black); hide_color_menu(); }

// line style menu
void solid_pressed() { change_line_style(Line_style::solid); hide_line_style_menu(); }
void dashed_pressed() { change_line_style(Line_style::dash); hide_line_style_menu(); }
void dotted_pressed() { change_line_style(Line_style::dot); hide_line_style_menu(); }

void next();
void quit();

// callback functions
// color

// line style

};

Lines_window::Lines_window(Point xy, int w, int h, const string& title)
:Window(xy, w, h, title),
next_button(Point(x_max() - 150, 0), 70, 20, "Next point", cb_next),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
next_x(Point(x_max() - 310, 0), 50, 20, "next x:"),
next_y(Point(x_max() - 210, 0), 50, 20, "next y:"),
xy_out(Point(100, 0), 100, 20, "current (x,y):"),
color_menu(Point(x_max() - 70, 30), 70, 20, Menu::vertical, "color"),
line_style_menu(Point(x_max() - 70, 90), 70, 20, Menu::vertical, "line style"),
{
attach(next_button);
attach(quit_button);
attach(next_x);
attach(next_y);
attach(xy_out);

// initialize out box and line color
xy_out.put("no point");
lines.set_color(Color::black);

color_menu.attach(new Button(Point(0, 0), 0, 0, "red", cb_red));
color_menu.attach(new Button(Point(0, 0), 0, 0, "blue", cb_blue));
color_menu.attach(new Button(Point(0, 0), 0, 0, "black", cb_black));

line_style_menu.attach(new Button(Point(0, 0), 0, 0, "solid", cb_solid));
line_style_menu.attach(new Button(Point(0, 0), 0, 0, "dashed", cb_dash));
line_style_menu.attach(new Button(Point(0, 0), 0, 0, "dotted", cb_dot));

attach(lines);
}

void Lines_window::next()
{
int x = next_x.get_int();
int y = next_y.get_int();

// update current position readout
ostringstream ss;
ss << '(' << x << ',' << y << ')';
xy_out.put(ss.str());

redraw();
}

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

// color callback
{
reference_to<Lines_window>(pw).red_pressed();
}

{
reference_to<Lines_window>(pw).blue_pressed();
}

{
reference_to<Lines_window>(pw).black_pressed();
}

{
}

// line style callback
{
reference_to<Lines_window>(pw).solid_pressed();
}

{
reference_to<Lines_window>(pw).dashed_pressed();
}

{
reference_to<Lines_window>(pw).dotted_pressed();
}

{
}

// next + quit callback
{
reference_to<Lines_window>(pw).next();
}

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

int main()
try
{
Lines_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;
}
```

line drawing program + color menu [fltk]

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

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Drill 3

#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;

struct Lines_window : Window {
Lines_window(Point xy, int w, int h, const string& title);
private:
// data
Open_polyline lines;

// widgets
Button next_button;	// add (next_x, next_y) to lines
Button quit_button;	// end program
In_box next_x;
In_box next_y;
Out_box xy_out;

void change(Color c) { lines.set_color(c); }

// actions invoked by callbacks
void red_pressed() { change(Color::red); hide_menu(); }
void blue_pressed() { change(Color::blue); hide_menu(); }
void black_pressed() { change(Color::black); hide_menu(); }
void next();
void quit();

// callback functions
};

Lines_window::Lines_window(Point xy, int w, int h, const string& title)
:Window(xy, w, h, title),
next_button(Point(x_max() - 150, 0), 70, 20, "Next point", cb_next),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
next_x(Point(x_max() - 310, 0), 50, 20, "next x:"),
next_y(Point(x_max() - 210, 0), 50, 20, "next y:"),
xy_out(Point(100, 0), 100, 20, "current (x,y):"),
color_menu(Point(x_max() - 70, 30), 70, 20, Menu::vertical, "color"),
{
attach(next_button);
attach(quit_button);
attach(next_x);
attach(next_y);
attach(xy_out);
xy_out.put("no point");
color_menu.attach(new Button(Point(0, 0), 0, 0, "red", cb_red));
color_menu.attach(new Button(Point(0, 0), 0, 0, "blue", cb_blue));
color_menu.attach(new Button(Point(0, 0), 0, 0, "black", cb_black));
attach(lines);
}

void Lines_window::next()
{
int x = next_x.get_int();
int y = next_y.get_int();

// update current position readout
ostringstream ss;
ss << '(' << x << ',' << y << ')';
xy_out.put(ss.str());

redraw();
}

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

{
reference_to<Lines_window>(pw).red_pressed();
}

{
reference_to<Lines_window>(pw).blue_pressed();
}

{
reference_to<Lines_window>(pw).black_pressed();
}

{
}

{
reference_to<Lines_window>(pw).next();
}

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

int main()
try
{
Lines_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;
}
```

line drawing program [fltk]

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

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Drill 2

#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;

struct Lines_window : Window {
Lines_window(Point xy, int w, int h, const string& title);
private:
// data
Open_polyline lines;

// widgets
Button next_button;	// add (next_x, next_y) to lines
Button quit_button;	// end program
In_box next_x;
In_box next_y;
Out_box xy_out;

// actions invoked by callbacks
void next();
void quit();

// callback functions
};

Lines_window::Lines_window(Point xy, int w, int h, const string& title)
:Window(xy, w, h, title),
next_button(Point(x_max() - 150, 0), 70, 20, "Next point", cb_next),
quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
next_x(Point(x_max() - 310, 0), 50, 20, "next x:"),
next_y(Point(x_max() - 210, 0), 50, 20, "next y:"),
xy_out(Point(100, 0), 100, 20, "current (x,y):")
{
attach(next_button);
attach(quit_button);
attach(next_x);
attach(next_y);
attach(xy_out);
xy_out.put("no point");
lines.set_color(Color::black);
attach(lines);
}

void Lines_window::next()
{
int x = next_x.get_int();
int y = next_y.get_int();

// update current position readout
ostringstream ss;
ss << '(' << x << ',' << y << ')';
xy_out.put(ss.str());

redraw();
}

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

{
reference_to<Lines_window>(pw).next();
}

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

int main()
try
{
Lines_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;
}
```

Graphical user interface – Fast Light Toolkit [FLTK]

What is FLTK? As described on fltk.org:

“FLTK (pronounced “fulltick”) is a cross-platform C++ GUI toolkit for UNIX®/Linux® (X11), Microsoft® Windows®, and MacOS® X. FLTK provides modern GUI functionality without the bloat and supports 3D graphics via OpenGL® and its built-in GLUT emulation.
FLTK is designed to be small and modular enough to be statically linked, but works fine as a shared library. FLTK also includes an excellent UI builder called FLUID that can be used to create applications in minutes.”

How to install FLTK under Visual Stduio 2017 Community
How to compile FLTK – [following the instruction of fltk.org] This approach apparently prevents cross-contamination. Instead of copying files and folders from fltk-1.3.4 to the Visual Studio Community 2017 folder structure, the include and library paths are propperly (I hope so!) added to the project.
How to compile FLTK – [following the instruction of Principles and Practice using C++]

FLTK Examples:
Chapter 12 – A Display Model [using FLTK]
Chapter 13 – Graphics Classes [using FLTK]
Chapter 14 – Graphics Class Design [using FLTK]
Chapter 15 – Graphing Functions and Data [using FLTK]
Chapter 16 – Graphical User Interface [using FLTK]

Average temperature data of Cambridge, England and Cambridge, Massachusetts graphing [fltk]

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

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 15 Exercise 11

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

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

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

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 2;
constexpr int y_scale = 2;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, xmax, ymax, "Function graphs");

// x axis
Axis x(Axis::x, Point(xoffset, ymax - yoffset), xlength, 12,
"month    Jan  Feb   Mar  Apr  May  Jun   Jul    Aug  Sep  Oct  Nov   Dec");
x.set_color(Color::black);
x.label.move(-100, 0);
win.attach(x);

// y axis
Axis y(Axis::y, Point(yoffset, ymax - yoffset), ylength, 20, "temperature in 0 - 20 C");
y.set_color(Color::black);
win.attach(y);

// data
// Cambridge, England monthly normal weather 2016
vector<double> camb_eng_temp = {
3.7,
3.8,
6.1,
8.0,
11.4,
14.3,
16.8,
16.9,
14.1,
10.5,
6.5,
4.7
};

// Cambridge, Massachusetts monthly normal weather 2016
vector<double> camb_mas_temp = {
-1.9,
-0.9,
3.7,
8.9,
14.6,
19.8,
23.1,
22.2,
18.2,
12.7,
7.4,
0.9
};

// graph
Open_polyline cet; // Cambridge, England
Open_polyline cmt; // Cambridge, Massachusetts

for (int i = 0; i < 12; i++) {
cet.add(Point(xoffset + i * (xlength / 12), (yspace + ylength) - camb_eng_temp[i] * 20));
cmt.add(Point(xoffset + i * (xlength / 12), (yspace + ylength) - camb_mas_temp[i] * 20));
}

cet.set_color(Color::red);
win.attach(cet);

cmt.set_color(Color::blue);
win.attach(cmt);

win.wait_for_button();
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}

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

labeled points data graphing [fltk]

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

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 15 Exercise 10

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

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

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

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 2;
constexpr int y_scale = 2;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

class bar_graph : public Shape
{
public:
bar_graph(Point origin, vector<Point>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, Color col, string label);

void draw_lines() const;

vector<Point>& get_data() { return data; }

private:
Point origin;
vector<Point>& data;

int x_scale;
int r1_min;
int r1_max;

int y_scale;
int r2_min;
int r2_max;

int bar_width;

Color col;
string label;
};

bar_graph::bar_graph(Point origin, vector<Point>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, Color col, string label)
: origin(origin),
data(data),
x_scale(x_scale),
r1_min(r1_min),
r1_max(r1_max),
y_scale(y_scale),
r2_min(r2_min),
r2_max(r2_max),
bar_width(bar_width),
col(col),
label(label)
{

}

void bar_graph::draw_lines() const
{
int ds = data.size();
cout << ds << endl;

for (int i = 0; i < data.size(); i++) {

int h = data[i].x;
int c = data[i].y;

// scale factor
double sx = (xlength / 2.0) / (r1_max - r1_min);
double sy = (ylength / 2.0) / (r2_max - r2_min);

// draw point
Point p(origin.x + (h - r1_min) * sx, origin.y - (c - r2_min) * sy);
cout << p << endl;

Graph_lib::Circle crcl(p, 3);
crcl.set_color(col);
crcl.set_fill_color(col);
crcl.draw();

// draw label
string point_label = "(" + to_string(data[i].x) + "," + to_string(data[i].y) + ")";
Text l(p, point_label);
l.set_color(Color::red);

l.draw();

}

// graph label
Text gl(Point(origin.x - 90, origin.y + 15), label);
gl.set_color(col);

gl.draw();
}

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, xmax, ymax, "Function graphs.");

int r1_min = 170;
int r1_max = 180;

int r2_min = 7;
int r2_max = 23;

// notch label x
string x_notch = "1 == " + to_string((r1_max - r1_min) / 10);

// notch label y
ostringstream strs;
strs << setprecision(2) << (r2_max - r2_min) / 10.0;
string y_notch = "1 == " + strs.str();

// x axis
Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, x_notch);
x.set_color(Color::black);
win.attach(x);

// y axis
Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, y_notch);
y.set_color(Color::black);
win.attach(y);

// people height data
vector<Point> d = {
Point(170, 7),
Point(175, 9),
Point(180, 23),
Point(173, 8),
Point(178, 20),
Point(177, 15),
Point(171, 10),
Point(174, 19)
};

// bar graph
bar_graph bg(orig, d, x_scale, r1_min, r1_max, y_scale, r2_min, r2_max, Color::blue, "labeled points");
win.attach(bg);

win.wait_for_button();
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}

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

bar graph – group of people height data graphing [fltk]

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

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 15 Exercise 8

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

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

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

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 2;
constexpr int y_scale = 2;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

struct ppl_height
{
ppl_height(double height, int count)
:height(height), count(count) {	}
double height;
int count;
};

void read_data(string location, vector<ppl_height>& v)
{
ifstream ist(location);
if (!ist) { error("no such file exists", location); }

char comma;
double height;
int count;

while (ist >> height >> comma >> count)
{
if (ist.eof()) {
break;
}
v.push_back(ppl_height(height, count));
}

}

class bar_graph : public Shape
{
public:
bar_graph(Point origin, vector<ppl_height>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, int bar_width, Color col, string label);

void draw_lines() const;

vector<ppl_height>& get_data() { return data; }

private:
Point origin;
vector<ppl_height>& data;

int x_scale;
int r1_min;
int r1_max;

int y_scale;
int r2_min;
int r2_max;

int bar_width;

Color col;
string label;
};

bar_graph::bar_graph(Point origin, vector<ppl_height>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, int bar_width, Color col, string label)
:	origin(origin),
data(data),
x_scale(x_scale),
r1_min(r1_min),
r1_max(r1_max),
y_scale(y_scale),
r2_min(r2_min),
r2_max(r2_max),
bar_width(bar_width),
col(col),
label(label)
{

}

void bar_graph::draw_lines() const
{
int ds = data.size();

for (int i = 0; i < data.size(); i++) {

double w = double(bar_width / 2);
int h = data[i].height;
int c = data[i].count;

// scale factor
double sx = (xlength / 2.0) / (r1_max - r1_min);
double sy = (ylength / 2.0) / (r2_max - r2_min);

Point p0(origin.x + (h - r1_min) * sx - w, origin.y - c * sy);
Point p1(origin.x + (h - r1_min) * sx + w, origin.y);

Graph_lib::Rectangle r(p0, p1);

r.set_color(col);
r.set_fill_color(col);

r.draw();

// bar labels
string hl = to_string((int)data[i].height);
Text height_label(Point(p1.x - bar_width, p1.y + 15), hl);
height_label.set_color(col);
height_label.draw();

string cl = to_string((int)data[i].count);
Text count_label(Point(p0.x, p0.y - 10), cl);
count_label.set_color(col);
count_label.draw();

}

// graph label
Text gl(Point(origin.x - 70, origin.y + 15), label);
gl.set_color(col);

gl.draw();
}

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, xmax, ymax, "Function graphs.");

int r1_min = 160;
int r1_max = 200;

int r2_min = 5;
int r2_max = 30;

int bar_width = 15;

// notch label x
string x_notch = "1 == " + to_string((r1_max - r1_min) / 10);

// notch label y
ostringstream strs;
strs << setprecision(2) << (r2_max - r2_min) / 10.0;
string y_notch = "1 == " + strs.str();

// x axis
Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, x_notch);
x.set_color(Color::black);
win.attach(x);

// y axis
Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, y_notch);
y.set_color(Color::black);
win.attach(y);

// people height data
vector<ppl_height> d = {	ppl_height(170, 7),
ppl_height(175, 9),
ppl_height(180, 23),
ppl_height(185, 17),
ppl_height(190, 6),
ppl_height(195, 1)
};

// stream data from file
vector<ppl_height> dff;
string location = "input/height_data.txt";

// bar graph
bar_graph bg(orig, dff, x_scale, r1_min, r1_max, y_scale, r2_min, r2_max, bar_width, Color::blue, "bar graph");
win.attach(bg);

win.wait_for_button();
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}

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