コード例 #1
0
class GUI(object):
    def __init__(self):
        self.screen = Screen()
        self.screen.set_input_timeouts(max_wait=0)
        self.steps = GridFlow([], 20, 2, 1, 'left')
        self.progress = SimpleFocusListWalker([])
        self.log = SimpleFocusListWalker([])

        self.widget = AttrMap(
            LineBox(Pile([
                ('fixed', 6, AttrMap(Filler(self.steps), 'default')),
                ('fixed', 1, Filler(Divider('\u2500'))),
                ('fixed', 3, ListBox(self.progress)),
                AttrMap(LineBox(ListBox(self.log), title='Message log'),
                        'default')
            ]),
                    title='Indico 1.2 -> 2.0 migration'), 'global_frame')

        self.screen.register_palette(
            [('green', 'light green', ''), ('white', 'white', ''),
             ('red', 'dark red', ''), ('yellow', 'yellow', ''),
             ('progress_empty', 'black',
              'light gray'), ('progress_progress', 'light cyan', 'light gray'),
             ('progress_done', 'black', 'light cyan'),
             ('box', 'white', 'dark gray'), ('step_done', 'light green', ''),
             ('step_working', 'dark gray',
              ''), ('global_frame', 'light cyan',
                    ''), ('fill', 'light cyan', 'dark cyan'),
             ('done', 'white', 'dark green'), ('eta', 'yellow', 'dark gray')] +
            generate_urwid_palette(PALETTE))

    def print_log(self, icon, message, prefix='', event_id=''):
        self.log.append(
            Text([
                color_segments(icon), ' ',
                color_segments(prefix), ' ' if prefix else '',
                color_segments(
                    '%[cyan][%[cyan!]{}%[cyan]]%[reset]'.format(event_id))
                if event_id else '', ' ' if event_id else '',
                color_segments(message)
            ]))
        self.log.set_focus(len(self.log) - 1)
        self.redraw()

    def start(self):
        # don't let Python warnings ruin the GUI
        warnings.filterwarnings('ignore')
        self.screen.start()
        self.redraw()

    def stop(self):
        self.screen.stop()
        warnings.filterwarnings('default')

    def create_progress_bar(self, description):
        if self.progress:
            del self.progress[:]
        return StepProgressBar(self, description)

    def set_success(self):
        if self.progress:
            del self.progress[:]
        self.progress.append(
            AttrMap(Text('Migration finished!', align='center'), 'done'))
        self.progress.append(
            AttrMap(Text('Please press any key...', align='center'), 'done'))
        self.redraw()
        self.wait_for_input()

    def wait_for_input(self):
        self.screen._getch(None)

    def set_step_banner(self, msg):
        if self.progress:
            del self.progress[:]
        self.progress.append(BoxAdapter(AttrMap(SolidFill('#'), 'fill'), 3))

    def redraw(self):
        screen_size = self.screen.get_cols_rows()
        canvas = self.widget.render(screen_size, focus=True)
        self.screen.get_input()
        self.screen.draw_screen(screen_size, canvas)
