large-scale refactoring of Pianoroll, CueEditor and AudioClipEditor

Enables code-sharing between "clip editors"
This commit is contained in:
Paul Davis 2025-07-29 14:55:46 -06:00
parent 81ca93bdfb
commit 1d4e3940d1
24 changed files with 2673 additions and 2668 deletions

View file

@ -2251,6 +2251,9 @@ ARDOUR_UI::save_state_canfail (string name, bool switch_to_it)
if ((ret = _session->save_state (name, false, switch_to_it)) != 0) { if ((ret = _session->save_state (name, false, switch_to_it)) != 0) {
return ret; return ret;
} }
std::string rus_path = Glib::build_filename (_session->session_directory().root_path(), "rus.xml");
region_ui_settings_manager.save (rus_path);
} }
save_ardour_state (); /* XXX cannot fail? yeah, right ... */ save_ardour_state (); /* XXX cannot fail? yeah, right ... */

View file

@ -89,6 +89,7 @@
#include "ardour_window.h" #include "ardour_window.h"
#include "editing.h" #include "editing.h"
#include "enums.h" #include "enums.h"
#include "region_ui_settings.h"
#include "shuttle_control.h" #include "shuttle_control.h"
#include "startup_fsm.h" #include "startup_fsm.h"
#include "transport_control.h" #include "transport_control.h"
@ -419,6 +420,8 @@ public:
void gui_idle_handler (); void gui_idle_handler ();
RegionUISettingsManager region_ui_settings_manager;
protected: protected:
friend class PublicEditor; friend class PublicEditor;

View file

@ -88,7 +88,6 @@ ARDOUR_UI::we_have_dependents ()
mixer->monitor_section().use_others_actions (); mixer->monitor_section().use_others_actions ();
StepEntry::setup_actions_and_bindings (); StepEntry::setup_actions_and_bindings ();
ClipEditorBox::init ();
RegionEditor::setup_actions_and_bindings (); RegionEditor::setup_actions_and_bindings ();
setup_action_tooltips (); setup_action_tooltips ();

View file

@ -80,6 +80,7 @@ ARDOUR_UI::audioengine_became_silent ()
pay_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://ardour.org/download"))); pay_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://ardour.org/download")));
subscribe_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://ardour.org/subscribe"))); subscribe_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://ardour.org/subscribe")));
msg.get_vbox()->pack_start (pay_label); msg.get_vbox()->pack_start (pay_label);
msg.get_vbox()->pack_start (pay_button_box); msg.get_vbox()->pack_start (pay_button_box);
msg.get_vbox()->pack_start (subscribe_label); msg.get_vbox()->pack_start (subscribe_label);

View file

