def create_scrollable_dialog(): def on_select(choice): print("Kytten is %s" % choice) def on_set(value): print("Kytten rating is %0.0f" % value) dialog = kytten.Dialog(kytten.Frame( kytten.Scrollable(kytten.VerticalLayout([ kytten.Label("Rate Kytten from 1 to 10:"), kytten.Slider(7.0, 1.0, 10.0, steps=9, on_set=on_set), kytten.Label("This slider is disabled:"), kytten.Slider( 1.0, 1.0, 10.0, steps=9, on_set=on_set, disabled=True), kytten.Label("Kytten is..."), kytten.Menu(options=[ "Awesome", "Cute", "-Disabled Option", "Excellent", "Fantastic", "Great", "Supercalifragilistiexpialidocious", "Terrific" ], align=kytten.HALIGN_LEFT, on_select=on_select), ], align=kytten.HALIGN_LEFT), width=200, height=150)), window=window, batch=batch, group=fg_group, anchor=kytten.ANCHOR_CENTER, theme=kytten.themes.felyne_light, on_escape=on_escape)
def do_add_new_field(self, fields_layout, on_input, on_delete): if self.popup is not None: self.popup.teardown() def do_cancel_add(dialog=None): self.popup.teardown() self.popup = None def do_add_field(dialog=None): global gDirty gDirty = True form = self.popup.get_values() self.popup.teardown() self.popup = None name = form['name'] if self.theme[self.path].has_key(name): self.popup_message("%s is already a field name!" % name) return try: value = safe_eval.safe_eval(form['value']) except kytten.safe_eval.Unsafe_Source_Error: value = form['value'] self.theme[self.path][name] = value fields_layout.add_row([ kytten.Label(name), kytten.Input(id=name, text=str(value), on_input=on_input), kytten.Button("Delete", id=name, on_click=on_delete) ]) if not self.delete_button.is_disabled(): self.delete_button.disable() self.dialog.set_needs_layout() self.popup = kytten.Dialog(kytten.Frame( kytten.VerticalLayout([ kytten.GridLayout([[ kytten.Label('Name'), kytten.Input(id='name', text='new_field') ], [ kytten.Label('Value'), kytten.Input(id='value', text='new_value') ]]), kytten.HorizontalLayout([ kytten.Button("Add", on_click=do_add_field), None, kytten.Button("Cancel", on_click=do_cancel_add) ]) ])), window=self.window, theme=gTheme, on_enter=do_add_field, on_escape=do_cancel_add)
def do_add_new_image(self): if self.popup is not None: self.popup.teardown() def do_cancel_add(dialog=None): self.popup.teardown() self.popup = None def do_add_image(dialog=None): global gDirty gDirty = True form = self.popup.get_values() self.popup.teardown() self.popup = None name = form['name'] if self.theme[self.path].has_key(name): self.popup_message("%s is already a field name!" % name) return if not name.startswith('image'): self.popup_message("Image names must begin with 'image'") texture = self.textures[form['texture']] self.theme[self.path][name] = FrameTextureGraphicElementTemplate( self.theme, texture, [0, 0, texture.width, texture.height], # stretch [0, 0, 0, 0]) # padding self.manager.push( ImageEditState(self.theme_dir, self.theme, self.textures, self.path, name)) self.popup = kytten.Dialog(kytten.Frame( kytten.VerticalLayout([ kytten.GridLayout([[ kytten.Label('Name'), kytten.Input(id='name', text='image') ], [ kytten.Label('Texture'), kytten.Dropdown( id='texture', options=self.textures.keys(), selected=self.textures.keys()[0]) ]]), kytten.HorizontalLayout([ kytten.Button("Add", on_click=do_add_image), None, kytten.Button("Cancel", on_click=do_cancel_add) ]) ])), window=self.window, theme=gTheme, on_enter=do_add_image, on_escape=do_cancel_add)
def _get_content(self): content = [kytten.Label("Theme: %s" % self.theme_dir)] if self.path: content += [kytten.Label("Path: %s" % '/'.join(self.path))] else: assert hasattr(self, 'name') self.file_label = kytten.Label("File: %s" % self.name) content += [self.file_label] content += [kytten.HorizontalLayout(self._get_buttons())] content += self._get_image_fields() content += self._get_custom_components() content += self._get_custom_fields() return content
def _get_custom_fields(self): # Handle all fields here that we don't have a basic handler for fields_layout = None def on_input(id, value): global gDirty gDirty = True try: self.theme[self.path][id] = safe_eval.safe_eval(value) except kytten.safe_eval.Unsafe_Source_Error: self.theme[self.path][id] = value def on_delete(id): self.do_delete_field(fields_layout, id) fields = [] items = self.theme[self.path].items() items.sort(lambda x, y: cmp(x[0], y[0])) index = 0 for k, v in items: if not k.startswith('image') and not isinstance(v, dict): if not k.endswith('color'): fields.append([ kytten.Label(k), kytten.Input(id=k, text=str(v), on_input=on_input), kytten.Button("Delete", id=k, on_click=on_delete) ]) else: fields.append([ kytten.Label(k), ColorSelector(id=k, color=v, on_select=on_input), kytten.Button("Delete", id=k, on_click=on_delete) ]) index += 1 fields_layout = kytten.GridLayout(fields) # Pop up a dialog if we want to add a new field def on_add_field(): self.do_add_new_field(fields_layout, on_input, on_delete) return [ kytten.FoldingSection( "Custom Fields", kytten.VerticalLayout([ kytten.GridLayout(fields, anchor=kytten.ANCHOR_LEFT), kytten.Button("Add Field", on_click=on_add_field), ])) ]
def do_save_as(self): if self.popup is not None: self.popup.teardown() def do_cancel_save_as(dialog): self.popup.teardown() self.popup = None def do_set_filename(dialog): form = dialog.get_values() filename = form['name'] if filename: name = os.path.join(self.theme_dir, filename) if os.path.isfile(name): self.popup_message("%s already exists" % filename) elif not filename.endswith('.json'): self.popup_message("%s must end in .json" % filename) else: self.name = filename self.file_label.label.text = 'File: %s' % self.name self.do_save() else: self.popup_message("Please select a file") self.popup = kytten.Dialog(kytten.Frame( kytten.HorizontalLayout( [kytten.Label("Filename"), kytten.Input(id='name')])), theme=gTheme, window=self.window, on_enter=do_set_filename, on_escape=do_cancel_save_as)
def do_add_field(dialog=None): global gDirty gDirty = True form = self.popup.get_values() self.popup.teardown() self.popup = None name = form['name'] if self.theme[self.path].has_key(name): self.popup_message("%s is already a field name!" % name) return try: value = safe_eval.safe_eval(form['value']) except kytten.safe_eval.Unsafe_Source_Error: value = form['value'] self.theme[self.path][name] = value fields_layout.add_row([ kytten.Label(name), kytten.Input(id=name, text=str(value), on_input=on_input), kytten.Button("Delete", id=name, on_click=on_delete) ]) if not self.delete_button.is_disabled(): self.delete_button.disable() self.dialog.set_needs_layout()
def on_show_state(self, window, manager): BaseState.on_show_state(self, window, manager) def on_theme_file_cancel(dialog): self.manager.pop() def on_theme_file_enter(dialog): form = dialog.get_values() filename = form['name'] if filename: name = os.path.join(self.theme_dir, filename) if os.path.isfile(name): self.popup_message("%s already exists" % filename) elif not filename.endswith('.json'): self.popup_message("%s must end in .json" % filename) else: self.set_theme_file(filename) else: self.popup_message("Please select a file") self.dialog = kytten.Dialog(kytten.TitleFrame( "kytten Theme Editor", kytten.VerticalLayout([ kytten.Label("Please select a theme file name"), kytten.Input(id='name') ]), ), window=window, anchor=kytten.ANCHOR_CENTER, theme=gTheme, on_escape=on_theme_file_cancel, on_enter=on_theme_file_enter)
def on_show_state(self, window, manager): BaseState.on_show_state(self, window, manager) def on_theme_file_select(filename): if filename: self.select_theme_file(filename) else: self.popup_message("Please select a file") def on_theme_file_cancel(dialog): self.manager.pop() json_files = glob.glob(os.path.join(self.theme_dir, '*.json')) json_files = [os.path.basename(x) for x in json_files] self.dialog = kytten.Dialog(kytten.TitleFrame( "kytten Theme Editor", kytten.VerticalLayout([ kytten.Label("Please select a theme file"), kytten.Menu(options=['(New File)'] + json_files, on_select=on_theme_file_select) ]), ), window=window, anchor=kytten.ANCHOR_CENTER, theme=gTheme, on_escape=on_theme_file_cancel)
def create_dropdown_dialog(): def on_select(choice): print("Selected: %s" % choice) dialog = kytten.Dialog(kytten.Frame( kytten.VerticalLayout([ kytten.Label("Select a letter:"), kytten.Dropdown([ 'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon', 'Phi', 'Chi', 'Psi', 'Omega' ], on_select=on_select), kytten.Label("This dropdown is disabled"), kytten.Dropdown(['Disabled', 'Enabled'], disabled=True), ]), ), window=window, batch=batch, group=fg_group, anchor=kytten.ANCHOR_CENTER, theme=kytten.themes.felyne_light, on_escape=on_escape)
def do_change_texture(self): if self.popup is not None: self.popup.teardown() def do_cancel_change(dialog=None): self.popup.teardown() self.popup = None def do_change_texture(dialog=None): global gDirty gDirty = True form = self.popup.get_values() self.popup.teardown() self.popup = None texture = self.textures[form['texture']] self.theme[self.path][self.image] = \ FrameTextureGraphicElementTemplate( self.theme, texture, [0, 0, texture.width, texture.height], # stretch [0, 0, 0, 0]) # padding manager = self.manager manager.pop() manager.push( ImageEditState(self.theme_dir, self.theme, self.textures, self.path, self.image)) self.popup = kytten.Dialog(kytten.Frame( kytten.VerticalLayout([ kytten.HorizontalLayout([ kytten.Label('Texture'), kytten.Dropdown(id='texture', options=self.textures.keys(), selected=self.textures.keys()[0]) ]), kytten.HorizontalLayout([ kytten.Button("Change", on_click=do_change_texture), None, kytten.Button("Cancel", on_click=do_cancel_change) ]), ])), window=self.window, theme=gTheme, on_enter=do_change_texture, on_escape=do_cancel_change)
def do_add_new_component(self): if self.popup is not None: self.popup.teardown() def do_cancel_add(dialog=None): self.popup.teardown() self.popup = None def do_add_component(dialog=None): global gDirty gDirty = True form = self.popup.get_values() self.popup.teardown() self.popup = None name = form['name'] if self.theme[self.path].has_key(name): self.popup_message("%s is already a field name!" % name) return self.theme[self.path][name] = {} self.manager.push( _NodeEditState(self.theme_dir, self.theme, self.textures, self.path + [name])) self.popup = kytten.Dialog(kytten.Frame( kytten.VerticalLayout([ kytten.HorizontalLayout([ kytten.Label('Name'), kytten.Input(id='name', text='new_component') ]), kytten.HorizontalLayout([ kytten.Button("Add", on_click=do_add_component), None, kytten.Button("Cancel", on_click=do_cancel_add) ]) ])), window=self.window, theme=gTheme, on_enter=do_add_component, on_escape=do_cancel_add)
def _get_content(self): def on_return(): self.manager.pop() def on_delete(): self.do_delete_image() def on_change_texture(): self.do_change_texture() content = [ kytten.VerticalLayout([ kytten.Document("""Theme: %s Path: %s Image: %s """ % (self.theme_dir, '/'.join(self.path), self.image), width=700), kytten.HorizontalLayout([ kytten.Button("Back", on_click=on_return), kytten.Button("Change Texture", on_click=on_change_texture), kytten.Button("Delete Image", on_click=on_delete) ]), ], align=kytten.HALIGN_LEFT) ] # Locate the base texture for the template self.template = self.theme[self.path][self.image] texture_id = self.template.texture.id our_texture = None our_filename = None for texture_name, texture in self.textures.iteritems(): if texture.id == texture_id: our_filename = texture_name our_texture = texture break assert our_texture is not None # Determine the region that we occupy x, y = self.template.texture.x, self.template.texture.y width, height = self.template.width, self.template.height self.region = (x, y, width, height) left, right, top, bottom = self.template.margins self.stretch = (left, bottom, width - right - left, height - top - bottom) self.padding = self.template.padding # Create the Resizable for the example's content example_resizable = Resizable(100, 100) def enable_example_resizable(is_checked): if is_checked: example_resizable.enable() else: example_resizable.disable() # Create the example example = kytten.Frame(example_resizable, path=self.path, image_name=self.image) # Create the ImageRegionPlacer for the editor region_placer = None def set_region(x, y, width, height): global gDirty gDirty = True if self.state == 'Region': # Try to keep stretch area the same but restrict it to # the current available region ox, oy, _, _ = self.region sx, sy, swidth, sheight = self.stretch sx += ox sy += oy if sx < x: swidth = max(0, swidth - x + sx) sx = x elif sx > x + width: swidth = 0 sx = x + width if sy < y: sheight = max(0, sheight - y + sy) sy = y elif sy > y + height: sheight = 0 sy = y + height if (sx - x) + swidth > width: swidth = max(0, width - (sx - x)) if (sy - y) + sheight > height: sheight = max(0, height - (sy - y)) self.region = (x, y, width, height) self.stretch = (sx - x, sy - y, swidth, sheight) elif self.state == 'Stretch': rx, ry, rwidth, rheight = self.region self.stretch = (x - rx, y - ry, width, height) else: # Padding rx, ry, rwidth, rheight = self.region left = x - rx bottom = y - ry top = ry + rheight - height - y right = rx + rwidth - width - x self.padding = (left, right, top, bottom) # Drop our old template and construct a new one x, y, width, height = self.region texture = self.theme._get_texture_region(our_filename, x, y, width, height) self.template = FrameTextureGraphicElementTemplate( self.theme, texture, self.stretch, self.padding) self.theme[self.path][self.image] = self.template example.delete() self.dialog.set_needs_layout() region_placer = ImageRegionPlacer(texture, x, y, width, height, on_resize=set_region) def set_placer_scale(scale): region_placer.set_scale(scale) # Create a drop-down to control what region we're setting def on_region_select(choice): self.state = choice if choice == 'Region': region_placer.set_region( *self.region, color=ImageRegionPlacer.IMAGE_REGION_COLOR) elif choice == 'Stretch': rx, ry, rwidth, rheight = self.region x, y, width, height = self.stretch region_placer.set_region( x + rx, y + ry, width, height, color=ImageRegionPlacer.IMAGE_STRETCH_COLOR, limits=self.region) else: # Padding rx, ry, rwidth, rheight = self.region left, right, top, bottom = self.padding region_placer.set_region( left + rx, bottom + ry, rwidth - left - right, rheight - top - bottom, color=ImageRegionPlacer.IMAGE_PADDING_COLOR, limits=self.region) region_control = kytten.Dropdown( options=['Region', 'Stretch', 'Padding'], selected=self.state, on_select=on_region_select) content += [ kytten.FoldingSection( 'Image Region', kytten.VerticalLayout([ region_control, region_placer, kytten.GridLayout([[ kytten.Label('Scale'), kytten.Slider(value=1.0, min_value=1.0, max_value=8.0, steps=7, width=400, on_set=set_placer_scale) ]], anchor=kytten.ANCHOR_LEFT) ], padding=10)), kytten.FoldingSection( 'Example', kytten.VerticalLayout([ ProxyDialog(example, self.theme), kytten.Checkbox("Show content sizer", on_click=enable_example_resizable, is_checked=True), ])), ] return content
480, caption='Kytten Test', resizable = True, vsync = False ) batch = pyglet.graphics.Batch() window.register_event_type('on_update') theme = kytten.Theme( os.path.join(os.getcwd(), 'theme') ) dialog = kytten.Dialog( kytten.TitleFrame( "Kytten Demo", kytten.VerticalLayout( [ kytten.Label("Drag Me!"), ] ), ), window = window, batch = batch, anchor = kytten.ANCHOR_TOP_LEFT, theme = theme ) @window.event def on_draw(): global window global batch window.clear() batch.draw()
def create_form_dialog(): dialog = None def on_enter(dialog): print("Form submitted!") for key, value in dialog.get_values().items(): print(" %s=%s" % (key, value)) on_escape(dialog) def on_submit(): on_enter(dialog) def on_cancel(): print("Form canceled.") on_escape(dialog) dialog = kytten.Dialog(kytten.Frame( kytten.Scrollable(kytten.VerticalLayout([ kytten.SectionHeader("Personnel Data", align=kytten.HALIGN_LEFT), kytten.Document( "Try tabbing through fields, " "if offscreen they'll be moved " "automatically", width=500), kytten.GridLayout([ [ kytten.Label("Name"), kytten.Input("name", "Lynx", max_length=20) ], [ kytten.Label("Job"), kytten.Input("job", "Cat", max_length=80) ], [kytten.Label("Hobby"), kytten.Input("hobby", "Programming")], [kytten.Label("Class"), kytten.Input("class", "Druid")], [ kytten.Label("Disabled"), kytten.Input("disabled", "Disabled input", disabled=True) ], [ kytten.Label("Sign"), kytten.Input("sign", "Free to good home") ], [kytten.Label("Blood Type"), kytten.Input("bloodtype", "Red")], [ kytten.Label("Favored Weapon"), kytten.Input("weapon", "Claws") ], ]), kytten.Checkbox("Full-Time", id="fulltime"), kytten.Checkbox("Married", id="married", disabled=True), kytten.SectionHeader("Actions", align=kytten.HALIGN_LEFT), kytten.HorizontalLayout([ kytten.Button("Submit", on_click=on_submit), kytten.Button("Disabled", disabled=True), None, kytten.Button("Cancel", on_click=on_cancel), ]), ], align=kytten.HALIGN_LEFT), height=200, width=360)), window=window, batch=batch, group=fg_group, anchor=kytten.ANCHOR_CENTER, theme=kytten.themes.felyne_light, on_enter=on_enter, on_escape=on_escape)
window.register_event_type('on_update') def update(dt): window.dispatch_event('on_update', dt) pyglet.clock.schedule(update) # Set up a background which changes when user hits left or right arrow # background = Background(batch=batch, group=bg_group) # window.push_handlers(background) # Set up a Dialog to choose test dialogs to show dialog = kytten.Dialog(kytten.TitleFrame( "Kytten Demo", kytten.VerticalLayout([ kytten.Label("Select dialog to show"), kytten.Menu(options=[ "Document", "Form", "Scrollable", "Folding", "Dropdown", "File Load", "File Save", "Directory Select" ], on_select=on_select), ]), ), window=window, batch=batch, group=fg_group, anchor=kytten.ANCHOR_TOP_LEFT, theme=kytten.themes.felyne_dark) window2 = kytten.Window( "Window",