"Lock" mode is now "Constrained", make snap absolute modifier configurable.
[ardour.git] / libs / gtkmm2ext / gtkmm2ext / cairocell.h
1 /*
2   Copyright (C) 2011 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 #ifndef __libgtmm2ext_cairocell_h__
21 #define __libgtmm2ext_cairocell_h__
22
23 #include <map>
24
25 #include <stdint.h>
26
27 #include <boost/shared_ptr.hpp>
28
29 #include <cairomm/cairomm.h>
30 #include <gtkmm/misc.h>
31
32 #include "gtkmm2ext/visibility.h"
33
34 class LIBGTKMM2EXT_API CairoCell
35 {
36   public:
37         CairoCell(int32_t id);
38         virtual ~CairoCell() {}
39         
40         int32_t id() const { return _id; }
41
42         virtual void render (Cairo::RefPtr<Cairo::Context>&) = 0;
43
44         double x() const { return bbox.x; }
45         double y() const { return bbox.y; }
46         double width() const { return bbox.width; }
47         double height() const { return bbox.height; }
48
49         void set_position (double x, double y) {
50                 bbox.x = x;
51                 bbox.y = y;
52         }
53
54         bool intersects (GdkRectangle& r) const {
55                 return gdk_rectangle_intersect (&r, &bbox, 0);
56         }
57
58         bool covers (double x, double y) const {
59                 return bbox.x <= x && bbox.x + bbox.width > x &&
60                         bbox.y <= y && bbox.y + bbox.height > y;
61         }
62
63         double xpad() const { return _xpad; }
64         void   set_xpad (double x) { _xpad = x; }
65
66         void set_visible (bool yn) { _visible = yn; }
67         bool visible() const { return _visible; }
68         virtual void set_size (Cairo::RefPtr<Cairo::Context>&) {}
69
70   protected:
71         int32_t _id;
72         GdkRectangle bbox;
73         bool _visible;
74         uint32_t _xpad;
75 };
76
77 class LIBGTKMM2EXT_API CairoFontDescription {
78   public:
79         CairoFontDescription (const std::string& f,
80                               Cairo::FontSlant s,
81                               Cairo::FontWeight w,
82                               double sz)
83                 : face (f)
84                 , _slant (s)
85                 , _weight (w)
86                 , _size (sz)
87         {}
88         CairoFontDescription (Pango::FontDescription&);
89
90         void apply (Cairo::RefPtr<Cairo::Context> context) {
91                 context->select_font_face (face, _slant, _weight);
92                 context->set_font_size (_size);
93         }
94
95         void set_size (double sz) { _size = sz; }
96         double size() const { return _size; }
97
98        Cairo::FontSlant slant() const { return _slant; }
99        void set_slant (Cairo::FontSlant sl) { _slant = sl; }
100
101        Cairo::FontWeight weight() const { return _weight; }
102        void set_weight (Cairo::FontWeight w) { _weight = w; }
103
104   private:
105         std::string face;
106         Cairo::FontSlant _slant;
107         Cairo::FontWeight _weight;
108         double _size;
109 };
110
111 class LIBGTKMM2EXT_API CairoTextCell : public CairoCell
112 {
113   public:
114         CairoTextCell (int32_t id, double width_chars, boost::shared_ptr<CairoFontDescription> font = boost::shared_ptr<CairoFontDescription>());
115         ~CairoTextCell() {}
116
117         virtual void set_size (Cairo::RefPtr<Cairo::Context>&);
118
119         boost::shared_ptr<CairoFontDescription> font() const { return _font; }
120
121         std::string get_text() const {
122                 return _text;
123         }
124
125         double width_chars() const { return _width_chars; }
126         void render (Cairo::RefPtr<Cairo::Context>&);
127
128   protected:
129         friend class CairoEditableText;
130         void set_width_chars (double wc) { _width_chars = wc; }
131         void set_text (const std::string& txt);
132         void set_font (boost::shared_ptr<CairoFontDescription> font) {
133                 _font = font;
134         }
135
136   protected:
137         double _width_chars;
138         std::string _text;
139         boost::shared_ptr<CairoFontDescription> _font;
140         double y_offset;
141         double x_offset;
142 };
143
144 class LIBGTKMM2EXT_API CairoCharCell : public CairoTextCell
145 {
146   public:
147         CairoCharCell(int32_t id, char c);
148
149         void set_size (Cairo::RefPtr<Cairo::Context>& context);
150 };
151
152 class LIBGTKMM2EXT_API CairoEditableText : public Gtk::Misc
153 {
154 public:
155         CairoEditableText (boost::shared_ptr<CairoFontDescription> font  = boost::shared_ptr<CairoFontDescription>());
156         ~CairoEditableText ();
157
158         void add_cell (CairoCell*);
159         void clear_cells ();
160
161         void start_editing (CairoCell*);
162         void stop_editing ();
163
164         void set_text (CairoTextCell* cell, const std::string&);
165         void set_width_chars (CairoTextCell* cell, uint32_t);
166
167         void set_draw_background (bool yn) { _draw_bg = yn; }
168         
169         void set_colors (double cr, double cg, double cb, double ca) {
170                 r = cr;
171                 g = cg;
172                 b = cb;
173                 a = ca;
174                 queue_draw ();
175         }
176
177         void set_edit_colors (double cr, double cg, double cb, double ca) {
178                 edit_r = cr;
179                 edit_g = cg;
180                 edit_b = cb;
181                 edit_a = ca;
182                 queue_draw ();
183         }
184
185         void set_bg (double r, double g, double b, double a) {
186                 bg_r = r;
187                 bg_g = g;
188                 bg_b = b;
189                 bg_a = a;
190                 queue_draw ();
191         }
192
193         double xpad() const { return _xpad; }
194         void set_xpad (double x) { _xpad = x; queue_resize(); }
195         double ypad() const { return _ypad; }
196         void set_ypad (double y) { _ypad = y; queue_resize(); }
197         
198         double corner_radius() const { return _corner_radius; }
199         void set_corner_radius (double r) { _corner_radius = r; queue_draw (); }
200
201         boost::shared_ptr<CairoFontDescription> font() const { return _font; }
202         void set_font (boost::shared_ptr<CairoFontDescription> font);
203         void set_font (Pango::FontDescription& font);
204
205         sigc::signal<bool,GdkEventScroll*,CairoCell*> scroll;
206         sigc::signal<bool,GdkEventButton*,CairoCell*> button_press;
207         sigc::signal<bool,GdkEventButton*,CairoCell*> button_release;
208
209 protected:
210         bool on_expose_event (GdkEventExpose*);
211         bool on_button_press_event (GdkEventButton*);
212         bool on_button_release_event (GdkEventButton*);
213         void on_size_request (GtkRequisition*);
214         bool on_focus_in_event (GdkEventFocus*);
215         bool on_focus_out_event (GdkEventFocus*);
216         bool on_scroll_event (GdkEventScroll*);
217         void on_size_allocate (Gtk::Allocation&);
218
219 private:
220         typedef std::vector<CairoCell*> CellMap;
221
222         CellMap cells;
223         boost::shared_ptr<CairoFontDescription> _font;
224         CairoCell* editing_cell;
225         bool _draw_bg;
226         double max_cell_width;
227         double max_cell_height;
228         double _corner_radius;
229         double _xpad;
230         double _ypad;
231         double r;
232         double g;
233         double b;
234         double a;
235         double edit_r;
236         double edit_g;
237         double edit_b;
238         double edit_a;
239         double bg_r;
240         double bg_g;
241         double bg_b;
242         double bg_a;
243
244         CairoCell* find_cell (uint32_t x, uint32_t y);
245         void queue_draw_cell (CairoCell* target);
246         void position_cells_and_get_bbox (GdkRectangle&);
247         void set_cell_sizes (); 
248 };
249
250 #endif /* __libgtmm2ext_cairocell_h__ */