Exemple #1
0
 def set_row(self, row, track_id, pos, show_cover=False):
     """
         Set row content
         @param row as Row
         @param track id as int
         @param pos as position
         @param show cover as bool
     """
     track = Track(track_id)
     row.show_indicator(Lp().player.current_track.id == track_id,
                        utils.is_loved(track_id))
     row.set_number(pos)
     self._update_pos_label(row, track_id)
     row.set_title_label(track.formated_name())
     row.set_duration_label(seconds_to_string(track.duration))
     row.set_id(track_id)
     if show_cover:
         surface = Lp().art.get_album_artwork(
                     track.album,
                     ArtSize.MEDIUM*row.get_scale_factor())
         row.set_cover(surface, track.album.name)
         del surface
         row.show_header(True)
Exemple #2
0
class Row(Gtk.ListBoxRow):
    """
        A row
    """

    def __init__(self, rowid, num):
        """
            Init row widgets
            @param rowid as int
            @param num as int
            @param show loved as bool
        """
        # We do not use Gtk.Builder for speed reasons
        Gtk.ListBoxRow.__init__(self)
        self._track = Track(rowid)
        self._number = num
        self._indicator = IndicatorWidget(self._track.id)
        self.set_indicator(Lp().player.current_track.id == self._track.id,
                           utils.is_loved(self._track.id))
        self._row_widget = Gtk.EventBox()
        self._row_widget.connect('button-press-event', self._on_button_press)
        self._row_widget.connect('enter-notify-event', self._on_enter_notify)
        self._grid = Gtk.Grid()
        self._grid.set_column_spacing(5)
        self._row_widget.add(self._grid)
        self._title_label = Gtk.Label.new(self._track.formated_name())
        self._title_label.set_use_markup(True)
        self._title_label.set_property('has-tooltip', True)
        self._title_label.connect('query-tooltip',
                                  self._on_title_query_tooltip)
        self._title_label.set_property('hexpand', True)
        self._title_label.set_property('halign', Gtk.Align.START)
        self._title_label.set_ellipsize(Pango.EllipsizeMode.END)
        self._duration_label = Gtk.Label.new(
                                       seconds_to_string(self._track.duration))
        self._duration_label.get_style_context().add_class('dim-label')
        self._num_label = Gtk.Label()
        self._num_label.set_ellipsize(Pango.EllipsizeMode.END)
        self._num_label.set_property('valign', Gtk.Align.CENTER)
        self._num_label.set_width_chars(4)
        self._num_label.get_style_context().add_class('dim-label')
        self.update_num_label()
        self._menu_button = Gtk.Button.new()
        # Here a hack to make old Gtk version support min-height css attribute
        # min-height = 24px, borders = 2px, we set directly on stack
        # min-width = 24px, borders = 2px, padding = 8px
        self._menu_button.set_size_request(34, 26)
        self._menu_button.set_relief(Gtk.ReliefStyle.NONE)
        self._menu_button.get_style_context().add_class('menu-button')
        self._menu_button.get_style_context().add_class('track-menu-button')
        self._grid.add(self._num_label)
        self._grid.add(self._title_label)
        self._grid.add(self._duration_label)
        # TODO Remove this later
        if Gtk.get_minor_version() > 16:
            self._grid.add(self._menu_button)
        else:
            self.connect('map', self._on_map)
        self.add(self._row_widget)
        self.get_style_context().add_class('trackrow')

    def set_indicator(self, playing, loved):
        """
            Show indicator
            @param widget name as str
            @param playing as bool
            @param loved as bool
        """
        self._indicator.clear()
        if playing:
            self.get_style_context().remove_class('trackrow')
            self.get_style_context().add_class('trackrowplaying')
            if loved:
                self._indicator.play_loved()
            else:
                self._indicator.play()
        else:
            self.get_style_context().remove_class('trackrowplaying')
            self.get_style_context().add_class('trackrow')
            if loved:
                self._indicator.loved()
            else:
                self._indicator.empty()

    def set_number(self, num):
        """
            Set number
            @param number as int
        """
        self._number = num

    def update_num_label(self):
        """
            Update position label for row
        """
        if Lp().player.is_in_queue(self._track.id):
            self._num_label.get_style_context().add_class('queued')
            pos = Lp().player.get_track_position(self._track.id)
            self._num_label.set_text(str(pos))
        elif self._number > 0:
            self._num_label.get_style_context().remove_class('queued')
            self._num_label.set_text(str(self._number))
        else:
            self._num_label.get_style_context().remove_class('queued')
            self._num_label.set_text('')

    def get_id(self):
        """
            Get object id
            @return Current id as int
        """
        return self._track.id

