2 Copyright (C) 1999 Paul Barton-Davis
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.
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.
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.
23 #include <gtk/gtkpaned.h>
26 #include <gtkmm2ext/utils.h>
27 #include <gtkmm/widget.h>
28 #include <gtkmm/button.h>
29 #include <gtkmm/window.h>
30 #include <gtkmm/paned.h>
31 #include <gtkmm/comboboxtext.h>
40 // Necessary for gettext
41 (void) bindtextdomain(PACKAGE, LOCALEDIR);
45 Gtkmm2ext::get_ink_pixel_size (Glib::RefPtr<Pango::Layout> layout,
49 Pango::Rectangle ink_rect = layout->get_ink_extents ();
51 width = (ink_rect.get_width() + PANGO_SCALE / 2) / PANGO_SCALE;
52 height = (ink_rect.get_height() + PANGO_SCALE / 2) / PANGO_SCALE;
56 get_pixel_size (Glib::RefPtr<Pango::Layout> layout,
60 layout->get_pixel_size (width, height);
64 Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w, const gchar *text,
65 gint hpadding, gint vpadding)
71 get_pixel_size (w.create_pango_layout (text), width, height);
72 w.set_size_request(width + hpadding, height + vpadding);
76 Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w,
77 const std::vector<std::string>& strings,
78 gint hpadding, gint vpadding)
86 for (vector<string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
87 get_pixel_size (w.create_pango_layout (*i), width, height);
88 width_max = max(width_max,width);
89 height_max = max(height_max, height);
91 w.set_size_request(width_max + hpadding, height_max + vpadding);
95 demultiply_alpha (guint8 src,
98 /* cairo pixel buffer data contains RGB values with the alpha
101 GdkPixbuf pixel buffer data contains RGB values without the
104 this removes the alpha component from the cairo version and
105 returns the GdkPixbuf version.
107 return alpha ? ((guint (src) << 8) - src) / alpha : 0;
111 convert_bgra_to_rgba (guint8 const* src,
116 guint8 const* src_pixel = src;
117 guint8* dst_pixel = dst;
119 /* cairo pixel data is endian-dependent ARGB with A in the most significant 8 bits,
120 with premultipled alpha values (see preceding function)
122 GdkPixbuf pixel data is non-endian-dependent RGBA with R in the lowest addressable
123 8 bits, and non-premultiplied alpha values.
125 convert from the cairo values to the GdkPixbuf ones.
128 for (int y = 0; y < height; y++) {
129 for (int x = 0; x < width; x++) {
130 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
131 /* Cairo [ B G R A ] is actually [ B G R A ] in memory SOURCE
133 Pixbuf [ R G B A ] is actually [ R G B A ] in memory DEST
135 dst_pixel[0] = demultiply_alpha (src_pixel[2],
136 src_pixel[3]); // R [0] <= [ 2 ]
137 dst_pixel[1] = demultiply_alpha (src_pixel[1],
138 src_pixel[3]); // G [1] <= [ 1 ]
139 dst_pixel[2] = demultiply_alpha (src_pixel[0],
140 src_pixel[3]); // B [2] <= [ 0 ]
141 dst_pixel[3] = src_pixel[3]; // alpha
143 #elif G_BYTE_ORDER == G_BIG_ENDIAN
144 /* Cairo [ B G R A ] is actually [ A R G B ] in memory SOURCE
146 Pixbuf [ R G B A ] is actually [ R G B A ] in memory DEST
148 dst_pixel[0] = demultiply_alpha (src_pixel[1],
149 src_pixel[0]); // R [0] <= [ 1 ]
150 dst_pixel[1] = demultiply_alpha (src_pixel[2],
151 src_pixel[0]); // G [1] <= [ 2 ]
152 dst_pixel[2] = demultiply_alpha (src_pixel[3],
153 src_pixel[0]); // B [2] <= [ 3 ]
154 dst_pixel[3] = src_pixel[0]; // alpha
157 #error ardour does not currently support PDP-endianess
166 Glib::RefPtr<Gdk::Pixbuf>
167 Gtkmm2ext::pixbuf_from_string(const string& name, Pango::FontDescription* font, int clip_width, int clip_height, Gdk::Color fg)
169 static Glib::RefPtr<Gdk::Pixbuf>* empty_pixbuf = 0;
172 if (empty_pixbuf == 0) {
173 empty_pixbuf = new Glib::RefPtr<Gdk::Pixbuf>;
174 *empty_pixbuf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, clip_width, clip_height);
176 return *empty_pixbuf;
179 Glib::RefPtr<Gdk::Pixbuf> buf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, clip_width, clip_height);
181 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, clip_width, clip_height);
182 cairo_t* cr = cairo_create (surface);
183 cairo_text_extents_t te;
185 cairo_set_source_rgba (cr, fg.get_red_p(), fg.get_green_p(), fg.get_blue_p(), 1.0);
186 cairo_select_font_face (cr, font->get_family().c_str(),
187 CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
188 cairo_set_font_size (cr, font->get_size() / Pango::SCALE);
189 cairo_text_extents (cr, name.c_str(), &te);
191 cairo_move_to (cr, 0.5, int (0.5 - te.height / 2 - te.y_bearing + clip_height / 2));
192 cairo_show_text (cr, name.c_str());
194 convert_bgra_to_rgba(cairo_image_surface_get_data (surface), buf->get_pixels(), clip_width, clip_height);
197 cairo_surface_destroy(surface);
203 Gtkmm2ext::set_popdown_strings (Gtk::ComboBoxText& cr, const vector<string>& strings, bool set_size, gint hpadding, gint vpadding)
205 vector<string>::const_iterator i;
212 for (i = strings.begin(); i != strings.end(); ++i) {
213 if ((*i).find_first_of ("gy") != string::npos) {
214 /* contains a descender */
219 if (i == strings.end()) {
221 /* make a copy of the strings then add one that has a descener */
224 copy.push_back ("g");
225 set_size_request_to_display_given_text (cr, copy, COMBO_FUDGE+10+hpadding, 15+vpadding);
228 set_size_request_to_display_given_text (cr, strings, COMBO_FUDGE+10+hpadding, 15+vpadding);
232 for (i = strings.begin(); i != strings.end(); ++i) {
238 Gtkmm2ext::get_paned_handle (Gtk::Paned& paned)
240 return GTK_PANED(paned.gobj())->handle;
244 Gtkmm2ext::set_decoration (Gtk::Window* win, Gdk::WMDecoration decor)
246 win->get_window()->set_decorations (decor);
249 void Gtkmm2ext::set_treeview_header_as_default_label(Gtk::TreeViewColumn* c)
251 gtk_tree_view_column_set_widget( c->gobj(), GTK_WIDGET(0) );
255 Gtkmm2ext::detach_menu (Gtk::Menu& menu)
257 /* its possible for a Gtk::Menu to have no gobj() because it has
258 not yet been instantiated. Catch this and provide a safe
262 if (menu.get_attach_widget()) {
269 Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
271 int fakekey = GDK_VoidSymbol;
275 case GDK_ISO_Left_Tab:
280 fakekey = GDK_uparrow;
284 fakekey = GDK_downarrow;
288 fakekey = GDK_rightarrow;
292 fakekey = GDK_leftarrow;
296 fakekey = GDK_3270_Enter;
307 if (fakekey != GDK_VoidSymbol) {
316 Gtkmm2ext::possibly_translate_legal_accelerator_to_real_key (uint32_t keyval)
351 Gtkmm2ext::physical_screen_height (Glib::RefPtr<Gdk::Window> win)
353 GdkScreen* scr = gdk_screen_get_default();
357 gint monitor = gdk_screen_get_monitor_at_window (scr, win->gobj());
358 gdk_screen_get_monitor_geometry (scr, monitor, &r);
361 return gdk_screen_get_height (scr);
366 Gtkmm2ext::physical_screen_width (Glib::RefPtr<Gdk::Window> win)
368 GdkScreen* scr = gdk_screen_get_default();
372 gint monitor = gdk_screen_get_monitor_at_window (scr, win->gobj());
373 gdk_screen_get_monitor_geometry (scr, monitor, &r);
376 return gdk_screen_get_width (scr);