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