From 92a4ced2b8994a5d52f6ce6ae70580a85cc72db4 Mon Sep 17 00:00:00 2001 From: langolierz Date: Thu, 27 Sep 2018 00:28:27 +0000 Subject: [PATCH] WIP adding shader menu to front - not working yet ! --- actions.py | 24 +++---- data_centre/data.py | 1 + display_centre/display.py | 38 ++++++++++- display_centre/menu.py | 59 +++++++++-------- .../python_for_shutting_down_osc_server.py | 17 +++++ r_e_c_u_r.py | 6 +- video_centre/alt_video_player.py | 2 +- video_centre/shaders.py | 63 +++++++++++++++++++ video_centre/video_driver.py | 3 +- 9 files changed, 169 insertions(+), 44 deletions(-) create mode 100644 dotfiles/python_for_shutting_down_osc_server.py create mode 100644 video_centre/shaders.py diff --git a/actions.py b/actions.py index f4e9ab0..e6e8077 100644 --- a/actions.py +++ b/actions.py @@ -5,12 +5,13 @@ import sys import os class Actions(object): - def __init__(self, tk, message_handler, data, video_driver, capture, display): + def __init__(self, tk, message_handler, data, video_driver, capture, shaders, display): self.tk = tk self.message_handler = message_handler self.data = data self.video_driver = video_driver self.capture = capture + self.shaders = shaders self.display = display @@ -82,15 +83,16 @@ class Actions(object): def cycle_display_mode(self): self.display.top_menu_index = 0 self.display.selected_list_index = self.display.top_menu_index - if self.data.display_mode == "BROWSER": - self.data.display_mode = "SETTINGS" - self.data.control_mode = 'NAV_SETTINGS' - elif self.data.display_mode == "SAMPLER": - self.data.display_mode = "BROWSER" - self.data.control_mode = 'NAV_BROWSER' - elif self.data.display_mode == "SETTINGS": - self.data.display_mode = "SAMPLER" - self.data.control_mode = 'PLAYER' + if self.data.settings['other']['VIDEO_BACKEND']['value'] == 'openframeworks': + display_modes = [["BROWSER",'NAV_BROWSER'],["SETTINGS",'NAV_SETTINGS'],[ "SAMPLER",'PLAYER'],["SHADERS",'SHAD_BROWSER']] + else: + display_modes = [["BROWSER",'NAV_BROWSER'],["SETTINGS",'NAV_SETTINGS'],[ "SAMPLER",'PLAYER']] + + current_mode_index = [index for index, i in enumerate(display_modes) if self.data.display_mode in i][0] + next_mode_index = (current_mode_index + 1) % len(display_modes) + self.data.display_mode = display_modes[next_mode_index][0] + self.data.control_mode = display_modes[next_mode_index][1] + def toggle_action_on_player(self): play = 'play' in self.data.settings['sampler']['ON_ACTION']['value'] @@ -343,7 +345,7 @@ class Actions(object): def quit_the_program(self): self.video_driver.exit_all_players() - self.video_driver.exit_osc_server() + self.video_driver.exit_osc_server('','') self.toggle_x_autorepeat() self.tk.destroy() diff --git a/data_centre/data.py b/data_centre/data.py index 6de827e..662c1e8 100644 --- a/data_centre/data.py +++ b/data_centre/data.py @@ -26,6 +26,7 @@ class Data(object): #self.EMPTY_BANK = [self.EMPTY_SLOT for i in range(10)] self.PATHS_TO_BROWSER = [self.PATH_TO_EXTERNAL_DEVICES, '/home/pi/Videos' ] + self.PATHS_TO_SHADERS = [self.PATH_TO_EXTERNAL_DEVICES, '/home/pi/Shaders' ] ### state data self.auto_repeat_on = True diff --git a/display_centre/display.py b/display_centre/display.py index d8574fd..691c5e5 100644 --- a/display_centre/display.py +++ b/display_centre/display.py @@ -9,14 +9,16 @@ class Display(object): ROW_OFFSET = 6.0 TITLE = '================== r_e_c_u_r ==================' - def __init__(self, tk, video_driver, capture, message_handler, data): + def __init__(self, tk, video_driver, capture, shaders, message_handler, data): self.tk = tk self.video_driver = video_driver self.capture = capture + self.shaders = shaders self.message_handler = message_handler self.data = data self.browser_menu = menu.BrowserMenu(self.data, self.message_handler, self.MENU_HEIGHT) self.settings_menu = menu.SettingsMenu(self.data, self.message_handler, self.MENU_HEIGHT) + self.shaders_menu = self.shaders.shaders_menu #self.top_menu_index = 0 #self.selected_list_index = self.top_menu_index @@ -74,8 +76,10 @@ class Display(object): self._load_browser() elif self.data.display_mode == 'SETTINGS': self._load_settings() - else: + elif self.data.display_mode == 'SAMPLER': self._load_sampler() + elif self.data.display_mode == 'SHADERS': + self._load_shaders() self.display_text.tag_add("COLUMN_NAME", 5.0, 6.0) @@ -138,6 +142,36 @@ class Display(object): self._highlight_this_row(self.settings_menu.selected_list_index - self.settings_menu.top_menu_index) + def _load_shaders(self): + line_count = 0 + self.display_text.insert(END, '------------------ ------------------ \n') + self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.28) + ## showing current shader info: + shader = self.shaders.selected_shader + self.display_text.insert(END, '{<6}:{<1}{<2} {^26} {<4}:{^5} \n'.format \ + (self.shaders.selected_status,shader[shad_type], \ + shader[shad_index], shader[name][0:26], '--:--' )) + for i in range(shader[param_number]): + self.display_text.insert(END, 'x{}{<2} '.format(i, self.shaders.selected_param_values[i])) + self.display_text.insert(END,'\n') + self.display_text.tag_add("COLUMN_NAME", 5.0, 7.0) + ## showing list of other shaders: + shaders_list = self.shaders.shaders_menu_list + number_of_shader_items = len(shaders_list) + shader_menu_height = self.MENU_HEIGHT - 1 + for index in range(number_of_shader_items): + if line_count > shader_menu_height : + break + if index >= self.shaders.shaders_menu.top_menu_index: + shader_line = shaders_list[index] + self.display_text.insert(END, '{:<30} {<2}'.format(shader_line['name'][0:30], shader_line['shad_type'])) + line_count = line_count + 1 + for index in range(shader_menu_height - number_of_shader_items): + self.display_text.insert(END, '\n') + + self._highlight_this_row(self.shaders.shaders_menu.selected_list_index - self.shaders.shaders_menu.top_menu_index) + + def _load_message(self): if self.message_handler.current_message[1]: self.display_text.insert(END, '{:5} {:42} \n'.format( diff --git a/display_centre/menu.py b/display_centre/menu.py index 578b57b..1fa2069 100644 --- a/display_centre/menu.py +++ b/display_centre/menu.py @@ -47,30 +47,6 @@ class Menu(object): else: return False, '|' - def generate_browser_list(self): - ######## starts the recursive process of listing all folders and video files to display ######## - self.browser_list = [] - for path in PATHS_TO_BROWSER: - self._add_folder_to_browser_list(path, 0) - - for browser_line in self.browser_list: - is_file, name = self.extract_file_type_and_name_from_browser_format(browser_line['name']) - if is_file: - is_slotted, bankslot_number = self._is_file_in_memory_bank(name) - if is_slotted: - browser_line['slot'] = bankslot_number - - def generate_settings_list(self): - self.settings_list = [] - for sub_setting in self.settings.keys(): - if sub_setting in self.settings_open_folders: - self.settings_list.append(dict(name=sub_setting + '/', value='')) - for setting in self.settings[sub_setting]: - setting_value = self.make_empty_if_none(self.settings[sub_setting][setting]['value']) - self.settings_list.append(dict(name=' ' + setting, value=setting_value)) - else: - self.settings_list.append(dict(name=sub_setting + '|', value='')) - @staticmethod def extract_file_type_and_name_from_menu_format(dir_name): # removes whitespace and folder state from display item ######## @@ -147,6 +123,7 @@ class SettingsMenu(Menu): OTHER_ORDER = [] def __init__(self, data, message_handler, menu_height): + Menu.__init__(self, data, message_handler, menu_height) self.generate_settings_list() @@ -190,9 +167,37 @@ class SettingsMenu(Menu): ordered_tuple_list.append((other_key, dictionary[other_key])) return ordered_tuple_list - - - +class ShadersMenu(Menu): + + def __init__(self, data, message_handler, menu_height): + Menu.__init__(self, data, message_handler, menu_height) + + def generate_raw_shaders_list(self): + ######## starts the recursive process of listing all folders and shader files to display ######## + self.menu_list = [] + for path in self.data.PATHS_TO_SHADERS: + self._add_folder_to_shaders_list(path, 0) + return self.menu_list + + + def _add_folder_to_shaders_list(self, current_path, current_level): + ######## adds the folders and shader files at the current level to the results list. recursively recalls at deeper level if folder is open ######## + + root, dirs, files = next(os.walk(current_path)) + + indent = ' ' * 4 * (current_level) + for folder in dirs: + is_open, char = self._check_folder_state(folder) + self.menu_list.append(dict(name='{}{}{}'.format(indent, folder, char), is_shader=False)) + if (is_open): + next_path = '{}/{}'.format(root, folder) + next_level = current_level + 1 + self._add_folder_to_shader_list(next_path, next_level) + + for f in files: + split_name = os.path.splitext(f) + if (split_name[1].lower() in ['.frag', '.shader', '.glsl', '.glslf', '.shader', '.fsh']): + self.menu_list.append(dict(name='{}{}'.format(indent, f), is_shader=True)) diff --git a/dotfiles/python_for_shutting_down_osc_server.py b/dotfiles/python_for_shutting_down_osc_server.py new file mode 100644 index 0000000..7c6cdf0 --- /dev/null +++ b/dotfiles/python_for_shutting_down_osc_server.py @@ -0,0 +1,17 @@ +from pythonosc import osc_message_builder +from pythonosc import udp_client +from pythonosc import dispatcher +import argparse + +def setup_osc_client(): + client_parser = argparse.ArgumentParser() + client_parser.add_argument("--ip", default="127.0.0.1", help="the ip") + client_parser.add_argument("--port", type=int, default=9000, help="the port") + + client_args = client_parser.parse_args() + + return udp_client.SimpleUDPClient(client_args.ip, client_args.port) + +client = setup_osc_client() + +client.send_message("/shutdown", True) diff --git a/r_e_c_u_r.py b/r_e_c_u_r.py index f57e365..8671be8 100755 --- a/r_e_c_u_r.py +++ b/r_e_c_u_r.py @@ -14,6 +14,7 @@ from user_input.midi_input import MidiInput from user_input.analog_input import AnalogInput from video_centre.video_driver import VideoDriver from video_centre.capture import Capture +from video_centre.shaders import Shaders import data_centre # create tk object @@ -31,12 +32,13 @@ data = Data(message_handler) # setup the video driver video_driver = VideoDriver(tk, message_handler, data) capture = Capture(tk, message_handler, data) +shaders = Shaders(tk, message_handler, data) # setup the display -display = Display(tk, video_driver, capture, message_handler, data) +display = Display(tk, video_driver, capture, shaders, message_handler, data) # setup the actions -actions = Actions(tk, message_handler, data, video_driver, capture, display) +actions = Actions(tk, message_handler, data, video_driver, capture, shaders, display) numpad_input = NumpadInput(tk, message_handler, display, actions, data) midi_input = MidiInput(tk, message_handler, display, actions, data) diff --git a/video_centre/alt_video_player.py b/video_centre/alt_video_player.py index 50e3ffa..e163ef5 100644 --- a/video_centre/alt_video_player.py +++ b/video_centre/alt_video_player.py @@ -103,7 +103,7 @@ class AltVideoPlayer: def toggle_pause(self): if self.status == "PLAYING": self.client.send_message("/player/{}/pause".format(self.name[0]), True) - elif self.status == "PAUSED": + elif self.status == "PAUSED" or self.status == "LOADED": self.client.send_message("/player/{}/play".format(self.name[0]), True) else: print("error toggling pause when video is neither playing or paused") diff --git a/video_centre/shaders.py b/video_centre/shaders.py new file mode 100644 index 0000000..dbf0c67 --- /dev/null +++ b/video_centre/shaders.py @@ -0,0 +1,63 @@ +import display_centre.menu as menu +import os + +class Shaders(object): + MENU_HEIGHT = 9 + EMPTY_SHADER = dict(name='none',is_shader=True,shad_type='-',param_number=0,path='-',shad_index=0) + def __init__(self, root, message_handler, data): + self.root = root + self.message_handler = message_handler + self.data = data + self.shaders_menu = menu.ShadersMenu(self.data, self.message_handler, self.MENU_HEIGHT) + self.selected_shader = self.EMPTY_SHADER + self.shaders_menu_list = self.generate_shaders_list() + print('shader list is {}'.format(self.shaders_menu_list)) + + # + + self.selected_status = '-' + self.selected_param_values = [0,0,0,0,0,0,0,0] + self.load_selected_shader() + + def generate_shaders_list(self): + shaders_menu_list = [] + raw_list = self.shaders_menu.generate_raw_shaders_list() + print('raw list is {}: '.format(raw_list)) + for line in raw_list: + shad_i = 0 + if line['is_shader']: + has_path, path = self.get_path_for_shader(line['name']) + shad_type = self.determine_if_shader_file_is_processing(path) + parameter_number = self.determine_shader_parameter_number(path) + shaders_menu_list.append(dict(name=line['name'],is_shader=True,shad_type=shad_type,param_number=parameter_number,path=path,shad_index=shad_i)) + shad_i = shad_i +1 + else: + shaders_menu_list.append(dict(name=line[name],is_shader=False,is_proc=None,param_number=None,path=None)) + return shaders_menu_list + + + def get_path_for_shader(self, file_name): + ######## returns full path for a given file name ######## + for path in self.data.PATHS_TO_SHADERS: + for root, dirs, files in os.walk(path): + if file_name in files: + return True, '{}/{}'.format(root, file_name) + return False, '' + + def determine_if_shader_file_is_processing(self, path): + pass + + def determine_shader_parameter_number(self, path): + pass + + def load_selected_shader(self): + pass + + def enter_on_shaders_selection(self): + is_file, name = self.shaders_menu.extract_file_type_and_name_from_menu_format( + self.menu_list[self.selected_list_index]['name']) + if is_file: + pass + else: + self.shader_menu.update_open_folders(name) + self.generate_shaders_list() diff --git a/video_centre/video_driver.py b/video_centre/video_driver.py index d4e5da1..bba18c8 100644 --- a/video_centre/video_driver.py +++ b/video_centre/video_driver.py @@ -158,6 +158,7 @@ class VideoDriver(object): this_dispatcher.map("/player/a/status", self.receive_status, "a.a") this_dispatcher.map("/player/b/status", self.receive_status, "b.b") this_dispatcher.map("/player/c/status", self.receive_status, "c.c") + this_dispatcher.map("/shutdown", self.exit_osc_server) #this_dispatcher.map("/player/a/status", self.set_status) server = osc_server.ThreadingOSCUDPServer((server_args.ip, server_args.port), this_dispatcher) @@ -165,7 +166,7 @@ class VideoDriver(object): server_thread.start() return server - def exit_osc_server(self): + def exit_osc_server(self, unused_addr, args): self.server.shutdown() def receive_position(self, unused_addr, player_name, args):