@ -599,6 +599,15 @@ ARDOUR_UI::load_session_stage_two (const std::string& path, const std::string& s
msg.hide (); msg.hide ();
} }
{
if (new_session) {
std::string rus_path = Glib::build_filename (new_session->session_directory().root_path(), "rus.xml");
region_ui_settings_manager.load (rus_path);
} else {
region_ui_settings_manager.clear ();
}
}
/* Now the session been created, add the transport controls */ /* Now the session been created, add the transport controls */
new_session->add_controllable(roll_controllable); new_session->add_controllable(roll_controllable);
@ -611,6 +620,7 @@ ARDOUR_UI::load_session_stage_two (const std::string& path, const std::string& s
set_session (new_session); set_session (new_session);
if (_session) { if (_session) {
_session->set_clean (); _session->set_clean ();
} }
@ -620,6 +630,7 @@ ARDOUR_UI::load_session_stage_two (const std::string& path, const std::string& s
flush_pending (10); flush_pending (10);
} }
retval = 0; retval = 0;
if (!mix_template.empty ()) { if (!mix_template.empty ()) {

View file

@ -41,12 +41,16 @@
#include "widgets/ardour_button.h" #include "widgets/ardour_button.h"
#include "widgets/ardour_icon.h" #include "widgets/ardour_icon.h"
#include "ardour_ui.h"
#include "audio_clip_editor.h" #include "audio_clip_editor.h"
#include "audio_clock.h" #include "audio_clock.h"
#include "editor_automation_line.h" #include "editor_automation_line.h"
#include "editor_cursors.h"
#include "editor_drag.h"
#include "control_point.h" #include "control_point.h"
#include "editor.h" #include "editor.h"
#include "region_view.h" #include "region_view.h"
#include "verbose_cursor.h"
#include "ui_config.h" #include "ui_config.h"
#include "pbd/i18n.h" #include "pbd/i18n.h"
@ -60,33 +64,11 @@ using namespace ArdourWidgets;
using std::max; using std::max;
using std::min; using std::min;
Glib::RefPtr<Gtk::ActionGroup> ClipEditorBox::clip_editor_actions;
void
ClipEditorBox::init ()
{
Bindings* bindings = Bindings::get_bindings (X_("Clip Editing"));
register_clip_editor_actions (bindings);
}
void
ClipEditorBox::register_clip_editor_actions (Bindings* clip_editor_bindings)
{
clip_editor_actions = ActionManager::create_action_group (clip_editor_bindings, X_("ClipEditing"));
/* two versions to allow same action for Delete and Backspace */
// ActionManager::register_action (clip_editor_actions, X_("zoom-in"), _("Zoom In"), sigc::mem_fun (*this, &ClipEditorBox::zoom_in));
// ActionManager::register_action (clip_editor_actions, X_("zoom-in"), _("Zoom In"), sigc::mem_fun (*this, &ClipEditorBox::zoom_out));
}
void void
AudioClipEditor::ClipBBTMetric::get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const AudioClipEditor::ClipBBTMetric::get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const
{ {
TriggerPtr trigger (tref.trigger()); TriggerPtr trigger (tref.trigger());
if (!trigger) { if (!trigger) {
std::cerr << "No trigger\n";
return; return;
} }
@ -121,46 +103,153 @@ AudioClipEditor::ClipBBTMetric::get_marks (std::vector<ArdourCanvas::Ruler::Mark
} }
} }
AudioClipEditor::AudioClipEditor () AudioClipEditor::AudioClipEditor (std::string const & name, bool with_transport)
: clip_metric (0) : CueEditor (name, with_transport)
, _spp (0) , clip_metric (nullptr)
, scroll_fraction (0) , scroll_fraction (0)
, current_line_drag (0) , current_line_drag (0)
, current_scroll_drag (0)
{ {
const double scale = UIConfiguration::instance ().get_ui_scale (); build_upper_toolbar ();
build_canvas ();
build_lower_toolbar ();
frame = new ArdourCanvas::Rectangle (root ()); load_bindings ();
frame->name = "audio clip editor frame"; register_actions ();
frame->set_fill (false);
frame->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::event_handler));
/* Scroll bar does not scroll and it outside the frame */ build_grid_type_menu ();
}
scroll_bar_trough = new ArdourCanvas::Rectangle (root ()); void
scroll_bar_handle = new ArdourCanvas::Rectangle (scroll_bar_trough); AudioClipEditor::load_shared_bindings ()
scroll_bar_handle->set_outline (false); {
scroll_bar_handle->set_corner_radius (5.); /* Full shared binding loading must have preceded this in some other EditingContext */
scroll_bar_handle->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::scroll_event_handler)); assert (!need_shared_actions);
scroll_bar_handle->disable_scroll_translation ();
/* A scrolling container for our waves and lines etc. */ Bindings* b = Bindings::get_bindings (X_("Editing"));
waves_container = new ArdourCanvas::ScrollGroup (frame, ScrollGroup::ScrollsHorizontally); /* Copy each shared bindings but give them a new name, which will make them refer to actions
add_scroller (*waves_container); * named after this EditingContext (ie. unique to this EC)
*/
ruler_container = new ArdourCanvas::Container (waves_container); Bindings* shared_bindings = new Bindings (editor_name(), *b);
ruler = new ArdourCanvas::Ruler (ruler_container, 0); register_common_actions (shared_bindings, editor_name());
ruler->name = "Clip Editor"; shared_bindings->associate ();
ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
ruler->set_fill_color (UIConfiguration::instance().color (X_("theme:bg1"))); /* Attach bindings to the canvas for this editing context */
ruler->set_outline_color (UIConfiguration::instance().color (X_("theme:contrasting less")));
bindings.push_back (shared_bindings);
}
void
AudioClipEditor::pack_inner (Gtk::Box& box)
{
box.pack_start (snap_box, false, false);
box.pack_start (grid_box, false, false);
}
void
AudioClipEditor::pack_outer (Gtk::Box& box)
{
if (with_transport_controls) {
box.pack_start (play_box, false, false);
}
std::cerr << "pack up rec box\n";
box.pack_start (rec_box, false, false);
box.pack_start (follow_playhead_button, false, false);
}
void
AudioClipEditor::build_lower_toolbar ()
{
_toolbox.pack_start (*_canvas_hscrollbar, false, false);
}
void
AudioClipEditor::build_canvas ()
{
_canvas.set_background_color (UIConfiguration::instance().color ("arrange base"));
_canvas.signal_event().connect (sigc::mem_fun (*this, &CueEditor::canvas_pre_event), false);
_canvas.use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes);
_canvas.PreRender.connect (sigc::mem_fun(*this, &EditingContext::pre_render));
/* scroll group for items that should not automatically scroll
* (e.g verbose cursor). It shares the canvas coordinate space.
*/
no_scroll_group = new ArdourCanvas::Container (_canvas.root());
h_scroll_group = new ArdourCanvas::ScrollGroup (_canvas.root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally);
CANVAS_DEBUG_NAME (h_scroll_group, "audioclip h scroll");
_canvas.add_scroller (*h_scroll_group);
v_scroll_group = new ArdourCanvas::ScrollGroup (_canvas.root(), ArdourCanvas::ScrollGroup::ScrollsVertically);
CANVAS_DEBUG_NAME (v_scroll_group, "audioclip v scroll");
_canvas.add_scroller (*v_scroll_group);
hv_scroll_group = new ArdourCanvas::ScrollGroup (_canvas.root(),
ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically|
ArdourCanvas::ScrollGroup::ScrollsHorizontally));
CANVAS_DEBUG_NAME (hv_scroll_group, "audioclip hv scroll");
_canvas.add_scroller (*hv_scroll_group);
cursor_scroll_group = new ArdourCanvas::ScrollGroup (_canvas.root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally);
CANVAS_DEBUG_NAME (cursor_scroll_group, "audioclip cursor scroll");
_canvas.add_scroller (*cursor_scroll_group);
/*a group to hold global rects like punch/loop indicators */
global_rect_group = new ArdourCanvas::Container (hv_scroll_group);
CANVAS_DEBUG_NAME (global_rect_group, "audioclip global rect group");
transport_loop_range_rect = new ArdourCanvas::Rectangle (global_rect_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, ArdourCanvas::COORD_MAX));
CANVAS_DEBUG_NAME (transport_loop_range_rect, "audioclip loop rect");
transport_loop_range_rect->hide();
/*a group to hold time (measure) lines */
time_line_group = new ArdourCanvas::Container (h_scroll_group);
CANVAS_DEBUG_NAME (time_line_group, "audioclip time line group");
n_timebars = 0;
minsec_ruler = new ArdourCanvas::Ruler (time_line_group, clip_metric, ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
// minsec_ruler->set_name ("audio clip editor ruler");
minsec_ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
minsec_ruler->set_fill_color (UIConfiguration::instance().color (X_("theme:bg1")));
minsec_ruler->set_outline_color (UIConfiguration::instance().color (X_("theme:contrasting less")));
n_timebars++;
minsec_ruler->Event.connect (sigc::mem_fun (*this, &CueEditor::ruler_event));
data_group = new ArdourCanvas::Container (hv_scroll_group);
CANVAS_DEBUG_NAME (data_group, "cue data group");
data_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars));
no_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars));
cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars));
h_scroll_group->set_position (Duple (_timeline_origin, 0.));
_verbose_cursor = new VerboseCursor (*this);
// _playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead"));
_playhead_cursor = new EditorCursor (*this, X_("playhead"));
_playhead_cursor->set_sensitive (UIConfiguration::instance().get_sensitize_playhead());
_playhead_cursor->set_color (UIConfiguration::instance().color ("play head"));
_playhead_cursor->canvas_item().raise_to_top();
h_scroll_group->raise_to_top ();
_canvas.set_name ("AudioClipCanvas");
_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
_canvas.set_can_focus ();
_canvas_viewport.signal_size_allocate().connect (sigc::mem_fun(*this, &AudioClipEditor::canvas_allocate), false);
_toolbox.pack_start (_canvas_viewport, true, true);
/* the lines */ /* the lines */
line_container = new ArdourCanvas::Container (waves_container); line_container = new ArdourCanvas::Container (data_group);
CANVAS_DEBUG_NAME (line_container, "audio clip line container");
const double line_width = 3.; const double line_width = 3.;
double scale = UIConfiguration::instance().get_ui_scale();
start_line = new Line (line_container); start_line = new Line (line_container);
start_line->set_outline_width (line_width * scale); start_line->set_outline_width (line_width * scale);
@ -222,41 +311,6 @@ AudioClipEditor::line_event_handler (GdkEvent* ev, ArdourCanvas::Line* l)
return false; return false;
} }
bool
AudioClipEditor::scroll_event_handler (GdkEvent* ev)
{
switch (ev->type) {
case GDK_BUTTON_PRESS:
current_scroll_drag = new ScrollDrag (*this);
current_scroll_drag->begin (&ev->button);
return true;
case GDK_BUTTON_RELEASE:
if (current_scroll_drag) {
current_scroll_drag->end (&ev->button);
delete current_scroll_drag;
current_scroll_drag = 0;
return true;
}
break;
case GDK_MOTION_NOTIFY:
if (current_scroll_drag) {
current_scroll_drag->motion (&ev->motion);
return true;
}
break;
case GDK_KEY_PRESS:
return key_press (&ev->key);
default:
break;
}
return false;
}
bool bool
AudioClipEditor::key_press (GdkEventKey* ev) AudioClipEditor::key_press (GdkEventKey* ev)
{ {
@ -266,27 +320,15 @@ AudioClipEditor::key_press (GdkEventKey* ev)
void void
AudioClipEditor::position_lines () AudioClipEditor::position_lines ()
{ {
if (!audio_region) { if (!_region) {
return; return;
} }
start_line->set_x0 (sample_to_pixel (audio_region->start ().samples ())); start_line->set_x0 (sample_to_pixel (_region->start ().samples ()));
start_line->set_x1 (sample_to_pixel (audio_region->start ().samples ())); start_line->set_x1 (sample_to_pixel (_region->start ().samples ()));
end_line->set_x0 (sample_to_pixel (audio_region->end ().samples ())); end_line->set_x0 (sample_to_pixel (_region->end ().samples ()));
end_line->set_x1 (sample_to_pixel (audio_region->end ().samples ())); end_line->set_x1 (sample_to_pixel (_region->end ().samples ()));
}
double
AudioClipEditor::sample_to_pixel (samplepos_t s)
{
return round (s / _spp);
}
samplepos_t
AudioClipEditor::pixel_to_sample (double p)
{
return round (p * _spp);
} }
AudioClipEditor::LineDrag::LineDrag (AudioClipEditor& ed, ArdourCanvas::Line& l) AudioClipEditor::LineDrag::LineDrag (AudioClipEditor& ed, ArdourCanvas::Line& l)
@ -317,78 +359,15 @@ AudioClipEditor::LineDrag::motion (GdkEventMotion* ev)
void void
AudioClipEditor::set_colors () AudioClipEditor::set_colors ()
{ {
set_background_color (UIConfiguration::instance ().color (X_("theme:bg"))); _canvas.set_background_color (UIConfiguration::instance ().color (X_("theme:bg")));
frame->set_outline_color (UIConfiguration::instance ().color (X_("neutral:midground")));
start_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting clock"))); start_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting clock")));
end_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting alt"))); end_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting alt")));
loop_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting selection"))); loop_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting selection")));
scroll_bar_trough->set_fill_color (UIConfiguration::instance ().color (X_("theme:bg")));
scroll_bar_trough->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting less")));
scroll_bar_handle->set_fill_color (UIConfiguration::instance ().color (X_("theme:contrasting clock")));
set_waveform_colors (); set_waveform_colors ();
} }
void
AudioClipEditor::scroll_changed ()
{
if (!audio_region) {
return;
}
const double right_edge = scroll_bar_handle->get ().x0;
const double avail_width = scroll_bar_trough->get ().width () - scroll_bar_handle->get ().width ();
scroll_fraction = right_edge / avail_width;
scroll_fraction = std::min (1., std::max (0., scroll_fraction));
const samplepos_t s = llrintf (audio_region->source (0)->length ().samples () * scroll_fraction);
ruler->set_range (s, s + pixel_to_sample (frame->get().width() - 2.));
scroll_to (sample_to_pixel (s), 0);
queue_draw ();
}
AudioClipEditor::ScrollDrag::ScrollDrag (AudioClipEditor& e)
: editor (e)
{
e.scroll_bar_handle->grab ();
}
void
AudioClipEditor::ScrollDrag::begin (GdkEventButton* ev)
{
last_x = ev->x;
}
void
AudioClipEditor::ScrollDrag::end (GdkEventButton* ev)
{
editor.scroll_bar_handle->ungrab ();
editor.scroll_changed ();
}
void
AudioClipEditor::ScrollDrag::motion (GdkEventMotion* ev)
{
ArdourCanvas::Rectangle& r (*editor.scroll_bar_handle);
const double xdelta = ev->x - last_x;
ArdourCanvas::Rect n (r.get ());
const double handle_width = n.width ();
const double avail_width = editor.scroll_bar_trough->get ().width () - handle_width;
n.x0 = std::max (0., std::min (avail_width, n.x0 + xdelta));
n.x1 = n.x0 + handle_width;
r.set (n);
last_x = ev->x;
editor.scroll_changed ();
}
void void
AudioClipEditor::drop_waves () AudioClipEditor::drop_waves ()
{ {
@ -400,11 +379,39 @@ AudioClipEditor::drop_waves ()
} }
void void
AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr) AudioClipEditor::set_trigger (TriggerReference& tr)
{ {
if (tr == ref) {
return;
}
CueEditor::set_trigger (tr);
rec_box.show ();
minsec_ruler->show ();
minsec_ruler->set_range (0, pixel_to_sample (_visible_canvas_width - 2.));
}
void
AudioClipEditor::set_region (std::shared_ptr<Region> region)
{
CueEditor::set_region (region);
if (_visible_pending_region) {
return;
}
drop_waves (); drop_waves ();
audio_region = r; if (!region) {
return;
}
std::shared_ptr<AudioRegion> r (std::dynamic_pointer_cast<AudioRegion> (region));
if (!r) {
return;
}
/* Ruler has to reflect tempo of the region, so we have to recreate it /* Ruler has to reflect tempo of the region, so we have to recreate it
* every time. Note that we retain ownership of the metric, and that * every time. Note that we retain ownership of the metric, and that
@ -414,8 +421,8 @@ AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr
*/ */
delete clip_metric; delete clip_metric;
clip_metric = new ClipBBTMetric (tr); clip_metric = new ClipBBTMetric (ref);
ruler->set_metric (clip_metric); minsec_ruler->set_metric (clip_metric);
uint32_t n_chans = r->n_channels (); uint32_t n_chans = r->n_channels ();
samplecnt_t len; samplecnt_t len;
@ -424,6 +431,7 @@ AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr
for (uint32_t n = 0; n < n_chans; ++n) { for (uint32_t n = 0; n < n_chans; ++n) {
std::shared_ptr<Region> wr = RegionFactory::get_whole_region_for_source (r->source (n)); std::shared_ptr<Region> wr = RegionFactory::get_whole_region_for_source (r->source (n));
if (!wr) { if (!wr) {
continue; continue;
} }
@ -433,8 +441,8 @@ AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr
continue; continue;
} }
WaveView* wv = new WaveView (waves_container, war); WaveView* wv = new WaveView (data_group, war);
wv->set_channel (n); wv->set_channel (0);
wv->set_show_zero_line (false); wv->set_show_zero_line (false);
wv->set_clip_level (1.0); wv->set_clip_level (1.0);
wv->lower_to_bottom (); wv->lower_to_bottom ();
@ -442,75 +450,56 @@ AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr
waves.push_back (wv); waves.push_back (wv);
} }
TriggerPtr trigger (tr.trigger());
std::shared_ptr<AudioTrigger> at = std::dynamic_pointer_cast<AudioTrigger> (trigger);
if (at) {
if (at->segment_tempo() == 0.) {
/* tempo unknown, hide ruler */
ruler->hide ();
} else {
ruler->show ();
ruler->set_range (0, pixel_to_sample (frame->get().width() - 2.));
}
} else {
ruler->hide ();
}
set_spp_from_length (len); set_spp_from_length (len);
set_wave_heights (); set_wave_heights ();
set_waveform_colors (); set_waveform_colors ();
line_container->show (); line_container->show ();
line_container->raise_to_top (); line_container->raise_to_top ();
set_session (&r->session ());
state_connection.disconnect ();
PBD::PropertyChange interesting_stuff;
region_changed (interesting_stuff);
region->PropertyChanged.connect (state_connection, invalidator (*this), std::bind (&AudioClipEditor::region_changed, this, _1), gui_context ());
maybe_set_from_rsu ();
} }
void void
AudioClipEditor::on_size_allocate (Gtk::Allocation& alloc) AudioClipEditor::canvas_allocate (Gtk::Allocation& alloc)
{ {
GtkCanvas::on_size_allocate (alloc); _canvas.size_allocate (alloc);
ArdourCanvas::Rect r (1, 1, alloc.get_width () - 2, alloc.get_height () - 2); _visible_canvas_width = alloc.get_width();
frame->set (r); _visible_canvas_height = alloc.get_height();
const double ruler_height = 25.; /* no track header here, "track width" is the whole canvas */
ruler->set (ArdourCanvas::Rect (2, 2, alloc.get_width() - 4, ruler_height)); _track_canvas_width = _visible_canvas_width;
const double scroll_bar_height = 10.; minsec_ruler->set (ArdourCanvas::Rect (2, 2, alloc.get_width() - 4, timebar_height));
const double scroll_bar_width = alloc.get_width () - 2;
const double scroll_bar_handle_left = scroll_bar_width * scroll_fraction;
scroll_bar_trough->set (ArdourCanvas::Rect (1, alloc.get_height () - scroll_bar_height, scroll_bar_width, alloc.get_height ()));
scroll_bar_handle->set (ArdourCanvas::Rect (scroll_bar_handle_left, scroll_bar_trough->get ().y0 + 1, scroll_bar_handle_left + 30., scroll_bar_trough->get ().y1 - 1));
position_lines (); position_lines ();
start_line->set_y1 (frame->get ().height () - 2. - scroll_bar_height); start_line->set_y1 (_visible_canvas_height - 2.);
end_line->set_y1 (frame->get ().height () - 2. - scroll_bar_height); end_line->set_y1 (_visible_canvas_height - 2.);
loop_line->set_y1 (frame->get ().height () - 2. - scroll_bar_height); loop_line->set_y1 (_visible_canvas_height - 2.);
set_wave_heights (); set_wave_heights ();
}
void catch_pending_show_region ();
AudioClipEditor::set_spp (double samples_per_pixel)
{
_spp = samples_per_pixel;
clip_metric->units_per_pixel = _spp; update_grid ();
position_lines ();
for (auto& wave : waves) {
wave->set_samples_per_pixel (_spp);
}
} }
void void
AudioClipEditor::set_spp_from_length (samplecnt_t len) AudioClipEditor::set_spp_from_length (samplecnt_t len)
{ {
double available_width = frame->get ().width (); if (_visible_canvas_width) {
double s = floor (len / available_width); set_samples_per_pixel (floor (len / _visible_canvas_width));
}
set_spp (s);
} }
void void
@ -521,12 +510,12 @@ AudioClipEditor::set_wave_heights ()
} }
uint32_t n = 0; uint32_t n = 0;
const Distance w = frame->get ().height () - scroll_bar_trough->get ().height () - 2. - ruler->get().height(); const Distance w = _visible_canvas_height - (n_timebars * timebar_height);
Distance ht = w / waves.size (); Distance ht = w / waves.size ();
for (auto& wave : waves) { for (auto& wave : waves) {
wave->set_height (ht); wave->set_height (ht);
wave->set_y_position (ruler->get ().height () + (n * ht)); wave->set_y_position ((n_timebars * timebar_height) + (n * ht));
++n; ++n;
} }
} }
@ -547,86 +536,146 @@ AudioClipEditor::set_waveform_colors ()
} }
} }
Gtk::Widget&
AudioClipEditor::contents ()
{
return _contents;
}
void
AudioClipEditor::region_changed (const PBD::PropertyChange& what_changed)
{
}
void
AudioClipEditor::set_samples_per_pixel (samplecnt_t spp)
{
CueEditor::set_samples_per_pixel (spp);
clip_metric->units_per_pixel = samples_per_pixel;
position_lines ();
for (auto& wave : waves) {
wave->set_samples_per_pixel (samples_per_pixel);
}
horizontal_adjustment.set_upper (max_zoom_extent().second.samples() / samples_per_pixel);
horizontal_adjustment.set_page_size (current_page_samples()/ samples_per_pixel / 10);
horizontal_adjustment.set_page_increment (current_page_samples()/ samples_per_pixel / 20);
horizontal_adjustment.set_step_increment (current_page_samples() / samples_per_pixel / 100);
}
samplecnt_t
AudioClipEditor::current_page_samples() const
{
return (samplecnt_t) _track_canvas_width * samples_per_pixel;
}
bool bool
AudioClipEditor::event_handler (GdkEvent* ev) AudioClipEditor::canvas_enter_leave (GdkEventCrossing* ev)
{ {
switch (ev->type) { switch (ev->type) {
case GDK_BUTTON_PRESS: case GDK_ENTER_NOTIFY:
break; if (ev->detail != GDK_NOTIFY_INFERIOR) {
case GDK_ENTER_NOTIFY: _canvas.grab_focus ();
break; // ActionManager::set_sensitive (_midi_actions, true);
case GDK_LEAVE_NOTIFY: within_track_canvas = true;
break; }
default: break;
break; case GDK_LEAVE_NOTIFY:
if (ev->detail != GDK_NOTIFY_INFERIOR) {
// ActionManager::set_sensitive (_midi_actions, false);
within_track_canvas = false;
ARDOUR_UI::instance()->reset_focus (&_canvas_viewport);
gdk_window_set_cursor (_canvas_viewport.get_window()->gobj(), nullptr);
}
default:
break;
} }
return false; return false;
} }
AudioClipEditorBox::AudioClipEditorBox () void
AudioClipEditor::begin_write ()
{ {
_header_label.set_text (_("AUDIO Region Trimmer:"));
_header_label.set_alignment (0.0, 0.5);
zoom_in_button.set_icon (ArdourIcon::ZoomIn);
zoom_out_button.set_icon (ArdourIcon::ZoomOut);
zoom_in_button.signal_clicked.connect (sigc::mem_fun (*this, &AudioClipEditorBox::zoom_in_click));
zoom_out_button.signal_clicked.connect (sigc::mem_fun (*this, &AudioClipEditorBox::zoom_out_click));
header_box.pack_start (_header_label, false, false);
header_box.pack_start (zoom_in_button, false, false);
header_box.pack_start (zoom_out_button, false, false);
pack_start (header_box, false, false, 6);
editor = manage (new AudioClipEditor);
editor->set_size_request (600, 120);
pack_start (*editor, true, true);
editor->show ();
}
AudioClipEditorBox::~AudioClipEditorBox ()
{
delete editor;
} }
void void
AudioClipEditorBox::zoom_in_click () AudioClipEditor::end_write ()
{ {
editor->set_spp (editor->spp () / 2.);
} }
void void
AudioClipEditorBox::zoom_out_click () AudioClipEditor::show_count_in (std::string const &)
{ {
editor->set_spp (editor->spp () * 2.);
} }
void void
AudioClipEditorBox::set_region (std::shared_ptr<Region> r, TriggerReference tref) AudioClipEditor::hide_count_in ()
{ {
std::shared_ptr<AudioRegion> ar = std::dynamic_pointer_cast<AudioRegion> (r); }
if (!ar) { void
return; AudioClipEditor::maybe_update ()
{
ARDOUR::TriggerPtr playing_trigger;
if (ref.trigger()) {
/* Trigger editor */
playing_trigger = ref.box()->currently_playing ();
if (!playing_trigger) {
if (_drags->active() || !_region || !_track || !_track->triggerbox()) {
return;
}
if (_track->triggerbox()->record_enabled() == Recording) {
_playhead_cursor->set_position (data_capture_duration);
}
} else {
if (playing_trigger->active ()) {
if (playing_trigger->the_region()) {
_playhead_cursor->set_position (playing_trigger->current_pos().samples() + playing_trigger->the_region()->start().samples());
}
} else {
_playhead_cursor->set_position (0);
}
}
#if 0
} else if (view->midi_region()) {
/* Timeline region editor */
if (!_session) {
return;
}
samplepos_t pos = _session->transport_sample();
samplepos_t spos = view->midi_region()->source_position().samples();
if (pos < spos) {
_playhead_cursor->set_position (0);
} else {
_playhead_cursor->set_position (pos - spos);
}
#endif
} else {
_playhead_cursor->set_position (0);
} }
set_session (&r->session ()); if (follow_playhead()) {
reset_x_origin_to_follow_playhead ();
state_connection.disconnect (); }
_region = r;
editor->set_region (ar, tref);
PBD::PropertyChange interesting_stuff;
region_changed (interesting_stuff);
_region->PropertyChanged.connect (state_connection, invalidator (*this), std::bind (&AudioClipEditorBox::region_changed, this, _1), gui_context ());
} }
void void
AudioClipEditorBox::region_changed (const PBD::PropertyChange& what_changed) AudioClipEditor::unset (bool trigger_too)
{ {
drop_waves ();
CueEditor::unset (trigger_too);
} }

