push2: parameterize and centralize colors
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 11 Jul 2016 13:07:52 +0000 (09:07 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 27 Sep 2016 19:59:31 +0000 (14:59 -0500)
libs/surfaces/push2/push2.cc
libs/surfaces/push2/push2.h
libs/surfaces/push2/track_mix.cc
libs/surfaces/push2/track_mix.h
libs/surfaces/push2/utils.cc [new file with mode: 0644]
libs/surfaces/push2/utils.h [new file with mode: 0644]
libs/surfaces/push2/wscript

index 46c1d7e2d9152ec1909e6457127de26b3058776e..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"
@@ -40,6 +42,8 @@
 
 #include "gtkmm2ext/rgb_macros.h"
 
+#include "canvas/colors.h"
+
 #include "push2.h"
 #include "gui.h"
 #include "layout.h"
@@ -141,6 +145,7 @@ Push2::Push2 (ARDOUR::Session& s)
 
        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 ();
@@ -1658,7 +1663,8 @@ void
 Push2::build_color_map ()
 {
        /* These are "standard" colors that Ableton docs suggest will always be
-          there
+          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));
@@ -1673,3 +1679,36 @@ Push2::build_color_map ()
                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();
+}
index eb6fc49e7ad1e648d65c36bd8fcc46401eb960d7..df6f0fa772e99dbbc4734747b960a4a1f2b7f587 100644 (file)
@@ -282,6 +282,25 @@ class Push2 : public ARDOUR::ControlProtocol
                        : Button (bb, ex, press, release, long_press) {}
        };
 
+       enum ColorName {
+               DarkBackground,
+               LightBackground,
+
+               ParameterName,
+
+               KnobArcBackground,
+               KnobArcStart,
+               KnobArcEnd,
+
+               KnobLine,
+               KnobLineShadow,
+
+               KnobForeground,
+               KnobBackground,
+               KnobShadow,
+               KnobBorder,
+       };
+
   public:
        Push2 (ARDOUR::Session&);
        ~Push2 ();
@@ -329,6 +348,7 @@ class Push2 : public ARDOUR::ControlProtocol
        void write (const MidiByteArray&);
 
        uint8_t get_color_index (uint32_t rgb);
+       uint32_t get_color (ColorName);
 
        static const int cols;
        static const int rows;
@@ -536,13 +556,19 @@ class Push2 : public ARDOUR::ControlProtocol
        bool percussion;
        void set_percussive_mode (bool);
 
-       /* color map */
+       /* color map (device side) */
 
        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 ();
+
+       /* our own colors */
+
+       typedef std::map<ColorName,uint32_t> Colors;
+       Colors colors;
+       void fill_color_table ();
 };
 
 } /* namespace */
index bb292b418be354fe71392a45918772cbbdfee26d..85626560723af967b84ae6880c5381f35e9dac93 100644 (file)
 #include "ardour/session.h"
 #include "ardour/tempo.h"
 
+#include "gtkmm2ext/rgb_macros.h"
+
+#include "knob.h"
 #include "menu.h"
 #include "push2.h"
 #include "track_mix.h"
+#include "utils.h"
 
 #include "i18n.h"
 
@@ -58,7 +62,7 @@ TrackMixLayout::TrackMixLayout (Push2& p, Session& s, Cairo::RefPtr<Cairo::Conte
 {
        name_layout = Pango::Layout::create (context);
 
-       Pango::FontDescription fd ("Sans Bold 24");
+       Pango::FontDescription fd ("Sans Bold 14");
        name_layout->set_font_description (fd);
 
        Pango::FontDescription fd2 ("Sans 10");
@@ -71,28 +75,61 @@ TrackMixLayout::TrackMixLayout (Push2& p, Session& s, Cairo::RefPtr<Cairo::Conte
                lower_layout[n]->set_text ("mute");
        }
 
+       Push2Knob* knob;
+
+       knob = new Push2Knob (p2);
+       knob->set_position (60, 80);
+       knob->set_radius (35);
+       knobs.push_back (knob);
+
+       knob = new Push2Knob (p2);
+       knob->set_position (180, 80);
+       knob->set_radius (35);
+       knobs.push_back (knob);
 }
 
 TrackMixLayout::~TrackMixLayout ()
 {
+       for (vector<Push2Knob*>::iterator k = knobs.begin(); k != knobs.end(); ++k) {
+               delete *k;
+       }
 }
 
 bool
 TrackMixLayout::redraw (Cairo::RefPtr<Cairo::Context> context) const
 {
-       if (!_dirty) {
+       bool children_dirty = false;
+
+       for (vector<Push2Knob*>::const_iterator k = knobs.begin(); k != knobs.end(); ++k) {
+               if ((*k)->dirty()) {
+                       children_dirty = true;
+                       break;
+               }
+       }
+
+       if (!children_dirty && !_dirty) {
                return false;
        }
 
-       context->set_source_rgb (0.764, 0.882, 0.882);
-       context->rectangle (0, 0, 960, 160);
+       set_source_rgb (context, p2.get_color (Push2::DarkBackground));
+       context->rectangle (0, 0, p2.cols, p2.rows);
        context->fill ();
 
-       context->set_source_rgb (0.23, 0.0, 0.349);
+       if (stripable) {
+               int r,g,b,a;
+               UINT_TO_RGBA (stripable->presentation_info().color(), &r, &g, &b, &a);
+               context->set_source_rgb (r/255.0, g/255.0, b/255.0);
+       } else {
+               context->set_source_rgb (0.23, 0.0, 0.349);
+       }
        context->move_to (10, 2);
        name_layout->update_from_cairo_context (context);
        name_layout->show_in_cairo_context (context);
 
+       for (vector<Push2Knob*>::const_iterator k = knobs.begin(); k != knobs.end(); ++k) {
+               (*k)->redraw (context);
+       }
+
        return true;
 }
 
@@ -109,6 +146,18 @@ TrackMixLayout::button_lower (uint32_t n)
 void
 TrackMixLayout::strip_vpot (int n, int delta)
 {
+       if (!stripable) {
+               return;
+       }
+
+       switch (n) {
+       case 0: /* gain */
+               boost::shared_ptr<AutomationControl> ac = stripable->gain_control();
+               if (ac) {
+                       ac->set_value (ac->get_value() + ((2.0/64.0) * delta), PBD::Controllable::UseGroup);
+               }
+               break;
+       }
 }
 
 void
@@ -127,6 +176,9 @@ TrackMixLayout::set_stripable (boost::shared_ptr<Stripable> s)
                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);
 
+               knobs[0]->set_controllable (stripable->gain_control());
+               knobs[1]->set_controllable (stripable->pan_azimuth_control());
+
                name_changed ();
                color_changed ();
        }
