예제 #1
0
class FauxButton(urwid.Button):
    button_left = Text("")
    button_right = Text("")

    def __init__(self, label, on_press=None, user_data=None):
        self.user_data = user_data
        super(FauxButton, self).__init__(label, on_press, user_data)
예제 #2
0
    def __init__(self,
                 original_widget,
                 title="",
                 tlcorner=u'┌',
                 tline=u'─',
                 lline=u'│',
                 trcorner=u'┐',
                 blcorner=u'└',
                 rline=u'│',
                 bline=u'─',
                 brcorner=u'┘'):
        """
        Draw a line around original_widget.

        Use 'title' to set an initial title text with will be centered
        on top of the box.

        You can also override the widgets used for the lines/corners:
            tline: top line
            bline: bottom line
            lline: left line
            rline: right line
            tlcorner: top left corner
            trcorner: top right corner
            blcorner: bottom left corner
            brcorner: bottom right corner

        """

        tline, bline = Divider(tline), Divider(bline)
        lline, rline = SolidFill(lline), SolidFill(rline)
        tlcorner, trcorner = Text(tlcorner), Text(trcorner)
        blcorner, brcorner = Text(blcorner), Text(brcorner)

        self.title_widget = Text(self.format_title(title))
        self.tline_widget = Columns([
            tline,
            ('flow', self.title_widget),
            tline,
        ])

        top = Columns([('fixed', 1, tlcorner), self.tline_widget,
                       ('fixed', 1, trcorner)])

        middle = Columns([
            ('fixed', 1, lline),
            original_widget,
            ('fixed', 1, rline),
        ],
                         box_columns=[0, 2],
                         focus_column=1)

        bottom = Columns([('fixed', 1, blcorner), bline,
                          ('fixed', 1, brcorner)])

        pile = Pile([('flow', top), middle, ('flow', bottom)], focus_item=1)

        WidgetDecoration.__init__(self, original_widget)
        WidgetWrap.__init__(self, pile)
예제 #3
0
파일: osk.py 프로젝트: xovox/RetroPie-Setup
    def setup_popup(self, title):
        """
        Overlays a dialog box on top of the working view using a Frame
        """

        # Header
        if self.small_display:
            header = Padding(Text(title, align='center'))
        else:
            header = LineBox(Text(title),
                             tline=None,
                             rline=' ',
                             lline=' ',
                             trcorner=' ',
                             tlcorner=' ',
                             blcorner='',
                             brcorner='')

        header = AttrWrap(header, 'header')

        # Body
        error_text = Text("", align='center')
        # register the Text widget with the application, so we can change it
        self._error = error_text

        error_text = AttrWrap(error_text, 'error')
        body = Pile([
            Divider(), error_text,
            Divider(),
            LineBox(GridFlow([self.setup_button("Dismiss", self.close_popup)],
                             12, 2, 0, 'center'),
                    bline=None,
                    lline=None,
                    rline=None,
                    tlcorner='─',
                    trcorner='─')
        ])

        body = LineBox(body)
        body = AttrWrap(body, 'body')

        # on small displays let the popup fill the screen (horizontal)
        if self.small_display:
            body = Padding(Filler(body, 'middle'), 'center')
        else:
            body = Padding(Filler(body, 'middle'), 'center', ('relative', 50))

        body = AttrWrap(body, 'bg')

        # Main dialog widget
        dialog = Frame(body, header=header, focus_part='body')

        return dialog
예제 #4
0
파일: osk.py 프로젝트: xovox/RetroPie-Setup
    def __init__(self, label, on_press=None, user_data=None, delimiters=True):
        self._label = Text(label, align='center')

        if delimiters:
            cols = Columns([('fixed', 1, Text("<")), self._label,
                            ('fixed', 1, Text(">"))],
                           dividechars=1)
        else:
            cols = self._label

        self.__super.__init__(cols)

        if on_press:
            connect_signal(self, 'click', on_press, user_data)
