update pad colors when selected track colors chane
[ardour.git] / libs / surfaces / push2 / push2.h
index e3fe7213598745a615a9ffb0ddabb67ad41b47c1..30422775d45751e18908656ae4bd1794421d5080 100644 (file)
 
 #include <vector>
 #include <map>
+#include <stack>
 #include <list>
 #include <set>
 
 #include <libusb.h>
 
-#include <cairomm/refptr.h>
-
 #define ABSTRACT_UI_EXPORTS
 #include "pbd/abstract_ui.h"
 
 #include "control_protocol/control_protocol.h"
 #include "control_protocol/types.h"
 
+#include "canvas/colors.h"
+
 #include "midi_byte_array.h"
 #include "mode.h"
 
-namespace Cairo {
-       class ImageSurface;
-       class Context;
-}
-
 namespace Pango {
        class Layout;
 }
@@ -73,6 +69,7 @@ public:
 class P2GUI;
 class Push2Menu;
 class Push2Layout;
+class Push2Canvas;
 
 class Push2 : public ARDOUR::ControlProtocol
             , public AbstractUI<Push2Request>
@@ -281,6 +278,32 @@ class Push2 : public ARDOUR::ControlProtocol
                        : Button (bb, ex, press, release, long_press) {}
        };
 
+       enum ColorName {
+               DarkBackground,
+               LightBackground,
+
+               ParameterName,
+               StripableName,
+               ClockText,
+
+               KnobArcBackground,
+               KnobArcStart,
+               KnobArcEnd,
+
+               KnobLine,
+               KnobLineShadow,
+
+               KnobForeground,
+               KnobBackground,
+               KnobShadow,
+               KnobBorder,
+       };
+
+       enum PressureMode {
+               AfterTouch,
+               PolyPressure,
+       };
+
   public:
        Push2 (ARDOUR::Session&);
        ~Push2 ();
@@ -306,7 +329,10 @@ class Push2 : public ARDOUR::ControlProtocol
        int pad_note (int row, int col) const;
        PBD::Signal0<void> PadChange;
 
+       void update_selection_color ();
+
        void set_pad_scale (int root, int octave, MusicalMode::Type mode, bool inkey);
+       PBD::Signal0<void> ScaleChange;
 
        MusicalMode::Type mode() const { return  _mode; }
        int scale_root() const { return _scale_root; }
@@ -314,6 +340,9 @@ class Push2 : public ARDOUR::ControlProtocol
        bool in_key() const { return _in_key; }
 
        Push2Layout* current_layout() const;
