Ardour  9.5-34-g533997b920
pianoroll.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Paul Davis <paul@linuxaudiosystems.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #pragma once
20 
21 #include <map>
22 
23 #include "pbd/timer.h"
24 
25 #include <ytkmm/adjustment.h>
26 #include <ytkmm/radiotoolbutton.h>
27 
28 #include "canvas/ruler.h"
29 #include "widgets/eventboxext.h"
30 
31 #include "cue_editor.h"
32 
33 namespace Gtk {
34  class Widget;
35  class HScrollbar;
36  class ScrolledWindow;
37 }
38 
39 namespace ArdourCanvas {
40  class Box;
41  class Button;
42  class Canvas;
43  class Container;
44  class GtkCanvasViewport;
45  class Icon;
46  class PianoRollHeader;
47  class ScrollGroup;
48  class Widget;
49 }
50 
51 namespace ArdourWidgets {
52  class ArdourButton;
53  class MetaButton;
54 }
55 
56 class CrossCursor;
57 class PianorollMidiView;
59 class MidiInspector;
60 
61 struct ControllerControls : public Gtk::HBox {
62  ControllerControls (int num, std::string const & name, Gtk::RadioButtonGroup& group);
64 
68  int number;
69 
70  bool showing() const;
71  bool editing() const;
72 
73  sigc::signal<void> show_clicked;
74  sigc::signal<void> edit_clicked;
75 
76  void set_showing (bool);
77  void set_editing (bool);
78 };
79 
80 class Pianoroll : public CueEditor
81 {
82  public:
86  };
87 
88 
89  Pianoroll (std::string const & name, bool with_transport_controls = false, bool expandable = false, bool single_region = false);
91 
93 
95 
98 
99  void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const {}
100 
103 
114 
115  int32_t get_grid_beat_divisions (Editing::GridType gt) const { return 1; }
116  int32_t get_grid_music_divisions (Editing::GridType gt) const { return 1; }
117 
118  std::shared_ptr<ARDOUR::MidiTrack> midi_track() const;
119 
120  void add_region (std::shared_ptr<ARDOUR::Region>, std::shared_ptr<ARDOUR::Track>);
121  void replace_region (std::shared_ptr<ARDOUR::Region>, std::shared_ptr<ARDOUR::MidiTrack>);
122  void remove_regions ();
123  void remove_region (std::shared_ptr<ARDOUR::Region>);
124  void set_region (std::shared_ptr<ARDOUR::Region>);
125 
126  double max_extents_scale() const { return 1.2; }
128 
129  void set_mouse_mode (Editing::MouseMode, bool force = false);
130 
131  void midi_action (void (MidiView::*method)());
132 
133  std::list<SelectableOwner*> selectable_owners();
134  void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<SelectableOwner*> const &, ARDOUR::SelectionOperation, bool);
135 
138  Gdk::Cursor* which_trim_cursor (bool left_side) const;
140 
141  void set_visible_channel (int chan);
142  int visible_channel () const { return _visible_channel; }
143 
147 
152 
153  void delete_ ();
154  void paste (float times, bool from_context_menu);
155  void keyboard_paste ();
157 
160  bool allow_trim_cursors () const;
161 
162  void shift_contents (Temporal::timepos_t const &, bool model);
164 
166 
167  void set_show_source (bool);
169 
171  void set_note_highlight (uint8_t note);
172 
173  void apply_note_range (uint8_t lowest, uint8_t highest);
174 
175  void note_entered ();
176  void note_left ();
177 
178  struct AutomationLane {
179  AutomationLane (Evoral::Parameter const &, Pianoroll const &, ArdourCanvas::Item*, uint32_t nth);
181 
182  double height() const { return group->height(); }
183  void deduce_color (uint32_t nth);
184 
190  };
191 
195 
196  bool get_midi_chord (int root_pitch, std::vector<int>& pitches) const;
197 
200 
201  protected:
203  Temporal::RoundMode direction,
204  ARDOUR::SnapPref gpref) const;
205 
209  bool ensure_snap = false) const;
210 
217  bool motion_handler (ArdourCanvas::Item*, GdkEvent*, bool from_autoscroll = false);
222 
223  void escape ();
225 
228 
230  std::string parameter_name (Evoral::Parameter const &) const;
231 
232  private:
239 
244  void toggle_size();
245 
248 
251 
252  bool no_toggle;
254  void add_single_controller_item (Gtk::Menu_Helpers::MenuList&, int, const std::string&);
255  void add_multi_controller_item (Gtk::Menu_Helpers::MenuList&, uint16_t, int, const std::string&);
256 
257  typedef std::map<Evoral::Parameter, AutomationLane*> AutomationLanes;
259 
261 
262  typedef std::map<std::shared_ptr<ARDOUR::Region>, PianorollMidiView*> RegionMidiViewMap;
264  void region_going_away (std::weak_ptr<ARDOUR::Region> region);
265 
267 
268  void build_canvas ();
272 
274 
276  {
277  public:
278  BBTMetric (Pianoroll& ec) : context (&ec) {}
279 
280  void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const {
281  context->metric_get_bbt (marks, lower, upper, maxchars);
282  }
283 
284  private:
286  };
287 
289 
291  void maybe_update ();
293 
294  void unset_region ();
295  void unset_trigger ();
296 
298 
300 
303 
306 
308 
309  sigc::signal<void> NoteModeChanged;
310 
312 
315 
319 
322 
325 
326  void set_note_selection (uint8_t note);
327  void add_note_selection (uint8_t note);
328  void extend_note_selection (uint8_t note);
329  void toggle_note_selection (uint8_t note);
330 
333 
334  void begin_write ();
335  void end_write ();
336 
338 
339  void show_count_in (std::string const &);
340  void hide_count_in ();
341 
342  void instant_save ();
343  void parameter_changed (std::string param);
345 
348 
349  void setup_colors ();
351 
353 
356 
359  void replace_chord (std::vector<int> intervals);
360  void invert_selected_chord (bool up);
361  void drop_selected_chord (std::vector<int> which_notes);
362 
364  sigc::connection selection_connection;
365 
370  static std::map<std::string,std::string> controller_name_map;
371 
374 
377 };
void metric_get_bbt(std::vector< ArdourCanvas::Ruler::Mark > &, samplepos_t, samplepos_t, gint)
bool with_transport_controls
Definition: cue_editor.h:155
std::vector< MidiView * > MidiViews
Definition: id.h:33
Pianoroll * context
Definition: pianoroll.h:285
void get_marks(std::vector< ArdourCanvas::Ruler::Mark > &marks, int64_t lower, int64_t upper, int maxchars) const
Definition: pianoroll.h:280
BBTMetric(Pianoroll &ec)
Definition: pianoroll.h:278
void set_from_rsu(RegionUISettings &)
void user_automation_show_button_click(GdkEventButton *ev, ArdourWidgets::MetaButton *metabutton)
void partition_height()
Gtk::ScrolledWindow * inspector_scroller
Definition: pianoroll.h:358
void build_lower_toolbar()
bool leave_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
void set_trigger_bounds(Temporal::timepos_t const &, Temporal::timepos_t const &)
void select_all_within(Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list< SelectableOwner * > const &, ARDOUR::SelectionOperation, bool)
sigc::signal< void > NoteModeChanged
Definition: pianoroll.h:309
PBD::ScopedConnectionList view_connections
Definition: pianoroll.h:290
void position_playhead_cursor(samplepos_t pos)
void note_mode_chosen(ARDOUR::NoteMode)
ARDOUR::InstrumentInfo * instrument_info() const
void set_note_selection(uint8_t note)
int visible_channel() const
Definition: pianoroll.h:142
bool button_release_dispatch(GdkEventButton *)
void parameter_changed(std::string param)
void update_rulers()
Definition: pianoroll.h:321
void set_trigger_start(Temporal::timepos_t const &)
AutomationLanes automation_lanes
Definition: pianoroll.h:258
static void build_midi_controller_name_map()
void our_midi_view_selection_changed()
void keyboard_paste()
void update_pitch_colors()
ArdourWidgets::ArdourDropdown policy_dropdown
Definition: pianoroll.h:249
void trigger_prop_change(PBD::PropertyChange const &)
void update_tempo_based_rulers()
void extend_note_selection(uint8_t note)
std::list< SelectableOwner * > selectable_owners()
Gtk::Menu _region_context_menu
Definition: pianoroll.h:323
void canvas_allocate(Gtk::Allocation)
Gtk::Widget & contents()
void remove_automation_lane(Evoral::Parameter const &param)
void add_single_controller_item(Gtk::Menu_Helpers::MenuList &, int, const std::string &)
sigc::connection selection_connection
Definition: pianoroll.h:364
void set_inspector_visibility(bool)
void rebuild_region_dropdown()
void delete_()
Gtk::Menu * build_automation_menu()
Gdk::Cursor * which_track_cursor() const
void set_mouse_mode(Editing::MouseMode, bool force=false)
@ ActiveView
Definition: pianoroll.h:85
@ AllViews
Definition: pianoroll.h:84
void inspector_button_clicked()
void map_transport_state()
void invert_selected_chord(bool up)
void snap_to_internal(Temporal::timepos_t &first, Temporal::RoundMode direction=Temporal::RoundNearest, ARDOUR::SnapPref gpref=ARDOUR::SnapToAny_Visual, bool ensure_snap=false) const
bool canvas_cue_start_event(GdkEvent *event, ArdourCanvas::Item *)
bool canvas_enter_leave(GdkEventCrossing *ev)
Gdk::Cursor * which_trim_cursor(bool left_side) const
bool button_press_handler_2(ArdourCanvas::Item *, GdkEvent *, ItemType)
bool button_release_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
void manage_possible_header(Gtk::Allocation &alloc)
void note_left()
void remove_regions()
Gtk::Menu * get_single_region_context_menu()
void midi_action(void(MidiView::*method)())
bool automation_clear_event(GdkEvent *event, Evoral::Parameter)
bool ignore_channel_changes
Definition: pianoroll.h:313
MidiInspector * midi_inspector
Definition: pianoroll.h:357
void set_sensitivities()
void toggle_note_selection(uint8_t note)
ArdourWidgets::ArdourButton inspector_button
Definition: pianoroll.h:372
void begin_write()
void point_selection_changed()
void set_region(std::shared_ptr< ARDOUR::Region >)
bool button_press_handler_1(ArdourCanvas::Item *, GdkEvent *, ItemType)
void set_trigger_end(Temporal::timepos_t const &)
void automation_show_button_click(Evoral::ParameterType type, int id)
static std::map< std::string, std::string > controller_name_map
Definition: pianoroll.h:370
bool canvas_bg_event(GdkEvent *event, ArdourCanvas::Item *)
void popup_region_context_menu(ArdourCanvas::Item *item, GdkEvent *event)
void add_multi_controller_item(Gtk::Menu_Helpers::MenuList &, uint16_t, int, const std::string &)
EditingPolicy editing_policy() const
Definition: pianoroll.h:97
bool single_region
Definition: pianoroll.h:243
void shift_contents(Temporal::timepos_t const &, bool model)
bool get_midi_chord(int root_pitch, std::vector< int > &pitches) const
Gdk::Cursor * which_mode_cursor() const
PianorollMidiView * _active_view
Definition: pianoroll.h:266
void build_canvas()
void pack_inner(Gtk::Box &)
std::string parameter_name(Evoral::Parameter const &) const
bool canvas_velocity_event(GdkEvent *event, ArdourCanvas::Item *)
ArdourWidgets::ArdourButton size_button
Definition: pianoroll.h:240
void set_color_mode(ARDOUR::ColorMode)
int32_t get_grid_music_divisions(Editing::GridType gt) const
Definition: pianoroll.h:116
void build_cc_menu(ArdourWidgets::MetaButton *)
void set_layered_automation(bool)
void automation_active_button_click(Evoral::ParameterType type, int id)
PianorollMidiBackground * bg
Definition: pianoroll.h:260
void maybe_update()
ArdourCanvas::Rectangle * meter_bar
Definition: pianoroll.h:235
void note_mode_clicked()
void apply_note_range(uint8_t lowest, uint8_t highest)
BBTMetric bbt_metric
Definition: pianoroll.h:288
bool canvas_note_event(GdkEvent *event, ArdourCanvas::Item *)
std::shared_ptr< ARDOUR::MidiTrack > midi_track() const
double max_extents_scale() const
Definition: pianoroll.h:126
bool allow_trim_cursors() const
bool canvas_velocity_base_event(GdkEvent *event, ArdourCanvas::Item *)
bool button_press_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
void get_per_region_note_selection(std::list< std::pair< PBD::ID, std::set< std::shared_ptr< Evoral::Note< Temporal::Beats > > > > > &) const
Definition: pianoroll.h:99
Evoral::Parameter automation_by_y(double y)
Temporal::timepos_t snap_to_grid(Temporal::timepos_t const &start, Temporal::RoundMode direction, ARDOUR::SnapPref gpref) const
void drop_selected_chord(std::vector< int > which_notes)
ArdourCanvas::PianoRollHeader * prh
Definition: pianoroll.h:236
PianorollMidiView * midi_view() const
Definition: pianoroll.h:158
ArdourWidgets::ArdourDropdown colors_dropdown
Definition: pianoroll.h:250
bool automation_group_event(GdkEvent *event, Evoral::Parameter)
void toggle_size()
bool motion_handler(ArdourCanvas::Item *, GdkEvent *, bool from_autoscroll=false)
void setup_colors()
RegionMidiViewMap region_view_map
Definition: pianoroll.h:263
bool canvas_control_point_event(GdkEvent *event, ArdourCanvas::Item *, ControlPoint *)
void add_automation_lane(Evoral::Parameter const &param)
bool user_automation_active_button_click(GdkEventButton *ev, ArdourWidgets::MetaButton *mb)
void replace_chord(std::vector< int > intervals)
void set_editing_policy(EditingPolicy)
void session_going_away()
ARDOUR::Quantize * get_quantize_op()
void unset_region()
void make_a_region()
bool expandable
Definition: pianoroll.h:242
void replace_region(std::shared_ptr< ARDOUR::Region >, std::shared_ptr< ARDOUR::MidiTrack >)
bool no_toggle
Definition: pianoroll.h:252
Pianoroll(std::string const &name, bool with_transport_controls=false, bool expandable=false, bool single_region=false)
ArdourWidgets::ArdourDropdown region_dropdown
Definition: pianoroll.h:246
int32_t get_grid_beat_divisions(Editing::GridType gt) const
Definition: pianoroll.h:115
void set_samples_per_pixel(samplecnt_t)
void bindings_changed()
void set_visible_channel(int chan)
void region_going_away(std::weak_ptr< ARDOUR::Region > region)
void unset_trigger()
void end_write()
void set_show_source(bool)
bool idle_data_captured()
void pack_outer(Gtk::Box &)
void instant_save()
void note_entered()
ArdourCanvas::Ruler * bbt_ruler
Definition: pianoroll.h:233
void set_note_highlight(uint8_t note)
Temporal::Beats get_draw_length_as_beats(bool &success, Temporal::timepos_t const &position) const
bool enter_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
int _visible_channel
Definition: pianoroll.h:307
void session_located()
ArdourWidgets::ArdourButton automation_button
Definition: pianoroll.h:241
Temporal::Beats get_grid_type_as_beats(bool &success, Temporal::timepos_t const &position) const
Gdk::Cursor * which_canvas_cursor(ItemType type) const
bool key_release_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
void automation_button_clicked()
void visible_channel_changed()
void cut_copy(Editing::CutCopyOp)
PianorollMidiView * empty_view
Definition: pianoroll.h:376
samplecnt_t current_page_samples() const
void clear_automation_lane(Evoral::Parameter const &param)
std::map< Evoral::Parameter, AutomationLane * > AutomationLanes
Definition: pianoroll.h:257
void escape()
ARDOUR::NoteMode note_mode() const
bool automation_close_event(GdkEvent *event, Evoral::Parameter)
std::map< std::shared_ptr< ARDOUR::Region >, PianorollMidiView * > RegionMidiViewMap
Definition: pianoroll.h:262
ArdourCanvas::Rectangle * tempo_bar
Definition: pianoroll.h:234
void show_count_in(std::string const &)
MidiViews midiviews_from_region_selection(RegionSelection const &) const
void toggle_automation(Evoral::Parameter param)
void motion_track(ArdourCanvas::Duple const &)
void show_automation_for_all()
void hide_count_in()
bool key_press_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
EditingPolicy _editing_policy
Definition: pianoroll.h:237
Temporal::timepos_t source_to_timeline(Temporal::timepos_t const &source_pos) const
ARDOUR::ColorMode _color_mode
Definition: pianoroll.h:238
bool canvas_cue_end_event(GdkEvent *event, ArdourCanvas::Item *)
void add_region(std::shared_ptr< ARDOUR::Region >, std::shared_ptr< ARDOUR::Track >)
void set_trigger_length(Temporal::timecnt_t const &)
void paste(float times, bool from_context_menu)
void remove_region(std::shared_ptr< ARDOUR::Region >)
CrossCursor * xcursor
Definition: pianoroll.h:352
bool button_press_dispatch(GdkEventButton *)
void add_note_selection(uint8_t note)
ARDOUR::ColorMode color_mode() const
Definition: pianoroll.h:227
void set_session(ARDOUR::Session *)
ItemType
Definition: editor_items.h:24
GtkImageIconNameData name
Definition: gtkimage.h:6
PBD::PropertyDescriptor< bool > region
PBD::PropertyDescriptor< timepos_t > start
Temporal::samplecnt_t samplecnt_t
Temporal::samplepos_t samplepos_t
CutCopyOp
Definition: editing.h:241
GridType
Definition: editing.h:53
MouseMode
Definition: editing.h:99
uint32_t ParameterType
Definition: ardour_ui.h:182
@ RoundNearest
Round to nearest.
Gtk::Label name
Definition: pianoroll.h:67
bool showing() const
bool editing() const
sigc::signal< void > show_clicked
Definition: pianoroll.h:73
ArdourWidgets::ArdourButton * edit_button
Definition: pianoroll.h:66
void set_editing(bool)
void set_showing(bool)
ControllerControls(int num, std::string const &name, Gtk::RadioButtonGroup &group)
sigc::signal< void > edit_clicked
Definition: pianoroll.h:74
ArdourWidgets::ArdourButton * show_hide_button
Definition: pianoroll.h:65
ArdourCanvas::Text * label
Definition: pianoroll.h:186
AutomationLane(Evoral::Parameter const &, Pianoroll const &, ArdourCanvas::Item *, uint32_t nth)
void deduce_color(uint32_t nth)
ArdourCanvas::Button * clear_button
Definition: pianoroll.h:189
ArdourCanvas::Line * label_separator
Definition: pianoroll.h:187
double height() const
Definition: pianoroll.h:182
ArdourCanvas::Icon * close_x
Definition: pianoroll.h:188
ArdourCanvas::Rectangle * group
Definition: pianoroll.h:185