예제 #5
0
    def render(self, size, focus=False):
        """
        Render the progress bar.
        """
        (maxcol, ) = size
        txt = Text(self.get_text(), self.text_align, CLIP)
        c = txt.render((maxcol, ))

        cf = float(self.current) * maxcol / self.done
        ccol = int(cf)
        cs = 0
        if self.satt is not None:
            cs = int((cf - ccol) * 8)
        if ccol < 0 or (ccol == 0 and cs == 0):
            c._attr = [[(self.normal, maxcol)]]
        elif ccol >= maxcol:
            c._attr = [[(self.complete, maxcol)]]
        elif cs and c._text[0][ccol] == " ":
            t = c._text[0]
            cenc = self.eighths[cs].encode("utf-8")
            c._text[0] = t[:ccol] + cenc + t[ccol + 1:]
            a = []
            if ccol > 0:
                a.append((self.complete, ccol))
            a.append((self.satt, len(cenc)))
            if maxcol - ccol - 1 > 0:
                a.append((self.normal, maxcol - ccol - 1))
            c._attr = [a]
            c._cs = [[(None, len(c._text[0]))]]
        else:
            c._attr = [[(self.complete, ccol), (self.normal, maxcol - ccol)]]
        return c
예제 #6
0
    def render(self, size, focus=False):
        """
        Render BarGraph.
        """
        (maxcol, maxrow) = size
        disp = self.calculate_display((maxcol, maxrow))

        combinelist = []
        for y_count, row in disp:
            l = []
            for bar_type, width in row:
                if type(bar_type) == tuple:
                    if len(bar_type) == 3:
                        # vertical eighths
                        fg, bg, k = bar_type
                        a = self.satt[(fg, bg)]
                        t = self.eighths[k] * width
                    else:
                        # horizontal lines
                        bg, k = bar_type
                        a = self.hatt[bg]
                        t = self.hlines[k] * width
                else:
                    a = self.attr[bar_type]
                    t = self.char[bar_type] * width
                l.append((a, t))
            c = Text(l).render((maxcol, ))
            assert c.rows() == 1, "Invalid characters in BarGraph!"
            combinelist += [(c, None, False)] * y_count

        canv = CanvasCombine(combinelist)
        return canv
예제 #7
0
 def __init__(self):
     """
     Create canvas containing an ASCII version of the Python
     Logo and store it.
     """
     blu = AttrSpec('light blue', 'default')
     yel = AttrSpec('yellow', 'default')
     width = 17
     self._canvas = Text([(blu, "     ______\n"), (blu, "   _|_o__  |"),
                          (yel, "__\n"), (blu, "  |   _____|"),
                          (yel, "  |\n"), (blu, "  |__|  "),
                          (yel, "______|\n"),
                          (yel, "     |____o_|")]).render((width, ))
예제 #8
0
    def __init__(self,
                 label,
                 state=False,
                 has_mixed=False,
                 on_state_change=None,
                 user_data=None,
                 checked_symbol=None):
        """
        :param label: markup for check box label
        :param state: False, True or "mixed"
        :param has_mixed: True if "mixed" is a state to cycle through
        :param on_state_change: shorthand for connect_signal()
                                function call for a single callback
        :param user_data: user_data for on_state_change

        Signals supported: ``'change'``, ``"postchange"``

        Register signal handler with::

          urwid.connect_signal(check_box, 'change', callback, user_data)

        where callback is callback(check_box, new_state [,user_data])
        Unregister signal handlers with::

          urwid.disconnect_signal(check_box, 'change', callback, user_data)

        >>> CheckBox(u"Confirm")
        <CheckBox selectable flow widget 'Confirm' state=False>
        >>> CheckBox(u"Yogourt", "mixed", True)
        <CheckBox selectable flow widget 'Yogourt' state='mixed'>
        >>> cb = CheckBox(u"Extra onions", True)
        >>> cb
        <CheckBox selectable flow widget 'Extra onions' state=True>
        >>> cb.render((20,), focus=True).text # ... = b in Python 3
        [...'[X] Extra onions    ']
        """
        self.__super.__init__(None)  # self.w set by set_state below
        self._label = Text("")
        self.has_mixed = has_mixed
        self._state = None
        if checked_symbol:
            self.states[True] = SelectableIcon(u"[%s]" % checked_symbol, 1)
        # The old way of listening for a change was to pass the callback
        # in to the constructor.  Just convert it to the new way:
        if on_state_change:
            connect_signal(self, 'change', on_state_change, user_data)
        self.set_label(label)
        self.set_state(state)