View file

@ -25,6 +25,8 @@
#include <ytkmm/label.h> #include <ytkmm/label.h>
#include <ytkmm/table.h> #include <ytkmm/table.h>
#include "pbd/history_owner.h"
#include "ardour/ardour.h" #include "ardour/ardour.h"
#include "ardour/session_handle.h" #include "ardour/session_handle.h"
#include "ardour/triggerbox.h" #include "ardour/triggerbox.h"
@ -36,7 +38,6 @@
#include "widgets/ardour_button.h" #include "widgets/ardour_button.h"
#include "canvas/canvas.h"
#include "canvas/container.h" #include "canvas/container.h"
#include "canvas/line.h" #include "canvas/line.h"
#include "canvas/rectangle.h" #include "canvas/rectangle.h"
@ -44,6 +45,7 @@
#include "canvas/scroll_group.h" #include "canvas/scroll_group.h"
#include "audio_clock.h" #include "audio_clock.h"
#include "cue_editor.h"
namespace ARDOUR namespace ARDOUR
{ {
@ -63,59 +65,76 @@ namespace ArdourWaveView
class WaveView; class WaveView;
} }
class ClipEditorBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr class AudioClipEditor : public CueEditor
{ {
public: public:
ClipEditorBox () {} AudioClipEditor (std::string const &, bool with_transport = false);
~ClipEditorBox () {}
virtual void set_region (std::shared_ptr<ARDOUR::Region>, ARDOUR::TriggerReference) = 0;
static void init ();
static void register_clip_editor_actions (Gtkmm2ext::Bindings*);
static Glib::RefPtr<Gtk::ActionGroup> clip_editor_actions;
};
class ClipEditor
{
public:
virtual ~ClipEditor () {}
virtual void zoom_in () = 0;
virtual void zoom_out () = 0;
};
class AudioClipEditor : public ArdourCanvas::GtkCanvas
{
public:
AudioClipEditor ();
~AudioClipEditor (); ~AudioClipEditor ();
void set_region (std::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::TriggerReference); void canvas_allocate (Gtk::Allocation&);
void on_size_allocate (Gtk::Allocation&);
double sample_to_pixel (ARDOUR::samplepos_t); Gtk::Widget& contents ();
samplepos_t pixel_to_sample (double);
void set_spp (double); void set_trigger (ARDOUR::TriggerReference&);
double spp () const void set_region (std::shared_ptr<ARDOUR::Region> r);
{ void region_changed (const PBD::PropertyChange& what_changed);
return _spp;
}
bool key_press (GdkEventKey*); bool key_press (GdkEventKey*);
private: /* EditingContext API. As of July 2025, we do not implement most of
ArdourCanvas::Rectangle* frame; * these
ArdourCanvas::ScrollGroup* waves_container; */
ArdourCanvas::Container* line_container;
ArdourCanvas::Line* start_line; bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
ArdourCanvas::Line* end_line; bool button_press_handler_1 (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
ArdourCanvas::Line* loop_line; bool button_press_handler_2 (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
ArdourCanvas::Rectangle* scroll_bar_trough; bool button_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
ArdourCanvas::Rectangle* scroll_bar_handle; bool button_press_dispatch (GdkEventButton*) { return true; }
ArdourCanvas::Container* ruler_container; bool button_release_dispatch (GdkEventButton*) { return true; }
ArdourCanvas::Ruler* ruler; bool motion_handler (ArdourCanvas::Item*, GdkEvent*, bool from_autoscroll = false) { return true; }
bool enter_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
bool leave_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
bool key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
bool key_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
bool canvas_note_event (GdkEvent* event, ArdourCanvas::Item*) { return true; }
bool canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item*) { return true; }
bool canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item*) { return true; }
bool canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item*, ControlPoint*) { return true; }
bool canvas_bg_event (GdkEvent* event, ArdourCanvas::Item*) { return true; }
samplecnt_t current_page_samples() const;
void set_samples_per_pixel (samplecnt_t);
Gdk::Cursor* which_track_cursor () const { return nullptr; }
Gdk::Cursor* which_mode_cursor () const { return nullptr; }
Gdk::Cursor* which_trim_cursor (bool left_side) const { return nullptr; }
Gdk::Cursor* which_canvas_cursor (ItemType type) const { return nullptr; }
Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start, Temporal::RoundMode direction, ARDOUR::SnapPref gpref) const { return start; }
void snap_to_internal (Temporal::timepos_t& first, Temporal::RoundMode direction = Temporal::RoundNearest, ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual, bool ensure_snap = false) const {}
void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<SelectableOwner*> const &, ARDOUR::SelectionOperation, bool) {}
void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const {}
void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const {}
void point_selection_changed () {}
void delete_ () {}
void paste (float times, bool from_context_menu) {}
void keyboard_paste () {}
void cut_copy (Editing::CutCopyOp) {}
void maybe_update ();
bool idle_data_captured () { return false; }
private:
ArdourCanvas::Container* line_container;
ArdourCanvas::Line* start_line;
ArdourCanvas::Line* end_line;
ArdourCanvas::Line* loop_line;
ArdourCanvas::Container* ruler_container;
ArdourCanvas::Ruler* minsec_ruler;
class ClipBBTMetric : public ArdourCanvas::Ruler::Metric class ClipBBTMetric : public ArdourCanvas::Ruler::Metric
{ {
@ -135,9 +154,7 @@ private:
std::vector<ArdourWaveView::WaveView*> waves; std::vector<ArdourWaveView::WaveView*> waves;
double non_wave_height; double non_wave_height;
samplepos_t left_origin; samplepos_t left_origin;
double _spp;
double scroll_fraction; double scroll_fraction;
std::shared_ptr<ARDOUR::AudioRegion> audio_region;
void scroll_left (); void scroll_left ();
void scrol_right (); void scrol_right ();
@ -150,7 +167,6 @@ private:
bool event_handler (GdkEvent* ev); bool event_handler (GdkEvent* ev);
bool line_event_handler (GdkEvent* ev, ArdourCanvas::Line*); bool line_event_handler (GdkEvent* ev, ArdourCanvas::Line*);
bool scroll_event_handler (GdkEvent* ev);
void drop_waves (); void drop_waves ();
void set_wave_heights (); void set_wave_heights ();
void set_spp_from_length (ARDOUR::samplecnt_t); void set_spp_from_length (ARDOUR::samplecnt_t);
@ -176,47 +192,21 @@ private:
friend class LineDrag; friend class LineDrag;
LineDrag* current_line_drag; LineDrag* current_line_drag;
class ScrollDrag
{
public:
ScrollDrag (AudioClipEditor&);
void begin (GdkEventButton*);
void end (GdkEventButton*);
void motion (GdkEventMotion*);
private:
AudioClipEditor& editor;
double last_x;
};
friend class ScrollDrag;
ScrollDrag* current_scroll_drag;
};
class AudioClipEditorBox : public ClipEditorBox
{
public:
AudioClipEditorBox ();
~AudioClipEditorBox ();
void set_region (std::shared_ptr<ARDOUR::Region>, ARDOUR::TriggerReference);
void region_changed (const PBD::PropertyChange& what_changed);
private:
Gtk::HBox header_box;
ArdourWidgets::ArdourButton zoom_in_button;
ArdourWidgets::ArdourButton zoom_out_button;
Gtk::Label _header_label;
Gtk::Table table;
AudioClipEditor* editor;
PBD::ScopedConnection state_connection; PBD::ScopedConnection state_connection;
std::shared_ptr<ARDOUR::Region> _region; void build_canvas ();
void build_lower_toolbar ();
void pack_inner (Gtk::Box&);
void pack_outer (Gtk::Box&);
void zoom_in_click (); bool canvas_enter_leave (GdkEventCrossing* ev);
void zoom_out_click ();
void begin_write ();
void end_write ();
void show_count_in (std::string const &);
void hide_count_in ();
void unset (bool trigger_too);
void load_shared_bindings ();
}; };

