def use_single_line(self, line_index, line_slice=None, align=align_none):
     display = self._display_lines[line_index]
     if line_slice is not None:
         display = display.subdisplay[line_slice]
     layer = Layer(priority=MESSAGE_BOX_PRIORITY, display_line1=display)
     return _CallbackControl(
         self._token_control,
         partial(self._set_message_box_layout, layer,
                 maybe(partial(align, display.width))))
예제 #2
0
 def use_single_line(self, line_index, line_slice=None, align=align_none):
     u"""
     Returns a control, that will change the notification to a single line view,
     if it is grabbed.
     """
     assert line_index >= 0 and line_index < len(self._display_lines)
     display = self._display_lines[line_index]
     if line_slice is not None:
         display = display.subdisplay[line_slice]
     layer = Layer(priority=MESSAGE_BOX_PRIORITY, display_line1=display)
     return _CallbackControl(
         self._token_control,
         partial(self._set_message_box_layout, layer,
                 maybe(partial(align, display.width))))
예제 #3
0
class NotificationComponent(Component):
    """'
    Displays notifications to the user for a given amount of time. A notification time
    of -1 creates an infinite duration notification.

    To adjust the way notifications are shown in special cases, assign a generated
    control using use_single_line or use_full_display to a layer. If the layer is on
    top, it will set the preferred view.
    This will show the notification on line 1 if my_component is enabled and
    the priority premise of the layer is met:

        my_component.layer = Layer(
            _notification = notification_component.use_single_line(1))
    """
    __module__ = __name__
    _default_align_text_fn = partial(maybe(partial(align_none,
                                                   DISPLAY_LENGTH)))

    def __init__(self,
                 default_notification_time=2.5,
                 blinking_time=0.3,
                 display_lines=[],
                 *a,
                 **k):
        super(NotificationComponent, self).__init__(*a, **k)
        self._display_lines = get_element(display_lines)
        self._token_control = _TokenControlElement()
        self._align_text_fn = self._default_align_text_fn
        self._message_box = MessageBoxComponent(parent=self)
        self._message_box.set_enabled(False)
        self._default_notification_time = default_notification_time
        self._blinking_time = blinking_time
        self._original_text = None
        self._blink_text = None
        self._blink_text_task = self._tasks.add(
            task.loop(
                task.sequence(
                    task.run(lambda: self._message_box.__setattr__(
                        'text', self._original_text)),
                    task.wait(self._blinking_time),
                    task.run(lambda: self._message_box.__setattr__(
                        'text', self._blink_text)),
                    task.wait(self._blinking_time)))).kill()
        return

    message_box_layer = forward_property('_message_box')('layer')

    def show_notification(self, text, blink_text=None, notification_time=None):
        u"""
        Triggers a notification with the given text.
        If text is a tuple, it will treat it as a format string + arguments.
        """
        self._create_tasks(notification_time)
        text = apply_formatting(text)
        text = self._align_text_fn(text)
        blink_text = self._align_text_fn(blink_text)
        if blink_text is not None:
            self._original_text = text
            self._blink_text = blink_text
            self._blink_text_task.restart()
        self._message_box.text = text
        self._message_box.set_enabled(True)
        self._notification_timeout_task.restart()
        self._current_notification = Notification(self)
        return ref(self._current_notification)

    def hide_notification(self):
        u"""
        Hides the current notification, if any existing.
        """
        self._blink_text_task.kill()
        self._message_box.set_enabled(False)

    def use_single_line(self, line_index, line_slice=None, align=align_none):
        u"""
        Returns a control, that will change the notification to a single line view,
        if it is grabbed.
        """
        assert line_index >= 0 and line_index < len(self._display_lines)
        display = self._display_lines[line_index]
        if line_slice is not None:
            display = display.subdisplay[line_slice]
        layer = Layer(priority=MESSAGE_BOX_PRIORITY, display_line1=display)
        return _CallbackControl(
            self._token_control,
            partial(self._set_message_box_layout, layer,
                    maybe(partial(align, display.width))))

    def use_full_display(self, message_line_index=2):
        u"""
        Returns a control, that will change the notification to use the whole display,
        if it is grabbed.
        """
        layer = Layer(
            priority=MESSAGE_BOX_PRIORITY,
            **dict([
                ('display_line1' if i == message_line_index else 'bg%d' % i,
                 line) for i, line in enumerate(self._display_lines)
            ]))
        return _CallbackControl(self._token_control,
                                partial(self._set_message_box_layout, layer))

    def _set_message_box_layout(self, layer, align_text_fn=None):
        self._message_box.layer = layer
        self._align_text_fn = partial(align_text_fn
                                      or self._default_align_text_fn)

    def _create_tasks(self, notification_time):
        duration = notification_time if notification_time is not None else self._default_notification_time
        self._notification_timeout_task = self._tasks.add(
            task.sequence(task.wait(duration), task.run(self.hide_notification)
                          )).kill() if duration != -1 else self._tasks.add(
                              task.Task())
        return
