def show_text(ctx, x_part, pixels_from_top, text, height=20, font_color=definitions.WHITE, background_color=None, margin_left=4, font_size_percentage=0.8): assert 0 <= x_part < 8 assert type(x_part) == int display_w = push2_python.constants.DISPLAY_LINE_PIXELS display_h = push2_python.constants.DISPLAY_N_LINES part_w = display_w // 8 x1 = part_w * x_part y1 = pixels_from_top ctx.save() if background_color is not None: ctx.set_source_rgb(*definitions.get_color_rgb_float(background_color)) ctx.rectangle(x1, y1, part_w, y1 + height) ctx.fill() ctx.set_source_rgb(*definitions.get_color_rgb_float(font_color)) ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) font_size = round(int(height * font_size_percentage)) margin_top = (height - font_size) // 2 ctx.set_font_size(font_size) ctx.move_to(x1 + margin_left, y1 + font_size + margin_top - 2) ctx.show_text(text) ctx.restore()
def show_text(ctx, x_part, pixels_from_top, text, height=20, font_color=definitions.WHITE, background_color=None, margin_left=4, margin_top=4, font_size_percentage=0.8, center_vertically=True, center_horizontally=False, rectangle_padding=0): assert 0 <= x_part < 8 assert type(x_part) == int display_w = push2_python.constants.DISPLAY_LINE_PIXELS display_h = push2_python.constants.DISPLAY_N_LINES part_w = display_w // 8 x1 = part_w * x_part y1 = pixels_from_top ctx.save() if background_color is not None: ctx.set_source_rgb(*definitions.get_color_rgb_float(background_color)) ctx.rectangle(x1 + rectangle_padding, y1 + rectangle_padding, part_w - rectangle_padding * 2, height - rectangle_padding * 2) ctx.fill() ctx.set_source_rgb(*definitions.get_color_rgb_float(font_color)) ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) font_size = round(int(height * font_size_percentage)) text_lines = text.split('\n') n_lines = len(text_lines) if center_vertically: margin_top = (height - font_size * n_lines) // 2 ctx.set_font_size(font_size) for i, line in enumerate(text_lines): if center_horizontally: (_, _, l_width, _, _, _) = ctx.text_extents(line) ctx.move_to(x1 + part_w / 2 - l_width / 2, y1 + font_size * (i + 1) + margin_top - 2) else: ctx.move_to(x1 + margin_left, y1 + font_size * (i + 1) + margin_top - 2) ctx.show_text(line) ctx.restore()
def on_midi_push_connection_established(self): # Do initial configuration of Push print('Doing initial Push config...') # Force configure MIDI out (in case it wasn't...) app.push.configure_midi_out() # Configure custom color palette app.push.color_palette = {} for count, color_name in enumerate(definitions.COLORS_NAMES): app.push.set_color_palette_entry( count, [color_name, color_name], rgb=definitions.get_color_rgb_float(color_name), allow_overwrite=True) app.push.reapply_color_palette() # Initialize all buttons to black, initialize all pads to off app.push.buttons.set_all_buttons_color(color=definitions.BLACK) app.push.pads.set_all_pads_to_color(color=definitions.BLACK) # Iterate over modes and (re-)activate them for mode in self.active_modes: mode.activate() # Update buttons and pads (just in case something was missing!) app.update_push2_buttons() app.update_push2_pads()
def update_display(self, ctx, w, h): # Divide display in 8 parts to show different settings part_w = w // 8 part_h = h # Draw labels and values for i in range(0, 8): part_x = i * part_w part_y = 0 ctx.set_source_rgb(0, 0, 0) # Draw black background ctx.rectangle(part_x - 3, part_y, w, h) # do x -3 to add some margin between parts ctx.fill() color = [1.0, 1.0, 1.0] if self.current_page == 0: # Performance settings if i == 0: # Root note if not self.app.is_mode_active(self.app.melodic_mode): color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DISABLED) show_title(ctx, part_x, h, 'ROOT NOTE') show_value( ctx, part_x, h, "{0} ({1})".format( self.app.melodic_mode.note_number_to_name( self.app.melodic_mode.root_midi_note), self.app.melodic_mode.root_midi_note), color) elif i == 1: # Poly AT/channel AT show_title(ctx, part_x, h, 'AFTERTOUCH') show_value( ctx, part_x, h, 'polyAT' if self.app.melodic_mode.use_poly_at else 'channel', color) elif i == 2: # Channel AT range start if self.app.melodic_mode.last_time_at_params_edited is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) show_title(ctx, part_x, h, 'cAT START') show_value(ctx, part_x, h, self.app.melodic_mode.channel_at_range_start, color) elif i == 3: # Channel AT range end if self.app.melodic_mode.last_time_at_params_edited is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) show_title(ctx, part_x, h, 'cAT END') show_value(ctx, part_x, h, self.app.melodic_mode.channel_at_range_end, color) elif i == 4: # Poly AT range if self.app.melodic_mode.last_time_at_params_edited is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) show_title(ctx, part_x, h, 'pAT RANGE') show_value(ctx, part_x, h, self.app.melodic_mode.poly_at_max_range, color) elif i == 5: # Poly AT curve if self.app.melodic_mode.last_time_at_params_edited is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) show_title(ctx, part_x, h, 'pAT CURVE') show_value(ctx, part_x, h, self.app.melodic_mode.poly_at_curve_bending, color) elif self.current_page == 1: # MIDI settings if i == 0: # MIDI in device if self.app.midi_in_tmp_device_idx is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) if self.app.midi_in_tmp_device_idx < 0: name = "None" else: name = "{0} {1}".format( self.app.midi_in_tmp_device_idx + 1, self.app.available_midi_in_device_names[ self.app.midi_in_tmp_device_idx]) else: if self.app.midi_in is not None: name = "{0} {1}".format( self.app.available_midi_in_device_names.index( self.app.midi_in.name) + 1, self.app.midi_in.name) else: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DISABLED) name = "None" show_title(ctx, part_x, h, 'IN DEVICE') show_value(ctx, part_x, h, name, color) elif i == 1: # MIDI in channel if self.app.midi_in is None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DISABLED) show_title(ctx, part_x, h, 'IN CH') show_value( ctx, part_x, h, self.app.midi_in_channel + 1 if self.app.midi_in_channel > -1 else "All", color) elif i == 2: # MIDI out device if self.app.midi_out_tmp_device_idx is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) if self.app.midi_out_tmp_device_idx < 0: name = "None" else: name = "{0} {1}".format( self.app.midi_out_tmp_device_idx + 1, self.app.available_midi_out_device_names[ self.app.midi_out_tmp_device_idx]) else: if self.app.midi_out is not None: name = "{0} {1}".format( self.app.available_midi_out_device_names.index( self.app.midi_out.name) + 1, self.app.midi_out.name) else: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DISABLED) name = "None" show_title(ctx, part_x, h, 'OUT DEVICE') show_value(ctx, part_x, h, name, color) elif i == 3: # MIDI out channel if self.app.midi_out is None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DISABLED) show_title(ctx, part_x, h, 'OUT CH') show_value( ctx, part_x, h, self.app.midi_out_channel + 1 if self.app.midi_out_channel >= 0 else 'TR', color) elif i == 4: # Pyramidi out channel show_title(ctx, part_x, h, 'PYRAMIDI CH') show_value( ctx, part_x, h, self.app.track_selection_mode.pyramidi_channel + 1, color) elif i == 5: # Notes MIDI in device if self.app.notes_midi_in_tmp_device_idx is not None: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DELAYED_ACTIONS) if self.app.notes_midi_in_tmp_device_idx < 0: name = "None" else: name = "{0} {1}".format( self.app.notes_midi_in_tmp_device_idx + 1, self.app.available_midi_in_device_names[ self.app.notes_midi_in_tmp_device_idx]) else: if self.app.notes_midi_in is not None: name = "{0} {1}".format( self.app.available_midi_in_device_names.index( self.app.notes_midi_in.name) + 1, self.app.notes_midi_in.name) else: color = definitions.get_color_rgb_float( definitions.FONT_COLOR_DISABLED) name = "None" show_title(ctx, part_x, h, 'NOTES IN') show_value(ctx, part_x, h, name, color) elif i == 6: # Re-send MIDI connection established (to push, not MIDI in/out device) show_title(ctx, part_x, h, 'RESET MIDI') elif self.current_page == 2: # About if i == 0: # Save button show_title(ctx, part_x, h, 'SAVE') elif i == 1: # definitions.VERSION info show_title(ctx, part_x, h, 'VERSION') show_value(ctx, part_x, h, 'Pysha ' + definitions.VERSION, color) elif i == 2: # Software update show_title(ctx, part_x, h, 'SW UPDATE') if self.is_running_sw_update: show_value(ctx, part_x, h, 'Running... ', color) elif i == 3: # FPS indicator show_title(ctx, part_x, h, 'FPS') show_value(ctx, part_x, h, self.app.actual_frame_rate, color) # After drawing all labels and values, draw other stuff if required if self.current_page == 0: # Performance settings # Draw polyAT velocity curve ctx.set_source_rgb(0.6, 0.6, 0.6) ctx.set_line_width(1) data = self.app.melodic_mode.get_poly_at_curve() n = len(data) curve_x = 4 * part_w + 3 # Start x point of curve curve_y = part_h - 10 # Start y point of curve curve_height = 50 curve_length = part_w * 4 - 6 ctx.move_to(curve_x, curve_y) for i, value in enumerate(data): x = curve_x + i * curve_length / n y = curve_y - curve_height * value / 127 ctx.line_to(x, y) ctx.line_to(x, curve_y) ctx.fill() current_time = time.time() if current_time - self.app.melodic_mode.latest_channel_at_value[ 0] < 3 and not self.app.melodic_mode.use_poly_at: # Lastest channel AT value received less than 3 seconds ago draw_text_at( ctx, 3, part_h - 3, f'Latest cAT: {self.app.melodic_mode.latest_channel_at_value[1]}', font_size=20) if current_time - self.app.melodic_mode.latest_poly_at_value[ 0] < 3 and self.app.melodic_mode.use_poly_at: # Lastest channel AT value received less than 3 seconds ago draw_text_at( ctx, 3, part_h - 3, f'Latest pAT: {self.app.melodic_mode.latest_poly_at_value[1]}', font_size=20) if current_time - self.app.melodic_mode.latest_velocity_value[ 0] < 3: # Lastest note on velocity value received less than 3 seconds ago draw_text_at( ctx, 3, part_h - 26, f'Latest velocity: {self.app.melodic_mode.latest_velocity_value[1]}', font_size=20)
def draw(self, ctx, x_part): margin_top = 25 # Param name name_height = 20 show_text(ctx, x_part, margin_top, self.name, height=name_height, font_color=definitions.WHITE) # Param value val_height = 30 color = self.get_color_func() show_text(ctx, x_part, margin_top + name_height, str(self.value), height=val_height, font_color=color) # Knob ctx.save() circle_break_degrees = 80 height = 55 radius = height / 2 display_w = push2_python.constants.DISPLAY_LINE_PIXELS x = (display_w // 8) * x_part y = margin_top + name_height + val_height + radius + 5 start_rad = (90 + circle_break_degrees // 2) * (math.pi / 180) end_rad = (90 - circle_break_degrees // 2) * (math.pi / 180) xc = x + radius + 3 yc = y def get_rad_for_value(value): total_degrees = 360 - circle_break_degrees return start_rad + total_degrees * ( (value - self.vmin) / (self.vmax - self.vmin)) * (math.pi / 180) # This is needed to prevent showing line from previous position ctx.set_source_rgb(0, 0, 0) ctx.move_to(xc, yc) ctx.stroke() # Inner circle ctx.arc(xc, yc, radius, start_rad, end_rad) ctx.set_source_rgb( *definitions.get_color_rgb_float(definitions.GRAY_LIGHT)) ctx.set_line_width(1) ctx.stroke() # Outer circle ctx.arc(xc, yc, radius, start_rad, get_rad_for_value(self.value)) ctx.set_source_rgb(*definitions.get_color_rgb_float(color)) ctx.set_line_width(3) ctx.stroke() ctx.restore()
def get_current_track_color_rgb(self): return definitions.get_color_rgb_float(self.get_current_track_color())
def update_display(self, ctx, w, h): # START DRAWING # Divide display in 8 parts to show different settings part_w = w // 8 part_h = h # Draw labels and values for i in range(0, 8): part_x = i * part_w part_y = 0 ctx.set_source_rgb(0, 0, 0) # Draw black background ctx.rectangle(part_x - 3, part_y, w, h) # do x -3 to add some margin between parts ctx.fill() color = [1.0, 1.0, 1.0] if self.current_page == 0: # Performance settings if i == 0: # Root note if not self.app.is_mode_active(self.app.melodic_mode): color = definitions.get_color_rgb_float(definitions.FONT_COLOR_DISABLED) title = "ROOT NOTE:" center_x = 60 color = [1, 0.25, 0.5] draw_title(ctx, center_x, title, *color) show_value(ctx, part_x, h, "{0} ({1})".format(self.app.melodic_mode.note_number_to_name( self.app.melodic_mode.root_midi_note), self.app.melodic_mode.root_midi_note), color) elif i == 3: # MIDI out device if self.app.midi_out_tmp_device_idx is not None: color = definitions.get_color_rgb_float(definitions.FONT_COLOR_DELAYED_ACTIONS) if self.app.midi_out_tmp_device_idx < 0: name = "None" else: name = "{0} {1}".format(self.app.midi_out_tmp_device_idx + 1, self.app.available_midi_out_device_names[ self.app.midi_out_tmp_device_idx]) else: if self.app.midi_out is not None: name = "{0} {1}".format( self.app.available_midi_out_device_names.index(self.app.midi_out.name) + 1, self.app.midi_out.name) else: color = definitions.get_color_rgb_float(definitions.FONT_COLOR_DISABLED) name = "None" # if 'iConnectAUDIO2+ USB1' in name: # name = 'iCA2 USB1' # color = definitions.get_color_rgb_float(definitions.GREEN) # # if 'iConnectAUDIO2+ DIN' in name: # name = 'iCA2 DIN' # color = definitions.get_color_rgb_float(definitions.RED) center_x = 420 title = "MIDI OUT:" color = [1, 0.1, 1] draw_title(ctx, center_x, title, *color) show_value(ctx, part_x, h, name, color) # elif i == 4: # MIDI out channel # if self.app.midi_out is None: # color = definitions.get_color_rgb_float(definitions.FONT_COLOR_DISABLED) # show_title(ctx, part_x, h, 'OUT CH') # show_value(ctx, part_x, h, self.app.midi_out_channel + 1, color) elif i == 5: # Re-send MIDI connection established (to push, not MIDI in/out device) center_x = 780 title = "RESET MIDI:" color = [1, 0.1, 0.1] draw_title(ctx, center_x, title, *color) elif i == 6: center_x = 780 title = "REBOOT:" color = [1, 0.1, 0.1] draw_title(ctx, center_x, title, *color) elif i == 7: # definitions.VERSION info center_x = 900 title = "SAVE:" color = [0.1, 1, 0.1] draw_title(ctx, center_x, title, *color) show_value(ctx, part_x, h, 'Niklas Pysha ' + definitions.VERSION, color)