Exemplo n.º 1
0
 def fill_skips(self, voice):
     """
     Add Skips at the end of the bar, so that it is filled.
     We assume that any elements already added are placed at
     the correct timepos.
     """
     # nt = short for "next timepos", the timepos to start fill skips to
     if voice.get_timeposes_of(self):
         nt = voice.get_timeposes_of(self)[-1]
         nt = nt + voice.m_tdict[nt]['elem'][0].m_duration.get_rat_value()
     else:
         # we get here if the bar is empty
         nt = self.m_timepos
     default_skip = Rat(1, 4)
     # pos within default skip
     pp =  nt - int (nt / default_skip) * default_skip
     if pp != Rat(0, 1):
         # Here we add a skip so that the next column will be X times
         # default_skip
         voice.set_elem([Skip(Duration.new_from_rat(default_skip - pp))],
                       nt)
         nt += (default_skip - pp)
     # And the we fill the bar with Skips as long as default_skip.
     while nt < self.end():
         voice.set_elem([Skip(Duration.new_from_rat(default_skip))], nt)
         nt += default_skip
Exemplo n.º 2
0
 def fill_skips(self, voice):
     """
     Add Skips at the end of the bar, so that it is filled.
     We assume that any elements already added are placed at
     the correct timepos.
     """
     # nt = short for "next timepos", the timepos to start fill skips to
     if voice.get_timeposes_of(self):
         nt = voice.get_timeposes_of(self)[-1]
         nt = nt + voice.m_tdict[nt]['elem'][0].m_duration.get_rat_value()
     else:
         # we get here if the bar is empty
         nt = self.m_timepos
     default_skip = Rat(1, 4)
     # pos within default skip
     pp = nt - int(nt / default_skip) * default_skip
     if pp != Rat(0, 1):
         # Here we add a skip so that the next column will be X times
         # default_skip
         voice.set_elem([Skip(Duration.new_from_rat(default_skip - pp))],
                        nt)
         nt += (default_skip - pp)
     # And the we fill the bar with Skips as long as default_skip.
     while nt < self.end():
         voice.set_elem([Skip(Duration.new_from_rat(default_skip))], nt)
         nt += default_skip
Exemplo n.º 3
0
 def f(widget, i):
     added = self.g_rwidget.on_add_item(elems.Rest(Duration(i, 0)))
     if self.g_add_dots_toggle.get_active():
         self.g_rwidget.on_toggle_dots(1)
     if added:
         self.g_rwidget.cursor_next()
     self.g_rwidget.grab_focus()
     self.g_rwidget.score_updated()
Exemplo n.º 4
0
 def on_key_press(self, window, event):
     if not self.m_editable:
         return
     key_dict = {
         Gdk.KEY_1: 1,
         Gdk.KEY_2: 2,
         Gdk.KEY_3: 4,
         Gdk.KEY_4: 8,
         Gdk.KEY_5: 16,
         Gdk.KEY_6: 32,
     }
     if event.keyval in (Gdk.KEY_Right, Gdk.KEY_KP_Right):
         self.cursor_next()
         self.queue_draw()
     elif event.keyval in (Gdk.KEY_Left, Gdk.KEY_KP_Left):
         self.cursor_prev()
         self.queue_draw()
     elif event.keyval == Gdk.KEY_BackSpace:
         self.backspace()
     elif event.keyval in (Gdk.KEY_Delete, Gdk.KEY_KP_Delete):
         self.delete()
     elif event.keyval in key_dict:
         if self.m_input_mode == self.NOTE_INPUT:
             added = self.on_add_item(
                 elems.Note(MusicalPitch.new_from_notename("c"),
                            Duration(key_dict[event.keyval], 0)))
         else:
             assert self.m_input_mode == self.REST_INPUT
             added = self.on_add_item(
                 elems.Rest(Duration(key_dict[event.keyval], 0)))
         if added:
             self.cursor_next()
         self.queue_draw()
         self.grab_focus()
     elif event.keyval == Gdk.KEY_period:
         self.on_toggle_dots(1)
     elif event.keyval == Gdk.KEY_colon:
         self.on_toggle_dots(-1)
     elif event.keyval == Gdk.KEY_t:
         self.on_toggle_tie()
     elif event.keyval == Gdk.KEY_r:
         if self.m_input_mode == self.NOTE_INPUT:
             self.m_input_mode = self.REST_INPUT
         else:
             self.m_input_mode = self.NOTE_INPUT