예제 #4
0
 def use_single_line(self, line_index, line_slice = None, align = align_none):
     """
     Returns a control, that will change the notification to a single line view,
     if it is grabbed.
     """
     if not (line_index >= 0 and line_index < len(self._display_lines)):
         raise AssertionError
         display = self._display_lines[line_index]
         display = line_slice is not None and display.subdisplay[line_slice]
     layer = Layer(priority=MESSAGE_BOX_PRIORITY, display_line1=display)
     return _CallbackControl(self._token_control, partial(self._set_message_box_layout, layer, maybe(partial(align, display.width))))
class NotificationComponent(Component):
    _default_align_text_fn = partial(maybe(partial(align_none,
                                                   DISPLAY_LENGTH)))

    def __init__(self,
                 default_notification_time=2.5,
                 blinking_time=0.3,
                 display_lines=[],
                 *a,
                 **k):
        (super(NotificationComponent, self).__init__)(*a, **k)
        self._display_lines = get_element(display_lines)
        self._token_control = _TokenControlElement()
        self._align_text_fn = self._default_align_text_fn
        self._message_box = MessageBoxComponent(parent=self)
        self._message_box.set_enabled(False)
        self._default_notification_time = default_notification_time
        self._blinking_time = blinking_time
        self._original_text = None
        self._blink_text = None
        self._blink_text_task = self._tasks.add(
            task.loop(
                task.sequence(
                    task.run(lambda: self._message_box.__setattr__(
                        'text', self._original_text)),
                    task.wait(self._blinking_time),
                    task.run(lambda: self._message_box.__setattr__(
                        'text', self._blink_text)),
                    task.wait(self._blinking_time)))).kill()

    message_box_layer = forward_property('_message_box')('layer')

    def show_notification(self, text, blink_text=None, notification_time=None):
        self._create_tasks(notification_time)
        text = apply_formatting(text)
        text = self._align_text_fn(text)
        blink_text = self._align_text_fn(blink_text)
        if blink_text is not None:
            self._original_text = text
            self._blink_text = blink_text
            self._blink_text_task.restart()
        self._message_box.text = text
        self._message_box.set_enabled(True)
        self._notification_timeout_task.restart()
        self._current_notification = Notification(self)
        return ref(self._current_notification)

    def hide_notification(self):
        self._blink_text_task.kill()
        self._message_box.set_enabled(False)

    def use_single_line(self, line_index, line_slice=None, align=align_none):
        display = self._display_lines[line_index]
        if line_slice is not None:
            display = display.subdisplay[line_slice]
        layer = Layer(priority=MESSAGE_BOX_PRIORITY, display_line1=display)
        return _CallbackControl(
            self._token_control,
            partial(self._set_message_box_layout, layer,
                    maybe(partial(align, display.width))))

    def use_full_display(self, message_line_index=2):
        layer = Layer(
            priority=MESSAGE_BOX_PRIORITY,
            **dict([
                ('display_line1' if i == message_line_index else 'bg%d' % i,
                 line) for i, line in enumerate(self._display_lines)
            ]))
        return _CallbackControl(self._token_control,
                                partial(self._set_message_box_layout, layer))

    def _set_message_box_layout(self, layer, align_text_fn=None):
        self._message_box.layer = layer
        self._align_text_fn = partial(align_text_fn
                                      or self._default_align_text_fn)

    def _create_tasks(self, notification_time):
        duration = notification_time if notification_time is not None else self._default_notification_time
        self._notification_timeout_task = self._tasks.add(
            task.sequence(task.wait(duration), task.run(self.hide_notification)
                          )).kill() if duration != -1 else self._tasks.add(
                              task.Task())