dde4e687f780b61b259366696800cc94d77aa294
[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 #include <cairomm/cairomm.h>
27 #include <gtkmm.h>
28
29 class CairoCell 
30 {
31   public:
32     CairoCell();
33     virtual ~CairoCell() {}
34
35     virtual void render (Cairo::RefPtr<Cairo::Context>&) = 0;
36
37     double x() const { return bbox.x; }
38     double y() const { return bbox.y; }
39     double width() const { return bbox.width; }
40     double height() const { return bbox.height; }
41
42     void set_position (double x, double y) {
43             bbox.x = x;
44             bbox.y = y;
45     }
46
47     bool intersects (GdkRectangle& r) const {
48             return gdk_rectangle_intersect (&r, &bbox, 0);
49     }
50
51     bool covers (double x, double y) const {
52             return bbox.x <= x && bbox.x + bbox.width > x &&
53                     bbox.y <= y && bbox.y + bbox.height > y;
54     }
55
56     double xpad() const { return _xpad; }
57     void   set_xpad (double x) { _xpad = x; }
58
59     void set_visible (bool yn) { _visible = yn; }
60     bool visible() const { return _visible; }
61     virtual void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&) {}
62
63   protected:
64     GdkRectangle bbox;
65     bool _visible;
66     uint32_t _xpad;
67 };
68
69 class CairoBarCell : public CairoCell 
70 {
71   public:
72     CairoBarCell() {};
73     
74     void render (Cairo::RefPtr<Cairo::Context>& context) {
75             context->move_to (bbox.x, bbox.y); 
76             context->set_line_width (bbox.width);
77             context->rel_line_to (0, bbox.height);
78             context->stroke ();
79     }
80
81     void set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font) {
82         Pango::FontMetrics metrics = context->get_metrics (font);
83         bbox.width = 2;
84         bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
85     }
86
87   private:
88 };
89
90 class CairoColonCell : public CairoCell 
91 {
92   public:
93     CairoColonCell() {};
94     
95     void render (Cairo::RefPtr<Cairo::Context>& context) {
96             /* two very small circles, at 1/3 and 2/3 of the height */
97             context->arc (bbox.x, bbox.y + (bbox.height/3.0), 1.5, 0.0, M_PI*2.0);
98             context->fill ();
99             context->arc (bbox.x, bbox.y + (2.0 * bbox.height/3.0), 1.5, 0.0, M_PI*2.0);
100             context->fill ();
101     }
102
103     void set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font) {
104         Pango::FontMetrics metrics = context->get_metrics (font);
105         bbox.width = 3.0;
106         bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
107     }
108
109   private:
110 };
111
112 class CairoTextCell : public CairoCell
113 {
114   public:
115     CairoTextCell (uint32_t width_chars);
116
117     void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&);
118
119     void   set_text (const std::string& txt) {
120             layout->set_text (txt); 
121     }
122     std::string get_text() const {
123             return layout->get_text ();
124     }
125     uint32_t width_chars() const { return _width_chars; }
126
127     void render (Cairo::RefPtr<Cairo::Context>&);
128
129   protected:
130     uint32_t _width_chars;
131     Glib::RefPtr<Pango::Layout> layout;
132 };
133
134 class CairoEditableText : public Gtk::Misc
135 {
136   public:
137     CairoEditableText ();
138     
139     void add_cell (uint32_t id, CairoCell*);
140     CairoCell* get_cell (uint32_t id);
141
142     void set_text (uint32_t id, const std::string& text);
143     
144     void set_colors (double cr, double cg, double cb, double ca) {
145             r = cr;
146             g = cg;
147             b = cb;
148             a = ca;
149             queue_draw ();
150     }
151
152     void set_edit_colors (double cr, double cg, double cb, double ca) {
153             edit_r = cr;
154             edit_g = cg;
155             edit_b = cb;
156             edit_a = ca;
157             queue_draw ();
158     }
159
160     void set_bg (double r, double g, double b, double a) {
161             bg_r = r;
162             bg_g = g;
163             bg_b = b;
164             bg_a = a;
165     }
166
167     bool on_expose_event (GdkEventExpose*);
168     bool on_key_press_event (GdkEventKey*);
169     bool on_key_release_event (GdkEventKey*);
170     bool on_button_press_event (GdkEventButton*);
171     bool on_button_release_event (GdkEventButton*);
172     void on_size_request (GtkRequisition*);
173     void on_size_allocate (Gtk::Allocation&);
174     bool on_focus_in_event (GdkEventFocus*);
175     bool on_focus_out_event (GdkEventFocus*);
176
177     void set_font (const std::string& str) {
178             font = Pango::FontDescription (str);
179     }
180
181   private:
182     typedef std::map<uint32_t,CairoCell*> CellMap;
183
184     CellMap cells;
185     Pango::FontDescription font;
186     uint32_t editing_id;
187     uint32_t editing_pos;
188     double width;
189     double max_cell_height;
190     double height;
191     double corner_radius;
192     double xpad;
193     double ypad;
194     double r;
195     double g;
196     double b;
197     double a;
198     double edit_r;
199     double edit_g;
200     double edit_b;
201     double edit_a;
202     double bg_r;
203     double bg_g;
204     double bg_b;
205     double bg_a;
206
207
208     CairoCell* find_cell (uint32_t x, uint32_t y, uint32_t& cell_id);
209     void edit_next_cell ();
210     void queue_draw_cell (CairoCell* target);
211     void set_text (CairoTextCell* cell, const std::string&);
212 };
213
214 #endif /* __libgtmm2ext_cairocell_h__ */