#######################
# PRIVATE             #
#######################
    def _on_map(self, widget):
        """
            Fix for Gtk < 3.18,
            if we are in a popover, do not show menu button
        """
        widget = self.get_parent()
        while widget is not None:
            if isinstance(widget, Gtk.Popover):
                break
            widget = widget.get_parent()
        if widget is None:
            self._grid.add(self._menu_button)

    def _on_enter_notify(self, widget, event):
        """
            Set image on buttons now, speed reason
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        if self._menu_button.get_image() is None:
            image = Gtk.Image.new_from_icon_name('open-menu-symbolic',
                                                 Gtk.IconSize.MENU)
            image.set_opacity(0.2)
            self._menu_button.set_image(image)
            self._menu_button.connect('clicked', self._on_button_clicked)
            self._indicator.update_button()

    def _on_button_press(self, widget, event):
        """
            Popup menu for track relative to track row
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        if event.button == 3 and Gtk.get_minor_version() > 16:
            window = widget.get_window()
            if window == event.window:
                self._popup_menu(widget, event.x, event.y)
            # Happens when pressing button over menu btn
            else:
                self._popup_menu(self._menu_button)
            return True
        elif event.button == 2:
            if self._track.id in Lp().player.get_queue():
                Lp().player.del_from_queue(self._track.id)
            else:
                Lp().player.append_to_queue(self._track.id)

    def _on_button_clicked(self, widget):
        """
            Popup menu for track relative to button
            @param widget as Gtk.Button
        """
        self._popup_menu(widget)

    def _popup_menu(self, widget, xcoordinate=None, ycoordinate=None):
        """
            Popup menu for track
            @param widget as Gtk.Button
            @param xcoordinate as int (or None)
            @param ycoordinate as int (or None)
        """
        popover = TrackMenuPopover(self._track.id, TrackMenu(self._track.id))
        popover.set_relative_to(widget)
        if xcoordinate is not None and ycoordinate is not None:
            rect = widget.get_allocation()
            rect.x = xcoordinate
            rect.y = ycoordinate
            rect.width = rect.height = 1
            popover.set_pointing_to(rect)
        popover.connect('closed', self._on_closed)
        self.get_style_context().add_class('track-menu-selected')
        popover.show()

    def _on_closed(self, widget):
        """
            Remove selected style
            @param widget as Gtk.Popover
        """
        self.get_style_context().remove_class('track-menu-selected')

    def _on_title_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip if needed
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        layout = self._title_label.get_layout()
        if layout.is_ellipsized():
            self._title_label.set_tooltip_markup(self._track.formated_name())
        elif len(self._track.artists) > 1:
            self._title_label.set_tooltip_text(
                                           ", ".join(self._track.artists[1:]))
        else:
            self._title_label.set_tooltip_text('')
