def init_widgets(): """Initiallise all the window components.""" global prop_window prop_window = Toplevel(TK_ROOT) prop_window.overrideredirect(1) prop_window.resizable(False, False) prop_window.transient(master=TK_ROOT) prop_window.attributes('-topmost', 1) prop_window.withdraw() # starts hidden f = ttk.Frame(prop_window, relief="raised", borderwidth="4") f.grid(row=0, column=0) ttk.Label( f, text="Properties:", anchor="center", ).grid( row=0, column=0, columnspan=3, sticky="EW", ) wid['name'] = ttk.Label(f, text="", anchor="center") wid['name'].grid(row=1, column=0, columnspan=3, sticky="EW") wid['ent_count'] = ttk.Label( f, text="", anchor="e", compound="left", image=png.spr('gear_ent'), ) wid['ent_count'].grid(row=0, column=2, rowspan=2, sticky=E) tooltip.add_tooltip( wid['ent_count'], 'The number of entities used for this item. The Source engine limits ' 'this to 2048 in total. This provides a guide to how many of these ' 'items can be placed in a map at once.' ) wid['author'] = ttk.Label(f, text="", anchor="center", relief="sunken") wid['author'].grid(row=2, column=0, columnspan=3, sticky="EW") sub_frame = ttk.Frame(f, borderwidth=4, relief="sunken") sub_frame.grid(column=0, columnspan=3, row=3) for i in range(5): wid['subitem', i] = ttk.Label( sub_frame, image=png.png('BEE2/alpha_64'), ) wid['subitem', i].grid(row=0, column=i) utils.bind_leftclick( wid['subitem', i], functools.partial(sub_sel, i), ) utils.bind_rightclick( wid['subitem', i], functools.partial(sub_open, i), ) wid['wip_dep'] = ttk.Label(f, text='', anchor="nw") wid['wip_dep'].grid(row=4, column=0, sticky="NW") ttk.Label(f, text="Description:", anchor="sw").grid( row=4, column=0, sticky="SW", ) spr_frame = ttk.Frame(f, borderwidth=4, relief="sunken") spr_frame.grid(column=1, columnspan=2, row=4, sticky=W) # sprites: inputs, outputs, rotation handle, occupied/embed state, # desiredFacing for spr_id in SPR: wid['sprite', spr_id] = sprite = ttk.Label( spr_frame, image=png.spr('ap_grey'), relief="raised", ) sprite.grid(row=0, column=spr_id.value) tooltip.add_tooltip(sprite) desc_frame = ttk.Frame(f, borderwidth=4, relief="sunken") desc_frame.grid(row=5, column=0, columnspan=3, sticky="EW") desc_frame.columnconfigure(0, weight=1) wid['desc'] = tkRichText(desc_frame, width=40, height=8) wid['desc'].grid(row=0, column=0, sticky="EW") desc_scroll = tk_tools.HidingScroll( desc_frame, orient=VERTICAL, command=wid['desc'].yview, ) wid['desc']['yscrollcommand'] = desc_scroll.set desc_scroll.grid(row=0, column=1, sticky="NS") def show_more_info(): url = selected_item.url if url is not None: try: webbrowser.open(url, new=OPEN_IN_TAB, autoraise=True) except webbrowser.Error: if messagebox.askyesno( icon="error", title="BEE2 - Error", message='Failed to open a web browser. Do you wish for ' 'the URL to be copied to the clipboard ' 'instead?', detail='"{!s}"'.format(url), parent=prop_window ): LOGGER.info("Saving {} to clipboard!", url) TK_ROOT.clipboard_clear() TK_ROOT.clipboard_append(url) # Either the webbrowser or the messagebox could cause the # properties to move behind the main window, so hide it # so it doesn't appear there. hide_context(None) wid['moreinfo'] = ttk.Button(f, text="More Info>>", command=show_more_info) wid['moreinfo'].grid(row=6, column=2, sticky=E) tooltip.add_tooltip(wid['moreinfo']) menu_info = Menu(wid['moreinfo']) menu_info.add_command(label='', state='disabled') def show_item_props(): snd.fx('expand') itemPropWin.show_window( selected_item.get_properties(), wid['changedefaults'], selected_sub_item.name, ) wid['changedefaults'] = ttk.Button( f, text="Change Defaults...", command=show_item_props, ) wid['changedefaults'].grid(row=6, column=1) tooltip.add_tooltip( wid['changedefaults'], 'Change the default settings for this item when placed.' ) wid['variant'] = ttk.Combobox( f, values=['VERSION'], exportselection=0, # On Mac this defaults to being way too wide! width=7 if utils.MAC else None, ) wid['variant'].state(['readonly']) # Prevent directly typing in values wid['variant'].bind('<<ComboboxSelected>>', set_item_version) wid['variant'].current(0) wid['variant'].grid(row=6, column=0, sticky=W) itemPropWin.init(hide_item_props)
def init_widgets(): """Initiallise all the window components.""" global prop_window prop_window = Toplevel(TK_ROOT) prop_window.overrideredirect(1) prop_window.resizable(False, False) prop_window.transient(master=TK_ROOT) prop_window.attributes('-topmost', 1) prop_window.withdraw() # starts hidden f = ttk.Frame(prop_window, relief="raised", borderwidth="4") f.grid(row=0, column=0) ttk.Label( f, text="Properties:", anchor="center", ).grid( row=0, column=0, columnspan=3, sticky="EW", ) wid['name'] = ttk.Label(f, text="", anchor="center") wid['name'].grid(row=1, column=0, columnspan=3, sticky="EW") wid['ent_count'] = ttk.Label( f, text="", anchor="e", compound="left", image=img.spr('gear_ent'), ) wid['ent_count'].grid(row=0, column=2, rowspan=2, sticky=E) tooltip.add_tooltip( wid['ent_count'], _('The number of entities used for this item. The Source engine ' 'limits this to 2048 in total. This provides a guide to how many of ' 'these items can be placed in a map at once.')) wid['author'] = ttk.Label(f, text="", anchor="center", relief="sunken") wid['author'].grid(row=2, column=0, columnspan=3, sticky="EW") sub_frame = ttk.Frame(f, borderwidth=4, relief="sunken") sub_frame.grid(column=0, columnspan=3, row=3) for i in range(5): wid['subitem', i] = ttk.Label( sub_frame, image=img.invis_square(64), ) wid['subitem', i].grid(row=0, column=i) utils.bind_leftclick( wid['subitem', i], functools.partial(sub_sel, i), ) utils.bind_rightclick( wid['subitem', i], functools.partial(sub_open, i), ) ttk.Label(f, text=_("Description:"), anchor="sw").grid( row=4, column=0, sticky="SW", ) spr_frame = ttk.Frame(f, borderwidth=4, relief="sunken") spr_frame.grid(column=1, columnspan=2, row=4, sticky=W) # sprites: inputs, outputs, rotation handle, occupied/embed state, # desiredFacing for spr_id in SPR: wid['sprite', spr_id] = sprite = ttk.Label( spr_frame, image=img.spr('ap_grey'), relief="raised", ) sprite.grid(row=0, column=spr_id.value) tooltip.add_tooltip(sprite) desc_frame = ttk.Frame(f, borderwidth=4, relief="sunken") desc_frame.grid(row=5, column=0, columnspan=3, sticky="EW") desc_frame.columnconfigure(0, weight=1) wid['desc'] = tkRichText(desc_frame, width=40, height=16) wid['desc'].grid(row=0, column=0, sticky="EW") desc_scroll = tk_tools.HidingScroll( desc_frame, orient=VERTICAL, command=wid['desc'].yview, ) wid['desc']['yscrollcommand'] = desc_scroll.set desc_scroll.grid(row=0, column=1, sticky="NS") def show_more_info(): url = selected_item.url if url is not None: try: webbrowser.open(url, new=OPEN_IN_TAB, autoraise=True) except webbrowser.Error: if messagebox.askyesno( icon="error", title="BEE2 - Error", message=_('Failed to open a web browser. Do you wish ' 'for the URL to be copied to the clipboard ' 'instead?'), detail='"{!s}"'.format(url), parent=prop_window): LOGGER.info("Saving {} to clipboard!", url) TK_ROOT.clipboard_clear() TK_ROOT.clipboard_append(url) # Either the webbrowser or the messagebox could cause the # properties to move behind the main window, so hide it # so it doesn't appear there. hide_context(None) wid['moreinfo'] = ttk.Button(f, text=_("More Info>>"), command=show_more_info) wid['moreinfo'].grid(row=6, column=2, sticky=E) tooltip.add_tooltip(wid['moreinfo']) menu_info = Menu(wid['moreinfo']) menu_info.add_command(label='', state='disabled') def show_item_props(): snd.fx('expand') itemPropWin.show_window( selected_item.get_properties(), wid['changedefaults'], selected_sub_item.name, ) wid['changedefaults'] = ttk.Button( f, text=_("Change Defaults..."), command=show_item_props, ) wid['changedefaults'].grid(row=6, column=1) tooltip.add_tooltip( wid['changedefaults'], _('Change the default settings for this item when placed.')) wid['variant'] = ttk.Combobox( f, values=['VERSION'], exportselection=0, # On Mac this defaults to being way too wide! width=7 if utils.MAC else None, ) wid['variant'].state(['readonly']) # Prevent directly typing in values wid['variant'].bind('<<ComboboxSelected>>', set_item_version) wid['variant'].current(0) wid['variant'].grid(row=6, column=0, sticky=W) itemPropWin.init(hide_item_props)
def set_sprite(pos, sprite): """Set one of the property sprites to a value.""" widget = wid['sprite', pos] widget['image'] = png.spr(sprite) widget.tooltip_text = SPRITE_TOOL.get(sprite, '')
def set_sprite(pos, sprite): """Set one of the property sprites to a value.""" widget = wid['sprite', pos] widget['image'] = img.spr(sprite) widget.tooltip_text = SPRITE_TOOL.get(sprite, '')
def set_sprite(pos, sprite): """Set one of the property sprites to a value.""" widget = wid['sprite', pos] widget['image'] = img.spr(sprite) tooltip.set_tooltip(widget, SPRITE_TOOL.get(sprite, ''))
def load_item_data(): """Refresh the window to use the selected item's data.""" global version_lookup item_data = selected_item.data for ind, pos in enumerate(SUBITEM_POS[selected_item.num_sub]): if pos == -1: wid['subitem'][ind]['image'] = png.png('BEE2/alpha_64') else: wid['subitem'][ind]['image'] = selected_item.get_icon(pos) wid['subitem'][ind]['relief'] = 'flat' wid['subitem'][pos_for_item()]['relief'] = 'raised' wid['author']['text'] = ', '.join(item_data['auth']) wid['name']['text'] = selected_sub_item.name wid['ent_count']['text'] = item_data['ent'] wid['desc'].set_text( get_description( global_last=selected_item.item.glob_desc_last, glob_desc=selected_item.item.glob_desc, style_desc=item_data['desc'] ) ) if itemPropWin.can_edit(selected_item.properties()): wid['changedefaults'].state(['!disabled']) else: wid['changedefaults'].state(['disabled']) if selected_item.is_wip and selected_item.is_dep: wid['wip_dep']['text'] = 'WIP, Deprecated Item!' elif selected_item.is_wip: wid['wip_dep']['text'] = 'WIP Item!' elif selected_item.is_dep: wid['wip_dep']['text'] = 'Deprecated Item!' else: wid['wip_dep']['text'] = '' version_lookup, version_names = selected_item.get_version_names() if len(version_names) <= 1: # There aren't any alternates to choose from, disable the box wid['variant'].state(['disabled']) # We want to display WIP / Dep tags still, so users know. if selected_item.is_wip and selected_item.is_dep: wid['variant']['values'] = ['[WIP] [DEP] No Alts!'] elif selected_item.is_wip: wid['variant']['values'] = ['[WIP] No Alt Versions!'] elif selected_item.is_dep: wid['variant']['values'] = ['[DEP] No Alt Versions!'] else: wid['variant']['values'] = ['No Alternate Versions!'] wid['variant'].current(0) else: wid['variant'].state(['!disabled']) wid['variant']['values'] = version_names wid['variant'].current(version_lookup.index(selected_item.selected_ver)) if selected_item.url is None: wid['moreinfo'].state(['disabled']) else: wid['moreinfo'].state(['!disabled']) wid['moreinfo'].tooltip_text = selected_item.url editor_data = item_data['editor'] has_inputs = False has_polarity = False has_outputs = False for inp_list in editor_data.find_all("Exporting", "Inputs"): for inp in inp_list: if inp.name == "connection_standard": has_inputs = True elif inp.name == "connection_tbeam_polarity": has_polarity = True for out_list in editor_data.find_all("Exporting", "Outputs"): for out in out_list: if out.name == "connection_standard": has_outputs = True break has_timer = any(editor_data.find_all("Properties", "TimerDelay")) editor_bit = next(editor_data.find_all("Editor")) rot_type = editor_bit["MovementHandle", "HANDLE_NONE"].casefold() facing_type = editor_bit["InvalidSurface", ""].casefold() surf_wall = "wall" in facing_type surf_floor = "floor" in facing_type surf_ceil = "ceiling" in facing_type is_embed = any(editor_data.find_all("Exporting", "EmbeddedVoxels")) if has_inputs: if has_polarity: wid['sprite'][0]['image'] = png.spr('in_polarity') else: wid['sprite'][0]['image'] = png.spr('in_norm') else: wid['sprite'][0]['image'] = png.spr('in_none') if has_outputs: if has_timer: wid['sprite'][1]['image'] = png.spr('out_tim') else: wid['sprite'][1]['image'] = png.spr('out_norm') else: wid['sprite'][1]['image'] = png.spr('out_none') wid['sprite'][2]['image'] = png.spr( ROT_TYPES.get( rot_type.casefold(), 'rot_none', ) ) if is_embed: wid['sprite'][3]['image'] = png.spr('space_embed') else: wid['sprite'][3]['image'] = png.spr('space_none') face_spr = "surf" if not surf_wall: face_spr += "_wall" if not surf_floor: face_spr += "_floor" if not surf_ceil: face_spr += "_ceil" if face_spr == "surf": face_spr += "_none" wid['sprite'][4]['image'] = png.spr(face_spr)
def load_item_data(): """Refresh the window to use the selected item's data.""" global version_lookup item_data = selected_item.data for ind, pos in enumerate(SUBITEM_POS[selected_item.num_sub]): if pos == -1: wid['subitem'][ind]['image'] = png.png('BEE2/alpha_64') else: wid['subitem'][ind]['image'] = selected_item.get_icon(pos) wid['subitem'][ind]['relief'] = 'flat' wid['subitem'][pos_for_item()]['relief'] = 'raised' wid['author']['text'] = ', '.join(item_data['auth']) wid['name']['text'] = selected_sub_item.name wid['ent_count']['text'] = item_data['ent'] wid['desc'].set_text( get_description(global_last=selected_item.item.glob_desc_last, glob_desc=selected_item.item.glob_desc, style_desc=item_data['desc'])) if itemPropWin.can_edit(selected_item.properties()): wid['changedefaults'].state(['!disabled']) else: wid['changedefaults'].state(['disabled']) if selected_item.is_wip and selected_item.is_dep: wid['wip_dep']['text'] = 'WIP, Deprecated Item!' elif selected_item.is_wip: wid['wip_dep']['text'] = 'WIP Item!' elif selected_item.is_dep: wid['wip_dep']['text'] = 'Deprecated Item!' else: wid['wip_dep']['text'] = '' version_lookup, version_names = selected_item.get_version_names() if len(version_names) <= 1: # There aren't any alternates to choose from, disable the box wid['variant'].state(['disabled']) # We want to display WIP / Dep tags still, so users know. if selected_item.is_wip and selected_item.is_dep: wid['variant']['values'] = ['[WIP] [DEP] No Alts!'] elif selected_item.is_wip: wid['variant']['values'] = ['[WIP] No Alt Versions!'] elif selected_item.is_dep: wid['variant']['values'] = ['[DEP] No Alt Versions!'] else: wid['variant']['values'] = ['No Alternate Versions!'] wid['variant'].current(0) else: wid['variant'].state(['!disabled']) wid['variant']['values'] = version_names wid['variant'].current(version_lookup.index( selected_item.selected_ver)) if selected_item.url is None: wid['moreinfo'].state(['disabled']) else: wid['moreinfo'].state(['!disabled']) wid['moreinfo'].tooltip_text = selected_item.url editor_data = item_data['editor'] has_inputs = False has_polarity = False has_outputs = False for inp_list in editor_data.find_all("Exporting", "Inputs"): for inp in inp_list: if inp.name == "CONNECTION_STANDARD": has_inputs = True elif inp.name == "CONNECTION_TBEAM_POLARITY": has_polarity = True for out_list in editor_data.find_all("Exporting", "Outputs"): for out in out_list: if out.name == "CONNECTION_STANDARD": has_outputs = True break has_timer = any(editor_data.find_all("Properties", "TimerDelay")) editor_bit = next(editor_data.find_all("Editor")) rot_type = editor_bit["MovementHandle", "HANDLE_NONE"].casefold() facing_type = editor_bit["InvalidSurface", ""].casefold() surf_wall = "wall" in facing_type surf_floor = "floor" in facing_type surf_ceil = "ceiling" in facing_type is_embed = any(editor_data.find_all("Exporting", "EmbeddedVoxels")) if has_inputs: if has_polarity: wid['sprite'][0]['image'] = png.spr('in_polarity') else: wid['sprite'][0]['image'] = png.spr('in_norm') else: wid['sprite'][0]['image'] = png.spr('in_none') if has_outputs: if has_timer: wid['sprite'][1]['image'] = png.spr('out_tim') else: wid['sprite'][1]['image'] = png.spr('out_norm') else: wid['sprite'][1]['image'] = png.spr('out_none') wid['sprite'][2]['image'] = png.spr( ROT_TYPES.get( rot_type.casefold(), 'rot_none', )) if is_embed: wid['sprite'][3]['image'] = png.spr('space_embed') else: wid['sprite'][3]['image'] = png.spr('space_none') face_spr = "surf" if not surf_wall: face_spr += "_wall" if not surf_floor: face_spr += "_floor" if not surf_ceil: face_spr += "_ceil" if face_spr == "surf": face_spr += "_none" wid['sprite'][4]['image'] = png.spr(face_spr)
def init_widgets(): """Initiallise all the window components.""" global prop_window, moreinfo_win prop_window = Toplevel(TK_ROOT) prop_window.overrideredirect(1) prop_window.resizable(False, False) prop_window.transient(master=TK_ROOT) prop_window.attributes('-topmost', 1) prop_window.relX = 0 prop_window.relY = 0 prop_window.withdraw() # starts hidden f = ttk.Frame(prop_window, relief="raised", borderwidth="4") f.grid(row=0, column=0) ttk.Label( f, text="Properties:", anchor="center", ).grid( row=0, column=0, columnspan=3, sticky="EW", ) wid['name'] = ttk.Label(f, text="", anchor="center") wid['name'].grid(row=1, column=0, columnspan=3, sticky="EW") wid['ent_count'] = ttk.Label( f, text="2", anchor="e", compound="left", image=png.spr('gear_ent'), ) wid['ent_count'].grid(row=0, column=2, rowspan=2, sticky=E) wid['author'] = ttk.Label(f, text="", anchor="center", relief="sunken") wid['author'].grid(row=2, column=0, columnspan=3, sticky="EW") sub_frame = ttk.Frame(f, borderwidth=4, relief="sunken") sub_frame.grid(column=0, columnspan=3, row=3) for i, _ in enumerate(wid['subitem']): wid['subitem'][i] = ttk.Label( sub_frame, image=png.png('BEE2/alpha_64'), ) wid['subitem'][i].grid(row=0, column=i) wid['subitem'][i].bind('<Button-1>', functools.partial(sub_sel, i)) wid['subitem'][i].bind('<Button-3>', functools.partial(sub_open, i)) wid['wip_dep'] = ttk.Label(f, text='', anchor="nw") wid['wip_dep'].grid(row=4, column=0, sticky="NW") ttk.Label(f, text="Description:", anchor="sw").grid( row=4, column=0, sticky="SW", ) spr_frame = ttk.Frame(f, borderwidth=4, relief="sunken") spr_frame.grid(column=1, columnspan=2, row=4, sticky=W) # sprites: inputs, outputs, rotation handle, occupied/embed state, # desiredFacing for i in range(5): spr = png.spr('ap_grey') wid['sprite'][i] = ttk.Label(spr_frame, image=spr, relief="raised") wid['sprite'][i].grid(row=0, column=i) desc_frame = ttk.Frame(f, borderwidth=4, relief="sunken") desc_frame.grid(row=5, column=0, columnspan=3, sticky="EW") wid['desc'] = tkRichText(desc_frame, width=40, height=8, font=None) wid['desc'].grid(row=0, column=0, sticky="EW") desc_scroll = ttk.Scrollbar( desc_frame, orient=VERTICAL, command=wid['desc'].yview, ) wid['desc']['yscrollcommand'] = desc_scroll.set desc_scroll.grid(row=0, column=1, sticky="NS") def show_more_info(): url = selected_item.url if url is not None: try: webbrowser.open(url, new=OPEN_IN_TAB, autoraise=True) except webbrowser.Error: if messagebox.askyesno( icon="error", title="BEE2 - Error", message='Failed to open a web browser. Do you wish for ' 'the URL to be copied to the clipboard ' 'instead?', detail='"{!s}"'.format(url), parent=prop_window ): print("Saving " + url + "to clipboard!") TK_ROOT.clipboard_clear() TK_ROOT.clipboard_append(url) # Either the webbrowser or the messagebox could cause the # properties to move behind the main window, so hide it # so it doesn't appear there. hide_context(None) wid['moreinfo'] = ttk.Button(f, text="More Info>>", command=show_more_info) wid['moreinfo'].grid(row=6, column=2, sticky=E) wid['moreinfo'].bind('<Enter>', more_info_show_url) wid['moreinfo'].bind('<Leave>', more_info_hide_url) moreinfo_win = Toplevel(TK_ROOT) moreinfo_win.withdraw() moreinfo_win.transient(master=TK_ROOT) moreinfo_win.overrideredirect(1) moreinfo_win.resizable(False, False) wid['moreinfo_context'] = ttk.Label( moreinfo_win, text='', relief="groove", font="TkSmallCaptionFont", padding=(5, 2), ) wid['moreinfo_context'].grid(row=0, column=0) menu_info = Menu(wid['moreinfo']) menu_info.add_command(label='', state='disabled') def show_item_props(): snd.fx('expand') itemPropWin.show_window( selected_item.get_properties(), wid['changedefaults'], selected_sub_item.name, ) wid['changedefaults'] = ttk.Button( f, text="Change Defaults...", command=show_item_props, ) wid['changedefaults'].grid(row=6, column=1) wid['variant'] = ttk.Combobox(f, values=['VERSION'], exportselection=0) wid['variant'].state(['readonly']) # Prevent directly typing in values wid['variant'].bind('<<ComboboxSelected>>', set_item_version) wid['variant'].current(0) wid['variant'].grid(row=6, column=0, sticky=W) itemPropWin.init(hide_item_props)