summaryrefslogtreecommitdiffabout
path: root/src/sleep_timeline.cc
Unidiff
Diffstat (limited to 'src/sleep_timeline.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--src/sleep_timeline.cc100
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
7namespace 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}