Exemple #3
0
class Row(Gtk.ListBoxRow):
    """
        A row
    """
    def __init__(self, rowid, num):
        """
            Init row widgets
            @param rowid as int
            @param num as int
            @param show loved as bool
        """
        # We do not use Gtk.Builder for speed reasons
        Gtk.ListBoxRow.__init__(self)
        self.set_sensitive(False)
        self._track = Track(rowid)
        self._number = num
        self._indicator = IndicatorWidget(self._track.id)
        self.set_indicator(Lp().player.current_track.id == self._track.id,
                           utils.is_loved(self._track.id))
        self.set_sensitive(True)
        self._row_widget = Gtk.EventBox()
        self._row_widget.connect('button-press-event', self._on_button_press)
        self._row_widget.connect('enter-notify-event', self._on_enter_notify)
        self._grid = Gtk.Grid()
        self._grid.set_column_spacing(5)
        self._row_widget.add(self._grid)
        self._title_label = Gtk.Label.new(self._track.formated_name())
        self._title_label.set_use_markup(True)
        self._title_label.set_property('has-tooltip', True)
        self._title_label.connect('query-tooltip',
                                  self._on_title_query_tooltip)
        self._title_label.set_property('hexpand', True)
        self._title_label.set_property('halign', Gtk.Align.START)
        self._title_label.set_ellipsize(Pango.EllipsizeMode.END)
        self._duration_label = Gtk.Label.new(
            seconds_to_string(self._track.duration))
        self._duration_label.get_style_context().add_class('dim-label')
        self._num_label = Gtk.Label()
        self._num_label.set_ellipsize(Pango.EllipsizeMode.END)
        self._num_label.set_property('valign', Gtk.Align.CENTER)
        self._num_label.set_width_chars(4)
        self._num_label.get_style_context().add_class('dim-label')
        self.update_num_label()
        self._menu_image = Gtk.Image.new()
        self._menu_image.set_opacity(0.2)
        self._menu_button = Gtk.Button.new()
        self._menu_button.set_relief(Gtk.ReliefStyle.NONE)
        self._menu_button.get_style_context().add_class('menu-button')
        self._menu_button.get_style_context().add_class('track-menu-button')
        self._menu_button.set_image(self._menu_image)
        self._menu_button.connect('clicked', self._on_button_clicked)
        self._grid.add(self._num_label)
        self._grid.add(self._title_label)
        self._grid.add(self._duration_label)
        # TODO Remove this later
        if Gtk.get_minor_version() > 16:
            self._grid.add(self._menu_button)
        else:
            self.connect('map', self._on_map)
        self.add(self._row_widget)
        self.get_style_context().add_class('trackrow')

    def set_indicator(self, playing, loved):
        """
            Show indicator
            @param widget name as str
            @param playing as bool
            @param loved as bool
        """
        self._indicator.clear()
        if playing:
            self.get_style_context().remove_class('trackrow')
            self.get_style_context().add_class('trackrowplaying')
            if loved:
                self._indicator.play_loved()
            else:
                self._indicator.play()
        else:
            self.get_style_context().remove_class('trackrowplaying')
            self.get_style_context().add_class('trackrow')
            if loved:
                self._indicator.loved()
            else:
                self._indicator.empty()

    def set_number(self, num):
        """
            Set number
            @param number as int
        """
        self._number = num

    def update_num_label(self):
        """
            Update position label for row
        """
        if Lp().player.is_in_queue(self._track.id):
            self._num_label.get_style_context().add_class('queued')
            pos = Lp().player.get_track_position(self._track.id)
            self._num_label.set_text(str(pos))
        elif self._number > 0:
            self._num_label.get_style_context().remove_class('queued')
            self._num_label.set_text(str(self._number))
        else:
            self._num_label.get_style_context().remove_class('queued')
            self._num_label.set_text('')

    def get_id(self):
        """
            Get object id
            @return Current id as int
        """
        return self._track.id


#######################
# PRIVATE             #
#######################

    def _on_map(self, widget):
        """
            Fix for Gtk < 3.18,
            if we are in a popover, do not show menu button
        """
        widget = self.get_parent()
        while widget is not None:
            if isinstance(widget, Gtk.Popover):
                break
            widget = widget.get_parent()
        if widget is None:
            self._grid.add(self._menu_button)

    def _on_enter_notify(self, widget, event):
        """
            Set image on buttons now, speed reason
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        if self._menu_image.get_pixbuf() is None:
            self._menu_image.set_from_icon_name('open-menu-symbolic',
                                                Gtk.IconSize.MENU)
            self._indicator.update_button()

    def _on_button_press(self, widget, event):
        """
            Popup menu for track relative to track row
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        if event.button == 3:
            window = widget.get_window()
            if window == event.window:
                self._popup_menu(widget, event.x, event.y)
            # Happens when pressing button over menu btn
            else:
                self._popup_menu(self._menu_button)
            return True
        elif event.button == 2:
            if self._track.id in Lp().player.get_queue():
                Lp().player.del_from_queue(self._track.id)
            else:
                Lp().player.append_to_queue(self._track.id)

    def _on_button_clicked(self, widget):
        """
            Popup menu for track relative to button
            @param widget as Gtk.Button
        """
        self._popup_menu(widget)

    def _popup_menu(self, widget, xcoordinate=None, ycoordinate=None):
        """
            Popup menu for track
            @param widget as Gtk.Button
            @param xcoordinate as int (or None)
            @param ycoordinate as int (or None)
        """
        popover = TrackMenuPopover(self._track.id, TrackMenu(self._track.id))
        popover.set_relative_to(widget)
        if xcoordinate is not None and ycoordinate is not None:
            rect = widget.get_allocation()
            rect.x = xcoordinate
            rect.y = ycoordinate
            rect.width = rect.height = 1
            popover.set_pointing_to(rect)
        popover.connect('closed', self._on_closed)
        self.get_style_context().add_class('track-menu-selected')
        popover.show()

    def _on_closed(self, widget):
        """
            Remove selected style
            @param widget as Gtk.Popover
        """
        self.get_style_context().remove_class('track-menu-selected')

    def _on_title_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip if needed
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        layout = self._title_label.get_layout()
        if layout.is_ellipsized():
            label = self._title_label.get_label()
            self._title_label.set_tooltip_markup(label)
        else:
            self._title_label.set_tooltip_text('')