Handle broadcast_playlist_loaded.
[euphoria.git] / lib / playlist.rb
1 require "euphoria/playlist_item"
2
3 class Playlist < Array
4         attr_reader :container
5
6         def initialize(xmms, on_cur_item_changed)
7                 super()
8
9                 @xmms = xmms
10                 @on_cur_item_changed = on_cur_item_changed
11                 @ee = nil
12                 @eet = nil
13                 @container = nil
14
15                 query_contents
16
17                 @xmms.playlist.current_pos.notifier do |res|
18                         begin
19                                 @current_pos = res.value
20                         rescue Xmms::Result::ValueError
21                                 @current_pos = nil
22                         end
23                 end
24
25                 @xmms.broadcast_playlist_current_pos.notifier do |res|
26                         @current_pos = res.value
27
28                         tmp = find { |i| i.hilighted }
29                         tmp.hilighted = false unless tmp.nil?
30
31                         current_item.hilighted = true
32                 end
33
34                 @xmms.broadcast_playlist_loaded.
35                         notifier(&method(:on_playlist_loaded))
36
37                 @xmms.broadcast_playlist_changed.notifier do |res|
38                         case res.value[:type]
39                                 when Xmms::Playlist::ADD
40                                         self << res.value[:id]
41                                 when Xmms::Playlist::REMOVE
42                                         # the daemon sends the position of the song, not the
43                                         # unique mlib id
44                                         delete(self[res.value[:position]])
45                                 when Xmms::Playlist::CLEAR
46                                         clear
47                         end
48                 end
49
50                 @xmms.broadcast_medialib_entry_changed.notifier do |res|
51                         @xmms.medialib_get_info(res.value).notifier do |res2|
52                                 props = res2.value
53
54                                 find_all { |i| i.id == props[:id] }.each do |item|
55                                         item.properties = props
56
57                                         if current_item && current_item.id == item.id
58                                                 @on_cur_item_changed.call(item)
59                                         end
60                                 end
61                         end
62                 end
63         end
64
65         def current_item
66                 @current_pos && self[@current_pos]
67         end
68
69         def show(eet, is_separate)
70                 return unless @ee.nil?
71
72                 @eet = eet
73
74                 if is_separate
75                         setup_ee
76                 else
77                         @ee = Euphoria.instance.ee
78                         @edje = Euphoria.instance.edje
79                 end
80
81                 @container = Esmart::Container.new(@edje.evas)
82                 @container.name = "playlist"
83                 @container.direction = Esmart::Container::VERTICAL
84                 @container.spacing = 0
85                 @container.fill_policy = Esmart::Container::FILL_X
86                 @container.show
87
88                 @edje.part("playlist.container").swallow(@container)
89
90                 if is_separate
91                         @edje.on_signal("close") do
92                                 each { |i| i.hide }
93
94                                 @edje = nil
95                                 @container = nil
96                                 @dragger = nil
97                                 @ee.delete
98                                 @ee = nil
99                         end
100                 end
101
102                 @edje.on_signal("drag", "playlist.scrollbar.handle") do
103                         @container.scroll_percent =
104                                 @edje.part("playlist.scrollbar.handle").
105                                 get_drag_value.last
106                 end
107
108                 if is_separate
109                         @edje.on_signal("file_dialog.open") do
110                                 Euphoria.instance.show_file_dialog
111                         end
112                 end
113
114                 @edje.on_signal("playlist_item.remove") do
115                         find_all { |i| i.selected }.each do |i|
116                                 @xmms.playlist_remove(i.position)
117                         end
118                 end
119
120                 each { |i| i.show(eet) }
121
122                 current_item && (current_item.hilighted = true)
123         end
124
125         def <<(id)
126                 push(id)
127         end
128
129         def push(*args)
130                 args.each do |id|
131                         item = PlaylistItem.new(id, @xmms, self)
132                         super(item)
133
134                         item.show(@eet) unless @container.nil?
135                         (item.selected = true) if size == 1
136                 end
137
138                 self
139         end
140
141         def delete(item)
142                 unless item.is_a?(PlaylistItem)
143                         item = find { |i| i.id == item }
144                 end
145
146                 item.hide if item.visible?
147                 super
148
149                 # fix up positions of the remaining items
150                 self[item.position..-1].each do |item|
151                         item.position -= 1
152                 end
153         end
154
155         def clear
156                 each { |i| i.hide if i.visible? }
157                 super
158         end
159
160         private
161         def setup_ee
162                 @ee = Ecore::Evas::SoftwareX11.new
163                 @ee.title = "Euphoria Playlist"
164                 @ee.borderless = true
165                 @ee.evas.font_hinting = Evas::Evas::AUTO
166
167                 @ee.on_pre_render { Edje::thaw }
168                 @ee.on_post_render { Edje::freeze }
169
170                 @ee.on_resize do
171                         x, y, w, h = @ee.geometry
172
173                         @edje.resize(w, h)
174                         @dragger.resize(w, h)
175                 end
176
177                 @dragger = Esmart::Draggies.new(@ee)
178                 @dragger.name = "dragger"
179                 @dragger.button = 1
180                 @dragger.show
181
182                 @edje = Edje::Edje.new(@ee.evas)
183                 @edje.load(@eet, "playlist")
184                 @edje.name = "edje"
185                 @edje.show
186
187                 w, h = @edje.get_size_max
188                 @ee.set_size_max(w, h)
189
190                 w, h = @edje.get_size_min
191                 @ee.set_size_min(w, h)
192
193                 @ee.resize(w, h)
194                 @ee.show
195
196                 @ee.shaped = !@edje.data("shaped").nil?
197         end
198
199         def query_contents
200                 @xmms.playlist.entries.notifier do |res|
201                         push(*res.value)
202                 end
203         end
204
205         def on_playlist_loaded(res)
206                 clear
207                 query_contents
208         end
209 end