luck 0.0.0
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/.gitignore +23 -0
- data/LICENSE +20 -0
- data/README.md +21 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/lib/luck/control.rb +35 -0
- data/lib/luck/display.rb +160 -0
- data/lib/luck/label.rb +46 -0
- data/lib/luck/listbox.rb +33 -0
- data/lib/luck/pane.rb +76 -0
- data/lib/luck/progressbar.rb +53 -0
- data/lib/luck/textbox.rb +46 -0
- data/lib/luck.rb +9 -0
- metadata +77 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Daniel Danopia
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Luck
|
2
|
+
====
|
3
|
+
|
4
|
+
Luck is a ncurses-like CLI UI system, written in pure Ruby.
|
5
|
+
|
6
|
+
The origin of the name is that it is the opposite of "curses".
|
7
|
+
|
8
|
+
Luck was developed for [Remora](http://github.com/danopia/remora) but
|
9
|
+
any application can use it now that I packaged it as a gem.
|
10
|
+
|
11
|
+
|
12
|
+
Usage
|
13
|
+
-----
|
14
|
+
|
15
|
+
TODO
|
16
|
+
|
17
|
+
|
18
|
+
Copyright
|
19
|
+
---------
|
20
|
+
|
21
|
+
Copyright (c) 2010 Daniel Danopia. See {file:LICENSE} for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "luck"
|
8
|
+
gem.summary = %Q{Pure-ruby CLI UI system}
|
9
|
+
gem.description = %Q{Pure-ruby CLI UI system. Includes multiple panes in a display and multiple controls in a pane. luck is lucky (as opposed to ncurses being cursed)}
|
10
|
+
gem.email = "me.github@danopia.net"
|
11
|
+
gem.homepage = "http://github.com/danopia/luck"
|
12
|
+
gem.authors = ["Daniel Danopia"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
#~ require 'rake/testtask'
|
22
|
+
#~ Rake::TestTask.new(:test) do |test|
|
23
|
+
#~ test.libs << 'lib' << 'test'
|
24
|
+
#~ test.pattern = 'test/**/*_test.rb'
|
25
|
+
#~ test.verbose = true
|
26
|
+
#~ end
|
27
|
+
|
28
|
+
#~ begin
|
29
|
+
#~ require 'rcov/rcovtask'
|
30
|
+
#~ Rcov::RcovTask.new do |test|
|
31
|
+
#~ test.libs << 'test'
|
32
|
+
#~ test.pattern = 'test/**/*_test.rb'
|
33
|
+
#~ test.verbose = true
|
34
|
+
#~ end
|
35
|
+
#~ rescue LoadError
|
36
|
+
#~ task :rcov do
|
37
|
+
#~ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
#~ end
|
39
|
+
#~ end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
begin
|
46
|
+
require 'yard'
|
47
|
+
require 'yard/rake/yardoc_task'
|
48
|
+
YARD::Rake::YardocTask.new do |t|
|
49
|
+
extra_files = %w(LICENSE)
|
50
|
+
t.files = ['lib/**/*.rb']
|
51
|
+
t.options = ["--files=#{extra_files.join(',')}"]
|
52
|
+
end
|
53
|
+
rescue LoadError
|
54
|
+
task :yard do
|
55
|
+
abort "YARD is not available. In order to run yard, you must: sudo gem install yard"
|
56
|
+
end
|
57
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/lib/luck/control.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Luck
|
2
|
+
class Control
|
3
|
+
attr_accessor :pane, :display, :x1, :y1, :x2, :y2
|
4
|
+
|
5
|
+
def initialize pane, x1, y1, x2, y2, &blck
|
6
|
+
@pane = pane
|
7
|
+
@display = pane.display
|
8
|
+
@x1, @y1 = x1, y1
|
9
|
+
@x2, @y2 = x2, y2
|
10
|
+
|
11
|
+
instance_eval &blck if blck
|
12
|
+
end
|
13
|
+
|
14
|
+
def x1
|
15
|
+
@pane.x1 + ((@x1 < 0) ? (@pane.width + @x1) : @x1)
|
16
|
+
end
|
17
|
+
def y1
|
18
|
+
@pane.y1 + ((@y1 < 0) ? (@pane.height + @y1) : @y1)
|
19
|
+
end
|
20
|
+
|
21
|
+
def x2
|
22
|
+
@pane.x1 + ((@x2 < 0) ? (@pane.width + @x2 + 1) : @x2)
|
23
|
+
end
|
24
|
+
def y2
|
25
|
+
@pane.y1 + ((@y2 < 0) ? (@pane.height + @y2 + 1) : @y2)
|
26
|
+
end
|
27
|
+
|
28
|
+
def width
|
29
|
+
x2 - x1
|
30
|
+
end
|
31
|
+
def height
|
32
|
+
y2 - y1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/luck/display.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
module Luck
|
2
|
+
class Display
|
3
|
+
attr_accessor :width, :height, :client, :panes, :buffer, :dirty, :active_control
|
4
|
+
|
5
|
+
def initialize client
|
6
|
+
@client = client
|
7
|
+
@panes = {}
|
8
|
+
@dirty = true
|
9
|
+
prepare_modes
|
10
|
+
|
11
|
+
size = terminal_size
|
12
|
+
@width = size[1]
|
13
|
+
@height = size[0]
|
14
|
+
end
|
15
|
+
|
16
|
+
def pane name, *args, &blck
|
17
|
+
@panes[name] = Pane.new(self, *args, &blck)
|
18
|
+
end
|
19
|
+
|
20
|
+
def place row, col, text
|
21
|
+
print "\e[#{row.to_i};#{col.to_i}H#{text}"
|
22
|
+
end
|
23
|
+
def color codes
|
24
|
+
"\e[#{codes}m"
|
25
|
+
end
|
26
|
+
|
27
|
+
def cursor=(show)
|
28
|
+
print "\e[?25h" if show
|
29
|
+
print "\e[?25l" unless show
|
30
|
+
$stdout.flush
|
31
|
+
end
|
32
|
+
|
33
|
+
def dirty! pane=nil
|
34
|
+
if pane && @dirty.is_a?(Array) && !(@dirty.include?(pane))
|
35
|
+
@dirty << pane
|
36
|
+
elsif pane && !@dirty
|
37
|
+
@dirty = [pane]
|
38
|
+
elsif !pane
|
39
|
+
@dirty = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle
|
44
|
+
handle_stdin
|
45
|
+
|
46
|
+
size = terminal_size
|
47
|
+
if @width != size[1] || @height != size[0]
|
48
|
+
@width = size[1]
|
49
|
+
@height = size[0]
|
50
|
+
dirty!
|
51
|
+
end
|
52
|
+
|
53
|
+
return unless @dirty
|
54
|
+
redraw @dirty
|
55
|
+
@dirty = false
|
56
|
+
end
|
57
|
+
|
58
|
+
def redraw panes=true
|
59
|
+
print "\e[H\e[J" if panes == true # clear all and go home
|
60
|
+
self.cursor = active_control
|
61
|
+
|
62
|
+
panes = @panes.keys if panes == true
|
63
|
+
|
64
|
+
panes.each do |key|
|
65
|
+
@panes[key].redraw
|
66
|
+
end
|
67
|
+
print "\e[u"
|
68
|
+
|
69
|
+
$stdout.flush
|
70
|
+
end
|
71
|
+
|
72
|
+
def handle_stdin
|
73
|
+
$stdin.read_nonblock(1024).each_char do |chr|
|
74
|
+
active_control.handle_char chr if active_control
|
75
|
+
#~ if chr == "\n"
|
76
|
+
#~ next if @buffer.empty?
|
77
|
+
#~
|
78
|
+
#~ if @buffer.to_i.to_s == @buffer && @results
|
79
|
+
#~ index = @buffer.to_i - 1
|
80
|
+
#~ next if index < 0 || index > @results.size
|
81
|
+
#~
|
82
|
+
#~ song = @results[index]
|
83
|
+
#~ @client.queue << song
|
84
|
+
#~
|
85
|
+
#~ unless @client.now_playing
|
86
|
+
#~ Thread.new do
|
87
|
+
#~ @client.queue.play_radio
|
88
|
+
#~ end
|
89
|
+
#~ end
|
90
|
+
#~
|
91
|
+
#~ @buffer = ''
|
92
|
+
#~ panes[:main].data[0] = @buffer.empty? ? (@search || '') : ''
|
93
|
+
#~ self.cursor = false
|
94
|
+
#~ else
|
95
|
+
#~ @search = @buffer
|
96
|
+
#~ @results = @client.search_songs(@search)['Return']
|
97
|
+
#~ panes[:main].data = @results.map do |result|
|
98
|
+
#~ "#{(@results.index(result)+1).to_s.rjust 2}) #{result['Name']} - #{result['ArtistName']} - #{result['AlbumName']}"
|
99
|
+
#~ end
|
100
|
+
#~ panes[:main].data.unshift @search
|
101
|
+
#~ panes[:main].title = "Search Results for #{@search}"
|
102
|
+
#~
|
103
|
+
#~ @buffer = ''
|
104
|
+
#~ self.cursor = false
|
105
|
+
#~ end
|
106
|
+
#~ else
|
107
|
+
#~ @buffer << chr
|
108
|
+
#~ @buffer.gsub!(/.\177/, '')
|
109
|
+
#~ @buffer.gsub!("\177", '')
|
110
|
+
#~ panes[:main].data[0] = @buffer.empty? ? (@search || '') : ''
|
111
|
+
#~ self.cursor = !(@buffer.empty?)
|
112
|
+
#~ end
|
113
|
+
end
|
114
|
+
|
115
|
+
self.cursor = active_control
|
116
|
+
$stdout.flush
|
117
|
+
|
118
|
+
rescue Errno::EAGAIN
|
119
|
+
rescue EOFError
|
120
|
+
end
|
121
|
+
|
122
|
+
######################################
|
123
|
+
# this is all copied from cashreg :P #
|
124
|
+
######################################
|
125
|
+
|
126
|
+
# yay grep
|
127
|
+
TIOCGWINSZ = 0x5413
|
128
|
+
TCGETS = 0x5401
|
129
|
+
TCSETS = 0x5402
|
130
|
+
ECHO = 8 # 0000010
|
131
|
+
ICANON = 2 # 0000002
|
132
|
+
|
133
|
+
# thanks google for all of this
|
134
|
+
def terminal_size
|
135
|
+
rows, cols = 25, 80
|
136
|
+
buf = [0, 0, 0, 0].pack("SSSS")
|
137
|
+
if $stdout.ioctl(TIOCGWINSZ, buf) >= 0 then
|
138
|
+
rows, cols, row_pixels, col_pixels = buf.unpack("SSSS")
|
139
|
+
end
|
140
|
+
return [rows, cols]
|
141
|
+
end
|
142
|
+
|
143
|
+
# had to convert these from C... fun
|
144
|
+
def prepare_modes
|
145
|
+
buf = [0, 0, 0, 0, 0, 0, ''].pack("IIIICCA*")
|
146
|
+
$stdout.ioctl(TCGETS, buf)
|
147
|
+
@old_modes = buf.unpack("IIIICCA*")
|
148
|
+
new_modes = @old_modes.clone
|
149
|
+
new_modes[3] &= ~ECHO # echo off
|
150
|
+
new_modes[3] &= ~ICANON # one char @ a time
|
151
|
+
$stdout.ioctl(TCSETS, new_modes.pack("IIIICCA*"))
|
152
|
+
self.cursor = false
|
153
|
+
end
|
154
|
+
def undo_modes # restore previous terminal mode
|
155
|
+
$stdout.ioctl(TCSETS, @old_modes.pack("IIIICCA*"))
|
156
|
+
print "\e[2J\e[H" # clear all and go home
|
157
|
+
self.cursor = true # show the mouse
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/lib/luck/label.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Luck
|
2
|
+
class Label < Control
|
3
|
+
attr_accessor :alignment, :text
|
4
|
+
|
5
|
+
def initialize *args
|
6
|
+
@alignment = :left
|
7
|
+
@text = 'Label'
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def align direction
|
12
|
+
@alignment = direction
|
13
|
+
end
|
14
|
+
|
15
|
+
def align_text text
|
16
|
+
case @alignment
|
17
|
+
when :center
|
18
|
+
text.center width
|
19
|
+
when :right
|
20
|
+
text.rjust width
|
21
|
+
else
|
22
|
+
text.ljust width
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def redraw
|
27
|
+
if text.empty?
|
28
|
+
@display.place y1, x1, ' ' * width
|
29
|
+
return
|
30
|
+
end
|
31
|
+
|
32
|
+
row = y1
|
33
|
+
text.each_line do |line|
|
34
|
+
line.chomp!
|
35
|
+
length = line.size
|
36
|
+
offset = 0
|
37
|
+
while offset < width || offset == 0
|
38
|
+
@display.place row, x1, align_text(line[offset, width])
|
39
|
+
row += 1
|
40
|
+
offset += width
|
41
|
+
return if row >= y2
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/luck/listbox.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Luck
|
2
|
+
class ListBox < Control
|
3
|
+
attr_accessor :data, :numbering, :hanging_indent
|
4
|
+
|
5
|
+
def initialize *args
|
6
|
+
@data = []
|
7
|
+
@hanging_indent = 0
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def number!
|
12
|
+
@numbering = true
|
13
|
+
@hanging_indent = 4
|
14
|
+
end
|
15
|
+
|
16
|
+
def redraw
|
17
|
+
row = y1
|
18
|
+
data.first(height).each_with_index do |line, index|
|
19
|
+
line = line.to_s
|
20
|
+
line = "#{(index + 1).to_s.rjust 2}. #{line}" if @numbering
|
21
|
+
length = line.size
|
22
|
+
offset = 0
|
23
|
+
while offset < length || offset == 0
|
24
|
+
@display.place row, x1 + ((offset > 0) ? @hanging_indent : 0), line[offset, width - ((offset > 0) ? @hanging_indent : 0)]
|
25
|
+
row += 1
|
26
|
+
offset += width - ((offset > 0) ? @hanging_indent : 0)
|
27
|
+
break if row >= y2
|
28
|
+
end
|
29
|
+
break if row >= y2
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/luck/pane.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Luck
|
2
|
+
class Pane
|
3
|
+
attr_accessor :display, :x1, :y1, :x2, :y2, :title, :controls
|
4
|
+
|
5
|
+
def initialize display, x1, y1, x2, y2, title, controls={}, &blck
|
6
|
+
@display = display
|
7
|
+
@x1, @y1 = x1, y1
|
8
|
+
@x2, @y2 = x2, y2
|
9
|
+
@title, @controls = title, controls
|
10
|
+
|
11
|
+
instance_eval &blck if blck
|
12
|
+
end
|
13
|
+
|
14
|
+
def control name, type, *args, &blck
|
15
|
+
@controls[name] = type.new(self, *args, &blck)
|
16
|
+
end
|
17
|
+
|
18
|
+
def x1
|
19
|
+
(@x1 < 0) ? (@display.width + @x1 + 1) : @x1
|
20
|
+
end
|
21
|
+
def y1
|
22
|
+
(@y1 < 0) ? (@display.height + @y1 + 1) : @y1
|
23
|
+
end
|
24
|
+
|
25
|
+
def x2
|
26
|
+
(@x2 < 0) ? (@display.width + @x2 + 1) : @x2
|
27
|
+
end
|
28
|
+
def y2
|
29
|
+
(@y2 < 0) ? (@display.height + @y2 + 1) : @y2
|
30
|
+
end
|
31
|
+
|
32
|
+
def width
|
33
|
+
x2 - x1
|
34
|
+
end
|
35
|
+
def height
|
36
|
+
y2 - y1
|
37
|
+
end
|
38
|
+
|
39
|
+
def redraw
|
40
|
+
draw_frame
|
41
|
+
draw_contents
|
42
|
+
end
|
43
|
+
|
44
|
+
def draw_contents
|
45
|
+
controls.each_value do |control|
|
46
|
+
control.redraw
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def topbar
|
51
|
+
title = " * #{@title} * "
|
52
|
+
left = (((width - 1).to_f / 2) - (title.size.to_f / 2)).to_i
|
53
|
+
|
54
|
+
if title.size >= width
|
55
|
+
"#{@display.color '1;34'} #{@title[0, width - 3].center(width - 3)} #{@display.color '0;2'}"
|
56
|
+
else
|
57
|
+
title_colored = "#{@display.color '1;34'}#{title}#{@display.color '0;2'}"
|
58
|
+
('-' * left) + title_colored + ('-' * (width - 1 - title.size - left))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def draw_frame
|
63
|
+
bottombar = '-' * (width - 1)
|
64
|
+
fillerbar = ' ' * (width - 1)
|
65
|
+
|
66
|
+
print @display.color('0;2')
|
67
|
+
@display.place y1, x1, "+#{topbar}+"
|
68
|
+
@display.place y2, x1, "+#{bottombar}+"
|
69
|
+
|
70
|
+
(y1 + 1).upto y2 - 1 do |row|
|
71
|
+
@display.place row, x1, "|#{fillerbar}|"
|
72
|
+
end
|
73
|
+
print @display.color('0')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Luck
|
2
|
+
class ProgressBar < Control
|
3
|
+
attr_accessor :maximum, :value, :precap, :bar, :arrow, :blank, :postcap
|
4
|
+
|
5
|
+
def initialize *args
|
6
|
+
@maximum = 1
|
7
|
+
@value = 0
|
8
|
+
@precap = '['
|
9
|
+
@bar = '='
|
10
|
+
@arrow = '>'
|
11
|
+
@blank = ' '
|
12
|
+
@postcap = ']'
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def percentage
|
17
|
+
@value.to_f / @maximum.to_f
|
18
|
+
end
|
19
|
+
|
20
|
+
def template str
|
21
|
+
@precap, @bar, @arrow, @blank, @postcap = str.unpack 'aaaaa'
|
22
|
+
end
|
23
|
+
|
24
|
+
def redraw
|
25
|
+
@display.place y1, x1, @precap + (@bar * (percentage * (width - @precap.size - @postcap.size)) + @arrow).ljust(width - @precap.size - @postcap.size, @blank) + @postcap
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class DoubleProgressBar < ProgressBar
|
30
|
+
attr_accessor :maximum2, :value2, :bar2, :arrow2
|
31
|
+
|
32
|
+
def initialize *args
|
33
|
+
@maximum2 = 1
|
34
|
+
@value2 = 0
|
35
|
+
@bar2 = '-'
|
36
|
+
@arrow2 = '>'
|
37
|
+
super
|
38
|
+
end
|
39
|
+
|
40
|
+
def percentage2
|
41
|
+
@value2.to_f / @maximum2.to_f
|
42
|
+
end
|
43
|
+
|
44
|
+
def template str
|
45
|
+
@precap, @bar2, @arrow2, @bar, @arrow, @blank, @postcap = str.unpack 'aaaaaaa'
|
46
|
+
end
|
47
|
+
|
48
|
+
def redraw
|
49
|
+
super
|
50
|
+
@display.place y1, x1, @precap + (@bar2 * (percentage2 * (width - @precap.size - @postcap.size)) + @arrow2)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/luck/textbox.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Luck
|
2
|
+
class TextBox < Label
|
3
|
+
attr_accessor :multiline, :handler, :label
|
4
|
+
|
5
|
+
def initialize *args
|
6
|
+
@label = ''
|
7
|
+
@text = 'Input box'
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def redraw
|
12
|
+
super
|
13
|
+
|
14
|
+
case @alignment
|
15
|
+
when :center
|
16
|
+
text.center width
|
17
|
+
when :right
|
18
|
+
text.rjust width
|
19
|
+
else
|
20
|
+
@display.place y1, x1 + text.size, "\e[s"
|
21
|
+
end
|
22
|
+
#print "\e[s" # save
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_submit &blck
|
26
|
+
@handler = blck
|
27
|
+
end
|
28
|
+
|
29
|
+
def text
|
30
|
+
return @text if @label.empty?
|
31
|
+
"#{@label}: #{@text}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_char char
|
35
|
+
if char == "\n" && !@multiline
|
36
|
+
@handler.call @text if @handler
|
37
|
+
@text = ''
|
38
|
+
elsif char == "\177"
|
39
|
+
@text.slice! -1
|
40
|
+
else
|
41
|
+
@text += char
|
42
|
+
end
|
43
|
+
redraw
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/luck.rb
ADDED
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: luck
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Danopia
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-07 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Pure-ruby CLI UI system. Includes multiple panes in a display and multiple controls in a pane. luck is lucky (as opposed to ncurses being cursed)
|
26
|
+
email: me.github@danopia.net
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.md
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- VERSION
|
40
|
+
- lib/luck.rb
|
41
|
+
- lib/luck/control.rb
|
42
|
+
- lib/luck/display.rb
|
43
|
+
- lib/luck/label.rb
|
44
|
+
- lib/luck/listbox.rb
|
45
|
+
- lib/luck/pane.rb
|
46
|
+
- lib/luck/progressbar.rb
|
47
|
+
- lib/luck/textbox.rb
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://github.com/danopia/luck
|
50
|
+
licenses: []
|
51
|
+
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options:
|
54
|
+
- --charset=UTF-8
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.3.5
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Pure-ruby CLI UI system
|
76
|
+
test_files: []
|
77
|
+
|