f594dd51e19fd4503c703f7f33876f1f222da62f
[ardour.git] / gtk2_ardour / cairo_widget.cc
1 #include "cairo_widget.h"
2 #include "gui_thread.h"
3
4 CairoWidget::CairoWidget ()
5         : _width (1),
6           _height (1),
7           _dirty (true),
8           _pixmap (0)
9 {
10
11 }
12
13 CairoWidget::~CairoWidget ()
14 {
15         if (_pixmap) {
16                 gdk_pixmap_unref (_pixmap);
17         }
18 }
19
20 bool
21 CairoWidget::on_expose_event (GdkEventExpose *event)
22 {
23         Gdk::Rectangle const exposure (
24                 event->area.x, event->area.y, event->area.width, event->area.height
25                 );
26
27         Gdk::Rectangle r = exposure;
28         Gdk::Rectangle content (0, 0, _width, _height);
29         bool intersects;
30         r.intersect (content, intersects);
31         
32         if (intersects) {
33
34                 GdkDrawable* drawable = get_window()->gobj ();
35
36                 if (_dirty) {
37
38                         if (_pixmap) {
39                                 gdk_pixmap_unref (_pixmap);
40                         }
41
42                         _pixmap = gdk_pixmap_new (drawable, _width, _height, -1);
43
44                         cairo_t* cr = gdk_cairo_create (_pixmap);
45                         render (cr);
46                         cairo_destroy (cr);
47
48                         _dirty = false;
49                 }
50
51                 gdk_draw_drawable (
52                         drawable,
53                         get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
54                         _pixmap,
55                         r.get_x(),
56                         r.get_y(),
57                         r.get_x(),
58                         r.get_y(),
59                         r.get_width(),
60                         r.get_height()
61                         );
62         }
63         
64         return true;
65 }
66
67 void
68 CairoWidget::set_dirty ()
69 {
70         ENSURE_GUI_THREAD (mem_fun (*this, &CairoWidget::set_dirty));
71
72         _dirty = true;
73         queue_draw ();
74 }
75
76 /** Handle a size allocation.
77  *  @param alloc GTK allocation.
78  */
79 void
80 CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
81 {
82         Gtk::EventBox::on_size_allocate (alloc);
83
84         _width = alloc.get_width ();
85         _height = alloc.get_height ();
86
87         set_dirty ();
88 }