Esempio n. 1
0
 def refresh_pad(self, pad, force=False):
     if pad >= libseq.getSequencesInBank(self.parent.bank):
         return
     cell = self.grid_canvas.find_withtag("pad:%d" % (pad))
     if cell:
         if force or libseq.hasSequenceChanged(self.parent.bank, pad):
             mode = libseq.getPlayMode(self.parent.bank, pad)
             state = libseq.getPlayState(self.parent.bank, pad)
             if state == zynthian_gui_stepsequencer.SEQ_RESTARTING:
                 state = zynthian_gui_stepsequencer.SEQ_PLAYING
             group = libseq.getGroup(self.parent.bank, pad)
             foreground = "white"
             if libseq.getSequenceLength(
                     self.parent.bank, pad
             ) == 0 or mode == zynthian_gui_stepsequencer.SEQ_DISABLED:
                 self.grid_canvas.itemconfig(
                     cell,
                     fill=zynthian_gui_stepsequencer.PAD_COLOUR_DISABLED)
             else:
                 self.grid_canvas.itemconfig(
                     cell,
                     fill=zynthian_gui_stepsequencer.PAD_COLOUR_STOPPED[
                         group % 16])
             pad_x = (pad % self.columns) * self.column_width
             pad_y = int(pad / self.columns) * self.row_height
             if libseq.getSequenceLength(self.parent.bank, pad) == 0:
                 mode = 0
             self.grid_canvas.itemconfig("lbl_pad:%d" % (pad),
                                         text="%s%d" %
                                         (chr(65 + group), pad + 1),
                                         fill=foreground)
             self.grid_canvas.itemconfig("mode:%d" % pad,
                                         image=self.mode_icon[mode])
             self.grid_canvas.itemconfig("state:%d" % pad,
                                         image=self.state_icon[state])
    def draw_sequence_label(self, row):
        if row >= self.vertical_zoom:
            return
        self.sequence_title_canvas.delete('rowtitle:%d' % (row))
        self.sequence_title_canvas.delete('rowback:%d' % (row))

        if row + self.row_offset > len(self.sequence_tracks):
            return
        sequence = self.sequence_tracks[row + self.row_offset][0]
        track = self.sequence_tracks[row + self.row_offset][1]
        group = libseq.getGroup(self.parent.bank, sequence)
        fill = zynthian_gui_stepsequencer.PAD_COLOUR_STOPPED[group % 16]
        font = tkFont.Font(family=zynthian_gui_config.font_topbar[0],
                           size=self.fontsize)
        channel = libseq.getChannel(self.parent.bank, sequence, track)
        if channel < 16 and self.parent.layers[channel]:
            track_name = self.parent.layers[channel].preset_name
        else:
            track_name = ""

        self.sequence_title_canvas.create_rectangle(
            0,
            self.row_height * row + 1,
            self.seq_track_title_width, (1 + row) * self.row_height - 1,
            tags=('rowback:%d' % (row), 'sequence_title'),
            fill=fill)
        if track == 0 or row == 0:
            # Create sequence title label from first visible track of sequence
            self.sequence_title_canvas.create_text(
                (0, self.row_height * row + 1),
                font=font,
                fill=CELL_FOREGROUND,
                tags=("rowtitle:%d" % (row), "sequence_title"),
                anchor="nw",
                text="%s%d" % (chr(65 + group), sequence + 1))
        self.sequence_title_canvas.create_text(
            (self.seq_track_title_width - 2, self.row_height * row + 1),
            font=font,
            fill=CELL_FOREGROUND,
            tags=("rowtitle:%d" % (row), "sequence_title"),
            anchor="ne",
            text="%d" % (track + 1))
        self.sequence_title_canvas.create_text(
            (0, self.row_height * (row + 1) - 1),
            font=tkFont.Font(family=zynthian_gui_config.font_topbar[0],
                             size=int(self.fontsize * 0.9)),
            fill=CELL_FOREGROUND,
            tags=("rowtitle:%d" % (row), "sequence_title"),
            anchor="sw",
            text="%s" % (track_name))
        self.sequence_title_canvas.tag_bind('sequence_title', "<Button-1>",
                                            self.on_sequence_click)