index c56b435b72df85de6b9de74494f7beb932fa671d..84aa4f043d9a2e254cc5e816818e1cee204187b1 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef __ardour_push2_track_mix_layout_h__
 #define __ardour_push2_track_mix_layout_h__
 
+#include <vector>
+
 #include "layout.h"
 
 namespace ARDOUR {
@@ -27,6 +29,8 @@ namespace ARDOUR {
 
 namespace ArdourSurface {
 
+class Push2Knob;
+
 class TrackMixLayout : public Push2Layout
 {
    public:
@@ -52,6 +56,8 @@ class TrackMixLayout : public Push2Layout
        Glib::RefPtr<Pango::Layout> upper_layout[8];
        Glib::RefPtr<Pango::Layout> lower_layout[8];
 
+       std::vector<Push2Knob*> knobs;
+
        void stripable_property_change (PBD::PropertyChange const& what_changed);
 
        void drop_stripable ();
diff --git a/libs/surfaces/push2/utils.cc b/libs/surfaces/push2/utils.cc
new file mode 100644 (file)
index 0000000..6227491
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+  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 <cairomm/context.h>
+
+#include "gtkmm2ext/rgb_macros.h"
+
+#include "utils.h"
+
+void
+set_source_rgba (Cairo::RefPtr<Cairo::Context> context, uint32_t col, bool with_alpha)
+{
+       int r, g, b, a;
+
+       UINT_TO_RGBA (col, &r, &g, &b, &a);
+
+       if (with_alpha) {
+               context->set_source_rgba (r/255.0, g/255.0, b/255.0, a/255.0);
+       } else {
+               context->set_source_rgb (r/255.0, g/255.0, b/255.0);
+       }
+}
+
+void
+set_source_rgb (Cairo::RefPtr<Cairo::Context> context, uint32_t color)
+{
+       set_source_rgba (context, color, false);
+}
diff --git a/libs/surfaces/push2/utils.h b/libs/surfaces/push2/utils.h
new file mode 100644 (file)
index 0000000..192c8d5
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  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.
+*/
+
+#ifndef __ardour_push2_utils_h__
+#define __ardour_push2_utils_h__
+
+#include <stdint.h>
+
+#include <cairomm/refptr.h>
+
+namespace Cairo {
+       class Context;
+}
+
+void set_source_rgba (Cairo::RefPtr<Cairo::Context>, uint32_t color, bool with_alpha = true);
+void set_source_rgb (Cairo::RefPtr<Cairo::Context> context, uint32_t color);
+
+#endif /* __ardour_push2_utils_h__ */
index ca872208c90c2015f94529ffcb99c729993ad8fe..147b2e3aa2977b9d7e7604a3eeddf32db084520e 100644 (file)
@@ -26,12 +26,14 @@ def build(bld):
             midi_byte_array.cc
             leds.cc
            gui.cc
+           knob.cc
            layout.cc
            mode.cc
            menu.cc
            mix.cc
            scale.cc
            track_mix.cc
+           utils.cc
     '''
     obj.export_includes = ['.']
     obj.defines      = [ 'PACKAGE="ardour_push2"' ]
@@ -41,7 +43,7 @@ def build(bld):
     obj.name         = 'libardour_push2'
     obj.target       = 'ardour_push2'
     obj.uselib       = 'CAIROMM PANGOMM USB GTKMM'
-    obj.use          = 'libardour libardour_cp libgtkmm2ext libpbd libevoral libtimecode'
+    obj.use          = 'libardour libardour_cp libgtkmm2ext libpbd libevoral libcanvas libtimecode'
     obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
 
 def shutdown():