예제 #9
0
    def set_scale(self, labels, top):
        """
        set_scale( [(label1 position, label1 markup),...], top )
        label position -- 0 < position < top for the y position
        label markup -- text markup for this label
        top -- top y position
        """

        labels = labels[:]  # shallow copy
        labels.sort()
        labels.reverse()
        self.pos = []
        self.txt = []
        for y, markup in labels:
            self.pos.append(y)
            self.txt.append(Text(markup))
        self.top = top
예제 #10
0
    def __init__(self,
                 label,
                 state=False,
                 has_mixed=False,
                 on_state_change=None,
                 user_data=None):
        """
        label -- markup for check box label
        state -- False, True or "mixed"
        has_mixed -- True if "mixed" is a state to cycle through
        on_state_change, user_data -- shorthand for connect_signal()
            function call for a single callback

        Signals supported: 'change'
        Register signal handler with:
          connect_signal(check_box, 'change', callback [,user_data])
        where callback is callback(check_box, new_state [,user_data])
        Unregister signal handlers with:
          disconnect_signal(check_box, 'change', callback [,user_data])

        >>> CheckBox(u"Confirm")
        <CheckBox selectable widget 'Confirm' state=False>
        >>> CheckBox(u"Yogourt", "mixed", True)
        <CheckBox selectable widget 'Yogourt' state='mixed'>
        >>> cb = CheckBox(u"Extra onions", True)
        >>> cb
        <CheckBox selectable widget 'Extra onions' state=True>
        >>> cb.render((20,), focus=True).text # ... = b in Python 3
        [...'[X] Extra onions    ']
        """
        self.__super.__init__(None)  # self.w set by set_state below
        self._label = Text("")
        self.has_mixed = has_mixed
        self._state = None
        # The old way of listening for a change was to pass the callback
        # in to the constructor.  Just convert it to the new way:
        if on_state_change:
            connect_signal(self, 'change', on_state_change, user_data)
        self.set_label(label)
        self.set_state(state)
