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