push2: parameterize and centralize colors
[ardour.git] / libs / surfaces / push2 / push2.cc
index 508cf5783faafe6eb747b24ad57558dcb24ba905..c187dc77aa0931058c772e05c964c35599a938df 100644 (file)
@@ -16,6 +16,8 @@
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include <stdlib.h>
+
 #include "pbd/compose.h"
 #include "pbd/convert.h"
 #include "pbd/debug.h"
 #include "ardour/session.h"
 #include "ardour/tempo.h"
 
+#include "gtkmm2ext/rgb_macros.h"
+
+#include "canvas/colors.h"
+
 #include "push2.h"
 #include "gui.h"
+#include "layout.h"
+#include "scale.h"
+#include "mix.h"
+#include "track_mix.h"
 #include "menu.h"
 
 #include "i18n.h"
@@ -133,8 +143,9 @@ Push2::Push2 (ARDOUR::Session& s)
 {
        context = Cairo::Context::create (frame_buffer);
 
-       build_pad_table ();
        build_maps ();
+       build_color_map ();
+       fill_color_table (); 
 
        /* master cannot be removed, so no need to connect to going-away signal */
        master = session->master_out ();
@@ -264,6 +275,8 @@ Push2::open ()
 
        mix_layout = new MixLayout (*this, *session, context);
        scale_layout = new ScaleLayout (*this, *session, context);
+       track_mix_layout = new TrackMixLayout (*this, *session, context);
+
        _current_layout = mix_layout;
 
        return 0;
@@ -900,16 +913,6 @@ Push2::handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes* ev)
 void
 Push2::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb)
 {
-       if (!session) {
-               return;
-       }
-
-       float speed;
-
-       /* range of +1 .. -1 */
-       speed = ((int32_t) pb - 8192) / 8192.0;
-       /* convert to range of +3 .. -3 */
-       session->request_transport_speed (speed * 3.0);
 }
 
 void
@@ -1266,7 +1269,7 @@ Push2::pad_filter (MidiBuffer& in, MidiBuffer& out) const
                                        Pad const * pad = nni->second;
                                        /* shift for output to the shadow port */
                                        if (pad->filtered >= 0) {
-                                               (*ev).set_note (pad->filtered);
+                                               (*ev).set_note (pad->filtered + (octave_shift*12));
                                                out.push_back (*ev);
                                                /* shift back so that the pads light correctly  */
                                                (*ev).set_note (n);
@@ -1350,16 +1353,6 @@ Push2::input_port()
        return _async_in;
 }
 
-void
-Push2::build_pad_table ()
-{
-       for (int n = 36; n < 100; ++n) {
-               pad_map[n] = n + (octave_shift*12);
-       }
-
-       PadChange (); /* emit signal */
-}
-
 int
 Push2::pad_note (int row, int col) const
 {
@@ -1617,3 +1610,105 @@ Push2::button_by_id (ButtonID bid)
 {
        return id_button_map[bid];
 }
+
+uint8_t
+Push2::get_color_index (uint32_t rgb)
+{
+       ColorMap::iterator i = color_map.find (rgb);
+
+       if (i != color_map.end()) {
+               return i->second;
+       }
+
+       int r, g, b, a;
+       UINT_TO_RGBA (rgb, &r, &g, &b, &a);
+       int w = 204; /* not sure where/when we should get this value */
+
+       /* get a free index */
+
+       uint8_t index;
+
+       if (color_map_free_list.empty()) {
+               /* random replacement of any entry above zero and below 122 (where the
+                * Ableton standard colors live)
+                */
+               index = 1 + (random() % 121);
+       } else {
+               index = color_map_free_list.top();
+               color_map_free_list.pop();
+       }
+
+       MidiByteArray palette_msg (17, 0xf0, 0x00 , 0x21, 0x1d, 0x01, 0x01, 0x03, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x01, 0x7E, 0x00, 0xF7);
+       MidiByteArray update_pallette_msg (8, 0xf0, 0x00, 0x21, 0x1d, 0x01, 0x01, 0x05, 0xF7);
+
+       palette_msg[7] = index;
+       palette_msg[8] = r & 0x7f;
+       palette_msg[9] = r & 0x1;
+       palette_msg[10] = g & 0x7f;
+       palette_msg[11] = g & 0x1;
+       palette_msg[12] = b & 0x7f;
+       palette_msg[13] = b & 0x1;
+       palette_msg[14] = w & 0x7f;
+       palette_msg[15] = w & 0x1;
+
+       write (palette_msg);
+       write (update_pallette_msg);
+
+       color_map[index] = rgb;
+
+       return index;
+}
+
+void
+Push2::build_color_map ()
+{
+       /* These are "standard" colors that Ableton docs suggest will always be
+          there. Put them in our color map so that when we look up these
+          colors, we will use the Ableton indices for them.
+       */
+
+       color_map.insert (make_pair (RGB_TO_UINT (0,0,0), 0));
+       color_map.insert (make_pair (RGB_TO_UINT (204,204,204), 122));
+       color_map.insert (make_pair (RGB_TO_UINT (64,64,64), 123));
+       color_map.insert (make_pair (RGB_TO_UINT (20,20,20), 124));
+       color_map.insert (make_pair (RGB_TO_UINT (0,0,255), 125));
+       color_map.insert (make_pair (RGB_TO_UINT (0,255,0), 126));
+       color_map.insert (make_pair (RGB_TO_UINT (255,0,0), 127));
+
+       for (uint8_t n = 1; n < 122; ++n) {
+               color_map_free_list.push (n);
+       }
+}
+
+void
+Push2::fill_color_table ()
+{
+       colors.insert (make_pair (DarkBackground, ArdourCanvas::rgba_to_color (0, 0, 0, 1)));
+       colors.insert (make_pair (LightBackground, ArdourCanvas::rgba_to_color (0.98, 0.98, 0.98, 1)));
+
+       colors.insert (make_pair (ParameterName, ArdourCanvas::rgba_to_color (0.32, 0.28, 0.47, 1)));
+
+       colors.insert (make_pair (KnobArcBackground, ArdourCanvas::rgba_to_color (0.3, 0.3, 0.3, 1.0)));
+       colors.insert (make_pair (KnobArcStart, ArdourCanvas::rgba_to_color (1.0, 0.0, 0.0, 1.0)));
+       colors.insert (make_pair (KnobArcEnd, ArdourCanvas::rgba_to_color (0.0, 1.0, 0.0, 1.0)));
+
+       colors.insert (make_pair (KnobLineShadow, ArdourCanvas::rgba_to_color  (0, 0, 0, 0.3)));
+       colors.insert (make_pair (KnobLine, ArdourCanvas::rgba_to_color (1, 1, 1, 1)));
+
+       colors.insert (make_pair (KnobForeground, ArdourCanvas::rgba_to_color (1, 1, 1, 1)));
+       colors.insert (make_pair (KnobBackground, ArdourCanvas::rgba_to_color (1, 1, 1, 1)));
+       colors.insert (make_pair (KnobShadow, ArdourCanvas::rgba_to_color (0, 0, 0, 0.1)));
+       colors.insert (make_pair (KnobBorder, ArdourCanvas::rgba_to_color (0, 0, 0, 1)));
+
+}
+
+uint32_t
+Push2::get_color (ColorName name)
+{
+       Colors::iterator c = colors.find (name);
+       if (c != colors.end()) {
+               return c->second;
+       }
+
+       return random();
+}