예제 #11
0
    def __init__(self, original_widget, title="",
                 title_align="center", title_attr=None,
                 tlcorner=u'┌', tline=u'─', lline=u'│',
                 trcorner=u'┐', blcorner=u'└', rline=u'│',
                 bline=u'─', brcorner=u'┘'):
        """
        Draw a line around original_widget.

        Use 'title' to set an initial title text with will be centered
        on top of the box.

        Use `title_attr` to apply a specific attribute to the title text.

        Use `title_align` to align the title to the 'left', 'right', or 'center'.
        The default is 'center'.

        You can also override the widgets used for the lines/corners:
            tline: top line
            bline: bottom line
            lline: left line
            rline: right line
            tlcorner: top left corner
            trcorner: top right corner
            blcorner: bottom left corner
            brcorner: bottom right corner

        If empty string is specified for one of the lines/corners, then no
        character will be output there.  This allows for seamless use of
        adjoining LineBoxes.
        """

        if tline:
            tline = Divider(tline)
        if bline:
            bline = Divider(bline)
        if lline:
            lline = SolidFill(lline)
        if rline:
            rline = SolidFill(rline)
        tlcorner, trcorner = Text(tlcorner), Text(trcorner)
        blcorner, brcorner = Text(blcorner), Text(brcorner)

        if not tline and title:
            raise ValueError('Cannot have a title when tline is empty string')

        if title_attr:
            self.title_widget = Text((title_attr, self.format_title(title)))
        else:
            self.title_widget = Text(self.format_title(title))

        if tline:
            if title_align not in ('left', 'center', 'right'):
                raise ValueError('title_align must be one of "left", "right", or "center"')
            if title_align == 'left':
                tline_widgets = [('flow', self.title_widget), tline]
            else:
                tline_widgets = [tline, ('flow', self.title_widget)]
                if title_align == 'center':
                    tline_widgets.append(tline)
            self.tline_widget = Columns(tline_widgets)
            top = Columns([
                ('fixed', 1, tlcorner),
                self.tline_widget,
                ('fixed', 1, trcorner)
            ])

        else:
            self.tline_widget = None
            top = None

        middle_widgets = []
        if lline:
            middle_widgets.append(('fixed', 1, lline))
        else:
            # Note: We need to define a fixed first widget (even if it's 0 width) so that the other
            # widgets have something to anchor onto
            middle_widgets.append(('fixed', 0, SolidFill(u"")))
        middle_widgets.append(original_widget)
        focus_col = len(middle_widgets) - 1
        if rline:
            middle_widgets.append(('fixed', 1, rline))

        middle = Columns(middle_widgets,
                box_columns=[0, 2], focus_column=focus_col)

        if bline:
            bottom = Columns([
                ('fixed', 1, blcorner), bline, ('fixed', 1, brcorner)
            ])
        else:
            bottom = None

        pile_widgets = []
        if top:
            pile_widgets.append(('flow', top))
        pile_widgets.append(middle)
        focus_pos = len(pile_widgets) - 1
        if bottom:
            pile_widgets.append(('flow', bottom))
        pile = Pile(pile_widgets, focus_item=focus_pos)

        WidgetDecoration.__init__(self, original_widget)
        WidgetWrap.__init__(self, pile)
예제 #12
0
class Button(WidgetWrap):
    def sizing(self):
        return frozenset([FLOW])

    button_left = Text("<")
    button_right = Text(">")

    signals = ["click"]

    def __init__(self, label, on_press=None, user_data=None):
        """
        :param label: markup for button label
        :param on_press: shorthand for connect_signal()
                         function call for a single callback
        :param user_data: user_data for on_press

        Signals supported: ``'click'``

        Register signal handler with::

          urwid.connect_signal(button, 'click', callback, user_data)

        where callback is callback(button [,user_data])
        Unregister signal handlers with::

          urwid.disconnect_signal(button, 'click', callback, user_data)

        >>> Button(u"Ok")
        <Button selectable flow widget 'Ok'>
        >>> b = Button("Cancel")
        >>> b.render((15,), focus=True).text # ... = b in Python 3
        [...'< Cancel      >']
        """
        self._label = SelectableIcon("", 0)
        cols = Columns([('fixed', 1, self.button_left), self._label,
                        ('fixed', 1, self.button_right)],
                       dividechars=1)
        self.__super.__init__(cols)

        # The old way of listening for a change was to pass the callback
        # in to the constructor.  Just convert it to the new way:
        if on_press:
            connect_signal(self, 'click', on_press, user_data)

        self.set_label(label)

    def _repr_words(self):
        # include button.label in repr(button)
        return self.__super._repr_words() + [python3_repr(self.label)]

    def set_label(self, label):
        """
        Change the button label.

        label -- markup for button label

        >>> b = Button("Ok")
        >>> b.set_label(u"Yup yup")
        >>> b
        <Button selectable flow widget 'Yup yup'>
        """
        self._label.set_text(label)

    def get_label(self):
        """
        Return label text.

        >>> b = Button(u"Ok")
        >>> print b.get_label()
        Ok
        >>> print b.label
        Ok
        """
        return self._label.text

    label = property(get_label)

    def keypress(self, size, key):
        """
        Send 'click' signal on 'activate' command.

        >>> assert Button._command_map[' '] == 'activate'
        >>> assert Button._command_map['enter'] == 'activate'
        >>> size = (15,)
        >>> b = Button(u"Cancel")
        >>> clicked_buttons = []
        >>> def handle_click(button):
        ...     clicked_buttons.append(button.label)
        >>> connect_signal(b, 'click', handle_click)
        >>> b.keypress(size, 'enter')
        >>> b.keypress(size, ' ')
        >>> clicked_buttons # ... = u in Python 2
        [...'Cancel', ...'Cancel']
        """
        if self._command_map[key] != ACTIVATE:
            return key

        self._emit('click')

    def mouse_event(self, size, event, button, x, y, focus):
        """
        Send 'click' signal on button 1 press.

        >>> size = (15,)
        >>> b = Button(u"Ok")
        >>> clicked_buttons = []
        >>> def handle_click(button):
        ...     clicked_buttons.append(button.label)
        >>> connect_signal(b, 'click', handle_click)
        >>> b.mouse_event(size, 'mouse press', 1, 4, 0, True)
        True
        >>> b.mouse_event(size, 'mouse press', 2, 4, 0, True) # ignored
        False
        >>> clicked_buttons # ... = u in Python 2
        [...'Ok']
        """
        if button != 1 or not is_mouse_press(event):
            return False

        self._emit('click')
        return True
