X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Futils.cc;h=ba151fe3499d62718b2ea080337526e49666f044;hb=849d80bfcc40fff9a5a58804a48dd98206a72426;hp=777eb6261650bc3c42eec0b58501b343b3e65520;hpb=cf806123ca5faaef483f898daba3f7bd38ec62eb;p=ardour.git diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 777eb62616..ba151fe349 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -45,7 +45,9 @@ #include #include "ardour/rc_configuration.h" #include "ardour/filesystem_paths.h" + #include "canvas/item.h" +#include "canvas/utils.h" #include "ardour_ui.h" #include "debug.h" @@ -62,7 +64,13 @@ using namespace Glib; using namespace PBD; using Gtkmm2ext::Keyboard; -sigc::signal DPIReset; +namespace ARDOUR_UI_UTILS { + sigc::signal DPIReset; +} + +#ifdef PLATFORM_WINDOWS +#define random() rand() +#endif /** Add an element to a menu, settings its sensitivity. @@ -71,7 +79,7 @@ sigc::signal DPIReset; * @param s true to make sensitive, false to make insensitive */ void -add_item_with_sensitivity (Menu_Helpers::MenuList& m, Menu_Helpers::MenuElem e, bool s) +ARDOUR_UI_UTILS::add_item_with_sensitivity (Menu_Helpers::MenuList& m, Menu_Helpers::MenuElem e, bool s) { m.push_back (e); if (!s) { @@ -81,7 +89,7 @@ add_item_with_sensitivity (Menu_Helpers::MenuList& m, Menu_Helpers::MenuElem e, gint -just_hide_it (GdkEventAny */*ev*/, Gtk::Window *win) +ARDOUR_UI_UTILS::just_hide_it (GdkEventAny */*ev*/, Gtk::Window *win) { win->hide (); return 0; @@ -96,7 +104,7 @@ just_hide_it (GdkEventAny */*ev*/, Gtk::Window *win) */ unsigned char* -xpm2rgb (const char** xpm, uint32_t& w, uint32_t& h) +ARDOUR_UI_UTILS::xpm2rgb (const char** xpm, uint32_t& w, uint32_t& h) { static long vals[256], val; uint32_t t, x, y, colors, cpp; @@ -138,7 +146,7 @@ xpm2rgb (const char** xpm, uint32_t& w, uint32_t& h) } unsigned char* -xpm2rgba (const char** xpm, uint32_t& w, uint32_t& h) +ARDOUR_UI_UTILS::xpm2rgba (const char** xpm, uint32_t& w, uint32_t& h) { static long vals[256], val; uint32_t t, x, y, colors, cpp; @@ -200,8 +208,34 @@ xpm2rgba (const char** xpm, uint32_t& w, uint32_t& h) return (savergb); } +/** Returns a Pango::FontDescription given a string describing the font. + * + * If the returned FontDescription does not specify a family, then + * the family is set to "Sans". This mirrors GTK's behaviour in + * gtkstyle.c. + * + * Some environments will force Pango to specify the family + * even if it was not specified in the string describing the font. + * Such environments should be left unaffected by this function, + * since the font family will be left alone. + * + * There may be other similar font specification enforcement + * that we might add here later. + */ Pango::FontDescription -get_font_for_style (string widgetname) +ARDOUR_UI_UTILS::sanitized_font (std::string const& name) +{ + Pango::FontDescription fd (name); + + if (fd.get_family().empty()) { + fd.set_family ("Sans"); + } + + return fd; +} + +Pango::FontDescription +ARDOUR_UI_UTILS::get_font_for_style (string widgetname) { Gtk::Window window (WINDOW_TOPLEVEL); Gtk::Label foobar; @@ -230,7 +264,7 @@ get_font_for_style (string widgetname) } uint32_t -rgba_from_style (string style, uint32_t r, uint32_t g, uint32_t b, uint32_t a, string attr, int state, bool rgba) +ARDOUR_UI_UTILS::rgba_from_style (string style, uint32_t r, uint32_t g, uint32_t b, uint32_t a, string attr, int state, bool rgba) { /* In GTK+2, styles aren't set up correctly if the widget is not attached to a toplevel window that has a screen pointer. @@ -284,12 +318,12 @@ rgba_from_style (string style, uint32_t r, uint32_t g, uint32_t b, uint32_t a, s if (state == Gtk::STATE_NORMAL && rgba) { return (uint32_t) RGBA_TO_UINT(r,g,b,a); } else { - return (uint32_t) RGB_TO_UINT(r,g,b); + return (uint32_t) RGBA_TO_UINT(r,g,b,255); } } bool -rgba_p_from_style (string style, float *r, float *g, float *b, string attr, int state) +ARDOUR_UI_UTILS::rgba_p_from_style (string style, float *r, float *g, float *b, string attr, int state) { static Gtk::Window* window = 0; assert (r && g && b); @@ -336,13 +370,41 @@ rgba_p_from_style (string style, float *r, float *g, float *b, string attr, int } void -set_color (Gdk::Color& c, int rgb) +ARDOUR_UI_UTILS::set_color_from_rgb (Gdk::Color& c, uint32_t rgb) { - c.set_rgb((rgb >> 16)*256, ((rgb & 0xff00) >> 8)*256, (rgb & 0xff)*256); + /* Gdk::Color color ranges are 16 bit, so scale from 8 bit by + multiplying by 256. + */ + c.set_rgb ((rgb >> 16)*256, ((rgb & 0xff00) >> 8)*256, (rgb & 0xff)*256); } +void +ARDOUR_UI_UTILS::set_color_from_rgba (Gdk::Color& c, uint32_t rgba) +{ + /* Gdk::Color color ranges are 16 bit, so scale from 8 bit by + multiplying by 256. + */ + c.set_rgb ((rgba >> 24)*256, ((rgba & 0xff0000) >> 16)*256, ((rgba & 0xff00) >> 8)*256); +} + +uint32_t +ARDOUR_UI_UTILS::gdk_color_to_rgba (Gdk::Color const& c) +{ + /* since alpha value is not available from a Gdk::Color, it is + hardcoded as 0xff (aka 255 or 1.0) + */ + + const uint32_t r = c.get_red_p () * 255.0; + const uint32_t g = c.get_green_p () * 255.0; + const uint32_t b = c.get_blue_p () * 255.0; + const uint32_t a = 0xff; + + return RGBA_TO_UINT (r,g,b,a); +} + + bool -relay_key_press (GdkEventKey* ev, Gtk::Window* win) +ARDOUR_UI_UTILS::relay_key_press (GdkEventKey* ev, Gtk::Window* win) { PublicEditor& ed (PublicEditor::instance()); @@ -358,13 +420,13 @@ relay_key_press (GdkEventKey* ev, Gtk::Window* win) } bool -forward_key_press (GdkEventKey* ev) +ARDOUR_UI_UTILS::forward_key_press (GdkEventKey* ev) { - return PublicEditor::instance().on_key_press_event(ev); + return PublicEditor::instance().on_key_press_event(ev); } bool -emulate_key_event (Gtk::Widget* w, unsigned int keyval) +ARDOUR_UI_UTILS::emulate_key_event (Gtk::Widget* w, unsigned int keyval) { GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET(w->gobj())); GdkKeymap *keymap = gdk_keymap_get_for_display (display); @@ -393,7 +455,7 @@ emulate_key_event (Gtk::Widget* w, unsigned int keyval) } bool -key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) +ARDOUR_UI_UTILS::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) { GtkWindow* win = window.gobj(); GtkWidget* focus = gtk_window_get_focus (win); @@ -524,8 +586,8 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) /* no special handling or there are modifiers in effect: accelerate first */ DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n"); - DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tevent send-event:%1 time:%2 length:%3 string:%4 hardware_keycode:%5 group:%6\n", - ev->send_event, ev->time, ev->length, ev->string, ev->hardware_keycode, ev->group)); + DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tevent send-event:%1 time:%2 length:%3 name %7 string:%4 hardware_keycode:%5 group:%6\n", + ev->send_event, ev->time, ev->length, ev->string, ev->hardware_keycode, ev->group, gdk_keyval_name (ev->keyval))); if (allow_activating) { DEBUG_TRACE (DEBUG::Accelerators, "\tsending to window\n"); @@ -564,7 +626,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) } Glib::RefPtr -get_xpm (std::string name) +ARDOUR_UI_UTILS::get_xpm (std::string name) { if (!xpm_map[name]) { @@ -574,7 +636,7 @@ get_xpm (std::string name) std::string data_file_path; - if(!find_file_in_search_path (spath, name, data_file_path)) { + if(!find_file (spath, name, data_file_path)) { fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg; } @@ -588,25 +650,83 @@ get_xpm (std::string name) return xpm_map[name]; } +vector +ARDOUR_UI_UTILS::get_icon_sets () +{ + Searchpath spath(ARDOUR::ardour_data_search_path()); + spath.add_subdirectory_to_paths ("icons"); + vector r; + + r.push_back (_("default")); + + for (vector::iterator s = spath.begin(); s != spath.end(); ++s) { + + vector entries; + + get_paths (entries, *s, false, false); + + for (vector::iterator e = entries.begin(); e != entries.end(); ++e) { + if (Glib::file_test (*e, Glib::FILE_TEST_IS_DIR)) { + r.push_back (Glib::filename_to_utf8 (Glib::path_get_basename(*e))); + } + } + } + + return r; +} + std::string -get_icon_path (const char* cname) +ARDOUR_UI_UTILS::get_icon_path (const char* cname, string icon_set) { + std::string data_file_path; string name = cname; name += X_(".png"); Searchpath spath(ARDOUR::ardour_data_search_path()); - spath.add_subdirectory_to_paths("icons"); - - std::string data_file_path; + if (!icon_set.empty() && icon_set != _("default")) { - if (!find_file_in_search_path (spath, name, data_file_path)) { - fatal << string_compose (_("cannot find icon image for %1 using %2"), name, spath.to_string()) << endmsg; + /* add "icons/icon_set" but .. not allowed to add both of these at once */ + spath.add_subdirectory_to_paths ("icons"); + spath.add_subdirectory_to_paths (icon_set); + + find_file (spath, name, data_file_path); + } + + if (data_file_path.empty()) { + + if (!icon_set.empty() && icon_set != _("default")) { + warning << string_compose (_("icon \"%1\" not found for icon set \"%2\", fallback to default"), cname, icon_set) << endmsg; + } + + Searchpath def (ARDOUR::ardour_data_search_path()); + def.add_subdirectory_to_paths ("icons"); + + if (!find_file (def, name, data_file_path)) { + fatal << string_compose (_("cannot find icon image for %1 using %2"), name, spath.to_string()) << endmsg; + /*NOTREACHED*/ + } } return data_file_path; } +Glib::RefPtr +ARDOUR_UI_UTILS::get_icon (const char* cname, string icon_set) +{ + Glib::RefPtr img; + try { + img = Gdk::Pixbuf::create_from_file (get_icon_path (cname, icon_set)); + } catch (const Gdk::PixbufError &e) { + cerr << "Caught PixbufError: " << e.what() << endl; + } catch (...) { + error << string_compose (_("Caught exception while loading icon named %1"), cname) << endmsg; + } + + return img; +} + +namespace ARDOUR_UI_UTILS { Glib::RefPtr get_icon (const char* cname) { @@ -621,9 +741,10 @@ get_icon (const char* cname) return img; } +} string -longest (vector& strings) +ARDOUR_UI_UTILS::longest (vector& strings) { if (strings.empty()) { return string (""); @@ -651,7 +772,7 @@ longest (vector& strings) } bool -key_is_legal_for_numeric_entry (guint keyval) +ARDOUR_UI_UTILS::key_is_legal_for_numeric_entry (guint keyval) { /* we assume that this does not change over the life of the process */ @@ -734,8 +855,9 @@ key_is_legal_for_numeric_entry (guint keyval) return false; } + void -set_pango_fontsize () +ARDOUR_UI_UTILS::set_pango_fontsize () { long val = ARDOUR::Config->get_font_scale(); @@ -751,7 +873,7 @@ set_pango_fontsize () } void -reset_dpi () +ARDOUR_UI_UTILS::reset_dpi () { long val = ARDOUR::Config->get_font_scale(); set_pango_fontsize (); @@ -763,7 +885,7 @@ reset_dpi () } void -resize_window_to_proportion_of_monitor (Gtk::Window* window, int max_width, int max_height) +ARDOUR_UI_UTILS::resize_window_to_proportion_of_monitor (Gtk::Window* window, int max_width, int max_height) { Glib::RefPtr screen = window->get_screen (); Gdk::Rectangle monitor_rect; @@ -778,7 +900,7 @@ resize_window_to_proportion_of_monitor (Gtk::Window* window, int max_width, int /** Replace _ with __ in a string; for use with menu item text to make underscores displayed correctly */ string -escape_underscores (string const & s) +ARDOUR_UI_UTILS::escape_underscores (string const & s) { string o; string::size_type const N = s.length (); @@ -796,7 +918,7 @@ escape_underscores (string const & s) /** Replace < and > with < and > respectively to make < > display correctly in markup strings */ string -escape_angled_brackets (string const & s) +ARDOUR_UI_UTILS::escape_angled_brackets (string const & s) { string o = s; boost::replace_all (o, "<", "<"); @@ -805,7 +927,7 @@ escape_angled_brackets (string const & s) } Gdk::Color -unique_random_color (list& used_colors) +ARDOUR_UI_UTILS::unique_random_color (list& used_colors) { Gdk::Color newcolor; @@ -846,7 +968,7 @@ unique_random_color (list& used_colors) } string -rate_as_string (float r) +ARDOUR_UI_UTILS::rate_as_string (float r) { char buf[32]; if (fmod (r, 1000.0f)) { @@ -856,3 +978,28 @@ rate_as_string (float r) } return buf; } + + +string +ARDOUR_UI_UTILS::track_number_to_string ( + int64_t tracknumber, + std::string sep, + std::string postfix + ) +{ + string rv; + if (tracknumber > 0) { + rv = ""; + rv += PBD::to_string (tracknumber, std::dec); + rv += ""; + rv += sep; + } + else if (tracknumber < 0) { + rv = ""; + rv += PBD::to_string (-tracknumber, std::dec); + rv += ""; + rv += sep; + } + rv += Glib::Markup::escape_text(postfix); + return rv; +}