+/*
+ Copyright (C) 2016 Paul Davis
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "ardour/mute_control.h"
#include "ardour/session.h"
+#include "ardour/solo_control.h"
#include "push2.h"
using namespace ArdourSurface;
+using namespace ARDOUR;
void
Push2::button_play ()
modifier_state = ModifierState (modifier_state & ~ModShift);
}
+void
+Push2::button_browse ()
+{
+ switch_bank (max (0, bank_start - 8));
+}
+
+void
+Push2::button_clip ()
+{
+ switch_bank (max (0, bank_start + 8));
+}
+
+void
+Push2::button_upper (uint32_t n)
+{
+ if (!stripable[n]) {
+ return;
+ }
+
+ boost::shared_ptr<SoloControl> sc = stripable[n]->solo_control ();
+ if (sc) {
+ sc->set_value (!sc->get_value(), PBD::Controllable::UseGroup);
+ }
+}
+
+void
+Push2::button_lower (uint32_t n)
+{
+ if (!stripable[n]) {
+ return;
+ }
+
+ boost::shared_ptr<MuteControl> mc = stripable[n]->mute_control ();
+
+ if (mc) {
+ mc->set_value (!mc->get_value(), PBD::Controllable::UseGroup);
+ }
+}
#include <pangomm/layout.h>
#include "pbd/compose.h"
+#include "pbd/convert.h"
#include "pbd/debug.h"
#include "pbd/failed_constructor.h"
, device_buffer (0)
, frame_buffer (Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, cols, rows))
, modifier_state (None)
+ , bank_start (0)
{
context = Cairo::Context::create (frame_buffer);
tc_clock_layout = Pango::Layout::create (context);
tc_clock_layout->set_font_description (fd);
bbt_clock_layout->set_font_description (fd);
- Pango::FontDescription fd2 ("Sans Bold 10");
+ Pango::FontDescription fd2 ("Sans 10");
for (int n = 0; n < 8; ++n) {
upper_layout[n] = Pango::Layout::create (context);
upper_layout[n]->set_font_description (fd2);
lower_layout[n] = Pango::Layout::create (context);
lower_layout[n]->set_font_description (fd2);
lower_layout[n]->set_text ("mute");
+ }
+
+ Pango::FontDescription fd3 ("Sans Bold 10");
+ for (int n = 0; n < 8; ++n) {
mid_layout[n] = Pango::Layout::create (context);
- mid_layout[n]->set_font_description (fd2);
- mid_layout[n]->set_text (string_compose ("Inst %1", n));
+ mid_layout[n]->set_font_description (fd3);
}
build_maps ();
vblank_connection.disconnect ();
periodic_connection.disconnect ();
session_connections.drop_connections ();
+ stripable_connections.drop_connections ();
if (handle) {
libusb_release_interface (handle, 0x00);
handle = 0;
}
+ for (int n = 0; n < 8; ++n) {
+ stripable[n].reset ();
+ }
+
delete [] device_frame_buffer;
device_frame_buffer = 0;
bbt_clock_layout->set_text (bbt_clock_text);
}
+ string mid_text;
+
+ for (int n = 0; n < 8; ++n) {
+ if (stripable[n]) {
+ mid_text = short_version (stripable[n]->name(), 10);
+ if (mid_text != mid_layout[n]->get_text()) {
+ mid_layout[n]->set_text (mid_text);
+ dirty = true;
+ }
+ }
+ }
+
if (!dirty) {
return false;
}
periodic_timeout->attach (main_loop()->get_context());
init_buttons ();
+ switch_bank (0);
} else {
cc_button_map.insert (make_pair (button->controller_number(), button)); \
id_button_map.insert (make_pair (button->id, button))
- MAKE_COLOR_BUTTON (Upper1, 102);
- MAKE_COLOR_BUTTON (Upper2, 103);
- MAKE_COLOR_BUTTON (Upper3, 104);
- MAKE_COLOR_BUTTON (Upper4, 105);
- MAKE_COLOR_BUTTON (Upper5, 106);
- MAKE_COLOR_BUTTON (Upper6, 107);
- MAKE_COLOR_BUTTON (Upper7, 108);
- MAKE_COLOR_BUTTON (Upper8, 109);
- MAKE_COLOR_BUTTON (Lower1, 21);
- MAKE_COLOR_BUTTON (Lower2, 22);
- MAKE_COLOR_BUTTON (Lower3, 23);
- MAKE_COLOR_BUTTON (Lower4, 24);
- MAKE_COLOR_BUTTON (Lower5, 25);
- MAKE_COLOR_BUTTON (Lower6, 26);
- MAKE_COLOR_BUTTON (Lower7, 27);
+ MAKE_COLOR_BUTTON_PRESS (Upper1, 102, &Push2::button_upper_1);
+ MAKE_COLOR_BUTTON_PRESS (Upper2, 103, &Push2::button_upper_2);
+ MAKE_COLOR_BUTTON_PRESS (Upper3, 104, &Push2::button_upper_3);
+ MAKE_COLOR_BUTTON_PRESS (Upper4, 105, &Push2::button_upper_4);
+ MAKE_COLOR_BUTTON_PRESS (Upper5, 106, &Push2::button_upper_5);
+ MAKE_COLOR_BUTTON_PRESS (Upper6, 107, &Push2::button_upper_6);
+ MAKE_COLOR_BUTTON_PRESS (Upper7, 108, &Push2::button_upper_7);
+ MAKE_COLOR_BUTTON_PRESS (Upper8, 109, &Push2::button_upper_8);
+ MAKE_COLOR_BUTTON_PRESS (Lower1, 20, &Push2::button_lower_1);
+ MAKE_COLOR_BUTTON_PRESS (Lower2, 21, &Push2::button_lower_2);
+ MAKE_COLOR_BUTTON_PRESS (Lower3, 22, &Push2::button_lower_3);
+ MAKE_COLOR_BUTTON_PRESS (Lower4, 23, &Push2::button_lower_4);
+ MAKE_COLOR_BUTTON_PRESS (Lower5, 24, &Push2::button_lower_5);
+ MAKE_COLOR_BUTTON_PRESS (Lower6, 25, &Push2::button_lower_6);
+ 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_WHITE_BUTTON (Mix, 112);
MAKE_WHITE_BUTTON (Undo, 119);
MAKE_WHITE_BUTTON (AddTrack, 53);
- MAKE_WHITE_BUTTON (Browse, 113);
+ MAKE_WHITE_BUTTON_PRESS (Browse, 111, &Push2::button_browse);
+ MAKE_WHITE_BUTTON_PRESS (Clip, 113, &Push2::button_clip);
MAKE_WHITE_BUTTON (Convert, 35);
MAKE_WHITE_BUTTON (DoubleLoop, 117);
MAKE_WHITE_BUTTON (Quantize, 116);
return retval;
}
+
+void
+Push2::switch_bank (uint32_t base)
+{
+ if (!session) {
+ return;
+ }
+
+ stripable_connections.drop_connections ();
+
+ /* try to get the first stripable for the requested bank */
+
+ stripable[0] = session->get_nth_stripable (base+0);
+
+ if (!stripable[0]) {
+ return;
+ }
+
+ /* at least one stripable in this bank */
+ bank_start = base;
+
+ stripable[1] = session->get_nth_stripable (base+1);
+ stripable[2] = session->get_nth_stripable (base+2);
+ stripable[3] = session->get_nth_stripable (base+3);
+ stripable[4] = session->get_nth_stripable (base+4);
+ stripable[5] = session->get_nth_stripable (base+5);
+ stripable[6] = session->get_nth_stripable (base+6);
+ stripable[7] = session->get_nth_stripable (base+7);
+
+ for (int n = 0; n < 8; ++n) {
+ if (!stripable[n]) {
+ continue;
+ }
+
+ /* stripable goes away? refill the bank, starting at the same point */
+
+ stripable[n]->DropReferences.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Push2::switch_bank, this, bank_start), this);
+ boost::shared_ptr<AutomationControl> sc = stripable[n]->solo_control();
+ if (sc) {
+ sc->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Push2::solo_change, this, n), this);
+ }
+
+ boost::shared_ptr<AutomationControl> mc = stripable[n]->mute_control();
+ if (mc) {
+ mc->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Push2::mute_change, this, n), this);
+ }
+
+ solo_change (n);
+ mute_change (n);
+
+ }
+}
+
+void
+Push2::solo_change (int n)
+{
+ ButtonID bid;
+
+ switch (n) {
+ case 0:
+ bid = Upper1;
+ break;
+ case 1:
+ bid = Upper2;
+ break;
+ case 2:
+ bid = Upper3;
+ break;
+ case 3:
+ bid = Upper4;
+ break;
+ case 4:
+ bid = Upper5;
+ break;
+ case 5:
+ bid = Upper6;
+ break;
+ case 6:
+ bid = Upper7;
+ break;
+ case 7:
+ bid = Upper8;
+ break;
+ default:
+ return;
+ }
+
+ boost::shared_ptr<AutomationControl> ac = stripable[n]->solo_control ();
+ if (!ac) {
+ return;
+ }
+
+ Button* b = id_button_map[bid];
+ if (ac->get_value()) {
+ b->set_color (LED::Red);
+ } else {
+ b->set_color (LED::Black);
+ }
+ b->set_state (LED::OneShot24th);
+ write (b->state_msg());
+}
+
+void
+Push2::mute_change (int n)
+{
+ ButtonID bid;
+
+ switch (n) {
+ case 0:
+ bid = Lower1;
+ break;
+ case 1:
+ bid = Lower2;
+ break;
+ case 2:
+ bid = Lower3;
+ break;
+ case 3:
+ bid = Lower4;
+ break;
+ case 4:
+ bid = Lower5;
+ break;
+ case 5:
+ bid = Lower6;
+ break;
+ case 6:
+ bid = Lower7;
+ break;
+ case 7:
+ bid = Lower8;
+ break;
+ default:
+ return;
+ }
+
+ boost::shared_ptr<AutomationControl> ac = stripable[n]->mute_control ();
+ if (!ac) {
+ return;
+ }
+
+ Button* b = id_button_map[bid];
+
+ if (ac->get_value ()) {
+ b->set_color (LED::Blue);
+ } else {
+ b->set_color (LED::Black);
+ }
+ b->set_state (LED::OneShot24th);
+ write (b->state_msg());
+}
void button_new ();
void button_shift_press ();
void button_shift_release ();
+ void button_browse ();
+ void button_clip ();
+ void button_upper (uint32_t n);
+ void button_lower (uint32_t n);
+ void button_upper_1 () { button_upper (0); }
+ void button_upper_2 () { button_upper (1); }
+ void button_upper_3 () { button_upper (2); }
+ void button_upper_4 () { button_upper (3); }
+ void button_upper_5 () { button_upper (4); }
+ void button_upper_6 () { button_upper (5); }
+ void button_upper_7 () { button_upper (6); }
+ void button_upper_8 () { button_upper (7); }
+ void button_lower_1 () { button_lower (0); }
+ void button_lower_2 () { button_lower (1); }
+ void button_lower_3 () { button_lower (2); }
+ void button_lower_4 () { button_lower (3); }
+ void button_lower_5 () { button_lower (4); }
+ void button_lower_6 () { button_lower (5); }
+ void button_lower_7 () { button_lower (6); }
+ void button_lower_8 () { button_lower (7); }
/* widgets */
Glib::RefPtr<Pango::Layout> upper_layout[8];
Glib::RefPtr<Pango::Layout> mid_layout[8];
Glib::RefPtr<Pango::Layout> lower_layout[8];
+
+ /* stripables */
+
+ int32_t bank_start;
+ PBD::ScopedConnectionList stripable_connections;
+ boost::shared_ptr<ARDOUR::Stripable> stripable[8];
+ boost::shared_ptr<ARDOUR::Stripable> master;
+ boost::shared_ptr<ARDOUR::Stripable> monitor;
+
+ void solo_change (int);
+ void mute_change (int);
+
+ void switch_bank (uint32_t base);
};