Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
toy-framework-2.h
Go to the documentation of this file.
1
2#ifndef _2GEOM_TOY_FRAMEWORK2_H_
3#define _2GEOM_TOY_FRAMEWORK2_H_
4
5
6
7#include <cairo.h>
8#include <gtk/gtk.h>
9#include <iostream>
10#include <optional>
11#include <sstream>
12#include <string>
13#include <utility>
14#include <vector>
15
16#include <assert.h>
17#include <2geom/exception.h>
18#include <2geom/point.h>
19#include <2geom/geom.h>
20#include <2geom/sbasis.h>
21#include <2geom/d2.h>
22#include <sched.h>
23#include <toys/path-cairo.h>
24
25using std::vector;
26
27//Utility functions
28double uniform();
29
30void draw_text(cairo_t *cr, Geom::Point pos, const char* txt, bool bottom = false, const char* fontdesc = "Sans");
31void draw_text(cairo_t *cr, Geom::Point pos, const std::string& txt, bool bottom = false, const std::string& fontdesc = "Sans");
32void draw_number(cairo_t *cr, Geom::Point pos, int num, std::string name=std::string(), bool bottom = true);
33void draw_number(cairo_t *cr, Geom::Point pos, unsigned num, std::string name=std::string(), bool bottom = true);
34void draw_number(cairo_t *cr, Geom::Point pos, double num, std::string name=std::string(), bool bottom = true);
35
36struct colour{
37 double r,g,b,a;
38 colour(double r, double g, double b, double a) : r(r), g(g), b(b), a(a) {}
39 static colour from_hsv( float H, // hue shift (radians)
40 float S, // saturation shift (scalar)
41 float V, // value multiplier (scalar)
42 float A
43 );
44 static colour from_hsl( float H, // hue shift (radians)
45 float S, // saturation shift (scalar)
46 float L, // value multiplier (scalar)
47 float A
48 );
49};
51
52class Handle{
53public:
54 std::string name;
55 float rgb[3];
56 Handle() {rgb[0] = rgb[1] = rgb[2] = 0;}
57 virtual ~Handle() {}
58 virtual void draw(cairo_t *cr, bool annotes=false) = 0;
59
60 virtual void* hit(Geom::Point pos) = 0;
61 virtual void move_to(void* hit, Geom::Point om, Geom::Point m) = 0;
62 virtual void load(FILE* f)=0;
63 virtual void save(FILE* f)=0;
64};
65
66class Toggle : public Handle{
67public:
69 const char* text;
70 bool on;
71 Toggle() : bounds(Geom::Point(0,0), Geom::Point(0,0)), text(""), on(false) {}
72 Toggle(const char* txt, bool v) : bounds(Geom::Point(0,0), Geom::Point(0,0)), text(txt), on(v) {}
73 Toggle(Geom::Rect bnds, const char* txt, bool v) : bounds(bnds), text(txt), on(v) {}
74 void draw(cairo_t *cr, bool annotes = false) override;
75 void toggle();
76 void set(bool state);
77 void handle_click(Geom::Point const &pos, unsigned button);
78 void* hit(Geom::Point pos) override;
79 void move_to(void* /*hit*/, Geom::Point /*om*/, Geom::Point /*m*/) override { /* not implemented */ }
80 void load(FILE* /*f*/) override { /* not implemented */ }
81 void save(FILE* /*f*/) override { /* not implemented */ }
82};
83
84
85template< typename T>
86class VectorHandle : public Handle
87{
88 public:
90 : m_handles()
91 {
92 }
93 void draw(cairo_t *cr, bool annotes=false) override
94 {
95 for (iterator it = m_handles.begin(); it != m_handles.end(); ++it)
96 it->draw(cr, annotes);
97 }
98
99 void* hit(Geom::Point pos) override
100 {
101 void* result = NULL;
102 for (iterator it = m_handles.begin(); it != m_handles.end(); ++it)
103 {
104 result = it->hit(pos);
105 if (result != NULL) break;
106 }
107 return result;
108 }
109
110 void move_to(void* hit, Geom::Point om, Geom::Point m) override
111 {
112 if (hit != NULL)
113 {
114 static_cast<T*>(hit)->move_to(hit, om, m);
115 }
116 }
117
118 void load(FILE* f) override
119 {
120 for (iterator it = m_handles.begin(); it != m_handles.end(); ++it)
121 it->load(f);
122 }
123
124 void save(FILE* f) override
125 {
126 for (iterator it = m_handles.begin(); it != m_handles.end(); ++it)
127 it->save(f);
128 }
129
130 void clear()
131 {
132 m_handles.clear();
133 }
134
135 void reserve(size_t sz)
136 {
137 m_handles.reserve(sz);
138 }
139
140 size_t size() const
141 {
142 return m_handles.size();
143 }
144
145 void push_back (const T& _handle)
146 {
147 m_handles.push_back(_handle);
148 }
149
150 const T& operator[] (size_t i) const
151 {
152 return m_handles.at(i);
153 }
154
155 T& operator[] (size_t i)
156 {
157 return m_handles.at(i);
158 }
159
160 private:
161 typedef typename std::vector<T>::iterator iterator;
162 std::vector<T> m_handles;
163}; // end class VectorHandle
164
165
166class PointHandle : public Handle{
167public:
168 PointHandle(double x, double y) : pos(x,y) {}
172 void draw(cairo_t *cr, bool annotes = false) override;
173
174 void* hit(Geom::Point mouse) override;
175 void move_to(void* hit, Geom::Point om, Geom::Point m) override;
176 void load(FILE* f) override;
177 void save(FILE* f) override;
178};
179
180class PointSetHandle : public Handle{
181public:
183 std::vector<Geom::Point> pts;
184 void draw(cairo_t *cr, bool annotes = false) override;
185
186 void* hit(Geom::Point mouse) override;
187 void move_to(void* hit, Geom::Point om, Geom::Point m) override;
188 void push_back(double x, double y) {pts.emplace_back(x,y);}
189 void push_back(Geom::Point pt) {pts.push_back(pt);}
190 unsigned size() {return pts.size();}
192 void load(FILE* f) override;
193 void save(FILE* f) override;
194};
195
196class RectHandle : public Handle{
197public:
202 void draw(cairo_t *cr, bool annotes = false) override;
203
204 void* hit(Geom::Point mouse) override;
205 void move_to(void* hit, Geom::Point om, Geom::Point m) override;
206 void load(FILE* f) override;
207 void save(FILE* f) override;
208};
209
210
211// used by Slider
212inline std::string default_formatter(double x)
213{
214 std::ostringstream os;
215 os << x;
216 return os.str();
217}
218
219class Slider : public Handle
220{
221 public:
222
223 typedef std::string (*formatter_t) (double );
224 typedef double value_type;
225
227 : m_handle(), m_pos(Geom::Point(0,0)), m_length(1),
228 m_min(0), m_max(1), m_step(0), m_dir(Geom::X),
230 {
231 value(0);
232 }
233
234 // pass step = 0 for having a continuos value variation
236 value_type _value, std::string _label = "" )
237 : m_handle(),m_pos(Geom::Point(0,0)), m_length(1),
238 m_min(_min), m_max(_max), m_step(_step), m_dir(Geom::X),
239 m_label(std::move(_label)), m_formatter(&default_formatter)
240 {
241 value(_value);
242 }
243
244 void set( value_type _min, value_type _max, value_type _step,
245 value_type _value, const std::string& _label = "" )
246 {
247 m_min = _min;
248 m_max = _max;
249 m_step = _step;
250 m_label = _label;
251 value(_value);
252 }
253
254 value_type value() const;
255
256 void value(value_type _value);
257
259 {
260 return m_max;
261 }
262
263 void max_value(value_type _value);
264
266 {
267 return m_min;
268 }
269
270 void min_value(value_type _value);
271
272 // dir = X horizontal slider dir = Y vertical slider
273 void geometry(Geom::Point _pos, value_type _length, Geom::Dim2 _dir = Geom::X);
274
275 void draw(cairo_t* cr, bool annotate = false) override;
276
277 void formatter( formatter_t _formatter )
278 {
279 m_formatter = _formatter;
280 }
281
282 void* hit(Geom::Point pos) override
283 {
284 if (m_handle.hit(pos) != NULL)
285 return this;
286 return NULL;
287 }
288
289 void move_to(void* hit, Geom::Point om, Geom::Point m) override;
290
291 void load(FILE* f) override
292 {
293 m_handle.load(f);
294 }
295
296 void save(FILE* f) override
297 {
298 m_handle.save(f);
299 }
300
301 private:
306 int m_dir;
307 std::string m_label;
309};
310
311
312
313
314
315class Toy {
316public:
317 vector<Handle*> handles;
318 bool mouse_down = false;
320 Handle* selected = nullptr;
321 void* hit_data = nullptr;
323 double notify_offset = 0.0;
324 std::string name;
325 bool show_timings = false;
326 FILE* spool_file = nullptr; // if non-NULL we record all interactions to this file
327
328 Toy() {}
329
330 virtual ~Toy() {}
331
332 virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream);
333
334 virtual void mouse_moved(Geom::Point const &pos, unsigned modifiers);
335 virtual void mouse_pressed(Geom::Point const &pos, unsigned button, unsigned modifiers);
336 virtual void mouse_released(Geom::Point const &pos, unsigned button, unsigned modifiers);
337 virtual void canvas_click(Geom::Point at, int button);
338 virtual void scroll(GdkScrollDirection dir, Geom::Point const &delta);
339
340 virtual void key_hit(unsigned keyval, unsigned modifiers) {}
341
342 //Cheapo way of informing the framework what the toy would like drawn for it.
343 virtual bool should_draw_numbers() { return true; }
344 virtual int should_draw_bounds() { return 0; }
345
346 virtual void first_time(int /*argc*/, char** /*argv*/) {}
347
348 virtual void resize_canvas(Geom::Rect const & /*s*/) {}
349 virtual void load(FILE* f);
350 virtual void save(FILE* f);
351};
352
353//Framework Accesors
354void redraw();
355void take_screenshot(const char* file);
356void init(int argc, char **argv, Toy *t, int width=600, int height=600);
357
358void toggle_events(std::vector<Toggle> &ts, Geom::Point const &pos, unsigned button);
359void draw_toggles(cairo_t *cr, std::vector<Toggle> &ts);
360Geom::Point read_point(FILE* f);
361void get_clipboard_text(std::function<void (char const *)> &&on_completion);
362
363
364
365
366const long long NS_PER_SECOND = 1000000000LL;
367const long long NS_PER_NS = 1;
368
369
370class Timer{
371public:
372 Timer() {}
373 // note that CPU time is tracked per-thread, so the timer is only useful
374 // in the thread it was start()ed from.
375
376 class Time{
377 public:
378 double value;
379 Time(long long /*s*/, long long l) : value(l) {}
380 Time(double v) : value(v) {}
381 Time operator/(double iters) const {
382 return Time(value / iters);
383 }
384 };
385
386 void start() {
388 }
389 void lap(long long &ns) {
390 nsec(ns);
391 ns -= start_time;
392 }
394 long long ns;
395 nsec(ns);
396 return Time(start_time, ns - start_time);
397 }
398 void nsec(long long &ns) {
399#if ! (defined(_WIN32) || defined(__APPLE__))
400 clock_gettime(clock, &ts);
401 ns = ts.tv_sec * NS_PER_SECOND + ts.tv_nsec / NS_PER_NS;
402#else
403 ns = 0;
404#endif
405 }
408#ifndef _WIN32
409 sched_yield();
410#endif
411 }
412private:
413 long long start_time;
414#if ! (defined(_WIN32) || defined(__APPLE__))
415 struct timespec ts;
416# ifdef _POSIX_THREAD_CPUTIME
417 static const clockid_t clock = CLOCK_THREAD_CPUTIME_ID;
418# else
419# ifdef CLOCK_MONOTONIC
420 static const clockid_t clock = CLOCK_MONOTONIC;
421# else
422 static const clockid_t clock = CLOCK_REALTIME;
423# endif
424# endif
425#endif
426};
427
428inline std::ostream& operator<<(std::ostream& o, Timer::Time const &t) {
429 double tm = t.value;
430 unsigned prefix = 0;
431 char prefixes[] = "num kMGT";
432 while(prefix < sizeof(prefixes) and tm > 1000) {
433 tm /= 1000.0;
434 prefix += 1;
435 }
436 o << tm << prefixes[prefix] << "s";
437 return o;
438}
439
440
441
442#endif // _2GEOM_TOY_FRAMEWORK2_H_
443/*
444 Local Variables:
445 mode:c++
446 c-file-style:"stroustrup"
447 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
448 indent-tabs-mode:nil
449 fill-column:99
450 End:
451 */
452// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Defines the different types of exceptions that 2geom can throw.
Various geometrical calculations.
Cartesian point / 2D vector and related operations.
pair< double, double > Point
Definition parser.cpp:7
Adaptor that creates 2D functions from 1D ones.
Definition d2.h:55
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
virtual void save(FILE *f)=0
virtual void move_to(void *hit, Geom::Point om, Geom::Point m)=0
virtual void load(FILE *f)=0
float rgb[3]
virtual void * hit(Geom::Point pos)=0
std::string name
virtual void draw(cairo_t *cr, bool annotes=false)=0
virtual ~Handle()
PointHandle(double x, double y)
void draw(cairo_t *cr, bool annotes=false) override
Geom::Point pos
void load(FILE *f) override
void move_to(void *hit, Geom::Point om, Geom::Point m) override
void save(FILE *f) override
void * hit(Geom::Point mouse) override
PointHandle(Geom::Point pt)
void load(FILE *f) override
void move_to(void *hit, Geom::Point om, Geom::Point m) override
void push_back(double x, double y)
void save(FILE *f) override
void push_back(Geom::Point pt)
void draw(cairo_t *cr, bool annotes=false) override
void * hit(Geom::Point mouse) override
Geom::D2< Geom::SBasis > asBezier()
std::vector< Geom::Point > pts
void move_to(void *hit, Geom::Point om, Geom::Point m) override
void draw(cairo_t *cr, bool annotes=false) override
RectHandle(Geom::Rect pos, bool show_center_handle)
void load(FILE *f) override
Geom::Rect pos
void * hit(Geom::Point mouse) override
void save(FILE *f) override
bool show_center_handle
value_type m_max
value_type max_value() const
void draw(cairo_t *cr, bool annotate=false) override
void load(FILE *f) override
formatter_t m_formatter
std::string m_label
value_type min_value() const
void * hit(Geom::Point pos) override
value_type value() const
void geometry(Geom::Point _pos, value_type _length, Geom::Dim2 _dir=Geom::X)
double value_type
void save(FILE *f) override
void set(value_type _min, value_type _max, value_type _step, value_type _value, const std::string &_label="")
Slider(value_type _min, value_type _max, value_type _step, value_type _value, std::string _label="")
void formatter(formatter_t _formatter)
std::string(* formatter_t)(double)
void move_to(void *hit, Geom::Point om, Geom::Point m) override
value_type m_min
PointHandle m_handle
value_type m_length
Geom::Point m_pos
value_type m_step
Time(long long, long long l)
Time operator/(double iters) const
Time lap()
void ask_for_timeslice()
Ask the OS nicely for a big time slice.
void start()
struct timespec ts
void lap(long long &ns)
static const clockid_t clock
long long start_time
void nsec(long long &ns)
void save(FILE *) override
void load(FILE *) override
void move_to(void *, Geom::Point, Geom::Point) override
Toggle(Geom::Rect bnds, const char *txt, bool v)
Geom::Rect bounds
Toggle(const char *txt, bool v)
void handle_click(Geom::Point const &pos, unsigned button)
const char * text
void draw(cairo_t *cr, bool annotes=false) override
void * hit(Geom::Point pos) override
virtual void first_time(int, char **)
virtual void canvas_click(Geom::Point at, int button)
virtual void load(FILE *f)
virtual void mouse_pressed(Geom::Point const &pos, unsigned button, unsigned modifiers)
Geom::Point old_mouse_point
virtual int should_draw_bounds()
virtual void mouse_moved(Geom::Point const &pos, unsigned modifiers)
bool mouse_down
virtual bool should_draw_numbers()
double notify_offset
vector< Handle * > handles
Handle * selected
virtual void mouse_released(Geom::Point const &pos, unsigned button, unsigned modifiers)
virtual void save(FILE *f)
int canvas_click_button
virtual void resize_canvas(Geom::Rect const &)
void * hit_data
bool show_timings
std::string name
virtual ~Toy()
virtual void key_hit(unsigned keyval, unsigned modifiers)
virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream)
FILE * spool_file
virtual void scroll(GdkScrollDirection dir, Geom::Point const &delta)
void * hit(Geom::Point pos) override
void save(FILE *f) override
size_t size() const
void push_back(const T &_handle)
const T & operator[](size_t i) const
void load(FILE *f) override
std::vector< T >::iterator iterator
std::vector< T > m_handles
void reserve(size_t sz)
void move_to(void *hit, Geom::Point om, Geom::Point m) override
void draw(cairo_t *cr, bool annotes=false) override
const double w
Definition conic-4.cpp:19
Css & result
double c[8][4]
Lifts one dimensional objects into 2D.
int _pos
Dim2
2D axis enumeration (X or Y).
Definition coord.h:48
@ X
Definition coord.h:48
Various utility functions.
Definition affine.h:22
STL namespace.
struct _cairo cairo_t
Definition path-cairo.h:16
Polynomial in symmetric power basis (S-basis)
int num
Definition scribble.cpp:47
static colour from_hsl(float H, float S, float L, float A)
colour(double r, double g, double b, double a)
static colour from_hsv(float H, float S, float V, float A)
int delta
double height
double width
Glib::ustring name
Definition toolbars.cpp:55
void draw_text(cairo_t *cr, Geom::Point pos, const char *txt, bool bottom=false, const char *fontdesc="Sans")
double uniform()
void toggle_events(std::vector< Toggle > &ts, Geom::Point const &pos, unsigned button)
const long long NS_PER_SECOND
Geom::Point read_point(FILE *f)
void cairo_set_source_rgba(cairo_t *cr, colour c)
void get_clipboard_text(std::function< void(char const *)> &&on_completion)
void draw_number(cairo_t *cr, Geom::Point pos, int num, std::string name=std::string(), bool bottom=true)
std::string default_formatter(double x)
const long long NS_PER_NS
void draw_toggles(cairo_t *cr, std::vector< Toggle > &ts)
void redraw()
void init(int argc, char **argv, Toy *t, int width=600, int height=600)
void take_screenshot(const char *file)