예제 #13
0
    def __init__(self,
                 original_widget,
                 title="",
                 title_align="center",
                 tlcorner='┌',
                 tline='─',
                 lline='│',
                 trcorner='┐',
                 blcorner='└',
                 rline='│',
                 bline='─',
                 brcorner='┘'):
        """
        Draw a line around original_widget.
        Use 'title' to set an initial title text with will be centered
        on top of the box.
        Use `title_align` to align the title to the 'left', 'right', or 'center'.
        The default is 'center'.
        You can also override the widgets used for the lines/corners:
            tline: top line
            bline: bottom line
            lline: left line
            rline: right line
            tlcorner: top left corner
            trcorner: top right corner
            blcorner: bottom left corner
            brcorner: bottom right corner
        .. note:: This differs from the vanilla urwid LineBox by discarding
            the a line if the middle of the line is set to either None or the
            empty string.
        """

        if tline:
            tline = Divider(tline)
        if bline:
            bline = Divider(bline)
        if lline:
            lline = SolidFill(lline)
        if rline:
            rline = SolidFill(rline)
        tlcorner, trcorner = Text(tlcorner), Text(trcorner)
        blcorner, brcorner = Text(blcorner), Text(brcorner)

        if not tline and title:
            raise ValueError('Cannot have a title when tline is unset')

        self.title_widget = Text(self.format_title(title))

        if tline:
            if title_align not in ('left', 'center', 'right'):
                raise ValueError(
                    'title_align must be one of "left", "right", or "center"')
            if title_align == 'left':
                tline_widgets = [('flow', self.title_widget), tline]
            else:
                tline_widgets = [tline, ('flow', self.title_widget)]
                if title_align == 'center':
                    tline_widgets.append(tline)
            self.tline_widget = Columns(tline_widgets)
            top = Columns([('fixed', 1, tlcorner), self.tline_widget,
                           ('fixed', 1, trcorner)])

        else:
            self.tline_widget = None
            top = None

        middle_widgets = []
        if lline:
            middle_widgets.append(('fixed', 1, lline))
        middle_widgets.append(original_widget)
        focus_col = len(middle_widgets) - 1
        if rline:
            middle_widgets.append(('fixed', 1, rline))

        middle = Columns(middle_widgets,
                         box_columns=[0, 2],
                         focus_column=focus_col)

        if bline:
            bottom = Columns([('fixed', 1, blcorner), bline,
                              ('fixed', 1, brcorner)])
        else:
            bottom = None

        pile_widgets = []
        if top:
            pile_widgets.append(('flow', top))
        pile_widgets.append(middle)
        focus_pos = len(pile_widgets) - 1
        if bottom:
            pile_widgets.append(('flow', bottom))
        pile = Pile(pile_widgets, focus_item=focus_pos)

        WidgetDecoration.__init__(self, original_widget)
        WidgetWrap.__init__(self, pile)
