update drobilla's fascistic dir-locals.el to force emacs users into whitespace submis...
[ardour.git] / gtk2_ardour / cairo_widget.cc
1 /*
2     Copyright (C) 2009 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "cairo_widget.h"
21 #include "gui_thread.h"
22
23 CairoWidget::CairoWidget ()
24         : _width (1),
25           _height (1),
26           _dirty (true),
27           _pixmap (0)
28 {
29
30 }
31
32 CairoWidget::~CairoWidget ()
33 {
34         if (_pixmap) {
35                 g_object_unref (_pixmap);
36         }
37 }
38
39 bool
40 CairoWidget::on_expose_event (GdkEventExpose *event)
41 {
42         Gdk::Rectangle const exposure (
43                 event->area.x, event->area.y, event->area.width, event->area.height
44                 );
45
46         Gdk::Rectangle r = exposure;
47         Gdk::Rectangle content (0, 0, _width, _height);
48         bool intersects;
49         r.intersect (content, intersects);
50
51         if (intersects) {
52
53                 GdkDrawable* drawable = get_window()->gobj ();
54
55                 if (_dirty) {
56
57                         if (_pixmap) {
58                                 g_object_unref (_pixmap);
59                         }
60
61                         _pixmap = gdk_pixmap_new (drawable, _width, _height, -1);
62
63                         cairo_t* cr = gdk_cairo_create (_pixmap);
64                         render (cr);
65                         cairo_destroy (cr);
66
67                         _dirty = false;
68                 }
69
70                 gdk_draw_drawable (
71                         drawable,
72                         get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
73                         _pixmap,
74                         r.get_x(),
75                         r.get_y(),
76                         r.get_x(),
77                         r.get_y(),
78                         r.get_width(),
79                         r.get_height()
80                         );
81         }
82
83         return true;
84 }
85
86 /** Marks the widget as dirty, so that render () will be called on
87  *  the next GTK expose event.
88  */
89
90 void
91 CairoWidget::set_dirty ()
92 {
93         ENSURE_GUI_THREAD (*this, &CairoWidget::set_dirty)
94
95         _dirty = true;
96         queue_draw ();
97 }
98
99 /** Handle a size allocation.
100  *  @param alloc GTK allocation.
101  */
102 void
103 CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
104 {
105         Gtk::EventBox::on_size_allocate (alloc);
106
107         _width = alloc.get_width ();
108         _height = alloc.get_height ();
109
110         set_dirty ();
111 }