Ejemplo n.º 1
0
    def __init__(self, tab=None, ltab=None, loader=None, tree=False):
        self.header = urwid.Edit()

        if loader is None:
            loader = self.FoolLoader

        self.loader = loader
        self.tree = tree
        self.tab = tab
        self.ltab = ltab
        self.search = ''

        connect_signal(self.header, "change", self.update)

        self.fn = FirstNode(nome='')
        self.tw = urwid.TreeWalker(self.fn)
        self.listbox = urwid.TreeListBox(self.tw)

        self.listbox.offset_rows = 3

        self.footer = urwid.AttrWrap(urwid.Text(self.footer_text),
                                     'foot')

        self.view = urwid.Frame(
            urwid.AttrWrap(self.listbox, 'body'),
            header=urwid.AttrWrap(self.header, 'head'),
            footer=self.footer, focus_part='header')

        self.i = 1
Ejemplo n.º 2
0
    def __init__(self, label, on_press=None, user_data=None):
        """
        label -- markup for button label
        on_press, user_data -- shorthand for connect_signal()
            function call for a single callback
        
        Signals supported: 'click'
        Register signal handler with:
          connect_signal(button, 'click', callback [,user_data])
        where callback is callback(button [,user_data])
        Unregister signal handlers with:
          disconnect_signal(button, 'click', callback [,user_data])

        >>> Button(u"Ok")
        <Button selectable 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)
Ejemplo n.º 3
0
Archivo: wimp.py Proyecto: eykd/urwid
    def __init__(self, label, on_press=None, user_data=None):
        """
        label -- markup for button label
        on_press, user_data -- shorthand for connect_signal()
            function call for a single callback

        Signals supported: 'click'
        Register signal handler with:
          connect_signal(button, 'click', callback [,user_data])
        where callback is callback(button [,user_data])
        Unregister signal handlers with:
          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)
Ejemplo n.º 4
0
    def __init__(self, body):
        """
        body -- a ListWalker-like object that contains
            widgets to be displayed inside the list box
        """
        if hasattr(body, 'get_focus'):
            self.body = body
        else:
            self.body = PollingListWalker(body)

        try:
            connect_signal(self.body, "modified", self._invalidate)
        except NameError:
            # our list walker has no modified signal so we must not
            # cache our canvases because we don't know when our
            # content has changed
            self.render = nocache_widget_render_instance(self)

        # offset_rows is the number of rows between the top of the view
        # and the top of the focused item
        self.offset_rows = 0
        # inset_fraction is used when the focused widget is off the
        # top of the view.  it is the fraction of the widget cut off
        # at the top.  (numerator, denominator)
        self.inset_fraction = (0, 1)

        # pref_col is the preferred column for the cursor when moving
        # between widgets that use the cursor (edit boxes etc.)
        self.pref_col = 'left'

        # variable for delayed focus change used by set_focus
        self.set_focus_pending = 'first selectable'

        # variable for delayed valign change used by set_focus_valign
        self.set_focus_valign_pending = None
Ejemplo n.º 5
0
 def __init__(self, df, csv_path):
     self._df = df
     self._csv_path = csv_path if (csv_path
                                   and csv_path != '-') else '<stdin>'
     self._col_widths = self._df_widths(df=df.head(200))
     self._header = FlexibleColumns(
         [(w,
           urwid.AttrMap(urwid.Text(str(x), wrap='clip', align='left'),
                         'column-header', 'column-header-selected'))
          for i, (w,
                  x) in enumerate(zip(self._col_widths, self._df.columns))],
         dividechars=1,
     )
     self._listbox = DataFrameListBox(df=df, col_widths=self._col_widths)
     self._footer_header = urwid.AttrMap(
         urwid.Columns([
             urwid.Text(str(self._csv_path), wrap='clip'),
             (8, urwid.Text('', wrap='clip', align='right')),
             (6, urwid.Text('', align='right')),
         ],
                       dividechars=1), 'footer-header')
     self._footer_body = urwid.Text('', align='left', wrap='clip')
     super().__init__(
         urwid.Frame(
             header=urwid.Pile([self._header,
                                urwid.Divider(div_char='─')]),
             body=self._listbox,
             footer=urwid.Pile([self._footer_header, self._footer_body]),
         ))
     signals.connect_signal(self._listbox, 'focused_col_changed',
                            self.handle_focused_col_changed)
     signals.connect_signal(self._listbox, 'focused_row_changed',
                            self.handle_focused_row_changed)
