diff --git a/gtk2_ardour/trigger_jump_dialog.cc b/gtk2_ardour/trigger_jump_dialog.cc new file mode 100644 index 0000000000..21511ef5ba --- /dev/null +++ b/gtk2_ardour/trigger_jump_dialog.cc @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2022 Ben Loftis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "gtkmm2ext/utils.h" + +#include "widgets/ardour_button.h" + +#include "ardour/triggerbox.h" + +#include "trigger_jump_dialog.h" + +#include "pbd/i18n.h" + +using namespace std; +using namespace Gtk; +using namespace Gtkmm2ext; +using namespace ARDOUR; +using namespace PBD; +using namespace ArdourWidgets; + +/** + * EditNoteDialog constructor. + * + * @param n Notes to edit. + */ + +TriggerJumpDialog::TriggerJumpDialog () + : ArdourDialog ("") +{ +// add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); +// add_button (Gtk::Stock::APPLY, Gtk::RESPONSE_ACCEPT); + set_default_response (Gtk::RESPONSE_ACCEPT); +} + +void +TriggerJumpDialog::on_trigger_set () +{ + _table.set_border_width (4); + _table.set_spacings (4); + + int r = 0; + + for (int i = 0; i < default_triggers_per_box; i++) { //someday this might change dynamically + ArdourButton* b = manage (new ArdourButton (ArdourButton::led_default_elements)); + + b->signal_clicked.connect(sigc::bind(sigc::mem_fun(*this, &TriggerJumpDialog::button_clicked), i)); + + Gtk::Label* l = manage(new Gtk::Label(string_compose ("%1:", (char)('A' + i)), ALIGN_RIGHT)); + _table.attach (*l, 0, 1, r,r+1, Gtk::FILL, Gtk::SHRINK); + _table.attach (*b, 1, 2, r,r+1, Gtk::FILL, Gtk::SHRINK); + + _buttonlist.push_back(b); + + ++r; + } + + get_vbox()->pack_start (_table); + + PropertyChange pc; + pc.add (Properties::name); + pc.add (Properties::follow_action0); + on_trigger_changed(pc); +} + +void +TriggerJumpDialog::button_clicked (int b) +{ + FollowAction jump_fa = trigger()->follow_action0(); + + jump_fa.type = FollowAction::JumpTrigger; //should already be the case if we are in this dialog, but let's take no chances + jump_fa.targets.flip(b); + + trigger()->set_follow_action0(jump_fa); +} + +void +TriggerJumpDialog::on_trigger_changed (PropertyChange const& what) +{ + set_title(string_compose(_("Jump Target for: %1"), trigger()->name())); + + TriggerBox &box = trigger()->box(); + + FollowAction jump_fa = trigger()->follow_action0(); + + //update button display state + ButtonList::const_iterator b = _buttonlist.begin (); + for (int i = 0; i < default_triggers_per_box; i++) { + + if (b==_buttonlist.end()) { + break; + } + + (*b)->set_text(box.trigger(i)->name()); + (*b)->set_active_state(jump_fa.targets.test(i) ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); + + ++b; + } + +} + +void +TriggerJumpDialog::done (int r) +{ + if (r != RESPONSE_ACCEPT) { + return; + } +} diff --git a/gtk2_ardour/trigger_jump_dialog.h b/gtk2_ardour/trigger_jump_dialog.h new file mode 100644 index 0000000000..5e30b2ed66 --- /dev/null +++ b/gtk2_ardour/trigger_jump_dialog.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 Ben Loftis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "trigger_ui.h" +#include "ardour_dialog.h" + +#include "pbd/properties.h" + +#include + +namespace ArdourWidgets { + class ArdourButton; +} + +class TriggerJumpDialog : public ArdourDialog, public TriggerUI +{ +public: + TriggerJumpDialog (); + + void done (int); + + void on_trigger_set (); + void button_clicked (int b); + void on_trigger_changed (PBD::PropertyChange const& what); + +private: + Gtk::Table _table; + + typedef std::list ButtonList; + ButtonList _buttonlist; +}; diff --git a/gtk2_ardour/trigger_ui.cc b/gtk2_ardour/trigger_ui.cc index 5c3e277eeb..154de4b469 100644 --- a/gtk2_ardour/trigger_ui.cc +++ b/gtk2_ardour/trigger_ui.cc @@ -44,9 +44,11 @@ #include "keyboard.h" #include "public_editor.h" #include "region_view.h" -#include "trigger_ui.h" +#include "trigger_jump_dialog.h" #include "ui_config.h" +#include "trigger_ui.h" + #include "pbd/i18n.h" using namespace ARDOUR; @@ -580,41 +582,23 @@ TriggerUI::follow_context_menu () MenuList& items = _follow_context_menu->items (); _follow_context_menu->set_name ("ArdourContextMenu"); - RadioMenuItem::Group fagroup; - _ignore_menu_action = true; - items.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_action0 ().type == FollowAction::None) { - dynamic_cast (&items.back ())->set_active (true); - } - items.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_action0 ().type == FollowAction::Stop) { - dynamic_cast (&items.back ())->set_active (true); - } - items.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_action0 ().type == FollowAction::Again) { - dynamic_cast (&items.back ())->set_active (true); - } - items.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_action0 ().type == FollowAction::ForwardTrigger) { - dynamic_cast (&items.back ())->set_active (true); - } - items.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_action0 ().type == FollowAction::ReverseTrigger) { - dynamic_cast (&items.back ())->set_active (true); - } + items.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::None)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::None)))); + items.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::Stop)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::Stop)))); + items.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::Again)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::Again)))); + items.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ForwardTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::ForwardTrigger)))); + items.push_back (MenuElem (TriggerUI::follow_action_to_string(FollowAction (FollowAction::ReverseTrigger)), sigc::bind(sigc::mem_fun (*this, &TriggerUI::set_follow_action), FollowAction (FollowAction::ReverseTrigger)))); 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 (RadioMenuElem (fagroup, string_compose ("%1", (char)('A' + i)), sigc::bind (sigc::mem_fun (*this, &TriggerUI::set_follow_action), jump_fa))); - if (trigger ()->follow_action0 () == jump_fa) { - dynamic_cast (&jitems.back ())->set_active (true); - } + jitems.push_back (MenuElem (string_compose ("%1", (char)('A' + i)), sigc::bind (sigc::mem_fun (*this, &TriggerUI::set_follow_action), jump_fa))); } + jitems.push_back (MenuElem (_("Multi"), sigc::mem_fun (*this, &TriggerUI::edit_jump))); + items.push_back (MenuElem (_("Jump..."), *jump_menu)); _ignore_menu_action = false; @@ -622,6 +606,27 @@ TriggerUI::follow_context_menu () _follow_context_menu->popup (1, gtk_get_current_event_time ()); } +void +TriggerUI::edit_jump () +{ + if (_ignore_menu_action) { + return; + } + + TriggerJumpDialog* d = new TriggerJumpDialog (); + d->set_trigger(tref); + d->show_all (); + + d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &TriggerUI::edit_jump_done), d)); +} + +void +TriggerUI::edit_jump_done (int r, TriggerJumpDialog* d) +{ + d->done (r); + delete d; +} + void TriggerUI::toggle_trigger_isolated () @@ -830,4 +835,6 @@ TriggerUI::set_trigger (ARDOUR::TriggerReference tr) tref.box->PropertyChanged.connect (trigger_connections, MISSING_INVALIDATOR, boost::bind (&TriggerUI::trigger_changed, this, _1), gui_context ()); tref.box->TriggerSwapped.connect (trigger_swap_connection, MISSING_INVALIDATOR, boost::bind (&TriggerUI::trigger_swap, this, _1), gui_context ()); + + on_trigger_set(); //derived classes can do initialization here } diff --git a/gtk2_ardour/trigger_ui.h b/gtk2_ardour/trigger_ui.h index 30874f3b70..fb9b8bf74e 100644 --- a/gtk2_ardour/trigger_ui.h +++ b/gtk2_ardour/trigger_ui.h @@ -35,6 +35,8 @@ namespace Gtk class Menu; } +class TriggerJumpDialog; + class TriggerUI { public: @@ -43,6 +45,7 @@ public: void set_trigger (ARDOUR::TriggerReference); + virtual void on_trigger_set () {} virtual void on_trigger_changed (PBD::PropertyChange const& ) = 0; static std::string follow_action_to_string (ARDOUR::FollowAction const &); @@ -73,6 +76,9 @@ public: void follow_context_menu (); void context_menu (); + void edit_jump_done (int r, TriggerJumpDialog* d); + void edit_jump(); + void set_follow_action (ARDOUR::FollowAction const &); void set_launch_style (ARDOUR::Trigger::LaunchStyle); void set_quantization (Temporal::BBT_Offset const&); diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 825418b66a..4a8fc70b3a 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -314,6 +314,7 @@ gtk2_ardour_sources = [ 'transport_masters_dialog.cc', 'transpose_dialog.cc', 'trigger_clip_picker.cc', + 'trigger_jump_dialog.cc', 'trigger_page.cc', 'trigger_region_list.cc', 'trigger_route_list.cc',