def view_node( self, identifier=None ): # "view" button does not use identifier and uses self.current_node if identifier is None: identifier = self.current_node if self.history and identifier == self.history[-1]: return children = self.lookup(identifier) if children is None: return _layout = layout(*self.children_to_fields(children)) if self.viewer is not None: self.viewer.delete() self.viewer = self.bottom.create(Node_Viewer, target_object=self, layout=_layout, row_h_range=(0, .15), max_rows=10) if self.history: # need to check for contents before testing [-1] in case history is empty if self.history[-1] != identifier: self.history.append(identifier) else: self.history.append(identifier) self.current_node = identifier self.top.synchronize_fields()
def view_node(self, identifier=None): if identifier is None: identifier = self.current_node if self.history and identifier == self.history[-1]: return children = self.lookup(identifier) if children is None: return _layout = layout(*self.children_to_fields(children)) if self.viewer is not None: self.viewer.delete() viewer_type = self.viewer_type self.viewer = self.viewer_area.create(viewer_type, target_object=self, layout=_layout, max_rows=6, row_h_range=(0, .15)) if self.history: # need to check for contents before testing [-1] in case history is empty if self.history[-1] != identifier: self.history.append(identifier) else: self.history.append(identifier) self.current_node = identifier self.navbar.synchronize_fields()
def generate_options_layout(): return layout( row_info(0, field_info("save_theme", button_text="Save Theme", entry_kwargs={"scale_to_text" : False}), field_info("load_theme", button_text="Load Theme", entry_kwargs={"scale_to_text" : False}), h_range=(0, .1)), tab_bar_kwargs={"include_new_tab_button" : False})
def create_subcomponents(self): if self.target_theme is None: self.target_theme = self.theme theme = self.target_theme theme_editor_layout = generate_theme_editor_layout(theme) options_layout = generate_options_layout() self.layout = layout(links=(page("editor", theme_editor_layout), page("options", options_layout))) super(Theme_Editor, self).create_subcomponents()
class _File_Saver(pride.gui.form.Form): defaults = {"layout" : layout( row_info(0, field_info("filename"), field_info("save_data", button_text="save"))), "h_range" : (0, .25), "include_delete_button" : True, "form_name" : "File saver"}
def create_subcomponents(self): values = self.parent_field.values self.value_index = dict((value, i) for i, value in enumerate(values)) rows = (row_info(i, field_info("select_entry", button_text=str(value), args=(value, i), entry_kwargs={"scale_to_text" : False})) for i, value in enumerate(values)) _layout = layout(*rows) form = self.dropdown_form = self.create(Dropdown_Form, layout=_layout) form.select_entry(self.parent_field.values[0], 0)
def select_file(self, filename): super(File_Selector, self).select_file(filename) self.filename = filename if self.confirmation_box is None: _layout = layout( row_info(0, field_info("filename"), field_info("confirm_selection", button_text="Confirm"), field_info("delete_confirmation", button_text='x'))) box = self.main_window.create(pride.gui.form.Form, layout=_layout, target_object=self) self.confirmation_box = box else: self.confirmation_box.synchronize_fields()
def generate_theme_editor_layout(theme): names = sorted(theme.theme_colors.keys()) links = [] for theme_profile in names: _theme_profile = theme.theme_colors[theme_profile] _links = [] for color_profile in sorted(_theme_profile.keys()): _object = _theme_profile[color_profile] if isinstance(_object, int): _layout = layout(row_info(0, field_info(color_profile, minimum=0)), target_object=_theme_profile) else: _layout = \ layout(row_info(0, field_info('a', minimum=0, maximum=255)), row_info(1, field_info('r', minimum=0, maximum=255)), row_info(2, field_info('g', minimum=0, maximum=255)), row_info(3, field_info('b', minimum=0, maximum=255)), target_object=_object) interface = getattr(_object, "interface", (tuple(), tuple())) additional = tuple() for name in "rgba": if name not in interface: additional += (name, ) _object.interface = (interface[0], interface[1] + additional) _links.append(page(color_profile, _layout)) links.append(page(theme_profile, layout(links=_links, tab_bar_kwargs={"include_new_tab_button" : False}))) return layout(links=links)
def create_subcomponents(self): filename = self.filename alias = os.path.split(filename)[-1] manifest, manifest_data = load_resources((alias, filename)) control_page = \ page("controls", layout( row_info(0, field_info("filename", field_type="pride.gui.fields.Media_Field", play_when_opened=True)), manifest=manifest, filename=alias)) resource_id = manifest[alias] store_resource(resource_id, manifest_data[alias]) self.layout = control_page[1] #layout(links=(control_page, )) super(Media_Player, self).create_subcomponents()
def create_subcomponents(self): window = self.application_window _layout = layout( row_info( 0, field_info("handle_back", button_text='<', scale_to_text=True), field_info("handle_up", button_text="/\\", scale_to_text=True), field_info("current_node", display_name=self.node_label), field_info("view_node", button_text="view", scale_to_text=True), field_info("delete", button_text='x', scale_to_text=True))) self.top = window.create(pride.gui.form.Form, location="top", target_object=self, h_range=(0, .1), layout=_layout) self.bottom = window.create("pride.gui.gui.Container", location="top")
class Prompt(pride.gui.form.Form): defaults = {"prompt_text" : '', "layout" : layout( row_info(0, field_info("prompt_text", editable=False, has_label=False, entry_kwargs={"theme_profile" : "default", "scale_to_text" : False, "hoverable" :False}), field_info("handle_yes", orientation="stacked", button_text="Yes"), field_info("handle_no", orientation="stacked", button_text="No"))), "location" : "top", "h_range" : (.25, .25), "include_delete_button" : True } def handle_yes(self): raise NotImplementedError() def handle_no(self): raise NotImplementedError()
class Media_Player(pride.gui.form.Form): defaults = {"_volume_requested" : None, "volume" : 100, "layout" : layout(row_info(0, field_info("resource_alias", label_kwargs={"text" : "resource name"}), field_info("volume", minimum=0, maximum=100)), row_info(1, field_info("track_position", minimum=0, maximum=1000, auto_create_id=False, label_kwargs={"text" : "track position"}, entry_kwargs={"include_minmax_buttons" : False, "include_incdec_buttons" : False, "hide_text" : True}), field_info("time_info", editable=False, auto_create_id=False, w_range=(0, .15), label_kwargs={"text" : "time"})), row_info(2, field_info("handle_play", button_text="|>", entry_kwargs={"scale_to_text" : False}), field_info("handle_stop", button_text="[]", entry_kwargs={"scale_to_text" : False}), field_info("handle_pause", button_text="||", entry_kwargs={"scale_to_text" : False}), field_info("handle_previous", button_text="<<", entry_kwargs={"scale_to_text" : False}), field_info("handle_next", button_text=">>", entry_kwargs={"scale_to_text" : False})) ), "_synchronize_instruction" : None} mutable_defaults = {"player" : vlc.MediaPlayer} verbosity = {"vlc_error" : "v"} parser_args = ("volume", ) def _get_track_position(self): output = int(round(1000 * self.player.get_position())) if output == -100: output = 0 return output def _set_track_position(self, value): adjusted = value / 1000.0 self.player.set_position(adjusted) track_position = property(_get_track_position, _set_track_position) def _get_volume(self): output = self.player.audio_get_volume() if output == -1: output = 0 return output def _set_volume(self, value): value = min(100, max(0, value)) self.player.audio_set_volume(value) # vlc cannot adjust volume while not playing/paused after = self.volume if after != value: # defer setting volume until play begins/resumes self._volume_requested = value volume = property(_get_volume, _set_volume) def _get_time_info(self): player = self.player progress = self._format_time(player.get_time()) total = self._format_time(player.get_length()) return "{}/{}".format(progress, total) time_info = property(_get_time_info) def _format_time(self, ms): progressf = [] seconds = int(floor(ms / 1000.0)) if seconds < 0: seconds = 0 minutes = int(floor(seconds / 60.0)) hours = int(floor(minutes / 60.0)) progressf.append(hours) progressf.append(minutes % 60) progressf.append(seconds % 60) if not hours: #if not minutes: # output = str(seconds).zfill(2) #else: output = ':'.join(str(item).zfill(2) for item in progressf[1:]) else: output = ':'.join(str(item).zfill(2) for item in progressf) return output def _get_resource_alias(self): media_entry = self.parent media_field = media_entry.parent_field form = media_field.parent_form return media_field.value def _set_resource_alias(self, value): self.parent.parent_field.value = value resource_alias = property(_get_resource_alias, _set_resource_alias) def _get_resource_filename(self): media_entry = self.parent media_field = media_entry.parent_field form = media_field.parent_form resource_id = form.manifest[self.resource_alias] resource_filename = os.path.join(pride.site_config.RESOURCE_DIRECTORY, resource_id) return resource_filename resource_filename = property(_get_resource_filename) def __init__(self, **kwargs): super(Media_Player, self).__init__(**kwargs) self.player.set_mrl(self.resource_filename) media_field = self.parent.parent_field if media_field.play_when_opened: self.handle_play() def create_subcomponents(self): super(Media_Player, self).create_subcomponents() self.disable_sliders() def disable_sliders(self): self.rows[0].fields[1].editable = False self.rows[1].fields[0].editable = False def enable_sliders(self): self.rows[0].fields[1].editable = True self.rows[1].fields[0].editable = True def handle_value_changed(self, field, old, new): if field.name == "resource_alias": if self.player.is_playing(): self.player.stop() try: self.player.set_mrl(self.resource_filename) except KeyError: pass elif field.name == "volume": field.update_position_from_value() super(Media_Player, self).handle_value_changed(field, old, new) def handle_play(self): should_play = True try: filename = self.resource_filename except KeyError: message = "No resource named '{}'".format(self.resource_alias) self.show_status(message) should_play = False if should_play: self.show_status("Playing {}".format(self.resource_alias)) player = self.player player.play() if self._volume_requested is not None: self.volume = self._volume_requested self._volume_requested = None self.enable_slider_synchronization() self.enable_sliders() def enable_slider_synchronization(self): inst = pride.Instruction(self.reference, "synchronize_slider") if self._synchronize_instruction is None: self._synchronize_instruction = inst inst.execute(priority=1) self._slider_synchronization_enabled = True def disable_slider_synchronization(self): if self._synchronize_instruction is not None: self._synchronize_instruction.unschedule() self._slider_synchronization_enabled = False def synchronize_slider(self): state = self.player.get_state() disable = False if state == vlc.State.Error: self.alert("VLC Error", verbosity=self.verbosity["vlc_error"]) self.show_status("VLC Error") disable = True elif state == vlc.State.Ended: self.show_status("Playback ended") disable = True if disable: self.disable_slider_synchronization() self.disable_sliders() rows = self.rows volume_bar = rows[0].fields[1] volume_bar.entry.texture_invalid = True volume_bar.update_position_from_value() fields = self.rows[1].fields seek_bar = fields[0] seek_bar.entry.texture_invalid = True seek_bar.update_position_from_value() if self._slider_synchronization_enabled: self._synchronize_instruction.execute(priority=1) time_info = fields[1] time_info.entry.texture_invalid = True def handle_stop(self): self.show_status("Stopping {}".format(self.resource_alias)) self.player.stop() self.track_position = 0 self.disable_slider_synchronization() self.synchronize_slider() self.disable_sliders() def handle_pause(self): self.show_status("Pausing {}".format(self.resource_alias)) self.player.pause() if hasattr(self, "_synchronize_instruction"): self.disable_slider_synchronization() def handle_previous(self): self.show_status("Back")# to {}".format(self.prior_filename)) def handle_next(self): self.show_status("Next")# to {}".format(self.playlist)) def delete(self): self.disable_slider_synchronization() self.player.release() del self.player super(Media_Player, self).delete()
def test_Remote_Form(): import pride.gui.main from pride.gui.form import (layout, row_info, field_info, load_resource_data, generate_manifest) images_dir = pride.site_config.IMAGES_DIRECTORY image_filename = os.path.join(images_dir, "testimage.png") image_data = load_resource_data(image_filename) audio_dir = pride.site_config.GUI_RESOURCES_DIRECTORY audio_filename = os.path.join(audio_dir, "testaudio.ogg") audio_data = load_resource_data(audio_filename) manifest_data = {"/images/testimage.png" : image_data, "/audio/testaudio.ogg" : audio_data} manifest = generate_manifest(manifest_data) resource_filename = os.path.join(pride.site_config.RESOURCE_DIRECTORY, manifest["/images/testimage.png"]) with open(resource_filename, "wb") as _file: _file.write(image_data) _file.flush() with open(os.path.join(pride.site_config.RESOURCE_DIRECTORY, manifest["/audio/testaudio.ogg"]), "wb") as _file: _file.write(audio_data) _file.flush() _layout = layout(row_info(0, field_info("test_bool"), field_info("test_text"), field_info("test_int"), h_range=(0, .2)), row_info(1, field_info("test_slider", minimum=0, maximum=100), field_info("test_dropdown", orientation="stacked", values=(0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144)), field_info("delete", button_text="Delete (Test Callable)"), h_range=(0, .3)), row_info(2, field_info("test_image", field_type="pride.gui.fields.Image_Field")), row_info(3, field_info("test_audio", field_type="pride.gui.fields.Media_Field")), row_info(4), row_info(5, field_info("test_bool")), test_bool=True, test_text="Text", test_int=0, test_slider=50, test_dropdown=0, test_image="/images/testimage.png", test_audio="/audio/testaudio.ogg", manifest=manifest, layout_name="Form2 test layout") class Test_Form(Remote_Form): defaults = {"layout" : _layout} def test_callable(self): self.alert("test_callable") pride.gui.main.run_programs([Test_Form])