ektoplayer 0.1.6 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +26 -12
- data/lib/ektoplayer/application.rb +6 -5
- data/lib/ektoplayer/bindings.rb +61 -55
- data/lib/ektoplayer/common.rb +19 -6
- data/lib/ektoplayer/compat.rb +3 -3
- data/lib/ektoplayer/config.rb +1 -11
- data/lib/ektoplayer/controllers/browser.rb +7 -5
- data/lib/ektoplayer/controllers/help.rb +1 -1
- data/lib/ektoplayer/controllers/info.rb +1 -1
- data/lib/ektoplayer/controllers/playlist.rb +24 -12
- data/lib/ektoplayer/icurses.rb +21 -0
- data/lib/ektoplayer/icurses/curses.rb +53 -0
- data/lib/ektoplayer/icurses/ffi_ncurses.rb +69 -0
- data/lib/ektoplayer/icurses/ncurses.rb +79 -0
- data/lib/ektoplayer/icurses/ncursesw.rb +1 -0
- data/lib/ektoplayer/icurses/sugar.rb +65 -0
- data/lib/ektoplayer/icurses/test.rb +99 -0
- data/lib/ektoplayer/models/player.rb +2 -2
- data/lib/ektoplayer/{mp3player.rb → players/mpg_portaudio_player.rb} +3 -3
- data/lib/ektoplayer/players/mpg_wrapper_player.rb +107 -0
- data/lib/ektoplayer/theme.rb +1 -6
- data/lib/ektoplayer/ui.rb +100 -129
- data/lib/ektoplayer/ui/colors.rb +14 -14
- data/lib/ektoplayer/ui/widgets.rb +4 -4
- data/lib/ektoplayer/ui/widgets/labelwidget.rb +1 -1
- data/lib/ektoplayer/ui/widgets/listwidget.rb +115 -46
- data/lib/ektoplayer/views/help.rb +7 -10
- data/lib/ektoplayer/views/info.rb +29 -38
- data/lib/ektoplayer/views/mainwindow.rb +2 -5
- data/lib/ektoplayer/views/playinginfo.rb +15 -20
- data/lib/ektoplayer/views/progressbar.rb +30 -10
- data/lib/ektoplayer/views/splash.rb +24 -25
- data/lib/ektoplayer/views/tabbar.rb +6 -5
- data/lib/ektoplayer/views/trackrenderer.rb +20 -14
- metadata +15 -47
- data/lib/ektoplayer/views/volumemeter.rb +0 -76
@@ -10,7 +10,7 @@ module Ektoplayer
|
|
10
10
|
|
11
11
|
register = view_operations.with_register('playlist.')
|
12
12
|
%w(up down page_up page_down top bottom
|
13
|
-
search_up search_down search_next search_prev).
|
13
|
+
search_up search_down search_next search_prev toggle_selection).
|
14
14
|
each { |op| register.(op, &@view.method(op)) }
|
15
15
|
|
16
16
|
register.(:play) do
|
@@ -18,24 +18,36 @@ module Ektoplayer
|
|
18
18
|
end
|
19
19
|
|
20
20
|
register.(:reload) do
|
21
|
-
|
21
|
+
view.get_selection.each do |index|
|
22
|
+
operations.send(:'playlist.reload', index)
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
26
|
register.(:download_album) do
|
25
|
-
|
27
|
+
view.get_selection.each do |index|
|
28
|
+
operations.send(:'playlist.download_album', index)
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
register.(:delete) do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
view.with_lock do
|
34
|
+
old_cursor, selection = view.cursor, view.get_selection
|
35
|
+
|
36
|
+
selection.each do
|
37
|
+
operations.send(:'playlist.delete', selection[0])
|
38
|
+
end
|
39
|
+
|
40
|
+
view.selected=(selection[0])
|
41
|
+
view.force_cursorpos(old_cursor)
|
42
|
+
end
|
33
43
|
end
|
34
44
|
|
35
45
|
register.(:goto_current) do
|
36
|
-
|
37
|
-
|
38
|
-
|
46
|
+
view.with_lock do
|
47
|
+
if index = playlist.current_playing
|
48
|
+
view.selected=(index)
|
49
|
+
view.center()
|
50
|
+
end
|
39
51
|
end
|
40
52
|
end
|
41
53
|
|
@@ -43,14 +55,14 @@ module Ektoplayer
|
|
43
55
|
view.mouse.on(65536) do view.up(5) end
|
44
56
|
view.mouse.on(2097152) do view.down(5) end
|
45
57
|
|
46
|
-
[
|
58
|
+
[ICurses::BUTTON1_CLICKED, ICurses::BUTTON2_CLICKED].
|
47
59
|
each do |button|
|
48
60
|
view.mouse.on(button) do |mevent|
|
49
61
|
view.select_from_cursorpos(mevent.y)
|
50
62
|
end
|
51
63
|
end
|
52
64
|
|
53
|
-
[
|
65
|
+
[ICurses::BUTTON1_DOUBLE_CLICKED, ICurses::BUTTON3_CLICKED].each do |btn|
|
54
66
|
view.mouse.on(btn) do |mevent|
|
55
67
|
view.select_from_cursorpos(mevent.y)
|
56
68
|
view_operations.send('playlist.play')
|
@@ -0,0 +1,21 @@
|
|
1
|
+
%w(ffi-ncurses ncursesw ncurses curses).each do |f|
|
2
|
+
begin
|
3
|
+
$USING_CURSES = f
|
4
|
+
require_relative "icurses/#{f}"
|
5
|
+
break
|
6
|
+
rescue LoadError
|
7
|
+
$USING_CURSES = nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
fail %{
|
12
|
+
No interface for ncurses found. Please install one of the following gems
|
13
|
+
- curses
|
14
|
+
- ffi-ncurses
|
15
|
+
- ncurses-ruby
|
16
|
+
- ncursesw
|
17
|
+
|
18
|
+
Maybe your distribution ships one of these already as a package.
|
19
|
+
} unless $USING_CURSES
|
20
|
+
|
21
|
+
require_relative 'icurses/sugar'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'curses'
|
2
|
+
|
3
|
+
module Curses
|
4
|
+
def Curses.initscr; init_screen end
|
5
|
+
def Curses.endwin; close_screen end
|
6
|
+
|
7
|
+
def Curses.newwin(*a) Curses::Window.new(*a) end
|
8
|
+
def Curses.newpad(*a) Curses::Pad.new(*a) end
|
9
|
+
|
10
|
+
class Window
|
11
|
+
def mvaddstr(y, x, s)
|
12
|
+
move(y, x)
|
13
|
+
addstr(s)
|
14
|
+
end
|
15
|
+
|
16
|
+
%w(curx cury maxx maxy begx begy).each do |method|
|
17
|
+
alias_method :"get#{method}", method.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
alias :timeout :timeout=
|
21
|
+
alias :notimeout :nodelay= #todo
|
22
|
+
alias :nodelay :nodelay=
|
23
|
+
|
24
|
+
alias :mvwin :move # 'fix' this Gem
|
25
|
+
def move(y, x)
|
26
|
+
setpos(y, x)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Pad < Window
|
31
|
+
alias :pnoutrefresh :refresh
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ICurses
|
36
|
+
include Curses
|
37
|
+
|
38
|
+
(Curses.public_methods - public_methods).each do |method|
|
39
|
+
define_singleton_method(method, &Curses.method(method))
|
40
|
+
end
|
41
|
+
|
42
|
+
def mousemask(mask, *a); Curses.mousemask(mask) end
|
43
|
+
module_function :mousemask
|
44
|
+
|
45
|
+
def getmouse(mevent=nil)
|
46
|
+
if mevent = Curses.getmouse()
|
47
|
+
return IMouseEvent.new(mevent)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
module_function :getmouse
|
51
|
+
|
52
|
+
IWindow = Curses::Window
|
53
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'ffi-ncurses'
|
2
|
+
|
3
|
+
module FFI::NCurses
|
4
|
+
alias_method :_newwin, :newwin
|
5
|
+
def newwin(*a)
|
6
|
+
IWindow.new(_newwin(*a))
|
7
|
+
end
|
8
|
+
module_function :newwin
|
9
|
+
|
10
|
+
alias_method :_newpad, :newpad
|
11
|
+
def newpad(*a)
|
12
|
+
IWindow.new(_newpad(*a))
|
13
|
+
end
|
14
|
+
module_function :newpad
|
15
|
+
|
16
|
+
alias_method :_stdscr, :stdscr
|
17
|
+
def stdscr
|
18
|
+
IWindow.new(_stdscr)
|
19
|
+
end
|
20
|
+
module_function :stdscr
|
21
|
+
|
22
|
+
alias_method :_mousemask, :mousemask
|
23
|
+
def mousemask(mask, *_)
|
24
|
+
_mousemask(mask, nil)
|
25
|
+
end
|
26
|
+
module_function :mousemask
|
27
|
+
|
28
|
+
alias_method :_getmouse, :getmouse
|
29
|
+
def getmouse(mevent=nil)
|
30
|
+
mevent = FFI::NCurses::Mouse::MEVENT.new
|
31
|
+
if _getmouse(mevent) > -1
|
32
|
+
return IMouseEvent.new(mevent)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
module_function :getmouse
|
36
|
+
|
37
|
+
|
38
|
+
class Window
|
39
|
+
def initialize(w)
|
40
|
+
@w = w
|
41
|
+
end
|
42
|
+
|
43
|
+
FFI::NCurses.public_methods.each do |method|
|
44
|
+
if method =~ /^(mv)?w/
|
45
|
+
define_method(method) do |*args|
|
46
|
+
FFI::NCurses.send(method, @w, *args)
|
47
|
+
end
|
48
|
+
|
49
|
+
next if method =~ /win$/
|
50
|
+
|
51
|
+
define_method(method.to_s.sub(?w, '')) do |*args|
|
52
|
+
FFI::NCurses.send(method, @w, *args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
%w(getcurx getcury getmaxx getmaxy getbegx getbegy
|
58
|
+
keypad nodelay notimeout prefresh pnoutrefresh).each do |meth|
|
59
|
+
|
60
|
+
define_method(meth) do |*args|
|
61
|
+
FFI::NCurses.send(meth, @w, *args)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
IWindow = Window
|
67
|
+
end
|
68
|
+
|
69
|
+
ICurses = FFI::NCurses
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require $USING_CURSES
|
2
|
+
|
3
|
+
Ncurses.initscr
|
4
|
+
|
5
|
+
module Ncurses
|
6
|
+
class IWindow
|
7
|
+
def initialize(w)
|
8
|
+
@w = w
|
9
|
+
end
|
10
|
+
|
11
|
+
def getch
|
12
|
+
return Ncurses::wgetch(self)
|
13
|
+
y, x = Ncurses::getcury(self), Ncurses::getcurx(self)
|
14
|
+
c = Ncurses::wgetch(self)
|
15
|
+
Ncurses::wmove(self, y, x)
|
16
|
+
c
|
17
|
+
end
|
18
|
+
|
19
|
+
%w(getcurx getcury getmaxx getmaxy getbegx getbegy
|
20
|
+
keypad nodelay notimeout prefresh pnoutrefresh).each do |meth|
|
21
|
+
define_method(meth) do |*args|
|
22
|
+
Ncurses.send(meth, @w, *args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Ncurses.public_methods.each do |meth|
|
27
|
+
if meth =~ /^(mv)?w/
|
28
|
+
define_method(meth) do |*args|
|
29
|
+
Ncurses.send(meth, @w, *args)
|
30
|
+
end
|
31
|
+
|
32
|
+
next if meth =~ /win$/
|
33
|
+
|
34
|
+
define_method(meth.to_s.sub(?w, '')) do |*args|
|
35
|
+
Ncurses.send(meth, @w, *args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module ICurses
|
43
|
+
include Ncurses
|
44
|
+
|
45
|
+
def method_missing(m, *a)
|
46
|
+
Ncurses.send(m, *a)
|
47
|
+
rescue NoMethodError
|
48
|
+
Ncurses.send(m.downcase, *a)
|
49
|
+
end
|
50
|
+
module_function :method_missing
|
51
|
+
|
52
|
+
def initscr; end # do nothing
|
53
|
+
module_function :initscr
|
54
|
+
|
55
|
+
def newwin(*a)
|
56
|
+
ICurses::IWindow.new( Ncurses.newwin(*a) )
|
57
|
+
end
|
58
|
+
module_function :newwin
|
59
|
+
|
60
|
+
def newpad(*a)
|
61
|
+
ICurses::IWindow.new( Ncurses.newpad(*a) )
|
62
|
+
end
|
63
|
+
module_function :newpad
|
64
|
+
|
65
|
+
def mousemask(mask, *_)
|
66
|
+
Ncurses.mousemask(mask, [])
|
67
|
+
end
|
68
|
+
module_function :mousemask
|
69
|
+
|
70
|
+
def getmouse(mevent=nil)
|
71
|
+
mevent = Ncurses::MEVENT.new
|
72
|
+
if Ncurses.getmouse(mevent) > -1
|
73
|
+
return IMouseEvent.new(mevent)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
module_function :getmouse
|
77
|
+
|
78
|
+
IWindow = Ncurses::IWindow
|
79
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'ncurses'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ICurses
|
2
|
+
class IMouseEvent
|
3
|
+
attr_accessor :x, :y, :z, :bstate
|
4
|
+
|
5
|
+
def initialize(mouse_event=nil)
|
6
|
+
from_mouse_event!(mouse_event)
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](key) send(key) end
|
10
|
+
def []=(key, value) send("#{key}=", value) end
|
11
|
+
|
12
|
+
def from_mouse_event!(m)
|
13
|
+
@x, @y, @z, @bstate = m.x, m.y, m.z, m.bstate
|
14
|
+
rescue
|
15
|
+
@x, @y, @z, @bstate = m[:x], m[:y], m[:z], m[:bstate]
|
16
|
+
rescue
|
17
|
+
@x= @y= @z= @bstate = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def update!(x: nil, y: nil, z: nil, bstate: nil)
|
21
|
+
@x = x if x
|
22
|
+
@y = y if y
|
23
|
+
@z = z if z
|
24
|
+
@bstate = (bstate or @bstate)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module ICurses
|
30
|
+
%w(lines cols colors init_pair color_pair).each do |meth|
|
31
|
+
meth_up = meth.upcase
|
32
|
+
|
33
|
+
if not respond_to? meth
|
34
|
+
alias_method(meth, meth_up) rescue (
|
35
|
+
define_method(meth) do |*args|
|
36
|
+
method_missing(meth_up, *args)
|
37
|
+
end
|
38
|
+
)
|
39
|
+
|
40
|
+
module_function(meth)
|
41
|
+
elsif not respond_to? meth_up
|
42
|
+
alias_method(meth_up, meth) rescue (
|
43
|
+
define_method(meth_up) do |*args|
|
44
|
+
method_missing(meth, *args)
|
45
|
+
end
|
46
|
+
)
|
47
|
+
module_function(meth_up)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class IWindow
|
52
|
+
unless respond_to? :<<
|
53
|
+
alias_method(:<<, :addstr)
|
54
|
+
end
|
55
|
+
|
56
|
+
%w(curx cury maxx maxy begx begy).each do |meth|
|
57
|
+
full = 'get' + meth
|
58
|
+
if not respond_to? meth
|
59
|
+
alias_method(meth, full)
|
60
|
+
elsif not respond_to? full
|
61
|
+
alias_method(full, meth)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
unless ARGV[0]
|
4
|
+
%w(curses ncurses ncursesw ffi_curses).each do |i|
|
5
|
+
puts i
|
6
|
+
fail i unless system($0, i)
|
7
|
+
end
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
$USING_CURSES = ARGV[0]
|
12
|
+
require_relative ARGV[0]
|
13
|
+
require_relative 'sugar'
|
14
|
+
|
15
|
+
begin
|
16
|
+
warn 'call: initscr'
|
17
|
+
ICurses.initscr
|
18
|
+
|
19
|
+
warn 'call: stdscr'
|
20
|
+
s = ICurses.stdscr
|
21
|
+
warn 'call: stdscr.clear, stdscr.refresh'
|
22
|
+
s.clear; s.refresh
|
23
|
+
|
24
|
+
warn 'call: newwin(0,0,0,0)'
|
25
|
+
w = ICurses.newwin(0,0,0,0)
|
26
|
+
warn 'call: win.erase'
|
27
|
+
w.erase
|
28
|
+
|
29
|
+
warn 'call: win.addstr, win.mvaddstr, win.move, win.getcurx, win.getcury'
|
30
|
+
w.addstr(ARGV[0])
|
31
|
+
w.mvaddstr(1,0, 'test 1')
|
32
|
+
w.move(2,0);
|
33
|
+
w.addstr('test 2')
|
34
|
+
x, y = w.getcurx, w.getcury
|
35
|
+
w.mvaddstr(y + 1, 0, 'test 3')
|
36
|
+
|
37
|
+
warn 'call win.getch'
|
38
|
+
w.getch
|
39
|
+
|
40
|
+
warn 'call: LINES COLS'
|
41
|
+
w.addstr("my term is #{ICurses.LINES} lines and #{ICurses.COLS} cols")
|
42
|
+
|
43
|
+
warn 'call: win.resize'
|
44
|
+
w.resize(50, 30)
|
45
|
+
|
46
|
+
warn 'call: win.refresh, win.noutrefresh'
|
47
|
+
w.refresh; w.noutrefresh
|
48
|
+
|
49
|
+
warn 'call: keypad(true)'
|
50
|
+
w.keypad(true)
|
51
|
+
|
52
|
+
warn 'call: timeout(-1)'
|
53
|
+
w.timeout(1000)
|
54
|
+
|
55
|
+
warn 'call: nodelay(false)'
|
56
|
+
w.nodelay(false)
|
57
|
+
|
58
|
+
warn 'call: notimeout(true)'
|
59
|
+
w.notimeout(true)
|
60
|
+
|
61
|
+
warn 'call: curs_set, nl, nonl, echo, noecho'
|
62
|
+
ICurses.curs_set(1); ICurses.curs_set(0)
|
63
|
+
ICurses.nl; ICurses.nonl
|
64
|
+
ICurses.echo; ICurses.noecho
|
65
|
+
|
66
|
+
warn 'call: mousemask'
|
67
|
+
ICurses.mousemask(ICurses::ALL_MOUSE_EVENTS, [])
|
68
|
+
|
69
|
+
# === Colors === #
|
70
|
+
warn 'call: start_color, use_default_colors, init_pair, attron, attroff'
|
71
|
+
ICurses.start_color
|
72
|
+
ICurses.use_default_colors
|
73
|
+
ICurses.init_pair(1, ICurses::COLOR_BLACK, ICurses::COLOR_GREEN)
|
74
|
+
w.attron(ICurses.color_pair(1))
|
75
|
+
w.addstr("my term is has #{ICurses.COLORS}")
|
76
|
+
w.attroff(ICurses.color_pair(1))
|
77
|
+
|
78
|
+
# === Sugar ===
|
79
|
+
warn 'call: <<'
|
80
|
+
w << 'sugar'
|
81
|
+
|
82
|
+
loop do
|
83
|
+
sleep 0.1
|
84
|
+
warn 'call getch()'
|
85
|
+
c = w.getch
|
86
|
+
unless c
|
87
|
+
warn "empty getch"
|
88
|
+
next
|
89
|
+
end
|
90
|
+
warn "returned #{c} (#{c.ord})"
|
91
|
+
ch = c.chr rescue ''
|
92
|
+
w.addstr("#{ch}")
|
93
|
+
break if ch == ?q
|
94
|
+
end
|
95
|
+
ensure
|
96
|
+
ICurses.endwin rescue puts $!
|
97
|
+
end
|
98
|
+
|
99
|
+
exit 0
|