Ejemplo n.º 6
0
 def __init__(self):
     """Initialize a screen that directly prints escape codes to an output
     terminal.
     """
     super(Screen, self).__init__()
     self._pal_escape = {}
     self._pal_attrspec = {}
     signals.connect_signal(self, UPDATE_PALETTE_ENTRY, 
         self._on_update_palette_entry)
     self.colors = 16 # FIXME: detect this
     self.has_underline = True # FIXME: detect this
     self.register_palette_entry( None, 'default','default')
     self._keyqueue = []
     self.prev_input_resize = 0
     self.set_input_timeouts()
     self.screen_buf = None
     self._screen_buf_canvas = None
     self._resized = False
     self.maxrow = None
     self.gpm_mev = None
     self.gpm_event_pending = False
     self._mouse_tracking_enabled = False
     self.last_bstate = 0
     self._setup_G1_done = False
     self._rows_used = None
     self._cy = 0
     term = os.environ.get('TERM', '')
     self.bright_is_bold = not term.startswith("xterm")
     self.back_color_erase = not term.startswith("screen")
     self._next_timeout = None
     self._term_output_file = sys.stdout
     self._term_input_file = sys.stdin
     # pipe for signalling external event loops about resize events
     self._resize_pipe_rd, self._resize_pipe_wr = os.pipe()
     fcntl.fcntl(self._resize_pipe_rd, fcntl.F_SETFL, os.O_NONBLOCK)
Ejemplo n.º 7
0
    def __init__(self, body):
        """
        body -- a ListWalker-like object that contains
            widgets to be displayed inside the list box
        """
        if hasattr(body,'get_focus'):
            self.body = body
        else:
            self.body = PollingListWalker(body)

        try:
            connect_signal(self.body, "modified", self._invalidate)
        except NameError:
            # our list walker has no modified signal so we must not
            # cache our canvases because we don't know when our
            # content has changed
            self.render = nocache_widget_render_instance(self)

        # offset_rows is the number of rows between the top of the view
        # and the top of the focused item
        self.offset_rows = 0
        # inset_fraction is used when the focused widget is off the 
        # top of the view.  it is the fraction of the widget cut off 
        # at the top.  (numerator, denominator)
        self.inset_fraction = (0,1)

        # pref_col is the preferred column for the cursor when moving
        # between widgets that use the cursor (edit boxes etc.)
        self.pref_col = 'left'

        # variable for delayed focus change used by set_focus
        self.set_focus_pending = 'first selectable'
        
        # variable for delayed valign change used by set_focus_valign
        self.set_focus_valign_pending = None
Ejemplo n.º 8
0
    def start(self):
        """
        Sets up the main loop, hooking into the event loop where necessary.
        Starts the :attr:`screen` if it hasn't already been started.

        If you want to control starting and stopping the event loop yourself,
        you should call this method before starting, and call `stop` once the
        loop has finished.  You may also use this method as a context manager,
        which will stop the loop automatically at the end of the block:

            with main_loop.start():
                ...

        Note that some event loop implementations don't handle exceptions
        specially if you manage the event loop yourself.  In particular, the
        Twisted and asyncio loops won't stop automatically when
        :exc:`ExitMainLoop` (or anything else) is raised.
        """
        self.screen.start()

        if self.handle_mouse:
            self.screen.set_mouse_tracking()

        if not hasattr(self.screen, "hook_event_loop"):
            raise CantUseExternalLoop("Screen {0!r} doesn't support external event loops")

        try:
            signals.connect_signal(self.screen, INPUT_DESCRIPTORS_CHANGED, self._reset_input_descriptors)
        except NameError:
            pass
        # watch our input descriptors
        self._reset_input_descriptors()
        self.idle_handle = self.event_loop.enter_idle(self.entering_idle)

        return StoppingContext(self)
Ejemplo n.º 9
0
 def __init__(self):
     """Initialize a screen that directly prints escape codes to an output
     terminal.
     """
     super(Screen, self).__init__()
     self._pal_escape = {}
     self._pal_attrspec = {}
     signals.connect_signal(self, UPDATE_PALETTE_ENTRY,
                            self._on_update_palette_entry)
     self.colors = 16  # FIXME: detect this
     self.has_underline = True  # FIXME: detect this
     self.register_palette_entry(None, 'default', 'default')
     self._keyqueue = []
     self.prev_input_resize = 0
     self.set_input_timeouts()
     self.screen_buf = None
     self._screen_buf_canvas = None
     self._resized = False
     self.maxrow = None
     self.gpm_mev = None
     self.gpm_event_pending = False
     self._mouse_tracking_enabled = False
     self.last_bstate = 0
     self._setup_G1_done = False
     self._rows_used = None
     self._cy = 0
     term = os.environ.get('TERM', '')
     self.bright_is_bold = not term.startswith("xterm")
     self.back_color_erase = not term.startswith("screen")
     self._next_timeout = None
     self._term_output_file = sys.stdout
     self._term_input_file = sys.stdin
     # pipe for signalling external event loops about resize events
     self._resize_pipe_rd, self._resize_pipe_wr = os.pipe()
     fcntl.fcntl(self._resize_pipe_rd, fcntl.F_SETFL, os.O_NONBLOCK)
