Merge branch 'nsm' of https://github.com/royvegard/ardour
[ardour.git] / libs / gtkmm2ext / gtkmm2ext / fastmeter.h
index 38b640788a634458efa7707ce2cf56bb6f9d99c9..9988d21f99d7329f822a68c8fb3454e0a6517e2d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2003 Paul Davis 
+    Copyright (C) 2003 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
 #ifndef __gtkmm2ext_fastmeter_h__
 #define __gtkmm2ext_fastmeter_h__
 
+#include <map>
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <cairomm/pattern.h>
 #include <gtkmm/drawingarea.h>
 #include <gdkmm/pixbuf.h>
 
@@ -27,14 +31,14 @@ namespace Gtkmm2ext {
 
 class FastMeter : public Gtk::DrawingArea {
   public:
-       enum Orientation { 
+       enum Orientation {
                Horizontal,
                Vertical
        };
-       
+
        FastMeter (long hold_cnt, unsigned long width, Orientation, int len=0, int clrb0=0x00ff00, int clr1=0xffff00, int clr2=0xffaa00, int clr3=0xff0000);
        virtual ~FastMeter ();
-       
+
        void set (float level);
        void clear ();
 
@@ -44,21 +48,22 @@ class FastMeter : public Gtk::DrawingArea {
 
        long hold_count() { return hold_cnt; }
        void set_hold_count (long);
-       
-  protected:
+
+protected:
        bool on_expose_event (GdkEventExpose*);
        void on_size_request (GtkRequisition*);
        void on_size_allocate (Gtk::Allocation&);
 
-  private:  
+private:
 
-       Glib::RefPtr<Gdk::Pixbuf> pixbuf;
+       Cairo::RefPtr<Cairo::Pattern> pattern;
        gint pixheight;
        gint pixwidth;
-       static int _clr0, _clr1, _clr2, _clr3;
+       int _clr0, _clr1, _clr2, _clr3;
 
        Orientation orientation;
        GdkRectangle pixrect;
+       GdkRectangle last_peak_rect;
        gint request_width;
        gint request_height;
        unsigned long hold_cnt;
@@ -66,21 +71,36 @@ class FastMeter : public Gtk::DrawingArea {
        float current_level;
        float current_peak;
        float current_user_level;
-       
+
        bool vertical_expose (GdkEventExpose*);
        bool horizontal_expose (GdkEventExpose*);
-       
-       static Glib::RefPtr<Gdk::Pixbuf> request_vertical_meter(int w, int h);
-
-       static Glib::RefPtr<Gdk::Pixbuf> *v_pixbuf_cache;
-       static int min_v_pixbuf_size;
-       static int max_v_pixbuf_size;
-
-       static Glib::RefPtr<Gdk::Pixbuf> request_horizontal_meter(int w, int h);
+       void queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>&, float);
+       void queue_horizontal_redraw (const Glib::RefPtr<Gdk::Window>&, float);
+
+       static Cairo::RefPtr<Cairo::Pattern> generate_meter_pattern (
+               int w, int h, int clr0, int clr1, int clr2, int clr3);
+       static Cairo::RefPtr<Cairo::Pattern> request_vertical_meter (
+               int w, int h, int clr0, int clr1, int clr2, int clr3);
+       static Cairo::RefPtr<Cairo::Pattern> request_horizontal_meter (
+               int w, int h, int clr0, int clr1, int clr2, int clr3);
+
+       struct PatternMapKey {
+               PatternMapKey (int w, int h, int c0, int c1, int c2, int c3)
+                       : dim(w, h)
+                       , cols(c0, c1, c2, c3)
+               {}
+               inline bool operator<(const PatternMapKey& rhs) const {
+                       return (dim < rhs.dim) || (dim == rhs.dim && cols < rhs.cols);
+               }
+               boost::tuple<int, int>           dim;  // width, height
+               boost::tuple<int, int, int, int> cols; // c0, c1, c2, c3
+       };
+       typedef std::map<PatternMapKey, Cairo::RefPtr<Cairo::Pattern> > PatternMap;
 
-       static Glib::RefPtr<Gdk::Pixbuf> *h_pixbuf_cache;
-       static int min_h_pixbuf_size;
-       static int max_h_pixbuf_size;
+       static PatternMap v_pattern_cache;
+       static PatternMap h_pattern_cache;
+       static int min_pattern_metric_size; // min dimension for axis that displays the meter level
+       static int max_pattern_metric_size; // max dimension for axis that displays the meter level
 };