40129a3f6387553573a41bb3cf80dbc46b1885f0
[ardour.git] / libs / surfaces / push2 / meter.h
1 /*
2     Copyright (C) 2003 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __push2_meter_h__
21 #define __push2_meter_h__
22
23 #include <map>
24 #include <boost/tuple/tuple.hpp>
25 #include <boost/tuple/tuple_comparison.hpp>
26
27 #include <cairomm/pattern.h>
28 #include <cairomm/region.h>
29
30 #include "canvas/item.h"
31
32 namespace ArdourSurface {
33
34 class Meter : public ArdourCanvas::Item {
35   public:
36         enum Orientation {
37                 Horizontal,
38                 Vertical
39         };
40
41         Meter (Item* parent,
42                long hold_cnt, unsigned long width, Orientation, int len=0,
43                int clr0=0x008800ff, int clr1=0x008800ff,
44                int clr2=0x00ff00ff, int clr3=0x00ff00ff,
45                int clr4=0xffaa00ff, int clr5=0xffaa00ff,
46                int clr6=0xffff00ff, int clr7=0xffff00ff,
47                int clr8=0xff0000ff, int clr9=0xff0000ff,
48                int bgc0=0x333333ff, int bgc1=0x444444ff,
49                int bgh0=0x991122ff, int bgh1=0x551111ff,
50                float stp0 = 55.0, // log_meter(-18);
51                float stp1 = 77.5, // log_meter(-9);
52                float stp2 = 92.5, // log_meter(-3); // 95.0, // log_meter(-2);
53                float stp3 = 100.0,
54                int styleflags = 3
55                 );
56         virtual ~Meter ();
57         static void flush_pattern_cache();
58
59         void set (float level, float peak = -1);
60         void clear ();
61
62         float get_level() { return current_level; }
63         float get_user_level() { return current_user_level; }
64         float get_peak() { return current_peak; }
65
66         long hold_count() { return hold_cnt; }
67         void set_hold_count (long);
68         void set_highlight (bool);
69         bool get_highlight () { return highlight; }
70
71         void render (ArdourCanvas::Rect const &, Cairo::RefPtr<Cairo::Context>) const;
72         void compute_bounding_box() const;
73
74   private:
75
76         Cairo::RefPtr<Cairo::Pattern> fgpattern;
77         Cairo::RefPtr<Cairo::Pattern> bgpattern;
78         gint pixheight;
79         gint pixwidth;
80
81         float _stp[4];
82         int _clr[10];
83         int _bgc[2];
84         int _bgh[2];
85         int _styleflags;
86
87         Orientation orientation;
88         mutable Cairo::RectangleInt pixrect;
89         mutable Cairo::RectangleInt last_peak_rect;
90         gint request_width;
91         gint request_height;
92         unsigned long hold_cnt;
93         unsigned long hold_state;
94         bool bright_hold;
95         float current_level;
96         float current_peak;
97         float current_user_level;
98         bool highlight;
99
100         void vertical_expose (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
101         void queue_vertical_redraw (float old_level);
102
103         void horizontal_expose (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
104         void queue_horizontal_redraw (float old_level);
105
106         static bool no_rgba_overlay;
107
108         static Cairo::RefPtr<Cairo::Pattern> generate_meter_pattern (
109                 int, int, int *, float *, int, bool);
110         static Cairo::RefPtr<Cairo::Pattern> request_vertical_meter (
111                 int, int, int *, float *, int);
112         static Cairo::RefPtr<Cairo::Pattern> request_horizontal_meter (
113                 int, int, int *, float *, int);
114
115         static Cairo::RefPtr<Cairo::Pattern> generate_meter_background (
116                 int, int, int *, bool, bool);
117         static Cairo::RefPtr<Cairo::Pattern> request_vertical_background (
118                 int, int, int *, bool);
119         static Cairo::RefPtr<Cairo::Pattern> request_horizontal_background (
120                 int, int, int *, bool);
121
122         struct Pattern10MapKey {
123                 Pattern10MapKey (
124                                 int w, int h,
125                                 float stp0, float stp1, float stp2, float stp3,
126                                 int c0, int c1, int c2, int c3,
127                                 int c4, int c5, int c6, int c7,
128                                 int c8, int c9, int st
129                                 )
130                         : dim(w, h)
131                         , stp(stp0, stp1, stp2, stp3)
132                         , cols(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9)
133                         , style(st)
134                 {}
135                 inline bool operator<(const Pattern10MapKey& rhs) const {
136                         return (dim < rhs.dim)
137                                 || (dim == rhs.dim && stp < rhs.stp)
138                                 || (dim == rhs.dim && stp == rhs.stp && cols < rhs.cols)
139                                 || (dim == rhs.dim && stp == rhs.stp && cols == rhs.cols && style < rhs.style);
140                 }
141                 boost::tuple<int, int> dim;
142                 boost::tuple<float, float, float, float> stp;
143                 boost::tuple<int, int, int, int, int, int, int, int, int, int> cols;
144                 int style;
145         };
146         typedef std::map<Pattern10MapKey, Cairo::RefPtr<Cairo::Pattern> > Pattern10Map;
147
148         struct PatternBgMapKey {
149                 PatternBgMapKey (int w, int h, int c0, int c1, bool shade)
150                         : dim(w, h)
151                         , cols(c0, c1)
152                         , sh(shade)
153                 {}
154                 inline bool operator<(const PatternBgMapKey& rhs) const {
155                         return (dim < rhs.dim) || (dim == rhs.dim && cols < rhs.cols) || (dim == rhs.dim && cols == rhs.cols && (sh && !rhs.sh));
156                 }
157                 boost::tuple<int, int> dim;
158                 boost::tuple<int, int> cols;
159                 bool sh;
160         };
161         typedef std::map<PatternBgMapKey, Cairo::RefPtr<Cairo::Pattern> > PatternBgMap;
162
163         static Pattern10Map vm_pattern_cache;
164         static PatternBgMap vb_pattern_cache;
165         static Pattern10Map hm_pattern_cache;
166         static PatternBgMap hb_pattern_cache;
167         static int min_pattern_metric_size; // min dimension for axis that displays the meter level
168         static int max_pattern_metric_size; // max dimension for axis that displays the meter level
169 };
170
171 } /* namespace */
172
173 #endif /* __push2_meter_h__ */