Ejemplo n.º 10
0
    def connect_signal(self, signal):
        self._sig_response = None

        def _set_signal_response(widget, *args, **kwargs):
            self._sig_response = (args, kwargs)
        self._set_signal_response = _set_signal_response

        signals.connect_signal(self.term, signal, self._set_signal_response)
    def connect_signal(self, signal):
        self._sig_response = None

        def _set_signal_response(widget, *args, **kwargs):
            self._sig_response = (args, kwargs)
        self._set_signal_response = _set_signal_response

        signals.connect_signal(self.term, signal, self._set_signal_response)
Ejemplo n.º 12
0
    def __init__(self, icon, label, on_press=None, user_data=None):
        self._icon = AttrMap(SelectableIcon(icon, 0), 'clip_dim')
        self._label = SelectableIcon(label, 0)

        cols = Columns([('fixed', len(icon), self._icon), self._label],
                       dividechars=1)
        WidgetWrap.__init__(self, cols)

        connect_signal(self, 'click', on_press, user_data)
Ejemplo n.º 13
0
    def __init__(self, label, on_press=None, user_data=None):
        self._label = urwid.wimp.SelectableIcon(label, 0)

        super(urwid.Button, self).__init__(self._label)
        # urwid.widget.WidgetWrap.__init__(self, self._label)

        # 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)
Ejemplo n.º 14
0
 def __init__(self, df, col_widths):
     self._size = None
     self._focused_col = None
     self._walker = DataFrameWalker(df=df, col_widths=col_widths)
     signals.connect_signal(
         self._walker,
         'modified',
         lambda: signals.emit_signal(self, 'focused_row_changed', self.
                                     focus_position),
     )
     super().__init__(self._walker)
