mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
triggerbox UI: lots of work on first pass control of follow action, launch style, quantization via context menu
This commit is contained in:
parent
d0e9b5d66d
commit
def9392ac6
3 changed files with 204 additions and 5 deletions
|
|
@ -4169,6 +4169,7 @@ Editor::get_grid_type_as_beats (bool& success, timepos_t const & position)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
#warning NUTEMPO need to implement all other subdivs
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
*/
|
||||
|
||||
#include <gtkmm/filechooserdialog.h>
|
||||
#include <gtkmm/menu.h>
|
||||
#include <gtkmm/menuitem.h>
|
||||
#include <gtkmm/stock.h>
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
|
@ -31,8 +33,11 @@
|
|||
|
||||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "triggerbox_ui.h"
|
||||
#include "public_editor.h"
|
||||
#include "ui_config.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace ArdourCanvas;
|
||||
|
|
@ -126,6 +131,7 @@ TriggerBoxUI::build ()
|
|||
|
||||
te->play_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::bang), n));
|
||||
te->name_text->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::text_event), n));
|
||||
te->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::event), n));
|
||||
|
||||
++n;
|
||||
}
|
||||
|
|
@ -149,14 +155,49 @@ TriggerBoxUI::text_event (GdkEvent *ev, size_t n)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerBoxUI::event (GdkEvent* ev, size_t n)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_RELEASE:
|
||||
switch (ev->button.button) {
|
||||
case 3:
|
||||
context_menu (n);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TriggerBoxUI::bang (GdkEvent *ev, size_t n)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_PRESS:
|
||||
if (ev->button.button == 1) {
|
||||
_triggerbox.queue_trigger (&_slots[n]->trigger());
|
||||
switch (ev->button.button) {
|
||||
case 1:
|
||||
_triggerbox.bang_trigger (&_slots[n]->trigger());
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
switch (ev->button.button) {
|
||||
case 1:
|
||||
if (_triggerbox.trigger (n)->launch_style() == Trigger::Gate) {
|
||||
_triggerbox.unbang_trigger (&_slots[n]->trigger());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -165,6 +206,137 @@ TriggerBoxUI::bang (GdkEvent *ev, size_t n)
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxUI::context_menu (size_t n)
|
||||
{
|
||||
using namespace Gtk;
|
||||
using namespace Gtk::Menu_Helpers;
|
||||
using namespace Temporal;
|
||||
|
||||
delete _context_menu;
|
||||
|
||||
_context_menu = new Menu;
|
||||
MenuList& items = _context_menu->items();
|
||||
_context_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
Menu* follow_menu = manage (new Menu);
|
||||
MenuList& fitems = follow_menu->items();
|
||||
|
||||
fitems.push_back (CheckMenuElem (_("Stop"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::Stop)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::Stop) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("Queued"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::QueuedTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::QueuedTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("Next"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::NextTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::NextTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("Previous"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::PrevTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::PrevTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("First"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::FirstTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::FirstTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("Last"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::LastTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::LastTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("Any"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::AnyTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::AnyTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
fitems.push_back (CheckMenuElem (_("Other"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_follow_action), n, Trigger::OtherTrigger)));
|
||||
if (_triggerbox.trigger (n)->follow_action() == Trigger::OtherTrigger) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&fitems.back ())->set_active (true);
|
||||
}
|
||||
|
||||
Menu* launch_menu = manage (new Menu);
|
||||
MenuList& litems = launch_menu->items();
|
||||
|
||||
litems.push_back (CheckMenuElem (_("Loop"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_launch_style), n, Trigger::Loop)));
|
||||
if (_triggerbox.trigger (n)->launch_style() == Trigger::Loop) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&litems.back ())->set_active (true);
|
||||
}
|
||||
litems.push_back (CheckMenuElem (_("Gate"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_launch_style), n, Trigger::Gate)));
|
||||
if (_triggerbox.trigger (n)->launch_style() == Trigger::Gate) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&litems.back ())->set_active (true);
|
||||
}
|
||||
litems.push_back (CheckMenuElem (_("Toggle"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_launch_style), n, Trigger::Toggle)));
|
||||
if (_triggerbox.trigger (n)->launch_style() == Trigger::Toggle) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&litems.back ())->set_active (true);
|
||||
}
|
||||
litems.push_back (CheckMenuElem (_("Repeat"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_launch_style), n, Trigger::Repeat)));
|
||||
if (_triggerbox.trigger (n)->launch_style() == Trigger::Repeat) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&litems.back ())->set_active (true);
|
||||
}
|
||||
|
||||
|
||||
Menu* quant_menu = manage (new Menu);
|
||||
MenuList& qitems = quant_menu->items();
|
||||
bool success;
|
||||
|
||||
Beats grid_beats (PublicEditor::instance().get_grid_type_as_beats (success, timepos_t (0)));
|
||||
BBT_Offset b;
|
||||
|
||||
if (success) {
|
||||
b = BBT_Offset (0, grid_beats.get_beats(), grid_beats.get_ticks());
|
||||
qitems.push_back (CheckMenuElem (_("Main Grid"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_quantization), n, b)));
|
||||
/* can't mark this active because the actual setting just a
|
||||
* precise setting below */
|
||||
}
|
||||
|
||||
b = BBT_Offset (1, 0, 0);
|
||||
qitems.push_back (CheckMenuElem (_("Bars"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_quantization), n, b)));
|
||||
if (_triggerbox.trigger (n)->quantization() == b) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&qitems.back ())->set_active (true);
|
||||
}
|
||||
|
||||
b = BBT_Offset (0, 1, 0);
|
||||
qitems.push_back (CheckMenuElem (_("Quarters"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_quantization), n, b)));
|
||||
if (_triggerbox.trigger (n)->quantization() == b) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&qitems.back ())->set_active (true);
|
||||
}
|
||||
b = BBT_Offset (0, 0, ticks_per_beat/2);
|
||||
qitems.push_back (CheckMenuElem (_("Eighths"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_quantization), n, b)));
|
||||
if (_triggerbox.trigger (n)->quantization() == b) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&qitems.back ())->set_active (true);
|
||||
}
|
||||
b = BBT_Offset (0, 0, ticks_per_beat/4);
|
||||
qitems.push_back (CheckMenuElem (_("Sixteenths"), sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::set_quantization), n, b)));
|
||||
if (_triggerbox.trigger (n)->quantization() == b) {
|
||||
dynamic_cast<Gtk::CheckMenuItem*> (&qitems.back ())->set_active (true);
|
||||
}
|
||||
|
||||
items.push_back (MenuElem (_("Follow Action..."), *follow_menu));
|
||||
items.push_back (MenuElem (_("Launch Style..."), *launch_menu));
|
||||
items.push_back (MenuElem (_("Quantization..."), *quant_menu));
|
||||
|
||||
_context_menu->popup (1, gtk_get_current_event_time());
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxUI::set_follow_action (size_t n, Trigger::FollowAction fa)
|
||||
{
|
||||
_triggerbox.trigger (n)->set_follow_action (fa);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxUI::set_launch_style (size_t n, Trigger::LaunchStyle ls)
|
||||
{
|
||||
_triggerbox.trigger (n)->set_launch_style (ls);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxUI::set_quantization (size_t n, Temporal::BBT_Offset const & q)
|
||||
{
|
||||
_triggerbox.trigger (n)->set_quantization (q);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxUI::choose_sample (size_t n)
|
||||
{
|
||||
|
|
@ -227,3 +399,18 @@ TriggerBoxWindow::TriggerBoxWindow (TriggerBox& tb)
|
|||
add (*tbw);
|
||||
tbw->show ();
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerBoxWindow::on_key_press_event (GdkEventKey* ev)
|
||||
{
|
||||
Gtk::Window& main_window (ARDOUR_UI::instance()->main_window());
|
||||
return ARDOUR_UI_UTILS::relay_key_press (ev, &main_window);
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerBoxWindow::on_key_release_event (GdkEventKey* ev)
|
||||
{
|
||||
Gtk::Window& main_window (ARDOUR_UI::instance()->main_window());
|
||||
return ARDOUR_UI_UTILS::relay_key_press (ev, &main_window);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,17 +23,19 @@
|
|||
|
||||
#include <gtkmm/window.h>
|
||||
|
||||
#include "ardour/triggerbox.h"
|
||||
|
||||
#include "canvas/box.h"
|
||||
#include "canvas/canvas.h"
|
||||
#include "canvas/rectangle.h"
|
||||
|
||||
namespace Gtk {
|
||||
class FileChooserDialog;
|
||||
class Menu;
|
||||
}
|
||||
|
||||
namespace ARDOUR {
|
||||
class Trigger;
|
||||
class TriggerBox;
|
||||
namespace Temporal {
|
||||
struct BBT_Offset;
|
||||
}
|
||||
|
||||
namespace ArdourCanvas {
|
||||
|
|
@ -68,12 +70,18 @@ class TriggerBoxUI : public ArdourCanvas::Box
|
|||
Slots _slots;
|
||||
Gtk::FileChooserDialog* file_chooser;
|
||||
sigc::connection file_chooser_connection;
|
||||
Gtk::Menu* _context_menu;
|
||||
|
||||
bool bang (GdkEvent*, size_t);
|
||||
bool text_event (GdkEvent*, size_t);
|
||||
bool event (GdkEvent*, size_t);
|
||||
|
||||
void choose_sample (size_t n);
|
||||
void sample_chosen (int r, size_t n);
|
||||
void context_menu (size_t n);
|
||||
void set_follow_action (size_t slot, ARDOUR::Trigger::FollowAction);
|
||||
void set_launch_style (size_t slot, ARDOUR::Trigger::LaunchStyle);
|
||||
void set_quantization (size_t slot, Temporal::BBT_Offset const &);
|
||||
|
||||
void build ();
|
||||
};
|
||||
|
|
@ -95,6 +103,9 @@ class TriggerBoxWindow : public Gtk::Window
|
|||
{
|
||||
public:
|
||||
TriggerBoxWindow (ARDOUR::TriggerBox&);
|
||||
|
||||
bool on_key_press_event (GdkEventKey*);
|
||||
bool on_key_release_event (GdkEventKey*);
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_triggerbox_ui_h__ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue