#include <cstdlib>
#include <cctype>
#include <fstream>
+#include <list>
#include <sys/stat.h>
#include <libart_lgpl/art_misc.h>
#include <gtkmm/rc.h>
#include "ardour/filesystem_paths.h"
#include "ardour_ui.h"
+#include "debug.h"
#include "public_editor.h"
#include "keyboard.h"
#include "utils.h"
return new ArdourCanvas::Points (npoints);
}
-Pango::FontDescription*
+Pango::FontDescription
get_font_for_style (string widgetname)
{
Gtk::Window window (WINDOW_TOPLEVEL);
PangoContext* ctxt = (PangoContext*) pango_layout_get_context ((PangoLayout*) layout->gobj());
pfd = pango_context_get_font_description (ctxt);
- return new Pango::FontDescription (pfd, true); /* make a copy */
+ return Pango::FontDescription (pfd); /* make a copy */
}
- return new Pango::FontDescription (pfd, true); /* make a copy */
+ return Pango::FontDescription (pfd); /* make a copy */
}
uint32_t
return PublicEditor::instance().on_key_press_event(ev);
}
-#ifdef GTKOSX
-static guint
-osx_keyval_without_alt (guint accent_keyval)
-{
- switch (accent_keyval) {
- case GDK_oe:
- return GDK_q;
- case GDK_registered:
- return GDK_r;
- case GDK_dagger:
- return GDK_t;
- case GDK_yen:
- return GDK_y;
- case GDK_diaeresis:
- return GDK_u;
- case GDK_oslash:
- return GDK_o;
- case GDK_Greek_pi:
- return GDK_p;
- case GDK_leftdoublequotemark:
- return GDK_bracketleft;
- case GDK_leftsinglequotemark:
- return GDK_bracketright;
- case GDK_guillemotleft:
- return GDK_backslash;
- case GDK_aring:
- return GDK_a;
- case GDK_ssharp:
- return GDK_s;
- case GDK_partialderivative:
- return GDK_d;
- case GDK_function:
- return GDK_f;
- case GDK_copyright:
- return GDK_g;
- case GDK_abovedot:
- return GDK_h;
- case GDK_notsign:
- return GDK_l;
- case GDK_ellipsis:
- return GDK_semicolon;
- case GDK_ae:
- return GDK_apostrophe;
- case GDK_Greek_OMEGA:
- return GDK_z;
- case GDK_ccedilla:
- return GDK_c;
- case GDK_radical:
- return GDK_v;
- case GDK_integral:
- return GDK_b;
- case GDK_mu:
- return GDK_m;
- case GDK_lessthanequal:
- return GDK_comma;
- case GDK_greaterthanequal:
- return GDK_period;
- case GDK_division:
- return GDK_slash;
- default:
- break;
- }
-
- return GDK_VoidSymbol;
-}
-#endif
-
bool
key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
{
GtkWidget* focus = gtk_window_get_focus (win);
bool special_handling_of_unmodified_accelerators = false;
bool allow_activating = true;
+ /* consider all relevant modifiers but not LOCK or SHIFT */
+ const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
-#undef DEBUG_ACCELERATOR_HANDLING
-#ifdef DEBUG_ACCELERATOR_HANDLING
- //bool debug = (getenv ("ARDOUR_DEBUG_ACCELERATOR_HANDLING") != 0);
- bool debug=true;
-#endif
if (focus) {
if (GTK_IS_ENTRY(focus) || Keyboard::some_magic_widget_has_focus()) {
special_handling_of_unmodified_accelerators = true;
}
#endif
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "Win = " << win << " Key event: code = " << ev->keyval << " state = " << hex << ev->state << dec << " special handling ? "
- << special_handling_of_unmodified_accelerators
- << " magic widget focus ? "
- << Keyboard::some_magic_widget_has_focus()
- << " allow_activation ? "
- << allow_activating
- << endl;
- }
-#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",
+ win,
+ ev->keyval,
+ ev->state,
+ special_handling_of_unmodified_accelerators,
+ Keyboard::some_magic_widget_has_focus(),
+ allow_activating,
+ focus));
/* This exists to allow us to override the way GTK handles
key events. The normal sequence is:
all "normal text" accelerators.
*/
-#ifdef GTKOSX
if (!special_handling_of_unmodified_accelerators) {
- if (ev->state & GDK_MOD1_MASK) {
- /* we're not in a text entry or "magic focus" widget so we don't want OS X "special-character"
- text-style handling of alt-<key>. change the keyval back to what it would be without
- the alt key. this way, we see <alt>-v rather than <alt>-radical and so on.
- */
- guint keyval_without_alt = osx_keyval_without_alt (ev->keyval);
-
- if (keyval_without_alt != GDK_VoidSymbol) {
-#ifdef DEBUG_ACCELERATOR_HANDLING
- cerr << "Remapped " << gdk_keyval_name (ev->keyval) << " to " << gdk_keyval_name (keyval_without_alt) << endl;
-
-#endif ev->keyval = keyval_without_alt;
- }
- }
- }
-#endif
- 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.
+ * however, this forces any key that GTK doesn't allow and that
+ * we have an alternative (see next comment) for to be
+ * automatically sent through the accel groups activation
+ * pathway, which prevents individual widgets & canvas items
+ * from ever seeing it if is used by a key binding.
+ *
+ * specifically, this hid Ctrl-down-arrow from MIDI region
+ * views because it is also bound to an action.
+ *
+ * until we have a robust, clean binding system, this
+ * quirk will have to remain in place.
+ */
/* pretend that certain key events that GTK does not allow
to be used as accelerators are actually something that
- it does allow.
+ it does allow. but only where there are no modifiers.
*/
uint32_t fakekey = ev->keyval;
if (Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
+ DEBUG_TRACE (DEBUG::Accelerators, "\taccel group activated by fakekey\n");
return true;
}
}
}
- /* consider all relevant modifiers but not LOCK or SHIFT */
-
- guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
-
if (!special_handling_of_unmodified_accelerators || (ev->state & mask)) {
/* no special handling or there are modifiers in effect: accelerate first */
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "\tactivate, then propagate\n";
- }
-#endif
+ DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n");
if (allow_activating) {
if (gtk_window_activate_key (win, ev)) {
return true;
}
+ } else {
+ DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n");
}
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "\tnot accelerated, now propagate\n";
- }
-#endif
+ DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n");
+
return gtk_window_propagate_key_event (win, ev);
}
/* no modifiers, propagate first */
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "\tpropagate, then activate\n";
- }
-#endif
- if (!gtk_window_propagate_key_event (win, ev)) {
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "\tpropagation didn't handle, so activate\n";
- }
-#endif
+ DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate, then activate\n");
+ 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);
+ } else {
+ DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n");
}
} else {
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "\thandled by propagate\n";
- }
-#endif
+ DEBUG_TRACE (DEBUG::Accelerators, "\thandled by propagate\n");
return true;
}
-#ifdef DEBUG_ACCELERATOR_HANDLING
- if (debug) {
- cerr << "\tnot handled\n";
- }
-#endif
+ DEBUG_TRACE (DEBUG::Accelerators, "\tnot handled\n");
return true;
}
return o;
}
-
+Gdk::Color
+unique_random_color (list<Gdk::Color>& used_colors)
+{
+ Gdk::Color newcolor;
+
+ while (1) {
+
+ /* avoid neon/glowing tones by limiting them to the
+ "inner section" (paler) of a color wheel/circle.
+ */
+
+ const int32_t max_saturation = 48000; // 65535 would open up the whole color wheel
+
+ newcolor.set_red (random() % max_saturation);
+ newcolor.set_blue (random() % max_saturation);
+ newcolor.set_green (random() % max_saturation);
+
+ if (used_colors.size() == 0) {
+ used_colors.push_back (newcolor);
+ return newcolor;
+ }
+
+ for (list<Gdk::Color>::iterator i = used_colors.begin(); i != used_colors.end(); ++i) {
+ Gdk::Color c = *i;
+ float rdelta, bdelta, gdelta;
+
+ rdelta = newcolor.get_red() - c.get_red();
+ bdelta = newcolor.get_blue() - c.get_blue();
+ gdelta = newcolor.get_green() - c.get_green();
+
+ if (sqrt (rdelta*rdelta + bdelta*bdelta + gdelta*gdelta) > 25.0) {
+ used_colors.push_back (newcolor);
+ return newcolor;
+ }
+ }
+
+ /* XXX need throttle here to make sure we don't spin for ever */
+ }
+}