1 // TimeBar.cc --- Time Bar
2 //
3 // Copyright (C) 2002 - 2009, 2011, 2012 Rob Caelers & Raymond Penners
4 // All rights reserved.
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "preinclude.h"
25 
26 #include "debug.hh"
27 
28 #include <sstream>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 
33 #include "TimeBar.hh"
34 #include "Text.hh"
35 #include "GtkUtil.hh"
36 
37 const int MARGINX = 4;
38 const int MARGINY = 2;
39 const int MIN_HORIZONTAL_BAR_WIDTH = 12;
40 const int MIN_HORIZONTAL_BAR_HEIGHT = 20; // stolen from gtk's progress bar
41 
42 using namespace std;
43 
44 Gdk::Color TimeBar::bar_colors[TimeBar::COLOR_ID_SIZEOF] =
45   {
46     Gdk::Color("lightblue"),
47     Gdk::Color("lightgreen"),
48     Gdk::Color("orange"),
49     Gdk::Color("red"),
50     Gdk::Color("#e00000"),
51     Gdk::Color("#00d4b2"),
52     Gdk::Color("lightgreen"),
53   };
54 
55 
56 //! Constructor
TimeBar()57 TimeBar::TimeBar() :
58   bar_value(0),
59   bar_max_value(0),
60   secondary_bar_value(0),
61   secondary_bar_max_value(0),
62   bar_text_align(0),
63   rotation(0)
64 {
65   add_events(Gdk::EXPOSURE_MASK);
66   add_events(Gdk::BUTTON_PRESS_MASK);
67 
68   set_bar_color(COLOR_ID_INACTIVE);
69   set_secondary_bar_color(COLOR_ID_INACTIVE);
70   set_text_color(Gdk::Color("black"));
71 
72   GtkUtil::set_theme_fg_color(this);
73 }
74 
75 //! Destructor
~TimeBar()76 TimeBar::~TimeBar()
77 {
78 }
79 
80 
81 //! Sets the time progress to be displayed.
82 void
set_progress(int value,int max_value)83 TimeBar::set_progress(int value, int max_value)
84 {
85   if (value > max_value)
86     {
87       value = max_value;
88     }
89 
90   bar_value = value;
91   bar_max_value = max_value;
92 }
93 
94 
95 //! Sets the secondary time progress to be displayed.
96 void
set_secondary_progress(int value,int max_value)97 TimeBar::set_secondary_progress(int value, int max_value)
98 {
99   if (value > max_value)
100     {
101       value = max_value;
102     }
103 
104   secondary_bar_value = value;
105   secondary_bar_max_value = max_value;
106 }
107 
108 
109 //! Sets the text to be displayed.
110 void
set_text(string text)111 TimeBar::set_text(string text)
112 {
113   bar_text = text;
114 }
115 
116 
117 //! Sets text alignment
118 void
set_text_alignment(int align)119 TimeBar::set_text_alignment(int align)
120 {
121   bar_text_align = align;
122 }
123 
124 
125 //! Sets the color of the bar.
126 void
set_bar_color(ColorId color)127 TimeBar::set_bar_color(ColorId color)
128 {
129   bar_color = color;
130 }
131 
132 
133 //! Sets the color of the secondary bar.
134 void
set_secondary_bar_color(ColorId color)135 TimeBar::set_secondary_bar_color(ColorId color)
136 {
137   secondary_bar_color = color;
138 }
139 
140 
141 //! Sets the text color.
142 void
set_text_color(Gdk::Color color)143 TimeBar::set_text_color(Gdk::Color color)
144 {
145   bar_text_color = color;
146 }
147 
148 
149 void
set_rotation(int r)150 TimeBar::set_rotation(int r)
151 {
152   rotation = r;
153   queue_resize();
154 }
155 
156 
157 //! Updates the screen.
update()158 void TimeBar::update()
159 {
160   queue_draw();
161 }
162 
163 
164 void
on_size_allocate(Gtk::Allocation & allocation)165 TimeBar::on_size_allocate(Gtk::Allocation &allocation)
166 {
167   //Use the offered allocation for this container:
168   set_allocation(allocation);
169 
170   if (
171 #ifdef HAVE_GTK3
172       get_realized()
173 #else
174       is_realized()
175 #endif
176       )
177     {
178       get_window()->move_resize(allocation.get_x(),
179                                 allocation.get_y(),
180                                 allocation.get_width(),
181                                 allocation.get_height());
182     }
183 }
184 
185 //! Returns the preferred size.
186 void
get_preferred_size(int & width,int & height) const187 TimeBar::get_preferred_size(int &width, int &height) const
188 {
189   // Not sure why create_pango_layout is not const...
190   Glib::RefPtr<Pango::Layout> pl = const_cast<TimeBar *>(this)->create_pango_layout(bar_text);
191 
192   string min_string = Text::time_to_string(-(59+59*60+9*60*60));
193   Glib::RefPtr<Pango::Layout> plmin = const_cast<TimeBar *>(this)->create_pango_layout(min_string);
194 
195   Glib::RefPtr<Pango::Context> pcl = pl->get_context();
196   Glib::RefPtr<Pango::Context> pcmin = plmin->get_context();
197   Pango::Matrix matrix = PANGO_MATRIX_INIT;
198 
199   pango_matrix_rotate(&matrix, 360 - rotation);
200 
201   pcl->set_matrix(matrix);
202   pcmin->set_matrix(matrix);
203 
204   pl->get_pixel_size(width, height);
205 
206   int mwidth, mheight;
207   plmin->get_pixel_size(mwidth, mheight);
208   if (mwidth > width)
209     width = mwidth;
210   if (mheight > height)
211     height = mheight;
212 
213   width = width + 2 * MARGINX;
214   height = max(height + 2 * MARGINY, MIN_HORIZONTAL_BAR_HEIGHT);
215 }
216 
217 
218 #ifndef HAVE_GTK3
219 
on_realize()220 void TimeBar::on_realize()
221 {
222   // FIXME: for some reason, the timebar get realized EACH TIME
223   //        the timerbox is cycled...
224   // We need to call the base on_realize()
225   Gtk::DrawingArea::on_realize();
226 
227   // Now we can allocate any additional resources we need
228   Glib::RefPtr<Gdk::Window> window = get_window();
229   window_gc = Gdk::GC::create(window);
230 
231   Glib::RefPtr<Gtk::Style> style = get_style();
232   Gdk::Color bg = style->get_bg(Gtk::STATE_NORMAL);
233   bar_colors[COLOR_ID_BG] = bg;
234 
235   Glib::RefPtr<Gdk::Colormap> colormap = get_colormap();
236   for (int i = 0; i < COLOR_ID_SIZEOF; i++)
237     {
238       colormap->alloc_color(bar_colors[i]);
239     }
240   window->clear();
241 }
242 
243 
244 void
on_size_request(GtkRequisition * requisition)245 TimeBar::on_size_request(GtkRequisition *requisition)
246 {
247   int width, height;
248 
249   get_preferred_size(width, height);
250 
251   if (rotation == 0 || rotation == 180)
252     {
253       requisition->width = width;
254       requisition->height = height;
255     }
256   else
257     {
258       requisition->width = height;
259       requisition->height = width;
260     }
261 }
262 
263 
264 //! Draws the timebar
265 bool
on_expose_event(GdkEventExpose * e)266 TimeBar::on_expose_event(GdkEventExpose *e)
267 {
268   const int border_size = 2;
269   Gtk::Allocation allocation = get_allocation();
270 
271   Glib::RefPtr<Gdk::Window> window = get_window();
272 
273   Glib::RefPtr<Gdk::Colormap> colormap = get_colormap();
274   for (int i = 0; i < COLOR_ID_SIZEOF; i++)
275     {
276       colormap->alloc_color(bar_colors[i]);
277     }
278 
279   // Physical width/height
280   int win_w = allocation.get_width();
281   int win_h = allocation.get_height();
282 
283   // Logical width/height
284   // width = direction of bar
285   int win_lw, win_lh;
286   if (rotation == 0 || rotation == 180)
287     {
288       win_lw = win_w;
289       win_lh = win_h;
290     }
291   else
292     {
293       win_lw = win_h;
294       win_lh = win_w;
295     }
296 
297   // Border
298   Gdk::Rectangle area(&e->area);
299   Glib::RefPtr<Gtk::Style> style = get_style();
300 
301   Gdk::Color bg = style->get_bg(Gtk::STATE_NORMAL);
302   bar_colors[COLOR_ID_BG] = bg;
303 
304   // Draw background
305   window_gc->set_foreground(bar_colors[COLOR_ID_BG]);
306   style->paint_shadow(window, Gtk::STATE_NORMAL, Gtk::SHADOW_IN, area,
307                       *this, "", 0, 0, win_w - 1, win_h -1);
308   window->draw_rectangle(window_gc, true,
309                          e->area.x+border_size,
310                          e->area.y+border_size,
311                          e->area.width -2*border_size,
312                          e->area.height -2*border_size);
313 
314   // Bar
315   int bar_width = 0;
316   if (bar_max_value > 0)
317     {
318       bar_width = (bar_value * (win_lw - 2 * border_size)) / bar_max_value;
319     }
320 
321   // Secondary bar
322   int sbar_width = 0;
323   if (secondary_bar_max_value >  0)
324     {
325       sbar_width = (secondary_bar_value * (win_lw - 2 * border_size)) / secondary_bar_max_value;
326     }
327 
328   int bar_height = win_lh - 2 * border_size;
329 
330   if (sbar_width > 0)
331     {
332       // Overlap
333 
334       // We should assert() because this is not supported
335       // but there are some weird boundary cases
336       // in which this still happens.. need to check
337       // this out some time.
338       // assert(secondary_bar_color == COLOR_ID_INACTIVE);
339       ColorId overlap_color;
340       switch (bar_color)
341         {
342         case COLOR_ID_ACTIVE:
343           overlap_color = COLOR_ID_INACTIVE_OVER_ACTIVE;
344           break;
345         case COLOR_ID_OVERDUE:
346           overlap_color = COLOR_ID_INACTIVE_OVER_OVERDUE;
347           break;
348         default:
349           // We could abort() because this is not supported
350           // but there are some weird boundary cases
351           // in which this still happens.. need to check
352           // this out some time.
353           overlap_color = COLOR_ID_INACTIVE_OVER_ACTIVE;
354         }
355 
356       if (sbar_width >= bar_width)
357         {
358           if (bar_width)
359             {
360               window_gc->set_foreground(bar_colors[overlap_color]);
361               draw_bar(window, window_gc, true,
362                        border_size, border_size,
363                        bar_width, bar_height,
364                        win_lw, win_lh);
365             }
366           if (sbar_width > bar_width)
367             {
368               window_gc->set_foreground(bar_colors[secondary_bar_color]);
369               draw_bar(window, window_gc, true,
370                        border_size + bar_width, border_size,
371                        sbar_width - bar_width, bar_height,
372                        win_lw, win_lh);
373             }
374         }
375       else
376         {
377           if (sbar_width)
378             {
379               window_gc->set_foreground(bar_colors[overlap_color]);
380               draw_bar(window, window_gc, true,
381                        border_size, border_size,
382                        sbar_width, bar_height,
383                        win_lw, win_lh);
384             }
385           window_gc->set_foreground(bar_colors[bar_color]);
386           draw_bar(window, window_gc, true,
387                    border_size + sbar_width, border_size,
388                    bar_width - sbar_width, bar_height,
389                    win_lw, win_lh);
390         }
391     }
392   else
393     {
394       // No overlap
395       window_gc->set_foreground(bar_colors[bar_color]);
396       draw_bar(window, window_gc, true,
397                border_size, border_size,
398                bar_width, bar_height, win_lw, win_lh);
399     }
400 
401 
402   // Text
403   window_gc->set_foreground(bar_text_color);
404   Glib::RefPtr<Pango::Layout> pl1 = create_pango_layout(bar_text);
405   Glib::RefPtr<Pango::Context> pc1 = pl1->get_context();
406 
407   Pango::Matrix matrix = PANGO_MATRIX_INIT;
408 
409   pango_matrix_rotate(&matrix, 360 - rotation);
410   pc1->set_matrix(matrix);
411 
412   int text_width, text_height;
413   pl1->get_pixel_size(text_width, text_height);
414 
415   int text_x, text_y;
416 
417   Gdk::Rectangle rect1, rect2;
418 
419   if (rotation == 0 || rotation == 180)
420     {
421       if (win_w - text_width - MARGINX > 0)
422         {
423           if (bar_text_align > 0)
424             text_x = (win_w - text_width - MARGINX);
425           else if (bar_text_align < 0)
426             text_x = MARGINX;
427           else
428             text_x = (win_w - text_width) / 2;
429         }
430       else
431         {
432           text_x = MARGINX;
433         }
434       text_y = (win_h - text_height) / 2;
435 
436       int left_width = (bar_width > sbar_width) ? bar_width : sbar_width;
437       left_width += border_size;
438 
439       Gdk::Rectangle left_rect(0, 0, left_width, win_h);
440       Gdk::Rectangle right_rect(left_width, 0, win_w - left_width, win_h);
441 
442       rect1 = left_rect;
443       rect2 = right_rect;
444     }
445   else
446     {
447       if (win_h - text_width - MARGINY > 0)
448         {
449           int a = bar_text_align;
450           if (rotation == 270)
451             {
452               a *= -1;
453             }
454           if (a > 0)
455             text_y = (win_h - text_width - MARGINY);
456           else if (a < 0)
457             text_y = MARGINY;
458           else
459             text_y = (win_h - text_width) / 2;
460         }
461       else
462         {
463           text_y = MARGINY;
464         }
465 
466       text_x = (win_w - text_height) / 2;
467 
468       int left_width = (bar_width > sbar_width) ? bar_width : sbar_width;
469       left_width += border_size;
470 
471       Gdk::Rectangle up_rect(0, 0, win_w, left_width);
472       Gdk::Rectangle down_rect(0, left_width, win_w, win_h - left_width);
473 
474       rect1 = up_rect;
475       rect2 = down_rect;
476     }
477 
478   Gdk::Color textcolor = style->get_fg(Gtk::STATE_NORMAL);
479 
480   Glib::RefPtr<Gdk::GC> window_gc1 = Gdk::GC::create(window);
481 
482   window_gc1->set_clip_origin(0,0);
483   window_gc1->set_clip_rectangle(rect1);
484   window_gc1->set_foreground(bar_text_color);
485   window->draw_layout(window_gc1, text_x, text_y, pl1);
486 
487   window_gc1->set_foreground(textcolor);
488   window_gc1->set_clip_rectangle(rect2);
489   window->draw_layout(window_gc1, text_x, text_y, pl1);
490   return true;
491 }
492 
493 
494 void
draw_bar(Glib::RefPtr<Gdk::Window> & window,const Glib::RefPtr<Gdk::GC> & gc,bool filled,int x,int y,int width,int height,int winw,int winh)495 TimeBar::draw_bar(Glib::RefPtr<Gdk::Window> &window,
496                   const Glib::RefPtr<Gdk::GC> &gc,
497                   bool filled, int x, int y, int width, int height,
498                   int winw, int winh)
499 {
500   (void) winh;
501 
502   if (rotation == 0 || rotation == 180)
503     {
504       window->draw_rectangle(gc, filled, x, y, width, height);
505     }
506   else
507     {
508       window->draw_rectangle(gc, filled, y, winw - x - width, height, width);
509     }
510 }
511 
512 #else
513 
514 Gtk::SizeRequestMode
get_request_mode_vfunc() const515 TimeBar::get_request_mode_vfunc() const
516 {
517   return Gtk::Widget::get_request_mode_vfunc();
518 }
519 
520 void
get_preferred_width_vfunc(int & minimum_width,int & natural_width) const521 TimeBar::get_preferred_width_vfunc(int &minimum_width, int &natural_width) const
522 {
523   int width, height;
524   get_preferred_size(width, height);
525 
526   if (rotation == 0 || rotation == 180)
527     {
528       minimum_width = natural_width = width;
529     }
530   else
531     {
532       minimum_width = natural_width = height;
533     }
534 }
535 
536 void
get_preferred_height_vfunc(int & minimum_height,int & natural_height) const537 TimeBar::get_preferred_height_vfunc(int &minimum_height, int &natural_height) const
538 {
539   int width, height;
540   get_preferred_size(width, height);
541 
542   if (rotation == 0 || rotation == 180)
543     {
544       minimum_height = natural_height = height;
545     }
546   else
547     {
548       minimum_height = natural_height = width;
549     }
550 }
551 
552 void
get_preferred_width_for_height_vfunc(int,int & minimum_width,int & natural_width) const553 TimeBar::get_preferred_width_for_height_vfunc(int /* height */, int &minimum_width, int &natural_width) const
554 {
555   get_preferred_width_vfunc(minimum_width, natural_width);
556 }
557 
558 void
get_preferred_height_for_width_vfunc(int,int & minimum_height,int & natural_height) const559 TimeBar::get_preferred_height_for_width_vfunc(int /* width */, int &minimum_height, int &natural_height) const
560 {
561   get_preferred_height_vfunc(minimum_height, natural_height);
562 }
563 
564 bool
on_draw(const Cairo::RefPtr<Cairo::Context> & cr)565 TimeBar::on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
566 {
567   const int border_size = 1;
568 
569   Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context();
570   Gtk::Allocation allocation = get_allocation();
571 
572   style_context->context_save();
573   style_context->add_class(GTK_STYLE_CLASS_FRAME);
574 
575   // Physical width/height
576   int win_w = allocation.get_width() - 2; // FIXME:
577   int win_h = allocation.get_height();
578 
579   // Logical width/height
580   // width = direction of bar
581   int win_lw, win_lh;
582   if (rotation == 0 || rotation == 180)
583     {
584       win_lw = win_w;
585       win_lh = win_h;
586     }
587   else
588     {
589       win_lw = win_h;
590       win_lh = win_w;
591     }
592 
593   // Draw background
594   style_context->set_state(Gtk::STATE_FLAG_ACTIVE);
595   Gdk::RGBA back_color = style_context->get_background_color();
596   set_color(cr, back_color);
597 
598   // clip to the area indicated by the expose event so that we only redraw
599   // the portion of the window that needs to be redrawn
600   cr->rectangle(0, 0, win_w, win_h);
601   cr->clip();
602 
603   style_context->context_save();
604   style_context->set_state((Gtk::StateFlags)Gtk::STATE_FLAG_ACTIVE);
605   style_context->render_background(cr, 0, 0, win_w - 1, win_h -1);
606   style_context->render_frame(cr, 0, 0, win_w - 1, win_h -1);
607   style_context->context_restore();
608 
609   // set_color(cr, back_color);
610   // cr->rectangle(border_size, border_size, win_w - 2*border_size, win_h - 2*border_size);
611   // cr->fill();
612 
613   // Bar
614   int bar_width = 0;
615   if (bar_max_value > 0)
616     {
617       bar_width = (bar_value * (win_lw - 2 * border_size - 1)) / bar_max_value;
618     }
619 
620   // Secondary bar
621   int sbar_width = 0;
622   if (secondary_bar_max_value >  0)
623     {
624       sbar_width = (secondary_bar_value * (win_lw - 2 * border_size - 1)) / secondary_bar_max_value;
625     }
626 
627   int bar_height = win_lh - 2 * border_size - 1;
628 
629   if (sbar_width > 0)
630     {
631       // Overlap
632 
633       // We should assert() because this is not supported
634       // but there are some weird boundary cases
635       // in which this still happens.. need to check
636       // this out some time.
637       // assert(secondary_bar_color == COLOR_ID_INACTIVE);
638       ColorId overlap_color;
639       switch (bar_color)
640         {
641         case COLOR_ID_ACTIVE:
642           overlap_color = COLOR_ID_INACTIVE_OVER_ACTIVE;
643           break;
644         case COLOR_ID_OVERDUE:
645           overlap_color = COLOR_ID_INACTIVE_OVER_OVERDUE;
646           break;
647         default:
648           // We could abort() because this is not supported
649           // but there are some weird boundary cases
650           // in which this still happens.. need to check
651           // this out some time.
652           overlap_color = COLOR_ID_INACTIVE_OVER_ACTIVE;
653         }
654 
655       if (sbar_width >= bar_width)
656         {
657           if (bar_width)
658             {
659               set_color(cr, bar_colors[overlap_color]);
660               draw_bar(cr,
661                        border_size, border_size,
662                        bar_width, bar_height,
663                        win_lw, win_lh);
664             }
665           if (sbar_width > bar_width)
666             {
667               set_color(cr, bar_colors[secondary_bar_color]);
668               draw_bar(cr,
669                        border_size + bar_width, border_size,
670                        sbar_width - bar_width, bar_height,
671                        win_lw, win_lh);
672             }
673         }
674       else
675         {
676           if (sbar_width)
677             {
678               set_color(cr, bar_colors[overlap_color]);
679               draw_bar(cr,
680                        border_size, border_size,
681                        sbar_width, bar_height,
682                        win_lw, win_lh);
683             }
684           set_color(cr, bar_colors[bar_color]);
685           draw_bar(cr,
686                    border_size + sbar_width, border_size,
687                    bar_width - sbar_width, bar_height,
688                    win_lw, win_lh);
689         }
690     }
691   else
692     {
693       // No overlap
694       set_color(cr, bar_colors[bar_color]);
695       draw_bar(cr,
696                border_size, border_size,
697                bar_width, bar_height, win_lw, win_lh);
698     }
699 
700   style_context->context_restore();
701   style_context->context_save();
702 
703   // Text
704   Pango::Matrix matrix = PANGO_MATRIX_INIT;
705   pango_matrix_rotate(&matrix, 360 - rotation);
706 
707   Glib::RefPtr<Pango::Layout> pl1 = create_pango_layout(bar_text);
708   Glib::RefPtr<Pango::Context> pc1 = pl1->get_context();
709 
710   pc1->set_matrix(matrix);
711 
712   int text_width, text_height;
713   pl1->get_pixel_size(text_width, text_height);
714 
715   int text_x, text_y;
716 
717   Gdk::Rectangle rect1, rect2;
718 
719   if (rotation == 0 || rotation == 180)
720     {
721       if (win_w - text_width - MARGINX > 0)
722         {
723           if (bar_text_align > 0)
724             text_x = (win_w - text_width - MARGINX);
725           else if (bar_text_align < 0)
726             text_x = MARGINX;
727           else
728             text_x = (win_w - text_width) / 2;
729         }
730       else
731         {
732           text_x = MARGINX;
733         }
734       text_y = (win_h - text_height) / 2;
735 
736       int left_width = (bar_width > sbar_width) ? bar_width : sbar_width;
737       left_width += border_size;
738 
739       Gdk::Rectangle left_rect(0, 0, left_width, win_h);
740       Gdk::Rectangle right_rect(left_width, 0, win_w - left_width, win_h);
741 
742       rect1 = left_rect;
743       rect2 = right_rect;
744     }
745   else
746     {
747       if (win_h - text_width - MARGINY > 0)
748         {
749           int a = bar_text_align;
750           if (rotation == 270)
751             {
752               a *= -1;
753             }
754           if (a > 0)
755             text_y = (win_h - text_width - MARGINY);
756           else if (a < 0)
757             text_y = MARGINY;
758           else
759             text_y = (win_h - text_width) / 2;
760         }
761       else
762         {
763           text_y = MARGINY;
764         }
765 
766       text_x = (win_w - text_height) / 2;
767 
768       int left_width = (bar_width > sbar_width) ? bar_width : sbar_width;
769       left_width += border_size;
770 
771       Gdk::Rectangle up_rect(0, 0, win_w, left_width);
772       Gdk::Rectangle down_rect(0, left_width, win_w, win_h - left_width);
773 
774       rect1 = up_rect;
775       rect2 = down_rect;
776     }
777 
778   cr->reset_clip();
779   cr->rectangle(rect1.get_x(), rect1.get_y(), rect1.get_width(), rect1.get_height());
780   cr->clip();
781 
782   cr->move_to(text_x, text_y);
783   set_color(cr, bar_text_color);
784   pl1->show_in_cairo_context(cr);
785 
786   cr->reset_clip();
787   cr->rectangle(rect2.get_x(), rect2.get_y(), rect2.get_width(), rect2.get_height());
788   cr->clip();
789 
790 
791   set_color(cr, style_context->get_color(Gtk::STATE_FLAG_ACTIVE));
792   cr->move_to(text_x, text_y);
793   pl1->show_in_cairo_context(cr);
794   style_context->context_restore();
795 
796   return Gtk::Widget::on_draw(cr);
797 }
798 
799 void
set_color(const Cairo::RefPtr<Cairo::Context> & cr,const Gdk::Color & color)800 TimeBar::set_color(const Cairo::RefPtr<Cairo::Context>& cr, const Gdk::Color &color)
801 {
802   cr->set_source_rgba(color.get_red_p(), color.get_green_p(), color.get_blue_p(), 1);
803 }
804 
805 
806 void
set_color(const Cairo::RefPtr<Cairo::Context> & cr,const Gdk::RGBA & color)807 TimeBar::set_color(const Cairo::RefPtr<Cairo::Context>& cr, const Gdk::RGBA &color)
808 {
809   cr->set_source_rgba(color.get_red(), color.get_green(), color.get_blue(), 1);
810 }
811 
812 void
draw_bar(const Cairo::RefPtr<Cairo::Context> & cr,int x,int y,int width,int height,int winw,int winh)813 TimeBar::draw_bar(const Cairo::RefPtr<Cairo::Context>& cr,
814                   int x, int y, int width, int height,
815                   int winw, int winh)
816 {
817   (void) winh;
818 
819   if (rotation == 0 || rotation == 180)
820     {
821       cr->rectangle(x, y, width, height);
822       cr->fill();
823     }
824   else
825     {
826       cr->rectangle(y, winw - x- width, height, width);
827       cr->fill();
828     }
829 }
830 
831 #endif
832