Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
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, '')
Exemple #4
0
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, '')
Exemple #5
0
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, ''))
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #8
0
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)