mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
Compare commits
17 commits
d50e854b05
...
d6815d7e40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6815d7e40 | ||
|
|
094fbfa132 | ||
|
|
b0a2d678dc | ||
|
|
8ed6f685cf | ||
|
|
f62c4908e0 | ||
|
|
a23f3aec50 | ||
|
|
fc9f796257 | ||
|
|
0a213e71b3 | ||
|
|
2fa8c7cd42 | ||
|
|
fd3ddce80a | ||
|
|
e14acfc07d | ||
|
|
76f4813ee6 | ||
|
|
b023b97538 | ||
|
|
d830800ed9 | ||
|
|
8d1684e1f7 | ||
|
|
9abf6bc260 | ||
|
|
f63c049d87 |
14 changed files with 248 additions and 87 deletions
|
|
@ -92,7 +92,7 @@ CueEntry::event_handler (GdkEvent* ev)
|
|||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
// name_button->set_fill_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
name_button->set_fill_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
}
|
||||
break;
|
||||
|
|
@ -123,7 +123,7 @@ CueEntry::_size_allocate (ArdourCanvas::Rect const& alloc)
|
|||
|
||||
name_text->size_allocate (ArdourCanvas::Rect (0, 0, height, height));
|
||||
name_text->set_position (Duple (4. * scale, 2.5 * scale));
|
||||
name_text->clamp_width (width - height);
|
||||
name_text->clamp_width (height);
|
||||
|
||||
/* font scale may have changed. uiconfig 'embeds' the ui-scale in the font */
|
||||
name_text->set_font_description (UIConfiguration::instance ().get_SmallBoldMonospaceFont ());
|
||||
|
|
@ -157,7 +157,7 @@ CueEntry::render (ArdourCanvas::Rect const& area, Cairo::RefPtr<Cairo::Context>
|
|||
|
||||
render_children (area, context);
|
||||
|
||||
{ //Play triangle, needs to match TriggerEntry buttons exactly
|
||||
if (false) { //Play triangle, needs to match TriggerEntry buttons exactly
|
||||
context->set_line_width (1 * scale);
|
||||
|
||||
float margin = 4 * scale;
|
||||
|
|
@ -249,7 +249,14 @@ CueBoxUI::context_menu (uint64_t idx)
|
|||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::set_all_follow_action), FollowAction (FollowAction::Again), idx)));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::set_all_follow_action), FollowAction (FollowAction::ReverseTrigger), idx)));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::set_all_follow_action), FollowAction (FollowAction::ForwardTrigger), idx)));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::JumpTrigger)), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::set_all_follow_action), FollowAction (FollowAction::JumpTrigger), idx)));
|
||||
Menu* jump_menu = manage (new Menu);
|
||||
MenuList& jitems = jump_menu->items ();
|
||||
for (int i = 0; i < default_triggers_per_box; i++) {
|
||||
FollowAction jump_fa = (FollowAction::JumpTrigger);
|
||||
jump_fa.targets.set(i);
|
||||
jitems.push_back (MenuElem (string_compose ("%1", (char)('A' + i)), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::set_all_follow_action), jump_fa, idx)));
|
||||
}
|
||||
fitems.push_back (MenuElem (_("Jump..."), *jump_menu));
|
||||
|
||||
Menu* launch_menu = manage (new Menu);
|
||||
MenuList& litems = launch_menu->items ();
|
||||
|
|
|
|||
|
|
@ -142,7 +142,15 @@ SlotPropertyTable::SlotPropertyTable ()
|
|||
_follow_left.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::Again), 0)));
|
||||
_follow_left.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::ReverseTrigger), 0)));
|
||||
_follow_left.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::ForwardTrigger), 0)));
|
||||
_follow_left.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::JumpTrigger)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::JumpTrigger), 0)));
|
||||
Menu* jump_menu = manage (new Menu);
|
||||
MenuList& jitems = jump_menu->items ();
|
||||
for (int i = 0; i < default_triggers_per_box; i++) {
|
||||
FollowAction jump_fa = (FollowAction::JumpTrigger);
|
||||
jump_fa.targets.set(i);
|
||||
jitems.push_back (MenuElem (string_compose ("%1", (char)('A' + i)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), jump_fa, 0)));
|
||||
}
|
||||
//jitems.push_back (MenuElem ("Combo...", sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::JumpTrigger), 0)));
|
||||
_follow_left.AddMenuElem (MenuElem (_("Jump..."), *jump_menu));
|
||||
_follow_left.set_sizing_text (longest_follow);
|
||||
|
||||
_follow_right.set_name("FollowAction");
|
||||
|
|
@ -151,7 +159,14 @@ SlotPropertyTable::SlotPropertyTable ()
|
|||
_follow_right.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::Again), 1)));
|
||||
_follow_right.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::ReverseTrigger), 1)));
|
||||
_follow_right.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::ForwardTrigger), 1)));
|
||||
_follow_right.AddMenuElem (MenuElem (follow_action_to_string(FollowAction (FollowAction::JumpTrigger)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), FollowAction (FollowAction::JumpTrigger), 1)));
|
||||
Menu* jump_menu_1 = manage (new Menu);
|
||||
MenuList& jitems_1 = jump_menu_1->items ();
|
||||
for (int i = 0; i < default_triggers_per_box; i++) {
|
||||
FollowAction jump_fa = (FollowAction::JumpTrigger);
|
||||
jump_fa.targets.set(i);
|
||||
jitems_1.push_back (MenuElem (string_compose ("%1", (char)('A' + i)), sigc::bind (sigc::mem_fun (*this, &SlotPropertyTable::set_follow_action), jump_fa, 1)));
|
||||
}
|
||||
_follow_right.AddMenuElem (MenuElem (_("Jump..."), *jump_menu_1));
|
||||
_follow_right.set_sizing_text (longest_follow);
|
||||
|
||||
_launch_style_button.set_name("FollowAction");
|
||||
|
|
|
|||
|
|
@ -346,7 +346,6 @@ TriggerMaster::context_menu ()
|
|||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind (sigc::mem_fun (*this, &TriggerMaster::set_all_follow_action), FollowAction (FollowAction::Again))));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind (sigc::mem_fun (*this, &TriggerMaster::set_all_follow_action), FollowAction (FollowAction::ForwardTrigger))));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind (sigc::mem_fun (*this, &TriggerMaster::set_all_follow_action), FollowAction (FollowAction::ReverseTrigger))));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::JumpTrigger)), sigc::bind (sigc::mem_fun (*this, &TriggerMaster::set_all_follow_action), FollowAction (FollowAction::JumpTrigger))));
|
||||
|
||||
Menu* launch_menu = manage (new Menu);
|
||||
MenuList& litems = launch_menu->items ();
|
||||
|
|
@ -565,7 +564,7 @@ CueMaster::CueMaster (Item* parent)
|
|||
Event.connect (sigc::mem_fun (*this, &CueMaster::event_handler));
|
||||
|
||||
stop_shape = new ArdourCanvas::Polygon (this);
|
||||
stop_shape->set_outline (true);
|
||||
stop_shape->set_outline (false);
|
||||
stop_shape->set_fill (true);
|
||||
stop_shape->name = X_("stopbutton");
|
||||
stop_shape->set_ignore_events (true);
|
||||
|
|
@ -640,7 +639,6 @@ CueMaster::event_handler (GdkEvent* ev)
|
|||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
stop_shape->set_outline_color (UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
stop_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
set_fill_color (HSV (fill_color ()).lighter (0.25).color ());
|
||||
}
|
||||
|
|
@ -668,7 +666,7 @@ CueMaster::_size_allocate (ArdourCanvas::Rect const& alloc)
|
|||
Rectangle::_size_allocate (alloc);
|
||||
|
||||
const double scale = UIConfiguration::instance ().get_ui_scale ();
|
||||
_poly_margin = 2. * scale;
|
||||
_poly_margin = 2 * scale;
|
||||
|
||||
const Distance width = _rect.width ();
|
||||
const Distance height = _rect.height ();
|
||||
|
|
@ -690,8 +688,7 @@ void
|
|||
CueMaster::set_default_colors ()
|
||||
{
|
||||
set_fill_color (HSV (UIConfiguration::instance ().color ("theme:bg")).darker (0.5).color ());
|
||||
stop_shape->set_outline_color (UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
stop_shape->set_fill_color (fill_color());
|
||||
stop_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:midground"));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -723,8 +720,6 @@ CueMaster::context_menu ()
|
|||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind (sigc::mem_fun (*this, &CueMaster::set_all_follow_action), FollowAction (FollowAction::Again))));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind (sigc::mem_fun (*this, &CueMaster::set_all_follow_action), FollowAction (FollowAction::ForwardTrigger))));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind (sigc::mem_fun (*this, &CueMaster::set_all_follow_action), FollowAction (FollowAction::ReverseTrigger))));
|
||||
fitems.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::JumpTrigger)), sigc::bind (sigc::mem_fun (*this, &CueMaster::set_all_follow_action), FollowAction (FollowAction::JumpTrigger))));
|
||||
|
||||
|
||||
Menu* launch_menu = manage (new Menu);
|
||||
MenuList& litems = launch_menu->items ();
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ using namespace std;
|
|||
TriggerPage::TriggerPage ()
|
||||
: Tabbable (_content, _("Trigger Drom"), X_("trigger"))
|
||||
, _cue_area_frame (0.5, 0, 1.0, 0)
|
||||
, _cue_box (32, 16 * default_triggers_per_box)
|
||||
, _master_widget (32, 16)
|
||||
, _cue_box (16, 16 * default_triggers_per_box)
|
||||
, _master_widget (16, 16)
|
||||
, _master (_master_widget.root ())
|
||||
{
|
||||
load_bindings ();
|
||||
|
|
@ -84,6 +84,7 @@ TriggerPage::TriggerPage ()
|
|||
_cue_area_box.pack_start (*spacer, Gtk::PACK_SHRINK);
|
||||
_cue_area_box.pack_start (_cue_box, Gtk::PACK_SHRINK);
|
||||
_cue_area_box.pack_start (_master_widget, Gtk::PACK_SHRINK);
|
||||
_cue_area_box.pack_start (_cue_rec_enable, Gtk::PACK_SHRINK);
|
||||
|
||||
/* left-side frame, same layout as TriggerStrip.
|
||||
* use Alignment instead of Frame with SHADOW_IN (2px)
|
||||
|
|
@ -286,6 +287,10 @@ TriggerPage::set_session (Session* s)
|
|||
|
||||
Editor::instance ().get_selection ().TriggersChanged.connect (sigc::mem_fun (*this, &TriggerPage::selection_changed));
|
||||
|
||||
TriggerBox::CueRecordingChanged.connect (_session_connections, invalidator (*this), boost::bind (&TriggerPage::rec_state_changed, this), gui_context ());
|
||||
rec_state_changed();
|
||||
_cue_rec_enable.signal_clicked.connect(sigc::mem_fun(*this, &TriggerPage::rec_state_clicked));
|
||||
|
||||
initial_track_display ();
|
||||
|
||||
_slot_prop_box.set_session (s);
|
||||
|
|
@ -481,6 +486,18 @@ TriggerPage::redisplay_track_list ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriggerPage::rec_state_clicked ()
|
||||
{
|
||||
TriggerBox::set_cue_recording(!TriggerBox::cue_recording());
|
||||
}
|
||||
|
||||
void
|
||||
TriggerPage::rec_state_changed ()
|
||||
{
|
||||
_cue_rec_enable.set_active_state( TriggerBox::cue_recording() ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerPage::parameter_changed (string const& p)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ private:
|
|||
void pi_property_changed (PBD::PropertyChange const&);
|
||||
void stripable_property_changed (PBD::PropertyChange const&, boost::weak_ptr<ARDOUR::Stripable>);
|
||||
|
||||
void rec_state_changed ();
|
||||
void rec_state_clicked ();
|
||||
|
||||
void add_sidebar_page (std::string const&, Gtk::Widget&);
|
||||
|
||||
bool no_strip_button_event (GdkEventButton*);
|
||||
|
|
@ -111,6 +114,7 @@ private:
|
|||
CueBoxWidget _cue_box;
|
||||
FittedCanvasWidget _master_widget;
|
||||
CueMaster _master;
|
||||
ArdourWidgets::ArdourButton _cue_rec_enable;
|
||||
|
||||
SlotPropertiesBox _slot_prop_box;
|
||||
|
||||
|
|
|
|||
|
|
@ -588,40 +588,18 @@ TriggerUI::follow_context_menu ()
|
|||
_ignore_menu_action = true;
|
||||
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::None)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::None))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::None) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::Stop)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::Stop))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::Stop) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::Again))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::Again) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::ForwardTrigger))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::ForwardTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::ReverseTrigger))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::ReverseTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
|
||||
#if 0
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::FirstTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::FirstTrigger))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::FirstTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::LastTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::LastTrigger))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::LastTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
#endif
|
||||
fitems.push_back (RadioMenuElem (fagroup, TriggerUI::follow_action_to_string(FollowAction (FollowAction::JumpTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::JumpTrigger))));
|
||||
if (trigger ()->follow_action (0) == FollowAction::JumpTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
Menu* jump_menu = manage (new Menu);
|
||||
MenuList& jitems = jump_menu->items ();
|
||||
for (int i = 0; i < default_triggers_per_box; i++) {
|
||||
FollowAction jump_fa = (FollowAction::JumpTrigger);
|
||||
jump_fa.targets.set(i);
|
||||
jitems.push_back (MenuElem (string_compose ("%1", (char)('A' + i)), sigc::bind (sigc::mem_fun (*this, &TriggerUI::set_follow_action), jump_fa)));
|
||||
}
|
||||
fitems.push_back (MenuElem (_("Jump..."), *jump_menu));
|
||||
|
||||
_ignore_menu_action = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -212,41 +212,47 @@ TriggerEntry::draw_follow_icon (Cairo::RefPtr<Cairo::Context> context, FollowAct
|
|||
break;
|
||||
case FollowAction::ForwardTrigger:
|
||||
context->move_to (size / 2, 3 * scale);
|
||||
context->line_to (size / 2, size - 3 * scale);
|
||||
context->line_to (size / 2, size - 5 * scale);
|
||||
context->stroke ();
|
||||
|
||||
context->arc (size / 2, 7 * scale, 2 * scale, 0, 2 * M_PI);
|
||||
set_source_rgba (context, fg_color);
|
||||
context->fill ();
|
||||
|
||||
context->arc (size / 2, 7 * scale, 1 * scale, 0, 2 * M_PI);
|
||||
set_source_rgba (context, fill_color ());
|
||||
context->fill ();
|
||||
|
||||
set_source_rgba (context, fg_color);
|
||||
context->arc (size / 2, size - 3 * scale, 2 * scale, 0, 2 * M_PI); // arrow head
|
||||
context->arc (size / 2, size - 5 * scale, 2 * scale, 0, 2 * M_PI); // arrow head
|
||||
context->fill ();
|
||||
break;
|
||||
case FollowAction::ReverseTrigger:
|
||||
context->arc (size / 2, 3 * scale, 2 * scale, 0, 2 * M_PI); // arrow head
|
||||
set_source_rgba (context, fg_color);
|
||||
context->fill ();
|
||||
|
||||
context->move_to (size / 2, 3 * scale);
|
||||
context->move_to (size / 2, 5 * scale);
|
||||
context->line_to (size / 2, size - 3 * scale);
|
||||
context->stroke ();
|
||||
|
||||
context->arc (size / 2, size - 7 * scale, 2 * scale, 0, 2 * M_PI);
|
||||
set_source_rgba (context, fg_color);
|
||||
context->arc (size / 2, 5 * scale, 2 * scale, 0, 2 * M_PI); // arrow head
|
||||
context->fill ();
|
||||
|
||||
context->arc (size / 2, size - 7 * scale, 1 * scale, 0, 2 * M_PI);
|
||||
set_source_rgba (context, bg_color);
|
||||
context->fill ();
|
||||
|
||||
break;
|
||||
/* ben: new shape here ? */
|
||||
case FollowAction::JumpTrigger: {
|
||||
if ( icon.targets.count() == 1 ) { //jump to a specific row
|
||||
int cue_idx = -1;
|
||||
for (int i = 0; i < default_triggers_per_box; i++) {
|
||||
if (icon.targets.test(i)) {
|
||||
cue_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create (context);
|
||||
layout->set_font_description (UIConfiguration::instance ().get_SmallMonospaceFont ());
|
||||
layout->set_text (string_compose ("%1", (char)('A' + cue_idx))); //XXX translate?
|
||||
int tw, th;
|
||||
layout->get_pixel_size (tw, th);
|
||||
context->move_to (size / 2, size / 2);
|
||||
context->rel_move_to (-tw / 2, -th / 2);
|
||||
layout->show_in_cairo_context (context);
|
||||
} else if (false) { // 'ANY' jump
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Cairo::Matrix m = context->get_matrix ();
|
||||
context->translate (size / 2, size / 2);
|
||||
context->rotate (i * M_PI / 3);
|
||||
context->move_to (0, 0);
|
||||
context->line_to (0, (size / 2) - 4 * scale);
|
||||
context->stroke ();
|
||||
context->set_matrix (m);
|
||||
}
|
||||
context->set_identity_matrix ();
|
||||
} else { // 'OTHER' jump
|
||||
context->set_line_width (1.5 * scale);
|
||||
set_source_rgba (context, HSV (UIConfiguration::instance ().color ("neutral:midground")).lighter (0.25).color ()); // needs to be brighter to maintain balance
|
||||
for (int i = 0; i < 6; i++) {
|
||||
|
|
@ -259,6 +265,7 @@ TriggerEntry::draw_follow_icon (Cairo::RefPtr<Cairo::Context> context, FollowAct
|
|||
context->set_matrix (m);
|
||||
}
|
||||
context->set_identity_matrix ();
|
||||
}
|
||||
} break;
|
||||
case FollowAction::None:
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ public:
|
|||
bool clear_xrun_markers ();
|
||||
bool clear_ranges ();
|
||||
|
||||
void clear_cue_markers (samplepos_t start, samplepos_t end);
|
||||
|
||||
void ripple (timepos_t const & at, timecnt_t const & distance, bool include_locked, bool notify);
|
||||
|
||||
XMLNode& get_state (void);
|
||||
|
|
|
|||
|
|
@ -1876,6 +1876,7 @@ private:
|
|||
void set_track_loop (bool);
|
||||
bool select_playhead_priority_target (samplepos_t&);
|
||||
void follow_playhead_priority ();
|
||||
void flush_cue_recording ();
|
||||
|
||||
/* These are synchronous and so can only be called from within the process
|
||||
* cycle
|
||||
|
|
|
|||
|
|
@ -522,6 +522,15 @@ class LIBARDOUR_API TriggerBoxThread
|
|||
void delete_trigger (Trigger*);
|
||||
};
|
||||
|
||||
struct CueRecord {
|
||||
int32_t cue_number;
|
||||
samplepos_t when;
|
||||
|
||||
CueRecord (int32_t cn, samplepos_t t): cue_number (cn), when (t) {}
|
||||
CueRecord () : cue_number (0), when (0) {}
|
||||
};
|
||||
|
||||
typedef PBD::RingBuffer<CueRecord> CueRecords;
|
||||
|
||||
class LIBARDOUR_API TriggerBox : public Processor
|
||||
{
|
||||
|
|
@ -529,6 +538,11 @@ class LIBARDOUR_API TriggerBox : public Processor
|
|||
TriggerBox (Session&, DataType dt);
|
||||
~TriggerBox ();
|
||||
|
||||
static CueRecords cue_records;
|
||||
static bool cue_recording () { return _cue_recording; }
|
||||
static void set_cue_recording (bool yn);
|
||||
static PBD::Signal0<void> CueRecordingChanged;
|
||||
|
||||
void run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool result_required);
|
||||
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
|
||||
bool configure_io (ChanCount in, ChanCount out);
|
||||
|
|
@ -698,6 +712,7 @@ class LIBARDOUR_API TriggerBox : public Processor
|
|||
static void init_pool();
|
||||
|
||||
static std::atomic<int> active_trigger_boxes;
|
||||
static std::atomic<bool> _cue_recording;
|
||||
};
|
||||
|
||||
class TriggerReference
|
||||
|
|
|
|||
|
|
@ -980,6 +980,18 @@ Locations::add (Location *loc, bool make_current)
|
|||
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||
|
||||
/* Do not allow multiple cue markers in the same location */
|
||||
|
||||
if (loc->is_cue_marker()) {
|
||||
for (LocationList::iterator i = locations.begin(); i != locations.end(); ++i) {
|
||||
if ((*i)->is_cue_marker() && (*i)->start() == loc->start()) {
|
||||
locations.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locations.push_back (loc);
|
||||
|
||||
if (make_current) {
|
||||
|
|
@ -1610,3 +1622,54 @@ Locations::ripple (timepos_t const & at, timecnt_t const & distance, bool includ
|
|||
changed(); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Locations::clear_cue_markers (samplepos_t start, samplepos_t end)
|
||||
{
|
||||
TempoMap::SharedPtr tmap (TempoMap::use());
|
||||
Temporal::Beats sb;
|
||||
Temporal::Beats eb;
|
||||
bool have_beats = false;
|
||||
vector<Location*> r;
|
||||
|
||||
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||
|
||||
for (LocationList::iterator i = locations.begin(); i != locations.end(); ) {
|
||||
|
||||
if ((*i)->is_cue_marker()) {
|
||||
Location* l (*i);
|
||||
|
||||
if (l->start().time_domain() == AudioTime) {
|
||||
samplepos_t when = l->start().samples();
|
||||
if (when >= start && when < end) {
|
||||
i = locations.erase (i);
|
||||
r.push_back (l);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (!have_beats) {
|
||||
sb = tmap->quarters_at (timepos_t (start));
|
||||
eb = tmap->quarters_at (timepos_t (end));
|
||||
have_beats = true;
|
||||
}
|
||||
|
||||
Temporal::Beats when = l->start().beats();
|
||||
if (when >= sb && when < eb) {
|
||||
r.push_back (l);
|
||||
i = locations.erase (i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
} /* end lock scope */
|
||||
|
||||
for (auto & l : r) {
|
||||
removed (l); /* EMIT SIGNAL */
|
||||
delete l;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1653,7 +1653,7 @@ Session::first_cue_within (samplepos_t s, samplepos_t e)
|
|||
}
|
||||
|
||||
void
|
||||
Session::cue_marker_change (Location* loc)
|
||||
Session::cue_marker_change (Location* /* ignored */)
|
||||
{
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SyncCues, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
|
||||
queue_event (ev);
|
||||
|
|
@ -1671,6 +1671,12 @@ Session::maybe_find_pending_cue ()
|
|||
int32_t ac = _pending_cue.exchange (-1);
|
||||
if (ac >= 0) {
|
||||
_active_cue.store (ac);
|
||||
|
||||
if (TriggerBox::cue_recording()) {
|
||||
CueRecord cr (ac, _transport_sample);
|
||||
TriggerBox::cue_records.write (&cr, 1);
|
||||
/* failure is acceptable, but unlikely */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1355,6 +1355,11 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
auditioner->cancel_audition ();
|
||||
}
|
||||
|
||||
/* This must be called while _transport_sample still reflects where we stopped
|
||||
*/
|
||||
|
||||
flush_cue_recording ();
|
||||
|
||||
if (did_record) {
|
||||
begin_reversible_command (Operations::capture);
|
||||
_have_captured = true;
|
||||
|
|
@ -2079,3 +2084,35 @@ Session::actual_speed() const
|
|||
if (_transport_fsm->transport_speed() < 0) return - _engine_speed;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Session::flush_cue_recording ()
|
||||
{
|
||||
if (!TriggerBox::cue_records.read_space()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CueRecord cr;
|
||||
TempoMap::SharedPtr tmap (TempoMap::use());
|
||||
|
||||
_locations->clear_cue_markers (_last_roll_location, _transport_sample);
|
||||
|
||||
while (TriggerBox::cue_records.read (&cr, 1) == 1) {
|
||||
BBT_Time bbt = tmap->bbt_at (timepos_t (cr.when));
|
||||
bbt = bbt.round_up_to_bar ();
|
||||
|
||||
timepos_t when;
|
||||
|
||||
if (tmap->time_domain() == Temporal::AudioTime) {
|
||||
when = timepos_t (tmap->sample_at (bbt));
|
||||
} else {
|
||||
when = timepos_t (tmap->quarters_at (bbt));
|
||||
}
|
||||
|
||||
Location* l = new Location (*this, when, when, std::string(), Location::Flags (Location::IsMark|Location::IsCueMarker), cr.cue_number);
|
||||
_locations->add (l);
|
||||
}
|
||||
|
||||
/* scheduled sync of cue markers in RT thread */
|
||||
cue_marker_change (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2183,6 +2183,9 @@ TriggerBox::TriggerMidiMapMode TriggerBox::_midi_map_mode (TriggerBox::Sequentia
|
|||
int TriggerBox::_first_midi_note = 60;
|
||||
std::atomic<int> TriggerBox::active_trigger_boxes (0);
|
||||
TriggerBoxThread* TriggerBox::worker = 0;
|
||||
CueRecords TriggerBox::cue_records (256);
|
||||
std::atomic<bool> TriggerBox::_cue_recording (true);
|
||||
PBD::Signal0<void> TriggerBox::CueRecordingChanged;
|
||||
|
||||
void
|
||||
TriggerBox::init ()
|
||||
|
|
@ -2224,6 +2227,15 @@ TriggerBox::TriggerBox (Session& s, DataType dt)
|
|||
Config->ParameterChanged.connect_same_thread (*this, boost::bind (&TriggerBox::parameter_changed, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBox::set_cue_recording (bool yn)
|
||||
{
|
||||
if (yn != _cue_recording) {
|
||||
_cue_recording = yn;
|
||||
CueRecordingChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBox::set_region (uint32_t slot, boost::shared_ptr<Region> region)
|
||||
{
|
||||
|
|
@ -2712,11 +2724,13 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||
_sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
|
||||
}
|
||||
|
||||
if (!_cue_recording) {
|
||||
int32_t cue_bang = _session.first_cue_within (start_sample, end_sample);
|
||||
if (cue_bang >= 0) {
|
||||
std::cerr << " CUE BANG " << cue_bang << std::endl;
|
||||
_active_scene = cue_bang;
|
||||
}
|
||||
}
|
||||
|
||||
/* STEP SIX: if at this point there is an active cue, make it trigger
|
||||
* our corresponding slot
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue