gswax 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gswax +4 -0
- data/lib/gswax.rb +306 -0
- data/lib/gswax/Wax.rb +273 -0
- data/lib/gswax/browser.rb +224 -0
- data/lib/gswax/images/arm.png +0 -0
- data/lib/gswax/images/default.png +0 -0
- data/lib/gswax/images/defaultHOVER.png +0 -0
- data/lib/gswax/images/dugout.png +0 -0
- data/lib/gswax/images/dugoutHOVER.png +0 -0
- data/lib/gswax/images/info.png +0 -0
- data/lib/gswax/images/infoHOVER.png +0 -0
- data/lib/gswax/images/next.png +0 -0
- data/lib/gswax/images/nextHOVER.png +0 -0
- data/lib/gswax/images/no_cover.png +0 -0
- data/lib/gswax/images/pause.png +0 -0
- data/lib/gswax/images/pauseHOVER.png +0 -0
- data/lib/gswax/images/play.png +0 -0
- data/lib/gswax/images/playHOVER.png +0 -0
- data/lib/gswax/images/playlist.png +0 -0
- data/lib/gswax/images/playlistHOVER.png +0 -0
- data/lib/gswax/images/prev.png +0 -0
- data/lib/gswax/images/prevHOVER.png +0 -0
- data/lib/gswax/images/settings.png +0 -0
- data/lib/gswax/images/settingsHOVER.png +0 -0
- data/lib/gswax/images/shuffle.png +0 -0
- data/lib/gswax/images/shuffleHOVER.png +0 -0
- data/lib/gswax/images/stanton.png +0 -0
- data/lib/gswax/images/stanton1.png +0 -0
- data/lib/gswax/images/vol.png +0 -0
- data/lib/gswax/images/volslider.png +0 -0
- data/lib/gswax/playlist.rb +182 -0
- data/lib/gswax/playlists/default +0 -0
- data/lib/gswax/scrollbox.rb +100 -0
- data/lib/gswax/settings/settings.yml +16 -0
- data/lib/gswax/settings_manager.rb +284 -0
- data/lib/gswax/shared.rb +206 -0
- data/lib/gswax/turntable.rb +251 -0
- data/lib/gswax/version.rb +3 -0
- metadata +107 -0
@@ -0,0 +1,224 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
this file is part of: gsWax v. 0.12.01
|
4
|
+
|
5
|
+
You should have received a copy of the GNU General Public License
|
6
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
7
|
+
=end
|
8
|
+
|
9
|
+
|
10
|
+
class DirBrowser
|
11
|
+
include Observable
|
12
|
+
|
13
|
+
def initialize(path = Settings.brains_dir)
|
14
|
+
@okfiles = [/.mp3/, /.flac/, /.ogg/, /.wav/]
|
15
|
+
@selected = []
|
16
|
+
@listview = ListView.new # def in shared.rb
|
17
|
+
@listview.add_observer(self, :on_list_signals)
|
18
|
+
|
19
|
+
init_ui
|
20
|
+
pathscan(path)
|
21
|
+
update_ui
|
22
|
+
end
|
23
|
+
|
24
|
+
def init_ui
|
25
|
+
@win = Gtk::Window.new
|
26
|
+
@win.set_size_request(750, 450)
|
27
|
+
@win.icon = Gdk::Pixbuf.new File.join(DIR, '../static/gshoes-icon.png')
|
28
|
+
@win.title = 'Directory Browser'
|
29
|
+
@win.signal_connect("destroy"){changed; notify_observers("BROWSER_CLOSED")}
|
30
|
+
@main = Gtk::HBox.new(false, 5)
|
31
|
+
@leftalign = Gtk::Alignment.new(0.5, 0, 0, 0)
|
32
|
+
@left = Gtk::VBox.new(false, 2)
|
33
|
+
@left.set_size_request(200, 450)
|
34
|
+
|
35
|
+
current_btn_frame = Gtk::Frame.new()
|
36
|
+
@current_dir_btn = Gtk::EventBox.new()
|
37
|
+
@current_dir_btn.set_size_request(200, 200)
|
38
|
+
@img = Gtk::Image.new()
|
39
|
+
@current_dir_btn.add(@img)
|
40
|
+
@current_dir_btn.signal_connect("button_press_event"){
|
41
|
+
@listview.list_selection.select_all
|
42
|
+
}
|
43
|
+
current_btn_frame.add(@current_dir_btn)
|
44
|
+
|
45
|
+
up_btn_frame = Gtk::Frame.new("/../")
|
46
|
+
up_btn_frame.label_xalign = 0.05
|
47
|
+
@up_dir_btn = Gtk::EventBox.new()
|
48
|
+
@current_dir_text = Gtk::Label.new()
|
49
|
+
@current_dir_text.width_chars = (26)
|
50
|
+
@current_dir_text.set_wrap(true)
|
51
|
+
@current_dir_text.justify = Gtk::JUSTIFY_CENTER
|
52
|
+
@current_dir_text.ypad = 5
|
53
|
+
@up_dir_btn.add(@current_dir_text)
|
54
|
+
@up_dir_btn.signal_connect("button_press_event"){up_one_dir}
|
55
|
+
up_btn_frame.add(@up_dir_btn)
|
56
|
+
|
57
|
+
add_btns_box = Gtk::HBox.new(true, 2)
|
58
|
+
@append_btn = Gtk::Button.new("list <<")
|
59
|
+
@append_btn.signal_connect("clicked"){notify_add_selected}
|
60
|
+
@prepend_btn = Gtk::Button.new(">> list")
|
61
|
+
@prepend_btn.signal_connect("clicked"){notify_add_selected("prepend")}
|
62
|
+
@append_btn.sensitive = false
|
63
|
+
@prepend_btn.sensitive = false
|
64
|
+
add_btns_box.pack_start(@append_btn, true, true, 2)
|
65
|
+
add_btns_box.pack_start(@prepend_btn, true, true, 2)
|
66
|
+
|
67
|
+
@left.pack_start(current_btn_frame, false, false, 10)
|
68
|
+
@left.pack_start(up_btn_frame, false, false, 10)
|
69
|
+
@left.pack_end(add_btns_box, false, false, 10)
|
70
|
+
|
71
|
+
@leftalign.add(@left)
|
72
|
+
|
73
|
+
@rightalign = Gtk::Alignment.new(0, 0, 1, 0)
|
74
|
+
@right = Gtk::VBox.new(false, 2)
|
75
|
+
@rightpane = Gtk::ScrolledWindow.new
|
76
|
+
@rightpane.set_size_request(500, 450)
|
77
|
+
horizontal = @rightpane.hadjustment
|
78
|
+
vertical = @rightpane.vadjustment
|
79
|
+
viewport = Gtk::Viewport.new(horizontal, vertical)
|
80
|
+
@rightpane.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS)
|
81
|
+
@rightpane.add_with_viewport(@listview.list)
|
82
|
+
@right.pack_start(@rightpane, true, true, 2)
|
83
|
+
@rightalign = Gtk::Alignment.new(0, 0, 1, 0)
|
84
|
+
@rightalign.add(@right)
|
85
|
+
|
86
|
+
@main.pack_start(@leftalign, true, true, 2)
|
87
|
+
@main.pack_start(@rightalign, true, true, 2)
|
88
|
+
|
89
|
+
@win.add(@main)
|
90
|
+
@win.show_all
|
91
|
+
end
|
92
|
+
|
93
|
+
def update_ui
|
94
|
+
##left side
|
95
|
+
@current_dir_btn.remove(@img)
|
96
|
+
pbuf = Gdk::Pixbuf.new(@image_file, 200, 200)
|
97
|
+
@img = Gtk::Image.new(pbuf)
|
98
|
+
@current_dir_btn.add(@img)
|
99
|
+
@current_dir_text.text = @current_dir
|
100
|
+
@left.show_all
|
101
|
+
|
102
|
+
##right side
|
103
|
+
@listview.store.clear
|
104
|
+
@dirs.each{|dir| @listview.add_to_list(dir)} if @dirs[0]
|
105
|
+
@files.each{|file| @listview.add_to_list(file)} if @files[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
def on_list_signals(*signal)
|
109
|
+
case signal[0]
|
110
|
+
when "changed"
|
111
|
+
add_btns_active(true)
|
112
|
+
when "row-activated"
|
113
|
+
right_select(signal[2])
|
114
|
+
add_btns_active(false)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def right_select(path)
|
119
|
+
iter = @listview.store.get_iter(path)
|
120
|
+
entry = iter[1]
|
121
|
+
if @dirs.include?(entry)
|
122
|
+
update_dir(entry)
|
123
|
+
elsif @files.include?(entry)
|
124
|
+
changed; notify_observers(["PLAY_NOW", entry])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def notify_add_selected(position = "append")
|
129
|
+
dirs = []
|
130
|
+
files = []
|
131
|
+
@listview.list_selection.selected_each{|mod, path, iter|
|
132
|
+
dirs << iter[1] ? File.directory?(iter[1]) : files << iter[1]
|
133
|
+
}
|
134
|
+
|
135
|
+
files.each{|file| @selected << file} if files[0]
|
136
|
+
|
137
|
+
if dirs[0]
|
138
|
+
dirs.each{|dir|
|
139
|
+
Find.find(dir){|item|
|
140
|
+
@okfiles.each{|ok| @selected << item if item.downcase =~ ok}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
if position == "prepend"
|
146
|
+
@selected.reverse!.insert(0, "PREPEND")
|
147
|
+
else
|
148
|
+
@selected.insert(0, "APPEND")
|
149
|
+
end
|
150
|
+
|
151
|
+
changed; notify_observers(@selected)
|
152
|
+
@selected = []
|
153
|
+
@listview.list_selection.unselect_all
|
154
|
+
add_btns_active(false)
|
155
|
+
end
|
156
|
+
|
157
|
+
def pathscan(path)
|
158
|
+
if path
|
159
|
+
if File.directory?(path)
|
160
|
+
dirs = []
|
161
|
+
files = []
|
162
|
+
Dir.open(path){|dir|
|
163
|
+
for entry in dir
|
164
|
+
next if entry == '.'
|
165
|
+
next if entry == '..'
|
166
|
+
unless entry[0] == '.'
|
167
|
+
item = path + File::Separator + entry
|
168
|
+
if File.directory?(item)
|
169
|
+
dirs << item unless File.basename(item)[0] == "."
|
170
|
+
else
|
171
|
+
@okfiles.each{|ok| files << item if item.downcase =~ ok}
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
}
|
176
|
+
@dirs = dirs.sort
|
177
|
+
@files = files.sort
|
178
|
+
@current_dir = path
|
179
|
+
@left_width = 200
|
180
|
+
get_image(@current_dir)
|
181
|
+
end
|
182
|
+
else
|
183
|
+
@current_dir = Settings.brains_dir
|
184
|
+
@image_file = Settings.brains_dir + File::Separator + "images" + File::Separator + "no_cover.png"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def get_image(path)
|
189
|
+
if path
|
190
|
+
image_files = []
|
191
|
+
Dir.entries(path).each{|entry|
|
192
|
+
image_files << entry if entry.downcase.include?(".jpg") || entry.downcase.include?(".png") || entry.downcase.include?(".gif")
|
193
|
+
}
|
194
|
+
if image_files[0]
|
195
|
+
@image_file = path + File::Separator + image_files[0]
|
196
|
+
else
|
197
|
+
@image_file = Settings.brains_dir + File::Separator + "images" + File::Separator + "no_cover.png"
|
198
|
+
end
|
199
|
+
else
|
200
|
+
@image_file = Settings.brains_dir + File::Separator + "images" + File::Separator + "no_cover.png"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def up_one_dir
|
205
|
+
newpath = @current_dir.split(File::Separator)[0..-2].join(File::Separator)
|
206
|
+
update_dir(newpath)
|
207
|
+
add_btns_active(false)
|
208
|
+
end
|
209
|
+
|
210
|
+
def update_dir(path)
|
211
|
+
pathscan(path)
|
212
|
+
update_ui
|
213
|
+
end
|
214
|
+
|
215
|
+
def add_btns_active(boolean)
|
216
|
+
@append_btn.sensitive = boolean
|
217
|
+
@prepend_btn.sensitive = boolean
|
218
|
+
end
|
219
|
+
|
220
|
+
def close_window
|
221
|
+
@win.destroy
|
222
|
+
end
|
223
|
+
|
224
|
+
end #DirBrowser
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,182 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
this file is part of: gsWax v. 0.12.01
|
4
|
+
|
5
|
+
You should have received a copy of the GNU General Public License
|
6
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
7
|
+
=end
|
8
|
+
|
9
|
+
|
10
|
+
class PlayList
|
11
|
+
include Observable
|
12
|
+
attr_accessor :listview, :main
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@selected = []
|
16
|
+
@listview = ListView.new # def in share.rb
|
17
|
+
@listview.list.reorderable = true
|
18
|
+
@listview.add_observer(self, :on_list_signals)
|
19
|
+
init_ui
|
20
|
+
end
|
21
|
+
|
22
|
+
def init_ui
|
23
|
+
@win = Gtk::Window.new
|
24
|
+
@win.set_size_request(500, 500)
|
25
|
+
@win.icon = Gdk::Pixbuf.new File.join(DIR, '../static/gshoes-icon.png')
|
26
|
+
@win.title = 'Playlist'
|
27
|
+
@win.signal_connect("destroy"){changed; notify_observers("PLAYLIST_CLOSED")}
|
28
|
+
|
29
|
+
@main = Gtk::VBox.new(false, 5)
|
30
|
+
|
31
|
+
show_list
|
32
|
+
|
33
|
+
@win.add(@main)
|
34
|
+
@win.show_all
|
35
|
+
end
|
36
|
+
|
37
|
+
def show_list
|
38
|
+
list_panel = Gtk::ScrolledWindow.new
|
39
|
+
list_panel.set_size_request(500, 460)
|
40
|
+
|
41
|
+
hadjust = list_panel.hadjustment
|
42
|
+
vadjust = list_panel.vadjustment
|
43
|
+
viewport = Gtk::Viewport.new(hadjust, vadjust)
|
44
|
+
list_panel.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS)
|
45
|
+
list_panel.add_with_viewport(@listview.list)
|
46
|
+
|
47
|
+
btn_panel = Gtk::HBox.new(true, 2)
|
48
|
+
|
49
|
+
add_tracks_btn = Gtk::Button.new("add tracks")
|
50
|
+
add_tracks_btn.signal_connect("clicked"){call_browser}
|
51
|
+
|
52
|
+
@remove_tracks_btn = Gtk::Button.new("remove tracks")
|
53
|
+
@remove_tracks_btn.signal_connect("clicked"){remove_tracks}
|
54
|
+
@remove_tracks_btn.sensitive = false
|
55
|
+
|
56
|
+
@clear_list_btn = Gtk::Button.new("clear list")
|
57
|
+
@clear_list_btn.signal_connect("clicked"){clear_list}
|
58
|
+
@clear_list_btn.sensitive = false
|
59
|
+
|
60
|
+
load_list_btn = Gtk::Button.new("load list")
|
61
|
+
load_list_btn.signal_connect("clicked"){load_list}
|
62
|
+
|
63
|
+
@save_list_btn = Gtk::Button.new("save list")
|
64
|
+
@save_list_btn.signal_connect("clicked"){save_list}
|
65
|
+
@save_list_btn.sensitive = false
|
66
|
+
|
67
|
+
btn_panel.pack_start(add_tracks_btn, true, true, 1)
|
68
|
+
btn_panel.pack_start(@remove_tracks_btn, true, true, 1)
|
69
|
+
btn_panel.pack_start(@clear_list_btn, true, true, 1)
|
70
|
+
btn_panel.pack_start(load_list_btn, true, true, 1)
|
71
|
+
btn_panel.pack_start(@save_list_btn, true, true, 1)
|
72
|
+
|
73
|
+
|
74
|
+
@main.pack_start(list_panel, true, true, 0)
|
75
|
+
@main.pack_end(btn_panel, true, true, 0)
|
76
|
+
end
|
77
|
+
|
78
|
+
def add(entry, position = "append")
|
79
|
+
if entry.class == String
|
80
|
+
@listview.add_to_list(entry, position)
|
81
|
+
elsif entry.class == Array
|
82
|
+
entry.each{|e| @listview.add_to_list(e, position)}
|
83
|
+
end
|
84
|
+
@clear_list_btn.sensitive = true
|
85
|
+
@save_list_btn.sensitive = true
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_list_signals(*signal)
|
89
|
+
case signal[0]
|
90
|
+
when "changed"
|
91
|
+
@remove_tracks_btn.sensitive = true
|
92
|
+
when "row-activated"
|
93
|
+
iter = @listview.store.get_iter(signal[2])
|
94
|
+
entry = iter[1]
|
95
|
+
changed; notify_observers(["PLAY_NOW", entry])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def on_browser_signals(signal)
|
100
|
+
case signal[0]
|
101
|
+
when "PREPEND"
|
102
|
+
add(signal[1..-1], "prepend")
|
103
|
+
when "APPEND"
|
104
|
+
add(signal[1..-1])
|
105
|
+
when "PLAY_NOW"
|
106
|
+
add(signal[1])
|
107
|
+
end
|
108
|
+
changed; notify_observers(signal)
|
109
|
+
end
|
110
|
+
|
111
|
+
def call_browser
|
112
|
+
changed; notify_observers("BROWSER")
|
113
|
+
end
|
114
|
+
|
115
|
+
def remove_tracks
|
116
|
+
tracks = []
|
117
|
+
|
118
|
+
@listview.list_selection.selected_rows.each{|path|
|
119
|
+
iter = @listview.store.get_iter(path)
|
120
|
+
tracks << iter[1]
|
121
|
+
@listview.store.remove(iter)
|
122
|
+
}
|
123
|
+
tracks.insert(0, "REMOVE")
|
124
|
+
changed; notify_observers(tracks)
|
125
|
+
end
|
126
|
+
|
127
|
+
def clear_list
|
128
|
+
if confirm("clear playlist?")
|
129
|
+
@listview.store.clear
|
130
|
+
@clear_list_btn.sensitive = false
|
131
|
+
@save_list_btn.sensitive = false
|
132
|
+
changed; notify_observers("CLEAR_LIST")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def load_list
|
137
|
+
list = []
|
138
|
+
playlist_dir = File.join(Settings.brains_dir, "playlists")
|
139
|
+
unless Dir.exists?(playlist_dir)
|
140
|
+
Dir.mkdir(playlist_dir)
|
141
|
+
end
|
142
|
+
Dir.chdir(playlist_dir){
|
143
|
+
@openfile = ask_open_file
|
144
|
+
}
|
145
|
+
if @openfile
|
146
|
+
File.open(@openfile, "r"){|file|
|
147
|
+
file.each_line{|line| list << line.chomp}
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
@listview.store.clear
|
152
|
+
add(list)
|
153
|
+
|
154
|
+
list.insert(0, @openfile)
|
155
|
+
list.insert(0, "LOAD_LIST")
|
156
|
+
changed; notify_observers(list)
|
157
|
+
end
|
158
|
+
|
159
|
+
def save_list
|
160
|
+
unless Dir.exists?((File.join(Settings.brains_dir, "playlists")))
|
161
|
+
Dir.mkdir(File.join(Settings.brains_dir, "playlists"))
|
162
|
+
end
|
163
|
+
Dir.chdir(File.join(Settings.brains_dir, "playlists")){
|
164
|
+
@savefile = ask_save_file
|
165
|
+
}
|
166
|
+
|
167
|
+
if @savefile
|
168
|
+
@listview.list_selection.select_all
|
169
|
+
File.open(@savefile, "w+"){|file|
|
170
|
+
@listview.list_selection.selected_each{|mod, path, iter| file.puts iter[1]}
|
171
|
+
}
|
172
|
+
@listview.list_selection.unselect_all
|
173
|
+
|
174
|
+
changed; notify_observers(["SAVE_LIST", @savefile])
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def close_window
|
179
|
+
@win.destroy
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|