def style_changed(new_style: Style) -> None: """Update the icons for the selected signage.""" for sign in Signage.all(): for potential_style in new_style.bases: try: icon = sign.styles[potential_style.id.upper()].icon break except KeyError: pass else: LOGGER.warning( 'No valid <{}> style for "{}" signage!', new_style.id, sign.id, ) try: icon = sign.styles['BEE2_CLEAN'].icon except KeyError: sign.dnd_icon = IMG_ERROR continue if icon: sign.dnd_icon = icon else: LOGGER.warning( 'No icon for "{}" signage in <{}> style!', sign.id, new_style.id, ) sign.dnd_icon = IMG_ERROR if window.winfo_ismapped(): drag_man.load_icons()
def style_changed(new_style: Style) -> None: """Update the icons for the selected signage.""" for sign in Signage.all(): for potential_style in new_style.bases: try: icon = sign.styles[potential_style.id.upper()].icon break except KeyError: pass else: LOGGER.warning( 'No valid <{}> style for "{}" signage!', new_style.id, sign.id, ) try: icon = sign.styles['BEE2_CLEAN'].icon except KeyError: sign.dnd_icon = img.img_error continue if icon: sign.dnd_icon = img.png(icon, resize_to=(64, 64)) else: LOGGER.warning( 'No icon for "{}" signage in <{}> style!', sign.id, new_style.id, ) sign.dnd_icon = img.img_error drag_man.refresh_icons()
def init_widgets(master: ttk.Frame) -> Optional[tk.Widget]: """Construct the widgets, returning the configuration button. If no signages are defined, this returns None. """ if not any(Signage.all()): return ttk.Label(master) window.resizable(True, True) window.title(gettext('Configure Signage')) frame_selected = ttk.Labelframe( window, text=gettext('Selected'), relief='raised', labelanchor='n', ) canv_all = tk.Canvas(window) scroll = tk_tools.HidingScroll(window, orient='vertical', command=canv_all.yview) canv_all['yscrollcommand'] = scroll.set name_label = ttk.Label(window, text='', justify='center') frame_preview = ttk.Frame(window, relief='raised', borderwidth=4) frame_selected.grid(row=0, column=0, sticky='nsew') ttk.Separator(orient='horizontal').grid(row=1, column=0, sticky='ew') name_label.grid(row=2, column=0) frame_preview.grid(row=3, column=0, pady=4) canv_all.grid(row=0, column=1, rowspan=4, sticky='nsew') scroll.grid(row=0, column=2, rowspan=4, sticky='ns') window.columnconfigure(1, weight=1) window.rowconfigure(3, weight=1) tk_tools.add_mousewheel(canv_all, canv_all, window) preview_left = ttk.Label(frame_preview, anchor='e') preview_right = ttk.Label(frame_preview, anchor='w') img.apply(preview_left, IMG_BLANK) img.apply(preview_right, IMG_BLANK) preview_left.grid(row=0, column=0) preview_right.grid(row=0, column=1) try: sign_arrow = Signage.by_id('SIGN_ARROW') except KeyError: LOGGER.warning('No arrow signage defined!') sign_arrow = None hover_arrow = False hover_toggle_id = None hover_sign: Optional[Signage] = None def hover_toggle() -> None: """Toggle between arrows and dual icons.""" nonlocal hover_arrow, hover_toggle_id hover_arrow = not hover_arrow if hover_sign is None: return if hover_arrow and sign_arrow: left = hover_sign.dnd_icon right = sign_arrow.dnd_icon else: try: left = Signage.by_id(hover_sign.prim_id or '').dnd_icon except KeyError: left = hover_sign.dnd_icon try: right = Signage.by_id(hover_sign.sec_id or '').dnd_icon except KeyError: right = IMG_BLANK img.apply(preview_left, left) img.apply(preview_right, right) hover_toggle_id = TK_ROOT.after(1000, hover_toggle) def on_hover(slot: dragdrop.Slot[Signage]) -> None: """Show the signage when hovered.""" nonlocal hover_arrow, hover_sign if slot.contents is not None: name_label['text'] = gettext('Signage: {}').format(slot.contents.name) hover_sign = slot.contents hover_arrow = True hover_toggle() else: on_leave(slot) def on_leave(slot: dragdrop.Slot[Signage]) -> None: """Reset the visible sign when left.""" nonlocal hover_toggle_id, hover_sign name_label['text'] = '' hover_sign = None if hover_toggle_id is not None: TK_ROOT.after_cancel(hover_toggle_id) hover_toggle_id = None img.apply(preview_left, IMG_BLANK) img.apply(preview_right, IMG_BLANK) drag_man.reg_callback(dragdrop.Event.HOVER_ENTER, on_hover) drag_man.reg_callback(dragdrop.Event.HOVER_EXIT, on_leave) for i in range(3, 31): SLOTS_SELECTED[i] = slot = drag_man.slot( frame_selected, source=False, label=f'00:{i:02g}' ) row, col = divmod(i-3, 4) slot.grid(row=row, column=col, padx=1, pady=1) prev_id = DEFAULT_IDS.get(i, '') if prev_id: try: slot.contents = Signage.by_id(prev_id) except KeyError: LOGGER.warning('Missing sign id: {}', prev_id) for sign in sorted(Signage.all(), key=lambda s: s.name): if not sign.hidden: slot = drag_man.slot(canv_all, source=True) slot.contents = sign drag_man.flow_slots(canv_all, drag_man.sources()) canv_all.bind( '<Configure>', lambda e: drag_man.flow_slots(canv_all, drag_man.sources()), ) def hide_window() -> None: """Hide the window.""" window.withdraw() drag_man.unload_icons() img.apply(preview_left, IMG_BLANK) img.apply(preview_right, IMG_BLANK) def show_window() -> None: """Show the window.""" drag_man.load_icons() window.deiconify() utils.center_win(window, TK_ROOT) window.protocol("WM_DELETE_WINDOW", hide_window) return ttk.Button( master, text=gettext('Configure Signage'), command=show_window, )