def render(self): self.config(height=40) seq_frame = Frame(self, **self.style.highlight) seq_frame.grid(row=0, column=0, sticky="nsew") seq_frame.pack_propagate(False) self.sequence = Entry(seq_frame, **self.style.input) self.sequence.place(x=0, y=0, relwidth=1, relheight=1, width=-40) self.sequence.set(self.value.sequence) self.sequence.configure(**self.style.no_highlight) self.sequence.focus_set() self.handler = Entry(self, **self.style.input) self.handler.grid(row=0, column=1, sticky="ew") self.handler.set(self.value.handler) self.handler.config(**self.style.highlight) self.add_arg = Checkbutton(self, **self.style.checkbutton) self.add_arg.grid(row=0, column=2, sticky="ew") self.add_arg.set(self.value.add) del_btn = Label(self, **self.style.button, image=get_icon_image("delete", 14, 14)) del_btn.grid(row=0, column=3, sticky='nswe') del_btn.bind("<Button-1>", self._delete_entry) # set the first two columns to expand evenly for column in range(2): self.grid_columnconfigure(column, weight=1, uniform=1) for widget in (self.sequence, self.handler): widget.on_change(self._on_value_change) self.add_arg._var.trace("w", lambda *_: self._on_value_change())
class ShortcutPicker(MessageDialog): def __init__(self, master, message, shortcut_pane=None): self.message = message super().__init__(master, self.render) self.title("Shortcut Picker") self.resizable(0, 0) self.geometry('350x200') self.value = None self.key = None self.shortcut_pane = shortcut_pane def on_key_change(self, event): self.key = KeyMap.get_key(event) if self.shortcut_pane is not None: routine = self.shortcut_pane.routine_from_shortcut(self.key) if routine is not None and self.shortcut_pane: self._warning['text'] = f"Key already assigned to {routine.desc}" self._warning.pack(fill="x") else: self._warning.pack_forget() self.event_pad.config(text=self.key.label) # returning break ensures this event does not propagate # preventing the event from invoking currently set bindings return "break" def render(self, _): self.detail = Label(self, **self.style.dark_text, text=self.message) self.detail.pack(fill="x") warn_frame = Frame(self, **self.style.dark) self._warning = Label( warn_frame, **self.style.dark_text_passive, padx=5, anchor='w', compound="left", image=get_tk_image("dialog_warning", 15, 15), ) self.event_pad = Label( self, **self.style.dark_text_accent) self._add_button(text="Cancel", value=None) self._add_button(text="Okay", command=self.exit_with_key, focus=True) warn_frame.pack(side="bottom", fill="x") self.event_pad.config( **self.style.bright, takefocus=True, text="Tap here to begin capturing shortcuts." ) self.event_pad.bind("<Any-KeyPress>", self.on_key_change) self.event_pad.bind("<Button-1>", lambda e: self.event_pad.focus_set()) self.event_pad.pack(fill="both", expand=True) def exit_with_key(self, _): self.value = self.key self.destroy() @classmethod def pick(cls, master, message, shortcut_pane=None): picker = cls(master, message, shortcut_pane) picker.wait_window() return picker.value
class Color(Editor): def __init__(self, master, style_def=None): super().__init__(master, style_def) self.config(**self.style.dark_highlight_active) self._entry = Entry(self, **self.style.dark_input, **self.style.no_highlight) self._color_button = Label(self, relief='groove', bd=1) self._color_button.bind('<ButtonRelease-1>', self._chooser) self._color_button.place(x=2, y=2, width=20, height=20) self._picker = ColorPicker(self, **self.style.dark_button) self._picker.place(relx=1, x=-22, y=0, width=20, height=20) self._picker.on_pick(self.set) self._entry.place(x=22, y=0, relheight=1, relwidth=1, width=-46) self._entry.on_change(self._change) def _change(self, value=None): value = self._entry.get() if value is None else value val = self._parse_color(value) if val: self._color_button.config(bg=value) if self._on_change: self._on_change(value) def _parse_color(self, value): try: val = self.winfo_rgb(value) except Exception: return "" val = tuple(map(lambda x: round((x / 65535) * 255), val)) return to_hex(val) def get(self): return self._entry.get() def set(self, value): self.adjust(value) def on_change(self, func, *args, **kwargs): super().on_change(func, *args, **kwargs) def adjust(self, value): self._entry.update_idletasks() self._entry.set(value) try: self._color_button.config(bg=value) except Exception: self._color_button.config(bg="#000000") def _chooser(self, *_): dialog = ColorDialog(self.window) dialog.update_idletasks() self.window.update_idletasks() dialog.post(self._color_button, side="auto", padding=4) if self.get().startswith("#"): dialog.set(self.get()) elif self.get(): dialog.set(self._parse_color(self.get())) dialog.on_change(self.adjust)
class Color(Editor): def __init__(self, master, style_def=None): super().__init__(master, style_def) self.config(**self.style.highlight_active) self._entry = Entry(self, **self.style.input, **self.style.no_highlight) self._color_button = Label(self, relief='groove', bd=1) self._color_button.bind('<ButtonRelease-1>', self._chooser) self._color_button.place(x=2, y=2, width=20, height=20) self._picker = ColorPicker(self, **self.style.button) self._picker.place(relx=1, x=-22, y=0, width=20, height=20) self._picker.on_pick(self._pick) self._entry.place(x=22, y=0, relheight=1, relwidth=1, width=-46) self._entry.on_change(self._change) def _change(self, value=None): value = self._entry.get() if value is None else value val = self._parse_color(value) if val is not None: self._color_button.config(bg=value or self._entry["bg"]) if self._on_change: self._on_change(value) def _pick(self, value): self.set(value) self._change(value) def _parse_color(self, value): if value == "" and self.style_def.get("allow_transparent", False): return value try: val = self.winfo_rgb(value) except Exception: return None val = tuple(map(lambda x: round((x / 65535) * 255), val)) return to_hex(val) def get(self): return self._entry.get() @suppress_change def set(self, value): self.adjust(value) def on_change(self, func, *args, **kwargs): super().on_change(func, *args, **kwargs) def adjust(self, value): self._entry.update_idletasks() self._entry.set(value) try: self._color_button.config(bg=value) except Exception: self._color_button.config(bg=self._entry["bg"]) def _chooser(self, *_): if self.get().startswith("#"): colour = self.get() elif self.get(): colour = self._parse_color(self.get()) else: colour = "#000000" dialog = ColorDialog(self.window, self._color_button, colour) dialog.set(colour) dialog.update_idletasks() self.window.update_idletasks() dialog.on_change(self.adjust)