mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-16 02:16:09 +01:00
redesign bottom of pianoroll (automation/MIDI CC buttons)
This should hopefully disambiguate where to click and why
This commit is contained in:
parent
7e9c73b807
commit
f3e581be0d
2 changed files with 161 additions and 85 deletions
|
|
@ -136,6 +136,8 @@ Pianoroll::rebuild_parameter_button_map()
|
|||
void
|
||||
Pianoroll::reset_user_cc_choice (std::string name, Evoral::Parameter param, MetaButton* metabutton)
|
||||
{
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
ParameterButtonMap::iterator iter;
|
||||
|
|
@ -150,6 +152,7 @@ Pianoroll::reset_user_cc_choice (std::string name, Evoral::Parameter param, Meta
|
|||
parameter_button_map.insert (std::make_pair (metabutton, param));
|
||||
|
||||
metabutton->set_by_menutext (name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -185,6 +188,8 @@ Pianoroll::add_multi_controller_item (Gtk::Menu_Helpers::MenuList&,
|
|||
const std::string& name,
|
||||
MetaButton* mb)
|
||||
{
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
using namespace Gtk;
|
||||
|
|
@ -231,22 +236,22 @@ Pianoroll::add_multi_controller_item (Gtk::Menu_Helpers::MenuList&,
|
|||
*/
|
||||
|
||||
mb->add_item (name, menu_text, *chn_menu, [](){});
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Pianoroll::build_lower_toolbar ()
|
||||
{
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
Gtk::RadioButtonGroup edit_group;
|
||||
|
||||
horizontal_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Pianoroll::scrolled));
|
||||
|
||||
ArdourButton::Element elements = ArdourButton::Element (ArdourButton::Text|ArdourButton::Indicator|ArdourButton::Edge|ArdourButton::Body);
|
||||
|
||||
velocity_button = new ArdourButton (_("Velocity"), elements);
|
||||
bender_button = new ArdourButton (_("Bender"), elements);
|
||||
pressure_button = new ArdourButton (_("Pressure"), elements);
|
||||
expression_button = new ArdourButton (_("Expression"), elements);
|
||||
modulation_button = new ArdourButton (_("Modulation"), elements);
|
||||
velocity_button = new ControllerControls (-1, _("Velocity"), edit_group);
|
||||
bender_button = new ControllerControls (MIDI_CMD_BENDER, _("Bender"), edit_group);
|
||||
pressure_button = new ControllerControls (MIDI_CMD_CHANNEL_PRESSURE, _("Pressure"), edit_group);
|
||||
expression_button = new ControllerControls (MIDI_CTL_MSB_EXPRESSION, _("Expression"), edit_group);
|
||||
modulation_button = new ControllerControls (MIDI_CTL_MSB_MODWHEEL, _("Modulation"), edit_group);
|
||||
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
cc_dropdown1 = new MetaButton ();
|
||||
|
|
@ -263,18 +268,6 @@ Pianoroll::build_lower_toolbar ()
|
|||
#endif
|
||||
rebuild_parameter_button_map ();
|
||||
|
||||
/* Only need to do this once because i->first is the actual button,
|
||||
* which does not change even when the parameter_button_map is rebuilt.
|
||||
*/
|
||||
|
||||
for (ParameterButtonMap::iterator i = parameter_button_map.begin(); i != parameter_button_map.end(); ++i) {
|
||||
i->first->set_active_color (0xff0000ff);
|
||||
i->first->set_distinct_led_click (true);
|
||||
i->first->set_led_left (true);
|
||||
i->first->set_act_on_release (false);
|
||||
i->first->set_fallthrough_to_parent (true);
|
||||
}
|
||||
|
||||
// button_bar.set_homogeneous (true);
|
||||
button_bar.set_spacing (6);
|
||||
button_bar.set_border_width (6);
|
||||
|
|
@ -289,26 +282,26 @@ Pianoroll::build_lower_toolbar ()
|
|||
button_bar.pack_start (*cc_dropdown3, false, false);
|
||||
#endif
|
||||
|
||||
velocity_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_button_event), ARDOUR::MidiVelocityAutomation, 0));
|
||||
pressure_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_button_event), ARDOUR::MidiChannelPressureAutomation, 0));
|
||||
bender_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_button_event), ARDOUR::MidiPitchBenderAutomation, 0));
|
||||
modulation_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_button_event), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_MODWHEEL));
|
||||
expression_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_button_event), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_EXPRESSION));
|
||||
velocity_button->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_show_button_click), ARDOUR::MidiVelocityAutomation, 0));
|
||||
pressure_button->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_show_button_click), ARDOUR::MidiChannelPressureAutomation, 0));
|
||||
bender_button->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_show_button_click), ARDOUR::MidiPitchBenderAutomation, 0));
|
||||
modulation_button->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_show_button_click), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_MODWHEEL));
|
||||
expression_button->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_show_button_click), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_EXPRESSION));
|
||||
|
||||
velocity_button->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_led_click), ARDOUR::MidiVelocityAutomation, 0));
|
||||
pressure_button->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_led_click), ARDOUR::MidiChannelPressureAutomation, 0));
|
||||
bender_button->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_led_click), ARDOUR::MidiPitchBenderAutomation, 0));
|
||||
modulation_button->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_led_click), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_MODWHEEL));
|
||||
expression_button->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_led_click), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_EXPRESSION));
|
||||
velocity_button->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_active_button_click), ARDOUR::MidiVelocityAutomation, 0));
|
||||
pressure_button->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_active_button_click), ARDOUR::MidiChannelPressureAutomation, 0));
|
||||
bender_button->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_active_button_click), ARDOUR::MidiPitchBenderAutomation, 0));
|
||||
modulation_button->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_active_button_click), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_MODWHEEL));
|
||||
expression_button->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::automation_active_button_click), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_EXPRESSION));
|
||||
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
cc_dropdown1->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_automation_button_event), cc_dropdown1), false);
|
||||
cc_dropdown2->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_automation_button_event), cc_dropdown2), false);
|
||||
cc_dropdown3->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_automation_button_event), cc_dropdown3), false);
|
||||
cc_dropdown1->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_automation_active_button_click), cc_dropdown1), false);
|
||||
cc_dropdown2->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_automation_active_button_click), cc_dropdown2), false);
|
||||
cc_dropdown3->show_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_automation_active_button_click), cc_dropdown3), false);
|
||||
|
||||
cc_dropdown1->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_led_click), cc_dropdown1));
|
||||
cc_dropdown2->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_led_click), cc_dropdown2));
|
||||
cc_dropdown3->signal_led_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_led_click), cc_dropdown3));
|
||||
cc_dropdown1->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_led_click), cc_dropdown1));
|
||||
cc_dropdown2->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_led_click), cc_dropdown2));
|
||||
cc_dropdown3->edit_clicked.connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::user_led_click), cc_dropdown3));
|
||||
|
||||
cc_dropdown1->signal_map().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::build_cc_menu), cc_dropdown1));
|
||||
cc_dropdown2->signal_map().connect (sigc::bind (sigc::mem_fun (*this, &Pianoroll::build_cc_menu), cc_dropdown2));
|
||||
|
|
@ -1483,8 +1476,9 @@ Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region)
|
|||
}
|
||||
|
||||
bool
|
||||
Pianoroll::user_automation_button_event (GdkEventButton* ev, MetaButton* mb)
|
||||
Pianoroll::user_automation_active_button_click (GdkEventButton* ev, MetaButton* mb)
|
||||
{
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
if (mb->is_menu_popup_event (ev)) {
|
||||
|
|
@ -1505,12 +1499,14 @@ Pianoroll::user_automation_button_event (GdkEventButton* ev, MetaButton* mb)
|
|||
view->set_active_automation (i->second);
|
||||
}
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Pianoroll::user_led_click (GdkEventButton* ev, MetaButton* metabutton)
|
||||
Pianoroll::user_automation_show_button_click (GdkEventButton* ev, MetaButton* metabutton)
|
||||
{
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
if (ev->button != 1) {
|
||||
|
|
@ -1523,43 +1519,31 @@ Pianoroll::user_led_click (GdkEventButton* ev, MetaButton* metabutton)
|
|||
return;
|
||||
}
|
||||
|
||||
automation_button_event (ev, i->second.type(), i->second.id());
|
||||
}
|
||||
|
||||
bool
|
||||
Pianoroll::automation_button_event (GdkEventButton* ev, Evoral::ParameterType type, int id)
|
||||
{
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
if (ev->button != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (view) {
|
||||
view->set_active_automation (Evoral::Parameter (type, _visible_channel, id));
|
||||
}
|
||||
|
||||
return true;
|
||||
automation_active_button_click (ev, i->second.type(), i->second.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Pianoroll::automation_led_click (GdkEventButton* ev, Evoral::ParameterType type, int id)
|
||||
Pianoroll::automation_active_button_click (Evoral::ParameterType type, int id)
|
||||
{
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
if (ev->button != 1) {
|
||||
return;
|
||||
if (view) {
|
||||
Evoral::Parameter p (type, id);
|
||||
std::string str (ARDOUR::EventTypeMap::instance().to_symbol (p));
|
||||
std::cerr << "set active for " << str << std::endl;
|
||||
view->set_active_automation (Evoral::Parameter (type, _visible_channel, id));
|
||||
}
|
||||
}
|
||||
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_RELEASE:
|
||||
if (view) {
|
||||
Evoral::Parameter param (type, _visible_channel, id);
|
||||
view->toggle_visibility (param);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
void
|
||||
Pianoroll::automation_show_button_click (Evoral::ParameterType type, int id)
|
||||
{
|
||||
EC_LOCAL_TEMPO_SCOPE;
|
||||
|
||||
if (view) {
|
||||
Evoral::Parameter param (type, _visible_channel, id);
|
||||
view->toggle_visibility (param);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1570,23 +1554,24 @@ Pianoroll::automation_state_changed ()
|
|||
|
||||
assert (view);
|
||||
|
||||
|
||||
for (ParameterButtonMap::iterator i = parameter_button_map.begin(); i != parameter_button_map.end(); ++i) {
|
||||
std::string str (ARDOUR::EventTypeMap::instance().to_symbol (i->second));
|
||||
|
||||
/* Indicate active automation state with selected/not-selected visual state */
|
||||
|
||||
if (view->is_active_automation (i->second)) {
|
||||
i->first->set_visual_state (Gtkmm2ext::Selected);
|
||||
i->first->set_editing (true);
|
||||
} else {
|
||||
i->first->set_visual_state (Gtkmm2ext::NoVisualState);
|
||||
i->first->set_editing (false);
|
||||
}
|
||||
|
||||
/* Indicate visible automation state with explicit widget active state (LED) */
|
||||
|
||||
if (view->is_visible_automation (i->second)) {
|
||||
i->first->set_active_state (Gtkmm2ext::ExplicitActive);
|
||||
i->first->set_showing (true);
|
||||
} else {
|
||||
i->first->set_active_state (Gtkmm2ext::Off);
|
||||
i->first->set_showing (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2137,3 +2122,73 @@ Pianoroll::midiviews_from_region_selection (RegionSelection const &) const
|
|||
|
||||
return mv;
|
||||
}
|
||||
|
||||
/*----*/
|
||||
|
||||
using namespace ArdourWidgets;
|
||||
|
||||
ControllerControls::ControllerControls (int num, std::string const & str, Gtk::RadioButtonGroup& group)
|
||||
: number (num)
|
||||
{
|
||||
using namespace Gtk;
|
||||
|
||||
ArdourButton::Element elements = ArdourButton::Element (ArdourButton::VectorIcon|ArdourButton::Edge|ArdourButton::Body);
|
||||
|
||||
show_hide_button = new ArdourButton (elements);
|
||||
edit_button = new ArdourButton (elements);
|
||||
name.set_text (str);
|
||||
|
||||
show_hide_button->set_icon (ArdourIcon::HideEye);
|
||||
edit_button->set_icon (ArdourIcon::ToolDraw);
|
||||
|
||||
show_hide_button->signal_clicked.connect (sigc::mem_fun (show_clicked, &sigc::signal<void>::emit));
|
||||
edit_button->signal_clicked.connect (sigc::mem_fun (edit_clicked, &sigc::signal<void>::emit));
|
||||
|
||||
show_hide_button->set_active_color (0xff0000ff);
|
||||
show_hide_button->set_act_on_release (false);
|
||||
show_hide_button->set_fallthrough_to_parent (false);
|
||||
|
||||
edit_button->set_active_color (0xff0000ff);
|
||||
edit_button->set_act_on_release (false);
|
||||
edit_button->set_fallthrough_to_parent (false);
|
||||
|
||||
set_spacing (6);
|
||||
set_border_width (12);
|
||||
pack_start (*show_hide_button, false, false);
|
||||
pack_start (*edit_button, false, false);
|
||||
pack_start (name, false, false, 6);
|
||||
show_all ();
|
||||
}
|
||||
|
||||
ControllerControls::~ControllerControls ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerControls::showing() const
|
||||
{
|
||||
return show_hide_button->active_state() != Gtkmm2ext::Off;
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerControls::editing() const
|
||||
{
|
||||
return edit_button->get_active();
|
||||
}
|
||||
|
||||
void
|
||||
ControllerControls::set_showing (bool yn)
|
||||
{
|
||||
show_hide_button->set_active_state (yn ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
||||
if (!yn) {
|
||||
show_hide_button->set_icon (ArdourIcon::EditorShowAutoOnTouch);
|
||||
} else {
|
||||
show_hide_button->set_icon (ArdourIcon::HideEye);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ControllerControls::set_editing (bool yn)
|
||||
{
|
||||
edit_button->set_active_state (yn ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "pbd/timer.h"
|
||||
|
||||
#include <ytkmm/adjustment.h>
|
||||
#include <ytkmm/radiotoolbutton.h>
|
||||
|
||||
#include "canvas/ruler.h"
|
||||
#include "widgets/eventboxext.h"
|
||||
|
|
@ -52,6 +53,25 @@ namespace ArdourWidgets {
|
|||
class PianorollMidiView;
|
||||
class PianorollMidiBackground;
|
||||
|
||||
struct ControllerControls : public Gtk::HBox {
|
||||
ControllerControls (int num, std::string const & name, Gtk::RadioButtonGroup& group);
|
||||
~ControllerControls();
|
||||
|
||||
ArdourWidgets::ArdourButton* show_hide_button;
|
||||
ArdourWidgets::ArdourButton* edit_button;
|
||||
Gtk::Label name;
|
||||
int number;
|
||||
|
||||
bool showing() const;
|
||||
bool editing() const;
|
||||
|
||||
sigc::signal<void> show_clicked;
|
||||
sigc::signal<void> edit_clicked;
|
||||
|
||||
void set_showing (bool);
|
||||
void set_editing (bool);
|
||||
};
|
||||
|
||||
class Pianoroll : public CueEditor
|
||||
{
|
||||
public:
|
||||
|
|
@ -156,16 +176,17 @@ class Pianoroll : public CueEditor
|
|||
ArdourCanvas::Rectangle* meter_bar;
|
||||
ArdourCanvas::PianoRollHeader* prh;
|
||||
|
||||
ArdourWidgets::ArdourButton* velocity_button;
|
||||
ArdourWidgets::ArdourButton* bender_button;
|
||||
ArdourWidgets::ArdourButton* pressure_button;
|
||||
ArdourWidgets::ArdourButton* expression_button;
|
||||
ArdourWidgets::ArdourButton* modulation_button;
|
||||
ArdourWidgets::MetaButton* cc_dropdown1;
|
||||
ArdourWidgets::MetaButton* cc_dropdown2;
|
||||
ArdourWidgets::MetaButton* cc_dropdown3;
|
||||
|
||||
typedef std::map<ArdourWidgets::ArdourButton*,Evoral::Parameter> ParameterButtonMap;
|
||||
ControllerControls* velocity_button;
|
||||
ControllerControls* bender_button;
|
||||
ControllerControls* pressure_button;
|
||||
ControllerControls* expression_button;
|
||||
ControllerControls* modulation_button;
|
||||
#ifdef PIANOROLL_USER_BUTTONS
|
||||
ControllerControls cc_dropdown1;
|
||||
ControllerControls cc_dropdown2;
|
||||
ControllerControls cc_dropdown3;
|
||||
#endif
|
||||
typedef std::map<ControllerControls*,Evoral::Parameter> ParameterButtonMap;
|
||||
ParameterButtonMap parameter_button_map;
|
||||
void rebuild_parameter_button_map ();
|
||||
|
||||
|
|
@ -205,11 +226,11 @@ class Pianoroll : public CueEditor
|
|||
|
||||
bool idle_data_captured ();
|
||||
|
||||
bool user_automation_button_event (GdkEventButton* ev, ArdourWidgets::MetaButton* mb);
|
||||
bool automation_button_event (GdkEventButton*, Evoral::ParameterType type, int id);
|
||||
bool automation_button_click (Evoral::ParameterType type, int id, ARDOUR::SelectionOperation);
|
||||
void automation_led_click (GdkEventButton*, Evoral::ParameterType type, int id);
|
||||
void user_led_click (GdkEventButton* ev, ArdourWidgets::MetaButton* metabutton);
|
||||
bool user_automation_active_button_click (GdkEventButton* ev, ArdourWidgets::MetaButton* mb);
|
||||
void user_automation_show_button_click (GdkEventButton* ev, ArdourWidgets::MetaButton* metabutton);
|
||||
|
||||
void automation_active_button_click (Evoral::ParameterType type, int id);
|
||||
void automation_show_button_click (Evoral::ParameterType type, int id);
|
||||
|
||||
int _visible_channel;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue