示例#1
0
    def __init__(self, title: str, text: str):
        super().__init__(TK_ROOT)
        self.withdraw()
        self.title(title)
        self.transient(master=TK_ROOT)
        self.resizable(width=True, height=True)
        self.text = text
        tk_tools.set_window_icon(self)

        # Hide when the exit button is pressed, or Escape
        # on the keyboard.
        self.protocol("WM_DELETE_WINDOW", self.withdraw)
        self.bind("<Escape>", self.withdraw)

        frame = tk.Frame(self, background='white')
        frame.grid(row=0, column=0, sticky='nsew')
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self.textbox = tkRichText(frame, width=80, height=24)
        self.textbox.configure(background='white', relief='flat')
        self.textbox.grid(row=0, column=0, sticky='nsew')
        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(0, weight=1)

        scrollbox = tk_tools.HidingScroll(
            frame,
            orient='vertical',
            command=self.textbox.yview,
        )
        scrollbox.grid(row=0, column=1, sticky='ns')
        self.textbox['yscrollcommand'] = scrollbox.set

        ttk.Button(
            frame,
            text=gettext('Close'),
            command=self.withdraw,
        ).grid(
            row=1,
            column=0,
        )
示例#2
0
    def __init__(
        self,
        f: tk.Frame,
        menu: tk.Menu,
        *,
        cmd_clear: Callable[[], None],
        cmd_shuffle: Callable[[], None],
        get_items: Callable[[], list[tuple[str, int]]],
        set_items: Callable[[Palette], None],
    ) -> None:
        """Initialises the palette pane.

        The parameters are used to communicate with the item list:
        - cmd_clear and cmd_shuffle are called to do those actions to the list.
        - pal_get_items is called to retrieve the current list of selected items.
        - cmd_save_btn_state is the .state() method on the save button.
        - cmd_set_items is called to apply a palette to the list of items.
        """
        self.palettes: dict[UUID, Palette] = {
            pal.uuid: pal
            for pal in paletteLoader.load_palettes()
        }

        try:
            self.selected_uuid = UUID(hex=BEE2_config.GEN_OPTS.get_val(
                'Last_Selected', 'palette_uuid', ''))
        except ValueError:
            self.selected_uuid = UUID_PORTAL2

        f.rowconfigure(1, weight=1)
        f.columnconfigure(0, weight=1)
        self.var_save_settings = tk.BooleanVar(
            value=BEE2_config.GEN_OPTS.get_bool('General',
                                                'palette_save_settings'))
        self.var_pal_select = tk.StringVar(value=self.selected_uuid.hex)
        self.get_items = get_items
        self.set_items = set_items
        # Overwritten to configure the save state button.
        self.save_btn_state = lambda s: None

        ttk.Button(
            f,
            text=gettext('Clear Palette'),
            command=cmd_clear,
        ).grid(row=0, sticky="EW")

        self.ui_treeview = treeview = ttk.Treeview(f,
                                                   show='tree',
                                                   selectmode='browse')
        self.ui_treeview.grid(row=1, sticky="NSEW")
        self.ui_treeview.tag_bind(TREE_TAG_PALETTES, '<ButtonPress>',
                                  self.event_select_tree)

        # Avoid re-registering the double-lambda, just do it here.
        # This makes clicking the groups return selection to the palette.
        evtid_reselect = self.ui_treeview.register(self.treeview_reselect)
        self.ui_treeview.tag_bind(
            TREE_TAG_GROUPS, '<ButtonPress>',
            lambda e: treeview.tk.call('after', 'idle', evtid_reselect))

        # And ensure when focus returns we reselect, in case it deselects.
        f.winfo_toplevel().bind('<FocusIn>',
                                lambda e: self.treeview_reselect(),
                                add=True)

        scrollbar = tk_tools.HidingScroll(
            f,
            orient='vertical',
            command=self.ui_treeview.yview,
        )
        scrollbar.grid(row=1, column=1, sticky="NS")
        self.ui_treeview['yscrollcommand'] = scrollbar.set

        self.ui_remove = ttk.Button(
            f,
            text=gettext('Delete Palette'),
            command=self.event_remove,
        )
        self.ui_remove.grid(row=2, sticky="EW")

        if tk_tools.USE_SIZEGRIP:
            ttk.Sizegrip(f).grid(row=2, column=1)

        self.ui_menu = menu
        self.ui_group_menus: dict[str, tk.Menu] = {}
        self.ui_group_treeids: dict[str, str] = {}
        menu.add_command(
            label=gettext('Clear'),
            command=cmd_clear,
        )
        menu.add_command(
            # Placeholder..
            label=gettext('Delete Palette'),  # This name is overwritten later
            command=self.event_remove,
        )
        self.ui_menu_delete_index = menu.index('end')

        menu.add_command(
            label=gettext('Change Palette Group...'),
            command=self.event_change_group,
        )
        self.ui_menu_regroup_index = menu.index('end')

        menu.add_command(
            label=gettext('Rename Palette...'),
            command=self.event_rename,
        )
        self.ui_menu_rename_index = menu.index('end')

        menu.add_command(
            label=gettext('Fill Palette'),
            command=cmd_shuffle,
        )

        menu.add_separator()

        menu.add_checkbutton(
            label=gettext('Save Settings in Palettes'),
            variable=self.var_save_settings,
        )

        menu.add_separator()

        menu.add_command(
            label=gettext('Save Palette'),
            command=self.event_save,
            accelerator=tk_tools.ACCEL_SAVE,
        )
        self.ui_menu_save_ind = menu.index('end')
        menu.add_command(
            label=gettext('Save Palette As...'),
            command=self.event_save_as,
            accelerator=tk_tools.ACCEL_SAVE_AS,
        )

        menu.add_separator()
        self.ui_menu_palettes_index = menu.index('end') + 1
        self.update_state()
示例#3
0
def init(start_open: bool, log_level: str = 'info') -> None:
    """Initialise the window."""
    global log_handler, text_box, level_selector

    window.columnconfigure(0, weight=1)
    window.rowconfigure(0, weight=1)
    window.title(_('Logs - {}').format(utils.BEE_VERSION))
    window.protocol('WM_DELETE_WINDOW', lambda: set_visible(False))

    text_box = tk.Text(
        window,
        name='text_box',
        width=50,
        height=15,
    )
    text_box.grid(row=0, column=0, sticky='NSEW')

    log_level = logging.getLevelName(log_level.upper())

    log_handler = TextHandler(text_box)

    try:
        log_handler.setLevel(log_level)
    except ValueError:
        log_level = logging.INFO
    log_handler.setFormatter(
        logging.Formatter(
            # One letter for level name
            '[{levelname[0]}] {module}.{funcName}(): {message}',
            style='{',
        ))

    logging.getLogger().addHandler(log_handler)

    scroll = tk_tools.HidingScroll(
        window,
        name='scroll',
        orient=tk.VERTICAL,
        command=text_box.yview,
    )
    scroll.grid(row=0, column=1, sticky='NS')
    text_box['yscrollcommand'] = scroll.set

    button_frame = ttk.Frame(window, name='button_frame')
    button_frame.grid(row=1, column=0, columnspan=2, sticky='EW')

    ttk.Button(
        button_frame,
        name='clear_btn',
        text='Clear',
        command=btn_clear,
    ).grid(row=0, column=0)

    ttk.Button(
        button_frame,
        name='copy_btn',
        text=_('Copy'),
        command=btn_copy,
    ).grid(row=0, column=1)

    sel_frame = ttk.Frame(button_frame, )
    sel_frame.grid(row=0, column=2, sticky='EW')
    button_frame.columnconfigure(2, weight=1)

    ttk.Label(
        sel_frame,
        text=_('Show:'),
        anchor='e',
        justify='right',
    ).grid(row=0, column=0, sticky='E')

    level_selector = ttk.Combobox(
        sel_frame,
        name='level_selector',
        values=[LVL_TEXT[level] for level in BOX_LEVELS],
        exportselection=0,
        # On Mac this defaults to being way too wide!
        width=15 if utils.MAC else None,
    )
    level_selector.state(['readonly'])  # Prevent directly typing in values
    level_selector.bind('<<ComboboxSelected>>', set_level)
    level_selector.current(BOX_LEVELS.index(log_level))

    level_selector.grid(row=0, column=1, sticky='E')
    sel_frame.columnconfigure(1, weight=1)

    utils.add_mousewheel(text_box, window, sel_frame, button_frame)

    if utils.USE_SIZEGRIP:
        ttk.Sizegrip(button_frame).grid(row=0, column=3)

    if start_open:
        window.deiconify()
        window.lift()
        # Force an update, we're busy with package extraction...
        window.update()
    else:
        window.withdraw()
示例#4
0
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,
    )
示例#5
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['item_id'] = ttk.Label(f, text="", anchor="center")
    wid['item_id'].grid(row=2, column=0, columnspan=3, sticky="EW")
    tooltip.add_tooltip(wid['item_id'])

    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=3, column=0, columnspan=3, sticky="EW")

    sub_frame = ttk.Frame(f, borderwidth=4, relief="sunken")
    sub_frame.grid(column=0, columnspan=3, row=4)
    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=5, 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=6, 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=7, 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():
        sound.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=7, 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=7, column=0, sticky=W)

    itemPropWin.init(hide_item_props)
示例#6
0
def init_widgets():
    """Make all the window components."""
    win.columnconfigure(0, weight=1)
    win.transient(master=TK_ROOT)
    tk_tools.set_window_icon(win)
    win.protocol("WM_DELETE_WINDOW", quit)
    win.bind("<Escape>", quit)

    pane = PanedWindow(
        win,
        orient=VERTICAL,
        sashpad=2,  # Padding above/below panes
        sashwidth=3,  # Width of border
        sashrelief=RAISED,  # Raise the border between panes
    )
    UI['pane'] = pane
    pane.grid(row=1, column=0, sticky='NSEW')
    win.rowconfigure(1, weight=1)

    UI['tabs'] = ttk.Notebook(pane)
    UI['tabs'].enable_traversal()  # Add keyboard shortcuts
    pane.add(UI['tabs'])
    pane.paneconfigure(UI['tabs'], minsize=50)

    trans_frame = ttk.Frame(pane)
    trans_frame.rowconfigure(1, weight=1)
    trans_frame.columnconfigure(0, weight=1)

    ttk.Label(
        trans_frame,
        text=_('Transcript:'),
    ).grid(
        row=0,
        column=0,
        sticky=W,
    )

    trans_inner_frame = ttk.Frame(trans_frame, borderwidth=2, relief='sunken')
    trans_inner_frame.grid(row=1, column=0, sticky='NSEW')
    trans_inner_frame.rowconfigure(0, weight=1)
    trans_inner_frame.columnconfigure(0, weight=1)

    default_bold_font = font.nametofont('TkDefaultFont').copy()
    default_bold_font['weight'] = 'bold'

    UI['trans'] = Text(
        trans_inner_frame,
        width=10,
        height=4,
        wrap='word',
        relief='flat',
        state='disabled',
        font='TkDefaultFont',
    )
    UI['trans_scroll'] = tk_tools.HidingScroll(
        trans_inner_frame,
        orient=VERTICAL,
        command=UI['trans'].yview,
    )
    UI['trans'].tag_config(
        'bold',
        font=default_bold_font,
    )
    UI['trans']['yscrollcommand'] = UI['trans_scroll'].set
    UI['trans_scroll'].grid(row=0, column=1, sticky='NS')
    UI['trans'].grid(row=0, column=0, sticky='NSEW')

    ttk.Button(
        win,
        text=_('Save'),
        command=save,
    ).grid(row=2, column=0)

    # Don't allow resizing the transcript box to be smaller than the
    # original size.
    trans_frame.update_idletasks()
    pane.paneconfigure(trans_frame, minsize=trans_frame.winfo_reqheight())
示例#7
0
def make_tab(group, config: ConfigFile, tab_type):
    """Create all the widgets for a tab."""
    if tab_type is TabTypes.MIDCHAMBER:
        # Mid-chamber voice lines have predefined values.
        group_name = _('Mid - Chamber')
        group_id = 'MIDCHAMBER'
        group_desc = _('Lines played during the actual chamber, '
                       'after specific events have occurred.')
    elif tab_type is TabTypes.RESPONSE:
        # Note: 'Response' tab header, and description
        group_name = _('Responses')
        group_id = None
        group_desc = _('Lines played in response to certain events in Coop.')
    elif tab_type is TabTypes.NORM:
        group_name = group['name', 'No Name!']
        group_id = group_name.upper()
        group_desc = group['desc', ''] + ':'
    else:
        raise ValueError('Invalid tab type!')

    # This is just to hold the canvas and scrollbar
    outer_frame = ttk.Frame(UI['tabs'])
    outer_frame.columnconfigure(0, weight=1)
    outer_frame.rowconfigure(0, weight=1)

    TABS[group_name] = outer_frame
    # We add this attribute so the refresh() method knows all the
    # tab names
    outer_frame.nb_text = group_name
    outer_frame.nb_type = tab_type

    # We need a canvas to make the list scrollable.
    canv = Canvas(
        outer_frame,
        highlightthickness=0,
    )
    scroll = tk_tools.HidingScroll(
        outer_frame,
        orient=VERTICAL,
        command=canv.yview,
    )
    canv['yscrollcommand'] = scroll.set
    canv.grid(row=0, column=0, sticky='NSEW')
    scroll.grid(row=0, column=1, sticky='NS')

    UI['tabs'].add(outer_frame)

    # This holds the actual elements
    frame = ttk.Frame(canv, )
    frame.columnconfigure(0, weight=1)
    canv.create_window(0, 0, window=frame, anchor="nw")

    ttk.Label(
        frame,
        text=group_name,
        anchor='center',
        font='tkHeadingFont',
    ).grid(
        row=0,
        column=0,
        sticky='EW',
    )

    ttk.Label(
        frame,
        text=group_desc,
    ).grid(
        row=1,
        column=0,
        sticky='EW',
    )

    ttk.Separator(frame, orient=HORIZONTAL).grid(
        row=2,
        column=0,
        sticky='EW',
    )

    if tab_type is TabTypes.RESPONSE:
        sorted_quotes = sorted(group, key=lambda prop: prop.real_name)
    else:
        sorted_quotes = sorted(
            group.find_all('Quote'),
            key=quote_sort_func,
            reverse=True,
        )

    for quote in sorted_quotes:  # type: Property
        if not quote.has_children():
            continue  # Skip over config commands..

        if tab_type is TabTypes.RESPONSE:
            try:
                name = RESPONSE_NAMES[quote.name]
            except KeyError:
                # Convert channels of the form 'death_goo' into 'Death - Goo'.
                channel, ch_arg = quote.name.split('_', 1)
                name = channel.title() + ' - ' + ch_arg.title()
                del channel, ch_arg

            group_id = quote.name
        else:
            # note: default for quote names
            name = quote['name', _('No Name!')]

        ttk.Label(
            frame,
            text=name,
            font=QUOTE_FONT,
        ).grid(
            column=0,
            sticky=W,
        )

        if tab_type is TabTypes.RESPONSE:
            line_iter = find_resp_lines(quote)
        else:
            line_iter = find_lines(quote)

        for badges, line, line_id in line_iter:
            line_frame = ttk.Frame(frame, )
            line_frame.grid(
                column=0,
                padx=(10, 0),
                sticky=W,
            )
            for x, (img, ctx) in enumerate(badges):
                label = ttk.Label(line_frame, image=img, padding=0)
                label.grid(row=0, column=x)
                add_tooltip(label, ctx)

            line_frame.columnconfigure(len(badges), weight=1)

            check = ttk.Checkbutton(
                line_frame,
                # note: default voice line name next to checkbox.
                text=line['name', _('No Name?')],
            )

            check.quote_var = IntVar(value=config.get_bool(
                group_id, line_id, True), )

            check['variable'] = check.quote_var

            check['command'] = functools.partial(
                check_toggled,
                var=check.quote_var,
                config_section=config[group_id],
                quote_id=line_id,
            )
            check.transcript = list(get_trans_lines(line))
            check.grid(
                row=0,
                column=len(badges),
            )
            check.bind("<Enter>", show_trans)

    def configure_canv(e):
        """Allow resizing the windows."""
        canv['scrollregion'] = (
            4,
            0,
            canv.winfo_reqwidth(),
            frame.winfo_reqheight(),
        )
        frame['width'] = canv.winfo_reqwidth()

    canv.bind('<Configure>', configure_canv)

    return outer_frame