Exemplo n.º 5
0
 def f(widget, i):
     added = self.g_rwidget.on_add_item(elems.Note(
         MusicalPitch.new_from_notename("c"),
         Duration(i, 0)))
     if self.g_add_dots_toggle.get_active():
         self.g_rwidget.on_toggle_dots(1)
     if added:
         self.g_rwidget.cursor_next()
     self.g_rwidget.grab_focus()
Exemplo n.º 6
0
 def new_from_string(string):
     s = string.strip()
     m = re_melodic.match(s)
     if m.end() < len(s) - 1:
         # FIXME: raise ValueError like rest
         raise Note.Exception("characters left in string", string)
     return Note(
         MusicalPitch.new_from_notename("%s%s" % (m.group('notename'),
                                                  m.group('octave'))),
         Duration.new_from_string("%s%s" % (m.group('len'), m.group('dots')))
     )
Exemplo n.º 7
0
 def new_from_string(string):
     s = string.strip()
     m = re_melodic.match(s)
     if m.end() < len(s) - 1:
         # FIXME: raise ValueError like rest
         raise Note.Exception("characters left in string", string)
     return Note(
         MusicalPitch.new_from_notename(
             "%s%s" % (m.group('notename'), m.group('octave'))),
         Duration.new_from_string("%s%s" %
                                  (m.group('len'), m.group('dots'))))
Exemplo n.º 8
0
 def new_from_string(string):
     return Skip(Duration.new_from_string(string))
Exemplo n.º 9
0
 def new_from_string(string):
     return Rest(Duration.new_from_string(string))
Exemplo n.º 10
0
 def new_from_string(string):
     return Skip(Duration.new_from_string(string))
Exemplo n.º 11
0
 def new_from_string(string):
     return Rest(Duration.new_from_string(string))
