Ardour  9.0-pre0-1159-gcb8dd39f31
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 
27 #include "canvas/ruler.h"
28 
29 #include "cue_editor.h"
30 
31 namespace Gtk {
32  class Widget;
33  class HScrollbar;
34 }
35 
36 namespace ArdourCanvas {
37  class Box;
38  class Canvas;
39  class Container;
40  class GtkCanvasViewport;
41  class PianoRollHeader;
42  class ScrollGroup;
43  class Widget;
44 }
45 
46 namespace ArdourWidgets {
47  class ArdourButton;
48  class MetaButton;
49 }
50 
51 class PianorollMidiView;
53 
54 class Pianoroll : public CueEditor
55 {
56  public:
57  Pianoroll (std::string const & name, bool with_transport_controls = false);
59 
64 
65  double visible_canvas_width() const { return _visible_canvas_width; }
67 
68  void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const {}
69 
72 
80 
81  int32_t get_grid_beat_divisions (Editing::GridType gt) const { return 1; }
82  int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) const { return 1; }
83 
85  void set_region (std::shared_ptr<ARDOUR::MidiRegion>);
86  void set_track (std::shared_ptr<ARDOUR::MidiTrack>);
87 
90 
91  double max_extents_scale() const { return 1.2; }
93 
94  void set_mouse_mode (Editing::MouseMode, bool force = false);
95  void step_mouse_mode (bool next);
97  bool internal_editing() const;
98 
100 
102  size_t n_timebars;
103 
106 
107  int set_state (const XMLNode&, int version);
108  XMLNode& get_state () const;
109 
110  void maybe_autoscroll (bool, bool, bool);
111  bool autoscroll_active() const;
112 
113  void midi_action (void (MidiView::*method)());
114 
115  std::list<SelectableOwner*> selectable_owners();
116  void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<SelectableOwner*> const &, ARDOUR::SelectionOperation, bool);
117 
120  Gdk::Cursor* which_trim_cursor (bool left_side) const;
122 
123  void set_visible_channel (int chan);
124  int visible_channel () const { return _visible_channel; }
125 
129 
134 
137 
138  void delete_ ();
139  void paste (float times, bool from_context_menu);
140  void keyboard_paste ();
142 
143  PianorollMidiView* midi_view() const { return view; }
145  bool allow_trim_cursors () const;
146 
147  void shift_midi (Temporal::timepos_t const &, bool model);
149 
150  protected:
151  void load_bindings ();
153 
155  Temporal::RoundMode direction,
156  ARDOUR::SnapPref gpref) const;
157 
161  bool ensure_snap = false) const;
162 
169  bool motion_handler (ArdourCanvas::Item*, GdkEvent*, bool from_autoscroll = false);
174 
176 
177  void escape ();
179 
180  private:
182  std::shared_ptr<ARDOUR::MidiTrack> _track;
185 
187 
188  /* The group containing all other groups that are scrolled vertically
189  and horizontally.
190  */
192 
193  /* The group containing all other groups that are scrolled horizontally ONLY
194  */
197 
198  /* Scroll group for cursors, scrolled horizontally, above everything else
199  */
201 
209 
211 
214 
224 
225  typedef std::map<ArdourWidgets::ArdourButton*,Evoral::Parameter> ParameterButtonMap;
228 
231 
232  void build_canvas ();
236 
238 
240 
241  void metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>&, samplepos_t, samplepos_t, gint);
242 
244  {
245  public:
246  BBTMetric (Pianoroll& ec) : context (&ec) {}
247 
248  void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const {
249  context->metric_get_bbt (marks, lower, upper, maxchars);
250  }
251 
252  private:
254  };
255 
257 
259 
260  /* autoscrolling */
261 
263  void start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const ArdourCanvas::Rect& boundary);
265 
266  sigc::connection _update_connection;
269  void maybe_update ();
272 
273  void unset ();
274 
277 
280  std::atomic<int> idle_update_queued;
283 
289 
291 
293  sigc::signal<void> NoteModeChanged;
294 
296 
298 
299  std::pair<Temporal::timepos_t,Temporal::timepos_t> max_zoom_extent() const;
300 
302 
304 
309 
314 
320 
322 
325  void blink_rec_enable (bool);
326  sigc::connection rec_blink_connection;
327 
329  void add_multi_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, uint16_t channels, int ctl, const std::string& name, ArdourWidgets::MetaButton*);
331 
334 
338 
339  sigc::connection count_in_connection;
341 
342  void count_in (Temporal::timepos_t, unsigned int);
344 
347 };
double _visible_canvas_width
Definition: id.h:34
Pianoroll * context
Definition: pianoroll.h:253
void get_marks(std::vector< ArdourCanvas::Ruler::Mark > &marks, int64_t lower, int64_t upper, int maxchars) const
Definition: pianoroll.h:248
BBTMetric(Pianoroll &ec)
Definition: pianoroll.h:246
void region_prop_change(PBD::PropertyChange const &)
void build_lower_toolbar()
bool leave_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
void set_trigger_bounds(Temporal::timepos_t const &, Temporal::timepos_t const &)
ArdourWidgets::ArdourButton solo_button
Definition: pianoroll.h:307
void select_all_within(Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list< SelectableOwner * > const &, ARDOUR::SelectionOperation, bool)
void add_multi_controller_item(Gtk::Menu_Helpers::MenuList &ctl_items, uint16_t channels, int ctl, const std::string &name, ArdourWidgets::MetaButton *)
ArdourWidgets::MetaButton * cc_dropdown1
Definition: pianoroll.h:221
void set_recording_length(Temporal::BBT_Offset bars)
sigc::signal< void > NoteModeChanged
Definition: pianoroll.h:293
PBD::ScopedConnectionList view_connections
Definition: pianoroll.h:268
void build_upper_toolbar()
void visual_changer(const VisualChange &)
void add_single_controller_item(Gtk::Menu_Helpers::MenuList &ctl_items, int ctl, const std::string &name, ArdourWidgets::MetaButton *)
PBD::ScopedConnectionList capture_connections
Definition: pianoroll.h:281
Temporal::Beats count_in_to
Definition: pianoroll.h:340
int visible_channel() const
Definition: pianoroll.h:124
bool button_release_dispatch(GdkEventButton *)
void register_actions()
std::atomic< int > idle_update_queued
Definition: pianoroll.h:280
void set_trigger_start(Temporal::timepos_t const &)
ArdourCanvas::GtkCanvasViewport * get_canvas_viewport() const
bool play_button_press(GdkEventButton *)
ArdourCanvas::Container * get_trackview_group() const
Definition: pianoroll.h:60
Gtk::EventBox _contents
Definition: pianoroll.h:212
void keyboard_paste()
void trigger_prop_change(PBD::PropertyChange const &)
void set(ARDOUR::TriggerReference &)
void rebuild_parameter_button_map()
std::list< SelectableOwner * > selectable_owners()
Temporal::BBT_Offset rec_length
Definition: pianoroll.h:316
void count_in(Temporal::timepos_t, unsigned int)
void step_mouse_mode(bool next)
void zoom_to_show(Temporal::timecnt_t const &)
void stop_canvas_autoscroll()
ArdourCanvas::GtkCanvas * get_canvas() const
void canvas_allocate(Gtk::Allocation)
Gtk::Widget & contents()
ArdourWidgets::ArdourButton rec_enable_button
Definition: pianoroll.h:305
bool rec_button_press(GdkEventButton *)
bool canvas_pre_event(GdkEvent *)
void delete_()
Gdk::Cursor * which_track_cursor() const
void set_mouse_mode(Editing::MouseMode, bool force=false)
ARDOUR::TriggerReference ref
Definition: pianoroll.h:181
void map_transport_state()
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 *)
Gtk::Label length_label
Definition: pianoroll.h:317
bool user_automation_button_event(GdkEventButton *ev, ArdourWidgets::MetaButton *mb)
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)
double timebar_height
Definition: pianoroll.h:101
void midi_action(void(MidiView::*method)())
void load_bindings()
ArdourCanvas::GtkCanvas * _canvas
Definition: pianoroll.h:184
bool ignore_channel_changes
Definition: pianoroll.h:332
ArdourWidgets::ArdourButton * bender_button
Definition: pianoroll.h:217
void data_captured(samplecnt_t)
void point_selection_changed()
bool button_press_handler_1(ArdourCanvas::Item *, GdkEvent *, ItemType)
void set_trigger_end(Temporal::timepos_t const &)
bool canvas_bg_event(GdkEvent *event, ArdourCanvas::Item *)
double visible_canvas_width() const
Definition: pianoroll.h:65
Gdk::Cursor * which_mode_cursor() const
void build_canvas()
bool canvas_velocity_event(GdkEvent *event, ArdourCanvas::Item *)
void full_zoom_clicked()
PianorollMidiBackground * bg
Definition: pianoroll.h:229
void maybe_update()
ArdourWidgets::ArdourButton * velocity_button
Definition: pianoroll.h:216
ArdourCanvas::Rectangle * meter_bar
Definition: pianoroll.h:207
void note_mode_clicked()
void metric_get_bbt(std::vector< ArdourCanvas::Ruler::Mark > &, samplepos_t, samplepos_t, gint)
std::shared_ptr< ARDOUR::MidiTrack > _track
Definition: pianoroll.h:182
Gtk::HBox play_box
Definition: pianoroll.h:319
bool zoom_in_allocate
Definition: pianoroll.h:303
std::pair< Temporal::timepos_t, Temporal::timepos_t > max_zoom_extent() const
BBTMetric bbt_metric
Definition: pianoroll.h:256
bool canvas_note_event(GdkEvent *event, ArdourCanvas::Item *)
double max_extents_scale() const
Definition: pianoroll.h:91
ArdourCanvas::ScrollGroup * get_cursor_scroll_group() const
Definition: pianoroll.h:89
bool allow_trim_cursors() const
void on_samples_per_pixel_changed()
ArdourCanvas::ScrollGroup * h_scroll_group
Definition: pianoroll.h:195
bool canvas_velocity_base_event(GdkEvent *event, ArdourCanvas::Item *)
PBD::ScopedConnectionList object_connections
Definition: pianoroll.h:267
ArdourCanvas::Rectangle * transport_loop_range_rect
Definition: pianoroll.h:210
void shift_midi(Temporal::timepos_t const &, bool model)
bool button_press_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
bool autoscroll_canvas()
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:68
Temporal::timepos_t snap_to_grid(Temporal::timepos_t const &start, Temporal::RoundMode direction, ARDOUR::SnapPref gpref) const
XMLNode & get_state() const
sigc::connection _update_connection
Definition: pianoroll.h:266
void set_track(std::shared_ptr< ARDOUR::MidiTrack >)
size_t n_timebars
Definition: pianoroll.h:102
ArdourCanvas::PianoRollHeader * prh
Definition: pianoroll.h:208
PianorollMidiView * midi_view() const
Definition: pianoroll.h:143
ArdourWidgets::MetaButton * cc_dropdown2
Definition: pianoroll.h:222
bool internal_editing() const
ArdourCanvas::ScrollGroup * get_hscroll_group() const
Definition: pianoroll.h:88
void start_canvas_autoscroll(bool allow_horiz, bool allow_vert, const ArdourCanvas::Rect &boundary)
bool with_transport_controls
Definition: pianoroll.h:335
bool motion_handler(ArdourCanvas::Item *, GdkEvent *, bool from_autoscroll=false)
bool bang_button_press(GdkEventButton *)
sigc::connection count_in_connection
Definition: pianoroll.h:339
void automation_state_changed()
bool canvas_control_point_event(GdkEvent *event, ArdourCanvas::Item *, ControlPoint *)
RegionSelection region_selection()
Gtk::HScrollbar * _canvas_hscrollbar
Definition: pianoroll.h:186
samplecnt_t data_capture_duration
Definition: pianoroll.h:282
ArdourWidgets::ArdourButton loop_button
Definition: pianoroll.h:308
void make_a_region()
ArdourWidgets::ArdourDropdown length_selector
Definition: pianoroll.h:315
Gtk::Widget & viewport()
void maybe_set_count_in()
int32_t get_grid_beat_divisions(Editing::GridType gt) const
Definition: pianoroll.h:81
void set_samples_per_pixel(samplecnt_t)
void bindings_changed()
void set_visible_channel(int chan)
ArdourCanvas::Container * get_noscroll_group() const
Definition: pianoroll.h:61
ArdourWidgets::ArdourButton * expression_button
Definition: pianoroll.h:219
bool bbt_ruler_event(GdkEvent *)
ArdourCanvas::ScrollGroup * hv_scroll_group
Definition: pianoroll.h:191
void rec_enable_change()
bool idle_data_captured()
ArdourCanvas::Ruler * bbt_ruler
Definition: pianoroll.h:205
ArdourWidgets::MetaButton * cc_dropdown3
Definition: pianoroll.h:223
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:290
Editing::MouseMode current_mouse_mode() const
bool solo_button_press(GdkEventButton *)
ArdourWidgets::ArdourButton * pressure_button
Definition: pianoroll.h:218
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)
ArdourCanvas::GtkCanvasViewport * _canvas_viewport
Definition: pianoroll.h:183
void visible_channel_changed()
void set_note_mode(ARDOUR::NoteMode)
void cut_copy(Editing::CutCopyOp)
int set_state(const XMLNode &, int version)
samplecnt_t current_page_samples() const
void blink_rec_enable(bool)
ArdourCanvas::ScrollGroup * v_scroll_group
Definition: pianoroll.h:196
std::map< ArdourWidgets::ArdourButton *, Evoral::Parameter > ParameterButtonMap
Definition: pianoroll.h:225
void escape()
ARDOUR::NoteMode note_mode() const
Definition: pianoroll.h:127
bool autoscroll_active() const
ArdourCanvas::Rectangle * tempo_bar
Definition: pianoroll.h:206
Pianoroll(std::string const &name, bool with_transport_controls=false)
int32_t get_grid_music_divisions(Editing::GridType gt, uint32_t event_state) const
Definition: pianoroll.h:82
void mouse_mode_toggled(Editing::MouseMode)
ArdourWidgets::ArdourButton play_button
Definition: pianoroll.h:306
void build_zoom_focus_menu()
PianorollMidiView * view
Definition: pianoroll.h:230
Gtk::VBox _toolbox
Definition: pianoroll.h:213
ArdourCanvas::Container * data_group
Definition: pianoroll.h:204
void ruler_locate(GdkEventButton *)
ParameterButtonMap parameter_button_map
Definition: pianoroll.h:226
void reset_user_cc_choice(std::string, Evoral::Parameter param, ArdourWidgets::MetaButton *)
void user_led_click(GdkEventButton *ev, ArdourWidgets::MetaButton *metabutton)
bool key_press_handler(ArdourCanvas::Item *, GdkEvent *, ItemType)
Gtk::HBox button_bar
Definition: pianoroll.h:215
void set_region(std::shared_ptr< ARDOUR::MidiRegion >)
ArdourCanvas::ScrollGroup * cursor_scroll_group
Definition: pianoroll.h:200
ArdourWidgets::ArdourButton * modulation_button
Definition: pianoroll.h:220
bool canvas_cue_end_event(GdkEvent *event, ArdourCanvas::Item *)
void unset()
void maybe_autoscroll(bool, bool, bool)
void set_trigger_length(Temporal::timecnt_t const &)
void paste(float times, bool from_context_menu)
Gtk::HBox rec_box
Definition: pianoroll.h:318
bool loop_button_press(GdkEventButton *)
ArdourCanvas::Container * no_scroll_group
Definition: pianoroll.h:203
void trigger_arm_change()
void automation_led_click(GdkEventButton *, Evoral::ParameterType type, int id)
bool button_press_dispatch(GdkEventButton *)
ArdourCanvas::Container * global_rect_group
Definition: pianoroll.h:202
void update_solo_display()
bool automation_button_event(GdkEventButton *, Evoral::ParameterType type, int id)
bool automation_button_click(Evoral::ParameterType type, int id, ARDOUR::SelectionOperation)
void set_session(ARDOUR::Session *)
sigc::connection rec_blink_connection
Definition: pianoroll.h:326
ARDOUR::NoteMode _note_mode
Definition: pianoroll.h:292
Definition: xml++.h:114
ItemType
Definition: editor_items.h:24
GtkImageIconNameData name
Definition: gtkimage.h:6
PBD::PropertyDescriptor< timepos_t > start
Temporal::samplecnt_t samplecnt_t
Temporal::samplepos_t samplepos_t
CutCopyOp
Definition: editing.h:228
GridType
Definition: editing.h:52
MouseMode
Definition: editing.h:98
uint32_t ParameterType
Definition: ardour_ui.h:191
@ RoundNearest
Round to nearest.