示例#8
0
    def __init__(self, translations: dict,
                 pipe: multiprocessing.connection.Connection) -> None:
        """Initialise the window."""
        self.win = window = tk.Toplevel(TK_ROOT)
        self.pipe = pipe
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)
        window.title(translations['log_title'])
        window.protocol('WM_DELETE_WINDOW', self.evt_close)
        window.withdraw()

        self.has_text = False
        self.text = tk.Text(
            window,
            name='text_box',
            width=50,
            height=15,
        )
        self.text.grid(row=0, column=0, sticky='NSEW')

        scroll = tk_tools.HidingScroll(
            window,
            name='scroll',
            orient=tk.VERTICAL,
            command=self.text.yview,
        )
        scroll.grid(row=0, column=1, sticky='NS')
        self.text['yscrollcommand'] = scroll.set

        # Assign colours for each logging level
        for level, colour in LVL_COLOURS.items():
            self.text.tag_config(
                logging.getLevelName(level),
                foreground=colour,
                # For multi-line messages, indent this much.
                lmargin2=30,
            )
        self.text.tag_config(
            logging.getLevelName(logging.CRITICAL),
            background='red',
        )
        # If multi-line messages contain carriage returns, lmargin2 doesn't
        # work. Add an additional tag for that.
        self.text.tag_config(
            'INDENT',
            lmargin1=30,
            lmargin2=30,
        )

        button_frame = ttk.Frame(window, name='button_frame')
        button_frame.grid(row=1, column=0, columnspan=2, sticky='EW')

        ttk.Button(
            button_frame,
            name='clear_btn',
            text=translations['clear'],
            command=self.evt_clear,
        ).grid(row=0, column=0)

        ttk.Button(
            button_frame,
            name='copy_btn',
            text=translations['copy'],
            command=self.evt_copy,
        ).grid(row=0, column=1)

        sel_frame = ttk.Frame(button_frame)
        sel_frame.grid(row=0, column=2, sticky='EW')
        button_frame.columnconfigure(2, weight=1)

        ttk.Label(
            sel_frame,
            text=translations['log_show'],
            anchor='e',
            justify='right',
        ).grid(row=0, column=0, sticky='E')

        self.level_selector = ttk.Combobox(
            sel_frame,
            name='level_selector',
            values=translations['level_text'],
            exportselection=False,
            # On Mac this defaults to being way too wide!
            width=15 if utils.MAC else None,
        )
        self.level_selector.state(['readonly'
                                   ])  # Prevent directly typing in values
        self.level_selector.bind('<<ComboboxSelected>>', self.evt_set_level)
        self.level_selector.current(1)

        self.level_selector.grid(row=0, column=1, sticky='E')
        sel_frame.columnconfigure(1, weight=1)

        tk_tools.add_mousewheel(self.text, window, sel_frame, button_frame)

        if tk_tools.USE_SIZEGRIP:
            ttk.Sizegrip(button_frame).grid(row=0, column=3)