Exemplo n.º 12
0
class RhythmWidget(MusicDisplayer):
    """
    Rhythm widget editor.
    Before editing, we feed it a Score objects with notes and/or
    skips. The user is not allowed to add skips in the middle of
    the rhythm. Only rests.
    """
    skipdur = Duration(4, 0)
    NOTE_INPUT = 1
    REST_INPUT = 2
    def __init__(self):
        MusicDisplayer.__init__(self)
        self.g_d.connect("expose_event", self.on_draw_cursor)
        self.add_events(gtk.gdk.KEY_RELEASE_MASK)
        self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.connect("key-press-event", self.on_key_press)
        self.set_flags(gtk.CAN_FOCUS)
        def f(*w):
            self.grab_focus()
        self.connect("button-press-event", f)
        self.m_cursor = None
        self.m_input_mode = RhythmWidget.NOTE_INPUT
    def get_cursor_timepos(self):
        """
        Return the timepos the cursor has. Return None if the
        cursor is not visible, for example when the staff is completely
        empty.
        """
        if self.m_cursor is None:
            return
        if not self.m_score.m_staffs:
            return None
        timeposes = self.m_score.m_staffs[0].get_timeposes()
        if timeposes:
            return self.m_score.m_staffs[0].get_timeposes()[self.m_cursor]
        return
    def cursor_prev(self):
        if self.m_cursor > 0:
            self.m_cursor -= 1
            self.adjust_hadjustment()
            self.emit('cursor-moved')
    def cursor_next(self):
        if self.m_cursor < len(self.m_score.m_staffs[0].get_timeposes()) - 1:
            self.m_cursor += 1
            self.adjust_hadjustment()
            self.emit('cursor-moved')
    def backspace(self):
        if self.m_cursor > 0:
            self.cursor_prev()
            self.delete()
            self.adjust_hadjustment()
            self.emit('cursor-moved')
    def on_key_press(self, window, event):
        if not self.m_editable:
            return
        key_dict = {gtk.keysyms._1: 1,
                    gtk.keysyms._2: 2,
                    gtk.keysyms._3: 4,
                    gtk.keysyms._4: 8,
                    gtk.keysyms._5: 16,
                    gtk.keysyms._6: 32,
        }
        if event.keyval in (gtk.keysyms.Right, gtk.keysyms.KP_Right):
            self.cursor_next()
            self.queue_draw()
        elif event.keyval in (gtk.keysyms.Left, gtk.keysyms.KP_Left):
            self.cursor_prev()
            self.queue_draw()
        elif event.keyval == gtk.keysyms.BackSpace:
            self.backspace()
        elif event.keyval in (gtk.keysyms.Delete, gtk.keysyms.KP_Delete):
            self.delete()
        elif event.keyval in key_dict:
            if self.m_input_mode == self.NOTE_INPUT:
                added = self.on_add_item(elems.Note(MusicalPitch.new_from_notename("c"),
                    Duration(key_dict[event.keyval], 0)))
            else:
                assert self.m_input_mode == self.REST_INPUT
                added = self.on_add_item(elems.Rest(
                    Duration(key_dict[event.keyval], 0)))
            if added:
                self.cursor_next()
            self.queue_draw()
            self.grab_focus()
        elif event.keyval == gtk.keysyms.period:
            self.on_toggle_dots(1)
        elif event.keyval == gtk.keysyms.colon:
            self.on_toggle_dots(-1)
        elif event.keyval == gtk.keysyms.t:
            self.on_toggle_tie()
        elif event.keyval == gtk.keysyms.r:
            if self.m_input_mode == self.NOTE_INPUT:
                self.m_input_mode = self.REST_INPUT
            else:
                self.m_input_mode = self.NOTE_INPUT
    def on_toggle_tie(self):
        timepos = self.get_cursor_timepos()
        if not isinstance(self.m_score.voice11.m_tdict[timepos]['elem'][0], elems.Note):
            return
        if self.m_score.voice11.m_tdict[timepos]['elem'][0].m_tieinfo in (None, 'end'):
            if self.m_score.voice11.tie_timepos(timepos):
                self.score_updated()
        elif self.m_score.voice11.m_tdict[timepos]['elem'][0].m_tieinfo in ('start', 'go'):
            if self.m_score.voice11.untie_next(timepos):
                self.score_updated()
    def delete(self):
        timepos = self.get_cursor_timepos()
        self.m_score.voice11.del_elem(timepos)
        self.score_updated()
    def on_toggle_dots(self, delta):
        """
        delta is the number of dots to add or remove.
        Return True if the number of dots was changed.
        Return False if not allowed.
        """
        timepos = self.get_cursor_timepos()
        elem = self.m_score.voice11.m_tdict[timepos]['elem'][0]
        if isinstance(elem, elems.Skip):
            return False
        if elem.m_duration.m_dots + delta < 0:
            return False
        new_elem = copy.deepcopy(self.m_score.voice11.m_tdict[timepos]['elem'][0])
        new_elem.m_duration.m_dots += delta
        if self.m_score.voice11.try_set_elem(new_elem, timepos, False):
            self.score_updated()
        return True
    def on_add_item(self, item):
        """
        Return True if an item was added.
        Return False if it was not added.
        """
        if self.m_score.voice11.try_set_elem(item, self.get_cursor_timepos(),
                self.m_ins_mode):
            self.score_updated()
            self.adjust_hadjustment()
            return True
        return False
    def set_score(self, score, cursor=0):
        self.m_score = score
        self.m_cursor = cursor
        self.score_updated()
    def score_updated(self):
        """
        Redraw the staff. This should be called whenever m_score is updated.
        It is not necessary to call when only the cursor have been moved.
        """
        self.m_scorecontext = engravers.ScoreContext(self.m_score)
        self.m_engravers = self.m_scorecontext.m_contexts
        self._display()
        if self.m_score.m_staffs:
            timeposes = self.m_score.m_staffs[0].get_timeposes()
            if self.m_cursor > len(timeposes) - 1:
                self.m_cursor = len(timeposes) - 1
        else:
            self.m_cursor = None
        self.emit('score-updated')
    def on_draw_cursor(self, darea, event):
        timepos = self.get_cursor_timepos()
        if not timepos:
            return
        engraver = None
        for e in self.m_scorecontext.m_contexts[0].m_engravers[timepos]['elem']:
            if isinstance(e, (engravers.NoteheadEngraver,
                              engravers.RestEngraver,
                              engravers.SkipEngraver)):
                engraver = e
                break
        if not engraver:
            return
        red = self.window.get_colormap().alloc_color('#FF0000', True, True)
        red = self.window.new_gc(red)
        y = engravers.dim20.first_staff_ypos + 10
        self.m_cursor_xpos = engraver.m_xpos
        darea.window.draw_rectangle(red, True,
                     engraver.m_xpos, y, 10, 3)
    def adjust_hadjustment(self):
        # Auto scrolling
        adj = self.get_hadjustment()
        if self.m_cursor_xpos > adj.value + adj.page_size * 0.7:
            x = self.m_cursor_xpos - adj.page_size * 0.7
            if x > adj.upper - adj.page_size:
                x = adj.upper - adj.page_size
            adj.set_value(x)
        if self.m_cursor == 0:
            adj.set_value(0.0)
        if self.m_cursor_xpos < adj.value + adj.page_size * 0.3:
            x = self.m_cursor_xpos - adj.page_size * 0.3
            if x < 0:
                x = 0
            adj.set_value(x)