Esempio n. 3
0
 def do_grid_size(self, params=None):
     # To avoid odd behaviour we stop all sequences from playing before changing grid size (blunt but effective!)
     bank = self.parent.bank
     for seq in range(libseq.getSequencesInBank(bank)):
         libseq.setPlayState(bank, seq,
                             zynthian_gui_stepsequencer.SEQ_STOPPED)
     channels = []
     groups = []
     for column in range(self.columns):
         channels.append(libseq.getChannel(bank, column * self.columns, 0))
         groups.append(libseq.getGroup(bank, column * self.columns))
     new_size = self.parent.get_param("Grid size", "value")
     delta = new_size - self.columns
     if delta > 0:
         # Growing grid so add extra sequences
         for column in range(self.columns):
             for row in range(self.columns, self.columns + delta):
                 pad = row + column * new_size
                 libseq.insertSequence(bank, pad)
                 libseq.setChannel(bank, pad, channels[column])
                 libseq.setGroup(bank, pad, groups[column])
                 zynseq.set_sequence_name(bank, pad, "%s" % (pad + 1))
         for column in range(self.columns, new_size):
             for row in range(new_size):
                 pad = row + column * new_size
                 libseq.insertSequence(bank, pad)
                 libseq.setChannel(bank, pad, column)
                 libseq.setGroup(bank, pad, column)
                 zynseq.set_sequence_name(bank, pad, "%s" % (pad + 1))
     if delta < 0:
         # Shrinking grid so remove excess sequences
         libseq.setSequencesInBank(bank, new_size *
                                   self.columns)  # Lose excess columns
         for offset in range(new_size, new_size * new_size + 1, new_size):
             logging.warning("offset: %d", offset)
             for pad in range(-delta):
                 libseq.removeSequence(bank, offset)
     self.columns = new_size
     self.refresh_pending = 1
    def select_cell(self, time=None, row=None, snap=True):
        if time == None:
            time = self.selected_cell[0]
        if row == None:
            row = self.selected_cell[1]
        if row >= len(self.sequence_tracks):
            row = len(self.sequence_tracks) - 1
        if row < 0:
            row = 0
        duration = int(
            libseq.getPatternLength(self.pattern) / self.clocks_per_division)
        sequence = self.sequence_tracks[row][0]
        track = self.sequence_tracks[row][1]
        self.parent.set_title(
            "Bank %d %s%d-%d (%d) %s" %
            (self.parent.bank,
             chr(65 + libseq.getGroup(self.parent.bank, sequence)),
             sequence + 1, track + 1,
             libseq.getChannel(self.parent.bank, sequence, track) + 1,
             self.get_note(libseq.getTriggerNote(self.parent.bank, sequence))))
        if not duration:
            duration = 1
        forward = time > self.selected_cell[0]
        backward = None
        if time < self.selected_cell[0]:
            backward = time
        # Skip cells if pattern won't fit
        if snap:
            prev_start = 0
            prev_end = 0
            next_start = time
            for previous in range(time - 1, -1, -1):
                # Iterate time divs back to start
                prev_pattern = libseq.getPattern(
                    self.parent.bank, sequence, track,
                    previous * self.clocks_per_division)
                if prev_pattern == -1:
                    continue
                prev_duration = int(
                    libseq.getPatternLength(prev_pattern) /
                    self.clocks_per_division)
                prev_start = previous
                prev_end = prev_start + prev_duration
                break
            for next in range(time + 1, time + duration * 2):
                next_pattern = libseq.getPattern(
                    self.parent.bank, sequence, track,
                    next * self.clocks_per_division)
                if next_pattern == -1:
                    continue
                next_start = next
                break
            if next_start < prev_end:
                next_start = prev_end
            if time >= prev_end and time < next_start:
                # Between patterns
                if time + duration > next_start:
                    # Insufficient space for new pattern between pattern
                    if forward:
                        time = next_start
                    else:
                        if next_start - prev_end < duration:
                            time = prev_start
                        else:
                            time = next_start - duration
            elif time == prev_start:
                # At start of previous
                pass
            elif time > prev_start and time < prev_end:
                # Within pattern
                if forward:
                    if prev_end + duration > next_start:
                        time = next_start
                    else:
                        time = prev_end
                else:
                    time = prev_start
            if time == 0 and duration > next_start:
                time = next_start

        if time < 0:
            time = 0
        if time + duration > self.col_offset + self.horizontal_zoom:
            # time is off right of display
            self.col_offset = time + duration - self.horizontal_zoom
            self.redraw_pending = 1
        if time < self.col_offset:
            # time is off left of display
            self.col_offset = time
            self.redraw_pending = 1
        if row >= self.row_offset + self.vertical_zoom:
            # row is off bottom of display
            self.row_offset = row - self.vertical_zoom + 1
            self.redraw_pending = 1
        elif row < self.row_offset:
            self.row_offset = row
            self.redraw_pending = 1
        if backward != None and self.col_offset > 0 and time > backward:
            self.col_offset = self.col_offset - 1
            self.redraw_pending = 1
        self.selected_cell = [time, row]
        self.sequence = self.sequence_tracks[row][0]
        self.track = self.sequence_tracks[row][1]
        coord = self.get_cell_coord(time - self.col_offset,
                                    row - self.row_offset, duration)
        coord[0] = coord[0] - 1
        coord[1] = coord[1] - 1
        coord[2] = coord[2]
        coord[3] = coord[3]
        selection_border = self.grid_canvas.find_withtag("selection")
        if not selection_border:
            selection_border = self.grid_canvas.create_rectangle(
                coord,
                fill="",
                outline=SELECT_BORDER,
                width=self.select_thickness,
                tags="selection")
        else:
            self.grid_canvas.coords(selection_border, coord)
        self.grid_canvas.itemconfig(selection_border, state='normal')
        self.grid_canvas.tag_raise(selection_border)
        if row < self.row_offset:
            self.row_offset = row
            self.redraw_pending = 1
        if row > self.row_offset + self.vertical_zoom:
            self.row_offset = row + self.vertical_zoom
            self.redraw_pending = 1
 def get_group(self):
     return int(libseq.getGroup(self.parent.bank, self.sequence))
Esempio n. 6
0
 def get_group(self):
     return libseq.getGroup(self.parent.bank, self.selected_pad)