1# Copyright (c) 2014-2021 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
2# This program is free software: you can redistribute it and/or modify
3# it under the terms of the GNU General Public License as published by
4# the Free Software Foundation, either version 3 of the License, or
5# (at your option) any later version.
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# GNU General Public License for more details.
10# You should have received a copy of the GNU General Public License
11# along with this program. If not, see <http://www.gnu.org/licenses/>.
12
13from gi.repository import Gtk, GLib
14
15
16from lollypop.utils import set_cursor_type, popup_widget
17from lollypop.widgets_player_artwork import ArtworkPlayerWidget
18from lollypop.widgets_player_label import LabelPlayerWidget
19from lollypop.define import App, ArtBehaviour, StorageType, MARGIN_SMALL
20from lollypop.define import ViewType
21from lollypop.helper_gestures import GesturesHelper
22
23
24class ToolbarInfo(Gtk.Bin, ArtworkPlayerWidget, GesturesHelper):
25    """
26        Informations toolbar
27    """
28
29    def __init__(self):
30        """
31            Init toolbar
32        """
33        Gtk.Bin.__init__(self)
34        self.__width = 0
35        horizontal_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 15)
36        horizontal_box.show()
37        self.__eventbox = Gtk.EventBox.new()
38        self.__eventbox.add(horizontal_box)
39        self.__eventbox.set_property("halign", Gtk.Align.START)
40        self.__eventbox.show()
41        self.__eventbox.connect("realize", set_cursor_type)
42        self.add(self.__eventbox)
43        GesturesHelper.__init__(self, self.__eventbox)
44        self.special_headerbar_hack()
45
46        self.__label = LabelPlayerWidget()
47        self.__artwork = ArtworkPlayerWidget(ArtBehaviour.CROP_SQUARE |
48                                             ArtBehaviour.CACHE)
49        self.__artwork.set_property("has-tooltip", True)
50        self.__artwork.set_margin_top(1)
51        horizontal_box.pack_start(self.__artwork, False, False, 0)
52        horizontal_box.pack_start(self.__label, False, False, 0)
53        self.set_margin_start(MARGIN_SMALL)
54        self.connect("realize", self.__on_realize)
55
56    def show_children(self):
57        """
58            Show labels and artwork
59        """
60        self.__artwork.show()
61        self.__label.show()
62
63    def hide_children(self):
64        """
65            Hide labels and artwork, ignore self
66        """
67        self.__artwork.hide()
68        self.__label.hide()
69
70    def do_get_preferred_width(self):
71        """
72            We force preferred width
73            @return (int, int)
74        """
75        return (self.__width, self.__width)
76
77    def get_preferred_height(self):
78        """
79            Return preferred height
80            @return (int, int)
81        """
82        return self.__labels.get_preferred_height()
83
84    def set_width(self, width):
85        """
86            Set widget width
87            @param width as int
88        """
89        self.__width = width
90        self.set_property("width-request", width)
91
92#######################
93# PROTECTED           #
94#######################
95    def _on_primary_long_press_gesture(self, x, y):
96        """
97            Show menu
98            @param x as int
99            @param y as int
100        """
101        if App().window.folded or not self.__artwork.get_visible():
102            return
103        if App().player.current_track.id is not None:
104            self.__popup_menu()
105
106    def _on_primary_press_gesture(self, x, y, event):
107        """
108            Show information popover
109            @param x as int
110            @param y as int
111            @param evnet as Gdk.Event
112        """
113        if App().window.folded or not self.__artwork.get_visible():
114            return
115        if App().player.current_track.id is not None:
116            from lollypop.pop_information import InformationPopover
117            popover = InformationPopover()
118            popover.populate()
119        popover.set_relative_to(self.__eventbox)
120        popover.popup()
121
122    def _on_secondary_press_gesture(self, x, y, event):
123        """
124            Show menu
125            @param x as int
126            @param y as int
127        """
128        self._on_primary_long_press_gesture(x, y)
129
130#######################
131# PRIVATE             #
132#######################
133    def __popup_menu(self):
134        """
135            Show contextual menu
136        """
137        if App().window.folded or not self.__artwork.get_visible():
138            return
139        track = App().player.current_track
140        if track.id >= 0:
141            from lollypop.menu_objects import TrackMenu, TrackMenuExt
142            from lollypop.widgets_menu import MenuBuilder
143            menu = TrackMenu(track, ViewType.TOOLBAR)
144            menu_widget = MenuBuilder(menu)
145            menu_widget.show()
146            if not track.storage_type & StorageType.EPHEMERAL:
147                menu_ext = TrackMenuExt(track)
148                menu_ext.show()
149                menu_widget.add_widget(menu_ext)
150            self.set_state_flags(Gtk.StateFlags.FOCUSED, False)
151            popup_widget(menu_widget, self.__eventbox, None, None, None)
152
153    def __on_query_tooltip(self, widget, x, y, keyboard, tooltip):
154        """
155            Show tooltip if needed
156            @param widget as Gtk.Widget
157            @param x as int
158            @param y as int
159            @param keyboard as bool
160            @param tooltip as Gtk.Tooltip
161        """
162        layout_title = self._title_label.get_layout()
163        layout_artist = self._artist_label.get_layout()
164        if layout_title.is_ellipsized() or layout_artist.is_ellipsized():
165            artist = GLib.markup_escape_text(self._artist_label.get_text())
166            title = GLib.markup_escape_text(self._title_label.get_text())
167            tooltip.set_markup("<b>%s</b> - %s" % (artist, title))
168        else:
169            return False
170        return True
171
172    def __on_realize(self, toolbar):
173        """
174            Calculate art size
175            @param toolbar as ToolbarInfos
176        """
177        art_size = self.get_allocated_height() - 1
178        self.__artwork.set_art_size(art_size, art_size)
179