gswax 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|