widgets_artist_banner.py 6.83 KB
Newer Older
Cédric Bellegarde's avatar
Cédric Bellegarde committed
1
# Copyright (c) 2014-2019 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
2 3 4 5 6 7 8 9 10 11 12
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

13
from gi.repository import Gtk, GLib, Gdk
14

15
from lollypop.objects import Album
16
from lollypop.define import App, ArtSize, ArtBehaviour
17 18 19 20 21 22 23 24 25 26 27 28 29 30


class ArtistBannerWidget(Gtk.Overlay):
    """
        Banner for artist
    """

    def __init__(self, artist_id):
        """
            Init artist banner
            @param artist_id as int
        """
        Gtk.Overlay.__init__(self)
        self.__width = 0
31
        self.__album_ids = None
32
        self.__album_id = None
33
        self.__height = self.default_height
34 35
        self.__artist_id = artist_id
        self.__allocation_timeout_id = None
36
        self.set_property("valign", Gtk.Align.START)
37
        self.__artwork = Gtk.Image()
38
        self.__artwork.get_style_context().add_class("black")
39
        self.get_style_context().add_class("black")
40 41 42
        self.__artwork.show()
        self.add(self.__artwork)
        self.connect("size-allocate", self.__on_size_allocate)
43 44 45 46
        self.connect("destroy", self.__on_destroy)
        self.__art_signal_id = App().art.connect(
                                           "artist-artwork-changed",
                                           self.__on_artist_artwork_changed)
47

48 49 50 51 52 53 54
    def set_height(self, height):
        """
            Set height
            @param height as int
        """
        self.__height = height

55 56 57 58 59 60 61 62 63 64 65 66
    def do_get_preferred_width(self):
        """
            Force preferred width
        """
        (min, nat) = Gtk.Bin.do_get_preferred_width(self)
        # Allow resizing
        return (0, 0)

    def do_get_preferred_height(self):
        """
            Force preferred height
        """
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
        return (self.__height, self.__height)

    @property
    def height(self):
        """
            Get height
            @return int
        """
        return self.__height

    @property
    def default_height(self):
        """
            Get default height
        """
82 83 84 85
        if App().window.is_adaptive:
            return ArtSize.LARGE + 20
        else:
            return ArtSize.BANNER + 40
86 87 88 89 90 91 92 93

#######################
# PROTECTED           #
#######################

#######################
# PRIVATE             #
#######################
94
    def __use_album_artwork(self, width, height):
95 96
        """
            Set artwork with album artwork
97 98
            @param width as int
            @param height as int
99
        """
100 101 102 103 104 105 106 107 108 109 110 111 112 113
        # Select an album
        if self.__album_id is None:
            if self.__album_ids is None:
                if App().settings.get_value("show-performers"):
                    self.__album_ids = App().tracks.get_album_ids(
                        [self.__artist_id], [])
                else:
                    self.__album_ids = App().albums.get_ids(
                        [self.__artist_id], [])
            if self.__album_ids:
                self.__album_id = self.__album_ids.pop(0)
        # Get artwork
        if self.__album_id is not None:
            album = Album(self.__album_id)
114 115
            App().art_helper.set_album_artwork(
                album,
116 117
                # +100 to prevent resize lag
                width + 100,
118
                height,
119
                self.__artwork.get_scale_factor(),
120
                ArtBehaviour.BLUR_HARD |
121
                ArtBehaviour.DARKER,
122
                self.__on_album_artwork)
123

124 125 126 127 128 129 130 131 132
    def __handle_size_allocate(self, allocation):
        """
            Change box max/min children
            @param allocation as Gtk.Allocation
        """
        self.__allocation_timeout_id = None
        if allocation.width == 1 or self.__width == allocation.width:
            return
        self.__width = allocation.width
133 134 135 136
        if App().settings.get_value("artist-artwork"):
            artist = App().artists.get_name(self.__artist_id)
            App().art_helper.set_artist_artwork(
                                        artist,
137 138
                                        # +100 to prevent resize lag
                                        allocation.width + 100,
139
                                        allocation.height,
140
                                        self.get_scale_factor(),
141
                                        ArtBehaviour.BLUR_HARD |
142
                                        ArtBehaviour.DARKER,
143
                                        self.__on_artist_artwork)
144
        else:
145
            self.__use_album_artwork(allocation.width, allocation.height)
146

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    def __on_destroy(self, widget):
        """
            Disconnect signal
            @param widget as Gtk.Widget
        """
        if self.__art_signal_id is not None:
            App().art.disconnect(self.__art_signal_id)

    def __on_artist_artwork_changed(self, art, prefix):
        """
            Update artwork if needed
            @param art as Art
            @param prefix as str
        """
        artist = App().artists.get_name(self.__artist_id)
        if prefix == artist:
            rect = Gdk.Rectangle()
            rect.width = self.get_allocated_width()
            rect.height = self.get_allocated_height()
            self.__width = 0
            self.__handle_size_allocate(rect)

169
    def __on_album_artwork(self, surface):
170 171 172 173
        """
            Set album artwork
            @param surface as str
        """
174
        if surface is None:
175
            self.__album_id = None
176 177 178
            self.__use_album_artwork(self.get_allocated_width(),
                                     self.get_allocated_height())
        else:
179
            self.__artwork.set_from_surface(surface)
180

181 182 183 184 185 186
    def __on_artist_artwork(self, surface):
        """
            Set artist artwork
            @param surface as str
        """
        if surface is None:
187 188
            self.__use_album_artwork(self.get_allocated_width(),
                                     self.get_allocated_height())
189 190 191
        else:
            self.__artwork.set_from_surface(surface)

192 193 194 195 196 197 198 199 200 201
    def __on_size_allocate(self, widget, allocation):
        """
            Change box max/min children
            @param widget as Gtk.Widget
            @param allocation as Gtk.Allocation
        """
        if self.__allocation_timeout_id is not None:
            GLib.source_remove(self.__allocation_timeout_id)
        self.__allocation_timeout_id = GLib.idle_add(
            self.__handle_size_allocate, allocation)