Esempio n. 1
0
    def __init__(self, scrollable_list=None, data_sources=tuple(), *a, **k):
        super(ListComponent, self).__init__(*a, **k)
        self._data_sources = data_sources
        self._activation_task = task.Task()
        self._action_on_scroll_task = task.Task()
        self._scrollable_list = None
        self._scroller = ScrollComponent(parent=self)
        self._pager = ScrollComponent(parent=self)
        self.last_action_item = lambda: self._last_action_item
        self.item_formatter = DefaultItemFormatter()
        for c in (self._scroller, self._pager):
            for button in (c.scroll_up_button, c.scroll_down_button):
                button.color = b'List.ScrollerOn'
                button.pressed_color = None
                button.disabled_color = b'List.ScrollerOff'

        if scrollable_list == None:
            self.scrollable_list = ActionList(
                num_visible_items=len(data_sources))
        else:
            self.scrollable_list = scrollable_list
        self._scrollable_list.num_visible_items = len(data_sources)
        self._delay_activation = BooleanContext()
        self._selected_index_float = 0.0
        self._in_encoder_selection = BooleanContext(False)
        self._execute_action_task = self._tasks.add(
            task.sequence(task.delay(1), task.run(self._execute_action)))
        self._execute_action_task.kill()
        return
Esempio n. 2
0
 def __init__(self, track_provider = None, *a, **k):
     self._track_provider = track_provider
     super(NotifyingViewControlComponent, self).__init__(*a, **k)
     self._page_tracks = ScrollComponent(self._create_track_pager(), parent=self)
     self.__on_tracks_changed.subject = self._track_provider
     self.__on_selected_track_changed.subject = self.song.view
     skin_scroll_buttons(self._page_tracks, u'TrackNavigation.On', u'TrackNavigation.Pressed')
     skin_scroll_buttons(self._scroll_tracks, u'TrackNavigation.On', u'TrackNavigation.Pressed')
     skin_scroll_buttons(self._scroll_scenes, u'SceneNavigation.On', u'SceneNavigation.Pressed')
Esempio n. 3
0
 def __init__(self, slideable=None, *a, **k):
     super(SlideComponent, self).__init__(*a, **k)
     slideable = slideable or self
     self._slideable = slideable
     self._position_scroll, self._page_scroll = self.register_components(
         ScrollComponent(), ScrollComponent())
     self._position_scroll.scrollable = self
     self._page_scroll.can_scroll_up = self.can_scroll_page_up
     self._page_scroll.can_scroll_down = self.can_scroll_page_down
     self._page_scroll.scroll_down = self.scroll_page_down
     self._page_scroll.scroll_up = self.scroll_page_up
     self._on_position_changed.subject = slideable
Esempio n. 4
0
 def __init__(self, track_provider=None, *a, **k):
     self._track_provider = track_provider
     super(NotifyingViewControlComponent, self).__init__(*a, **k)
     self._page_tracks = ScrollComponent(self._create_track_pager(),
                                         parent=self)
     self.__on_tracks_changed.subject = self._track_provider
     self.__on_selected_track_changed.subject = self.song.view
     self._page_tracks.scroll_up_button.color = 'TrackNavigation.On'
     self._page_tracks.scroll_down_button.color = 'TrackNavigation.On'
     self._scroll_tracks.scroll_up_button.color = 'TrackNavigation.On'
     self._scroll_tracks.scroll_down_button.color = 'TrackNavigation.On'
     self._scroll_scenes.scroll_up_button.color = 'SceneNavigation.On'
     self._scroll_scenes.scroll_down_button.color = 'SceneNavigation.On'
class ViewControlComponent(ViewControlComponentBase):
    scene_scroll_encoder = StepEncoderControl(num_steps=64)

    def __init__(self, *a, **k):
        (super(ViewControlComponent, self).__init__)(*a, **k)
        self._scroll_scenes = ScrollComponent((BasicSceneScroller()),
                                              parent=self)

    @scene_scroll_encoder.value
    def scene_scroll_encoder(self, value, _):
        if value > 0:
            self._scroll_scenes.scroll_down()
        elif value < 0:
            self._scroll_scenes.scroll_up()
