Пример #1
0
def test_change(shortcut_engine, mocker):
    callback = mocker.Mock(return_value=True)
    old_shortcut = Shortcut("start", "<control>a")
    new_shortcut = Shortcut("start", "<control>b")

    shortcut_engine.connect(old_shortcut, callback)
    shortcut_engine.change(new_shortcut)

    assert active_shortcut(shortcut_engine, old_shortcut) is False
    assert active_shortcut(shortcut_engine, new_shortcut) is True

    key, mod = Gtk.accelerator_parse(new_shortcut.value)
    callback.assert_called_once_with(shortcut_engine.accel_group, mocker.ANY,
                                     key, mod)
Пример #2
0
def test_disconnect(shortcut_engine, mocker):
    shortcut = Shortcut("start", "<control>s")
    shortcut_engine.connect(shortcut, mocker.Mock())

    shortcut_engine.disconnect(shortcut)

    assert active_shortcut(shortcut_engine, shortcut) is False
Пример #3
0
def test_connect(shortcut_engine, mocker):
    callback = mocker.Mock(return_value=True)
    shortcut = Shortcut("start", "<control>s")

    shortcut_engine.connect(shortcut, callback)
    assert active_shortcut(shortcut_engine, shortcut) is True

    key, mod = Gtk.accelerator_parse(shortcut.value)
    callback.assert_called_once_with(shortcut_engine.accel_group, mocker.ANY,
                                     key, mod)
Пример #4
0
class Menu(Subscriber):
    PREFERENCE_SHORTCUT = Shortcut("session.settings", "<control>comma")

    @inject(
        bus="tomate.bus",
        about="tomate.ui.about",
        preference="tomate.ui.preference",
        shortcuts="tomate.ui.shortcut",
    )
    def __init__(self, bus: Bus, about, preference, shortcuts: ShortcutEngine):
        self.connect(bus)

        self.widget = Gtk.Menu(halign=Gtk.Align.CENTER)
        self.widget.add(self._create_menu_item("header.menu.preference", _("Preferences"), preference.widget))
        self.widget.add(self._create_menu_item("header.menu.about", _("About"), about.widget))
        self.widget.show_all()

        shortcuts.connect(Menu.PREFERENCE_SHORTCUT, lambda *_: preference.widget.run())

    def _create_menu_item(self, name: str, label: str, dialog: Gtk.Dialog) -> Gtk.MenuItem:
        menu_item = Gtk.MenuItem.new_with_label(label)
        menu_item.props.name = name
        menu_item.connect("activate", lambda *_: dialog.run())
        return menu_item
Пример #5
0
class SessionButton(Subscriber):
    POMODORO_SHORTCUT = Shortcut("session.pomodoro", "<control>1")
    SHORT_BREAK_SHORTCUT = Shortcut("session.short_break", "<control>2")
    LONG_BREAK_SHORTCUT = Shortcut("session.long_break", "<control>3")

    @inject(
        bus="tomate.bus",
        session="tomate.session",
        shortcuts="tomate.ui.shortcut",
    )
    def __init__(self, bus: Bus, session: Session, shortcuts: ShortcutEngine):
        self.connect(bus)
        self._session = session
        self._shortcuts = shortcuts

        self.widget = self._create_mode_button()
        self._add_button(SessionButton.POMODORO_SHORTCUT, "Pomodoro", SessionType.POMODORO)
        self._add_button(SessionButton.SHORT_BREAK_SHORTCUT, "Short Break", SessionType.SHORT_BREAK)
        self._add_button(SessionButton.LONG_BREAK_SHORTCUT, "Long Break", SessionType.LONG_BREAK)
        self.widget.connect("mode_changed", self._on_button_clicked)

    def _create_mode_button(self) -> ModeButton:
        return ModeButton(
            can_focus=False,
            homogeneous=True,
            margin_bottom=12,
            margin_left=12,
            margin_right=12,
            sensitive=True,
        )

    def _add_button(self, shortcut: Shortcut, label: str, session_type: SessionType) -> None:
        self.widget.append_text(
            _(label),
            tooltip_text=_("{} ({})".format(label, self._shortcuts.label(shortcut))),
            name=shortcut.name,
        )
        self._shortcuts.connect(shortcut, self._change_session(session_type))

    def _change_session(self, session_type: SessionType) -> Callable[[], bool]:
        def callback(*_) -> bool:
            logger.debug("action=change session=%s", session_type)
            self.widget.set_selected(session_type.value)
            return True

        return callback

    def _on_button_clicked(self, _, number):
        session_type = SessionType.of(number)
        logger.debug("action=mode_changed session=%s", session_type)
        self._session.change(session_type)

    @on(Events.SESSION_CHANGE)
    def _on_session_change(self, payload=SessionPayload) -> None:
        logger.debug("action=change current=%d next=%d", self.widget.get_selected(), payload.type.value)
        if self.widget.get_selected() != payload.type.value:
            self.widget.set_selected(payload.type.value)

    @on(Events.SESSION_START)
    def _on_session_start(self, **__):
        logger.debug("action=disable")
        self.widget.props.sensitive = False

    @on(Events.SESSION_READY, Events.SESSION_INTERRUPT, Events.SESSION_END)
    def _on_session_stop(self, payload: Union[SessionPayload, SessionEndPayload]):
        logger.debug("action=enable session=%s", payload.type)
        self.widget.props.sensitive = True
        self.widget.set_selected(payload.type.value)
