]> git.0d.be Git - jack_mixer.git/blob - meter.py
Fix remove channels and remove some debug prints
[jack_mixer.git] / meter.py
1 # This file is part of jack_mixer
2 #
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 from gi.repository import Gtk
19 from gi.repository import Gdk
20 from gi.repository import GObject
21 import cairo
22
23 class MeterWidget(Gtk.DrawingArea):
24     def __init__(self, scale):
25         GObject.GObject.__init__(self)
26
27         self.scale = scale
28
29         self.connect("draw", self.draw)
30         #self.connect("size-request", self.on_size_request)
31         self.connect("size-allocate", self.on_size_allocate)
32
33         self.color_bg = Gdk.Color(0,0,0)
34         self.color_value = None
35         self.color_mark = Gdk.Color(int(65535 * 0.2), int(65535 * 0.2), int(65535 * 0.2))
36         self.width = 0
37         self.height = 0
38         self.cache_surface = None
39
40     def get_preferred_width(self):
41         print 'get_preferred_width called'
42         return 2
43
44     def get_preferred_height(self):
45         return 200
46
47     def set_color(self, color):
48         self.color_value = color
49         self.cache_surface = None
50         self.invalidate_all()
51
52     def on_expose(self, widget, event):
53         cairo_ctx = widget.window.cairo_create()
54
55         # set a clip region for the expose event
56         cairo_ctx.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
57         cairo_ctx.clip()
58
59         self.draw(cairo_ctx)
60
61         return False
62
63     def on_size_allocate(self, widget, allocation):
64         self.width = float(allocation.width)
65         self.height = float(allocation.height)
66         self.font_size = 10
67         self.cache_surface = None
68
69     def on_size_request(self, widget, requisition):
70         #print "size-request, %u x %u" % (requisition.width, requisition.height)
71         requisition.width = 20
72         return
73
74     def invalidate_all(self):
75         self.queue_draw_area(0, 0, int(self.width), int(self.height))
76
77     def draw_background(self, cairo_ctx):
78         if not self.cache_surface:
79             self.cache_surface = cairo.Surface.create_similar(
80                             cairo_ctx.get_target(),
81                             cairo.CONTENT_COLOR,
82                             int(self.width),
83                             int(self.height))
84             cache_cairo_ctx = cairo.Context(self.cache_surface)
85
86             cache_cairo_ctx.set_source_rgba(0, 0, 0, 0)
87             cache_cairo_ctx.rectangle(0, 0, self.width, self.height)
88             cache_cairo_ctx.fill()
89
90             cache_cairo_ctx.set_source_rgba(0.2, 0.2, 0.2, 1)
91             cache_cairo_ctx.select_font_face("Fixed")
92             cache_cairo_ctx.set_font_size(self.font_size)
93             glyph_width = self.font_size * 3 / 5 # avarage glyph ratio
94             for mark in self.scale.get_marks():
95                 mark_position = int(self.height * (1 - mark.scale))
96                 cache_cairo_ctx.move_to(0, mark_position)
97                 cache_cairo_ctx.line_to(self.width, mark_position)
98                 cache_cairo_ctx.stroke()
99                 x_correction = self.width / 2 - glyph_width * len(mark.text) / 2
100                 cache_cairo_ctx.move_to(x_correction, mark_position - 2)
101                 cache_cairo_ctx.show_text(mark.text)
102         cairo_ctx.set_source_surface(self.cache_surface, 0, 0)
103         cairo_ctx.paint()
104
105     def draw_value(self, cairo_ctx, value, x, width):
106         if self.color_value is not None:
107             cairo_ctx.set_source_rgb(self.color_value.red/65535.,
108                     self.color_value.green/65535., self.color_value.blue/65535.)
109         else:
110             height = self.height
111             gradient = cairo.LinearGradient(1, 1, width-1, height-1)
112             gradient.add_color_stop_rgb(0, 1, 0, 0)
113             gradient.add_color_stop_rgb(0.2, 1, 1, 0)
114             gradient.add_color_stop_rgb(1, 0, 1, 0)
115             cairo_ctx.set_source(gradient)
116         cairo_ctx.rectangle(x, self.height * (1 - value), width, self.height * value)
117         cairo_ctx.fill()
118
119     def set_scale(self, scale):
120         self.scale = scale
121         self.cache_surface = None
122         self.invalidate_all()
123
124 class MonoMeterWidget(MeterWidget):
125     def __init__(self, scale):
126         MeterWidget.__init__(self, scale)
127         self.value = 0.0
128         self.raw_value = 0.0
129
130     def draw(self, widget, cairo_ctx):
131         self.draw_background(cairo_ctx)
132         self.draw_value(cairo_ctx, self.value, self.width/4.0, self.width/2.0)
133
134     def set_value(self, value):
135         if value != self.raw_value:
136             self.raw_value = value
137             self.value = self.scale.db_to_scale(value)
138             self.invalidate_all()
139         if value == self.raw_value:
140             return
141         self.raw_value = value
142         old_value = self.value
143         self.value = self.scale.db_to_scale(value)
144         if (abs(old_value-self.value) * self.height) > 1:
145             self.invalidate_all()
146
147 class StereoMeterWidget(MeterWidget):
148     def __init__(self, scale):
149         MeterWidget.__init__(self, scale)
150         self.left = 0.0
151         self.right = 0.0
152
153         self.raw_left = 0.0
154         self.raw_right = 0.0
155
156     def draw(self, widget, cairo_ctx):
157         self.draw_background(cairo_ctx)
158         self.draw_value(cairo_ctx, self.left, self.width/5.0, self.width/5.0)
159         self.draw_value(cairo_ctx, self.right, self.width/5.0 * 3.0, self.width/5.0)
160
161     def set_values(self, left, right):
162         if left == self.raw_left and right == self.raw_right:
163             return
164         self.raw_left = left
165         self.raw_right = right
166         old_left = self.left
167         old_right = self.right
168         self.left = self.scale.db_to_scale(left)
169         self.right = self.scale.db_to_scale(right)
170         if (abs(old_left-self.left) * self.height) > 0.01 or (abs(old_right-self.right) * self.height) > 0.01:
171             self.invalidate_all()