File diff suppressed because it is too large Load diff

View file

@ -20,15 +20,34 @@
#include "pbd/history_owner.h" #include "pbd/history_owner.h"
#include "canvas/canvas.h"
#include "widgets/ardour_button.h"
#include "widgets/eventboxext.h"
#include "editing.h" #include "editing.h"
#include "editing_context.h" #include "editing_context.h"
#include "region_ui_settings.h"
namespace Gtk {
class HScrollbar;
}
class CueEditor : public EditingContext, public PBD::HistoryOwner class CueEditor : public EditingContext, public PBD::HistoryOwner
{ {
public: public:
CueEditor (std::string const & name); CueEditor (std::string const & name, bool with_transport_controls);
~CueEditor (); ~CueEditor ();
virtual Gtk::Widget& contents () = 0;
void session_going_away ();
ArdourCanvas::Container* get_trackview_group () const { return data_group; }
ArdourCanvas::Container* get_noscroll_group() const { return no_scroll_group; }
ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const; void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const;
StripableTimeAxisView* get_stripable_time_axis_by_id (const PBD::ID& id) const; StripableTimeAxisView* get_stripable_time_axis_by_id (const PBD::ID& id) const;
TrackViewList axis_views_from_routes (std::shared_ptr<ARDOUR::RouteList>) const; TrackViewList axis_views_from_routes (std::shared_ptr<ARDOUR::RouteList>) const;
@ -46,6 +65,7 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
void redisplay_grid (bool immediate_redraw); void redisplay_grid (bool immediate_redraw);
Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) const; Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) const;
std::list<SelectableOwner*> selectable_owners() { return std::list<SelectableOwner*>(); }
void instant_save(); void instant_save();
@ -56,6 +76,8 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
void undo_selection_op (); void undo_selection_op ();
void redo_selection_op (); void redo_selection_op ();
RegionSelection region_selection();
PBD::HistoryOwner& history() { return *this; } PBD::HistoryOwner& history() { return *this; }
void history_changed (); void history_changed ();
PBD::ScopedConnection history_connection; PBD::ScopedConnection history_connection;
@ -85,6 +107,7 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
Editing::MouseMode current_mouse_mode () const; Editing::MouseMode current_mouse_mode () const;
/** cue editors are *always* used for internal editing */ /** cue editors are *always* used for internal editing */
bool internal_editing() const { return true; } bool internal_editing() const { return true; }
void mouse_mode_toggled (Editing::MouseMode);
Gdk::Cursor* get_canvas_cursor () const; Gdk::Cursor* get_canvas_cursor () const;
MouseCursors const* cursors () const { MouseCursors const* cursors () const {
@ -97,10 +120,150 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
std::shared_ptr<Temporal::TempoMap const> start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>); std::shared_ptr<Temporal::TempoMap const> start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>); void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>);
void scrolled ();
bool canvas_pre_event (GdkEvent*);
void catch_pending_show_region ();
std::pair<Temporal::timepos_t,Temporal::timepos_t> max_zoom_extent() const;
void full_zoom_clicked();
void zoom_to_show (Temporal::timecnt_t const &);
bool ruler_event (GdkEvent*);
virtual void set_show_source (bool);
virtual void set_region (std::shared_ptr<ARDOUR::Region>);
virtual void set_track (std::shared_ptr<ARDOUR::Track>);
virtual void set_trigger (ARDOUR::TriggerReference&);
virtual void maybe_update () = 0;
ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const;
ArdourCanvas::GtkCanvas* get_canvas() const;
int set_state (const XMLNode&, int version);
XMLNode& get_state () const;
protected: protected:
ArdourCanvas::GtkCanvasViewport _canvas_viewport;
ArdourCanvas::GtkCanvas& _canvas;
ARDOUR::TriggerReference ref;
std::shared_ptr<ARDOUR::Region> _region;
std::shared_ptr<ARDOUR::Track> _track;
bool with_transport_controls;
bool show_source;
ArdourWidgets::EventBoxExt _contents;
Gtk::VBox _toolbox;
Gtk::HBox button_bar;
Gtk::HScrollbar* _canvas_hscrollbar;
void load_bindings ();
void register_actions ();
/* The group containing all other groups that are scrolled vertically
and horizontally.
*/
ArdourCanvas::ScrollGroup* hv_scroll_group;
/* The group containing all other groups that are scrolled horizontally ONLY
*/
ArdourCanvas::ScrollGroup* h_scroll_group;
ArdourCanvas::ScrollGroup* v_scroll_group;
/* Scroll group for cursors, scrolled horizontally, above everything else
*/
ArdourCanvas::ScrollGroup* cursor_scroll_group;
ArdourCanvas::Container* global_rect_group;
ArdourCanvas::Container* no_scroll_group;
ArdourCanvas::Container* data_group;
Gtk::Label length_label;
Gtk::HBox rec_box;
Gtk::HBox play_box;
virtual void pack_inner (Gtk::Box&) = 0;
virtual void pack_outer (Gtk::Box&) = 0;
void build_zoom_focus_menu ();
virtual void update_rulers() {}
virtual bool canvas_enter_leave (GdkEventCrossing* ev) = 0;
void build_upper_toolbar ();
void do_undo (uint32_t n); void do_undo (uint32_t n);
void do_redo (uint32_t n); void do_redo (uint32_t n);
Temporal::timepos_t _get_preferred_edit_position (Editing::EditIgnoreOption, bool use_context_click, bool from_outside_canvas); Temporal::timepos_t _get_preferred_edit_position (Editing::EditIgnoreOption, bool use_context_click, bool from_outside_canvas);
ArdourWidgets::ArdourButton rec_enable_button;
ArdourWidgets::ArdourButton play_button;
ArdourWidgets::ArdourButton solo_button;
ArdourWidgets::ArdourButton loop_button;
ArdourCanvas::Rectangle* transport_loop_range_rect;
bool play_button_press (GdkEventButton*);
bool solo_button_press (GdkEventButton*);
bool bang_button_press (GdkEventButton*);
bool loop_button_press (GdkEventButton*);
ArdourWidgets::ArdourDropdown length_selector;
Temporal::BBT_Offset rec_length;
bool zoom_in_allocate;
void set_recording_length (Temporal::BBT_Offset bars);
bool rec_button_press (GdkEventButton*);
void rec_enable_change ();
void blink_rec_enable (bool);
sigc::connection rec_blink_connection;
sigc::connection _update_connection;
PBD::ScopedConnectionList object_connections;
void trigger_arm_change ();
double timebar_height;
size_t n_timebars;
/* autoscrolling */
bool autoscroll_canvas ();
void start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const ArdourCanvas::Rect& boundary);
void visual_changer (const VisualChange&);
void update_solo_display ();
std::shared_ptr<ARDOUR::Region> _visible_pending_region;
void ruler_locate (GdkEventButton*);
virtual void begin_write () = 0;
virtual void end_write () = 0;
virtual void manage_possible_header (Gtk::Allocation&) {}
sigc::connection count_in_connection;
Temporal::Beats count_in_to;
void count_in (Temporal::timepos_t, unsigned int);
void maybe_set_count_in ();
virtual void show_count_in (std::string const &) = 0;
virtual void hide_count_in () = 0;
void data_captured (samplecnt_t);
virtual bool idle_data_captured () = 0;
std::atomic<int> idle_update_queued;
PBD::ScopedConnectionList capture_connections;
samplecnt_t data_capture_duration;
virtual void unset (bool trigger_too);
RegionUISettings region_ui_settings;
void maybe_set_from_rsu ();
virtual void set_from_rsu (RegionUISettings&);
void metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>&, samplepos_t, samplepos_t, gint);
}; };

File diff suppressed because it is too large Load diff

View file

