def update_selection_cursor(self): if self.selected_pad >= libseq.getSequencesInBank(self.parent.bank): self.selected_pad = libseq.getSequencesInBank(self.parent.bank) - 1 col = int(self.selected_pad / self.columns) row = self.selected_pad % self.columns self.grid_canvas.coords( self.selection, 1 + col * self.column_width, 1 + row * self.row_height, (1 + col) * self.column_width - self.select_thickness, (1 + row) * self.row_height - self.select_thickness) self.grid_canvas.tag_raise(self.selection)
def update_sequence_tracks(self): self.sequence_tracks.clear() for sequence in range(libseq.getSequencesInBank(self.parent.bank)): for track in range( libseq.getTracksInSequence(self.parent.bank, sequence)): self.sequence_tracks.append((sequence, track)) return len(self.sequence_tracks)
def on_zyncoder(self, encoder, value): if encoder == ENC_SELECT: # SELECT encoder adjusts horizontal pad selection pad = self.selected_pad + self.columns * value col = int(pad / self.columns) row = pad % self.columns if col >= self.columns: col = 0 row += 1 pad = row + self.columns * col elif pad < 0: col = self.columns - 1 row -= 1 pad = row + self.columns * col if row < 0 or row >= self.columns or col >= self.columns: return self.selected_pad = pad self.update_selection_cursor() elif encoder == ENC_BACK: # BACK encoder adjusts vertical pad selection pad = self.selected_pad + value if pad < 0 or pad >= libseq.getSequencesInBank(self.parent.bank): return self.selected_pad = pad self.update_selection_cursor()
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 on_sequence_drag_start(self, event): if self.parent.lst_menu.winfo_viewable(): self.parent.hide_menu() return if self.parent.param_editor_item: self.parent.show_param_editor(self.parent.param_editor_item) if libseq.getSequencesInBank(self.parent.bank) > self.vertical_zoom: self.sequence_drag_start = event
def set_grid_size(self): if libseq.getSequencesInBank(self.parent.bank) > self.parent.get_param( "Grid size", "value") * self.parent.get_param( "Grid size", "value"): self.zyngui.show_confirm( "Reducing the quantity of sequences in bank %d will delete sequences but patterns will still be available. Continue?" % (self.parent.bank), self.do_grid_size) else: self.do_grid_size()
def on_sequence_drag_motion(self, event): if not self.sequence_drag_start: return offset = int((event.y - self.sequence_drag_start.y) / self.row_height) if not offset: return self.sequence_drag_start.y = event.y pos = self.row_offset - offset if pos < 0: pos = 0 if pos + self.vertical_zoom >= libseq.getSequencesInBank( self.parent.bank): pos = libseq.getSequencesInBank( self.parent.bank) - self.vertical_zoom if self.row_offset == pos: return self.row_offset = pos self.redraw_pending = 1 sequence = self.selected_cell[1] if self.selected_cell[1] < self.row_offset: sequence = self.row_offset elif self.selected_cell[1] >= self.row_offset + self.vertical_zoom: sequence = self.row_offset + self.vertical_zoom - 1 self.select_cell(self.selected_cell[0], sequence)
def select_bank(self, bank): if bank > 0: if libseq.getSequencesInBank(bank) == 0: libseq.setSequencesInBank(bank, 16) for pad in range(4, 8): libseq.setChannel(bank, pad, 0, 1) libseq.setGroup(bank, pad, 1) for pad in range(8, 12): libseq.setChannel(bank, pad, 0, 2) libseq.setGroup(bank, pad, 2) for pad in range(12, 16): libseq.setChannel(bank, pad, 0, 9) libseq.setGroup(bank, pad, 9) self.bank = bank self.set_title("Bank %d" % bank) try: self.child.select_bank(bank) except: pass
def select_bank(self, bank): if bank > 0: if libseq.getSequencesInBank(bank) == 0: libseq.setSequencesInBank(bank, 16) for column in range(4): if column == 3: channel = 9 else: channel = column for row in range(4): pad = row + 4 * column zynseq.set_sequence_name( bank, pad, "%d" % (libseq.getPatternAt(bank, pad, 0, 0))) libseq.setGroup(bank, pad, channel) libseq.setChannel(bank, pad, 0, channel) self.bank = bank self.set_title("Bank %d" % bank) try: self.child.select_bank(bank) except: pass
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 get_seqeuences(self): return libseq.getSequencesInBank(self.parent.bank)
def get_columns(self): columns = int(sqrt(libseq.getSequencesInBank(self.parent.bank))) if columns < 0: columns = 1 return columns
def update_grid(self): self.refresh_pending = 0 self.grid_canvas.delete(tkinter.ALL) pads = libseq.getSequencesInBank(self.parent.bank) if pads < 1: return self.columns = int(sqrt(pads)) self.column_width = self.width / self.columns self.row_height = self.height / self.columns self.selection = self.grid_canvas.create_rectangle( 0, 0, self.column_width, self.row_height, fill="", outline=SELECT_BORDER, width=self.select_thickness, tags="selection") iconsize = (int(self.column_width * 0.6), int(self.row_height * 0.2)) img = (Image.open("/zynthian/zynthian-ui/icons/oneshot.png").resize( iconsize)) self.mode_icon[1] = ImageTk.PhotoImage(img) img = (Image.open("/zynthian/zynthian-ui/icons/loop.png").resize( iconsize)) self.mode_icon[2] = ImageTk.PhotoImage(img) img = (Image.open("/zynthian/zynthian-ui/icons/oneshotall.png").resize( iconsize)) self.mode_icon[3] = ImageTk.PhotoImage(img) img = (Image.open("/zynthian/zynthian-ui/icons/loopall.png").resize( iconsize)) self.mode_icon[4] = ImageTk.PhotoImage(img) img = (Image.open( "/zynthian/zynthian-ui/icons/oneshotsync.png").resize(iconsize)) self.mode_icon[5] = ImageTk.PhotoImage(img) img = (Image.open("/zynthian/zynthian-ui/icons/loopsync.png").resize( iconsize)) self.mode_icon[6] = ImageTk.PhotoImage(img) iconsize = (int(self.row_height * 0.2), int(self.row_height * 0.2)) img = (Image.open("/zynthian/zynthian-ui/icons/starting.png").resize( iconsize)) self.state_icon[ zynthian_gui_stepsequencer.SEQ_STARTING] = ImageTk.PhotoImage(img) img = (Image.open("/zynthian/zynthian-ui/icons/playing.png").resize( iconsize)) self.state_icon[ zynthian_gui_stepsequencer.SEQ_PLAYING] = ImageTk.PhotoImage(img) img = (Image.open("/zynthian/zynthian-ui/icons/stopping.png").resize( iconsize)) self.state_icon[ zynthian_gui_stepsequencer.SEQ_STOPPING] = ImageTk.PhotoImage(img) # Draw pads for pad in range(self.columns**2): pad_x = int(pad / self.columns) * self.column_width pad_y = pad % self.columns * self.row_height self.grid_canvas.create_rectangle(pad_x, pad_y, pad_x + self.column_width - 2, pad_y + self.row_height - 2, fill='grey', width=0, tags=("pad:%d" % (pad), "gridcell", "trigger_%d" % (pad))) self.grid_canvas.create_text( int(pad_x + self.column_width / 2), int(pad_y + 0.1 * self.row_height), anchor="n", font=tkFont.Font(family=zynthian_gui_config.font_topbar[0], size=int(self.row_height * 0.3)), fill=zynthian_gui_config.color_panel_tx, tags=("lbl_pad:%d" % (pad), "trigger_%d" % (pad))) self.grid_canvas.create_image(int(pad_x + self.column_width * 0.1), int(pad_y + 0.8 * self.row_height), tags=("mode:%d" % (pad), "trigger_%d" % (pad)), anchor="sw") self.grid_canvas.create_image(int(pad_x + self.column_width * 0.9), int(pad_y + 0.8 * self.row_height), tags=("state:%d" % (pad), "trigger_%d" % (pad)), anchor="se") self.grid_canvas.tag_bind("trigger_%d" % (pad), '<Button-1>', self.on_pad_press) self.grid_canvas.tag_bind("trigger_%d" % (pad), '<ButtonRelease-1>', self.on_pad_release) self.refresh_pad(pad, True) self.update_selection_cursor()