示例#1
0
    def update_widgets(self,
                       update_dir=True,
                       update_file=True,
                       update_select=True):
        """
        Update self.dir_widget, self.file_widget or self.select_widget,
        corresponding to which of the paramters are set to True.
        """

        if update_dir or update_file:
            (dirlist, filelist) = self._dirfiles(self.directory)

        if update_dir:
            # Directory widget:
            widget_list = [
                AttrWrap(SelText(dir), None, self.attr[1]) for dir in dirlist
            ]

            self.dir_widget.box_widget.body = SimpleListWalker(widget_list)

        if update_file:
            # File widget:
            widget_list = [
                AttrWrap(SelText(dir), None, self.attr[1]) for dir in filelist
            ]

            self.file_widget.box_widget.body = SimpleListWalker(widget_list)

        if update_select:
            # Selection widget:
            selected_file = join(self.directory, self.file)
            self.select_widget.set_edit_text(selected_file)
示例#2
0
    def __init__(self, choice_callback=None,
                       command_callback=None,
                       help_callback=None):

        self.palette = [
                ('brick', 'light red', 'black'),
                ('rubble', 'yellow', 'black'),
                ('wood', 'light green', 'black'),
                ('concrete', 'white', 'black'),
                ('stone', 'light cyan', 'black'),
                ('marble', 'light magenta', 'black'),
                ('jack', 'dark gray', 'white'),
                ('msg_info', 'white', 'black'),
                ('msg_err', 'light red', 'black'),
                ('msg_debug', 'light green', 'black'),
                ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
                LineBox(self.state),
                (13, LineBox(self.choices)),
                ])

        self.right_frame = Pile([
                LineBox(self.game_log),
                LineBox(self.roll)
                ])

        self.state.set_focus(len(self.state_text)-1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)
                                ])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None
示例#3
0
class Sidebar(BoxWidget):
    signals = ['select', 'search']

    def __init__(self, phones):
        self.phone_edit = EnterEdit('Phone:', '')
        self.chan_edit = EnterEdit('Chanl:', '')
        self.call_id_edit = EnterEdit('SipID:', '')
        self.text_edit = EnterEdit('Find:', '')
        connect_signal(self.phone_edit, 'enter', self.on_change, 'phone')
        connect_signal(self.chan_edit, 'enter', self.on_change, 'chan')
        connect_signal(self.call_id_edit, 'enter', self.on_change, 'call_id')
        connect_signal(self.text_edit, 'enter', self.on_change, 'text')
        self.phones_text = Text([('key', 'F4'), ' Phones'])
        self.head = Pile([
            AttrWrap(Text([('key', 'F3'), ' Search']), 'bar'),
            AttrWrap(self.phone_edit, 'no', 'selection'),
            AttrWrap(self.chan_edit, 'no', 'selection'),
            AttrWrap(self.call_id_edit, 'no', 'selection'),
            Divider('-'),
            AttrWrap(self.text_edit, 'no', 'selection'),
            AttrWrap(self.phones_text, 'bar'),
        ])
        self.items = SimpleListWalker([])
        self.set_results(phones)
        self.listbox = ListBox(self.items)
        self.frame = Frame(self.listbox, header=self.head)

    def set_results(self, results):
        self.phones_text.set_text([('key', 'F4'),
                                   ' Results (%s)' % len(results)])
        self.items[:] = []
        group = []
        for ref in results:
            item = RadioButton(group, ref, state=False)
            connect_signal(item, 'change', self.on_select_phone, ref)
            item = AttrWrap(item, 'no', 'selection')
            self.items.append(item)

    def render(self, size, focus=False):
        return self.frame.render(size, focus)

    def keypress(self, size, key):
        return self.frame.keypress(size, key)

    # noinspection PyUnusedLocal
    def on_select_phone(self, button, new_state, call_id):
        if new_state:
            self._emit('select', call_id)

    # noinspection PyUnusedLocal
    def on_change(self, widget, value, field_name):
        self._emit('search', field_name, value)
示例#4
0
文件: widget.py 项目: coyotevz/nobix
class Menu(Dialog):#{{{

    def __init__(self, menu_items, focus_item=0, **kwargs):#{{{
        # menu items: ( (text, attr), (callback, args), shortcut )
        self.item_list = SimpleListWalker([])
        listbox = ListBox(self.item_list)
        self.__super.__init__(listbox, keypress=self.on_keypress, **kwargs)

        self.attr_style = 'dialog.menu'
        self.title_attr_style = 'dialog.menu.title'
        self.shortcuts = {}

        def wrap(callback):
            if callback:
                def w(*args):
                    self.install_callback(callback, args)
                    self.quit()
                w.__name__ = callback.__name__
                w.__doc__ = callback.__doc__
                return w
            return None


        for item in menu_items:
            tag_attr = item[0]
            if len(item) > 1:
                ca = item[1]
                if isinstance(ca, tuple):
                    if len(ca) == 2:
                        cb, args = ca
                    else:
                        cb, args = ca, ()
                else:
                    cb = ca
                    args = ()
                if not callable(cb):
                    raise ValueError("You must pass a callable callback")
            else:
                cb, args = None, ()
            self.item_list.append(AttrMap(MenuItem(tag_attr, wrap(cb), args),
                                  'dialog.menu.item', 'dialog.menu.item.focus'))
            if len(item) > 2:
                self.shortcuts[item[2]] = len(self.item_list) - 1

        self.item_list.set_focus(focus_item)
#}}}
    def on_keypress(self, key):#{{{
        if key == "esc":
            self.quit()
        elif key in self.shortcuts:
            self.item_list[self.shortcuts[key]].original_widget.activate()
        return key