class NotifyingViewControlComponent(ViewControlComponent):
    __events__ = (u'selection_scrolled', u'selection_paged')

    def __init__(self, track_provider=None, enable_skinning=True, *a, **k):
        self._track_provider = track_provider
        super(NotifyingViewControlComponent, self).__init__(*a, **k)
        self._page_tracks = ScrollComponent(self._create_track_pager(),
                                            parent=self)
        self.__on_tracks_changed.subject = self._track_provider
        self.__on_selected_track_changed.subject = self.song.view
        if enable_skinning:
            skin_scroll_buttons(self._page_tracks, u'TrackNavigation.On',
                                u'TrackNavigation.Pressed')
            skin_scroll_buttons(self._scroll_tracks, u'TrackNavigation.On',
                                u'TrackNavigation.Pressed')
            skin_scroll_buttons(self._scroll_scenes, u'SceneNavigation.On',
                                u'SceneNavigation.Pressed')

    def set_prev_track_page_button(self, button):
        self._page_tracks.set_scroll_up_button(button)

    def set_next_track_page_button(self, button):
        self._page_tracks.set_scroll_down_button(button)

    def _create_track_scroller(self):
        scroller = NotifyingTrackScroller()
        self.register_disconnectable(
            ObservablePropertyAlias(self,
                                    property_host=scroller,
                                    property_name=u'scrolled',
                                    alias_name=u'selection_scrolled'))
        return scroller

    def _create_scene_scroller(self):
        return BasicSceneScroller()

    def _create_track_pager(self):
        pager = NotifyingTrackPager(track_provider=self._track_provider)
        self.register_disconnectable(
            ObservablePropertyAlias(self,
                                    property_host=pager,
                                    property_name=u'scrolled',
                                    alias_name=u'selection_paged'))
        return pager

    @listens(u'tracks')
    def __on_tracks_changed(self):
        self._update_track_scrollers()

    @listens(u'selected_track')
    def __on_selected_track_changed(self):
        self._update_track_scrollers()

    def _update_track_scrollers(self):
        self._scroll_tracks.update()
        self._page_tracks.update()
