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