示例#5
0
    def __init__(self, name):
        self.name = name

        self._connected = False
        self._parent = None

        self.status = {}
        self.children = []
        self.input_history = None
        self.output_walker = SimpleListWalker([])
        self.input_text = ""
        self.auto_scroll = True

        self.read_line_index = -1
示例#6
0
    def __init__(self, num_rows=20, w=(14, 14, 18, 16, 16, 16, 20)):
        """
            @method __init__
            Initializes the widget
        """
        self.m_process_list = ProcessList(w)
        self.prev_sort_item = None

        self.w_status = HeaderButton('Status', 'status', self.handle_click)
        self.w_pid = HeaderButton('PID', 'pid', self.handle_click)
        self.w_name = HeaderButton('Name', 'name', self.handle_click)
        self.w_cpu = HeaderButton('CPU %', 'cpu_perc', self.handle_click)
        self.w_mem = HeaderButton('MEM %', 'mem_perc', self.handle_click)
        self.w_up = HeaderButton('Uptime', 'uptime', self.handle_click)
        self.w_pname = HeaderButton('Process', 'pname', self.handle_click)

        self.w_cpu.activate()
        self.prev_sort_item = self.w_cpu

        self.header_buttons = h = [
            self.w_status, self.w_pid, self.w_name, self.w_cpu, self.w_mem,
            self.w_up, self.w_pname
        ]

        m_header = AttrMap(
            Columns([('fixed', w[i], h[i]) for i in range(0, len(h))]),
            'invert')
        m_lb = ListBox(
            SimpleListWalker(
                [m_header, BoxAdapter(self.m_process_list, num_rows)]))
        super(ProcessTable, self).__init__(m_lb, None)
        self.update()
示例#7
0
    def create_interface(self):
        self.screen = Screen()
        self.screen.start()

        self.screen.register_palette([
            ("title", "white", "dark blue", "standout"),
            ("line", "light gray", "black"),
            ("help", "white", "dark blue")]
        )

        self.body = ListBox(SimpleListWalker([]))
        self.lines = self.body.body

        self.title = Text(MAIN_TITLE)
        self.header = AttrWrap(self.title, "title")

        self.help = AttrWrap(
            Text(HELP_STRINGS["main"]),
            "help"
        )

        self.input = Edit(caption="%s> " % self.ircchannel)
        self.footer = Pile([self.help, self.input])

        self.top = Frame(self.body, self.header, self.footer)
示例#8
0
    def _build_widget(self, **kwargs):
        total_items = []
        for _item in self.radio_items.keys():
            desc = AttrWrap(
                Text("  {}".format(
                    self.radio_items[_item][1])), 'input', 'input focus')
            total_items.append(
                AttrWrap(self.radio_items[_item][0], 'input', 'input focus'))
            total_items.append(AttrWrap(desc, 'input'))
            total_items.append(Divider('-'))

        self.input_lbox = ListBox(SimpleListWalker(total_items[:-1]))
        self.add_buttons()

        self.container_box_adapter = BoxAdapter(self.input_lbox,
                                                len(total_items))
        self.container_lbox = ListBox(
            [self.container_box_adapter,
             Divider(),
             self.btn_pile])

        return LineBox(
            BoxAdapter(self.container_lbox,
                       height=len(total_items) + 3),
            title=self.title)