コード例 #2
0
class ScreenWidget(WidgetWrap):

    _info_template = ("{collection_size:>2g}"
                      " [ {rating} | {purity} ]"
                      " {format} {width:d}×{height:d}")

    def __init__(self, screen, screen_controller):
        self._screen = screen
        self._scrctrl = screen_controller
        self._left_border = Text(" ")
        # self._playpause = Text("⏸")
        self._info = Text(self._info_template)
        self._scale = Text("")
        self._transformations = Parenthesis("")
        self._tags = Parenthesis("")
        self._top = Columns([
            (1, self._left_border),
            # (2, self._playpause),
            ('pack', self._info),
            ('pack', self._scale),
            ('pack', self._transformations),
            ('pack', self._tags),
        ], dividechars=1)
        self._path = PathWidget()
        self._root = AttrMap(Pile([
            self._top,
            Columns([(1, self._left_border), self._path]),
        ]), None, 'focused screen')
        super().__init__(self._root)
        self.update()

    def selectable(self):
        return True

    def render(self, size, focus=False):
        # maybe this is better:
        # https://groups.google.com/a/excess.org/forum/#!topic/urwid/3Si0ZRKkFaw
        self._left_border.set_text("│" if focus else " ")
        return self._root.render(size, focus)

    def update(self, *_):
        wp = self._screen.wallpaper
        self._info.set_text(self._info_template.format(
            collection_size=len(self._screen.wallpapers),
            rating=("☆" if wp.rating == 0 else "★·" + str(wp.rating)),
            purity=("♡" if wp.purity == 0 else "♥·" + str(wp.purity)),
            format=wp.format,
            width=wp.width,
            height=wp.height,
        ))
        self._scale.set_text((
            'warning' if self._screen.wallpaper_scale > 1 else None,
            f"{self._screen.wallpaper_scale:.0%}",
        ))
        trafos = []
        if wp.x_offset or wp.y_offset:
            trafos.append("{:+},{:+}".format(wp.x_offset, wp.y_offset))
        if wp.zoom != 1:
            trafos.append("{:.0%}".format(wp.zoom))
        if wp.transformations[2]:
            trafos.append(str(wp.transformations[2]) + "°")
        if wp.transformations[0]:
            trafos.append("↔")
        if wp.transformations[1]:
            trafos.append("↕")
        self._transformations.set_text(",".join(trafos))
        self._tags.set_text(",".join(wp.tags))
        self._path.set_text(wp.path)

    def keypress(self, size, key):
        log.debug("processing keypress '%s'", key)
        if self._top.focus.selectable():
            child_result = self._top.keypress(size, key)
            if child_result is None:
                return

        wp = self._screen.wallpaper
        if key == 'delete': self._screen.wallpapers.remove_current()
        elif key == 'o': wp.open()
        elif key == 'a': self._screen.wallpapers.next()
        elif key == 'q': self._screen.wallpapers.prev()
        elif key == 's': wp.rating -= 1
        elif key == 'w': wp.rating += 1
        elif key == 'd': wp.purity += 1
        elif key == 'e': wp.purity -= 1
        elif key == 'z': wp.zoom += .05
        elif key == 'Z': wp.zoom += .2
        elif key == 'u': wp.zoom -= .05
        elif key == 'U': wp.zoom -= .2
        elif key == 'r': wp.rotate(+90)
        elif key == 'R': wp.rotate(-90)
        elif key == 'f': wp.flip_horizontal()
        elif key == 'F': wp.flip_vertical()
        elif key == 'h' or key == 'left':
            wp.x_offset += 10
        elif key == 'H' or key == 'shift left':
            wp.x_offset += 100
        elif key == 'l' or key == 'right':
            wp.x_offset -= 10
        elif key == 'L' or key == 'shift right':
            wp.x_offset -= 100
        elif key == 'k' or key == 'up':
            wp.y_offset += 10
        elif key == 'K' or key == 'shift up':
            wp.y_offset += 100
        elif key == 'j' or key == 'down':
            wp.y_offset -= 10
        elif key == 'J' or key == 'shift down':
            wp.y_offset -= 100
        elif key == '1':
            # 100% zoom
            wp.zoom = min(wp.width / self._screen.width,
                          wp.height / self._screen.height)
        elif key == '!':
            # zoom to fit
            w_rel = self._screen.width / wp.width
            h_rel = self._screen.height / wp.height
            wp.zoom = min(w_rel, h_rel) / max(w_rel, h_rel)
        elif key == '0':
            # zoom to fill (default)
            del wp.zoom
            del wp.x_offset
            del wp.y_offset
            del wp.transformations
        elif key == 't':
            if wp.tags:
                self._tags.text += ","
            self._tags.editable = True
            # make sure to adjust when changing the layout:
            self._top.focus_position = 4
            return
        elif key == 'enter' and self._tags.editable:
            self._tags.editable = False
            wp.tags = self._tags.text
        elif key == 'esc' and self._tags.editable:
            self._tags.editable = False
            self._tags.text = ",".join(wp.tags)
        else:
            return key
        self.update()
        self._scrctrl.display_wallpapers()

    def mouse_event(self, size, event, button, *_):
        if event == 'mouse release':
            self._screen.wallpaper.open()
        elif event == 'mouse press' and button == 4:
            self._screen.wallpapers.prev()
            self.update()
            self._scrctrl.display_wallpapers()
        elif event == 'mouse press' and button == 5:
            self._screen.wallpapers.next()
            self.update()
            self._scrctrl.display_wallpapers()