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