luck 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|