Пример #6
0
class HeaderBar(Subscriber):
    START_SHORTCUT = Shortcut("session.start", "<control>s")
    STOP_SHORTCUT = Shortcut("session.stop", "<control>p")
    RESET_SHORTCUT = Shortcut("session.reset", "<control>r")

    @inject(
        bus="tomate.bus",
        menu="tomate.ui.headerbar.menu",
        session="tomate.session",
        shortcuts="tomate.ui.shortcut",
    )
    def __init__(self, bus: Bus, menu: Menu, session: Session, shortcuts: ShortcutEngine):
        self.connect(bus)
        self._shortcuts = shortcuts
        self.widget = self._create_headerbar()

        self._start_button = self._add_button(
            Gtk.STOCK_MEDIA_PLAY,
            "Starts the session",
            HeaderBar.START_SHORTCUT,
            lambda *_: session.start(),
        )

        self._stop_button = self._add_button(
            Gtk.STOCK_MEDIA_STOP,
            "Stops the session",
            HeaderBar.STOP_SHORTCUT,
            lambda *_: session.stop(),
            no_show_all=True,
            visible=False,
        )

        self._reset_button = self._add_button(
            Gtk.STOCK_CLEAR,
            "Clear session count",
            HeaderBar.RESET_SHORTCUT,
            lambda *_: session.reset(),
            sensitive=False,
        )

        self._add_preference_button(menu, shortcuts)

    def _create_headerbar(self):
        return Gtk.HeaderBar(
            show_close_button=True,
            title=_("No session yet"),
            decoration_layout=":close",
        )

    def _add_button(self, icon: str, tooltip_text: str, shortcut: Shortcut, on_clicked, **props) -> Gtk.Button:
        image = Gtk.Image.new_from_icon_name(icon, Gtk.IconSize.BUTTON)
        image.show()

        button = Gtk.Button(
            tooltip_text=_("{} ({})".format(tooltip_text, self._shortcuts.label(shortcut))), name=shortcut.name, **props
        )
        button.add(image)
        button.connect("clicked", on_clicked)

        self.widget.pack_start(button)
        self._shortcuts.connect(shortcut, on_clicked)

        return button

    def _add_preference_button(self, menu, shortcuts) -> None:
        icon = Gtk.Image.new_from_icon_name(Gtk.STOCK_PREFERENCES, Gtk.IconSize.BUTTON)
        button = Gtk.MenuButton(
            name=Menu.PREFERENCE_SHORTCUT.name,
            popup=menu.widget,
            tooltip_text=_("Open preferences ({})".format(shortcuts.label(Menu.PREFERENCE_SHORTCUT))),
        )
        button.add(icon)
        self.widget.pack_end(button)

    @on(Events.SESSION_START)
    def _on_session_start(self, **__):
        logger.debug("action=enable_stop")
        self._start_button.props.visible = False
        self._stop_button.props.visible = True
        self._reset_button.props.sensitive = False

    @on(Events.SESSION_INTERRUPT, Events.SESSION_END)
    def _on_session_stop(self, payload: Union[SessionEndPayload, SessionPayload]) -> None:
        logger.debug("action=enable_start pomodoros=%d", payload.pomodoros)
        self._start_button.props.visible = True
        self._stop_button.props.visible = False
        self._reset_button.props.sensitive = bool(payload.pomodoros)
        self._update_title(payload.pomodoros)

    @on(Events.SESSION_RESET)
    def _on_session_reset(self, **__):
        logger.debug("action=disable_reset")
        self._reset_button.props.sensitive = False
        self._update_title(0)

    def _update_title(self, pomodoros: int) -> None:
        self.widget.props.title = _("Session {}".format(pomodoros)) if pomodoros else _("No session yet")
Пример #7
0
def test_label_with_fallback(shortcut_engine):
    label = shortcut_engine.label(Shortcut("", "<control>p"))

    assert label == "Ctrl+P"
Пример #8
0
def test_label(shortcut_engine):
    label = shortcut_engine.label(Shortcut("test", ""))

    assert label == "Ctrl+S"