1 /* 2 * Copyright (C) 2010-2016 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2014-2019 Robin Gareus <robin@gareus.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef _PIANO_KEYBOARD_H_ 21 #define _PIANO_KEYBOARD_H_ 22 23 #include <map> 24 #include <gtkmm/drawingarea.h> 25 26 #include "piano_key_bindings.h" 27 28 #define NNOTES (128) 29 30 class APianoKeyboard : public Gtk::DrawingArea 31 { 32 public: 33 APianoKeyboard (); 34 ~APianoKeyboard (); 35 36 sigc::signal<void, int, int> NoteOn; 37 sigc::signal<void, int> NoteOff; 38 sigc::signal<void> Rest; 39 sigc::signal<void,bool> SustainChanged; 40 sigc::signal<void, int, bool> PitchBend; 41 sigc::signal<void, bool> SwitchOctave; 42 43 void sustain_press (); 44 void sustain_release (); 45 46 void set_note_on (int note); 47 void set_note_off (int note); 48 void reset (); 49 50 void set_grand_piano_highlight (bool enabled); 51 void set_annotate_layout (bool enabled); 52 void set_annotate_octave (bool enabled); 53 54 void set_monophonic (bool monophonic); 55 void set_octave (int octave); 56 void set_octave_range (int octave_range); 57 void set_keyboard_layout (PianoKeyBindings::Layout layout); 58 void set_velocities (int min_vel, int max_vel, int key_vel); 59 60 protected: 61 bool on_key_press_event (GdkEventKey*); 62 bool on_key_release_event (GdkEventKey*); 63 bool on_button_press_event (GdkEventButton*); 64 bool on_button_release_event (GdkEventButton*); 65 bool on_motion_notify_event (GdkEventMotion*); 66 bool on_expose_event (GdkEventExpose*); 67 68 void on_size_request (Gtk::Requisition*); 69 void on_size_allocate (Gtk::Allocation&); 70 71 private: 72 void annotate_layout (cairo_t* cr, int note) const; 73 void annotate_note (cairo_t* cr, int note) const; 74 void draw_note (cairo_t* cr, int note) const; 75 76 void queue_note_draw (int note); 77 78 bool handle_fixed_keys (GdkEventKey*); 79 80 void press_key (int key, int vel); 81 void release_key (int key); 82 void stop_sustained_notes (); 83 void stop_unsustained_notes (); 84 85 int get_note_for_xy (int x, int y) const; 86 int get_velocity_for_note_at_y (int note, int y) const; 87 88 int is_black (int key) const; 89 double black_key_left_shift (int key) const; 90 91 void recompute_dimensions (); 92 93 struct PKNote { PKNotePKNote94 PKNote () 95 : pressed (false) 96 , sustained (false) 97 , white (false) 98 , x (0) 99 , w (0) 100 , h (0) 101 {} 102 103 bool pressed; /* true if key is in pressed down state. */ 104 bool sustained; /* true if note is sustained. */ 105 bool white; /* true if key is white; 0 otherwise. */ 106 int x; /* Distance between the left edge of the key and the left edge of the widget, in pixels. */ 107 int w; /* Width of the key, in pixels. */ 108 int h; /* Height of the key, in pixels. */ 109 }; 110 111 bool _sustain_new_notes; 112 bool _highlight_grand_piano_range; 113 bool _annotate_layout; 114 bool _annotate_octave; 115 int _octave; 116 int _octave_range; 117 int _note_being_pressed_using_mouse; 118 int _min_note; 119 int _max_note; 120 int _last_key; 121 bool _monophonic; 122 int _min_velocity; 123 int _max_velocity; 124 int _key_velocity; 125 126 PKNote _notes[NNOTES]; 127 128 PianoKeyBindings _keyboard_layout; 129 std::map<std::string, int> _note_stack; 130 131 /* these are only valid during expose/draw */ 132 PangoFontDescription* _font_cue; 133 PangoFontDescription* _font_octave; 134 }; 135 136 #endif 137