X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Futils.cc;h=c903e591b496731d1d00717c2686919a883da8dd;hb=e3dd226ffa562d28758555d67961d95723e2a2f0;hp=fa305e6989ad893d1b577ffcccd0c9a7c093474c;hpb=cd12698b9caff8a7fc0006f409cbf317e67fec82;p=ardour.git diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index fa305e6989..c903e591b4 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -64,7 +64,9 @@ 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() @@ -77,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) { @@ -87,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; @@ -102,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; @@ -144,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; @@ -221,7 +223,7 @@ xpm2rgba (const char** xpm, uint32_t& w, uint32_t& h) * that we might add here later. */ Pango::FontDescription -sanitized_font (std::string const& name) +ARDOUR_UI_UTILS::sanitized_font (std::string const& name) { Pango::FontDescription fd (name); @@ -233,7 +235,7 @@ sanitized_font (std::string const& name) } Pango::FontDescription -get_font_for_style (string widgetname) +ARDOUR_UI_UTILS::get_font_for_style (string widgetname) { Gtk::Window window (WINDOW_TOPLEVEL); Gtk::Label foobar; @@ -261,114 +263,8 @@ get_font_for_style (string widgetname) return Pango::FontDescription (pfd); /* make a copy */ } -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) -{ - /* In GTK+2, styles aren't set up correctly if the widget is not - attached to a toplevel window that has a screen pointer. - */ - - static Gtk::Window* window = 0; - - if (window == 0) { - window = new Window (WINDOW_TOPLEVEL); - } - - Gtk::Label foo; - - window->add (foo); - - foo.set_name (style); - foo.ensure_style (); - - GtkRcStyle* rc = foo.get_style()->gobj()->rc_style; - - if (rc) { - if (attr == "fg") { - r = rc->fg[state].red / 257; - g = rc->fg[state].green / 257; - b = rc->fg[state].blue / 257; - - /* what a hack ... "a" is for "active" */ - if (state == Gtk::STATE_NORMAL && rgba) { - a = rc->fg[GTK_STATE_ACTIVE].red / 257; - } - } else if (attr == "bg") { - r = g = b = 0; - r = rc->bg[state].red / 257; - g = rc->bg[state].green / 257; - b = rc->bg[state].blue / 257; - } else if (attr == "base") { - r = rc->base[state].red / 257; - g = rc->base[state].green / 257; - b = rc->base[state].blue / 257; - } else if (attr == "text") { - r = rc->text[state].red / 257; - g = rc->text[state].green / 257; - b = rc->text[state].blue / 257; - } - } else { - warning << string_compose (_("missing RGBA style for \"%1\""), style) << endl; - } - - window->remove (); - - if (state == Gtk::STATE_NORMAL && rgba) { - return (uint32_t) RGBA_TO_UINT(r,g,b,a); - } else { - 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) -{ - static Gtk::Window* window = 0; - assert (r && g && b); - - if (window == 0) { - window = new Window (WINDOW_TOPLEVEL); - } - - Gtk::EventBox foo; - - window->add (foo); - - foo.set_name (style); - foo.ensure_style (); - - GtkRcStyle* rc = foo.get_style()->gobj()->rc_style; - - if (!rc) { - warning << string_compose (_("missing RGBA style for \"%1\""), style) << endl; - return false; - } - if (attr == "fg") { - *r = rc->fg[state].red / 65535.0; - *g = rc->fg[state].green / 65535.0; - *b = rc->fg[state].blue / 65535.0; - } else if (attr == "bg") { - *r = rc->bg[state].red / 65535.0; - *g = rc->bg[state].green / 65535.0; - *b = rc->bg[state].blue / 65535.0; - } else if (attr == "base") { - *r = rc->base[state].red / 65535.0; - *g = rc->base[state].green / 65535.0; - *b = rc->base[state].blue / 65535.0; - } else if (attr == "text") { - *r = rc->text[state].red / 65535.0; - *g = rc->text[state].green / 65535.0; - *b = rc->text[state].blue / 65535.0; - } else { - return false; - } - - window->remove (); - return true; -} - void -set_color_from_rgb (Gdk::Color& c, uint32_t rgb) +ARDOUR_UI_UTILS::set_color_from_rgb (Gdk::Color& c, uint32_t rgb) { /* Gdk::Color color ranges are 16 bit, so scale from 8 bit by multiplying by 256. @@ -377,7 +273,7 @@ set_color_from_rgb (Gdk::Color& c, uint32_t rgb) } void -set_color_from_rgba (Gdk::Color& c, uint32_t rgba) +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. @@ -386,7 +282,7 @@ set_color_from_rgba (Gdk::Color& c, uint32_t rgba) } uint32_t -gdk_color_to_rgba (Gdk::Color const& c) +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) @@ -400,41 +296,9 @@ gdk_color_to_rgba (Gdk::Color const& c) return RGBA_TO_UINT (r,g,b,a); } -uint32_t -contrasting_text_color (uint32_t c) -{ - double r, g, b, a; - ArdourCanvas::color_to_rgba (c, r, g, b, a); - - const double black_r = 0.0; - const double black_g = 0.0; - const double black_b = 0.0; - - const double white_r = 1.0; - const double white_g = 1.0; - const double white_b = 1.0; - - /* Use W3C contrast guideline calculation */ - - double white_contrast = (max (r, white_r) - min (r, white_r)) + - (max (g, white_g) - min (g, white_g)) + - (max (b, white_b) - min (b, white_b)); - - double black_contrast = (max (r, black_r) - min (r, black_r)) + - (max (g, black_g) - min (g, black_g)) + - (max (b, black_b) - min (b, black_b)); - - if (white_contrast > black_contrast) { - /* use white */ - return ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0); - } else { - /* use black */ - return ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0); - } -} bool -relay_key_press (GdkEventKey* ev, Gtk::Window* win) +ARDOUR_UI_UTILS::relay_key_press (GdkEventKey* ev, Gtk::Window* win) { PublicEditor& ed (PublicEditor::instance()); @@ -450,13 +314,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); @@ -484,8 +348,66 @@ emulate_key_event (Gtk::Widget* w, unsigned int keyval) return forward_key_press(&ev); } +static string +show_gdk_event_state (int state) +{ + string s; + if (state & GDK_SHIFT_MASK) { + s += "+SHIFT"; + } + if (state & GDK_LOCK_MASK) { + s += "+LOCK"; + } + if (state & GDK_CONTROL_MASK) { + s += "+CONTROL"; + } + if (state & GDK_MOD1_MASK) { + s += "+MOD1"; + } + if (state & GDK_MOD2_MASK) { + s += "+MOD2"; + } + if (state & GDK_MOD3_MASK) { + s += "+MOD3"; + } + if (state & GDK_MOD4_MASK) { + s += "+MOD4"; + } + if (state & GDK_MOD5_MASK) { + s += "+MOD5"; + } + if (state & GDK_BUTTON1_MASK) { + s += "+BUTTON1"; + } + if (state & GDK_BUTTON2_MASK) { + s += "+BUTTON2"; + } + if (state & GDK_BUTTON3_MASK) { + s += "+BUTTON3"; + } + if (state & GDK_BUTTON4_MASK) { + s += "+BUTTON4"; + } + if (state & GDK_BUTTON5_MASK) { + s += "+BUTTON5"; + } + if (state & GDK_SUPER_MASK) { + s += "+SUPER"; + } + if (state & GDK_HYPER_MASK) { + s += "+HYPER"; + } + if (state & GDK_META_MASK) { + s += "+META"; + } + if (state & GDK_RELEASE_MASK) { + s += "+RELEASE"; + } + + return s; +} 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); @@ -493,6 +415,9 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) bool allow_activating = true; /* consider all relevant modifiers but not LOCK or SHIFT */ const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK)); + GdkModifierType modifier = GdkModifierType (ev->state); + modifier = GdkModifierType (modifier & gtk_accelerator_get_default_mod_mask()); + Gtkmm2ext::possibly_translate_mod_to_make_legal_accelerator(modifier); if (focus) { if (GTK_IS_ENTRY(focus) || Keyboard::some_magic_widget_has_focus()) { @@ -513,14 +438,15 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) #endif - DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 focus = %7 Key event: code = %2 state = %3 special handling ? %4 magic widget focus ? %5 allow_activation ? %6\n", + DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 focus = %7 (%8) Key event: code = %2 state = %3 special handling ? %4 magic widget focus ? %5 allow_activation ? %6\n", win, ev->keyval, - ev->state, + show_gdk_event_state (ev->state), special_handling_of_unmodified_accelerators, Keyboard::some_magic_widget_has_focus(), allow_activating, - focus)); + focus, + (focus ? gtk_widget_get_name (focus) : "no focus widget"))); /* This exists to allow us to override the way GTK handles key events. The normal sequence is: @@ -555,6 +481,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) if (!special_handling_of_unmodified_accelerators) { + /* XXX note that for a brief moment, the conditional above * included "|| (ev->state & mask)" so as to enforce the * implication of special_handling_of_UNMODIFIED_accelerators. @@ -582,29 +509,9 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tactivate (was %1 now %2) without special hanlding of unmodified accels\n", ev->keyval, fakekey)); - GdkModifierType mod = GdkModifierType (ev->state); - - mod = GdkModifierType (mod & gtk_accelerator_get_default_mod_mask()); -#ifdef GTKOSX - /* GTK on OS X is currently (February 2012) setting both - the Meta and Mod2 bits in the event modifier state if - the Command key is down. - - gtk_accel_groups_activate() does not invoke any of the logic - that gtk_window_activate_key() will that sorts out that stupid - state of affairs, and as a result it fails to find a match - for the key event and the current set of accelerators. - - to fix this, if the meta bit is set, remove the mod2 bit - from the modifier. this assumes that our bindings use Primary - which will have set the meta bit in the accelerator entry. - */ - if (mod & GDK_META_MASK) { - mod = GdkModifierType (mod & ~GDK_MOD2_MASK); - } -#endif - - if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, mod)) { + DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tmodified modifier was %1\n", show_gdk_event_state (modifier))); + + if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, modifier)) { DEBUG_TRACE (DEBUG::Accelerators, "\taccel group activated by fakekey\n"); return true; } @@ -616,13 +523,13 @@ 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"); - if (gtk_window_activate_key (win, ev)) { - DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n"); + if (gtk_accel_groups_activate (G_OBJECT(win), ev->keyval, modifier)) { + DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n"); return true; } } else { @@ -641,7 +548,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) if (!gtk_window_propagate_key_event (win, ev)) { DEBUG_TRACE (DEBUG::Accelerators, "\tpropagation didn't handle, so activate\n"); if (allow_activating) { - return gtk_window_activate_key (win, ev); + return gtk_accel_groups_activate (G_OBJECT(win), ev->keyval, modifier); } else { DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n"); } @@ -656,7 +563,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]) { @@ -681,7 +588,7 @@ get_xpm (std::string name) } vector -get_icon_sets () +ARDOUR_UI_UTILS::get_icon_sets () { Searchpath spath(ARDOUR::ardour_data_search_path()); spath.add_subdirectory_to_paths ("icons"); @@ -693,7 +600,7 @@ get_icon_sets () vector entries; - get_files_in_directory (*s, 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)) { @@ -706,11 +613,14 @@ get_icon_sets () } std::string -get_icon_path (const char* cname, string icon_set) +ARDOUR_UI_UTILS::get_icon_path (const char* cname, string icon_set, bool is_image) { std::string data_file_path; string name = cname; - name += X_(".png"); + + if (is_image) { + name += X_(".png"); + } Searchpath spath(ARDOUR::ardour_data_search_path()); @@ -720,10 +630,13 @@ get_icon_path (const char* cname, string icon_set) spath.add_subdirectory_to_paths ("icons"); spath.add_subdirectory_to_paths (icon_set); + find_file (spath, name, data_file_path); + } else { + spath.add_subdirectory_to_paths ("icons"); find_file (spath, name, data_file_path); } - if (data_file_path.empty()) { + if (is_image && 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; @@ -734,7 +647,7 @@ get_icon_path (const char* cname, string icon_set) 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*/ + abort(); /*NOTREACHED*/ } } @@ -742,7 +655,7 @@ get_icon_path (const char* cname, string icon_set) } Glib::RefPtr -get_icon (const char* cname, string icon_set) +ARDOUR_UI_UTILS::get_icon (const char* cname, string icon_set) { Glib::RefPtr img; try { @@ -756,6 +669,7 @@ get_icon (const char* cname, string icon_set) return img; } +namespace ARDOUR_UI_UTILS { Glib::RefPtr get_icon (const char* cname) { @@ -770,9 +684,10 @@ get_icon (const char* cname) return img; } +} string -longest (vector& strings) +ARDOUR_UI_UTILS::longest (vector& strings) { if (strings.empty()) { return string (""); @@ -800,7 +715,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 */ @@ -883,10 +798,11 @@ 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(); + long val = ARDOUR_UI::config()->get_font_scale(); /* FT2 rendering - used by GnomeCanvas, sigh */ @@ -900,9 +816,9 @@ set_pango_fontsize () } void -reset_dpi () +ARDOUR_UI_UTILS::reset_dpi () { - long val = ARDOUR::Config->get_font_scale(); + long val = ARDOUR_UI::config()->get_font_scale(); set_pango_fontsize (); /* Xft rendering */ @@ -912,7 +828,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; @@ -927,7 +843,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 (); @@ -945,7 +861,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, "<", "<"); @@ -954,7 +870,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; @@ -995,7 +911,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)) {