class Map: def __init__(self): self.width = 30 #int(settings.game_data['map_width']) self.height = 20 #int(settings.game_data['map_height']) self.seed = 42352336 self.water = 5 # int(settings.game_data['water_level']) self.max_diff = 1 self.canvas = Canvas() self.tile = generator.generate_map( width=self.width, height=self.height, seed=self.seed, water=self.water, max_diff=self.max_diff ) for x in range(self.width): for y in range(self.height): self.tile[x][y].map = self self.canvas.add(self.tile[x][y]) # real pixel dimensions self.real_x = 0 self.real_y = 0 self.real_w = 0 self.real_h = 0 def update_canvas(self, x, y, w, h): # gets maximal rectangle dimensions in pixels to contain canvas help_points_size = (self.width * 3 + 1, self.height * 2 + 1) if w / self.width > h / (self.height * numpy.sqrt(3)): # more padding on left and right uy = h // help_points_size[1] ux = int(uy // numpy.sqrt(3)) else: # more padding on top and bottom ux = w // help_points_size[0] uy = int(ux * numpy.sqrt(3)) + 1 self.real_x = (w - help_points_size[0] * ux) / 2 self.real_y = (h - help_points_size[1] * uy) / 2 self.real_w = help_points_size[0] * ux self.real_h = help_points_size[1] * uy for column in range(self.width): x = 3 * ux * column + self.real_x for row in range(self.height): y = uy * 2 * row + uy * ((column + 1) % 2) + uy - ux * 2 + self.real_y self.tile[column][row].set_pos_and_size(pos=(x, y), size=(ux * 4 - 2, ux * 4 - 2)) def click(self, position): tiles = [] for x in range(self.width): for y in range(self.height): if self.tile[x][y].contains(position): tiles.append(self.tile[x][y]) tile = util_get_closest_tile(tiles, position) if tile is not None: side = tile.get_side(position) print(f"{tile.grid_pos} {side}") tile.activate_line(side) else: print("Poza") def random_free_tile(self): x = random.randrange(0, self.width) y = random.randrange(0, self.height) while self.tile[x][y].depth != 0: x = random.randrange(0, self.width) y = random.randrange(0, self.height) return self.tile[x][y]
def __init__(self, app, music_player): """Create main GUI Arguments: parent -- parent application to this widget music_player -- audio generator for full application network -- network client and server handler """ # Initialize Tkinter, and instruct it hide root window self.tk_root = Tkinter.Tk() self.tk_root.withdraw() # Perform widget initializations super(GUI, self).__init__() # OVERALL STRUCTURE WINDOW_WIDTH = 800 WINDOW_HEIGHT = 600 OUTER_PADDING = 20 # Set default parameters to be used in accurately loading an # initial state to the GUI self.app = app self.music_player = music_player self.track_id = MusicPlayer.WAVETABLE_A self.popup_count = 0 # Turn off multi-touch in this GUI Config.set('input', 'mouse', 'mouse,disable_multitouch') # Determine image directory IMAGE_DIR = system.get_images_dir() # For dynamic GUI coloring self.TRACK_COLORS = [[.7, .4, .9, 1.0], [.6, .9, .4, 1.0], [.8, .5, .3, 1.0]] self.colorables = [] # Create widget for the main layout. This will be added separately # from each of our popup windows self.main_layout = NSWidget() self.add_widget(self.main_layout) # BUTTON GRID NOTE_BUTTON_WIDTH = 48 NOTE_BUTTON_HEIGHT = 48 NOTE_BUTTON_PADDING = 7 ROW_LABEL_WIDTH = 54 ROW_LABEL_HEIGHT = NOTE_BUTTON_HEIGHT ROW_LABEL_FONT_SIZE = 10 NOTE_BUTTON_ROWS = MusicPlayer.NUM_ROWS NOTE_BUTTON_COLS = MusicPlayer.NUM_COLS GRID_WIDTH = NOTE_BUTTON_PADDING + ROW_LABEL_WIDTH + \ NOTE_BUTTON_PADDING + (NOTE_BUTTON_COLS * (NOTE_BUTTON_WIDTH + NOTE_BUTTON_PADDING)) GRID_HEIGHT = NOTE_BUTTON_PADDING + (NOTE_BUTTON_ROWS * (NOTE_BUTTON_HEIGHT + NOTE_BUTTON_PADDING)) GRID_X = OUTER_PADDING GRID_Y = WINDOW_HEIGHT - OUTER_PADDING - GRID_HEIGHT PLAYHEAD_WIDTH = NOTE_BUTTON_WIDTH + 4 PLAYHEAD_HEIGHT = GRID_HEIGHT PLAYHEAD_OPACITY = .5 PLAYHEAD_COLOR = Color(1.0, 1.0, 1.0) # Playhead playhead_widget = Widget() playhead_canvas = Canvas() playhead_canvas.add(PLAYHEAD_COLOR) playhead = Rectangle(size=[PLAYHEAD_WIDTH, PLAYHEAD_HEIGHT]) playhead_canvas.add(playhead) playhead_canvas.opacity = PLAYHEAD_OPACITY playhead_widget.canvas = playhead_canvas self.main_layout.add_widget(playhead_widget) self.playhead = playhead # For each row, create labels and notes self.row_labels = [] self.note_buttons = [] row_top = GRID_Y + GRID_HEIGHT - NOTE_BUTTON_PADDING for row in range(0, NOTE_BUTTON_ROWS): col_x = GRID_X + NOTE_BUTTON_PADDING # Make label for row row_label = Label(text=str(row), width=ROW_LABEL_WIDTH, height=ROW_LABEL_HEIGHT, text_size=[ROW_LABEL_WIDTH, ROW_LABEL_HEIGHT], font_size=ROW_LABEL_FONT_SIZE, halign='center', valign='middle') row_label.x = col_x row_label.top = row_top self.main_layout.add_widget(row_label) self.row_labels.append(row_label) col_x = col_x + ROW_LABEL_WIDTH + NOTE_BUTTON_PADDING # Create all buttons for row row_notes = [] for col in range(0, NOTE_BUTTON_COLS): col_button = NSToggleButton(width=NOTE_BUTTON_WIDTH, height=NOTE_BUTTON_HEIGHT) col_button.id = 'row' + str(row) + ',col' + str(col) col_button.x = col_x col_button.top = row_top col_button.bind(on_press=self.trigger_note) row_notes.append(col_button) self.main_layout.add_widget(col_button) self.colorables.append(col_button) col_x = col_x + NOTE_BUTTON_WIDTH + NOTE_BUTTON_PADDING self.note_buttons.append(row_notes) row_top = row_top - NOTE_BUTTON_PADDING - NOTE_BUTTON_HEIGHT # Set playhead start position leftmost_note = self.note_buttons[0][0] playhead_x = leftmost_note.center_x - (PLAYHEAD_WIDTH / 2) playhead_y = GRID_Y self.playhead.pos = [playhead_x, playhead_y] # PLAYBACK MENU PLAYBACK_X = OUTER_PADDING PLAYBACK_Y = OUTER_PADDING PLAYBACK_WIDTH = GRID_WIDTH PLAYBACK_HEIGHT = WINDOW_HEIGHT - OUTER_PADDING - GRID_HEIGHT - \ OUTER_PADDING - OUTER_PADDING PLAYBACK_CENTER_Y = PLAYBACK_Y + (PLAYBACK_HEIGHT / 2) PLAYBACK_TOP = PLAYBACK_Y + PLAYBACK_HEIGHT PLAY_BUTTON_WIDTH = 48 PLAY_BUTTON_HEIGHT = 48 PLAYALL_BUTTON_WIDTH = 60 PLAYALL_BUTTON_HEIGHT = PLAY_BUTTON_HEIGHT / 2 PLAYALL_BUTTON_FONT_SIZE = 8 PLAYALL_BUTTON_TEXT_SIZE = [PLAYALL_BUTTON_WIDTH, PLAYALL_BUTTON_HEIGHT] PAGE_BUTTON_WIDTH = 20 PAGE_BUTTON_HEIGHT = 30 NUM_PAGE_BUTTONS = MusicPlayer.NUM_PAGES PAGE_LABEL_WIDTH = (PAGE_BUTTON_WIDTH * NUM_PAGE_BUTTONS) PAGE_LABEL_HEIGHT = 20 PAGE_LABEL_FONT_SIZE = 10 PAGE_LABEL_OFFSET = 5 TRACK_BUTTON_WIDTH = 48 TRACK_BUTTON_HEIGHT = 48 NUM_TRACK_BUTTONS = MusicPlayer.NUM_TRACKS NUM_PLAYBACK_ELEMENTS = 4 TRACK_LABEL_WIDTH = TRACK_BUTTON_WIDTH * NUM_TRACK_BUTTONS TRACK_LABEL_HEIGHT = PAGE_LABEL_HEIGHT TRACK_LABEL_FONT_SIZE = PAGE_LABEL_FONT_SIZE TRACK_LABEL_TEXT_SIZE = [TRACK_LABEL_WIDTH, TRACK_LABEL_HEIGHT] TRACK_LABEL_OFFSET = PAGE_LABEL_OFFSET PLAYBACK_PADDING = (PLAYBACK_WIDTH - (PAGE_BUTTON_WIDTH * NUM_PAGE_BUTTONS) - (PLAY_BUTTON_WIDTH) - (TRACK_BUTTON_WIDTH * NUM_TRACK_BUTTONS) - PLAYALL_BUTTON_WIDTH) / (NUM_PLAYBACK_ELEMENTS + 1) # Play/pause button PLAY_BUTTON_X = PLAYBACK_X + PLAYBACK_PADDING # TODO: add a border for this button play_button = ToggleButton(width=PLAY_BUTTON_WIDTH, height=PLAY_BUTTON_HEIGHT) play_button.bind(on_press=self.play_pause) play_button.background_normal = \ os.path.join(IMAGE_DIR, "media-playback-start-4.png") play_button.background_down = \ os.path.join(IMAGE_DIR, "media-playback-pause-4.png") play_button.x = PLAY_BUTTON_X play_button.center_y = PLAYBACK_CENTER_Y self.play_button = play_button self.main_layout.add_widget(play_button) self.colorables.append(play_button) # Buttons to play one page or all one_page_button = NSToggleButton(width=PLAYALL_BUTTON_WIDTH, height=PLAYALL_BUTTON_HEIGHT, text='One page', text_size=PLAYALL_BUTTON_TEXT_SIZE, font_size=PLAYALL_BUTTON_FONT_SIZE, halign='center', valign='middle') one_page_button.bind(on_press=self.play_one_page) one_page_button.x = play_button.right + PLAYBACK_PADDING one_page_button.top = PLAYBACK_CENTER_Y + PLAYALL_BUTTON_HEIGHT self.one_page_button = one_page_button self.main_layout.add_widget(one_page_button) self.colorables.append(one_page_button) all_pages_button = NSToggleButton(width=PLAYALL_BUTTON_WIDTH, height=PLAYALL_BUTTON_HEIGHT, text='All pages', text_size=PLAYALL_BUTTON_TEXT_SIZE, font_size=PLAYALL_BUTTON_FONT_SIZE, halign='center', valign='middle') all_pages_button.bind(on_press=self.play_all_pages) all_pages_button.x = one_page_button.x all_pages_button.top = PLAYBACK_CENTER_Y self.all_pages_button = all_pages_button self.main_layout.add_widget(all_pages_button) self.colorables.append(all_pages_button) if music_player.play_all == False: one_page_button.state = 'down' all_pages_button.state = 'normal' elif music_player.play_all == True: one_page_button.state = 'normal' all_pages_button.state = 'down' # Page selection buttons self.page_buttons = [] page_buttons = [] page_label = Label(text='Page Select', text_size=[PAGE_LABEL_WIDTH, PAGE_LABEL_HEIGHT], font_size=PAGE_LABEL_FONT_SIZE, width=PAGE_LABEL_WIDTH, height=PAGE_LABEL_HEIGHT, halign='center', valign='middle') page_button_x = all_pages_button.right + PLAYBACK_PADDING page_label.x = page_button_x page_label.top = PLAYBACK_CENTER_Y - (PAGE_BUTTON_HEIGHT / 2) - \ PAGE_LABEL_OFFSET self.main_layout.add_widget(page_label) for page_index in range(0, NUM_PAGE_BUTTONS): page_id = 'page' + str(page_index) page_button = NSToggleButton(width=PAGE_BUTTON_WIDTH, height=PAGE_BUTTON_HEIGHT, id=page_id) page_button.bind(on_press=self.select_page) page_button.x = page_button_x page_button.center_y = PLAYBACK_CENTER_Y page_buttons.append(page_button) self.main_layout.add_widget(page_button) self.colorables.append(page_button) page_button_x += PAGE_BUTTON_WIDTH self.page_buttons = page_buttons # Select the current music player's page with the GUI page_buttons[music_player.page_index].state = 'down' # Track selection buttons TRACK_BUTTON_FONT_SIZE = 10 TRACK_BUTTON_TEXT_SIZE = [TRACK_BUTTON_WIDTH, TRACK_BUTTON_HEIGHT] track_text = ["Bass", "Lead", "Drum"] track_buttons = [] self.track_buttons = [] track_button_x = page_buttons[len(page_buttons) - 1].right + \ PLAYBACK_PADDING for track_index in range(0, NUM_TRACK_BUTTONS): track_id = 'track' + str(track_index) track_button = NSToggleButton(text=track_text[track_index], width=TRACK_BUTTON_WIDTH, height=TRACK_BUTTON_HEIGHT, id=track_id, text_size=TRACK_BUTTON_TEXT_SIZE, font_size=TRACK_BUTTON_FONT_SIZE, halign='center', valign='middle') track_button.bind(on_press=self.select_track) track_button.x = track_button_x track_button.center_y = PLAYBACK_CENTER_Y track_buttons.append(track_button) self.main_layout.add_widget(track_button) track_button_x += TRACK_BUTTON_WIDTH self.track_buttons = track_buttons # Select the current track in the GUI track_buttons[self.track_id].state = 'down' leftmost_track_button = self.track_buttons[0] track_label = Label(text='Instrument Select', text_size=TRACK_LABEL_TEXT_SIZE, font_size=TRACK_LABEL_FONT_SIZE, width=TRACK_LABEL_WIDTH, height=TRACK_LABEL_HEIGHT, halign='center', valign='middle') track_label.x = leftmost_track_button.x track_label.top = leftmost_track_button.y - TRACK_LABEL_OFFSET # self.main_layout.add_widget(track_label) # SETTINGS TABS TABS_X = OUTER_PADDING + GRID_WIDTH + OUTER_PADDING TABS_Y = GRID_Y TABS_WIDTH = WINDOW_WIDTH - OUTER_PADDING - GRID_WIDTH - \ OUTER_PADDING - OUTER_PADDING TABS_HEIGHT = GRID_HEIGHT # Element is button, label, etc. Section is vertical group of elements TAB_SECTION_PADDING = 20 TAB_ELEMENT_PADDING = 10 # Note: it's a good idea to make these tabs the size of our icons, # which is 48x48 TAB_HEADER_WIDTH = 48 TAB_HEADER_HEIGHT = TAB_HEADER_WIDTH TAB_HEADER_FONT_SIZE = 20 SECTION_LABEL_FONT_SIZE = 16 SECTION_LABEL_WIDTH = TABS_WIDTH - TAB_SECTION_PADDING * 2 SECTION_LABEL_HEIGHT = 30 SECTION_LABEL_TEXT_SIZE = [SECTION_LABEL_WIDTH, SECTION_LABEL_HEIGHT] ELEMENT_LABEL_FONT_SIZE = 10 ELEMENT_LABEL_WIDTH = TABS_WIDTH - TAB_ELEMENT_PADDING * 2 ELEMENT_LABEL_HEIGHT = 20 ELEMENT_LABEL_TEXT_SIZE = [ELEMENT_LABEL_WIDTH, ELEMENT_LABEL_HEIGHT] TAB_CONTENT_HEIGHT = TABS_HEIGHT - TAB_HEADER_HEIGHT TAB_CONTENT_TOP = TABS_Y + TAB_CONTENT_HEIGHT # Create main tabbed panel tabs = TabbedPanel(tab_width=TAB_HEADER_WIDTH, tab_height=TAB_HEADER_HEIGHT, width=TABS_WIDTH, height=TABS_HEIGHT) tabs.x = TABS_X tabs.y = TABS_Y self.main_layout.add_widget(tabs) self.tabs = tabs # Music tab (default) music_tab_content = Widget(width=TABS_WIDTH, height=TAB_CONTENT_HEIGHT) tabs.default_tab_content = music_tab_content tabs.default_tab.text = "" # TODO: make these paths absolute? tabs.default_tab.background_normal = \ os.path.join(IMAGE_DIR, "audio-keyboard.png") print "@@ default tab bg: ", tabs.default_tab.background_normal tabs.default_tab.background_down = \ os.path.join(IMAGE_DIR, "audio-keyboard-down.png") # Global music options global_music_label = Label(text='Global', font_size=SECTION_LABEL_FONT_SIZE, width=SECTION_LABEL_WIDTH, height=SECTION_LABEL_HEIGHT, text_size=SECTION_LABEL_TEXT_SIZE, halign='center', valign='middle') global_music_label.center_x = tabs.center_x global_music_label.top = TAB_CONTENT_TOP - TAB_SECTION_PADDING music_tab_content.add_widget(global_music_label) MUSIC_SLIDER_WIDTH = TABS_WIDTH - 40 MUSIC_SLIDER_HEIGHT = 20 # Note: these sliders buttons have a predefined height, so we are a # slave to that height for positioning the sliders global_volume_slider = NSSlider(min=MusicPlayer.MIN_VOLUME, max=MusicPlayer.MAX_VOLUME, value=music_player.global_volume, orientation='horizontal', height=MUSIC_SLIDER_HEIGHT, width=MUSIC_SLIDER_WIDTH) global_volume_slider.bind(on_touch_move=self.change_global_volume) global_volume_slider.center_x = tabs.center_x global_volume_slider.top = global_music_label.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(global_volume_slider) self.global_volume_slider = global_volume_slider self.colorables.append(global_volume_slider) global_volume_label = Label(text='Volume', font_size=ELEMENT_LABEL_FONT_SIZE, width=ELEMENT_LABEL_WIDTH, height=ELEMENT_LABEL_HEIGHT, text_size=ELEMENT_LABEL_TEXT_SIZE, halign='center', valign='middle') global_volume_label.center_x = tabs.center_x global_volume_label.top = global_volume_slider.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(global_volume_label) global_tempo_slider = NSSlider(min=MusicPlayer.MIN_TEMPO, max=MusicPlayer.MAX_TEMPO, value=music_player.tempo, orientation='horizontal', height=MUSIC_SLIDER_HEIGHT, width=MUSIC_SLIDER_WIDTH) global_tempo_slider.bind(on_touch_move=self.change_global_tempo) global_tempo_slider.center_x = tabs.center_x global_tempo_slider.top = global_volume_label.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(global_tempo_slider) self.global_tempo_slider = global_tempo_slider self.colorables.append(global_tempo_slider) global_tempo_label = Label(text='Tempo', font_size=ELEMENT_LABEL_FONT_SIZE, width=ELEMENT_LABEL_WIDTH, height=ELEMENT_LABEL_HEIGHT, text_size=ELEMENT_LABEL_TEXT_SIZE, halign='center', valign='middle') global_tempo_label.center_x = tabs.center_x global_tempo_label.top = global_tempo_slider.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(global_tempo_label) # Instrument settings track_music_label = Label(text='Instrument', font_size=SECTION_LABEL_FONT_SIZE, width=SECTION_LABEL_WIDTH, height=SECTION_LABEL_HEIGHT, text_size=SECTION_LABEL_TEXT_SIZE, halign='center', valign='middle') track_music_label.center_x = tabs.center_x track_music_label.top = global_tempo_label.y - TAB_SECTION_PADDING music_tab_content.add_widget(track_music_label) track_volume_initial = music_player.get_volume(self.track_id) track_volume_slider = NSSlider(min=MusicPlayer.MIN_VOLUME, max=MusicPlayer.MAX_VOLUME, value=track_volume_initial, orientation='horizontal', height=MUSIC_SLIDER_HEIGHT, width=MUSIC_SLIDER_WIDTH) track_volume_slider.bind(on_touch_move=self.change_track_volume) track_volume_slider.center_x = tabs.center_x track_volume_slider.top = track_music_label.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(track_volume_slider) self.track_volume_slider = track_volume_slider self.colorables.append(track_volume_slider) track_volume_label = Label(text='Volume', font_size=ELEMENT_LABEL_FONT_SIZE, width=ELEMENT_LABEL_WIDTH, height=ELEMENT_LABEL_HEIGHT, text_size=ELEMENT_LABEL_TEXT_SIZE, halign='center', valign='middle') track_volume_label.center_x = tabs.center_x track_volume_label.top = track_volume_slider.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(track_volume_label) track_reverb_initial = music_player.get_reverb(self.track_id) track_reverb_slider = NSSlider(min=MusicPlayer.MIN_REVERB, max=MusicPlayer.MAX_REVERB, value=track_reverb_initial, orientation='horizontal', height=MUSIC_SLIDER_HEIGHT, width=MUSIC_SLIDER_WIDTH) track_reverb_slider.bind(on_touch_move=self.change_track_reverb) track_reverb_slider.center_x = tabs.center_x track_reverb_slider.top = track_volume_label.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(track_reverb_slider) self.track_reverb_slider = track_reverb_slider self.colorables.append(track_reverb_slider) track_reverb_label = Label(text='Reverb', font_size=ELEMENT_LABEL_FONT_SIZE, width=ELEMENT_LABEL_WIDTH, height=ELEMENT_LABEL_HEIGHT, text_size=ELEMENT_LABEL_TEXT_SIZE, halign='center', valign='middle') track_reverb_label.center_x = tabs.center_x track_reverb_label.top = track_reverb_slider.y - TAB_ELEMENT_PADDING music_tab_content.add_widget(track_reverb_label) # Network tab network_tab = TabbedPanelHeader() network_tab.text = "" network_tab.background_normal = \ os.path.join(IMAGE_DIR, "network-wired-2.png") network_tab.background_down = \ os.path.join(IMAGE_DIR, "network-wired-2-down.png") tabs.add_widget(network_tab) TEXT_INPUT_HEIGHT = 30 PORT_INPUT_WIDTH = 70 IP_INPUT_WIDTH = TABS_WIDTH - TAB_SECTION_PADDING - \ PORT_INPUT_WIDTH - TAB_ELEMENT_PADDING - \ TAB_SECTION_PADDING PORT_LABEL_TEXT_SIZE = [PORT_INPUT_WIDTH, ELEMENT_LABEL_HEIGHT] IP_LABEL_TEXT_SIZE = [IP_INPUT_WIDTH, ELEMENT_LABEL_HEIGHT] NETWORK_BUTTON_WIDTH = TABS_WIDTH - TAB_SECTION_PADDING * 2 NETWORK_BUTTON_HEIGHT = 80 NETWORK_BUTTON_FONT_SIZE = 16 NETWORK_BUTTON_TEXT_SIZE = [NETWORK_BUTTON_WIDTH, NETWORK_BUTTON_HEIGHT] SERVER_PORT_TEXT = 'Server Port' SERVER_IP_TEXT = 'Server IP Address' network_tab_content = Widget(width=TABS_WIDTH, height=TAB_CONTENT_HEIGHT) network_tab.content = network_tab_content # Server input labels server_port_label = Label(text=SERVER_PORT_TEXT, width=PORT_INPUT_WIDTH, height=ELEMENT_LABEL_HEIGHT, text_size=PORT_LABEL_TEXT_SIZE, font_size=ELEMENT_LABEL_FONT_SIZE) server_port_label.top = TAB_CONTENT_TOP - TAB_SECTION_PADDING server_port_label.x = TABS_X + TAB_SECTION_PADDING network_tab_content.add_widget(server_port_label) server_ip_label = Label(text=SERVER_IP_TEXT, width=IP_INPUT_WIDTH, height=ELEMENT_LABEL_HEIGHT, text_size=IP_LABEL_TEXT_SIZE, font_size=ELEMENT_LABEL_FONT_SIZE) server_ip_label.top = server_port_label.top server_ip_label.x = server_port_label.right + TAB_ELEMENT_PADDING network_tab_content.add_widget(server_ip_label) # Server startup input server_port_input = NSTextInput(text='', width=PORT_INPUT_WIDTH, height=TEXT_INPUT_HEIGHT, multiline=False) server_port_input.bind(focus=self.select_text_input) server_port_input.original_text = SERVER_PORT_TEXT server_port_input.x = server_port_label.x server_port_input.top = server_port_label.y - TAB_ELEMENT_PADDING network_tab_content.add_widget(server_port_input) self.server_port_input = server_port_input server_ip_input = NSTextInput(text='', width=IP_INPUT_WIDTH, height=TEXT_INPUT_HEIGHT, multiline=False) server_ip_input.bind(focus=self.select_text_input) server_ip_input.original_text=SERVER_IP_TEXT server_ip_input.x = server_ip_label.x server_ip_input.top = server_port_input.top network_tab_content.add_widget(server_ip_input) self.server_ip_input = server_ip_input server_start_button = NSDisableButton(text='Start server', width=NETWORK_BUTTON_WIDTH, height=NETWORK_BUTTON_HEIGHT, text_size=NETWORK_BUTTON_TEXT_SIZE, font_size=NETWORK_BUTTON_FONT_SIZE, halign='center', valign='middle') server_start_button.bind(on_press=self.start_server) server_start_button.center_x = tabs.center_x server_start_button.top = server_ip_input.y - TAB_ELEMENT_PADDING network_tab_content.add_widget(server_start_button) self.server_start_button = server_start_button join_server_button = NSDisableButton(text='Join server', width=NETWORK_BUTTON_WIDTH, height=NETWORK_BUTTON_HEIGHT, text_size=NETWORK_BUTTON_TEXT_SIZE, font_size=NETWORK_BUTTON_FONT_SIZE, halign='center', valign='middle') join_server_button.bind(on_press=self.ask_join_server) join_server_button.x = server_start_button.x join_server_button.top = server_start_button.y - TAB_ELEMENT_PADDING network_tab_content.add_widget(join_server_button) self.join_server_button = join_server_button end_connection_button = NSDisableButton(text='End connection', width=NETWORK_BUTTON_WIDTH, height=NETWORK_BUTTON_HEIGHT, text_size=NETWORK_BUTTON_TEXT_SIZE, font_size=NETWORK_BUTTON_FONT_SIZE, halign='center', valign='middle') end_connection_button.bind(on_press=self.ask_end_connection) end_connection_button.disable() end_connection_button.x = server_start_button.x end_connection_button.top = join_server_button.y - TAB_ELEMENT_PADDING network_tab_content.add_widget(end_connection_button) self.end_connection_button = end_connection_button # System options tab system_tab = TabbedPanelHeader() system_tab.background_normal = \ os.path.join(IMAGE_DIR, "media-floppy.png") system_tab.background_down = \ os.path.join(IMAGE_DIR, "media-floppy-down.png") tabs.add_widget(system_tab) system_tab_content = Widget(width=TABS_WIDTH, height=TAB_CONTENT_HEIGHT) system_tab.content = system_tab_content NUM_SYSTEM_BUTTONS = 3 SYSTEM_BUTTON_PADDING = 20 SYSTEM_BUTTON_FONT_SIZE = 24 SYSTEM_BUTTON_WIDTH = TABS_WIDTH - SYSTEM_BUTTON_PADDING * 2 SYSTEM_BUTTON_HEIGHT = (TAB_CONTENT_HEIGHT - SYSTEM_BUTTON_PADDING * (NUM_SYSTEM_BUTTONS + 1)) / NUM_SYSTEM_BUTTONS SYSTEM_BUTTON_TEXT_SIZE = [SYSTEM_BUTTON_WIDTH, SYSTEM_BUTTON_HEIGHT] # Load button load_button = NSDisableButton(text='Load', width=SYSTEM_BUTTON_WIDTH, height=SYSTEM_BUTTON_HEIGHT, text_size=SYSTEM_BUTTON_TEXT_SIZE, font_size=SYSTEM_BUTTON_FONT_SIZE, halign='center', valign='middle') load_button.bind(on_press=self.load_file) load_button.center_x = tabs.center_x load_button.top = TAB_CONTENT_TOP - SYSTEM_BUTTON_PADDING system_tab_content.add_widget(load_button) self.load_button = load_button # Save button save_button = NSDisableButton(text='Save', width=SYSTEM_BUTTON_WIDTH, height=SYSTEM_BUTTON_HEIGHT, text_size=SYSTEM_BUTTON_TEXT_SIZE, font_size=SYSTEM_BUTTON_FONT_SIZE, halign='center', valign='middle') save_button.bind(on_press=self.save_file) save_button.center_x = tabs.center_x save_button.top = load_button.y - SYSTEM_BUTTON_PADDING system_tab_content.add_widget(save_button) # Quit button quit_button = NSDisableButton(text='Quit', width=SYSTEM_BUTTON_WIDTH, height=SYSTEM_BUTTON_HEIGHT, text_size=SYSTEM_BUTTON_TEXT_SIZE, font_size=SYSTEM_BUTTON_FONT_SIZE, halign='center', valign='middle') quit_button.bind(on_press=self.request_exit) quit_button.center_x = tabs.center_x quit_button.top = save_button.y - SYSTEM_BUTTON_PADDING system_tab_content.add_widget(quit_button) # APPLICATION TITLE TITLE_WIDTH = TABS_WIDTH TITLE_HEIGHT = 50 TITLE_TEXT_SIZE = [TITLE_WIDTH, TITLE_HEIGHT] TITLE_FONT_SIZE = 30 SUBTITLE_WIDTH = TITLE_WIDTH SUBTITLE_HEIGHT = 30 SUBTITLE_TEXT_SIZE = [SUBTITLE_WIDTH, SUBTITLE_HEIGHT] SUBTITLE_FONT_SIZE = 15 TITLE_X = TABS_X title_label = Label(text='NetSeq', width=TITLE_WIDTH, height=TITLE_HEIGHT, halign='center', valign='middle', text_size=TITLE_TEXT_SIZE, font_size=TITLE_FONT_SIZE) title_label.top = PLAYBACK_TOP title_label.x = TITLE_X self.main_layout.add_widget(title_label) subtitle_label = Label(text='Music with Friends', width=SUBTITLE_WIDTH, height=SUBTITLE_HEIGHT, text_size=SUBTITLE_TEXT_SIZE, font_size=SUBTITLE_FONT_SIZE, halign='center', valign='middle') subtitle_label.top = title_label.y subtitle_label.x = TITLE_X self.main_layout.add_widget(subtitle_label) # Finishing steps self.set_color(self.track_id) self.reload_row_labels()
class SkeletonRendererDebug: boneLineColor = Color(1, 0, 0, 1) boneOriginColor = Color(0, 1, 0, 1) attachmentLineColor = Color(0, 0, 1, 0.5) triangleLineColor = Color(1, 0.64, 0, 0.5) boundingBoxColor = Color(0, 1, 0, 0.8) aabbColor = Color(0, 1, 0, 0.5) def __init__(self, canvas=None): self.drawBones = True self.drawRegionAttachments = True self.drawBoundingBoxes = True self.drawMeshHull = True self.drawMeshTriangles = True self.bounds = SkeletonBounds() self.shapes = None self.scale = 1 self.boneWidth = 2 self.preMultipliedAlpha = False if canvas is None: self.shapes = Canvas() else: self.shapes = canvas def draw(self, skeleton): self.shapes.clear() skeletonX = skeleton.getX() skeletonY = skeleton.getY() glEnable(GL_BLEND) srcFunc = GL_ONE if self.preMultipliedAlpha else GL_SRC_ALPHA glBlendFunc(srcFunc, GL_ONE_MINUS_SRC_ALPHA) bones = skeleton.getBones() if self.drawBones: self.shapes.add(self.boneLineColor) for i in range(len(bones)): bone = bones[i] if bone.parent is None: continue x = skeletonX + bone.data.length * bone.m00 + bone.worldX y = skeletonY + bone.data.length * bone.m10 + bone.worldY self.shapes.add( Line(points=[ skeletonX + bone.worldX, skeletonY + bone.worldY, x, y ], width=self.boneWidth * self.scale)) self.shapes.add(Line(circle=(skeletonX, skeletonY, 4 * self.scale))) if self.drawRegionAttachments: self.shapes.add(self.attachmentLineColor) slots = skeleton.getSlots() for i in range(len(slots)): slot = slots[i] attachment = slot.attachment if isinstance(attachment, RegionAttachment): attachment.updateWorldVertices(slot, False) vertices = attachment.getWorldVertices() self.shapes.add( Line(points=([ vertices[X1], vertices[Y1], vertices[X2], vertices[Y2] ]))) self.shapes.add( Line(points=([ vertices[X2], vertices[Y2], vertices[X3], vertices[Y3] ]))) self.shapes.add( Line(points=([ vertices[X3], vertices[Y3], vertices[X4], vertices[Y4] ]))) self.shapes.add( Line(points=([ vertices[X4], vertices[Y4], vertices[X1], vertices[Y1] ]))) if self.drawMeshHull or self.drawMeshTriangles: slots = skeleton.getSlots() for i in range(len(slots)): slot = slots[i] attachment = slot.attachment vertices = None triangles = None hullLength = 0 if isinstance(attachment, MeshAttachment): attachment.updateWorldVertices(slot, False) vertices = attachment.getWorldVertices() triangles = attachment.getTriangles() hullLength = attachment.getHullLength() elif isinstance(attachment, SkinnedMeshAttachment): attachment.updateWorldVertices(slot, False) vertices = attachment.getWorldVertices() triangles = attachment.getTriangles() hullLength = attachment.getHullLength() if vertices is None or triangles is None: continue if self.drawMeshTriangles: self.shapes.add(self.triangleLineColor) for ii in range(0, len(triangles), 3): v1, v2, v3 = triangles[ii] * 5, triangles[ ii + 1] * 5, triangles[ii + 3] * 5 self.shapes.add( Line(points=[ vertices[v1], vertices[v1 + 1], vertices[v2], vertices[v2 + 1], vertices[v3], vertices[v3 + 1] ])) if self.drawMeshHull and hullLength > 0: self.shapes.add(self.attachmentLineColor) hullLength = hullLength / 2 * 5 lastX, lastY = vertices[hullLength - 5], vertices[hullLength - 4] for ii in range(0, hullLength, 5): x, y = vertices[ii], vertices[ii + 1] self.shapes.add(Line(points=[x, y, lastX, lastY])) lastX = x lastY = y if self.drawBoundingBoxes: bounds = self.bounds bounds.update(skeleton, True) self.shapes.add(self.aabbColor) self.shapes.add( Rectangle(x=bounds.getMinX(), y=bounds.getMinY(), width=bounds.getWidth(), height=bounds.getHeight())) self.shapes.add(self.boundingBoxColor) polygons = bounds.getPolygons() for polygon in polygons: self.shapes.add(Line(points=polygon)) if self.drawBones: self.shapes.add(self.boneOriginColor) for bone in bones: self.shapes.add(Color(0, 1, 0, 1)) self.shapes.add( Line(circle=(skeletonX + bone.worldX, skeletonY + bone.worldY, 3 * self.scale))) del bones def getShapeRenderer(self): return self.shapes def setBones(self, bones): self.drawBones = bones def setScale(self, scale): self.scale = scale def setRegionAttachments(self, regionAttachments): self.drawRegionAttachments = regionAttachments def setBoundingBoxes(self, boundingBoxes): self.drawBoundingBoxes = boundingBoxes def setMeshHull(self, meshHull): self.drawMeshHull = meshHull def setMeshTriangles(self, meshTriangles): self.drawMeshTriangles = meshTriangles def setPremultipliedAlpha(self, premultipliedAlpha): self.preMultipliedAlpha = premultipliedAlpha
class MyWidget(Widget): def __init__(self): super(MyWidget, self).__init__() self.cos_table = CosTable([(0,0), (100,1), (1000,.25), (8191,0)]) self.osc_out = Osc(table=self.cos_table, freq=220) # For each element of the GUI, make sure to # 1. Create a unique reference attached to this object for # future manipulation. e.g. self.main_box = main_box after you've # created a BoxLayout called main_box # Interesting things about Kivy UI programming: # 1. y starts counting from bottom left # 2. set size_hint to '[None, None]' for all new widgets if defining # the size and manually # MAIN LAYOUT main_layout = FloatLayout(size=[800,600], orientation='horizontal') self.main_layout = main_layout self.add_widget(main_layout) # TABS WITH GAME CONTROL # Tabbed panel for music, settings, network # Y-position of tabbed panel depends on tab height! tabs = TabbedPanel(tab_width=50, size=[160, 480], pos=[0, 120], size_hint=(None, None)) self.tabs = tabs main_layout.add_widget(tabs) # Music tab music_button = Button(text="Music things") tabs.default_tab_content = music_button tabs.default_tab.text = "Music" # Network tab network_tab = TabbedPanelHeader(text="Net") tabs.add_widget(network_tab) network_layout = BoxLayout(orientation="vertical", padding=10) server_button = Button(text="Start server") ip_label = Label(text="Your IP is\n123.234.456.789"); client_label = Label(text="Connect to server: "); server_ip_input = TextInput(text="Enter server IP") network_layout.add_widget(server_button) network_layout.add_widget(ip_label) network_layout.add_widget(client_label) network_layout.add_widget(server_ip_input) network_tab.content = network_layout # Global tab global_tab = TabbedPanelHeader(text="Global") tabs.add_widget(global_tab) global_button = Button(text="Global things") global_tab.content = global_button # END TABS # RIGHT-SIDE LAYOUT: NOTES GRID AND PLAYBACK UI music_layout = FloatLayout(size=[640, 600], pos=[161, 0], size_hint=[None, None]) self.music_layout = music_layout main_layout.add_widget(music_layout) # NOTES GRID # Right now Kivy isn't really paying attention to button size and # padding. Later on, we'll fix this with a FloatLayout note_rows = note_cols = 8 padding_between = 5 note_grid = GridLayout(size=[640, 480], pos=[161, 121], size_hint=[None, None], rows=note_rows, cols=note_cols, padding=padding_between) music_layout.add_widget(note_grid) edge_padding = 30 grid_start_x = note_grid.x + edge_padding grid_end_x = note_grid.right - edge_padding grid_start_y = note_grid.y + edge_padding grid_end_y = note_grid.top - edge_padding notes_matrix = [] note_width = grid_end_x - grid_start_x - padding_between * \ (note_rows - 1) note_height = grid_end_y - grid_start_y - padding_between * \ (note_rows - 1) # Adding a rectangle to test playback indicator self.playback_indicator = Rectangle(pos=[161,121], size=[75, 480]) self.playback_canvas = Canvas() playback_widget = Widget() self.playback_canvas.add(self.playback_indicator) self.playback_canvas.opacity = .5 playback_widget.canvas = self.playback_canvas music_layout.add_widget(playback_widget) for row in range(0, note_rows): for col in range(0, note_cols): new_id = str(row) + "," + str(col) new_button = ToggleButton(text=new_id, id=new_id, width=note_width, height=note_height) active_color = (1, 0, 0, 1) new_button.background_color = active_color new_button.bind(on_press=self.play_note) note_grid.add_widget(new_button) # PLAYBACK BUTTONS playback = Button(text="For playback", size=[640, 120], size_hint=[None, None], pos=[161, 0]) music_layout.add_widget(playback) def play_note(self, instance): if instance.state == "down": print "Playing!" self.osc_out.out() self.playback_indicator.pos = [260, 121] else: print "Stopping!" self.osc_out.stop() self.playback_canvas.opacity = 0