@ -147,7 +147,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
void toggle_follow_playhead (); void toggle_follow_playhead ();
/** @return true if the editor is following the playhead */ /** @return true if the editor is following the playhead */
bool follow_playhead () const { return _follow_playhead; } bool follow_playhead () const;
Temporal::timepos_t get_preferred_edit_position (Editing::EditIgnoreOption eio = Editing::EDIT_IGNORE_NONE, Temporal::timepos_t get_preferred_edit_position (Editing::EditIgnoreOption eio = Editing::EDIT_IGNORE_NONE,
bool use_context_click = false, bool use_context_click = false,
@ -258,6 +258,9 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
double timeline_to_canvas (double p) const { return p + _timeline_origin; } double timeline_to_canvas (double p) const { return p + _timeline_origin; }
double canvas_to_timeline (double p) const { return p - _timeline_origin; } double canvas_to_timeline (double p) const { return p - _timeline_origin; }
double visible_canvas_width () const { return _visible_canvas_width; }
double visible_canvas_height () const { return _visible_canvas_height; }
/** computes the timeline position for an event whose coordinates /** computes the timeline position for an event whose coordinates
* are in canvas units (pixels, scroll offset included). The time * are in canvas units (pixels, scroll offset included). The time
* domain used by the return value will match ::default_time_domain() * domain used by the return value will match ::default_time_domain()
@ -291,12 +294,12 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
void cycle_snap_mode (); void cycle_snap_mode ();
void next_grid_choice (); void next_grid_choice ();
void prev_grid_choice (); void prev_grid_choice ();
void set_grid_to (Editing::GridType); void set_grid_type (Editing::GridType);
void set_snap_mode (Editing::SnapMode); void set_snap_mode (Editing::SnapMode);
void set_draw_length_to (Editing::GridType); void set_draw_length (Editing::GridType);
void set_draw_velocity_to (int); void set_draw_velocity (int);
void set_draw_channel_to (int); void set_draw_channel (int);
Editing::GridType draw_length () const; Editing::GridType draw_length () const;
int draw_velocity () const; int draw_velocity () const;
@ -516,7 +519,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
Glib::RefPtr<Gtk::ActionGroup> velocity_actions; Glib::RefPtr<Gtk::ActionGroup> velocity_actions;
Glib::RefPtr<Gtk::ActionGroup> zoom_actions; Glib::RefPtr<Gtk::ActionGroup> zoom_actions;
void load_shared_bindings (); virtual void load_shared_bindings ();
Editing::GridType pre_internal_grid_type; Editing::GridType pre_internal_grid_type;
Editing::SnapMode pre_internal_snap_mode; Editing::SnapMode pre_internal_snap_mode;
@ -525,19 +528,11 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
static std::vector<std::string> grid_type_strings; static std::vector<std::string> grid_type_strings;
Glib::RefPtr<Gtk::RadioAction> grid_type_action (Editing::GridType); std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > grid_actions;
Glib::RefPtr<Gtk::RadioAction> snap_mode_action (Editing::SnapMode); std::map<Editing::SnapMode, Glib::RefPtr<Gtk::RadioAction> > snap_mode_actions;
std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > draw_length_actions;
Glib::RefPtr<Gtk::RadioAction> draw_length_action (Editing::GridType); std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_velocity_actions;
Glib::RefPtr<Gtk::RadioAction> draw_velocity_action (int); std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_channel_actions;
Glib::RefPtr<Gtk::RadioAction> draw_channel_action (int);
Editing::GridType _grid_type;
Editing::SnapMode _snap_mode;
Editing::GridType _draw_length;
int _draw_velocity;
int _draw_channel;
void draw_channel_chosen (int); void draw_channel_chosen (int);
void draw_velocity_chosen (int); void draw_velocity_chosen (int);
@ -561,8 +556,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
ArdourWidgets::ArdourDropdown draw_channel_selector; ArdourWidgets::ArdourDropdown draw_channel_selector;
void build_draw_midi_menus (); void build_draw_midi_menus ();
void grid_type_selection_done (Editing::GridType);
void snap_mode_selection_done (Editing::SnapMode);
void snap_mode_chosen (Editing::SnapMode); void snap_mode_chosen (Editing::SnapMode);
void grid_type_chosen (Editing::GridType); void grid_type_chosen (Editing::GridType);
@ -600,7 +593,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
EditorCursor* _playhead_cursor; EditorCursor* _playhead_cursor;
EditorCursor* _snapped_cursor; EditorCursor* _snapped_cursor;
bool _follow_playhead; Glib::RefPtr<Gtk::ToggleAction> follow_playhead_action;
/* selection process */ /* selection process */
@ -633,7 +626,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
bool ensure_snap = false) const = 0; bool ensure_snap = false) const = 0;
void check_best_snap (Temporal::timepos_t const & presnap, Temporal::timepos_t &test, Temporal::timepos_t &dist, Temporal::timepos_t &best) const; void check_best_snap (Temporal::timepos_t const & presnap, Temporal::timepos_t &test, Temporal::timepos_t &dist, Temporal::timepos_t &best) const;
virtual double visible_canvas_width() const = 0;
enum BBTRulerScale { enum BBTRulerScale {
bbt_show_many, bbt_show_many,
@ -819,8 +811,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
/* protected helper functions to help with registering actions */ /* protected helper functions to help with registering actions */
static Glib::RefPtr<Gtk::Action> reg_sens (Glib::RefPtr<Gtk::ActionGroup> group, char const* name, char const* label, sigc::slot<void> slot); static Glib::RefPtr<Gtk::Action> reg_sens (Glib::RefPtr<Gtk::ActionGroup> group, char const* name, char const* label, sigc::slot<void> slot);
static void toggle_reg_sens (Glib::RefPtr<Gtk::ActionGroup> group, char const* name, char const* label, sigc::slot<void> slot); static Glib::RefPtr<Gtk::ToggleAction> toggle_reg_sens (Glib::RefPtr<Gtk::ActionGroup> group, char const* name, char const* label, sigc::slot<void> slot);
static void radio_reg_sens (Glib::RefPtr<Gtk::ActionGroup> action_group, Gtk::RadioAction::Group& radio_group, char const* name, char const* label, sigc::slot<void> slot); static Glib::RefPtr<Gtk::RadioAction> radio_reg_sens (Glib::RefPtr<Gtk::ActionGroup> action_group, Gtk::RadioAction::Group& radio_group, char const* name, char const* label, sigc::slot<void> slot);
void center_screen_internal (samplepos_t, float); void center_screen_internal (samplepos_t, float);

View file

@ -379,7 +379,6 @@ Editor::Editor ()
, _last_cut_copy_source_track (nullptr) , _last_cut_copy_source_track (nullptr)
, _region_selection_change_updates_region_list (true) , _region_selection_change_updates_region_list (true)
, _following_mixer_selection (false) , _following_mixer_selection (false)
, _show_touched_automation (false)
, _control_point_toggled_on_press (false) , _control_point_toggled_on_press (false)
, _stepping_axis_view (nullptr) , _stepping_axis_view (nullptr)
, _main_menu_disabler (nullptr) , _main_menu_disabler (nullptr)
@ -1151,7 +1150,7 @@ Editor::map_position_change (samplepos_t sample)
return; return;
} }
if (_follow_playhead) { if (follow_playhead()) {
center_screen (sample); center_screen (sample);
} }
@ -1229,7 +1228,7 @@ Editor::set_session (Session *t)
if (!_pianoroll) { if (!_pianoroll) {
// XXX this should really not happen here // XXX this should really not happen here
_pianoroll = new Pianoroll ("editor pianoroll", true); _pianoroll = new Pianoroll ("editor pianoroll", true);
_pianoroll->viewport().set_size_request (-1, 120); _pianoroll->get_canvas_viewport()->set_size_request (-1, 120);
} }
_pianoroll->set_session (_session); _pianoroll->set_session (_session);
@ -2068,6 +2067,8 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
void void
Editor::show_rulers_for_grid () Editor::show_rulers_for_grid ()
{ {
GridType gt (grid_type());
/* show appropriate rulers for this grid setting. */ /* show appropriate rulers for this grid setting. */
if (grid_musical()) { if (grid_musical()) {
ruler_tempo_action->set_active(true); ruler_tempo_action->set_active(true);
@ -2079,7 +2080,7 @@ Editor::show_rulers_for_grid ()
ruler_minsec_action->set_active(false); ruler_minsec_action->set_active(false);
ruler_samples_action->set_active(false); ruler_samples_action->set_active(false);
} }
} else if (_grid_type == GridTypeTimecode) { } else if (gt == GridTypeTimecode) {
ruler_timecode_action->set_active(true); ruler_timecode_action->set_active(true);
if (UIConfiguration::instance().get_rulers_follow_grid()) { if (UIConfiguration::instance().get_rulers_follow_grid()) {
@ -2089,7 +2090,7 @@ Editor::show_rulers_for_grid ()
ruler_minsec_action->set_active(false); ruler_minsec_action->set_active(false);
ruler_samples_action->set_active(false); ruler_samples_action->set_active(false);
} }
} else if (_grid_type == GridTypeMinSec) { } else if (gt == GridTypeMinSec) {
ruler_minsec_action->set_active(true); ruler_minsec_action->set_active(true);
if (UIConfiguration::instance().get_rulers_follow_grid()) { if (UIConfiguration::instance().get_rulers_follow_grid()) {
@ -2099,7 +2100,7 @@ Editor::show_rulers_for_grid ()
ruler_timecode_action->set_active(false); ruler_timecode_action->set_active(false);
ruler_samples_action->set_active(false); ruler_samples_action->set_active(false);
} }
} else if (_grid_type == GridTypeCDFrame) { } else if (gt == GridTypeCDFrame) {
ruler_minsec_action->set_active(true); ruler_minsec_action->set_active(true);
if (UIConfiguration::instance().get_rulers_follow_grid()) { if (UIConfiguration::instance().get_rulers_follow_grid()) {
@ -2334,7 +2335,7 @@ Editor::set_state (const XMLNode& node, int version)
RefPtr<ToggleAction> tact; RefPtr<ToggleAction> tact;
tact = ActionManager::get_toggle_action ((editor_name () + X_("Editing")).c_str(), X_("toggle-follow-playhead")); tact = ActionManager::get_toggle_action ((editor_name () + X_("Editing")).c_str(), X_("toggle-follow-playhead"));
yn = _follow_playhead; yn = follow_playhead();
if (tact->get_active() != yn) { if (tact->get_active() != yn) {
tact->set_active (yn); tact->set_active (yn);
} }
@ -2374,19 +2375,14 @@ Editor::get_state () const
node->set_property ("y-origin", vertical_adjustment.get_value ()); node->set_property ("y-origin", vertical_adjustment.get_value ());
node->set_property ("maximised", _maximised); node->set_property ("maximised", _maximised);
node->set_property ("follow-playhead", _follow_playhead); node->set_property ("follow-playhead", follow_playhead());
node->set_property ("stationary-playhead", _stationary_playhead); node->set_property ("stationary-playhead", _stationary_playhead);
node->set_property ("mouse-mode", mouse_mode); node->set_property ("mouse-mode", mouse_mode);
node->set_property ("join-object-range", smart_mode_action->get_active ()); node->set_property ("join-object-range", smart_mode_action->get_active ());
Glib::RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-mixer")); node->set_property (X_("show-editor-mixer"), show_editor_mixer_action->get_active());
node->set_property (X_("show-editor-mixer"), tact->get_active()); node->set_property (X_("show-editor-list"), show_editor_list_action->get_active());
node->set_property (X_("show-editor-props"), show_editor_props_action->get_active());
tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-list"));
node->set_property (X_("show-editor-list"), tact->get_active());
tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-props"));
node->set_property (X_("show-editor-props"), tact->get_active());
node->set_property (X_("editor-list-page"), _the_notebook.get_current_page ()); node->set_property (X_("editor-list-page"), _the_notebook.get_current_page ());
node->set_property (X_("editor-list-btn1"), _notebook_tab1.index ()); node->set_property (X_("editor-list-btn1"), _notebook_tab1.index ());
@ -2399,7 +2395,7 @@ Editor::get_state () const
} }
node->set_property (X_("show-marker-lines"), _show_marker_lines); node->set_property (X_("show-marker-lines"), _show_marker_lines);
node->set_property (X_("show-touched-automation"), _show_touched_automation); node->set_property (X_("show-touched-automation"), show_touched_automation());
node->add_child_nocopy (selection->get_state ()); node->add_child_nocopy (selection->get_state ());
@ -2615,7 +2611,7 @@ Editor::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode direction,
ret = snap_to_bbt (presnap, direction, gpref); ret = snap_to_bbt (presnap, direction, gpref);
} }
switch (_grid_type) { switch (grid_type()) {
case GridTypeTimecode: case GridTypeTimecode:
ret = snap_to_timecode(presnap, direction, gpref); ret = snap_to_timecode(presnap, direction, gpref);
break; break;
@ -3458,28 +3454,29 @@ Editor::set_stationary_playhead (bool yn)
} }
bool bool
Editor::show_touched_automation () const Editor::show_touched_automation() const
{ {
if (!contents().get_mapped()) { if (!contents().get_mapped()) {
return false; return false;
} }
return _show_touched_automation;
if (!show_touched_automation_action) {
return false;
}
return show_touched_automation_action->get_active ();
} }
void void
Editor::toggle_show_touched_automation () Editor::toggle_show_touched_automation ()
{ {
RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-touched-automation")); set_show_touched_automation (show_touched_automation_action->get_active());
set_show_touched_automation (tact->get_active());
} }
void void
Editor::set_show_touched_automation (bool yn) Editor::set_show_touched_automation (bool yn)
{ {
if (_show_touched_automation == yn) { show_touched_automation_action->set_active (yn);
return;
}
_show_touched_automation = yn;
if (!yn) { if (!yn) {
RouteTimeAxisView::signal_ctrl_touched (true); RouteTimeAxisView::signal_ctrl_touched (true);
} }
@ -4546,7 +4543,7 @@ Editor::located ()
if (_session) { if (_session) {
_playhead_cursor->set_position (_session->audible_sample ()); _playhead_cursor->set_position (_session->audible_sample ());
if (_follow_playhead && !_pending_initial_locate) { if (follow_playhead() && !_pending_initial_locate) {
reset_x_origin_to_follow_playhead (); reset_x_origin_to_follow_playhead ();
} }
update_section_box (); update_section_box ();
@ -5330,7 +5327,7 @@ Editor::super_rapid_screen_update ()
return; return;
} }
if (!_follow_playhead || pending_visual_change.being_handled) { if (!follow_playhead() || pending_visual_change.being_handled) {
/* We only do this if we aren't already /* We only do this if we aren't already
* handling a visual change (ie if * handling a visual change (ie if
* pending_visual_change.being_handled is * pending_visual_change.being_handled is
@ -5721,7 +5718,7 @@ Editor::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapP
timepos_t best = timepos_t::max (start.time_domain()); // this records the best snap-result we've found so far timepos_t best = timepos_t::max (start.time_domain()); // this records the best snap-result we've found so far
/* check Grid */ /* check Grid */
if ( (_grid_type != GridTypeNone) && (uic.get_snap_target () != SnapTargetOther) ) { if ( (grid_type() != GridTypeNone) && (uic.get_snap_target () != SnapTargetOther) ) {
timepos_t pre (presnap); timepos_t pre (presnap);
timepos_t post (snap_to_grid (pre, direction, pref)); timepos_t post (snap_to_grid (pre, direction, pref));
check_best_snap (presnap, post, dist, best); check_best_snap (presnap, post, dist, best);

View file

@ -2065,6 +2065,11 @@ private:
Glib::RefPtr<Gtk::Action> selection_undo_action; Glib::RefPtr<Gtk::Action> selection_undo_action;
Glib::RefPtr<Gtk::Action> selection_redo_action; Glib::RefPtr<Gtk::Action> selection_redo_action;
Glib::RefPtr<Gtk::ToggleAction> show_editor_mixer_action;
Glib::RefPtr<Gtk::ToggleAction> show_editor_list_action;
Glib::RefPtr<Gtk::ToggleAction> show_editor_props_action;
Glib::RefPtr<Gtk::ToggleAction> show_touched_automation_action;
void history_changed (); void history_changed ();
Editing::EditPoint _edit_point; Editing::EditPoint _edit_point;
@ -2200,7 +2205,6 @@ private:
/* RTAV Automation display option */ /* RTAV Automation display option */
void toggle_show_touched_automation (); void toggle_show_touched_automation ();
void set_show_touched_automation (bool); void set_show_touched_automation (bool);
bool _show_touched_automation;
int time_fx (ARDOUR::RegionList&, Temporal::ratio_t ratio, bool pitching, bool fixed_end); int time_fx (ARDOUR::RegionList&, Temporal::ratio_t ratio, bool pitching, bool fixed_end);
void toggle_sound_midi_notes (); void toggle_sound_midi_notes ();

View file

@ -187,17 +187,17 @@ Editor::register_actions ()
/* attachments visibility (editor-mixer-strip, bottom properties, sidebar list) */ /* attachments visibility (editor-mixer-strip, bottom properties, sidebar list) */
act = ActionManager::register_toggle_action (editor_actions, "show-editor-list", _("Show Editor List"), sigc::mem_fun (*this, &Tabbable::att_right_button_toggled)); show_editor_list_action = ActionManager::register_toggle_action (editor_actions, "show-editor-list", _("Show Editor List"), sigc::mem_fun (*this, &Tabbable::att_right_button_toggled));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (show_editor_list_action);
right_attachment_button.set_related_action (act); right_attachment_button.set_related_action (show_editor_list_action);
act = ActionManager::register_toggle_action (editor_actions, "show-editor-mixer", _("Show Editor Mixer"), sigc::mem_fun (*this, &Tabbable::att_left_button_toggled)); show_editor_mixer_action = ActionManager::register_toggle_action (editor_actions, "show-editor-mixer", _("Show Editor Mixer"), sigc::mem_fun (*this, &Tabbable::att_left_button_toggled));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (show_editor_mixer_action);
left_attachment_button.set_related_action (act); left_attachment_button.set_related_action (show_editor_mixer_action);
act = ActionManager::register_toggle_action (editor_actions, "show-editor-props", _("Show Editor Properties Box"), sigc::mem_fun (*this, &Tabbable::att_bottom_button_toggled)); show_editor_props_action = ActionManager::register_toggle_action (editor_actions, "show-editor-props", _("Show Editor Properties Box"), sigc::mem_fun (*this, &Tabbable::att_bottom_button_toggled));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (show_editor_props_action);
bottom_attachment_button.set_related_action (act); bottom_attachment_button.set_related_action (show_editor_props_action);
reg_sens (editor_actions, "playhead-to-next-region-boundary", _("Playhead to Next Region Boundary"), sigc::bind (sigc::mem_fun(*this, &Editor::cursor_to_next_region_boundary), true)); reg_sens (editor_actions, "playhead-to-next-region-boundary", _("Playhead to Next Region Boundary"), sigc::bind (sigc::mem_fun(*this, &Editor::cursor_to_next_region_boundary), true));
reg_sens (editor_actions, "playhead-to-next-region-boundary-noselection", _("Playhead to Next Region Boundary (No Track Selection)"), sigc::bind (sigc::mem_fun(*this, &Editor::cursor_to_next_region_boundary), false)); reg_sens (editor_actions, "playhead-to-next-region-boundary-noselection", _("Playhead to Next Region Boundary (No Track Selection)"), sigc::bind (sigc::mem_fun(*this, &Editor::cursor_to_next_region_boundary), false));
@ -480,7 +480,7 @@ Editor::register_actions ()
ActionManager::register_toggle_action (editor_actions, "toggle-stationary-playhead", _("Stationary Playhead"), (mem_fun(*this, &Editor::toggle_stationary_playhead))); ActionManager::register_toggle_action (editor_actions, "toggle-stationary-playhead", _("Stationary Playhead"), (mem_fun(*this, &Editor::toggle_stationary_playhead)));
ActionManager::register_toggle_action (editor_actions, "show-touched-automation", _("Show Automation Lane on Touch"), (mem_fun(*this, &Editor::toggle_show_touched_automation))); show_touched_automation_action = ActionManager::register_toggle_action (editor_actions, "show-touched-automation", _("Show Automation Lane on Touch"), (mem_fun(*this, &Editor::toggle_show_touched_automation)));
act = reg_sens (editor_actions, "insert-time", _("Insert Time"), (sigc::mem_fun(*this, &Editor::do_insert_time))); act = reg_sens (editor_actions, "insert-time", _("Insert Time"), (sigc::mem_fun(*this, &Editor::do_insert_time)));
ActionManager::track_selection_sensitive_actions.push_back (act); ActionManager::track_selection_sensitive_actions.push_back (act);

View file

@ -3106,7 +3106,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
/* only snap to bars. */ /* only snap to bars. */
editing_context.set_grid_to (GridTypeBar); editing_context.set_grid_type (GridTypeBar);
editing_context.set_snap_mode (SnapMagnetic); editing_context.set_snap_mode (SnapMagnetic);
} }
@ -3143,7 +3143,7 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
} }
/* reinstate old snap setting */ /* reinstate old snap setting */
editing_context.set_grid_to (_old_grid_type); editing_context.set_grid_type (_old_grid_type);
editing_context.set_snap_mode (_old_snap_mode); editing_context.set_snap_mode (_old_snap_mode);
_editor.commit_tempo_map_edit (map); _editor.commit_tempo_map_edit (map);
@ -3167,7 +3167,7 @@ MeterMarkerDrag::aborted (bool moved)
if (moved) { if (moved) {
/* reinstate old snap setting */ /* reinstate old snap setting */
editing_context.set_grid_to (_old_grid_type); editing_context.set_grid_type (_old_grid_type);
editing_context.set_snap_mode (_old_snap_mode); editing_context.set_snap_mode (_old_snap_mode);
// delete the dummy marker we used for visual representation while moving. // delete the dummy marker we used for visual representation while moving.

View file

@ -150,14 +150,14 @@ Editor::mouse_mode_toggled (MouseMode m)
this must toggle the actions and not call set_snap_*() directly, this must toggle the actions and not call set_snap_*() directly,
otherwise things get out of sync and the combo box stops working. */ otherwise things get out of sync and the combo box stops working. */
if (!UIConfiguration::instance().get_grid_follows_internal()) { if (!UIConfiguration::instance().get_grid_follows_internal()) {
grid_type_action(pre_internal_grid_type)->set_active(true); grid_actions[pre_internal_grid_type]->set_active(true);
snap_mode_action(pre_internal_snap_mode)->set_active(true); snap_mode_actions[pre_internal_snap_mode]->set_active(true);
} else if (!was_internal && internal_editing()) { } else if (!was_internal && internal_editing()) {
grid_type_action(internal_grid_type)->set_active(true); grid_actions[internal_grid_type]->set_active(true);
snap_mode_action(internal_snap_mode)->set_active(true); snap_mode_actions[internal_snap_mode]->set_active(true);
} else if (was_internal && !internal_editing()) { } else if (was_internal && !internal_editing()) {
grid_type_action(pre_internal_grid_type)->set_active(true); grid_actions[pre_internal_grid_type]->set_active(true);
snap_mode_action(pre_internal_snap_mode)->set_active(true); snap_mode_actions[pre_internal_snap_mode]->set_active(true);
} }
instant_save (); instant_save ();
@ -2108,7 +2108,7 @@ void
Editor::mouse_brush_insert_region (RegionView* rv, timepos_t const & pos) Editor::mouse_brush_insert_region (RegionView* rv, timepos_t const & pos)
{ {
/* no brushing without a useful quantize setting */ /* no brushing without a useful quantize setting */
if (_grid_type == GridTypeNone) if (grid_type() == GridTypeNone)
return; return;
/* don't brush a copy over the original */ /* don't brush a copy over the original */

View file

@ -2620,7 +2620,7 @@ Editor::maybe_locate_with_edit_preroll (samplepos_t location)
} }
//if follow_playhead is on, keep the playhead on the screen //if follow_playhead is on, keep the playhead on the screen
if (_follow_playhead) if (follow_playhead())
if (location < _leftmost_sample) if (location < _leftmost_sample)
location = _leftmost_sample; location = _leftmost_sample;
@ -7801,7 +7801,7 @@ Editor::playhead_forward_to_grid ()
timepos_t pos (_playhead_cursor->current_sample ()); timepos_t pos (_playhead_cursor->current_sample ());
if (_grid_type == GridTypeNone) { if (grid_type() == GridTypeNone) {
timepos_t const decipage (samplepos_t(floor (current_page_samples() * 0.1))); timepos_t const decipage (samplepos_t(floor (current_page_samples() * 0.1)));
if (pos < timepos_t::max (pos.time_domain()).earlier (decipage)) { if (pos < timepos_t::max (pos.time_domain()).earlier (decipage)) {
pos += timepos_t (decipage); pos += timepos_t (decipage);
@ -7830,7 +7830,7 @@ Editor::playhead_backward_to_grid ()
timepos_t pos (_playhead_cursor->current_sample ()); timepos_t pos (_playhead_cursor->current_sample ());
if (_grid_type == GridTypeNone) { if (grid_type() == GridTypeNone) {
samplepos_t const decipage (floor (current_page_samples() * 0.1)); samplepos_t const decipage (floor (current_page_samples() * 0.1));
if (pos.samples() > decipage) { if (pos.samples() > decipage) {
pos.shift_earlier (timepos_t (decipage)); pos.shift_earlier (timepos_t (decipage));

View file

@ -363,7 +363,7 @@ Editor::compute_current_bbt_points (Temporal::TempoMapPoints& grid, samplepos_t
const samplecnt_t sr (_session->sample_rate()); const samplecnt_t sr (_session->sample_rate());
float divisor; float divisor;
switch (_grid_type) { switch (grid_type()) {
case GridTypeBeatDiv3: case GridTypeBeatDiv3:
case GridTypeBeatDiv6: case GridTypeBeatDiv6:
case GridTypeBeatDiv12: case GridTypeBeatDiv12:

View file

@ -202,7 +202,6 @@ MidiView::init (std::shared_ptr<MidiTrack> mt)
void void
MidiView::note_mode_changed () MidiView::note_mode_changed ()
{ {
std::cerr << "NM change\n";
clear_events (); clear_events ();
model_changed (); model_changed ();
} }

File diff suppressed because it is too large Load diff

View file

@ -58,12 +58,8 @@ class Pianoroll : public CueEditor
Pianoroll (std::string const & name, bool with_transport_controls = false); Pianoroll (std::string const & name, bool with_transport_controls = false);
~Pianoroll (); ~Pianoroll ();
ArdourCanvas::Container* get_trackview_group () const { return data_group; }
ArdourCanvas::Container* get_noscroll_group() const { return no_scroll_group; }
Gtk::Widget& viewport();
Gtk::Widget& contents (); Gtk::Widget& contents ();
double visible_canvas_width() const { return _visible_canvas_width; }
samplecnt_t current_page_samples() const; samplecnt_t current_page_samples() const;
void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const {} void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const {}
@ -83,33 +79,13 @@ class Pianoroll : public CueEditor
int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) const { return 1; } int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) const { return 1; }
void set_trigger (ARDOUR::TriggerReference&); void set_trigger (ARDOUR::TriggerReference&);
void set_region (std::shared_ptr<ARDOUR::MidiRegion>); void set_region (std::shared_ptr<ARDOUR::Region>);
void set_track (std::shared_ptr<ARDOUR::MidiTrack>); void set_track (std::shared_ptr<ARDOUR::Track>);
ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
double max_extents_scale() const { return 1.2; } double max_extents_scale() const { return 1.2; }
void set_samples_per_pixel (samplecnt_t); void set_samples_per_pixel (samplecnt_t);
void set_mouse_mode (Editing::MouseMode, bool force = false); void set_mouse_mode (Editing::MouseMode, bool force = false);
void step_mouse_mode (bool next);
Editing::MouseMode current_mouse_mode () const;
bool internal_editing() const;
void trigger_arm_change ();
double timebar_height;
size_t n_timebars;
ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const;
ArdourCanvas::GtkCanvas* get_canvas() const;
int set_state (const XMLNode&, int version);
XMLNode& get_state () const;
void maybe_autoscroll (bool, bool, bool);
bool autoscroll_active() const;
void midi_action (void (MidiView::*method)()); void midi_action (void (MidiView::*method)());
@ -133,9 +109,6 @@ class Pianoroll : public CueEditor
void set_trigger_length (Temporal::timecnt_t const &); void set_trigger_length (Temporal::timecnt_t const &);
void set_trigger_bounds (Temporal::timepos_t const &, Temporal::timepos_t const &); void set_trigger_bounds (Temporal::timepos_t const &, Temporal::timepos_t const &);
void full_zoom_clicked();
void zoom_to_show (Temporal::timecnt_t const &);
void delete_ (); void delete_ ();
void paste (float times, bool from_context_menu); void paste (float times, bool from_context_menu);
void keyboard_paste (); void keyboard_paste ();
@ -143,7 +116,6 @@ class Pianoroll : public CueEditor
PianorollMidiView* midi_view() const { return view; } PianorollMidiView* midi_view() const { return view; }
void set_session (ARDOUR::Session*); void set_session (ARDOUR::Session*);
void session_going_away ();
bool allow_trim_cursors () const; bool allow_trim_cursors () const;
void shift_midi (Temporal::timepos_t const &, bool model); void shift_midi (Temporal::timepos_t const &, bool model);
@ -154,9 +126,6 @@ class Pianoroll : public CueEditor
void set_show_source (bool); void set_show_source (bool);
protected: protected:
void load_bindings ();
void register_actions ();
Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start, Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start,
Temporal::RoundMode direction, Temporal::RoundMode direction,
ARDOUR::SnapPref gpref) const; ARDOUR::SnapPref gpref) const;
@ -178,46 +147,14 @@ class Pianoroll : public CueEditor
bool key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType); bool key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
bool key_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType); bool key_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
void mouse_mode_toggled (Editing::MouseMode);
void escape (); void escape ();
private: private:
ARDOUR::TriggerReference ref;
std::shared_ptr<ARDOUR::MidiTrack> _track;
ArdourCanvas::GtkCanvasViewport* _canvas_viewport;
ArdourCanvas::GtkCanvas* _canvas;
Gtk::HScrollbar* _canvas_hscrollbar;
/* The group containing all other groups that are scrolled vertically
and horizontally.
*/
ArdourCanvas::ScrollGroup* hv_scroll_group;
/* The group containing all other groups that are scrolled horizontally ONLY
*/
ArdourCanvas::ScrollGroup* h_scroll_group;
ArdourCanvas::ScrollGroup* v_scroll_group;
/* Scroll group for cursors, scrolled horizontally, above everything else
*/
ArdourCanvas::ScrollGroup* cursor_scroll_group;
ArdourCanvas::Container* global_rect_group;
ArdourCanvas::Container* no_scroll_group;
ArdourCanvas::Container* data_group;
ArdourCanvas::Ruler* bbt_ruler; ArdourCanvas::Ruler* bbt_ruler;
ArdourCanvas::Rectangle* tempo_bar; ArdourCanvas::Rectangle* tempo_bar;
ArdourCanvas::Rectangle* meter_bar; ArdourCanvas::Rectangle* meter_bar;
ArdourCanvas::PianoRollHeader* prh; ArdourCanvas::PianoRollHeader* prh;
ArdourCanvas::Rectangle* transport_loop_range_rect;
ArdourWidgets::EventBoxExt _contents;
Gtk::VBox _toolbox;
Gtk::HBox button_bar;
ArdourWidgets::ArdourButton* velocity_button; ArdourWidgets::ArdourButton* velocity_button;
ArdourWidgets::ArdourButton* bender_button; ArdourWidgets::ArdourButton* bender_button;
ArdourWidgets::ArdourButton* pressure_button; ArdourWidgets::ArdourButton* pressure_button;
@ -236,15 +173,10 @@ class Pianoroll : public CueEditor
void build_canvas (); void build_canvas ();
void canvas_allocate (Gtk::Allocation); void canvas_allocate (Gtk::Allocation);
void build_upper_toolbar ();
void build_lower_toolbar (); void build_lower_toolbar ();
RegionSelection region_selection();
bool canvas_enter_leave (GdkEventCrossing* ev); bool canvas_enter_leave (GdkEventCrossing* ev);
void metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>&, samplepos_t, samplepos_t, gint);
class BBTMetric : public ArdourCanvas::Ruler::Metric class BBTMetric : public ArdourCanvas::Ruler::Metric
{ {
public: public:
@ -260,16 +192,6 @@ class Pianoroll : public CueEditor
BBTMetric bbt_metric; BBTMetric bbt_metric;
bool canvas_pre_event (GdkEvent*);
/* autoscrolling */
bool autoscroll_canvas ();
void start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const ArdourCanvas::Rect& boundary);
void stop_canvas_autoscroll ();
sigc::connection _update_connection;
PBD::ScopedConnectionList object_connections;
PBD::ScopedConnectionList view_connections; PBD::ScopedConnectionList view_connections;
void maybe_update (); void maybe_update ();
void trigger_prop_change (PBD::PropertyChange const &); void trigger_prop_change (PBD::PropertyChange const &);
@ -277,14 +199,9 @@ class Pianoroll : public CueEditor
void unset (bool trigger_too); void unset (bool trigger_too);
void visual_changer (const VisualChange&);
void bindings_changed (); void bindings_changed ();
void data_captured (samplecnt_t);
bool idle_data_captured (); bool idle_data_captured ();
std::atomic<int> idle_update_queued;
PBD::ScopedConnectionList capture_connections;
samplecnt_t data_capture_duration;
bool user_automation_button_event (GdkEventButton* ev, ArdourWidgets::MetaButton* mb); bool user_automation_button_event (GdkEventButton* ev, ArdourWidgets::MetaButton* mb);
bool automation_button_event (GdkEventButton*, Evoral::ParameterType type, int id); bool automation_button_event (GdkEventButton*, Evoral::ParameterType type, int id);
@ -299,37 +216,8 @@ class Pianoroll : public CueEditor
void automation_state_changed (); void automation_state_changed ();
void build_zoom_focus_menu ();
std::pair<Temporal::timepos_t,Temporal::timepos_t> max_zoom_extent() const;
void point_selection_changed (); void point_selection_changed ();
bool zoom_in_allocate;
ArdourWidgets::ArdourButton rec_enable_button;
ArdourWidgets::ArdourButton play_button;
ArdourWidgets::ArdourButton solo_button;
ArdourWidgets::ArdourButton loop_button;
bool play_button_press (GdkEventButton*);
bool bang_button_press (GdkEventButton*);
bool solo_button_press (GdkEventButton*);
bool loop_button_press (GdkEventButton*);
ArdourWidgets::ArdourDropdown length_selector;
Temporal::BBT_Offset rec_length;
Gtk::Label length_label;
Gtk::HBox rec_box;
Gtk::HBox play_box;
void set_recording_length (Temporal::BBT_Offset bars);
bool rec_button_press (GdkEventButton*);
void rec_enable_change ();
void blink_rec_enable (bool);
sigc::connection rec_blink_connection;
void add_single_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, int ctl, const std::string& name, ArdourWidgets::MetaButton*); void add_single_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, int ctl, const std::string& name, ArdourWidgets::MetaButton*);
void add_multi_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, uint16_t channels, int ctl, const std::string& name, ArdourWidgets::MetaButton*); void add_multi_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, uint16_t channels, int ctl, const std::string& name, ArdourWidgets::MetaButton*);
void reset_user_cc_choice (std::string, Evoral::Parameter param, ArdourWidgets::MetaButton*); void reset_user_cc_choice (std::string, Evoral::Parameter param, ArdourWidgets::MetaButton*);
@ -337,30 +225,29 @@ class Pianoroll : public CueEditor
bool ignore_channel_changes; bool ignore_channel_changes;
void visible_channel_changed (); void visible_channel_changed ();
bool with_transport_controls;
void update_solo_display ();
void map_transport_state (); void map_transport_state ();
sigc::connection count_in_connection;
Temporal::Beats count_in_to;
void count_in (Temporal::timepos_t, unsigned int);
void maybe_set_count_in ();
bool bbt_ruler_event (GdkEvent*);
void ruler_locate (GdkEventButton*);
void scrolled ();
void update_tempo_based_rulers (); void update_tempo_based_rulers ();
void update_rulers() { update_tempo_based_rulers (); }
Gtk::Menu _region_context_menu; Gtk::Menu _region_context_menu;
void popup_region_context_menu (ArdourCanvas::Item* item, GdkEvent* event); void popup_region_context_menu (ArdourCanvas::Item* item, GdkEvent* event);
std::shared_ptr<ARDOUR::MidiRegion> _visible_pending_region;
void catch_pending_show_region ();
bool show_source;
void set_note_selection (uint8_t note); void set_note_selection (uint8_t note);
void add_note_selection (uint8_t note); void add_note_selection (uint8_t note);
void extend_note_selection (uint8_t note); void extend_note_selection (uint8_t note);
void toggle_note_selection (uint8_t note); void toggle_note_selection (uint8_t note);
void pack_inner (Gtk::Box&);
void pack_outer (Gtk::Box&);
void begin_write ();
void end_write ();
void manage_possible_header (Gtk::Allocation& alloc);
void show_count_in (std::string const &);
void hide_count_in ();
void instant_save ();
}; };

View file

@ -19,6 +19,7 @@
#include "pbd/compose.h" #include "pbd/compose.h"
#include "ardour/midi_region.h" #include "ardour/midi_region.h"
#include "ardour/midi_track.h"
#include "gtkmm2ext/doi.h" #include "gtkmm2ext/doi.h"
@ -35,7 +36,7 @@ PianorollWindow::PianorollWindow (std::string const & name, Session& s)
, region_editor (nullptr) , region_editor (nullptr)
{ {
pianoroll->set_session (&s); pianoroll->set_session (&s);
pianoroll->viewport().set_size_request (600, 120); pianoroll->get_canvas_viewport()->set_size_request (600, 120);
add (hpacker); add (hpacker);
hpacker.show (); hpacker.show ();

View file

@ -144,24 +144,21 @@ TriggerPage::TriggerPage ()
_sidebar_pager2.set_index (3); _sidebar_pager2.set_index (3);
_midi_editor = new Pianoroll (X_("MIDICueEditor")); _midi_editor = new Pianoroll (X_("MIDICueEditor"));
_audio_editor = new AudioClipEditor (X_("AudioClipEditor"));
_audio_editor->get_canvas_viewport()->show ();
_midi_editor->get_canvas_viewport()->show ();
/* Bottom -- Properties of selected Slot/Region */ /* Bottom -- Properties of selected Slot/Region */
table.set_homogeneous (false); hpacker.set_homogeneous (false);
table.set_spacings (8); //match to slot_properties_box::set_spacings hpacker.set_spacing (8); //match to slot_properties_box::set_spacings
table.set_border_width (8); hpacker.set_border_width (8);
int col = 0; hpacker.pack_start (_properties_box, false, false);
table.attach (_properties_box, col, col + 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK | Gtk::FILL); hpacker.pack_start (_midi_trig_box, false, false);
++col; hpacker.pack_start (_audio_trig_box, false, false);
table.attach (_audio_trig_box, col, col + 1, 0, 1, Gtk::FILL, Gtk::SHRINK | Gtk::FILL); hpacker.set_no_show_all ();
clip_editor_column = ++col;
++col;
table.set_no_show_all ();
_parameter_box.pack_start (table);
_parameter_box.show ();
_sidebar_notebook.signal_switch_page().connect ([this](GtkNotebookPage*, guint page) { _sidebar_notebook.signal_switch_page().connect ([this](GtkNotebookPage*, guint page) {
std::string label (_sidebar_notebook.get_tab_label_text (*_sidebar_notebook.get_nth_page (page))); std::string label (_sidebar_notebook.get_tab_label_text (*_sidebar_notebook.get_nth_page (page)));
@ -184,7 +181,7 @@ TriggerPage::TriggerPage ()
/* Top-level Layout */ /* Top-level Layout */
content_app_bar.add (_application_bar); content_app_bar.add (_application_bar);
content_main.add (_strip_group_box); content_main.add (_strip_group_box);
content_att_bottom.add (_parameter_box); content_att_bottom.add (hpacker);
content_att_right.add (_sidebar_vbox); content_att_right.add (_sidebar_vbox);
/* Show all */ /* Show all */
@ -263,6 +260,7 @@ TriggerPage::get_state () const
node->set_property (X_("triggerpage-sidebar-btn2"), _sidebar_pager2.index ()); node->set_property (X_("triggerpage-sidebar-btn2"), _sidebar_pager2.index ());
node->add_child_nocopy (_midi_editor->get_state()); node->add_child_nocopy (_midi_editor->get_state());
node->add_child_nocopy (_audio_editor->get_state());
Glib::RefPtr<ToggleAction> act = ActionManager::get_toggle_action ("Cues", "ToggleTriggerList"); Glib::RefPtr<ToggleAction> act = ActionManager::get_toggle_action ("Cues", "ToggleTriggerList");
node->set_property ("show-trigger-list", act->get_active ()); node->set_property ("show-trigger-list", act->get_active ());
@ -306,6 +304,11 @@ TriggerPage::set_state (const XMLNode& node, int version)
_midi_editor->set_state (*mn, version); _midi_editor->set_state (*mn, version);
} }
XMLNode* an = node.child (_audio_editor->editor_name().c_str());
if (an) {
_audio_editor->set_state (*an, version);
}
bool yn = true; bool yn = true;
node.get_property ("show-trigger-list", yn); node.get_property ("show-trigger-list", yn);
{ {
@ -368,10 +371,10 @@ TriggerPage::set_session (Session* s)
initial_track_display (); initial_track_display ();
_properties_box.set_session (s); _properties_box.set_session (s);
_audio_trig_box.set_session (s); _audio_trig_box.set_session (s);
_midi_trig_box.set_session (s);
_midi_editor->set_session (s); _midi_editor->set_session (s);
_audio_editor->set_session (s);
update_title (); update_title ();
start_updating (); start_updating ();
@ -475,9 +478,7 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
/* hide everything */ /* hide everything */
_audio_trig_box.hide (); hide_all ();
_midi_trig_box.hide ();
_midi_editor->viewport().hide ();
Tabbable::showhide_att_bottom (false); Tabbable::showhide_att_bottom (false);
@ -485,10 +486,13 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
TriggerReference ref (trigger->boxptr(), trigger->index()); TriggerReference ref (trigger->boxptr(), trigger->index());
if (box.data_type () == DataType::AUDIO) { if (box.data_type () == DataType::AUDIO) {
if (trigger->the_region()) {
_audio_trig_box.set_trigger (ref); _audio_trig_box.set_trigger (ref);
_audio_trig_box.show (); _audio_trig_box.show ();
}
_audio_editor->set_trigger (ref);
hpacker.pack_start (_audio_editor->contents(), true, true);
} else { } else {
@ -496,7 +500,7 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
_midi_trig_box.show (); _midi_trig_box.show ();
_midi_editor->set_trigger (ref); _midi_editor->set_trigger (ref);
_midi_editor->viewport().show (); hpacker.pack_start (_midi_editor->contents(), true, true);
} }
if (_show_bottom_pane) { if (_show_bottom_pane) {
@ -505,38 +509,46 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
} }
void void
TriggerPage::selection_changed () TriggerPage::hide_all ()
{ {
Selection& selection (Editor::instance ().get_selection ()); if (_audio_editor->contents().get_parent()) {
_audio_editor->contents().get_parent()->remove (_audio_editor->contents());
/* hide everything */ }
_audio_trig_box.hide ();
_midi_trig_box.hide ();
_midi_editor->contents().hide(); // although we de-parent this, it requires this explicit HIDE to prevent bleeding into other pages on macOS
if (_midi_editor->contents().get_parent()) { if (_midi_editor->contents().get_parent()) {
_midi_editor->contents().get_parent()->remove (_midi_editor->contents()); _midi_editor->contents().get_parent()->remove (_midi_editor->contents());
} }
_audio_trig_box.hide ();
_midi_trig_box.hide ();
}
void
TriggerPage::selection_changed ()
{
Selection& selection (Editor::instance ().get_selection ());
hide_all ();
Tabbable::showhide_att_bottom (false); Tabbable::showhide_att_bottom (false);
if (selection.triggers.empty ()) { if (selection.triggers.empty ()) {
return; return;
} }
TriggerSelection ts = selection.triggers; TriggerReference ref = selection.triggers.front()->trigger_reference ();
TriggerEntry* entry = *ts.begin ();
TriggerReference ref = entry->trigger_reference ();
TriggerPtr trigger = entry->trigger ();
std::shared_ptr<TriggerBox> box = ref.box(); std::shared_ptr<TriggerBox> box = ref.box();
if (box->data_type () == DataType::AUDIO) { if (box->data_type () == DataType::AUDIO) {
if (trigger->the_region()) { _audio_trig_box.set_trigger (ref);
_audio_trig_box.set_trigger (ref); _audio_trig_box.show ();
_audio_trig_box.show ();
} _audio_editor->set_trigger (ref);
_audio_editor->get_canvas_viewport()->show ();
hpacker.pack_start (_audio_editor->contents(), true, true);
_audio_editor->contents().show_all ();
} else { } else {
@ -544,12 +556,13 @@ TriggerPage::selection_changed ()
_midi_trig_box.show (); _midi_trig_box.show ();
_midi_editor->set_trigger (ref); _midi_editor->set_trigger (ref);
_midi_editor->get_canvas_viewport()->show ();
table.attach (_midi_editor->contents(), clip_editor_column, clip_editor_column + 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL); hpacker.pack_start (_midi_editor->contents(), true, true);
_midi_editor->contents().show_all (); _midi_editor->contents().show_all ();
} }
table.show (); hpacker.show ();
if (_show_bottom_pane) { if (_show_bottom_pane) {
Tabbable::showhide_att_bottom (true); Tabbable::showhide_att_bottom (true);

View file

@ -30,6 +30,7 @@
#include "widgets/tabbable.h" #include "widgets/tabbable.h"
#include "application_bar.h" #include "application_bar.h"
#include "audio_clip_editor.h"
#include "audio_region_operations_box.h" #include "audio_region_operations_box.h"
#include "audio_trigger_properties_box.h" #include "audio_trigger_properties_box.h"
#include "axis_provider.h" #include "axis_provider.h"
@ -76,7 +77,7 @@ private:
void remove_route (TriggerStrip*); void remove_route (TriggerStrip*);
void clear_selected_slot (); void clear_selected_slot ();
void hide_all ();
void redisplay_track_list (); void redisplay_track_list ();
void pi_property_changed (PBD::PropertyChange const&); void pi_property_changed (PBD::PropertyChange const&);
void stripable_property_changed (PBD::PropertyChange const&, std::weak_ptr<ARDOUR::Stripable>); void stripable_property_changed (PBD::PropertyChange const&, std::weak_ptr<ARDOUR::Stripable>);
@ -117,7 +118,6 @@ private:
Gtk::EventBox _no_strips; Gtk::EventBox _no_strips;
Gtk::Alignment _cue_area_frame; Gtk::Alignment _cue_area_frame;
Gtk::VBox _cue_area_box; Gtk::VBox _cue_area_box;
Gtk::HBox _parameter_box;
Gtk::VBox _sidebar_vbox; Gtk::VBox _sidebar_vbox;
ArdourWidgets::MetaButton _sidebar_pager1; ArdourWidgets::MetaButton _sidebar_pager1;
ArdourWidgets::MetaButton _sidebar_pager2; ArdourWidgets::MetaButton _sidebar_pager2;
@ -126,7 +126,7 @@ private:
TriggerSourceList _trigger_source_list; TriggerSourceList _trigger_source_list;
TriggerRegionList _trigger_region_list; TriggerRegionList _trigger_region_list;
TriggerRouteList _trigger_route_list; TriggerRouteList _trigger_route_list;
Gtk::Table table; Gtk::HBox hpacker;
CueBoxWidget _cue_box; CueBoxWidget _cue_box;
FittedCanvasWidget _master_widget; FittedCanvasWidget _master_widget;
@ -140,10 +140,10 @@ private:
#if REGION_PROPERTIES_BOX_TODO #if REGION_PROPERTIES_BOX_TODO
AudioRegionOperationsBox _audio_ops_box; AudioRegionOperationsBox _audio_ops_box;
AudioClipEditorBox _audio_trim_box;
#endif #endif
Pianoroll* _midi_editor; Pianoroll* _midi_editor;
AudioClipEditor* _audio_editor;
RouteProcessorSelection _selection; RouteProcessorSelection _selection;
std::list<TriggerStrip*> _strips; std::list<TriggerStrip*> _strips;