示例#9
0
    def __init__(self,
                 choice_callback=None,
                 command_callback=None,
                 help_callback=None):

        self.palette = [
            ('brick', 'light red', 'black'),
            ('rubble', 'yellow', 'black'),
            ('wood', 'light green', 'black'),
            ('concrete', 'white', 'black'),
            ('stone', 'light cyan', 'black'),
            ('marble', 'light magenta', 'black'),
            ('jack', 'dark gray', 'white'),
            ('msg_info', 'white', 'black'),
            ('msg_err', 'light red', 'black'),
            ('msg_debug', 'light green', 'black'),
        ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
            LineBox(self.state),
            (13, LineBox(self.choices)),
        ])

        self.right_frame = Pile([LineBox(self.game_log), LineBox(self.roll)])

        self.state.set_focus(len(self.state_text) - 1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None
示例#10
0
    def render_component(self, props):
        def make_todo(id, completed, text):
            def on_click():
                props['on_todo_click'](id)

            return Todo(
                on_click=on_click,
                completed=completed,
                text=text,
            )

        return ListBox(
            SimpleListWalker([make_todo(**todo) for todo in props['todos']]))
示例#11
0
    def __init__(self, contents, offset=1):
        """
        Arguments:

        `contents` is a list with the elements contained in the
        `ScrollableListBox`.

        `offset` is the number of position that `scroll_up` and `scroll_down`
        shift the cursor.
        """
        self.offset = offset

        ListBox.__init__(self, SimpleListWalker(contents))
示例#12
0
 def __init__(self, phones):
     self.phone_edit = EnterEdit('Phone:', '')
     self.chan_edit = EnterEdit('Chanl:', '')
     self.call_id_edit = EnterEdit('SipID:', '')
     self.text_edit = EnterEdit('Find:', '')
     connect_signal(self.phone_edit, 'enter', self.on_change, 'phone')
     connect_signal(self.chan_edit, 'enter', self.on_change, 'chan')
     connect_signal(self.call_id_edit, 'enter', self.on_change, 'call_id')
     connect_signal(self.text_edit, 'enter', self.on_change, 'text')
     self.phones_text = Text([('key', 'F4'), ' Phones'])
     self.head = Pile([
         AttrWrap(Text([('key', 'F3'), ' Search']), 'bar'),
         AttrWrap(self.phone_edit, 'no', 'selection'),
         AttrWrap(self.chan_edit, 'no', 'selection'),
         AttrWrap(self.call_id_edit, 'no', 'selection'),
         Divider('-'),
         AttrWrap(self.text_edit, 'no', 'selection'),
         AttrWrap(self.phones_text, 'bar'),
     ])
     self.items = SimpleListWalker([])
     self.set_results(phones)
     self.listbox = ListBox(self.items)
     self.frame = Frame(self.listbox, header=self.head)
示例#13
0
文件: tabs.py 项目: sushi-irc/nigiri
	def __init__(self, name):
		self.name = name

		self._connected = False
		self._parent = None

		self.status = {}
		self.children = []
		self.input_history = None
		self.output_walker = SimpleListWalker([])
		self.input_text = ""
		self.auto_scroll = True

		self.read_line_index = -1
示例#14
0
    def _insert_charm_selections(self):
        first_index = 0
        bgroup = []
        for i, charm_class in enumerate(self.charms):
            charm = charm_class
            if charm.name() and not first_index:
                first_index = i
            r = RadioButton(bgroup, charm.name())
            r.text_label = charm.name()
            self.boxes.append(r)

        # Add input widget for specifying NumUnits
        self.count_editor = IntEdit("Number of units to add: ", 1)
        self.boxes.append(self.count_editor)
        wrapped_boxes = self._wrap_focus(self.boxes)
        items = ListBox(SimpleListWalker(wrapped_boxes))
        items.set_focus(first_index)
        return (len(self.boxes), BoxAdapter(items, len(self.boxes)))
示例#15
0
    def _build_widget(self, **kwargs):

        total_items = []
        for _item in self.input_items.keys():
            total_items.append(
                AttrWrap(self.input_items[_item], 'input', 'input focus'))
        self.input_lbox = ListBox(SimpleListWalker(total_items))

        # Add buttons
        self.add_buttons()
        self.container_box_adapter = BoxAdapter(self.input_lbox,
                                                len(total_items))
        self.container_lbox = ListBox(
            [self.container_box_adapter,
             Divider(), self.btn_pile])

        return LineBox(BoxAdapter(self.container_lbox,
                                  height=len(total_items) + 1 +
                                  len(self.btn_pile.contents)),
                       title=self.title)
示例#16
0
文件: widget.py 项目: coyotevz/nobix
    def __init__(self, **kwargs):#{{{

        self.search_box = SearchBox()
        self.items_count = Text("", align='right')

        self.search_items = SimpleListWalker(self._null_list_item())
        connect_signal(self.search_items, "modified", self._update_items_count)
        self.search_list = ListBox(self.search_items)

        connect_signal(self.search_box, "edit-done", self.on_edit_done)
        connect_signal(self.search_box, "edit-cancel", lambda w: self.quit())
        connect_signal(self.search_box, "change", lambda sb, term: self.set_search_term(term))

        self._constr = self.get_item_constructor()

        self.multiple_selection = kwargs.pop('multiple_selection', False)
        self._selected_items = OrderedSet([])

        opts = {
            'height': kwargs.get('height', None),
            'width': kwargs.get('width', ('relative', 90)),
            'title': kwargs.get('title', self.title),
            'subtitle': kwargs.get('subtitle', self.subtitle),
            'compact_header': kwargs.get('compact_header', True),
        }
        kwargs.update(opts)

        self.pile = Pile([
            ('fixed', 15, AttrMap(self.search_list, 'dialog.search.item')),
            Columns([
                AttrMap(self.search_box, 'dialog.search.input'),
                ('fixed', 1, AttrMap(Divider(), 'dialog.search.input')),
                ('fixed', 4, AttrMap(self.items_count, 'dialog.search.input')),
                ]),
            ], focus_item=0)

        self.__super.__init__(self.pile, **kwargs)

        self.attr_style = "dialog.search"
        self.title_attr_style = "dialog.search.title"
        self.subtitle_attr_style = "dialog.search.subtitle"
示例#17
0
class CursesGUI(object):
    def __init__(self,
                 choice_callback=None,
                 command_callback=None,
                 help_callback=None):

        self.palette = [
            ('brick', 'light red', 'black'),
            ('rubble', 'yellow', 'black'),
            ('wood', 'light green', 'black'),
            ('concrete', 'white', 'black'),
            ('stone', 'light cyan', 'black'),
            ('marble', 'light magenta', 'black'),
            ('jack', 'dark gray', 'white'),
            ('msg_info', 'white', 'black'),
            ('msg_err', 'light red', 'black'),
            ('msg_debug', 'light green', 'black'),
        ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
            LineBox(self.state),
            (13, LineBox(self.choices)),
        ])

        self.right_frame = Pile([LineBox(self.game_log), LineBox(self.roll)])

        self.state.set_focus(len(self.state_text) - 1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None

    def register_loggers(self):
        """Gets the global loggers and sets up log handlers.
        """
        self.game_logger_handler = RollLogHandler(self._roll_write)
        self.logger_handler = RollLogHandler(self._roll_write)

        self.game_logger = logging.getLogger('gtr.game')
        self.logger = logging.getLogger('gtr')

        self.logger.addHandler(self.logger_handler)
        self.game_logger.addHandler(self.game_logger_handler)

        #self.set_log_level(logging.INFO)

    def unregister_loggers(self):
        self.game_logger.removeHandler(self.game_logger_handler)
        self.logger.removeHandler(self.logger_handler)

    def fail_safely(f):
        """Wraps functions in this class to catch arbitrary exceptions,
        shut down the event loop and reset the terminal to a normal state.

        It then re-raises the exception.
        """
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            retval = None
            try:
                retval = f(self, *args, **kwargs)
            except urwid.ExitMainLoop:
                from twisted.internet import reactor
                if not self.reactor_stop_fired and reactor.running:
                    # Make sure to call reactor.stop once
                    reactor.stop()
                    self.reactor_stop_fired = True

            except:
                #pdb.set_trace()
                from twisted.internet import reactor
                if not self.reactor_stop_fired and reactor.running:
                    # Make sure to call reactor.stop once
                    reactor.stop()
                    self.reactor_stop_fired = True

                if not self.called_loop_stop:
                    self.called_loop_stop = True
                    self.loop.stop()

                # Save exception info for printing later outside the GUI.
                self.exc_info = sys.exc_info()

                raise

            return retval

        return wrapper

    def set_log_level(self, level):
        """Set the log level as per the standard library logging module.

        Default is logging.INFO.
        """
        logging.getLogger('gtr.game').setLevel(level)
        logging.getLogger('gtr').setLevel(level)

    def run(self):
        loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input)
        loop.run()

    def run_twisted(self):
        from twisted.internet import reactor
        evloop = urwid.TwistedEventLoop(reactor, manage_reactor=False)
        self.screen = urwid.raw_display.Screen()
        self.screen.register_palette(self.palette)
        self.loop = MainLoop(self.frame_widget,
                             unhandled_input=self.handle_input,
                             screen=self.screen,
                             event_loop=evloop)
        self.loop.set_alarm_in(0.1, lambda loop, _: loop.draw_screen())

        self.loop.start()

        # The loggers get a Handler that writes to the screen. We want this to only
        # happen if the screen exists, so de-register them after the reactor stops.
        reactor.addSystemEventTrigger('after', 'startup',
                                      self.register_loggers)
        reactor.addSystemEventTrigger('before', 'shutdown',
                                      self.unregister_loggers)
        reactor.run()

        # We might have stopped the screen already, and the stop() method
        # doesn't check for stopping twice.
        if self.called_loop_stop:
            self.logger.warn('Internal error!')
        else:
            self.loop.stop()
            self.called_loop_stop = True

    @fail_safely
    def handle_input(self, key):
        if key == 'enter':
            text = self.edit_widget.edit_text
            if text in ['q', 'Q']:
                self.handle_quit_request()
            else:
                self.quit_flag = False

                try:
                    i = int(text)
                except ValueError:
                    i = None
                    self.handle_invalid_choice(text)

                if i is not None:
                    self.handle_choice(i)

            self.edit_widget.set_edit_text('')

    def _roll_write(self, line, attr=None):
        """Add a line to the roll with palette attributes 'attr'.

        If no attr is specified, None is used.

        Default attr is plain text
        """
        text = Text((attr, '* ' + line))

        self.roll_list.append(text)
        self.roll_list.set_focus(len(self.roll_list) - 1)
        self._modified()

    @fail_safely
    def update_state(self, state):
        """Sets the game state window via one large string.
        """
        self.logger.debug('Drawing game state.')
        self.state_text[:] = [self.colorize(s) for s in state.split('\n')]
        self._modified()

    @fail_safely
    def update_game_log(self, log):
        """Sets the game log window via one large string.
        """
        self.logger.debug('Drawing game log.')
        self.game_log_list[:] = [self.colorize(s) for s in log.split('\n')]
        self.game_log_list.set_focus(len(self.game_log_list) - 1)
        self._modified()

    @fail_safely
    def update_choices(self, choices):
        """Update choices list.
        """
        self.choices_list[:] = [self.colorize(str(c)) for c in choices]
        self._modified()

        length = len([c for c in choices if c[2] == '['])
        i = randint(1, length) if length else 0
        self.choices_list.append(
            self.colorize('\nPicking random choice: {0} in 1s'.format(i)))
        self._modified()
        #from twisted.internet import reactor
        #reactor.callLater(1, self.handle_choice, i)

    @fail_safely
    def update_prompt(self, prompt):
        """Set the prompt for the input field.
        """
        self.edit_widget.set_caption(prompt)
        self._modified()

    def _modified(self):
        if self.loop:
            self.loop.draw_screen()

    @fail_safely
    def quit(self):
        """Quit the program.
        """
        #import pdb; pdb.set_trace()
        #raise TypeError('Artificial TypeError')
        raise urwid.ExitMainLoop()

    def handle_invalid_choice(self, s):
        if len(s):
            text = 'Invalid choice: "' + s + '". Please enter an integer.'
            self.logger.warn(text)

    def handle_quit_request(self):
        if True or self.quit_flag:
            self.quit()
        else:
            self.quit_flag = True
            text = 'Are you sure you want to quit? Press Q again to confirm.'
            self.logger.warn(text)

    def handle_choice(self, i):
        if self.choice_callback:
            self.choice_callback(i)

    def colorize(self, s):
        """Applies color to roles found in a string.

        A string with attributes applied looks like

        Text([('attr1', 'some text'), 'some more text'])

        so we need to split into a list of tuples of text.
        """
        regex_color_dict = {
            r'\b([Ll]egionaries|[Ll]egionary|[Ll]eg|LEGIONARIES|LEGIONARY|LEG)\b':
            'brick',
            r'\b([Ll]aborers?|[Ll]ab|LABORERS?|LAB)\b': 'rubble',
            r'\b([Cc]raftsmen|[Cc]raftsman|[Cc]ra|CRAFTSMEN|CRAFTSMAN|CRA)\b':
            'wood',
            r'\b([Aa]rchitects?|[Aa]rc|ARCHITECTS?|ARC)\b': 'concrete',
            r'\b([Mm]erchants?|[Mm]er|MERCHANTS?|MER)\b': 'stone',
            r'\b([Pp]atrons?|[Pp]at|PATRONS?|PAT)\b': 'marble',
            r'\b([Jj]acks?|JACKS?)\b': 'jack',
            r'\b([Bb]ricks?|[Bb]ri|BRICKS?|BRI)\b': 'brick',
            r'\b([Rr]ubble|[Rr]ub|RUBBLE|RUB)\b': 'rubble',
            r'\b([Ww]ood|[Ww]oo|WOOD|WOO)\b': 'wood',
            r'\b([Cc]oncrete|[Cc]on|CONCRETE|CON)\b': 'concrete',
            r'\b([Ss]tone|[Ss]to|STONE|STO)\b': 'stone',
            r'\b([Mm]arble|[Mm]ar|MARBLE|MAR)\b': 'marble',
        }

        def _colorize(s, regex, attr):
            """s is a tuple of ('attr', 'text'). This splits based on the regex
            and adds attr to any matches. Returns a list of tuples

            [('attr1', 'text1'), ('attr2', 'text2'), ('attr3','text3')]

            with some attributes being None if they aren't colored.
            """
            output = []
            a, t = s
            # Make a list of all tokens, split by matches
            tokens = re.split(regex, t)
            for tok in tokens:
                m = re.match(regex, tok)
                if m:
                    # matches get the new attributes
                    output.append((attr, tok))
                else:
                    # non-matches keep the old ones
                    output.append((a, tok))

            return output

        output = [(None, s)]

        for k, v in regex_color_dict.items():
            new_output = []
            for token in output:
                new_output.extend(_colorize(token, k, v))

            output[:] = new_output

        return Text(output)
