push2: color palette management, and responding to 2 track properties in TrackMix...
authorPaul Davis <paul@linuxaudiosystems.com>
Sun, 10 Jul 2016 19:22:16 +0000 (15:22 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 27 Sep 2016 19:59:31 +0000 (14:59 -0500)
libs/surfaces/push2/mix.cc
libs/surfaces/push2/push2.cc
libs/surfaces/push2/push2.h
libs/surfaces/push2/track_mix.cc
libs/surfaces/push2/track_mix.h

index f0ee572455072c84c1c4356d788ceb246706a0bf..e7c8bf72c553c1e7991bf17b492513eca550fbc7 100644 (file)
@@ -269,7 +269,6 @@ MixLayout::stripable_property_change (PropertyChange const& what_changed, int wh
        }
 }
 
-
 void
 MixLayout::solo_change (int n)
 {
index aea91ddc38837b43de2ccf4c0a34d561c6345ff4..69e2f619cbde704d787473b0853bf955a788efd9 100644 (file)
@@ -38,6 +38,8 @@
 #include "ardour/session.h"
 #include "ardour/tempo.h"
 
+#include "gtkmm2ext/rgb_macros.h"
+
 #include "push2.h"
 #include "gui.h"
 #include "layout.h"
@@ -138,6 +140,7 @@ Push2::Push2 (ARDOUR::Session& s)
        context = Cairo::Context::create (frame_buffer);
 
        build_maps ();
+       build_color_map ();
 
        /* master cannot be removed, so no need to connect to going-away signal */
        master = session->master_out ();
@@ -1602,3 +1605,85 @@ 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;
+       }
+
+       cerr << "new color 0x" << std::hex << rgb << std::dec << endl;
+
+       int r, g, b, a;
+       UINT_TO_RGBA (rgb, &r, &g, &b, &a);
+       uint8_t r7, r1;
+       uint8_t b7, b1;
+       uint8_t g7, g1;
+       uint8_t w7, w1;
+
+       r7 = r & 0x7f;
+       r1 = r & 0x1;
+       g7 = g & 0x7f;
+       g1 = g & 0x1;
+       b7 = b & 0x7f;
+       b1 = b & 0x1;
+       w7 = 204 & 0x7f;
+       w1 = 204 & 0x1;
+
+       /* get a free index */
+
+       uint8_t index;
+
+       if (color_map_free_list.empty()) {
+               /* random replacement of any entry below 122 (where the
+                * Ableton standard colors live, and not zero either (black)
+                */
+               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] = r7;
+       palette_msg[9] = r1;
+       palette_msg[10] = g7;
+       palette_msg[11] = g1;
+       palette_msg[12] = b7;
+       palette_msg[13] = b1;
+       palette_msg[14] = w7;
+       palette_msg[15] = w1;
+
+       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
+       */
+
+       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);
+       }
+}
index b94126867d6657b6a89875d5905032a140ec9769..eb6fc49e7ad1e648d65c36bd8fcc46401eb960d7 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <vector>
 #include <map>
+#include <stack>
 #include <list>
 #include <set>
 
@@ -327,6 +328,8 @@ class Push2 : public ARDOUR::ControlProtocol
 
        void write (const MidiByteArray&);
 
+       uint8_t get_color_index (uint32_t rgb);
+
        static const int cols;
        static const int rows;
 
@@ -532,6 +535,14 @@ class Push2 : public ARDOUR::ControlProtocol
 
        bool percussion;
        void set_percussive_mode (bool);
+
+       /* color map */
+
+       typedef std::map<uint32_t,uint8_t> ColorMap;
+       typedef std::stack<uint8_t> ColorMapFreeList;
+       ColorMap color_map;
+       ColorMapFreeList color_map_free_list;
+       void build_color_map ();
 };
 
 } /* namespace */
index 181f374c8ef22f8de7d3c48f914b22318a10aaf3..bb292b418be354fe71392a45918772cbbdfee26d 100644 (file)
@@ -60,6 +60,17 @@ TrackMixLayout::TrackMixLayout (Push2& p, Session& s, Cairo::RefPtr<Cairo::Conte
 
        Pango::FontDescription fd ("Sans Bold 24");
        name_layout->set_font_description (fd);
+
+       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);
+               upper_layout[n]->set_text ("solo");
+               lower_layout[n] = Pango::Layout::create (context);
+               lower_layout[n]->set_font_description (fd2);
+               lower_layout[n]->set_text ("mute");
+       }
+
 }
 
 TrackMixLayout::~TrackMixLayout ()
@@ -112,7 +123,12 @@ TrackMixLayout::set_stripable (boost::shared_ptr<Stripable> s)
 
        if (stripable) {
                stripable->DropReferences.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&TrackMixLayout::drop_stripable, this), &p2);
+
+               stripable->PropertyChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&TrackMixLayout::stripable_property_change, this, _1), &p2);
+               stripable->presentation_info().PropertyChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&TrackMixLayout::stripable_property_change, this, _1), &p2);
+
                name_changed ();
+               color_changed ();
        }
 
        _dirty = true;
@@ -132,3 +148,26 @@ TrackMixLayout::name_changed ()
        name_layout->set_text (stripable->name());
        _dirty = true;
 }
+
+void
+TrackMixLayout::color_changed ()
+{
+       uint32_t rgb = stripable->presentation_info().color();
+       uint8_t index = p2.get_color_index (rgb);
+
+       Push2::Button* b = p2.button_by_id (Push2::Upper1);
+       b->set_color (index);
+       b->set_state (Push2::LED::OneShot24th);
+       p2.write (b->state_msg ());
+}
+
+void
+TrackMixLayout::stripable_property_change (PropertyChange const& what_changed)
+{
+       if (what_changed.contains (Properties::color)) {
+               color_changed ();
+       }
+       if (what_changed.contains (Properties::name)) {
+               name_changed ();
+       }
+}
index 54081c115c780014939e002f85515ea249a29e8b..c56b435b72df85de6b9de74494f7beb932fa671d 100644 (file)
@@ -49,9 +49,14 @@ class TrackMixLayout : public Push2Layout
        bool _dirty;
 
        Glib::RefPtr<Pango::Layout> name_layout;
+       Glib::RefPtr<Pango::Layout> upper_layout[8];
+       Glib::RefPtr<Pango::Layout> lower_layout[8];
+
+       void stripable_property_change (PBD::PropertyChange const& what_changed);
 
        void drop_stripable ();
        void name_changed ();
+       void color_changed ();
 };
 
 } /* namespace */