#ifndef GRAPH_GUARD #define GRAPH_GUARD 1 #include "Point.h" #include //#include //#include #include "fltk.h" #include "std_lib_facilities.h" namespace Graph_lib { // defense against ill-behaved Linux macros: #undef major #undef minor struct Color { enum Color_type { red=FL_RED, blue=FL_BLUE, green=FL_GREEN, yellow=FL_YELLOW, white=FL_WHITE, black=FL_BLACK, magenta=FL_MAGENTA, cyan=FL_CYAN, dark_red=FL_DARK_RED, dark_green=FL_DARK_GREEN, dark_yellow=FL_DARK_YELLOW, dark_blue=FL_DARK_BLUE, dark_magenta=FL_DARK_MAGENTA, dark_cyan=FL_DARK_CYAN }; enum Transparency { invisible = 0, visible=255 }; Color(Color_type cc) :c{Fl_Color(cc)}, v{visible} { } // Color(Color_type cc, Transparency vv) :c{Fl_Color(cc)}, v{vv} { } Color(Color_type cc, Transparency vv) : c{Fl_Color(cc)}, v{static_cast(vv)} { } Color(int cc) :c{Fl_Color(cc)}, v{visible} { } // Color(Transparency vv) :c{Fl_Color()}, v{vv} { } Color(Transparency vv) :c{Fl_Color()}, v{static_cast(vv)} { } int as_int() const { return c; } char visibility() const { return v; } void set_visibility(Transparency vv) { v=vv; } private: Fl_Color c; unsigned char v; // 0 or 1 for now }; struct Line_style { enum Line_style_type { solid=FL_SOLID, // ------- dash=FL_DASH, // - - - - dot=FL_DOT, // ....... dashdot=FL_DASHDOT, // - . - . dashdotdot=FL_DASHDOTDOT, // -..-.. }; Line_style(Line_style_type ss) :s{ss}, w{0} { } Line_style(Line_style_type lst, int ww) :s{lst}, w{ww} { } Line_style(int ss) :s{ss}, w{0} { } int width() const { return w; } int style() const { return s; } private: int s; int w; }; class Font { public: enum Font_type { helvetica=FL_HELVETICA, helvetica_bold=FL_HELVETICA_BOLD, helvetica_italic=FL_HELVETICA_ITALIC, helvetica_bold_italic=FL_HELVETICA_BOLD_ITALIC, courier=FL_COURIER, courier_bold=FL_COURIER_BOLD, courier_italic=FL_COURIER_ITALIC, courier_bold_italic=FL_COURIER_BOLD_ITALIC, times=FL_TIMES, times_bold=FL_TIMES_BOLD, times_italic=FL_TIMES_ITALIC, times_bold_italic=FL_TIMES_BOLD_ITALIC, symbol=FL_SYMBOL, screen=FL_SCREEN, screen_bold=FL_SCREEN_BOLD, zapf_dingbats=FL_ZAPF_DINGBATS }; Font(Font_type ff) :f{ff} { } Font(int ff) :f{ff} { } int as_int() const { return f; } private: int f; }; template class Vector_ref { vector v; vector owned; public: Vector_ref() {} Vector_ref(T* a, T* b=0, T* c=0, T* d=0) { if (a) push_back(a); if (b) push_back(b); if (c) push_back(c); if (d) push_back(d); } ~Vector_ref() { for (unsigned i=0; i; class Shape { // deals with color and style, and holds sequence of lines protected: // Shape(); Shape(initializer_list lst); // add() the Points to this Shape Shape() : // lcolor(fl_color()), lcolor{static_cast(fl_color())}, ls{0}, fcolor{Color::invisible} { } void add(Point p){ points.push_back(p); } void set_point(int i, Point p) { points[i] = p; } public: void draw() const; // deals with color and draw_lines protected: virtual void draw_lines() const; // simply draw the appropriate lines public: virtual void move(int dx, int dy); // move the shape +=dx and +=dy void set_color(Color col) { lcolor = col; } Color color() const { return lcolor; } void set_style(Line_style sty) { ls = sty; } Line_style style() const { return ls; } void set_fill_color(Color col) { fcolor = col; } Color fill_color() const { return fcolor; } Point point(int i) const { return points[i]; } int number_of_points() const { return int(points.size()); } virtual ~Shape() { } /* struct Window* attached; Shape(const Shape& a) :attached(a.attached), points(a.points), line_color(a.line_color), ls(a.ls) { if (a.attached)error("attempt to copy attached shape"); } */ Shape(const Shape&) = delete; Shape& operator=(const Shape&) = delete; private: vector points; // not used by all shapes Color lcolor; Line_style ls {0}; Color fcolor {Color::invisible}; // Shape(const Shape&); // Shape& operator=(const Shape&); }; // graph f(x) for x in [r1:r2) using count line segments // with (0,0) displayed at xy // x coordinates are scaled by xscale and y coordinates scaled by yscale // // Note that f can be either a function or a lambda. // Solution courtesy of Jordan Harris struct Function : Shape { // the function parameters are not stored template Function(Fct f, double r1, double r2, Point xy, int count = 100, double xscale = 25, double yscale = 25) { if (r2-r1<=0) error("bad graphing range"); if (count<=0) error("non-positive graphing count"); double dist = (r2-r1)/count; double r = r1; for (int i = 0; i lst) : Shape{lst} { if (lst.size() % 2) error("odd number of points for Lines"); } void draw_lines() const; void add(Point p1, Point p2) { Shape::add(p1); Shape::add(p2); } }; struct Text : Shape { // the point is the bottom left of the first letter //Text(Point x, const string& s) : lab{ s } { add(x); } Text(Point x, const string& s) : lab{s}, fnt{fl_font()}, fnt_sz{fl_size()} { add(x); } void draw_lines() const; void set_label(const string& s) { lab = s; } string label() const { return lab; } void set_font(Font f) { fnt = f; } Font font() const { return Font(fnt); } void set_font_size(int s) { fnt_sz = s; } int font_size() const { return fnt_sz; } private: string lab; // label Font fnt{ fl_font() }; int fnt_sz{ (14draw(point(0).x,point(0).y); } private: // define "masking box" within image relative to position (cx,cy) int w,h,cx,cy; Fl_Image* p; Text fn; }; } #endif