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 GObject, Gtk, Gdk
14
15from lollypop.define import App
16from lollypop.utils import emit_signal
17from lollypop.helper_signals import SignalsHelper, signals_map
18from lollypop.helper_gestures import GesturesHelper
19
20
21class TracksWidget(Gtk.ListBox, SignalsHelper, GesturesHelper):
22    """
23        Widget showing a track list
24    """
25
26    __gsignals__ = {
27        "activated": (GObject.SignalFlags.RUN_FIRST,
28                      None, (GObject.TYPE_PYOBJECT,)),
29        "do-selection": (GObject.SignalFlags.RUN_FIRST,
30                         None, (GObject.TYPE_PYOBJECT,)),
31        "do-shift-selection": (GObject.SignalFlags.RUN_FIRST,
32                               None, (GObject.TYPE_PYOBJECT,))
33    }
34
35    @signals_map
36    def __init__(self, view_type):
37        """
38            Init track widget
39            @param view_type as ViewType
40        """
41        Gtk.ListBox.__init__(self)
42        GesturesHelper.__init__(self, self)
43        self.__view_type = view_type
44        self.get_style_context().add_class("trackswidget")
45        self.set_property("hexpand", True)
46        self.set_selection_mode(Gtk.SelectionMode.NONE)
47        return [
48            (App().player, "queue-changed", "_on_queue_changed")
49        ]
50
51    def update_playing(self, track_id):
52        """
53            Update playing track
54            @param track_id as int
55        """
56        for row in self.get_children():
57            row.set_indicator()
58
59    def update_duration(self, track_id):
60        """
61            Update duration for track id
62            @param track_id as int
63        """
64        for row in self.get_children():
65            if row.track.id == track_id:
66                row.update_duration()
67
68#######################
69# PROTECTED           #
70#######################
71    def _on_queue_changed(self, *ignore):
72        """
73            Update all position labels
74        """
75        for row in self.get_children():
76            row.update_number_label()
77
78    def _on_primary_long_press_gesture(self, x, y):
79        """
80            Show row menu
81            @param x as int
82            @param y as int
83        """
84        row = self.get_row_at_y(y)
85        if row is None:
86            return
87        emit_signal(self, "do-selection", row)
88
89    def _on_primary_press_gesture(self, x, y, event):
90        """
91            Activate current row
92            @param x as int
93            @param y as int
94            @param event as Gdk.Event
95        """
96        row = self.get_row_at_y(y)
97        if row is None:
98            return
99        if event.state & Gdk.ModifierType.SHIFT_MASK:
100            emit_signal(self, "do-shift-selection", row)
101        elif event.state & Gdk.ModifierType.CONTROL_MASK:
102            emit_signal(self, "do-selection", row)
103        elif event.state & Gdk.ModifierType.MOD1_MASK:
104            emit_signal(self, "do-selection", None)
105            App().player.clear_albums()
106            App().player.load(row.track)
107        else:
108            emit_signal(self, "activated", row.track)
109            emit_signal(self, "do-selection", None)
110
111    def _on_secondary_press_gesture(self, x, y, event):
112        """
113            Show row menu
114            @param x as int
115            @param y as int
116            @param event as Gdk.Event
117        """
118        row = self.get_row_at_y(y)
119        if row is None:
120            return
121        row.popup_menu(self, x, y)
122
123#######################
124# PRIVATE             #
125#######################
126