-rw-r--r-- | src/sleep_timeline.cc | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/sleep_timeline.cc b/src/sleep_timeline.cc new file mode 100644 index 0000000..e5d4146 --- a/dev/null +++ b/src/sleep_timeline.cc | |||
@@ -0,0 +1,100 @@ | |||
1 | #include <cstdlib> | ||
2 | #include <vector> | ||
3 | #include <gtkmm/widget.h> | ||
4 | |||
5 | #include "sleep_timeline.h" | ||
6 | |||
7 | namespace napkin { | ||
8 | namespace gtk { | ||
9 | using std::vector; | ||
10 | using std::min; | ||
11 | |||
12 | void render_sleep_timeline( | ||
13 | const hypnodata_t& hd, | ||
14 | const Glib::RefPtr<Gdk::Drawable>& w, | ||
15 | int x0,int y0,int dx,int dy, | ||
16 | time_t _t0,time_t _t1) { | ||
17 | static Gdk::Color c_tobed("darkgreen"), c_alarm("red"), | ||
18 | c_almostawake("maroon"), c_midnight("blue"), c_hour("#606060"), | ||
19 | c_timeline("#404040"), c_window("red"), | ||
20 | c_background("#ffffc0"), c_border("gray"); | ||
21 | static bool beenthere=false; | ||
22 | if(!beenthere) { | ||
23 | Glib::RefPtr<Gdk::Colormap> cm(Gtk::Widget::get_default_colormap()); | ||
24 | cm->alloc_color(c_tobed); cm->alloc_color(c_alarm); | ||
25 | cm->alloc_color(c_almostawake); | ||
26 | cm->alloc_color(c_midnight); cm->alloc_color(c_hour); | ||
27 | cm->alloc_color(c_timeline); cm->alloc_color(c_window); | ||
28 | cm->alloc_color(c_background); cm->alloc_color(c_border); | ||
29 | beenthere = true; | ||
30 | } | ||
31 | Glib::RefPtr<Gdk::GC> gc = Gdk::GC::create(w); | ||
32 | |||
33 | gc->set_foreground(c_background); | ||
34 | w->draw_rectangle(gc,true, x0,y0, dx,dy+1 ); | ||
35 | gc->set_foreground(c_border); | ||
36 | w->draw_rectangle(gc,false, x0,y0, dx,dy+1 ); | ||
37 | x0+=3; dx-=6; | ||
38 | |||
39 | time_t t0, t1; | ||
40 | if(_t0 && _t1 && _t0!=_t1 && _t0<=hd.to_bed && hd.alarm<=_t1) | ||
41 | t0 = _t0, t1 = _t1; | ||
42 | else | ||
43 | t0 = hd.to_bed, t1 = hd.alarm; | ||
44 | time_t dt = t1-t0; | ||
45 | |||
46 | time_t tb = hd.to_bed; time_t ta = hd.alarm; | ||
47 | int xb = x0+dx*(tb-t0)/dt, | ||
48 | xa = x0+dx*(ta-t0)/dt; | ||
49 | int ym = y0+dy/2; | ||
50 | gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER); | ||
51 | gc->set_foreground(c_timeline); | ||
52 | w->draw_line(gc, xb,ym, xa,ym ); | ||
53 | time_t ws = ta-hd.window*60; | ||
54 | int xws = x0+dx*(ws-t0)/dt; | ||
55 | gc->set_foreground(c_window); | ||
56 | w->draw_rectangle(gc, true, xws,ym-1, xa-xws,3 ); | ||
57 | gc->set_foreground(c_almostawake); | ||
58 | int tl2 = min(dy/2 - 3, 7); | ||
59 | int yt0 = ym-tl2, yt1 = ym+tl2+1; | ||
60 | for(vector<time_t>::const_iterator i=hd.almost_awakes.begin();i!=hd.almost_awakes.end();++i) { | ||
61 | int x = x0+dx*(*i-t0)/dt; | ||
62 | w->draw_line(gc, x,yt0, x,yt1 ); | ||
63 | } | ||
64 | tl2 = min(dy/5, 5); | ||
65 | yt0 = ym-tl2; yt1 = ym+tl2+1; | ||
66 | gc->set_foreground(c_hour); | ||
67 | time_t midnight = hd.aligned_start()+24*60*60; | ||
68 | for(time_t h = tb-tb%3600 + 3600; h<ta ; h+=3600) { | ||
69 | if(h==midnight) gc->set_foreground(c_midnight); | ||
70 | int x = x0+dx*(h-t0)/dt; | ||
71 | w->draw_line(gc, x,yt0, x,yt1 ); | ||
72 | if(h==midnight) gc->set_foreground(c_hour); | ||
73 | } | ||
74 | gc->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER); | ||
75 | gc->set_foreground(c_tobed); | ||
76 | w->draw_line(gc, xb,yt0, xb,yt1 ); | ||
77 | gc->set_foreground(c_alarm); | ||
78 | w->draw_line(gc, xa,yt0, xa,yt1 ); | ||
79 | } | ||
80 | |||
81 | |||
82 | bool sleep_timeline_t::on_expose_event(GdkEventExpose*) { | ||
83 | if(!hd) return true; | ||
84 | Glib::RefPtr<Gdk::Window> w = get_window(); | ||
85 | int x0,y0,dx,dy,wd; | ||
86 | w->get_geometry(x0,y0,dx,dy,wd); | ||
87 | render_sleep_timeline( | ||
88 | *hd, | ||
89 | w, | ||
90 | 0,0, dx-2,dy-2 ); | ||
91 | return true; | ||
92 | } | ||
93 | |||
94 | void sleep_timeline_t::set_data(const hypnodata_ptr_t& _hd) { | ||
95 | hd = _hd; | ||
96 | queue_draw(); | ||
97 | } | ||
98 | |||
99 | } | ||
100 | } | ||