diff --git a/gtk2_ardour/gtk_pianokeyboard.c b/gtk2_ardour/gtk_pianokeyboard.c index e9212be439..c9a105b713 100644 --- a/gtk2_ardour/gtk_pianokeyboard.c +++ b/gtk2_ardour/gtk_pianokeyboard.c @@ -34,7 +34,15 @@ #include #include #include +#include + #include +#include +#include + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif #include #include @@ -125,9 +133,9 @@ draw_note(PianoKeyboard *pk, cairo_t* cr, int note) } } else if (pk->highlight_grand_piano_range && (note < PIANO_MIN_NOTE || note > PIANO_MAX_NOTE)) { if (is_white) { - cairo_set_source_rgb (cr, 0.8, 0.8, 0.8); + cairo_set_source_rgb (cr, 0.7, 0.7, 0.7); } else { - cairo_set_source_rgb (cr, 0.2, 0.2, 0.2); + cairo_set_source_rgb (cr, 0.3, 0.3, 0.3); } } else { if (is_white) { @@ -150,6 +158,30 @@ draw_note(PianoKeyboard *pk, cairo_t* cr, int note) draw_keyboard_cue (pk, cr); } + if (pk->print_note_label && (note % 12) == 0) { + int tw, th; + char buf[32]; + sprintf (buf, "ArdourMono %dpx", MAX (10, MIN (20, MIN (w / 2 + 3, h / 7)))); + PangoFontDescription* font = pango_font_description_from_string (buf); + sprintf (buf, "C%2d", (note / 12) - 1); + PangoLayout* pl = pango_cairo_create_layout(cr); + pango_layout_set_font_description(pl, font); + pango_layout_set_text (pl, buf, -1); + pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT); + pango_layout_get_pixel_size (pl, &tw, &th); + + if (th < w && tw < h * .3) { + cairo_save(cr); + cairo_move_to (cr, x + (w - th) / 2, h - 3); + cairo_rotate (cr, M_PI / -2.0); + cairo_set_source_rgba (cr, .0, .0, .0, 1.0); + pango_cairo_show_layout(cr, pl); + cairo_restore(cr); + } + g_object_unref(pl); + pango_font_description_free (font); + } + /* We need to redraw black keys that partially obscure the white one. */ if (note < NNOTES - 2 && !pk->notes[note + 1].white) { draw_note(pk, cr, note + 1); @@ -854,11 +886,12 @@ piano_keyboard_new(void) pk->sustain_new_notes = 0; pk->enable_keyboard_cue = FALSE; pk->highlight_grand_piano_range = FALSE; + pk->print_note_label = FALSE; pk->octave = 4; pk->octave_range = 7; pk->note_being_pressed_using_mouse = -1; - pk->min_note = PIANO_MIN_NOTE; - pk->max_note = PIANO_MAX_NOTE; + pk->min_note = 0; + pk->max_note = 127; pk->last_key = 0; pk->monophonic = FALSE; @@ -888,6 +921,13 @@ piano_keyboard_set_grand_piano_highlight (PianoKeyboard *pk, gboolean enabled) gtk_widget_queue_draw(GTK_WIDGET(pk)); } +void +piano_keyboard_show_note_label (PianoKeyboard *pk, gboolean enabled) +{ + pk->print_note_label = enabled; + gtk_widget_queue_draw(GTK_WIDGET(pk)); +} + void piano_keyboard_set_monophonic(PianoKeyboard *pk, gboolean monophonic) { @@ -992,7 +1032,7 @@ piano_keyboard_set_octave_range (PianoKeyboard *pk, int octave_range) pk->min_note = (pk->octave + 0) * 12; break; case 6: - pk->min_note = (pk->octave + 1) * 12; + pk->min_note = (pk->octave - 1) * 12; break; case 7: case 8: @@ -1024,13 +1064,11 @@ piano_keyboard_set_octave_range (PianoKeyboard *pk, int octave_range) pk->min_note = MAX (0, pk->max_note - octave_range * 12); } - printf ("Oct: %d, Range: %d MIDI %d .. %d\n", pk->octave, octave_range, pk->min_note, pk->max_note); - recompute_dimensions(pk); gtk_widget_queue_draw(GTK_WIDGET(pk)); } -gboolean +void piano_keyboard_set_keyboard_layout(PianoKeyboard *pk, const char *layout) { assert(layout); @@ -1048,9 +1086,6 @@ piano_keyboard_set_keyboard_layout(PianoKeyboard *pk, const char *layout) bind_keys_dvorak(pk); } else { - /* Unknown layout name. */ - return TRUE; + assert (0); } - - return FALSE; } diff --git a/gtk2_ardour/gtk_pianokeyboard.h b/gtk2_ardour/gtk_pianokeyboard.h index 70077da508..8e15ae9ef8 100644 --- a/gtk2_ardour/gtk_pianokeyboard.h +++ b/gtk2_ardour/gtk_pianokeyboard.h @@ -59,6 +59,7 @@ struct _PianoKeyboard int sustain_new_notes; gboolean enable_keyboard_cue; gboolean highlight_grand_piano_range; + gboolean print_note_label; int octave; int octave_range; int widget_margin; @@ -89,11 +90,12 @@ void piano_keyboard_set_note_on (PianoKeyboard *pk, int note); void piano_keyboard_set_note_off (PianoKeyboard *pk, int note); void piano_keyboard_set_keyboard_cue (PianoKeyboard *pk, gboolean enabled); void piano_keyboard_set_grand_piano_highlight (PianoKeyboard *pk, gboolean enabled); +void piano_keyboard_show_note_label (PianoKeyboard *pk, gboolean enabled); void piano_keyboard_set_monophonic (PianoKeyboard *pk, gboolean monophonic); void piano_keyboard_set_octave (PianoKeyboard *pk, int octave); void piano_keyboard_set_octave_range(PianoKeyboard *pk, int octave_range); -gboolean piano_keyboard_set_keyboard_layout (PianoKeyboard *pk, const char *layout); +void piano_keyboard_set_keyboard_layout (PianoKeyboard* pk, const char* layout); void piano_keyboard_set_velocities (PianoKeyboard *pk, int min_vel, int max_vel, int key_vel); G_END_DECLS diff --git a/gtk2_ardour/virtual_keyboard_window.cc b/gtk2_ardour/virtual_keyboard_window.cc index 299a380cbb..b8dc7c2482 100644 --- a/gtk2_ardour/virtual_keyboard_window.cc +++ b/gtk2_ardour/virtual_keyboard_window.cc @@ -47,6 +47,7 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () , _yaxis_velocity ("Y-Axis", ArdourButton::led_default_elements) , _highlight_grand_piano ("Grand Piano", ArdourButton::led_default_elements) , _highlight_key_range ("Key Bindings", ArdourButton::led_default_elements) + , _show_note_label ("Label C Key", ArdourButton::led_default_elements) , _send_panic ("Panic", ArdourButton::default_elements) , _piano_key_velocity (*manage (new Adjustment (100, 1, 127, 1, 16))) , _piano_min_velocity (*manage (new Adjustment (1 , 1, 127, 1, 16))) @@ -60,16 +61,17 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () _pianomm->set_flags(Gtk::CAN_FOCUS); _pianomm->add_events(Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); piano_keyboard_set_keyboard_layout (_piano, "QWERTY"); + piano_keyboard_show_note_label (_piano, true); using namespace Menu_Helpers; _keyboard_layout.AddMenuElem (MenuElem ("QWERTY", - sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), 0))); + sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), "QWERTY"))); _keyboard_layout.AddMenuElem (MenuElem ("QWERTZ", - sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), 1))); + sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), "QWERTZ"))); _keyboard_layout.AddMenuElem (MenuElem ("AZERTY", - sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), 2))); + sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), "AZERTY"))); _keyboard_layout.AddMenuElem (MenuElem ("DVORAK", - sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), 3))); + sigc::bind (sigc::mem_fun (*this, &VirtualKeyboardWindow::select_keyboard_layout), "DVORAK"))); _keyboard_layout.set_active (_("QWERTY")); _cfg_display.set_active (false); @@ -77,6 +79,7 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () _yaxis_velocity.set_active (false); _highlight_grand_piano.set_active (false); _highlight_key_range.set_active (false); + _show_note_label.set_active (true); _pitchbend = boost::shared_ptr (new VKBDControl ("PB", 8192, 16383)); _pitch_slider = manage (new VSliderController(&_pitch_adjustment, _pitchbend, 0, PX_SCALE (15))); @@ -88,6 +91,7 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () set_tooltip (_highlight_grand_piano, "Shade keys outside the range of a Grand Piano (A0-C8)."); set_tooltip (_highlight_key_range, "Indicate which notes can be controlled by keyboard-shortcuts."); + set_tooltip (_show_note_label, "When enabled, print octave number on C-Keys"); set_tooltip (_yaxis_velocity, "When enabled, mouse-click y-axis position defines the velocity."); set_tooltip (_piano_octave_key, "The center octave, and lowest octave for keyboard control."); @@ -123,12 +127,13 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () cfg_tbl->attach (*manage (new ArdourVSpacer), 7, 8, 0, 2, SHRINK, FILL, 4, 0); - cfg_tbl->attach (_highlight_grand_piano, 8, 9, 0, 1, FILL, SHRINK, 4, 2); - cfg_tbl->attach (_highlight_key_range, 8, 9, 1, 2, FILL, SHRINK, 4, 2); + cfg_tbl->attach (_highlight_grand_piano, 8, 9, 0, 1, FILL, SHRINK, 4, 1); + cfg_tbl->attach (_highlight_key_range, 8, 9, 1, 2, FILL, SHRINK, 4, 1); cfg_tbl->attach (*manage (new ArdourVSpacer), 9,10, 0, 2, SHRINK, FILL, 4, 0); - cfg_tbl->attach (_keyboard_layout, 10,11, 0, 2, SHRINK, SHRINK, 4, 0); + cfg_tbl->attach (_show_note_label, 10,11, 0, 1, FILL, SHRINK, 4, 1); + cfg_tbl->attach (_keyboard_layout, 10,11, 1, 2, FILL, SHRINK, 4, 1); cfg_tbl->show_all (); /* bank/patch */ @@ -188,8 +193,8 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () box1->pack_start (*tbl, true, false); Box* box2 = manage (new VBox ()); - box2->pack_start (_pgm_display, false, false); - box2->pack_start (_cfg_display, false, false); + box2->pack_start (_pgm_display, false, false, 1); + box2->pack_start (_cfg_display, false, false, 1); box1->pack_start (*box2, false, false); _cfg_box = manage (new HBox ()); @@ -223,12 +228,14 @@ VirtualKeyboardWindow::VirtualKeyboardWindow () _yaxis_velocity.signal_button_release_event().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::toggle_yaxis_velocity), false); _highlight_grand_piano.signal_button_release_event().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::toggle_highlight_piano), false); _highlight_key_range.signal_button_release_event().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::toggle_highlight_key), false); + _show_note_label.signal_button_release_event().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::toggle_note_label), false); _send_panic.signal_button_release_event().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::send_panic_message), false); g_signal_connect (G_OBJECT (_piano), "note-on", G_CALLBACK (VirtualKeyboardWindow::_note_on_event_handler), this); g_signal_connect (G_OBJECT (_piano), "note-off", G_CALLBACK (VirtualKeyboardWindow::_note_off_event_handler), this); update_velocity_settings (0); + update_octave_range (); set_keep_above (true); vbox->show_all(); @@ -260,11 +267,16 @@ VirtualKeyboardWindow::get_state () { XMLNode* node = new XMLNode (X_("VirtualKeyboard")); node->set_property (X_("YAxisVelocity"), _yaxis_velocity.get_active()); + node->set_property (X_("HighlightGrandPiano"), _highlight_grand_piano.get_active()); + node->set_property (X_("HighlightKeyRange"), _highlight_key_range.get_active()); + node->set_property (X_("ShowNoteLabel"), _show_note_label.get_active()); node->set_property (X_("Layout"), _keyboard_layout.get_text ()); node->set_property (X_("Channel"), _piano_channel.get_value_as_int ()); node->set_property (X_("MinVelocity"), _piano_min_velocity.get_value_as_int ()); node->set_property (X_("MaxVelocity"), _piano_max_velocity.get_value_as_int ()); node->set_property (X_("KeyVelocity"), _piano_key_velocity.get_value_as_int ()); + node->set_property (X_("Octave"), _piano_octave_key.get_value_as_int ()); + node->set_property (X_("Range"), _piano_octave_range.get_value_as_int ()); for (int i = 0; i < VKBD_NCTRLS; ++i) { char buf[16]; sprintf (buf, "CC-%d", i); @@ -299,7 +311,19 @@ VirtualKeyboardWindow::set_state (const XMLNode &root) bool a; if (node->get_property(X_("YAxisVelocity"), a)) { - _yaxis_velocity.set_active (a); + _yaxis_velocity.set_active (a); + } + if (node->get_property(X_("HighlightGrandPiano"), a)) { + _highlight_grand_piano.set_active (a); + piano_keyboard_set_grand_piano_highlight (_piano, a); + } + if (node->get_property(X_("HighlightKeyRange"), a)) { + _highlight_key_range.set_active (a); + piano_keyboard_set_keyboard_cue (_piano, a); + } + if (node->get_property(X_("ShowNoteLabel"), a)) { + _show_note_label.set_active (a); + piano_keyboard_show_note_label (_piano, a); } int v; @@ -315,8 +339,16 @@ VirtualKeyboardWindow::set_state (const XMLNode &root) if (node->get_property(X_("KeyVelocity"), v)) { _piano_key_velocity.set_value (v); } + if (node->get_property(X_("Octave"), v)) { + _piano_octave_key.set_value (v); + } + if (node->get_property(X_("Range"), v)) { + _piano_octave_range.set_value (v); + } update_velocity_settings (0); + update_octave_range (); + update_octave_key (); } void @@ -333,23 +365,10 @@ VirtualKeyboardWindow::on_key_press_event (GdkEventKey* ev) } void -VirtualKeyboardWindow::select_keyboard_layout (int l) +VirtualKeyboardWindow::select_keyboard_layout (std::string const& l) { - switch (l) { - default: - case 0: - piano_keyboard_set_keyboard_layout (_piano, "QWERTY"); - break; - case 1: - piano_keyboard_set_keyboard_layout (_piano, "QWERTZ"); - break; - case 2: - piano_keyboard_set_keyboard_layout (_piano, "AZERTY"); - break; - case 3: - piano_keyboard_set_keyboard_layout (_piano, "DVORAK"); - break; - } + piano_keyboard_set_keyboard_layout (_piano, l.c_str()); + _keyboard_layout.set_active (l); } bool @@ -416,6 +435,15 @@ VirtualKeyboardWindow::toggle_highlight_key (GdkEventButton*) return false; } +bool +VirtualKeyboardWindow::toggle_note_label (GdkEventButton*) +{ + bool a = ! _show_note_label.get_active (); + _show_note_label.set_active (a); + piano_keyboard_show_note_label (_piano, a); + return false; +} + bool VirtualKeyboardWindow::send_panic_message (GdkEventButton*) { diff --git a/gtk2_ardour/virtual_keyboard_window.h b/gtk2_ardour/virtual_keyboard_window.h index 44a71867c0..e60dc91e3b 100644 --- a/gtk2_ardour/virtual_keyboard_window.h +++ b/gtk2_ardour/virtual_keyboard_window.h @@ -113,7 +113,7 @@ private: void control_change_event_handler (int, int); void pitch_bend_event_handler (int); - void select_keyboard_layout (int); + void select_keyboard_layout (std::string const&); void update_velocity_settings (int); void update_octave_key (); void update_octave_range (); @@ -125,6 +125,7 @@ private: bool toggle_yaxis_velocity (GdkEventButton*); bool toggle_highlight_piano (GdkEventButton*); bool toggle_highlight_key (GdkEventButton*); + bool toggle_note_label (GdkEventButton*); bool send_panic_message (GdkEventButton*); PianoKeyboard* _piano; @@ -143,6 +144,7 @@ private: ArdourWidgets::ArdourButton _yaxis_velocity; ArdourWidgets::ArdourButton _highlight_grand_piano; ArdourWidgets::ArdourButton _highlight_key_range; + ArdourWidgets::ArdourButton _show_note_label; ArdourWidgets::ArdourButton _send_panic; ArdourWidgets::ArdourDropdown _keyboard_layout;