# GNU Solfege - free ear training software # Copyright (C) 2000, 2001, 2002, 2003, 2004, 2007 Tom Cato Amundsen # # 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 # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin ST, Fifth Floor, Boston, MA 02110-1301 USA import gtk import gobject import mpd import cfg DELAY1 = 500 DELAY2 = 50 class NotenameSpinButton(gtk.HBox): def __init__(self, default_value): gtk.HBox.__init__(self) self.m_value = mpd.notename_to_int(default_value) self.g_label = gtk.Label(mpd.int_to_user_notename(self.m_value)) self.g_label.set_use_markup(1) frame = gtk.Frame() e = gtk.EventBox() frame.add(e) self.pack_start(frame, False) self.g_label.set_size_request(60, -1)#FIXME hardcoded value frame.set_shadow_type(gtk.SHADOW_IN) e.add(self.g_label) vbox = gtk.VBox() self.pack_start(vbox, False) # up self.g_up = gtk.Arrow(gtk.ARROW_UP, gtk.SHADOW_OUT) eb1 = gtk.EventBox() eb1.connect('button-press-event', self.on_up_press) eb1.connect('button-release-event', self.on_up_release) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) frame.add(self.g_up) eb1.add(frame) vbox.pack_start(eb1) # down self.g_down = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_ETCHED_IN) eb2 = gtk.EventBox() eb2.connect('button-press-event', self.on_down_press) eb2.connect('button-release-event', self.on_down_release) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) frame.add(self.g_down) eb2.add(frame) vbox.pack_start(eb2) self.m_timeout = None def on_up_press(self, eb, ev): if self.m_timeout: gobject.source_remove(self.m_timeout) self.m_timeout = None if ev.type == gtk.gdk.BUTTON_PRESS: if self.m_value < 127: self.up() if self.m_value < 127: self.m_timeout = gobject.timeout_add(DELAY1, self.on_up_timeout) def on_up_release(self, eb, ev): if self.m_timeout: gobject.source_remove(self.m_timeout) self.m_timeout = None def on_up_timeout(self, *v): if self.m_value < 127: self.up() self.m_timeout = gobject.timeout_add(DELAY2, self.on_up_timeout) def up(self): self.m_value += 1 self.g_label.set_text(mpd.int_to_user_notename(self.m_value)) self.g_label.set_use_markup(1) self.emit('value-changed', self.m_value) def on_down_press(self, eb, ev): if self.m_timeout: gobject.source_remove(self.m_timeout) self.m_timeout = None if ev.type == gtk.gdk.BUTTON_PRESS: if self.m_value > 0: self.down() if self.m_value > 0: self.m_timeout = gobject.timeout_add(DELAY1, self.on_down_timeout) def on_down_release(self, eb, ev): if self.m_timeout: gobject.source_remove(self.m_timeout) self.m_timeout = None def on_down_timeout(self, *v): if self.m_value > 0: self.down() self.m_timeout = gobject.timeout_add(DELAY2, self.on_down_timeout) def down(self): self.m_value -= 1 self.g_label.set_text(mpd.int_to_user_notename(self.m_value)) self.g_label.set_use_markup(1) self.emit('value-changed', self.m_value) def get_value(self): return self.m_value def set_value(self, val): self.m_value = val self.g_label.set_text(mpd.int_to_user_notename(val)) self.g_label.set_use_markup(1) gobject.signal_new('value-changed', NotenameSpinButton, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) class NotenameRangeController(object): def __init__(self, spin_low, spin_high, lowest_value, highest_value): self.g_spin_low = spin_low self.g_spin_low.connect('value-changed', self.on_low_changed) self.g_spin_high = spin_high self.g_spin_high.connect('value-changed', self.on_high_changed) self.m_lowest_value = mpd.notename_to_int(lowest_value) self.m_highest_value = mpd.notename_to_int(highest_value) def on_low_changed(self, widget, v): if widget.get_value() > self.g_spin_high.get_value(): self.g_spin_low.set_value(self.g_spin_high.get_value()) elif widget.get_value() < self.m_lowest_value: self.g_spin_low.set_value(self.m_lowest_value) def on_high_changed(self, widget, v): if widget.get_value() < self.g_spin_low.get_value(): self.g_spin_high.set_value(self.g_spin_low.get_value()) elif widget.get_value() > self.m_highest_value: self.g_spin_high.set_value(self.m_highest_value) class nNotenameRangeController(NotenameRangeController, cfg.ConfigUtils): def __init__(self, spin_low, spin_high, lowest_value, highest_value, exname, name_low, name_high): NotenameRangeController.__init__(self, spin_low, spin_high, lowest_value, highest_value) cfg.ConfigUtils.__init__(self, exname) self.m_name_low = name_low self.m_name_high = name_high low = mpd.notename_to_int(self.get_string(self.m_name_low)) high = mpd.notename_to_int(self.get_string(self.m_name_high)) if low > high: low = high self.g_spin_low.set_value(low) self.g_spin_high.set_value(high) def on_low_changed(self, w, v): NotenameRangeController.on_low_changed(self, w, v) self.set_string(self.m_name_low, mpd.int_to_notename(self.g_spin_low.get_value())) def on_high_changed(self, w, v): NotenameRangeController.on_high_changed(self, w, v) self.set_string(self.m_name_high, mpd.int_to_notename(self.g_spin_high.get_value())) def set_range(self, lowest_value, highest_value): """ Set the lowest and highest tone allowed. make a separate function for NotenameRangeController if we need it. """ assert mpd.compare_notenames(lowest_value, highest_value) <= 0 self.m_lowest_value = mpd.notename_to_int(lowest_value) self.m_highest_value = mpd.notename_to_int(highest_value) if self.m_lowest_value > self.g_spin_low.get_value(): self.set_string(self.m_name_low, lowest_value) self.g_spin_low.set_value(self.m_lowest_value) if self.m_highest_value < self.g_spin_high.get_value(): self.set_string(self.m_name_high, highest_value) self.g_spin_high.set_value(self.m_highest_value)