예제 #14
0
파일: osk.py 프로젝트: xovox/RetroPie-Setup
    def setup_frame(self, title, input_title):
        """
        Creates the main view, with a 3 horizontal pane container (Frame)
        """
        self.keys = []  # List of keys added to the OSK
        self._shift = False  # OSK Shift key state

        # title frame (header) uses a LineBox with just the bottom line enabled
        # if we're on a small display, use a simple Text with Padding
        if self.small_display:
            header = Padding(Text(title, align='center'))

        else:
            header = LineBox(Text(title),
                             tline=None,
                             rline=' ',
                             lline=' ',
                             trcorner=' ',
                             tlcorner=' ',
                             blcorner='',
                             brcorner='')

        header = AttrWrap(header, 'header')

        # Body frame, containing the input and the OSK widget
        input = Text([('input text', ''), ('prompt', ASCII_BLOCK)])
        self.input = input

        Key = self.add_osk_key  # alias the key creation function
        osk = Pile([
            # 1st keyboard row
            WrappableColumns([
                (1, Text(" ")),
                (3, Key('`', shifted='~')),
                (3, Key('1', shifted='!')),
                (3, Key('2', shifted='@')),
                (3, Key('3', shifted='#')),
                (3, Key('4', shifted='$')),
                (3, Key('5', shifted='%')),
                (3, Key('6', shifted='^')),
                (3, Key('7', shifted='&')),
                (3, Key('8', shifted='*')),
                (3, Key('9', shifted='(')),
                (3, Key('0', shifted=')')),
                (3, Key('-', shifted='_')),
                (3, Key('=', shifted='+')),
                (1, Text(" ")),
            ], 0),
            Divider(),
            # 2nd keyboard row
            WrappableColumns([
                (2, Text(" ")),
                (3, Key('q')),
                (3, Key('w')),
                (3, Key('e')),
                (3, Key('r')),
                (3, Key('t')),
                (3, Key('y')),
                (3, Key('u')),
                (3, Key('i')),
                (3, Key('o')),
                (3, Key('p')),
                (3, Key('[', shifted='{')),
                (3, Key(']', shifted='}')),
                (3, Key('\\', shifted='|')),
            ], 0),
            Divider(),
            # 3rd keyboard row
            WrappableColumns([
                (3, Text(" ")),
                (3, Key('a')),
                (3, Key('s')),
                (3, Key('d')),
                (3, Key('f')),
                (3, Key('g')),
                (3, Key('h')),
                (3, Key('j')),
                (3, Key('k')),
                (3, Key('l')),
                (3, Key(';', shifted=':')),
                (3, Key('\'', shifted='"')),
            ], 0),
            Divider(),
            # 4th keyboard row
            WrappableColumns([(4, Text(" ")), (3, Key('z')), (3, Key('x')),
                              (3, Key('c')), (3, Key('v')), (3, Key('b')),
                              (3, Key('n')), (3, Key('m')),
                              (3, Key(',', shifted='<')),
                              (3, Key('.', shifted='>')),
                              (3, Key('/', shifted='?'))], 0),
            Divider(),
            # 5th (last) keyboard row
            WrappableColumns([
                (1, Text(" ")),
                (9,
                 Key('↑ Shift',
                     shifted='↑ SHIFT',
                     callback=self.shift_key_press)),
                (2, Text(" ")),
                (15, Key('Space', value=' ', shifted=' ')),
                (2, Text(" ")),
                (10, Key('Delete ←', callback=self.bksp_key_press)),
            ], 0),
            Divider()
        ])

        if self.small_display:
            # small displays: remove last divider line
            osk.contents.pop(len(osk.contents) - 1)

        osk = Padding(osk, 'center', 40)

        # setup the text input and the buttons
        input = AttrWrap(LineBox(input), 'input')
        input = Padding(AttrWrap(input, 'input text'),
                        'center', ('relative', 80),
                        min_width=30)
        ok_btn = self.setup_button("OK", self.button_press, exitcode=0)
        cancel_btn = self.setup_button("Cancel", self.button_press, exitcode=1)

        # setup the main OSK area, depending on the screen size
        if self.small_display:
            body = Pile([
                Text(f'Enter the {input_title}', align='center'), input,
                Divider(), osk,
                Divider(),
                GridFlow([ok_btn, cancel_btn], 10, 2, 0, 'center'),
                Divider()
            ])
        else:
            body = Pile([
                Divider(), input,
                Divider(), osk,
                LineBox(GridFlow([ok_btn, cancel_btn], 10, 2, 0, 'center'),
                        bline=None,
                        lline=None,
                        rline=None,
                        tlcorner='─',
                        trcorner='─')
            ])
            body = LineBox(body, f'Enter the {input_title}')

        body = AttrWrap(body, 'body')  # Style the main OSK area

        # wrap and align the main OSK in the frame
        body = Padding(body, 'center', 55, min_width=42)
        body = Filler(body, 'middle')

        body = AttrWrap(body, 'bg')  # Style the body containing the OSK

        frame = Frame(body, header=header, focus_part='body')

        return frame
