MIDI Transform channel-count 1..16 (not 0..15)
[ardour.git] / libs / canvas / canvas / 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 ArdourCanvas {
33
34 class Canvas;
35
36 class Meter : public Item {
37   public:
38         enum Orientation {
39                 Horizontal,
40                 Vertical
41         };
42
43         Meter (Item* parent,
44                long hold_cnt, unsigned long width, Orientation, int len=0,
45                int clr0=0x008800ff, int clr1=0x008800ff,
46                int clr2=0x00ff00ff, int clr3=0x00ff00ff,
47                int clr4=0xffaa00ff, int clr5=0xffaa00ff,
48                int clr6=0xffff00ff, int clr7=0xffff00ff,
49                int clr8=0xff0000ff, int clr9=0xff0000ff,
50                int bgc0=0x333333ff, int bgc1=0x444444ff,
51                int bgh0=0x991122ff, int bgh1=0x551111ff,
52                float stp0 = 55.0, // log_meter(-18);
53                float stp1 = 77.5, // log_meter(-9);
54                float stp2 = 92.5, // log_meter(-3); // 95.0, // log_meter(-2);
55                float stp3 = 100.0,
56                int styleflags = 3
57                 );
58
59         Meter (ArdourCanvas::Canvas* canvas,
60                long hold_cnt, unsigned long width, Orientation, int len=0,
61                int clr0=0x008800ff, int clr1=0x008800ff,
62                int clr2=0x00ff00ff, int clr3=0x00ff00ff,
63                int clr4=0xffaa00ff, int clr5=0xffaa00ff,
64                int clr6=0xffff00ff, int clr7=0xffff00ff,
65                int clr8=0xff0000ff, int clr9=0xff0000ff,
66                int bgc0=0x333333ff, int bgc1=0x444444ff,
67                int bgh0=0x991122ff, int bgh1=0x551111ff,
68                float stp0 = 55.0, // log_meter(-18);
69                float stp1 = 77.5, // log_meter(-9);
70                float stp2 = 92.5, // log_meter(-3); // 95.0, // log_meter(-2);
71                float stp3 = 100.0,
72                int styleflags = 3
73                 );
74         virtual ~Meter ();
75         static void flush_pattern_cache();
76
77         void set (float level, float peak = -1);
78         void clear ();
79
80         float get_level() { return current_level; }
81         float get_user_level() { return current_user_level; }
82         float get_peak() { return current_peak; }
83
84         long hold_count() { return hold_cnt; }
85         void set_hold_count (long);
86         void set_highlight (bool);
87         bool get_highlight () { return highlight; }
88
89         void render (ArdourCanvas::Rect const &, Cairo::RefPtr<Cairo::Context>) const;
90         void compute_bounding_box() const;
91
92   private:
93
94         Cairo::RefPtr<Cairo::Pattern> fgpattern;
95         Cairo::RefPtr<Cairo::Pattern> bgpattern;
96         gint pixheight;
97         gint pixwidth;
98
99         float _stp[4];
100         int _clr[10];
101         int _bgc[2];
102         int _bgh[2];
103         int _styleflags;
104
105         Orientation orientation;
106         mutable Cairo::RectangleInt pixrect;
107         mutable Cairo::RectangleInt last_peak_rect;
108         unsigned long hold_cnt;
109         unsigned long hold_state;
110         bool bright_hold;
111         float current_level;
112         float current_peak;
113         float current_user_level;
114         bool highlight;
115
116         void init (int clr0, int clr1, int clr2, int clr3,
117                    int clr4, int clr5, int clr6, int clr7,
118                    int clr8, int clr9,
119                    int bgc0, int bgc1,
120                    int bgh0, int bgh1,
121                    float stp0, float stp1,
122                    float stp2, float stp3,
123                    int dimen, int len);
124
125         void vertical_expose (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
126         void queue_vertical_redraw (float old_level);
127
128         void horizontal_expose (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
129         void queue_horizontal_redraw (float old_level);
130
131         static bool no_rgba_overlay;
132
133         static Cairo::RefPtr<Cairo::Pattern> generate_meter_pattern (int, int, int *, float *, int, bool);
134         static Cairo::RefPtr<Cairo::Pattern> vertical_meter_pattern (int, int, int *, float *, int);
135         static Cairo::RefPtr<Cairo::Pattern> horizontal_meter_pattern (int, int, int *, float *, int);
136
137         static Cairo::RefPtr<Cairo::Pattern> generate_meter_background (int, int, int *, bool, bool);
138         static Cairo::RefPtr<Cairo::Pattern> vertical_background (int, int, int *, bool);
139         static Cairo::RefPtr<Cairo::Pattern> horizontal_background (int, int, int *, bool);
140
141         struct Pattern10MapKey {
142                 Pattern10MapKey (
143                                 int w, int h,
144                                 float stp0, float stp1, float stp2, float stp3,
145                                 int c0, int c1, int c2, int c3,
146                                 int c4, int c5, int c6, int c7,
147                                 int c8, int c9, int st
148                                 )
149                         : dim(w, h)
150                         , stp(stp0, stp1, stp2, stp3)
151                         , cols(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9)
152                         , style(st)
153                 {}
154                 inline bool operator<(const Pattern10MapKey& rhs) const {
155                         return (dim < rhs.dim)
156                                 || (dim == rhs.dim && stp < rhs.stp)
157                                 || (dim == rhs.dim && stp == rhs.stp && cols < rhs.cols)
158                                 || (dim == rhs.dim && stp == rhs.stp && cols == rhs.cols && style < rhs.style);
159                 }
160                 boost::tuple<int, int> dim;
161                 boost::tuple<float, float, float, float> stp;
162                 boost::tuple<int, int, int, int, int, int, int, int, int, int> cols;
163                 int style;
164         };
165         typedef std::map<Pattern10MapKey, Cairo::RefPtr<Cairo::Pattern> > Pattern10Map;
166
167         struct PatternBgMapKey {
168                 PatternBgMapKey (int w, int h, int c0, int c1, bool shade)
169                         : dim(w, h)
170                         , cols(c0, c1)
171                         , sh(shade)
172                 {}
173                 inline bool operator<(const PatternBgMapKey& rhs) const {
174                         return (dim < rhs.dim) || (dim == rhs.dim && cols < rhs.cols) || (dim == rhs.dim && cols == rhs.cols && (sh && !rhs.sh));
175                 }
176                 boost::tuple<int, int> dim;
177                 boost::tuple<int, int> cols;
178                 bool sh;
179         };
180         typedef std::map<PatternBgMapKey, Cairo::RefPtr<Cairo::Pattern> > PatternBgMap;
181
182         static Pattern10Map vm_pattern_cache;
183         static PatternBgMap vb_pattern_cache;
184         static Pattern10Map hm_pattern_cache;
185         static PatternBgMap hb_pattern_cache;
186         static int min_pattern_metric_size; // min dimension for axis that displays the meter level
187         static int max_pattern_metric_size; // max dimension for axis that displays the meter level
188 };
189
190 } /* namespace */
191
192 #endif /* __push2_meter_h__ */