示例#18
0
 def __init__(self, content):
     self.walker = SimpleListWalker(content)
     super(SimpleListBox, self).__init__(self.walker)
示例#19
0
        """
        return datetime.fromtimestamp(self.pget_uptime()).strftime(f)


"""
    Testing
"""
if __name__ == '__main__':

    def exit(p):
        if p is 'q':
            raise ExitMainLoop()

    def refresh(loop, data):
        p1.update()
        p2.update()
        loop.set_alarm_in(1, refresh)

    p1 = Process(1, lambda x: x, lambda: x)
    p2 = Process(os.getpid(), lambda x: x, lambda: x)

    lb = ListBox(SimpleListWalker([p1, p2]))

    m = MainLoop(lb,
                 palette=[('reversed', 'standout', ''),
                          ('popbg', 'white', 'dark blue')],
                 pop_ups=True,
                 unhandled_input=exit)
    m.set_alarm_in(1, refresh)
    m.run()
示例#20
0
    def _build_widget(self):
        lw = SimpleListWalker([x for x in self.contents])

        return ListBox(lw)
示例#21
0
文件: widget.py 项目: coyotevz/nobix
class SearchDialog(Dialog):#{{{
    title = "SearchDialog"
    subtitle = "GenericWindow"
    _items = []

    def __init__(self, **kwargs):#{{{

        self.search_box = SearchBox()
        self.items_count = Text("", align='right')

        self.search_items = SimpleListWalker(self._null_list_item())
        connect_signal(self.search_items, "modified", self._update_items_count)
        self.search_list = ListBox(self.search_items)

        connect_signal(self.search_box, "edit-done", self.on_edit_done)
        connect_signal(self.search_box, "edit-cancel", lambda w: self.quit())
        connect_signal(self.search_box, "change", lambda sb, term: self.set_search_term(term))

        self._constr = self.get_item_constructor()

        self.multiple_selection = kwargs.pop('multiple_selection', False)
        self._selected_items = OrderedSet([])

        opts = {
            'height': kwargs.get('height', None),
            'width': kwargs.get('width', ('relative', 90)),
            'title': kwargs.get('title', self.title),
            'subtitle': kwargs.get('subtitle', self.subtitle),
            'compact_header': kwargs.get('compact_header', True),
        }
        kwargs.update(opts)

        self.pile = Pile([
            ('fixed', 15, AttrMap(self.search_list, 'dialog.search.item')),
            Columns([
                AttrMap(self.search_box, 'dialog.search.input'),
                ('fixed', 1, AttrMap(Divider(), 'dialog.search.input')),
                ('fixed', 4, AttrMap(self.items_count, 'dialog.search.input')),
                ]),
            ], focus_item=0)

        self.__super.__init__(self.pile, **kwargs)

        self.attr_style = "dialog.search"
        self.title_attr_style = "dialog.search.title"
        self.subtitle_attr_style = "dialog.search.subtitle"
#}}}
    def keypress(self, key):#{{{
        if key == 'insert' and self.multiple_selection:
            if self.pile.get_focus().original_widget is self.search_list:
                wid, pos = self.search_list.get_focus()
            else:
                pos = 0
            current_item = self.search_items[pos]
            article = self.get_data_for(pos)
            current_item.original_widget.selected = not current_item.original_widget.selected
            if current_item.original_widget.selected:
                current_item.attr_map = {None: 'dialog.search.item.selected'}
                current_item.focus_map = {None: 'dialog.search.item.focus.selected'}
                self._selected_items.add(article)
            else:
                current_item.attr_map = {None: 'dialog.search.item'}
                current_item.focus_map = {None: 'dialog.search.item.focus'}
                self._selected_items.discard(article)

            self.search_list.set_focus(pos+1)
            self._update_items_count()
#}}}
    def on_edit_done(self, widget, text):#{{{
        result = []
        if self.pile.get_focus().original_widget is self.search_list:
            wid, pos = self.search_list.get_focus()
        else:
            pos = 0
        if self.multiple_selection:
            result = list(self._selected_items)
        if len(result) < 1:
            if self.get_data_for(pos):
                result = [self.get_data_for(pos)]
        self.dialog_result = result
        self.quit()
#}}}
    def set_search_term(self, term):#{{{
        self._clear_search_items()
        query = self.get_query(term)
        if query is not None:
            self._items = tuple(query[:150])
            if len(self._items) > 0:
                l_items = map(self._constr, self._items)
                for i in l_items:
                    i.set_search_box(self.search_box)
                self.search_items.extend([AttrMap(i, 'dialog.search.item',\
                    'dialog.search.item.focus') for i in l_items])
                if self.multiple_selection:
                    for a in (self._selected_items & set(self._items)):
                        idx = self._items.index(a)
                        self.search_items[idx].attr_map = {None: 'dialog.search.item.selected'}
                        self.search_items[idx].focus_map = {None: 'dialog.search.item.focus.selected'}
                        self.search_items[idx].original_widget.selected = True
                return
        self.search_items.extend(self._null_list_item())
#}}}
    def _clear_search_items(self):#{{{
        self.search_items[:] = []
        self._update_items_count()
#}}}
    def _null_list_item(self):#{{{
        null = SearchListItem([Text("")])
        null.set_search_box(self.search_box)
        return [null]
#}}}
    def _update_items_count(self):#{{{
        if len(self.search_items) > 149:
            self.items_count.set_text("+150")
        else:
            self.items_count.set_text("")
        selected_count = len(self._selected_items)
        if selected_count > 0:
            self._title_widget.set_text(self.title + (" (+%d)" % selected_count))
        else:
            self._title_widget.set_text(self.title)

#}}}
    def get_data_for(self, index):#{{{
        try:
            return self._items[index]
        except IndexError as e: # index out of range
            return None
#}}}
    def get_query(self, term):#{{{
        raise NotImplementedError("This must be implemented by subclass")
#}}}
    def get_item_constructor(self):#{{{
        return None
示例#22
0
 def __init__(self, contents):
     self.list_walker = SimpleListWalker(contents)
     ListBox.__init__(self, self.list_walker)
示例#23
0
 def __init__(self, tags):
     tag_widgets = self._create_tag_widgets(tags)
     self.list_content = SimpleListWalker(tag_widgets)
     ListBox.__init__(self, self.list_content)
示例#24
0
class Tab(object):

    __metaclass__ = MetaSignals
    signals = ["child_added", "child_removed", "remove", "connected"]

    _valid_stati = [
        "informative", "actions", "actions_highlight", "actions_own",
        "messages", "messages_highlight", "messages_own"
    ]

    def __repr__(self):
        return "<tab: %s:%s:%s>" % (type(self).__name__, self._parent,
                                    self.name)

    def __str__(self):
        return self.name

    # Properties

    @types(switch=bool)
    def set_connected(self, switch):
        self._connected = switch

        for child in self.children:
            child.set_connected(switch)

        urwid.emit_signal(self, "connected", switch)

    connected = property(lambda x: x._connected, set_connected)

    def set_input_text(self, text):
        self._input_text = text

    input_text = property(lambda x: x._input_text, set_input_text)

    # Methods

    @types(name=(String, str, unicode))
    def __init__(self, name):
        self.name = name

        self._connected = False
        self._parent = None

        self.status = {}
        self.children = []
        self.input_history = None
        self.output_walker = SimpleListWalker([])
        self.input_text = ""
        self.auto_scroll = True

        self.read_line_index = -1

    def set_readline(self):
        if self.read_line_index != -1:
            try:
                del self.output_walker[self.read_line_index]
            except IndexError:
                pass

        line = Text("-" * 30)
        line.set_align_mode("center")
        self.output_walker.append(line)
        self.read_line_index = len(self.output_walker) - 1

    def child_added(self, child):
        urwid.emit_signal(self, "child_added", self, child)
        child.set_connected(self.connected)
        self.children.append(child)

    def child_removed(self, child):
        urwid.emit_signal(self, "child_removed", self, child)
        try:
            i = self.children.index(child)
        except ValueError:
            pass
        else:
            del self.children[i]

    def set_parent(self, parent):
        if parent in self.children:
            print "Loop detected in '%s'.set_parent(%s)" % (self, parent)
            return

        try:
            self._parent.child_removed(self)
        except AttributeError:
            pass

        self._parent = parent

        try:
            self._parent.child_added(self)
        except AttributeError:
            pass

    parent = property(lambda x: x._parent, set_parent)

    def remove(self):
        """ emit remove signals """
        for child in self.children:
            child.remove()
            self.child_removed(child)
        urwid.emit_signal(self, "remove")
        self.set_parent(None)

    @types(name=str)
    def add_status(self, name):
        if name in self._valid_stati:
            self.status[name] = True

    @types(status=str)
    def has_status(self, status):
        return self.status.has_key(status)

    @types(name=str)
    def remove_status(self, name):
        try:
            del self.status[name]
        except KeyError:
            pass

    def reset_status(self):
        self.status = {}

    def print_last_log(self, lines=0):
        """	Fetch the given amount of lines of history for
			the channel on the given server and print it to the
			channel's textview.
		"""
        lines = UInt64(lines or config.get("chatting", "last_log_lines", "0"))

        if type(self) == Server:
            server = self.name
            channel = ""
        else:
            server = self.parent.name
            channel = self.name

        for line in connection.sushi.log(server, channel, lines):
            self.output_walker.append(Text(unicode(line)))
示例#25
0
def parse_tag_from_node(node):
    from .tags import parse_tag_from_node
    body = [parse_tag_from_node(PyQuery(child)) for child in node.children()]
    walker = SimpleListWalker(body)
    return ListBox(walker)
示例#26
0
class CursesGUI(object):

    def __init__(self, choice_callback=None,
                       command_callback=None,
                       help_callback=None):

        self.palette = [
                ('brick', 'light red', 'black'),
                ('rubble', 'yellow', 'black'),
                ('wood', 'light green', 'black'),
                ('concrete', 'white', 'black'),
                ('stone', 'light cyan', 'black'),
                ('marble', 'light magenta', 'black'),
                ('jack', 'dark gray', 'white'),
                ('msg_info', 'white', 'black'),
                ('msg_err', 'light red', 'black'),
                ('msg_debug', 'light green', 'black'),
                ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
                LineBox(self.state),
                (13, LineBox(self.choices)),
                ])

        self.right_frame = Pile([
                LineBox(self.game_log),
                LineBox(self.roll)
                ])

        self.state.set_focus(len(self.state_text)-1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)
                                ])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None


    def register_loggers(self):
        """Gets the global loggers and sets up log handlers.
        """
        self.game_logger_handler = RollLogHandler(self._roll_write)
        self.logger_handler = RollLogHandler(self._roll_write)

        self.game_logger = logging.getLogger('gtr.game')
        self.logger = logging.getLogger('gtr')

        self.logger.addHandler(self.logger_handler)
        self.game_logger.addHandler(self.game_logger_handler)

        #self.set_log_level(logging.INFO)


    def unregister_loggers(self):
        self.game_logger.removeHandler(self.game_logger_handler)
        self.logger.removeHandler(self.logger_handler)


    def fail_safely(f):
        """Wraps functions in this class to catch arbitrary exceptions,
        shut down the event loop and reset the terminal to a normal state.

        It then re-raises the exception.
        """
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            retval = None
            try:
                retval = f(self, *args, **kwargs)
            except urwid.ExitMainLoop:
                from twisted.internet import reactor
                if not self.reactor_stop_fired and reactor.running:
                    # Make sure to call reactor.stop once
                    reactor.stop()
                    self.reactor_stop_fired = True

            except:
                #pdb.set_trace()
                from twisted.internet import reactor
                if not self.reactor_stop_fired and reactor.running:
                    # Make sure to call reactor.stop once
                    reactor.stop()
                    self.reactor_stop_fired = True

                if not self.called_loop_stop:
                    self.called_loop_stop = True
                    self.loop.stop()
                
                # Save exception info for printing later outside the GUI.
                self.exc_info = sys.exc_info()

                raise

            return retval

        return wrapper
                

    def set_log_level(self, level):
        """Set the log level as per the standard library logging module.

        Default is logging.INFO.
        """
        logging.getLogger('gtr.game').setLevel(level)
        logging.getLogger('gtr').setLevel(level)


    def run(self):
        loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input)
        loop.run()

    def run_twisted(self):
        from twisted.internet import reactor
        evloop = urwid.TwistedEventLoop(reactor, manage_reactor=False)
        self.screen = urwid.raw_display.Screen()
        self.screen.register_palette(self.palette)
        self.loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input,
                             screen = self.screen,
                             event_loop = evloop)
        self.loop.set_alarm_in(0.1, lambda loop, _: loop.draw_screen())

        self.loop.start()

        # The loggers get a Handler that writes to the screen. We want this to only
        # happen if the screen exists, so de-register them after the reactor stops.
        reactor.addSystemEventTrigger('after','startup', self.register_loggers)
        reactor.addSystemEventTrigger('before','shutdown', self.unregister_loggers)
        reactor.run()
        
        # We might have stopped the screen already, and the stop() method
        # doesn't check for stopping twice.
        if self.called_loop_stop:
            self.logger.warn('Internal error!')
        else:
            self.loop.stop()
            self.called_loop_stop = True

    @fail_safely
    def handle_input(self, key):
        if key == 'enter':
            text = self.edit_widget.edit_text
            if text in ['q', 'Q']:
                self.handle_quit_request()
            else:
                self.quit_flag = False

                try:
                    i = int(text)
                except ValueError:
                    i = None
                    self.handle_invalid_choice(text)

                if i is not None:
                    self.handle_choice(i)

            self.edit_widget.set_edit_text('')

    def _roll_write(self, line, attr=None):
        """Add a line to the roll with palette attributes 'attr'.

        If no attr is specified, None is used.

        Default attr is plain text
        """
        text = Text((attr, '* ' + line))
            
        self.roll_list.append(text)
        self.roll_list.set_focus(len(self.roll_list)-1)
        self._modified()

    @fail_safely
    def update_state(self, state):
        """Sets the game state window via one large string.
        """
        self.logger.debug('Drawing game state.')
        self.state_text[:] = [self.colorize(s) for s in state.split('\n')]
        self._modified()

    @fail_safely
    def update_game_log(self, log):
        """Sets the game log window via one large string.
        """
        self.logger.debug('Drawing game log.')
        self.game_log_list[:] = [self.colorize(s) for s in log.split('\n')]
        self.game_log_list.set_focus(len(self.game_log_list)-1)
        self._modified()

    @fail_safely
    def update_choices(self, choices):
        """Update choices list.
        """
        self.choices_list[:] = [self.colorize(str(c)) for c in choices]
        self._modified()

        length = len([c for c in choices if c[2] == '['])
        i = randint(1,length) if length else 0
        self.choices_list.append(self.colorize('\nPicking random choice: {0} in 1s'.format(i)))
        self._modified()
        #from twisted.internet import reactor
        #reactor.callLater(1, self.handle_choice, i)

    @fail_safely
    def update_prompt(self, prompt):
        """Set the prompt for the input field.
        """
        self.edit_widget.set_caption(prompt)
        self._modified()


    def _modified(self):
        if self.loop:
            self.loop.draw_screen()


    @fail_safely
    def quit(self):
        """Quit the program.
        """
        #import pdb; pdb.set_trace()
        #raise TypeError('Artificial TypeError')
        raise urwid.ExitMainLoop()

    def handle_invalid_choice(self, s):
        if len(s):
            text = 'Invalid choice: "' + s + '". Please enter an integer.'
            self.logger.warn(text)

    def handle_quit_request(self):
        if True or self.quit_flag:
            self.quit()
        else:
            self.quit_flag = True
            text = 'Are you sure you want to quit? Press Q again to confirm.'
            self.logger.warn(text)

    def handle_choice(self, i):
        if self.choice_callback:
            self.choice_callback(i)


    def colorize(self, s):
        """Applies color to roles found in a string.

        A string with attributes applied looks like

        Text([('attr1', 'some text'), 'some more text'])

        so we need to split into a list of tuples of text.
        """
        regex_color_dict = {
              r'\b([Ll]egionaries|[Ll]egionary|[Ll]eg|LEGIONARIES|LEGIONARY|LEG)\b' : 'brick',
              r'\b([Ll]aborers?|[Ll]ab|LABORERS?|LAB)\b' : 'rubble',
              r'\b([Cc]raftsmen|[Cc]raftsman|[Cc]ra|CRAFTSMEN|CRAFTSMAN|CRA)\b' : 'wood',
              r'\b([Aa]rchitects?|[Aa]rc|ARCHITECTS?|ARC)\b' : 'concrete',
              r'\b([Mm]erchants?|[Mm]er|MERCHANTS?|MER)\b' : 'stone',
              r'\b([Pp]atrons?|[Pp]at|PATRONS?|PAT)\b' : 'marble',
              r'\b([Jj]acks?|JACKS?)\b' : 'jack',

              r'\b([Bb]ricks?|[Bb]ri|BRICKS?|BRI)\b' : 'brick',
              r'\b([Rr]ubble|[Rr]ub|RUBBLE|RUB)\b' : 'rubble',
              r'\b([Ww]ood|[Ww]oo|WOOD|WOO)\b' : 'wood',
              r'\b([Cc]oncrete|[Cc]on|CONCRETE|CON)\b' : 'concrete',
              r'\b([Ss]tone|[Ss]to|STONE|STO)\b' : 'stone',
              r'\b([Mm]arble|[Mm]ar|MARBLE|MAR)\b' : 'marble',
        }

        def _colorize(s, regex, attr):
            """s is a tuple of ('attr', 'text'). This splits based on the regex
            and adds attr to any matches. Returns a list of tuples

            [('attr1', 'text1'), ('attr2', 'text2'), ('attr3','text3')]

            with some attributes being None if they aren't colored.
            """
            output = []
            a, t = s
            # Make a list of all tokens, split by matches
            tokens = re.split(regex, t)
            for tok in tokens:
                m = re.match(regex, tok)
                if m:
                    # matches get the new attributes
                    output.append( (attr,tok) )
                else:
                    # non-matches keep the old ones
                    output.append( (a, tok) )

            return output


        output = [ (None, s) ] 
        
        for k,v in regex_color_dict.items():
            new_output = []
            for token in output:
                new_output.extend(_colorize(token, k, v))

            output[:] = new_output

        return Text(output)
示例#27
0
文件: tabs.py 项目: sushi-irc/nigiri
class Tab(object):

	__metaclass__ = MetaSignals
	signals = ["child_added", "child_removed", "remove", "connected"]

	_valid_stati = [
		"informative",
		"actions", "actions_highlight","actions_own",
		"messages","messages_highlight","messages_own"]

	def __repr__(self):
		return "<tab: %s:%s:%s>" % (
			type(self).__name__, self._parent, self.name)

	def __str__(self):
		return self.name

	# Properties

	@types(switch = bool)
	def set_connected(self, switch):
		self._connected = switch

		for child in self.children:
			child.set_connected(switch)

		urwid.emit_signal(self, "connected", switch)

	connected = property(lambda x: x._connected, set_connected)

	def set_input_text(self, text):
		self._input_text = text

	input_text = property(lambda x: x._input_text, set_input_text)

	# Methods

	@types(name = (String, str, unicode))
	def __init__(self, name):
		self.name = name

		self._connected = False
		self._parent = None

		self.status = {}
		self.children = []
		self.input_history = None
		self.output_walker = SimpleListWalker([])
		self.input_text = ""
		self.auto_scroll = True

		self.read_line_index = -1

	def set_readline(self):
		if self.read_line_index != -1:
			try:
				del self.output_walker[self.read_line_index]
			except IndexError:
				pass

		line = Text("-"*30)
		line.set_align_mode ("center")
		self.output_walker.append(line)
		self.read_line_index = len(self.output_walker)-1

	def child_added(self, child):
		urwid.emit_signal(self, "child_added", self, child)
		child.set_connected(self.connected)
		self.children.append(child)

	def child_removed(self, child):
		urwid.emit_signal(self, "child_removed", self, child)
		try:
			i = self.children.index(child)
		except ValueError:
			pass
		else:
			del self.children[i]

	def set_parent(self, parent):
		if parent in self.children:
			print "Loop detected in '%s'.set_parent(%s)" % (
				self, parent)
			return

		try:
			self._parent.child_removed(self)
		except AttributeError:
			pass

		self._parent = parent

		try:
			self._parent.child_added(self)
		except AttributeError:
			pass

	parent = property(lambda x: x._parent, set_parent)

	def remove(self):
		""" emit remove signals """
		for child in self.children:
			child.remove()
			self.child_removed(child)
		urwid.emit_signal(self, "remove")
		self.set_parent(None)

	@types(name = str)
	def add_status(self, name):
		if name in self._valid_stati:
			self.status[name] = True

	@types(status = str)
	def has_status(self, status):
		return self.status.has_key(status)

	@types(name = str)
	def remove_status(self, name):
		try:
			del self.status[name]
		except KeyError:
			pass

	def reset_status(self):
		self.status = {}

	def print_last_log(self, lines=0):
		"""	Fetch the given amount of lines of history for
			the channel on the given server and print it to the
			channel's textview.
		"""
		lines = UInt64(lines or config.get(
			"chatting",
			"last_log_lines",
			"0"))

		if type(self) == Server:
			server = self.name
			channel = ""
		else:
			server = self.parent.name
			channel = self.name

		for line in connection.sushi.log(server, channel, lines):
			self.output_walker.append(Text(unicode(line)))