mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 23:35:03 +01:00
large-scale refactoring of Pianoroll, CueEditor and AudioClipEditor
Enables code-sharing between "clip editors"
This commit is contained in:
parent
81ca93bdfb
commit
1d4e3940d1
24 changed files with 2673 additions and 2668 deletions
|
|
@ -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) {
|
||||
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 ... */
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@
|
|||
#include "ardour_window.h"
|
||||
#include "editing.h"
|
||||
#include "enums.h"
|
||||
#include "region_ui_settings.h"
|
||||
#include "shuttle_control.h"
|
||||
#include "startup_fsm.h"
|
||||
#include "transport_control.h"
|
||||
|
|
@ -419,6 +420,8 @@ public:
|
|||
|
||||
void gui_idle_handler ();
|
||||
|
||||
RegionUISettingsManager region_ui_settings_manager;
|
||||
|
||||
protected:
|
||||
friend class PublicEditor;
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@ ARDOUR_UI::we_have_dependents ()
|
|||
mixer->monitor_section().use_others_actions ();
|
||||
|
||||
StepEntry::setup_actions_and_bindings ();
|
||||
ClipEditorBox::init ();
|
||||
RegionEditor::setup_actions_and_bindings ();
|
||||
|
||||
setup_action_tooltips ();
|
||||
|
|
|
|||
|
|
@ -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")));
|
||||
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_button_box);
|
||||
msg.get_vbox()->pack_start (subscribe_label);
|
||||
|
|
|
|||
|
|
@ -599,6 +599,15 @@ ARDOUR_UI::load_session_stage_two (const std::string& path, const std::string& s
|
|||
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 */
|
||||
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);
|
||||
|
||||
|
||||
if (_session) {
|
||||
_session->set_clean ();
|
||||
}
|
||||
|
|
@ -620,6 +630,7 @@ ARDOUR_UI::load_session_stage_two (const std::string& path, const std::string& s
|
|||
flush_pending (10);
|
||||
}
|
||||
|
||||
|
||||
retval = 0;
|
||||
|
||||
if (!mix_template.empty ()) {
|
||||
|
|
|
|||
|
|
@ -41,12 +41,16 @@
|
|||
#include "widgets/ardour_button.h"
|
||||
#include "widgets/ardour_icon.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "audio_clip_editor.h"
|
||||
#include "audio_clock.h"
|
||||
#include "editor_automation_line.h"
|
||||
#include "editor_cursors.h"
|
||||
#include "editor_drag.h"
|
||||
#include "control_point.h"
|
||||
#include "editor.h"
|
||||
#include "region_view.h"
|
||||
#include "verbose_cursor.h"
|
||||
#include "ui_config.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
|
@ -60,33 +64,11 @@ using namespace ArdourWidgets;
|
|||
using std::max;
|
||||
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
|
||||
AudioClipEditor::ClipBBTMetric::get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const
|
||||
{
|
||||
TriggerPtr trigger (tref.trigger());
|
||||
if (!trigger) {
|
||||
std::cerr << "No trigger\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -121,46 +103,153 @@ AudioClipEditor::ClipBBTMetric::get_marks (std::vector<ArdourCanvas::Ruler::Mark
|
|||
}
|
||||
}
|
||||
|
||||
AudioClipEditor::AudioClipEditor ()
|
||||
: clip_metric (0)
|
||||
, _spp (0)
|
||||
AudioClipEditor::AudioClipEditor (std::string const & name, bool with_transport)
|
||||
: CueEditor (name, with_transport)
|
||||
, clip_metric (nullptr)
|
||||
, scroll_fraction (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 ());
|
||||
frame->name = "audio clip editor frame";
|
||||
frame->set_fill (false);
|
||||
frame->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::event_handler));
|
||||
load_bindings ();
|
||||
register_actions ();
|
||||
|
||||
/* Scroll bar does not scroll and it outside the frame */
|
||||
build_grid_type_menu ();
|
||||
}
|
||||
|
||||
scroll_bar_trough = new ArdourCanvas::Rectangle (root ());
|
||||
scroll_bar_handle = new ArdourCanvas::Rectangle (scroll_bar_trough);
|
||||
scroll_bar_handle->set_outline (false);
|
||||
scroll_bar_handle->set_corner_radius (5.);
|
||||
scroll_bar_handle->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::scroll_event_handler));
|
||||
scroll_bar_handle->disable_scroll_translation ();
|
||||
void
|
||||
AudioClipEditor::load_shared_bindings ()
|
||||
{
|
||||
/* Full shared binding loading must have preceded this in some other EditingContext */
|
||||
assert (!need_shared_actions);
|
||||
|
||||
/* A scrolling container for our waves and lines etc. */
|
||||
Bindings* b = Bindings::get_bindings (X_("Editing"));
|
||||
|
||||
waves_container = new ArdourCanvas::ScrollGroup (frame, ScrollGroup::ScrollsHorizontally);
|
||||
add_scroller (*waves_container);
|
||||
/* Copy each shared bindings but give them a new name, which will make them refer to actions
|
||||
* named after this EditingContext (ie. unique to this EC)
|
||||
*/
|
||||
|
||||
ruler_container = new ArdourCanvas::Container (waves_container);
|
||||
ruler = new ArdourCanvas::Ruler (ruler_container, 0);
|
||||
ruler->name = "Clip Editor";
|
||||
ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
|
||||
ruler->set_fill_color (UIConfiguration::instance().color (X_("theme:bg1")));
|
||||
ruler->set_outline_color (UIConfiguration::instance().color (X_("theme:contrasting less")));
|
||||
Bindings* shared_bindings = new Bindings (editor_name(), *b);
|
||||
register_common_actions (shared_bindings, editor_name());
|
||||
shared_bindings->associate ();
|
||||
|
||||
/* Attach bindings to the canvas for this editing context */
|
||||
|
||||
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 */
|
||||
|
||||
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.;
|
||||
double scale = UIConfiguration::instance().get_ui_scale();
|
||||
|
||||
start_line = new Line (line_container);
|
||||
start_line->set_outline_width (line_width * scale);
|
||||
|
|
@ -222,41 +311,6 @@ AudioClipEditor::line_event_handler (GdkEvent* ev, ArdourCanvas::Line* l)
|
|||
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
|
||||
AudioClipEditor::key_press (GdkEventKey* ev)
|
||||
{
|
||||
|
|
@ -266,27 +320,15 @@ AudioClipEditor::key_press (GdkEventKey* ev)
|
|||
void
|
||||
AudioClipEditor::position_lines ()
|
||||
{
|
||||
if (!audio_region) {
|
||||
if (!_region) {
|
||||
return;
|
||||
}
|
||||
|
||||
start_line->set_x0 (sample_to_pixel (audio_region->start ().samples ()));
|
||||
start_line->set_x1 (sample_to_pixel (audio_region->start ().samples ()));
|
||||
start_line->set_x0 (sample_to_pixel (_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_x1 (sample_to_pixel (audio_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);
|
||||
end_line->set_x0 (sample_to_pixel (_region->end ().samples ()));
|
||||
end_line->set_x1 (sample_to_pixel (_region->end ().samples ()));
|
||||
}
|
||||
|
||||
AudioClipEditor::LineDrag::LineDrag (AudioClipEditor& ed, ArdourCanvas::Line& l)
|
||||
|
|
@ -317,78 +359,15 @@ AudioClipEditor::LineDrag::motion (GdkEventMotion* ev)
|
|||
void
|
||||
AudioClipEditor::set_colors ()
|
||||
{
|
||||
set_background_color (UIConfiguration::instance ().color (X_("theme:bg")));
|
||||
|
||||
frame->set_outline_color (UIConfiguration::instance ().color (X_("neutral:midground")));
|
||||
_canvas.set_background_color (UIConfiguration::instance ().color (X_("theme:bg")));
|
||||
|
||||
start_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting clock")));
|
||||
end_line->set_outline_color (UIConfiguration::instance ().color (X_("theme:contrasting alt")));
|
||||
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 ();
|
||||
}
|
||||
|
||||
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
|
||||
AudioClipEditor::drop_waves ()
|
||||
{
|
||||
|
|
@ -400,11 +379,39 @@ AudioClipEditor::drop_waves ()
|
|||
}
|
||||
|
||||
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 ();
|
||||
|
||||
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
|
||||
* 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;
|
||||
clip_metric = new ClipBBTMetric (tr);
|
||||
ruler->set_metric (clip_metric);
|
||||
clip_metric = new ClipBBTMetric (ref);
|
||||
minsec_ruler->set_metric (clip_metric);
|
||||
|
||||
uint32_t n_chans = r->n_channels ();
|
||||
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) {
|
||||
std::shared_ptr<Region> wr = RegionFactory::get_whole_region_for_source (r->source (n));
|
||||
|
||||
if (!wr) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -433,8 +441,8 @@ AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr
|
|||
continue;
|
||||
}
|
||||
|
||||
WaveView* wv = new WaveView (waves_container, war);
|
||||
wv->set_channel (n);
|
||||
WaveView* wv = new WaveView (data_group, war);
|
||||
wv->set_channel (0);
|
||||
wv->set_show_zero_line (false);
|
||||
wv->set_clip_level (1.0);
|
||||
wv->lower_to_bottom ();
|
||||
|
|
@ -442,75 +450,56 @@ AudioClipEditor::set_region (std::shared_ptr<AudioRegion> r, TriggerReference tr
|
|||
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_wave_heights ();
|
||||
set_waveform_colors ();
|
||||
|
||||
line_container->show ();
|
||||
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
|
||||
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);
|
||||
frame->set (r);
|
||||
_visible_canvas_width = alloc.get_width();
|
||||
_visible_canvas_height = alloc.get_height();
|
||||
|
||||
const double ruler_height = 25.;
|
||||
ruler->set (ArdourCanvas::Rect (2, 2, alloc.get_width() - 4, ruler_height));
|
||||
/* no track header here, "track width" is the whole canvas */
|
||||
_track_canvas_width = _visible_canvas_width;
|
||||
|
||||
const double scroll_bar_height = 10.;
|
||||
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));
|
||||
minsec_ruler->set (ArdourCanvas::Rect (2, 2, alloc.get_width() - 4, timebar_height));
|
||||
|
||||
position_lines ();
|
||||
|
||||
start_line->set_y1 (frame->get ().height () - 2. - scroll_bar_height);
|
||||
end_line->set_y1 (frame->get ().height () - 2. - scroll_bar_height);
|
||||
loop_line->set_y1 (frame->get ().height () - 2. - scroll_bar_height);
|
||||
start_line->set_y1 (_visible_canvas_height - 2.);
|
||||
end_line->set_y1 (_visible_canvas_height - 2.);
|
||||
loop_line->set_y1 (_visible_canvas_height - 2.);
|
||||
|
||||
set_wave_heights ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioClipEditor::set_spp (double samples_per_pixel)
|
||||
{
|
||||
_spp = samples_per_pixel;
|
||||
catch_pending_show_region ();
|
||||
|
||||
clip_metric->units_per_pixel = _spp;
|
||||
|
||||
position_lines ();
|
||||
|
||||
for (auto& wave : waves) {
|
||||
wave->set_samples_per_pixel (_spp);
|
||||
}
|
||||
update_grid ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioClipEditor::set_spp_from_length (samplecnt_t len)
|
||||
{
|
||||
double available_width = frame->get ().width ();
|
||||
double s = floor (len / available_width);
|
||||
|
||||
set_spp (s);
|
||||
if (_visible_canvas_width) {
|
||||
set_samples_per_pixel (floor (len / _visible_canvas_width));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -521,12 +510,12 @@ AudioClipEditor::set_wave_heights ()
|
|||
}
|
||||
|
||||
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 ();
|
||||
|
||||
for (auto& wave : waves) {
|
||||
wave->set_height (ht);
|
||||
wave->set_y_position (ruler->get ().height () + (n * ht));
|
||||
wave->set_y_position ((n_timebars * timebar_height) + (n * ht));
|
||||
++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
|
||||
AudioClipEditor::event_handler (GdkEvent* ev)
|
||||
AudioClipEditor::canvas_enter_leave (GdkEventCrossing* ev)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_PRESS:
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->detail != GDK_NOTIFY_INFERIOR) {
|
||||
_canvas.grab_focus ();
|
||||
// ActionManager::set_sensitive (_midi_actions, true);
|
||||
within_track_canvas = true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
AudioClipEditorBox::zoom_in_click ()
|
||||
AudioClipEditor::end_write ()
|
||||
{
|
||||
editor->set_spp (editor->spp () / 2.);
|
||||
}
|
||||
|
||||
void
|
||||
AudioClipEditorBox::zoom_out_click ()
|
||||
AudioClipEditor::show_count_in (std::string const &)
|
||||
{
|
||||
editor->set_spp (editor->spp () * 2.);
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
void
|
||||
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 ());
|
||||
|
||||
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 ());
|
||||
if (follow_playhead()) {
|
||||
reset_x_origin_to_follow_playhead ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioClipEditorBox::region_changed (const PBD::PropertyChange& what_changed)
|
||||
AudioClipEditor::unset (bool trigger_too)
|
||||
{
|
||||
drop_waves ();
|
||||
CueEditor::unset (trigger_too);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include <ytkmm/label.h>
|
||||
#include <ytkmm/table.h>
|
||||
|
||||
#include "pbd/history_owner.h"
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/session_handle.h"
|
||||
#include "ardour/triggerbox.h"
|
||||
|
|
@ -36,7 +38,6 @@
|
|||
|
||||
#include "widgets/ardour_button.h"
|
||||
|
||||
#include "canvas/canvas.h"
|
||||
#include "canvas/container.h"
|
||||
#include "canvas/line.h"
|
||||
#include "canvas/rectangle.h"
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
#include "canvas/scroll_group.h"
|
||||
|
||||
#include "audio_clock.h"
|
||||
#include "cue_editor.h"
|
||||
|
||||
namespace ARDOUR
|
||||
{
|
||||
|
|
@ -63,59 +65,76 @@ namespace ArdourWaveView
|
|||
class WaveView;
|
||||
}
|
||||
|
||||
class ClipEditorBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr
|
||||
class AudioClipEditor : public CueEditor
|
||||
{
|
||||
public:
|
||||
ClipEditorBox () {}
|
||||
~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 (std::string const &, bool with_transport = false);
|
||||
~AudioClipEditor ();
|
||||
|
||||
void set_region (std::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::TriggerReference);
|
||||
void on_size_allocate (Gtk::Allocation&);
|
||||
void canvas_allocate (Gtk::Allocation&);
|
||||
|
||||
double sample_to_pixel (ARDOUR::samplepos_t);
|
||||
samplepos_t pixel_to_sample (double);
|
||||
Gtk::Widget& contents ();
|
||||
|
||||
void set_spp (double);
|
||||
double spp () const
|
||||
{
|
||||
return _spp;
|
||||
}
|
||||
void set_trigger (ARDOUR::TriggerReference&);
|
||||
void set_region (std::shared_ptr<ARDOUR::Region> r);
|
||||
void region_changed (const PBD::PropertyChange& what_changed);
|
||||
|
||||
bool key_press (GdkEventKey*);
|
||||
|
||||
private:
|
||||
ArdourCanvas::Rectangle* frame;
|
||||
ArdourCanvas::ScrollGroup* waves_container;
|
||||
ArdourCanvas::Container* line_container;
|
||||
ArdourCanvas::Line* start_line;
|
||||
ArdourCanvas::Line* end_line;
|
||||
ArdourCanvas::Line* loop_line;
|
||||
ArdourCanvas::Rectangle* scroll_bar_trough;
|
||||
ArdourCanvas::Rectangle* scroll_bar_handle;
|
||||
ArdourCanvas::Container* ruler_container;
|
||||
ArdourCanvas::Ruler* ruler;
|
||||
/* EditingContext API. As of July 2025, we do not implement most of
|
||||
* these
|
||||
*/
|
||||
|
||||
bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
|
||||
bool button_press_handler_1 (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
|
||||
bool button_press_handler_2 (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
|
||||
bool button_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) { return true; }
|
||||
bool button_press_dispatch (GdkEventButton*) { return true; }
|
||||
bool button_release_dispatch (GdkEventButton*) { return true; }
|
||||
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
|
||||
{
|
||||
|
|
@ -135,9 +154,7 @@ private:
|
|||
std::vector<ArdourWaveView::WaveView*> waves;
|
||||
double non_wave_height;
|
||||
samplepos_t left_origin;
|
||||
double _spp;
|
||||
double scroll_fraction;
|
||||
std::shared_ptr<ARDOUR::AudioRegion> audio_region;
|
||||
|
||||
void scroll_left ();
|
||||
void scrol_right ();
|
||||
|
|
@ -150,7 +167,6 @@ private:
|
|||
|
||||
bool event_handler (GdkEvent* ev);
|
||||
bool line_event_handler (GdkEvent* ev, ArdourCanvas::Line*);
|
||||
bool scroll_event_handler (GdkEvent* ev);
|
||||
void drop_waves ();
|
||||
void set_wave_heights ();
|
||||
void set_spp_from_length (ARDOUR::samplecnt_t);
|
||||
|
|
@ -176,47 +192,21 @@ private:
|
|||
friend class LineDrag;
|
||||
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;
|
||||
|
||||
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 ();
|
||||
void zoom_out_click ();
|
||||
bool canvas_enter_leave (GdkEventCrossing* ev);
|
||||
|
||||
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
|
|
@ -20,15 +20,34 @@
|
|||
|
||||
#include "pbd/history_owner.h"
|
||||
|
||||
#include "canvas/canvas.h"
|
||||
|
||||
#include "widgets/ardour_button.h"
|
||||
#include "widgets/eventboxext.h"
|
||||
|
||||
#include "editing.h"
|
||||
#include "editing_context.h"
|
||||
#include "region_ui_settings.h"
|
||||
|
||||
namespace Gtk {
|
||||
class HScrollbar;
|
||||
}
|
||||
|
||||
class CueEditor : public EditingContext, public PBD::HistoryOwner
|
||||
{
|
||||
public:
|
||||
CueEditor (std::string const & name);
|
||||
CueEditor (std::string const & name, bool with_transport_controls);
|
||||
~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;
|
||||
StripableTimeAxisView* get_stripable_time_axis_by_id (const PBD::ID& id) 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);
|
||||
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();
|
||||
|
||||
|
|
@ -56,6 +76,8 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
|
|||
void undo_selection_op ();
|
||||
void redo_selection_op ();
|
||||
|
||||
RegionSelection region_selection();
|
||||
|
||||
PBD::HistoryOwner& history() { return *this; }
|
||||
void history_changed ();
|
||||
PBD::ScopedConnection history_connection;
|
||||
|
|
@ -85,6 +107,7 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
|
|||
Editing::MouseMode current_mouse_mode () const;
|
||||
/** cue editors are *always* used for internal editing */
|
||||
bool internal_editing() const { return true; }
|
||||
void mouse_mode_toggled (Editing::MouseMode);
|
||||
|
||||
Gdk::Cursor* get_canvas_cursor () 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>);
|
||||
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:
|
||||
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_redo (uint32_t n);
|
||||
|
||||
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
|
|
@ -147,7 +147,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
|
|||
void toggle_follow_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,
|
||||
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 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
|
||||
* are in canvas units (pixels, scroll offset included). The time
|
||||
* 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 next_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_draw_length_to (Editing::GridType);
|
||||
void set_draw_velocity_to (int);
|
||||
void set_draw_channel_to (int);
|
||||
void set_draw_length (Editing::GridType);
|
||||
void set_draw_velocity (int);
|
||||
void set_draw_channel (int);
|
||||
|
||||
Editing::GridType draw_length () 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> zoom_actions;
|
||||
|
||||
void load_shared_bindings ();
|
||||
virtual void load_shared_bindings ();
|
||||
|
||||
Editing::GridType pre_internal_grid_type;
|
||||
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;
|
||||
|
||||
Glib::RefPtr<Gtk::RadioAction> grid_type_action (Editing::GridType);
|
||||
Glib::RefPtr<Gtk::RadioAction> snap_mode_action (Editing::SnapMode);
|
||||
|
||||
Glib::RefPtr<Gtk::RadioAction> draw_length_action (Editing::GridType);
|
||||
Glib::RefPtr<Gtk::RadioAction> draw_velocity_action (int);
|
||||
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;
|
||||
std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > grid_actions;
|
||||
std::map<Editing::SnapMode, Glib::RefPtr<Gtk::RadioAction> > snap_mode_actions;
|
||||
std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > draw_length_actions;
|
||||
std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_velocity_actions;
|
||||
std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_channel_actions;
|
||||
|
||||
void draw_channel_chosen (int);
|
||||
void draw_velocity_chosen (int);
|
||||
|
|
@ -561,8 +556,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
|
|||
ArdourWidgets::ArdourDropdown draw_channel_selector;
|
||||
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 grid_type_chosen (Editing::GridType);
|
||||
|
||||
|
|
@ -600,7 +593,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
|
|||
EditorCursor* _playhead_cursor;
|
||||
EditorCursor* _snapped_cursor;
|
||||
|
||||
bool _follow_playhead;
|
||||
Glib::RefPtr<Gtk::ToggleAction> follow_playhead_action;
|
||||
|
||||
/* selection process */
|
||||
|
||||
|
|
@ -633,7 +626,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
|
|||
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;
|
||||
virtual double visible_canvas_width() const = 0;
|
||||
|
||||
enum BBTRulerScale {
|
||||
bbt_show_many,
|
||||
|
|
@ -819,8 +811,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
|
|||
/* 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 void 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::ToggleAction> toggle_reg_sens (Glib::RefPtr<Gtk::ActionGroup> 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -379,7 +379,6 @@ Editor::Editor ()
|
|||
, _last_cut_copy_source_track (nullptr)
|
||||
, _region_selection_change_updates_region_list (true)
|
||||
, _following_mixer_selection (false)
|
||||
, _show_touched_automation (false)
|
||||
, _control_point_toggled_on_press (false)
|
||||
, _stepping_axis_view (nullptr)
|
||||
, _main_menu_disabler (nullptr)
|
||||
|
|
@ -1151,7 +1150,7 @@ Editor::map_position_change (samplepos_t sample)
|
|||
return;
|
||||
}
|
||||
|
||||
if (_follow_playhead) {
|
||||
if (follow_playhead()) {
|
||||
center_screen (sample);
|
||||
}
|
||||
|
||||
|
|
@ -1229,7 +1228,7 @@ Editor::set_session (Session *t)
|
|||
if (!_pianoroll) {
|
||||
// XXX this should really not happen here
|
||||
_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);
|
||||
|
||||
|
|
@ -2068,6 +2067,8 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
|
|||
void
|
||||
Editor::show_rulers_for_grid ()
|
||||
{
|
||||
GridType gt (grid_type());
|
||||
|
||||
/* show appropriate rulers for this grid setting. */
|
||||
if (grid_musical()) {
|
||||
ruler_tempo_action->set_active(true);
|
||||
|
|
@ -2079,7 +2080,7 @@ Editor::show_rulers_for_grid ()
|
|||
ruler_minsec_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);
|
||||
|
||||
if (UIConfiguration::instance().get_rulers_follow_grid()) {
|
||||
|
|
@ -2089,7 +2090,7 @@ Editor::show_rulers_for_grid ()
|
|||
ruler_minsec_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);
|
||||
|
||||
if (UIConfiguration::instance().get_rulers_follow_grid()) {
|
||||
|
|
@ -2099,7 +2100,7 @@ Editor::show_rulers_for_grid ()
|
|||
ruler_timecode_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);
|
||||
|
||||
if (UIConfiguration::instance().get_rulers_follow_grid()) {
|
||||
|
|
@ -2334,7 +2335,7 @@ Editor::set_state (const XMLNode& node, int version)
|
|||
RefPtr<ToggleAction> tact;
|
||||
|
||||
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) {
|
||||
tact->set_active (yn);
|
||||
}
|
||||
|
|
@ -2374,19 +2375,14 @@ Editor::get_state () const
|
|||
node->set_property ("y-origin", vertical_adjustment.get_value ());
|
||||
|
||||
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 ("mouse-mode", mouse_mode);
|
||||
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"), tact->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_("show-editor-mixer"), show_editor_mixer_action->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());
|
||||
|
||||
node->set_property (X_("editor-list-page"), _the_notebook.get_current_page ());
|
||||
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-touched-automation"), _show_touched_automation);
|
||||
node->set_property (X_("show-touched-automation"), show_touched_automation());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
switch (_grid_type) {
|
||||
switch (grid_type()) {
|
||||
case GridTypeTimecode:
|
||||
ret = snap_to_timecode(presnap, direction, gpref);
|
||||
break;
|
||||
|
|
@ -3458,28 +3454,29 @@ Editor::set_stationary_playhead (bool yn)
|
|||
}
|
||||
|
||||
bool
|
||||
Editor::show_touched_automation () const
|
||||
Editor::show_touched_automation() const
|
||||
{
|
||||
if (!contents().get_mapped()) {
|
||||
return false;
|
||||
}
|
||||
return _show_touched_automation;
|
||||
|
||||
if (!show_touched_automation_action) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return show_touched_automation_action->get_active ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::toggle_show_touched_automation ()
|
||||
{
|
||||
RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-touched-automation"));
|
||||
set_show_touched_automation (tact->get_active());
|
||||
set_show_touched_automation (show_touched_automation_action->get_active());
|
||||
}
|
||||
|
||||
void
|
||||
Editor::set_show_touched_automation (bool yn)
|
||||
{
|
||||
if (_show_touched_automation == yn) {
|
||||
return;
|
||||
}
|
||||
_show_touched_automation = yn;
|
||||
show_touched_automation_action->set_active (yn);
|
||||
if (!yn) {
|
||||
RouteTimeAxisView::signal_ctrl_touched (true);
|
||||
}
|
||||
|
|
@ -4546,7 +4543,7 @@ Editor::located ()
|
|||
|
||||
if (_session) {
|
||||
_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 ();
|
||||
}
|
||||
update_section_box ();
|
||||
|
|
@ -5330,7 +5327,7 @@ Editor::super_rapid_screen_update ()
|
|||
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
|
||||
* handling a visual change (ie if
|
||||
* 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
|
||||
|
||||
/* 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 post (snap_to_grid (pre, direction, pref));
|
||||
check_best_snap (presnap, post, dist, best);
|
||||
|
|
|
|||
|
|
@ -2065,6 +2065,11 @@ private:
|
|||
Glib::RefPtr<Gtk::Action> selection_undo_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 ();
|
||||
|
||||
Editing::EditPoint _edit_point;
|
||||
|
|
@ -2200,7 +2205,6 @@ private:
|
|||
/* RTAV Automation display option */
|
||||
void toggle_show_touched_automation ();
|
||||
void set_show_touched_automation (bool);
|
||||
bool _show_touched_automation;
|
||||
|
||||
int time_fx (ARDOUR::RegionList&, Temporal::ratio_t ratio, bool pitching, bool fixed_end);
|
||||
void toggle_sound_midi_notes ();
|
||||
|
|
|
|||
|
|
@ -187,17 +187,17 @@ Editor::register_actions ()
|
|||
|
||||
/* 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));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
right_attachment_button.set_related_action (act);
|
||||
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 (show_editor_list_action);
|
||||
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));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
left_attachment_button.set_related_action (act);
|
||||
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 (show_editor_mixer_action);
|
||||
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));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
bottom_attachment_button.set_related_action (act);
|
||||
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 (show_editor_props_action);
|
||||
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-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, "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)));
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
|
|
|
|||
|
|
@ -3106,7 +3106,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
|
|||
|
||||
/* only snap to bars. */
|
||||
|
||||
editing_context.set_grid_to (GridTypeBar);
|
||||
editing_context.set_grid_type (GridTypeBar);
|
||||
editing_context.set_snap_mode (SnapMagnetic);
|
||||
}
|
||||
|
||||
|
|
@ -3143,7 +3143,7 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
_editor.commit_tempo_map_edit (map);
|
||||
|
|
@ -3167,7 +3167,7 @@ MeterMarkerDrag::aborted (bool moved)
|
|||
|
||||
if (moved) {
|
||||
/* 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);
|
||||
|
||||
// delete the dummy marker we used for visual representation while moving.
|
||||
|
|
|
|||
|
|
@ -150,14 +150,14 @@ Editor::mouse_mode_toggled (MouseMode m)
|
|||
this must toggle the actions and not call set_snap_*() directly,
|
||||
otherwise things get out of sync and the combo box stops working. */
|
||||
if (!UIConfiguration::instance().get_grid_follows_internal()) {
|
||||
grid_type_action(pre_internal_grid_type)->set_active(true);
|
||||
snap_mode_action(pre_internal_snap_mode)->set_active(true);
|
||||
grid_actions[pre_internal_grid_type]->set_active(true);
|
||||
snap_mode_actions[pre_internal_snap_mode]->set_active(true);
|
||||
} else if (!was_internal && internal_editing()) {
|
||||
grid_type_action(internal_grid_type)->set_active(true);
|
||||
snap_mode_action(internal_snap_mode)->set_active(true);
|
||||
grid_actions[internal_grid_type]->set_active(true);
|
||||
snap_mode_actions[internal_snap_mode]->set_active(true);
|
||||
} else if (was_internal && !internal_editing()) {
|
||||
grid_type_action(pre_internal_grid_type)->set_active(true);
|
||||
snap_mode_action(pre_internal_snap_mode)->set_active(true);
|
||||
grid_actions[pre_internal_grid_type]->set_active(true);
|
||||
snap_mode_actions[pre_internal_snap_mode]->set_active(true);
|
||||
}
|
||||
|
||||
instant_save ();
|
||||
|
|
@ -2108,7 +2108,7 @@ void
|
|||
Editor::mouse_brush_insert_region (RegionView* rv, timepos_t const & pos)
|
||||
{
|
||||
/* no brushing without a useful quantize setting */
|
||||
if (_grid_type == GridTypeNone)
|
||||
if (grid_type() == GridTypeNone)
|
||||
return;
|
||||
|
||||
/* don't brush a copy over the original */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
if (follow_playhead())
|
||||
if (location < _leftmost_sample)
|
||||
location = _leftmost_sample;
|
||||
|
||||
|
|
@ -7801,7 +7801,7 @@ Editor::playhead_forward_to_grid ()
|
|||
|
||||
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)));
|
||||
if (pos < timepos_t::max (pos.time_domain()).earlier (decipage)) {
|
||||
pos += timepos_t (decipage);
|
||||
|
|
@ -7830,7 +7830,7 @@ Editor::playhead_backward_to_grid ()
|
|||
|
||||
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));
|
||||
if (pos.samples() > decipage) {
|
||||
pos.shift_earlier (timepos_t (decipage));
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ Editor::compute_current_bbt_points (Temporal::TempoMapPoints& grid, samplepos_t
|
|||
const samplecnt_t sr (_session->sample_rate());
|
||||
|
||||
float divisor;
|
||||
switch (_grid_type) {
|
||||
switch (grid_type()) {
|
||||
case GridTypeBeatDiv3:
|
||||
case GridTypeBeatDiv6:
|
||||
case GridTypeBeatDiv12:
|
||||
|
|
|
|||
|
|
@ -202,7 +202,6 @@ MidiView::init (std::shared_ptr<MidiTrack> mt)
|
|||
void
|
||||
MidiView::note_mode_changed ()
|
||||
{
|
||||
std::cerr << "NM change\n";
|
||||
clear_events ();
|
||||
model_changed ();
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -58,12 +58,8 @@ class Pianoroll : public CueEditor
|
|||
Pianoroll (std::string const & name, bool with_transport_controls = false);
|
||||
~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 ();
|
||||
|
||||
double visible_canvas_width() const { return _visible_canvas_width; }
|
||||
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 {}
|
||||
|
|
@ -83,33 +79,13 @@ class Pianoroll : public CueEditor
|
|||
int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) const { return 1; }
|
||||
|
||||
void set_trigger (ARDOUR::TriggerReference&);
|
||||
void set_region (std::shared_ptr<ARDOUR::MidiRegion>);
|
||||
void set_track (std::shared_ptr<ARDOUR::MidiTrack>);
|
||||
|
||||
ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
|
||||
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
|
||||
void set_region (std::shared_ptr<ARDOUR::Region>);
|
||||
void set_track (std::shared_ptr<ARDOUR::Track>);
|
||||
|
||||
double max_extents_scale() const { return 1.2; }
|
||||
void set_samples_per_pixel (samplecnt_t);
|
||||
|
||||
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)());
|
||||
|
||||
|
|
@ -133,9 +109,6 @@ class Pianoroll : public CueEditor
|
|||
void set_trigger_length (Temporal::timecnt_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 paste (float times, bool from_context_menu);
|
||||
void keyboard_paste ();
|
||||
|
|
@ -143,7 +116,6 @@ class Pianoroll : public CueEditor
|
|||
|
||||
PianorollMidiView* midi_view() const { return view; }
|
||||
void set_session (ARDOUR::Session*);
|
||||
void session_going_away ();
|
||||
bool allow_trim_cursors () const;
|
||||
|
||||
void shift_midi (Temporal::timepos_t const &, bool model);
|
||||
|
|
@ -154,9 +126,6 @@ class Pianoroll : public CueEditor
|
|||
void set_show_source (bool);
|
||||
|
||||
protected:
|
||||
void load_bindings ();
|
||||
void register_actions ();
|
||||
|
||||
Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start,
|
||||
Temporal::RoundMode direction,
|
||||
ARDOUR::SnapPref gpref) const;
|
||||
|
|
@ -178,46 +147,14 @@ class Pianoroll : public CueEditor
|
|||
bool key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
|
||||
bool key_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
|
||||
|
||||
void mouse_mode_toggled (Editing::MouseMode);
|
||||
|
||||
void escape ();
|
||||
|
||||
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::Rectangle* tempo_bar;
|
||||
ArdourCanvas::Rectangle* meter_bar;
|
||||
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* bender_button;
|
||||
ArdourWidgets::ArdourButton* pressure_button;
|
||||
|
|
@ -236,15 +173,10 @@ class Pianoroll : public CueEditor
|
|||
|
||||
void build_canvas ();
|
||||
void canvas_allocate (Gtk::Allocation);
|
||||
void build_upper_toolbar ();
|
||||
void build_lower_toolbar ();
|
||||
|
||||
RegionSelection region_selection();
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
|
@ -260,16 +192,6 @@ class Pianoroll : public CueEditor
|
|||
|
||||
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;
|
||||
void maybe_update ();
|
||||
void trigger_prop_change (PBD::PropertyChange const &);
|
||||
|
|
@ -277,14 +199,9 @@ class Pianoroll : public CueEditor
|
|||
|
||||
void unset (bool trigger_too);
|
||||
|
||||
void visual_changer (const VisualChange&);
|
||||
void bindings_changed ();
|
||||
|
||||
void data_captured (samplecnt_t);
|
||||
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 automation_button_event (GdkEventButton*, Evoral::ParameterType type, int id);
|
||||
|
|
@ -299,37 +216,8 @@ class Pianoroll : public CueEditor
|
|||
|
||||
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 ();
|
||||
|
||||
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_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*);
|
||||
|
|
@ -337,30 +225,29 @@ class Pianoroll : public CueEditor
|
|||
bool ignore_channel_changes;
|
||||
void visible_channel_changed ();
|
||||
|
||||
bool with_transport_controls;
|
||||
void update_solo_display ();
|
||||
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_rulers() { update_tempo_based_rulers (); }
|
||||
|
||||
Gtk::Menu _region_context_menu;
|
||||
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 add_note_selection (uint8_t note);
|
||||
void extend_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 ();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "pbd/compose.h"
|
||||
|
||||
#include "ardour/midi_region.h"
|
||||
#include "ardour/midi_track.h"
|
||||
|
||||
#include "gtkmm2ext/doi.h"
|
||||
|
||||
|
|
@ -35,7 +36,7 @@ PianorollWindow::PianorollWindow (std::string const & name, Session& s)
|
|||
, region_editor (nullptr)
|
||||
{
|
||||
pianoroll->set_session (&s);
|
||||
pianoroll->viewport().set_size_request (600, 120);
|
||||
pianoroll->get_canvas_viewport()->set_size_request (600, 120);
|
||||
|
||||
add (hpacker);
|
||||
hpacker.show ();
|
||||
|
|
|
|||
|
|
@ -144,24 +144,21 @@ TriggerPage::TriggerPage ()
|
|||
_sidebar_pager2.set_index (3);
|
||||
|
||||
_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 */
|
||||
|
||||
table.set_homogeneous (false);
|
||||
table.set_spacings (8); //match to slot_properties_box::set_spacings
|
||||
table.set_border_width (8);
|
||||
hpacker.set_homogeneous (false);
|
||||
hpacker.set_spacing (8); //match to slot_properties_box::set_spacings
|
||||
hpacker.set_border_width (8);
|
||||
|
||||
int col = 0;
|
||||
table.attach (_properties_box, col, col + 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK | Gtk::FILL);
|
||||
++col;
|
||||
table.attach (_audio_trig_box, col, col + 1, 0, 1, Gtk::FILL, Gtk::SHRINK | Gtk::FILL);
|
||||
clip_editor_column = ++col;
|
||||
++col;
|
||||
|
||||
table.set_no_show_all ();
|
||||
|
||||
_parameter_box.pack_start (table);
|
||||
_parameter_box.show ();
|
||||
hpacker.pack_start (_properties_box, false, false);
|
||||
hpacker.pack_start (_midi_trig_box, false, false);
|
||||
hpacker.pack_start (_audio_trig_box, false, false);
|
||||
hpacker.set_no_show_all ();
|
||||
|
||||
_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)));
|
||||
|
|
@ -184,7 +181,7 @@ TriggerPage::TriggerPage ()
|
|||
/* Top-level Layout */
|
||||
content_app_bar.add (_application_bar);
|
||||
content_main.add (_strip_group_box);
|
||||
content_att_bottom.add (_parameter_box);
|
||||
content_att_bottom.add (hpacker);
|
||||
content_att_right.add (_sidebar_vbox);
|
||||
|
||||
/* Show all */
|
||||
|
|
@ -263,6 +260,7 @@ TriggerPage::get_state () const
|
|||
node->set_property (X_("triggerpage-sidebar-btn2"), _sidebar_pager2.index ());
|
||||
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
XMLNode* an = node.child (_audio_editor->editor_name().c_str());
|
||||
if (an) {
|
||||
_audio_editor->set_state (*an, version);
|
||||
}
|
||||
|
||||
bool yn = true;
|
||||
node.get_property ("show-trigger-list", yn);
|
||||
{
|
||||
|
|
@ -368,10 +371,10 @@ TriggerPage::set_session (Session* s)
|
|||
initial_track_display ();
|
||||
|
||||
_properties_box.set_session (s);
|
||||
|
||||
_audio_trig_box.set_session (s);
|
||||
|
||||
_midi_trig_box.set_session (s);
|
||||
_midi_editor->set_session (s);
|
||||
_audio_editor->set_session (s);
|
||||
|
||||
update_title ();
|
||||
start_updating ();
|
||||
|
|
@ -475,9 +478,7 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
|
|||
|
||||
/* hide everything */
|
||||
|
||||
_audio_trig_box.hide ();
|
||||
_midi_trig_box.hide ();
|
||||
_midi_editor->viewport().hide ();
|
||||
hide_all ();
|
||||
|
||||
Tabbable::showhide_att_bottom (false);
|
||||
|
||||
|
|
@ -485,10 +486,13 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
|
|||
TriggerReference ref (trigger->boxptr(), trigger->index());
|
||||
|
||||
if (box.data_type () == DataType::AUDIO) {
|
||||
if (trigger->the_region()) {
|
||||
_audio_trig_box.set_trigger (ref);
|
||||
_audio_trig_box.show ();
|
||||
}
|
||||
|
||||
_audio_trig_box.set_trigger (ref);
|
||||
_audio_trig_box.show ();
|
||||
|
||||
_audio_editor->set_trigger (ref);
|
||||
|
||||
hpacker.pack_start (_audio_editor->contents(), true, true);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -496,7 +500,7 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
|
|||
_midi_trig_box.show ();
|
||||
|
||||
_midi_editor->set_trigger (ref);
|
||||
_midi_editor->viewport().show ();
|
||||
hpacker.pack_start (_midi_editor->contents(), true, true);
|
||||
}
|
||||
|
||||
if (_show_bottom_pane) {
|
||||
|
|
@ -505,38 +509,46 @@ TriggerPage::trigger_arm_changed (Trigger const * trigger)
|
|||
}
|
||||
|
||||
void
|
||||
TriggerPage::selection_changed ()
|
||||
TriggerPage::hide_all ()
|
||||
{
|
||||
Selection& selection (Editor::instance ().get_selection ());
|
||||
|
||||
/* 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 (_audio_editor->contents().get_parent()) {
|
||||
_audio_editor->contents().get_parent()->remove (_audio_editor->contents());
|
||||
}
|
||||
|
||||
if (_midi_editor->contents().get_parent()) {
|
||||
_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);
|
||||
|
||||
if (selection.triggers.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TriggerSelection ts = selection.triggers;
|
||||
TriggerEntry* entry = *ts.begin ();
|
||||
TriggerReference ref = entry->trigger_reference ();
|
||||
TriggerPtr trigger = entry->trigger ();
|
||||
TriggerReference ref = selection.triggers.front()->trigger_reference ();
|
||||
std::shared_ptr<TriggerBox> box = ref.box();
|
||||
|
||||
if (box->data_type () == DataType::AUDIO) {
|
||||
|
||||
if (trigger->the_region()) {
|
||||
_audio_trig_box.set_trigger (ref);
|
||||
_audio_trig_box.show ();
|
||||
}
|
||||
_audio_trig_box.set_trigger (ref);
|
||||
_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 {
|
||||
|
||||
|
|
@ -544,12 +556,13 @@ TriggerPage::selection_changed ()
|
|||
_midi_trig_box.show ();
|
||||
|
||||
_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 ();
|
||||
}
|
||||
|
||||
table.show ();
|
||||
hpacker.show ();
|
||||
|
||||
if (_show_bottom_pane) {
|
||||
Tabbable::showhide_att_bottom (true);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "widgets/tabbable.h"
|
||||
|
||||
#include "application_bar.h"
|
||||
#include "audio_clip_editor.h"
|
||||
#include "audio_region_operations_box.h"
|
||||
#include "audio_trigger_properties_box.h"
|
||||
#include "axis_provider.h"
|
||||
|
|
@ -76,7 +77,7 @@ private:
|
|||
void remove_route (TriggerStrip*);
|
||||
|
||||
void clear_selected_slot ();
|
||||
|
||||
void hide_all ();
|
||||
void redisplay_track_list ();
|
||||
void pi_property_changed (PBD::PropertyChange const&);
|
||||
void stripable_property_changed (PBD::PropertyChange const&, std::weak_ptr<ARDOUR::Stripable>);
|
||||
|
|
@ -117,7 +118,6 @@ private:
|
|||
Gtk::EventBox _no_strips;
|
||||
Gtk::Alignment _cue_area_frame;
|
||||
Gtk::VBox _cue_area_box;
|
||||
Gtk::HBox _parameter_box;
|
||||
Gtk::VBox _sidebar_vbox;
|
||||
ArdourWidgets::MetaButton _sidebar_pager1;
|
||||
ArdourWidgets::MetaButton _sidebar_pager2;
|
||||
|
|
@ -126,7 +126,7 @@ private:
|
|||
TriggerSourceList _trigger_source_list;
|
||||
TriggerRegionList _trigger_region_list;
|
||||
TriggerRouteList _trigger_route_list;
|
||||
Gtk::Table table;
|
||||
Gtk::HBox hpacker;
|
||||
|
||||
CueBoxWidget _cue_box;
|
||||
FittedCanvasWidget _master_widget;
|
||||
|
|
@ -140,10 +140,10 @@ private:
|
|||
|
||||
#if REGION_PROPERTIES_BOX_TODO
|
||||
AudioRegionOperationsBox _audio_ops_box;
|
||||
AudioClipEditorBox _audio_trim_box;
|
||||
#endif
|
||||
|
||||
Pianoroll* _midi_editor;
|
||||
AudioClipEditor* _audio_editor;
|
||||
|
||||
RouteProcessorSelection _selection;
|
||||
std::list<TriggerStrip*> _strips;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue