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