Ejemplo n.º 15
0
    def __init__(self, icon, label, on_press=None, user_data=None): 
        self._icon  = AttrMap(SelectableIcon(icon, 0), 'clip_dim')
        self._label = SelectableIcon(label, 0)

        cols = Columns([
            ('fixed', len(icon), self._icon),
            self._label],
            dividechars=1)
        WidgetWrap.__init__(self, cols)

        connect_signal(self, 'click', on_press, user_data)
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
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)
Ejemplo n.º 18
0
    def __init__(self,
                 label,
                 state=False,
                 has_mixed=False,
                 on_state_change=None,
                 user_data=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'``

        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
        # 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)
Ejemplo n.º 19
0
    def __init__(self, input=STDIN, output=sys.stdout):
        """Initialize a screen that directly prints escape codes to an output
        terminal.
        """
        super(Screen, self).__init__()
        self._pal_escape = {}
        self._pal_attrspec = {}
        signals.connect_signal(self, UPDATE_PALETTE_ENTRY,
            self._on_update_palette_entry)
        self.colors = 16 # FIXME: detect this
        self.has_underline = True # FIXME: detect this
        self._keyqueue = []
        self.prev_input_resize = 0
        self.set_input_timeouts()
        self.screen_buf = None
        self._screen_buf_canvas = None
        self._resized = False
        self.maxrow = None
        self.gpm_mev = None
        self.gpm_event_pending = False
        self._mouse_tracking_enabled = False
        self.last_bstate = 0
        self._setup_G1_done = False
        self._rows_used = None
        self._cy = 0
        self.term = os.environ.get('TERM', '')
        self.fg_bright_is_bold = not self.term.startswith("xterm")
        self.bg_bright_is_blink = (self.term == "linux")
        self.back_color_erase = not self.term.startswith("screen")
        self.register_palette_entry( None, 'default','default')
        self._next_timeout = None
        self.signal_handler_setter = signal.signal

        # Our connections to the world
        self._term_output_file = output
        if input is STDIN:
            if IS_WINDOWS:
                input, self._send_input = socket.socketpair()
            else:
                input = sys.stdin
        self._term_input_file = input

        # pipe for signalling external event loops about resize events
        self._resize_pipe_rd, self._resize_pipe_wr = socket.socketpair()
        self._resize_pipe_rd.setblocking(False)
Ejemplo n.º 20
0
    def __init__(self):
        self.header = urwid.Edit()

        connect_signal(self.header, "change", self.update)

        self.carrega("lists_a", "osfab")

        self.listbox.offset_rows = 3

        self.footer = urwid.AttrWrap(urwid.Text(self.footer_text), "foot")

        self.view = urwid.Frame(
            urwid.AttrWrap(self.listbox, "body"),
            header=urwid.AttrWrap(self.header, "head"),
            footer=self.footer,
            focus_part="header",
        )

        self.i = 1
Ejemplo n.º 21
0
    def _run(self):
        if self.handle_mouse:
            self.screen.set_mouse_tracking()

        if not hasattr(self.screen, 'get_input_descriptors'):
            return self._run_screen_event_loop()

        self.draw_screen()

        fd_handles = []

        def reset_input_descriptors(only_remove=False):
            for handle in fd_handles:
                self.event_loop.remove_watch_file(handle)
            if only_remove:
                del fd_handles[:]
            else:
                fd_handles[:] = [
                    self.event_loop.watch_file(fd, self._update)
                    for fd in self.screen.get_input_descriptors()
                ]
            if not fd_handles and self._input_timeout is not None:
                self.event_loop.remove_alarm(self._input_timeout)

        try:
            signals.connect_signal(self.screen, INPUT_DESCRIPTORS_CHANGED,
                                   reset_input_descriptors)
        except NameError:
            pass
        # watch our input descriptors
        reset_input_descriptors()
        idle_handle = self.event_loop.enter_idle(self.entering_idle)

        # Go..
        self.event_loop.run()

        # tidy up
        self.event_loop.remove_enter_idle(idle_handle)
        reset_input_descriptors(True)
        signals.disconnect_signal(self.screen, INPUT_DESCRIPTORS_CHANGED,
                                  reset_input_descriptors)
Ejemplo n.º 22
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)
Ejemplo n.º 23
0
    def _run(self):
        if self.handle_mouse:
            self.screen.set_mouse_tracking()

        if not hasattr(self.screen, 'get_input_descriptors'):
            return self._run_screen_event_loop()

        self.draw_screen()

        fd_handles = []
        def reset_input_descriptors(only_remove=False):
            for handle in fd_handles:
                self.event_loop.remove_watch_file(handle)
            if only_remove:
                del fd_handles[:]
            else:
                fd_handles[:] = [
                    self.event_loop.watch_file(fd, self._update)
                    for fd in self.screen.get_input_descriptors()]
            if not fd_handles and self._input_timeout is not None:
                self.event_loop.remove_alarm(self._input_timeout)

        try:
            signals.connect_signal(self.screen, INPUT_DESCRIPTORS_CHANGED,
                reset_input_descriptors)
        except NameError:
            pass
        # watch our input descriptors
        reset_input_descriptors()
        idle_handle = self.event_loop.enter_idle(self.entering_idle)

        # Go..
        self.event_loop.run()

        # tidy up
        self.event_loop.remove_enter_idle(idle_handle)
        reset_input_descriptors(True)
        signals.disconnect_signal(self.screen, INPUT_DESCRIPTORS_CHANGED,
            reset_input_descriptors)
Ejemplo n.º 24
0
    def start(self):
        """
        Sets up the main loop, hooking into the event loop where necessary.
        Starts the :attr:`screen` if it hasn't already been started.

        If you want to control starting and stopping the event loop yourself,
        you should call this method before starting, and call `stop` once the
        loop has finished.  You may also use this method as a context manager,
        which will stop the loop automatically at the end of the block:

            with main_loop.start():
                ...

        Note that some event loop implementations don't handle exceptions
        specially if you manage the event loop yourself.  In particular, the
        Twisted and asyncio loops won't stop automatically when
        :exc:`ExitMainLoop` (or anything else) is raised.
        """
        self.screen.start()

        if self.handle_mouse:
            self.screen.set_mouse_tracking()

        if not hasattr(self.screen, 'hook_event_loop'):
            raise CantUseExternalLoop(
                "Screen {0!r} doesn't support external event loops")

        try:
            signals.connect_signal(self.screen, INPUT_DESCRIPTORS_CHANGED,
                                   self._reset_input_descriptors)
        except NameError:
            pass
        # watch our input descriptors
        self._reset_input_descriptors()
        self.idle_handle = self.event_loop.enter_idle(self.entering_idle)

        return StoppingContext(self)
Ejemplo n.º 25
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("Confirm")
        <CheckBox selectable widget 'Confirm' state=False>
        >>> CheckBox("Yogourt", "mixed", True)
        <CheckBox selectable widget 'Yogourt' state='mixed'>
        >>> cb = CheckBox("Extra onions", True)
        >>> cb
        <CheckBox selectable widget 'Extra onions' state=True>
        >>> cb.render((20,), focus=True).text  # preview CheckBox
        ['[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)