2 /* Gnome Music Player Client (GMPC)
3 * Copyright (C) 2004-2011 Qball Cow <qball@gmpclient.org>
4 * Project homepage: http://gmpclient.org/
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 /* trick to get config.h included */
27 static const string some_unique_name_fav
= Config
.VERSION
;
28 private const bool use_transition_fav
= Gmpc
.use_transition
;
29 static Gmpc
.Favorites
.List favorites
= null;
31 namespace Gmpc
.Favorites
{
33 * This class is created, and stays active until the last GmpcFavoritesButton gets removed
35 private class List
: GLib
.Object
{
36 private MPD
.Data
.Item? list
= null;
38 gmpcconn
.connection_changed
.connect(con_changed
);
39 gmpcconn
.status_changed
.connect(status_changed
);
43 * If disconnected from mpd, clear the list.
48 con_changed(Gmpc
.Connection conn
, MPD
.Server server
, int connect
)
51 list
= MPD
.Database
.get_playlist_content(server
, _("Favorites"));
58 * If playlist changed update the list
62 status_changed(Gmpc
.Connection conn
, MPD
.Server server
, MPD
.Status
.Changed what
)
64 if((what
&MPD
.Status
.Changed
.STORED_PLAYLIST
) == MPD
.Status
.Changed
.STORED_PLAYLIST
)
66 list
= MPD
.Database
.get_playlist_content(server
, _("Favorites"));
70 /****************************************************************************************
72 ****************************************************************************************/
74 * Signal for the widget using the list to see if it needs to recheck status
76 public signal void updated();
79 * Check if the song (specified by path) is favored
83 is_favorite(string path
)
85 unowned MPD
.Data
.Item iter
= this
.list
.get_first();
88 if(iter
.type
== MPD
.Data
.Type
.SONG
)
90 if(iter
.song
.file
== path
){
99 * Favor, or unfavor a song
103 set_favorite(string path
, bool favorite
)
105 bool current
= this
.is_favorite(path
);
106 /* Do nothing if state does not change */
107 if(current
!= favorite
)
111 MPD
.Database
.playlist_list_add(server
, _("Favorites"), path
);
114 /* To be able to remove it we have to first lookup the position */
115 /* This needs libmpd 0.18.1 */
116 unowned MPD
.Data
.Item iter
= this
.list
.get_first();
119 if(iter
.type
== MPD
.Data
.Type
.SONG
)
121 if(iter
.song
.file
== path
){
122 MPD
.Database
.playlist_list_delete(server
, _("Favorites"), iter
.song
.pos
);
133 * The actual favorite button
135 public class Button
: Gtk
.EventBox
{
136 /* the song the button show show the state for */
137 private MPD
.Song? song
;
138 /* The image displaying the state */
139 private Gtk
.Image image
;
140 /* The current state */
141 private bool fstate
= false;
142 /* The pixbuf holding the unmodified image */
143 private Gdk
.Pixbuf pb
= null;
146 * Creation of the object
149 this
.no_show_all
= true;
150 this
.visible_window
= false;
151 var it
= Gtk
.IconTheme
.get_default();
153 pb
= it
.load_icon("emblem-favorite",24, 0);
155 GLib
.error("error: %s\n", e
.message
);
157 if(favorites
== null){
158 favorites
= new
List();
159 /* make sure favorites is set to NULL again when destroyed */
160 favorites
.add_weak_pointer(&favorites
);
164 favorites
.updated
.connect(update
);
165 this
.image
= new Gtk
.Image();
166 this
.update(favorites
);
167 this
.add(this
.image
);
168 this
.button_press_event
.connect(button_press_event_callback
);
169 this
.enter_notify_event
.connect(enter_notify_event_callback
);
170 this
.leave_notify_event
.connect(leave_notify_event_callback
);
174 if(favorites
!= null)
179 button_press_event_callback(Gtk
.Widget button
,Gdk
.EventButton event
)
181 if(event
.button
== 1 && this
.song
!= null) {
182 favorites
.set_favorite(this
.song
.file
, !this
.fstate
);
183 this
.fstate
= !this
.fstate
;
185 else if (event
.button
== 3 && this
.song
!= null) {
186 var menu
= new Gtk
.Menu();
188 MPD
.Data
.Item ? item
= MPD
.Database
.get_playlist_list(server
);
191 string pp
= item
.playlist
.path
;
192 var entry
= new Gtk
.ImageMenuItem
.with_label(pp
);
193 if(pp
== _("Favorites")) {
194 entry
.set_image(new Gtk
.Image
.from_icon_name("emblem-favorite", Gtk
.IconSize
.MENU
));
196 entry
.set_image(new Gtk
.Image
.from_icon_name("media-playlist", Gtk
.IconSize
.MENU
));
198 entry
.activate
.connect((source
) => {
199 MPD
.Database
.playlist_list_add(server
,pp
, this
.song
.file
);
208 menu
.popup(null, null, null, event
.button
, event
.time
);
216 /* on mouse over, do some pre-highlighting */
219 enter_notify_event_callback(Gtk
.Widget button
, Gdk
.EventCrossing motion
)
223 Gmpc
.Misc
.colorshift_pixbuf(pb2
, pb
, 10);
225 Gmpc
.Misc
.colorshift_pixbuf(pb2
, pb
,-50);
227 this
.image
.set_from_pixbuf(pb2
);
230 /* Reset default highlighting */
233 leave_notify_event_callback(Gtk
.Widget button
, Gdk
.EventCrossing motion
)
235 this
.update(favorites
);
238 /* Update the icon according to state */
241 update(Gmpc
.Favorites
.List list
)
243 if(this
.song
!= null){
244 this
.fstate
= favorites
.is_favorite(this
.song
.file
);
246 /* Hide the widget and do nothing */
250 /* Copy the pixbuf */
252 /* Depending on the state colorshift the pixbuf */
254 Gmpc
.Misc
.colorshift_pixbuf(pb2
, pb
, 30);
256 Gmpc
.Misc
.colorshift_pixbuf(pb2
, pb
, -80);
258 this
.image
.set_from_pixbuf(pb2
);
262 /**********************************************************************
264 *********************************************************************/
265 /* Set the song the button should watch. or NULL to watch non */
268 set_song(MPD
.Song? song
)
270 if(this
.song
== null && song
== null ) return;
271 if(this
.song
!= null && song
!= null && this
.song
.file
== song
.file
) return;
273 this
.update(favorites
);