diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-07-11 13:13:04 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-09-27 14:59:31 -0500 |
commit | 11843e00ba5c158bce788ee08c564c5526e7646b (patch) | |
tree | 91fd6c77303b412c7a8f84639fa6ba46b0ae7404 /libs/surfaces | |
parent | b83096528813b30a7864d1a4bf9da9d60b848bc2 (diff) |
continuing work on refining push2 mix layout
Diffstat (limited to 'libs/surfaces')
-rw-r--r-- | libs/surfaces/push2/buttons.cc | 35 | ||||
-rw-r--r-- | libs/surfaces/push2/layout.h | 4 | ||||
-rw-r--r-- | libs/surfaces/push2/mix.cc | 361 | ||||
-rw-r--r-- | libs/surfaces/push2/mix.h | 16 | ||||
-rw-r--r-- | libs/surfaces/push2/push2.cc | 21 | ||||
-rw-r--r-- | libs/surfaces/push2/push2.h | 3 | ||||
-rw-r--r-- | libs/surfaces/push2/track_mix.cc | 4 |
7 files changed, 254 insertions, 190 deletions
diff --git a/libs/surfaces/push2/buttons.cc b/libs/surfaces/push2/buttons.cc index c33ef8807f..e7a775d004 100644 --- a/libs/surfaces/push2/buttons.cc +++ b/libs/surfaces/push2/buttons.cc @@ -120,6 +120,10 @@ Push2::build_maps () button = new ColorButton ((i), (cc), (p)); \ cc_button_map.insert (std::make_pair (button->controller_number(), button)); \ id_button_map.insert (std::make_pair (button->id, button)) +#define MAKE_COLOR_BUTTON_PRESS_RELEASE_LONG(i,cc,p,r,l) \ + button = new ColorButton ((i), (cc), (p), (r), (l)); \ + cc_button_map.insert (std::make_pair (button->controller_number(), button)); \ + id_button_map.insert (std::make_pair (button->id, button)) MAKE_COLOR_BUTTON_PRESS (Upper1, 102, &Push2::button_upper_1); MAKE_COLOR_BUTTON_PRESS (Upper2, 103, &Push2::button_upper_2); @@ -138,8 +142,8 @@ Push2::build_maps () MAKE_COLOR_BUTTON_PRESS (Lower7, 26, &Push2::button_lower_7); MAKE_COLOR_BUTTON_PRESS (Lower8, 27, &Push2::button_lower_8); MAKE_COLOR_BUTTON (Master, 28); - MAKE_COLOR_BUTTON (Mute, 60); - MAKE_COLOR_BUTTON_PRESS (Solo, 61, &Push2::button_solo); + MAKE_COLOR_BUTTON_PRESS (Mute, 60, &Push2::button_mute); + MAKE_COLOR_BUTTON_PRESS_RELEASE_LONG (Solo, 61, &Push2::relax, &Push2::button_solo, &Push2::button_solo_long_press); MAKE_COLOR_BUTTON_PRESS (Stop, 29, &Push2::button_stop); MAKE_COLOR_BUTTON_PRESS (Fwd32ndT, 43, &Push2::button_fwd32t); MAKE_COLOR_BUTTON_PRESS (Fwd32nd,42 , &Push2::button_fwd32); @@ -281,12 +285,28 @@ Push2::button_metronome () } void -Push2::button_solo () +Push2::button_solo_long_press () { cancel_all_solo (); } void +Push2::button_mute () +{ + if (_current_layout) { + _current_layout->button_mute (); + } +} + +void +Push2::button_solo () +{ + if (_current_layout) { + _current_layout->button_solo (); + } +} + +void Push2::button_new () { access_action ("Editor/start-range-from-playhead"); @@ -543,9 +563,9 @@ void Push2::button_scale_press () { if (_current_layout != scale_layout) { - _current_layout = scale_layout; + set_current_layout (_current_layout); } else { - _current_layout = mix_layout; + set_current_layout (mix_layout); } } @@ -553,11 +573,10 @@ void Push2::button_mix_press () { if (_current_layout == track_mix_layout) { - _current_layout = mix_layout; + set_current_layout (mix_layout); } else { if (ControlProtocol::first_selected_stripable()) { - dynamic_cast<TrackMixLayout*> (track_mix_layout)->set_stripable (ControlProtocol::first_selected_stripable()); - _current_layout = track_mix_layout; + set_current_layout (track_mix_layout); } } } diff --git a/libs/surfaces/push2/layout.h b/libs/surfaces/push2/layout.h index 969c510dfb..1fc18af959 100644 --- a/libs/surfaces/push2/layout.h +++ b/libs/surfaces/push2/layout.h @@ -44,6 +44,8 @@ class Push2Layout bool mapped() const; virtual bool redraw (Cairo::RefPtr<Cairo::Context>) const = 0; + virtual void on_show () {} + virtual void on_hide () {} virtual void button_upper (uint32_t n) {} virtual void button_lower (uint32_t n) {} @@ -53,6 +55,8 @@ class Push2Layout virtual void button_left () {} virtual void button_select_press () {} virtual void button_select_release () {} + virtual void button_solo () {} + virtual void button_mute () {} virtual void strip_vpot (int, int) = 0; virtual void strip_vpot_touch (int, bool) = 0; diff --git a/libs/surfaces/push2/mix.cc b/libs/surfaces/push2/mix.cc index dde022a39e..e72d8a86f1 100644 --- a/libs/surfaces/push2/mix.cc +++ b/libs/surfaces/push2/mix.cc @@ -57,7 +57,9 @@ using namespace ArdourSurface; MixLayout::MixLayout (Push2& p, Session& s, Cairo::RefPtr<Cairo::Context> context) : Push2Layout (p, s) + , _dirty (true) , bank_start (0) + , vpot_mode (Volume) { tc_clock_layout = Pango::Layout::create (context); bbt_clock_layout = Pango::Layout::create (context); @@ -108,16 +110,30 @@ MixLayout::MixLayout (Push2& p, Session& s, Cairo::RefPtr<Cairo::Context> contex } for (int n = 0; n < 8; ++n) { - knobs[n] = new Push2Knob (p2); + knobs[n] = new Push2Knob (p2, context); knobs[n]->set_position (60 + (n*120), 95); knobs[n]->set_radius (25); } - switch_bank (0); + mode_button = p2.button_by_id (Push2::Upper1); } MixLayout::~MixLayout () { + for (int n = 0; n < 8; ++n) { + delete knobs[n]; + } +} + +void +MixLayout::on_show () +{ + mode_button->set_color (Push2::LED::White); + mode_button->set_state (Push2::LED::OneShot24th); + p2.write (mode_button->state_msg()); + + switch_bank (bank_start); + show_vpot_mode (); } bool @@ -162,7 +178,7 @@ MixLayout::redraw (Cairo::RefPtr<Cairo::Context> context) const tc_clock_layout->set_text (tc_clock_text); } - if (bbt_clock_text != tc_clock_layout->get_text()) { + if (bbt_clock_text != bbt_clock_layout->get_text()) { children_dirty = true; bbt_clock_layout->set_text (bbt_clock_text); } @@ -176,15 +192,32 @@ MixLayout::redraw (Cairo::RefPtr<Cairo::Context> context) const for (int n = 0; n < 8; ++n) { if (stripable[n]) { - string name = short_version (stripable[n]->name(), 10); - if (name != lower_layout[n]->get_text()) { - lower_layout[n]->set_text (name); + string shortname = short_version (stripable[n]->name(), 10); + string text; + boost::shared_ptr<AutomationControl> ac; + ac = stripable[n]->solo_control(); + if (ac && ac->get_value()) { + text += "* "; + } + boost::shared_ptr<MuteControl> mc; + mc = stripable[n]->mute_control (); + if (mc) { + if (mc->muted_by_self_or_masters()) { + text += "! "; + } else if (mc->muted_by_others_soloing()) { + text += "- "; // it would be nice to use Unicode mute"\uD83D\uDD07 "; + } + } + text += shortname; + + if (text != lower_layout[n]->get_text()) { + lower_layout[n]->set_text (text); children_dirty = true; } } } - if (!children_dirty) { + if (!children_dirty && !_dirty) { return false; } @@ -205,9 +238,24 @@ MixLayout::redraw (Cairo::RefPtr<Cairo::Context> context) const set_source_rgb (context, p2.get_color (Push2::ParameterName)); for (int n = 0; n < 8; ++n) { + if (upper_layout[n]->get_text().empty()) { continue; } + + /* Draw highlight box */ + + uint32_t color = p2.get_color (Push2::ParameterName); + + if (n == (int) vpot_mode) { + set_source_rgb (context, color); + context->rectangle (10 + (n*120) - 5, 2, 120, 21); + context->fill(); + set_source_rgb (context, ArdourCanvas::contrasting_text_color (color)); + } else { + set_source_rgb (context, color); + } + context->move_to (10 + (n*120), 2); upper_layout[n]->update_from_cairo_context (context); upper_layout[n]->show_in_cairo_context (context); @@ -229,40 +277,146 @@ MixLayout::redraw (Cairo::RefPtr<Cairo::Context> context) const } if (stripable[n]) { + uint32_t color = stripable[n]->presentation_info().color(); + if (stripable[n]->presentation_info().selected()) { - set_source_rgb (context, stripable[n]->presentation_info().color()); - context->rectangle (10 + (n*120) - 5, 137, 120, 22); + set_source_rgb (context, color); + context->rectangle (10 + (n*120) - 5, 137, 120, 21); context->fill(); - set_source_rgb (context, ArdourCanvas::contrasting_text_color (stripable[n]->presentation_info().color())); + set_source_rgb (context, ArdourCanvas::contrasting_text_color (color)); } else { - set_source_rgb (context, stripable[n]->presentation_info().color()); + set_source_rgb (context, color); } + + context->move_to (10 + (n*120), 140); + lower_layout[n]->update_from_cairo_context (context); + lower_layout[n]->show_in_cairo_context (context); } - /* XXX what color is used here? text should be empty anyway... no stripable */ - context->move_to (10 + (n*120), 140); - lower_layout[n]->update_from_cairo_context (context); - lower_layout[n]->show_in_cairo_context (context); } + _dirty = false; + return true; } void MixLayout::button_upper (uint32_t n) { - if (!stripable[n]) { - return; + Push2::Button* b; + switch (n) { + case 0: + vpot_mode = Volume; + b = p2.button_by_id (Push2::Upper1); + break; + case 1: + vpot_mode = PanAzimuth; + b = p2.button_by_id (Push2::Upper2); + break; + case 2: + vpot_mode = PanWidth; + b = p2.button_by_id (Push2::Upper3); + break; + case 3: + vpot_mode = Send1; + b = p2.button_by_id (Push2::Upper4); + break; + case 4: + vpot_mode = Send2; + b = p2.button_by_id (Push2::Upper5); + break; + case 5: + vpot_mode = Send3; + b = p2.button_by_id (Push2::Upper6); + break; + case 6: + vpot_mode = Send4; + b = p2.button_by_id (Push2::Upper7); + break; + case 7: + vpot_mode = Send5; + b = p2.button_by_id (Push2::Upper8); + break; + } + + if (b != mode_button) { + mode_button->set_color (Push2::LED::Black); + mode_button->set_state (Push2::LED::OneShot24th); + p2.write (mode_button->state_msg()); } - if (p2.modifier_state() & Push2::ModShift) { - boost::shared_ptr<AutomationControl> sc = stripable[n]->rec_enable_control (); - if (sc) { - sc->set_value (!sc->get_value(), PBD::Controllable::UseGroup); + mode_button = b; + + show_vpot_mode (); +} + +void +MixLayout::show_vpot_mode () +{ + mode_button->set_color (Push2::LED::White); + mode_button->set_state (Push2::LED::OneShot24th); + p2.write (mode_button->state_msg()); + + boost::shared_ptr<AutomationControl> ac; + switch (vpot_mode) { + case Volume: + for (int s = 0; s < 8; ++s) { + if (stripable[s]) { + knobs[s]->set_controllable (stripable[s]->gain_control()); + } else { + knobs[s]->set_controllable (boost::shared_ptr<AutomationControl>()); + } + knobs[s]->remove_flag (Push2Knob::ArcToZero); } - } else { - boost::shared_ptr<SoloControl> sc = stripable[n]->solo_control (); - if (sc) { - sc->set_value (!sc->self_soloed(), PBD::Controllable::UseGroup); + break; + case PanAzimuth: + for (int s = 0; s < 8; ++s) { + if (stripable[s]) { + knobs[s]->set_controllable (stripable[s]->pan_azimuth_control()); + knobs[s]->add_flag (Push2Knob::ArcToZero); + } else { + knobs[s]->set_controllable (boost::shared_ptr<AutomationControl>()); + + } + } + break; + case PanWidth: + for (int s = 0; s < 8; ++s) { + if (stripable[s]) { + knobs[s]->set_controllable (stripable[s]->pan_width_control()); + } else { + knobs[s]->set_controllable (boost::shared_ptr<AutomationControl>()); + + } + knobs[s]->remove_flag (Push2Knob::ArcToZero); + } + break; + default: + break; + } + + _dirty = true; +} + +void +MixLayout::button_mute () +{ + boost::shared_ptr<Stripable> s = ControlProtocol::first_selected_stripable(); + if (s) { + boost::shared_ptr<AutomationControl> ac = s->mute_control(); + if (ac) { + ac->set_value (!ac->get_value(), PBD::Controllable::UseGroup); + } + } +} + +void +MixLayout::button_solo () +{ + boost::shared_ptr<Stripable> s = ControlProtocol::first_selected_stripable(); + if (s) { + boost::shared_ptr<AutomationControl> ac = s->solo_control(); + if (ac) { + ac->set_value (!ac->get_value(), PBD::Controllable::UseGroup); } } } @@ -280,11 +434,10 @@ MixLayout::button_lower (uint32_t n) void MixLayout::strip_vpot (int n, int delta) { - if (stripable[n]) { - boost::shared_ptr<AutomationControl> ac = stripable[n]->gain_control(); - if (ac) { - ac->set_value (ac->get_value() + ((2.0/64.0) * delta), PBD::Controllable::UseGroup); - } + boost::shared_ptr<Controllable> ac = knobs[n]->controllable(); + + if (ac) { + ac->set_value (ac->get_value() + ((2.0/64.0) * delta), PBD::Controllable::UseGroup); } } @@ -322,147 +475,11 @@ MixLayout::stripable_property_change (PropertyChange const& what_changed, int wh void MixLayout::solo_change (int n) { - Push2::ButtonID bid; - - switch (n) { - case 0: - bid = Push2::Upper1; - break; - case 1: - bid = Push2::Upper2; - break; - case 2: - bid = Push2::Upper3; - break; - case 3: - bid = Push2::Upper4; - break; - case 4: - bid = Push2::Upper5; - break; - case 5: - bid = Push2::Upper6; - break; - case 6: - bid = Push2::Upper7; - break; - case 7: - bid = Push2::Upper8; - break; - default: - return; - } - - boost::shared_ptr<SoloControl> ac = stripable[n]->solo_control (); - if (!ac) { - return; - } - - Push2::Button* b = p2.button_by_id (bid); - - if (ac->soloed()) { - b->set_color (Push2::LED::Green); - } else { - b->set_color (Push2::LED::Black); - } - - if (ac->soloed_by_others_upstream() || ac->soloed_by_others_downstream()) { - b->set_state (Push2::LED::Blinking4th); - } else { - b->set_state (Push2::LED::OneShot24th); - } - - p2.write (b->state_msg()); } void MixLayout::mute_change (int n) { - Push2::ButtonID bid; - - if (!stripable[n]) { - return; - } - - cerr << "Mute changed on " << n << ' ' << stripable[n]->name() << endl; - - switch (n) { - case 0: - bid = Push2::Lower1; - break; - case 1: - bid = Push2::Lower2; - break; - case 2: - bid = Push2::Lower3; - break; - case 3: - bid = Push2::Lower4; - break; - case 4: - bid = Push2::Lower5; - break; - case 5: - bid = Push2::Lower6; - break; - case 6: - bid = Push2::Lower7; - break; - case 7: - bid = Push2::Lower8; - break; - default: - return; - } - - boost::shared_ptr<MuteControl> mc = stripable[n]->mute_control (); - - if (!mc) { - return; - } - - Push2::Button* b = p2.button_by_id (bid); - - if (Config->get_show_solo_mutes() && !Config->get_solo_control_is_listen_control ()) { - - if (mc->muted_by_self ()) { - /* full mute */ - b->set_color (Push2::LED::Blue); - b->set_state (Push2::LED::OneShot24th); - cerr << "FULL MUTE1\n"; - } else if (mc->muted_by_others_soloing () || mc->muted_by_masters ()) { - /* this will reflect both solo mutes AND master mutes */ - b->set_color (Push2::LED::Blue); - b->set_state (Push2::LED::Blinking4th); - cerr << "OTHER MUTE1\n"; - } else { - /* no mute at all */ - b->set_color (Push2::LED::Black); - b->set_state (Push2::LED::OneShot24th); - cerr << "NO MUTE1\n"; - } - - } else { - - if (mc->muted_by_self()) { - /* full mute */ - b->set_color (Push2::LED::Blue); - b->set_state (Push2::LED::OneShot24th); - cerr << "FULL MUTE2\n"; - } else if (mc->muted_by_masters ()) { - /* this shows only master mutes, not mute-by-others-soloing */ - b->set_color (Push2::LED::Blue); - b->set_state (Push2::LED::Blinking4th); - cerr << "OTHER MUTE1\n"; - } else { - /* no mute at all */ - b->set_color (Push2::LED::Black); - b->set_state (Push2::LED::OneShot24th); - cerr << "NO MUTE2\n"; - } - } - - p2.write (b->state_msg()); } void @@ -498,16 +515,6 @@ MixLayout::switch_bank (uint32_t base) /* stripable goes away? refill the bank, starting at the same point */ stripable[n]->DropReferences.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&MixLayout::switch_bank, this, bank_start), &p2); - boost::shared_ptr<AutomationControl> sc = stripable[n]->solo_control(); - if (sc) { - sc->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&MixLayout::solo_change, this, n), &p2); - } - - boost::shared_ptr<AutomationControl> mc = stripable[n]->mute_control(); - if (mc) { - mc->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&MixLayout::mute_change, this, n), &p2); - } - stripable[n]->presentation_info().PropertyChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&MixLayout::stripable_property_change, this, _1, n), &p2); solo_change (n); @@ -545,6 +552,8 @@ MixLayout::switch_bank (uint32_t base) b->set_color (p2.get_color_index (stripable[n]->presentation_info().color())); b->set_state (Push2::LED::OneShot24th); p2.write (b->state_msg()); + + knobs[n]->set_text_color (stripable[n]->presentation_info().color()); } } diff --git a/libs/surfaces/push2/mix.h b/libs/surfaces/push2/mix.h index 3183426cad..c506a3bfbb 100644 --- a/libs/surfaces/push2/mix.h +++ b/libs/surfaces/push2/mix.h @@ -20,6 +20,7 @@ #define __ardour_push2_mix_layout_h__ #include "layout.h" +#include "push2.h" namespace ARDOUR { class Stripable; @@ -36,6 +37,7 @@ class MixLayout : public Push2Layout ~MixLayout (); bool redraw (Cairo::RefPtr<Cairo::Context>) const; + void on_show (); void button_upper (uint32_t n); void button_lower (uint32_t n); @@ -43,11 +45,14 @@ class MixLayout : public Push2Layout void button_right (); void button_select_press (); void button_select_release (); + void button_solo (); + void button_mute (); void strip_vpot (int, int); void strip_vpot_touch (int, bool); private: + mutable bool _dirty; Glib::RefPtr<Pango::Layout> tc_clock_layout; Glib::RefPtr<Pango::Layout> bbt_clock_layout; Glib::RefPtr<Pango::Layout> upper_layout[8]; @@ -66,6 +71,17 @@ class MixLayout : public Push2Layout void stripable_property_change (PBD::PropertyChange const& what_changed, int which); void switch_bank (uint32_t base); + + enum VPotMode { + Volume, + PanAzimuth, + PanWidth, + Send1, Send2, Send3, Send4, Send5 + }; + + Push2::Button* mode_button; + VPotMode vpot_mode; + void show_vpot_mode (); }; } /* namespace */ diff --git a/libs/surfaces/push2/push2.cc b/libs/surfaces/push2/push2.cc index b89d133f76..d1fd5e48fe 100644 --- a/libs/surfaces/push2/push2.cc +++ b/libs/surfaces/push2/push2.cc @@ -145,7 +145,7 @@ Push2::Push2 (ARDOUR::Session& s) build_maps (); build_color_map (); - fill_color_table (); + fill_color_table (); /* master cannot be removed, so no need to connect to going-away signal */ master = session->master_out (); @@ -277,8 +277,6 @@ Push2::open () scale_layout = new ScaleLayout (*this, *session, context); track_mix_layout = new TrackMixLayout (*this, *session, context); - _current_layout = mix_layout; - return 0; } @@ -514,6 +512,7 @@ Push2::redraw () /* display splash for 3 seconds */ if (get_microseconds() - splash_start > 3000000) { + cerr << "splash done\n"; splash_start = 0; } else { return false; @@ -611,7 +610,7 @@ Push2::set_active (bool yn) init_touch_strip (); set_pad_scale (_scale_root, _root_octave, _mode, _in_key); splash (); - + set_current_layout (mix_layout); } else { @@ -1712,3 +1711,17 @@ Push2::get_color (ColorName name) return random(); } + +void +Push2::set_current_layout (Push2Layout* layout) +{ + if (_current_layout) { + _current_layout->on_hide (); + } + + _current_layout = layout; + + if (_current_layout) { + _current_layout->on_show (); + } +} diff --git a/libs/surfaces/push2/push2.h b/libs/surfaces/push2/push2.h index 29502239e8..d30f89fabe 100644 --- a/libs/surfaces/push2/push2.h +++ b/libs/surfaces/push2/push2.h @@ -443,7 +443,9 @@ class Push2 : public ARDOUR::ControlProtocol void button_left (); void button_metronome (); void button_repeat (); + void button_mute (); void button_solo (); + void button_solo_long_press (); void button_fixed_length (); void button_new (); void button_browse (); @@ -521,6 +523,7 @@ class Push2 : public ARDOUR::ControlProtocol Push2Layout* mix_layout; Push2Layout* scale_layout; Push2Layout* track_mix_layout; + void set_current_layout (Push2Layout*); bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const; diff --git a/libs/surfaces/push2/track_mix.cc b/libs/surfaces/push2/track_mix.cc index 8562656072..69d56425c0 100644 --- a/libs/surfaces/push2/track_mix.cc +++ b/libs/surfaces/push2/track_mix.cc @@ -77,12 +77,12 @@ TrackMixLayout::TrackMixLayout (Push2& p, Session& s, Cairo::RefPtr<Cairo::Conte Push2Knob* knob; - knob = new Push2Knob (p2); + knob = new Push2Knob (p2, context); knob->set_position (60, 80); knob->set_radius (35); knobs.push_back (knob); - knob = new Push2Knob (p2); + knob = new Push2Knob (p2, context); knob->set_position (180, 80); knob->set_radius (35); knobs.push_back (knob); |