Esempio n. 7
0
class ListComponent(Component):
    """
    Component that handles a ScrollableList.  If an action button is
    passed, it can handle an ActionList.
    """
    __events__ = ('item_action', 'selected_item')
    SELECTION_DELAY = 0.5
    ENCODER_FACTOR = 10.0
    empty_list_message = b''
    _current_action_item = None
    _last_action_item = None
    action_button = ButtonControl(color=b'Browser.Load')
    encoders = control_list(EncoderControl)

    def __init__(self, scrollable_list=None, data_sources=tuple(), *a, **k):
        super(ListComponent, self).__init__(*a, **k)
        self._data_sources = data_sources
        self._activation_task = task.Task()
        self._action_on_scroll_task = task.Task()
        self._scrollable_list = None
        self._scroller = ScrollComponent(parent=self)
        self._pager = ScrollComponent(parent=self)
        self.last_action_item = lambda: self._last_action_item
        self.item_formatter = DefaultItemFormatter()
        for c in (self._scroller, self._pager):
            for button in (c.scroll_up_button, c.scroll_down_button):
                button.color = b'List.ScrollerOn'
                button.pressed_color = None
                button.disabled_color = b'List.ScrollerOff'

        if scrollable_list == None:
            self.scrollable_list = ActionList(
                num_visible_items=len(data_sources))
        else:
            self.scrollable_list = scrollable_list
        self._scrollable_list.num_visible_items = len(data_sources)
        self._delay_activation = BooleanContext()
        self._selected_index_float = 0.0
        self._in_encoder_selection = BooleanContext(False)
        self._execute_action_task = self._tasks.add(
            task.sequence(task.delay(1), task.run(self._execute_action)))
        self._execute_action_task.kill()
        return

    @property
    def _trigger_action_on_scrolling(self):
        return self.action_button.is_pressed

    def _get_scrollable_list(self):
        return self._scrollable_list

    def _set_scrollable_list(self, new_list):
        if new_list != self._scrollable_list:
            self._scrollable_list = new_list
            if new_list != None:
                new_list.num_visible_items = len(self._data_sources)
                self._scroller.scrollable = new_list
                self._pager.scrollable = new_list.pager
                self._on_scroll.subject = new_list
                self._selected_index_float = new_list.selected_item_index
            else:
                self._scroller.scrollable = ScrollComponent.default_scrollable
                self._scroller.scrollable = ScrollComponent.default_pager
            self._on_selected_item_changed.subject = new_list
            self.update()
        return

    scrollable_list = property(_get_scrollable_list, _set_scrollable_list)

    def set_data_sources(self, sources):
        self._data_sources = sources
        if self._scrollable_list:
            self._scrollable_list.num_visible_items = len(sources)
        self._update_display()

    select_next_button = forward_property(b'_scroller')(b'scroll_down_button')
    select_prev_button = forward_property(b'_scroller')(b'scroll_up_button')
    next_page_button = forward_property(b'_pager')(b'scroll_down_button')
    prev_page_button = forward_property(b'_pager')(b'scroll_up_button')

    def on_enabled_changed(self):
        super(ListComponent, self).on_enabled_changed()
        if not self.is_enabled():
            self._execute_action_task.kill()

    @listens(b'scroll')
    def _on_scroll(self):
        if self._trigger_action_on_scrolling:
            trigger_selected = partial(self._trigger_action,
                                       self.selected_item)
            self._action_on_scroll_task.kill()
            self._action_on_scroll_task = self._tasks.add(
                task.sequence(task.wait(defaults.MOMENTARY_DELAY),
                              task.delay(1), task.run(trigger_selected)))

    @listens(b'selected_item')
    def _on_selected_item_changed(self):
        self._scroller.update()
        self._pager.update()
        self._update_display()
        self._update_action_feedback()
        self._activation_task.kill()
        self._action_on_scroll_task.kill()
        if self.SELECTION_DELAY and self._delay_activation:
            self._activation_task = self._tasks.add(
                task.sequence(
                    task.wait(self.SELECTION_DELAY),
                    task.run(
                        self._scrollable_list.request_notify_item_activated)))
        else:
            self._scrollable_list.request_notify_item_activated()
        if not self._in_encoder_selection:
            self._selected_index_float = float(
                self._scrollable_list.selected_item_index)
        self.notify_selected_item(self._scrollable_list.selected_item)

    @encoders.value
    def encoders(self, value, encoder):
        self._add_offset_to_selected_index(value)

    def _add_offset_to_selected_index(self, offset):
        if self.is_enabled() and self._scrollable_list:
            with self._delay_activation():
                with self._in_encoder_selection():
                    self._selected_index_float = clamp(
                        self._selected_index_float +
                        offset * self.ENCODER_FACTOR, 0,
                        len(self._scrollable_list.items))
                    self._scrollable_list.select_item_index_with_border(
                        int(self._selected_index_float), 1)

    @action_button.pressed
    def action_button(self, button):
        if self._current_action_item == None:
            self._trigger_action(
                self.next_item if self._action_target_is_next_item(
                ) else self.selected_item)
        return

    def do_trigger_action(self, item):
        item.action()
        self.notify_item_action(item)

    def _trigger_action(self, item):
        if self.is_enabled() and self._can_be_used_for_action(item):
            if self._scrollable_list != None:
                self._scrollable_list.select_item(item)
            self._current_action_item = item
            self.update()
            self._execute_action_task.restart()
        return

    def _execute_action(self):
        """ Is called by the execute action task and should not be called directly
            use _trigger_action instead """
        if self._current_action_item != None:
            self.do_trigger_action(self._current_action_item)
            self._last_action_item = self._current_action_item
            self._current_action_item = None
            self.update()
        return

    @property
    def selected_item(self):
        if self._scrollable_list != None:
            return self._scrollable_list.selected_item
        else:
            return

    @property
    def next_item(self):
        item = None
        if self._scrollable_list != None:
            all_items = self._scrollable_list.items
            next_index = self._scrollable_list.selected_item_index + 1
            item = all_items[next_index] if in_range(next_index, 0,
                                                     len(all_items)) else None
        return item

    def _can_be_used_for_action(self, item):
        return item != None and item.supports_action and item != self.last_action_item(
        )

    def _action_target_is_next_item(self):
        return self.selected_item == self.last_action_item(
        ) and self._can_be_used_for_action(self.next_item)

    def _update_action_feedback(self):
        color = b'Browser.Loading'
        if self._current_action_item == None:
            if self._action_target_is_next_item():
                color = b'Browser.LoadNext'
            elif self._can_be_used_for_action(self.selected_item):
                color = b'Browser.Load'
            else:
                color = b'Browser.LoadNotPossible'
        self.action_button.color = color
        return

    def _update_display(self):
        visible_items = self._scrollable_list.visible_items if self._scrollable_list else []
        for index, data_source in enumerate(self._data_sources):
            item = visible_items[index] if index < len(visible_items) else None
            action_in_progress = item and item == self._current_action_item
            display_string = self.item_formatter(index, item,
                                                 action_in_progress)
            data_source.set_display_string(display_string)

        if not visible_items and self._data_sources and self.empty_list_message:
            self._data_sources[0].set_display_string(self.empty_list_message)
        return

    def update(self):
        super(ListComponent, self).update()
        if self.is_enabled():
            self._update_action_feedback()
            self._update_display()
 def __init__(self, *a, **k):
     (super(ViewControlComponent, self).__init__)(*a, **k)
     self._scroll_scenes = ScrollComponent((BasicSceneScroller()),
                                           parent=self)