예제 #15
0
    def __init__(self,
                 original_widget,
                 title="",
                 tlcorner=None,
                 tline=None,
                 lline=None,
                 trcorner=None,
                 blcorner=None,
                 rline=None,
                 bline=None,
                 brcorner=None):
        """
        Draw a line around original_widget.

        Use 'title' to set an initial title text with will be centered
        on top of the box.

        You can also override the widgets used for the lines/corners:
            tline: top line
            bline: bottom line
            lline: left line
            rline: right line
            tlcorner: top left corner
            trcorner: top right corner
            blcorner: bottom left corner
            brcorner: bottom right corner
        """
        self.title_widget = Text(self.format_title(title))

        def use_attr(a, t):
            if a is not None:
                t = AttrWrap(t, a)
                return t
            else:
                return t

        self.tline_widget = Columns([
            Divider(self.ACS_HLINE),
            ('flow', self.title_widget),
            Divider(self.ACS_HLINE),
        ])

        tline = use_attr(tline, self.tline_widget)
        bline = use_attr(bline, Divider(self.ACS_HLINE))
        lline = use_attr(lline, SolidFill(self.ACS_VLINE))
        rline = use_attr(rline, SolidFill(self.ACS_VLINE))
        tlcorner = use_attr(tlcorner, Text(self.ACS_ULCORNER))
        trcorner = use_attr(trcorner, Text(self.ACS_URCORNER))
        blcorner = use_attr(blcorner, Text(self.ACS_LLCORNER))
        brcorner = use_attr(brcorner, Text(self.ACS_LRCORNER))
        top = Columns([('fixed', 1, tlcorner), tline, ('fixed', 1, trcorner)])
        middle = Columns([('fixed', 1, lline), original_widget,
                          ('fixed', 1, rline)],
                         box_columns=[0, 2],
                         focus_column=1)
        bottom = Columns([('fixed', 1, blcorner), bline,
                          ('fixed', 1, brcorner)])
        pile = Pile([('flow', top), middle, ('flow', bottom)], focus_item=1)

        WidgetDecoration.__init__(self, original_widget)
        WidgetWrap.__init__(self, pile)