+       void         use_previous_layout ();
+
+       Push2Canvas* canvas() const { return _canvas; }
 
        enum ModifierState {
                None = 0,
@@ -324,32 +353,29 @@ class Push2 : public ARDOUR::ControlProtocol
        ModifierState modifier_state() const { return _modifier_state; }
 
        Button* button_by_id (ButtonID);
+       static std::string button_name_by_id (ButtonID);
+
+       void strip_buttons_off ();
 
        void write (const MidiByteArray&);
 
-       static const int cols;
-       static const int rows;
+       uint8_t get_color_index (ArdourCanvas::Color rgba);
+       ArdourCanvas::Color get_color (ColorName);
+
+       PressureMode pressure_mode () const { return _pressure_mode; }
+       void set_pressure_mode (PressureMode);
+       PBD::Signal1<void,PressureMode> PressureModeChange;
+
+       libusb_device_handle* usb_handle() const { return handle; }
 
   private:
        libusb_device_handle *handle;
-       uint8_t   frame_header[16];
-       uint16_t* device_frame_buffer;
-       int  device_buffer;
-       Cairo::RefPtr<Cairo::ImageSurface> frame_buffer;
-       sigc::connection vblank_connection;
-       sigc::connection periodic_connection;
-
        ModifierState _modifier_state;
 
-       static const int pixels_per_row;
-
        void do_request (Push2Request*);
        int stop ();
        int open ();
        int close ();
-       bool redraw ();
-       int blit_to_device_frame_buffer ();
-       bool vblank ();
 
        void relax () {}
 
@@ -368,17 +394,16 @@ class Push2 : public ARDOUR::ControlProtocol
        void init_buttons (bool startup);
        void init_touch_strip ();
 
-       /* map of Pads by note number */
+       /* map of Pads by note number (the "fixed" note number sent by the
+        * hardware, not the note number generated if the pad is touched)
+        */
        typedef std::map<int,Pad*> NNPadMap;
        NNPadMap nn_pad_map;
-       /* map of Pads by coordinate
-        *
-        * coord = row * 64 + column;
-        *
-        * rows start at top left
+
+       /* map of Pads by note number they generate (their "filtered" value)
         */
-       typedef std::map<int,Pad*> CoordPadMap;
-       CoordPadMap coord_pad_map;
+       typedef std::multimap<int,Pad*> FNPadMap;
+       FNPadMap fn_pad_map;
 
        void set_button_color (ButtonID, uint8_t color_index);
        void set_button_state (ButtonID, LED::State);
@@ -405,6 +430,8 @@ class Push2 : public ARDOUR::ControlProtocol
        void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
 
        bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
+
+       sigc::connection periodic_connection;
        bool periodic ();
 
        void thread_init ();
@@ -426,7 +453,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 ();
@@ -442,6 +471,9 @@ class Push2 : public ARDOUR::ControlProtocol
        void button_fwd4 ();
        void button_add_track ();
        void button_stop ();
+       void button_master ();
+       void button_quantize ();
+       void button_duplicate ();
        void button_shift_press ();
        void button_shift_release ();
        void button_shift_long_press ();
@@ -454,6 +486,7 @@ class Push2 : public ARDOUR::ControlProtocol
        void button_octave_down ();
        void button_layout_press ();
        void button_scale_press ();
+       void button_mix_press ();
 
        void button_upper (uint32_t n);
        void button_lower (uint32_t n);
@@ -488,20 +521,26 @@ class Push2 : public ARDOUR::ControlProtocol
        boost::shared_ptr<ARDOUR::Stripable> master;
        boost::shared_ptr<ARDOUR::Stripable> monitor;
 
-       /* Cairo graphics context */
-
-       Cairo::RefPtr<Cairo::Context> context;
+       sigc::connection vblank_connection;
+       bool vblank ();
 
        void splash ();
        ARDOUR::microseconds_t splash_start;
 
+       /* the canvas */
+
+       Push2Canvas* _canvas;
+
        /* Layouts */
 
        mutable Glib::Threads::Mutex layout_lock;
        Push2Layout* _current_layout;
-       Push2Layout* drawn_layout;
+       Push2Layout* _previous_layout;
        Push2Layout* mix_layout;
        Push2Layout* scale_layout;
+       Push2Layout* track_mix_layout;
+       Push2Layout* splash_layout;
+       void set_current_layout (Push2Layout*);
 
        bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
 
@@ -518,6 +557,7 @@ class Push2 : public ARDOUR::ControlProtocol
        int connection_state;
        bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
        PBD::ScopedConnection port_connection;
+       void connected ();
 
        /* GUI */
 
@@ -529,9 +569,6 @@ class Push2 : public ARDOUR::ControlProtocol
        PBD::ScopedConnection selection_connection;
        void stripable_selection_change (ARDOUR::StripableNotificationListPtr);
 
-       std::map<int,int> pad_map;
-       void build_pad_table();
-
        MusicalMode::Type _mode;
        int _scale_root;
        int _root_octave;
@@ -541,92 +578,27 @@ class Push2 : public ARDOUR::ControlProtocol
 
        bool percussion;
        void set_percussive_mode (bool);
-};
-
-class Push2Layout
-{
-  public:
-       Push2Layout (Push2& p, ARDOUR::Session& s);
-       virtual ~Push2Layout ();
-
-       bool mapped() const;
-
-       virtual bool redraw (Cairo::RefPtr<Cairo::Context>) const = 0;
-
-       virtual void button_upper (uint32_t n) {}
-       virtual void button_lower (uint32_t n) {}
-       virtual void button_up ()  {}
-       virtual void button_down ()  {}
-       virtual void button_right ()  {}
-       virtual void button_left ()  {}
-       virtual void button_select_press () {}
-       virtual void button_select_release () {}
-
-       virtual void strip_vpot (int, int) = 0;
-       virtual void strip_vpot_touch (int, bool) = 0;
-
-  protected:
-       Push2& p2;
-       ARDOUR::Session& session;
-};
-
-
-class MixLayout : public Push2Layout
-{
-   public:
-       MixLayout (Push2& p, ARDOUR::Session&, Cairo::RefPtr<Cairo::Context>);
-       ~MixLayout ();
-
-       bool redraw (Cairo::RefPtr<Cairo::Context>) const;
-
-       void button_upper (uint32_t n);
-       void button_lower (uint32_t n);
-       void button_left ();
-       void button_right ();
-       void button_select_press ();
-       void button_select_release ();
-
-       void strip_vpot (int, int);
-       void strip_vpot_touch (int, bool);
-
-  private:
-       Glib::RefPtr<Pango::Layout> tc_clock_layout;
-       Glib::RefPtr<Pango::Layout> bbt_clock_layout;
-       Glib::RefPtr<Pango::Layout> upper_layout[8];
-       Glib::RefPtr<Pango::Layout> mid_layout[8];
-       Glib::RefPtr<Pango::Layout> lower_layout[8];
 
-       /* stripables */
+       /* color map (device side) */
 
-       int32_t bank_start;
-       PBD::ScopedConnectionList stripable_connections;
-       boost::shared_ptr<ARDOUR::Stripable> stripable[8];
+       typedef std::map<ArdourCanvas::Color,uint8_t> ColorMap;
+       typedef std::stack<uint8_t> ColorMapFreeList;
+       ColorMap color_map;
+       ColorMapFreeList color_map_free_list;
+       void build_color_map ();
 
-       void solo_change (int);
-       void mute_change (int);
+       /* our own colors */
 
-       void stripable_property_change (PBD::PropertyChange const& what_changed, int which);
-
-       void switch_bank (uint32_t base);
-};
-
-class ScaleLayout : public Push2Layout
-{
-   public:
-       ScaleLayout (Push2& p, ARDOUR::Session&, Cairo::RefPtr<Cairo::Context>);
-       ~ScaleLayout ();
-
-       bool redraw (Cairo::RefPtr<Cairo::Context>) const;
-
-       void button_upper (uint32_t n);
-       void button_lower (uint32_t n);
+       typedef std::map<ColorName,ArdourCanvas::Color> Colors;
+       Colors colors;
+       void fill_color_table ();
+       void reset_pad_colors ();
 
-       void strip_vpot (int, int);
-       void strip_vpot_touch (int, bool);
+       PressureMode _pressure_mode;
+       void request_pressure_mode ();
 
-   private:
-       Push2Menu* scale_menu;
-       void build_scale_menu (Cairo::RefPtr<Cairo::Context>);
+       uint8_t selection_color;
+       uint8_t contrast_color;
 };
 
 } /* namespace */