release: 12
[jack_mixer.git] / slider.py
blob836cfcd16c424046ae7519fc4163dbcf06a709e6
1 # This file is part of jack_mixer
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
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
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.
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.
18 from gi.repository import Gtk
19 from gi.repository import Gdk
20 from gi.repository import GObject
21 import cairo
23 class AdjustmentdBFS(Gtk.Adjustment):
24 def __init__(self, scale, default_db, step_inc):
25 self.default_value = scale.db_to_scale(default_db)
26 self.db = default_db
27 self.scale = scale
28 self.step_increment = step_inc
29 Gtk.Adjustment.__init__(self, self.default_value, 0.0, 1.0, 0.02)
30 self.connect("value-changed", self.on_value_changed)
31 self.disable_value_notify = False
33 def step_up(self):
34 self.set_value(self.get_value() + self.step_increment)
36 def step_down(self):
37 self.set_value(self.get_value() - self.step_increment)
39 def reset(self):
40 self.set_value(self.default_value)
42 def get_value_db(self):
43 return self.db
45 def set_value_db(self, db):
46 self.db = db
47 self.disable_value_notify = True
48 self.set_value(self.scale.db_to_scale(db))
49 self.disable_value_notify = False
50 self.emit("volume-changed")
52 def on_value_changed(self, adjustment):
53 if not self.disable_value_notify:
54 self.db = self.scale.scale_to_db(self.get_value())
55 self.emit("volume-changed")
57 def set_scale(self, scale):
58 self.scale = scale
59 self.disable_value_notify = True
60 self.set_value(self.scale.db_to_scale(self.db))
61 self.disable_value_notify = False
63 GObject.signal_new("volume-changed", AdjustmentdBFS,
64 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
67 class GtkSlider(Gtk.VScale):
68 def __init__(self, adjustment):
69 Gtk.VScale.__init__(self)#, adjustment)
70 self.set_adjustment(adjustment)
71 self.set_draw_value(False)
72 self.set_inverted(True)
74 # HACK: we want the behaviour you get with the middle button, so we
75 # mangle the events. Clicking with other buttons moves the slider in
76 # step increments, clicking with the middle button moves the slider
77 # to the location of the click.
78 self.connect('button-press-event', self.button_press_event)
79 self.connect('button-release-event', self.button_release_event)
81 def button_press_event(self, widget, event):
82 print("button press", event.button)
83 # event.button = 2
84 return False
86 def button_release_event(self, widget, event):
87 #event.button = 2
88 return False
91 class CustomSliderWidget(Gtk.DrawingArea):
92 def __init__(self, adjustment):
93 Gtk.DrawingArea.__init__(self)
95 self.adjustment = adjustment
97 self.connect("draw", self.on_expose)
98 self.connect("size_allocate", self.on_size_allocate)
99 adjustment.connect("value-changed", self.on_value_changed)
100 self.connect("button-press-event", self.on_mouse)
101 self.connect("motion-notify-event", self.on_mouse)
102 self.connect("scroll-event", self.on_scroll)
103 self.set_events(Gdk.EventMask.BUTTON1_MOTION_MASK |
104 Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
106 def on_scroll(self, widget, event):
107 delta = self.adjustment.step_increment
108 value = self.adjustment.get_value()
109 if event.direction == Gdk.ScrollDirection.UP:
110 y = value + delta
111 elif event.direction == Gdk.ScrollDirection.DOWN:
112 y = value - delta
113 if y >= 1:
114 y = 1
115 elif y <= 0:
116 y = 0
117 self.adjustment.set_value(y)
118 return True
120 def on_mouse(self, widget, event):
121 if event.type == Gdk.EventType.BUTTON_PRESS:
122 #print "mouse button %u pressed %u:%u" % (event.button, event.x, event.y)
123 if event.button == 1:
124 if event.y >= self.slider_rail_up and event.y < self.slider_rail_up + self.slider_rail_height:
125 self.adjustment.set_value(1 - float(event.y - self.slider_rail_up)/float(self.slider_rail_height))
126 elif event.type == Gdk.EventType.MOTION_NOTIFY:
127 #print "mouse motion %u:%u" % (event.x, event.y)
128 if event.y < self.slider_rail_up:
129 y = self.slider_rail_up
130 elif event.y > self.slider_rail_up + self.slider_rail_height:
131 y = self.slider_rail_up + self.slider_rail_height
132 else:
133 y = event.y
134 self.adjustment.set_value(1 - float(y - self.slider_rail_up)/float(self.slider_rail_height))
136 return False
138 def on_value_changed(self, adjustment):
139 self.invalidate_all()
141 def on_expose(self, widget, cairo_ctx):
143 self.draw(cairo_ctx)
145 return False
147 def get_preferred_width(self, widget):
148 minimal_width = natural_width = self.width
149 return (minimal_width, natural_width)
151 def get_preferred_height(self, widget):
152 requisition = Gtk.Requisition()
153 on_size_request(self, widget, requisition)
154 minimal_height = natural_heigt = requisition.height
155 return (minimal_height, natural_height)
158 def on_size_allocate(self, widget, allocation):
159 self.width = float(allocation.width)
160 self.height = float(allocation.height)
161 self.font_size = 10
163 def on_size_request(self, widget, requisition):
164 #print "size-request, %u x %u" % (requisition.width, requisition.height)
165 requisition.width = 20
166 return
168 def invalidate_all(self):
169 self.queue_draw_area(0, 0, int(self.width), int(self.height))
171 def draw(self, cairo_ctx):
172 if self.has_focus():
173 state = Gtk.StateType.PRELIGHT
174 else:
175 state = Gtk.StateType.NORMAL
177 #cairo_ctx.rectangle(0, 0, self.width, self.height)
178 #cairo_ctx.set_source_color(self.style.bg[state])
179 #cairo_ctx.fill_preserve()
180 #Gdk.cairo_set_source_color(cairo_ctx,
181 # self.get_style_context().get_color(state).to_color())
182 #cairo_ctx.stroke()
184 slider_knob_width = self.width * 3 / 4
185 slider_knob_height = self.width * 3 / 2
186 slider_knob_height -= slider_knob_height % 2
187 slider_knob_height += 1
189 slider_x = self.width/2
191 cairo_ctx.set_line_width(1)
193 # slider rail
194 Gdk.cairo_set_source_color(cairo_ctx,
195 self.get_style_context().get_color(state).to_color())
196 self.slider_rail_up = slider_knob_height/2 + (self.width - slider_knob_width)/2
197 self.slider_rail_height = self.height - 2 * self.slider_rail_up
198 cairo_ctx.move_to(slider_x, self.slider_rail_up)
199 cairo_ctx.line_to(slider_x, self.slider_rail_height + self.slider_rail_up)
200 cairo_ctx.stroke()
202 # slider knob
203 slider_y = round(self.slider_rail_up + self.slider_rail_height * (1 - self.adjustment.get_value()))
204 lg = cairo.LinearGradient(slider_x -
205 float(slider_knob_width)/2, slider_y - slider_knob_height/2,
206 slider_x - float(slider_knob_width)/2, slider_y +
207 slider_knob_height/2)
208 slider_alpha = 1.0
209 lg.add_color_stop_rgba(0, 0.55, 0.55, 0.55, slider_alpha)
210 lg.add_color_stop_rgba(0.1, 0.65, 0.65, 0.65, slider_alpha)
211 lg.add_color_stop_rgba(0.1, 0.75, 0.75, 0.75, slider_alpha)
212 lg.add_color_stop_rgba(0.125, 0.75, 0.75, 0.75, slider_alpha)
213 lg.add_color_stop_rgba(0.125, 0.15, 0.15, 0.15, slider_alpha)
214 lg.add_color_stop_rgba(0.475, 0.35, 0.35, 0.35, slider_alpha)
215 lg.add_color_stop_rgba(0.475, 0, 0, 0, slider_alpha)
216 lg.add_color_stop_rgba(0.525, 0, 0, 0, slider_alpha)
217 lg.add_color_stop_rgba(0.525, 0.35, 0.35, 0.35, slider_alpha)
218 lg.add_color_stop_rgba(0.875, 0.65, 0.65, 0.65, slider_alpha)
219 lg.add_color_stop_rgba(0.875, 0.75, 0.75, 0.75, slider_alpha)
220 lg.add_color_stop_rgba(0.900, 0.75, 0.75, 0.75, slider_alpha)
221 lg.add_color_stop_rgba(0.900, 0.15, 0.15, 0.15, slider_alpha)
222 lg.add_color_stop_rgba(1.000, 0.10, 0.10, 0.10, slider_alpha)
223 cairo_ctx.rectangle(slider_x - float(slider_knob_width)/2,
224 slider_y - slider_knob_height/2,
225 float(slider_knob_width),
226 slider_knob_height)
227 Gdk.cairo_set_source_color(cairo_ctx,
228 self.get_style_context().get_background_color(state).to_color())
229 cairo_ctx.fill_preserve()
230 cairo_ctx.set_source(lg)
231 cairo_ctx.fill()