reterm 0.4.2
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +131 -0
- data/designer/main.rb +10 -0
- data/designer/src/ComponentParams.rb +120 -0
- data/designer/src/ComponentsList.rb +90 -0
- data/designer/src/CreatedList.rb +156 -0
- data/designer/src/Designer.rb +114 -0
- data/designer/src/ToggleArea.rb +67 -0
- data/designer/src/common.rb +1 -0
- data/designer/src/component_factory.rb +30 -0
- data/designer/src/component_map.rb +116 -0
- data/designer/src/glade/ComponentParams.glade +96 -0
- data/designer/src/glade/Designer.glade +184 -0
- data/designer/src/images/add.png +0 -0
- data/designer/src/images/asciitext.png +0 -0
- data/designer/src/images/blank.png +0 -0
- data/designer/src/images/blank_sm.png +0 -0
- data/designer/src/images/button.png +0 -0
- data/designer/src/images/dial.png +0 -0
- data/designer/src/images/entry.png +0 -0
- data/designer/src/images/hslider.png +0 -0
- data/designer/src/images/label.png +0 -0
- data/designer/src/images/matrix.png +0 -0
- data/designer/src/images/orig/Check.png +0 -0
- data/designer/src/images/orig/ascii_text.png +0 -0
- data/designer/src/images/orig/button.png +0 -0
- data/designer/src/images/orig/dial.png +0 -0
- data/designer/src/images/orig/entry.png +0 -0
- data/designer/src/images/orig/hslider.png +0 -0
- data/designer/src/images/orig/label.png +0 -0
- data/designer/src/images/orig/matrix.png +0 -0
- data/designer/src/images/orig/radio.png +0 -0
- data/designer/src/images/orig/rocker.png +0 -0
- data/designer/src/images/orig/slist.png +0 -0
- data/designer/src/images/orig/vslider.png +0 -0
- data/designer/src/images/radio.png +0 -0
- data/designer/src/images/remove.png +0 -0
- data/designer/src/images/rocker.png +0 -0
- data/designer/src/images/slist.png +0 -0
- data/designer/src/images/vslider.png +0 -0
- data/lib/reterm.rb +22 -0
- data/lib/reterm/color_pair.rb +66 -0
- data/lib/reterm/component.rb +40 -0
- data/lib/reterm/components.rb +32 -0
- data/lib/reterm/components/ascii_text.rb +46 -0
- data/lib/reterm/components/button.rb +31 -0
- data/lib/reterm/components/dial.rb +95 -0
- data/lib/reterm/components/dialog.rb +34 -0
- data/lib/reterm/components/entry.rb +38 -0
- data/lib/reterm/components/hslider.rb +32 -0
- data/lib/reterm/components/image.rb +55 -0
- data/lib/reterm/components/label.rb +20 -0
- data/lib/reterm/components/matrix.rb +43 -0
- data/lib/reterm/components/radio.rb +33 -0
- data/lib/reterm/components/rocker.rb +71 -0
- data/lib/reterm/components/slist.rb +32 -0
- data/lib/reterm/components/template.rb +23 -0
- data/lib/reterm/components/vslider.rb +61 -0
- data/lib/reterm/init.rb +95 -0
- data/lib/reterm/layout.rb +63 -0
- data/lib/reterm/layouts.rb +16 -0
- data/lib/reterm/layouts/horizontal.rb +19 -0
- data/lib/reterm/layouts/vertical.rb +19 -0
- data/lib/reterm/loader.rb +126 -0
- data/lib/reterm/menu.rb +81 -0
- data/lib/reterm/mixins/cdk_component.rb +45 -0
- data/lib/reterm/mixins/component_input.rb +37 -0
- data/lib/reterm/mixins/event_dispatcher.rb +20 -0
- data/lib/reterm/mixins/nav_input.rb +126 -0
- data/lib/reterm/panel.rb +37 -0
- data/lib/reterm/resize.rb +27 -0
- data/lib/reterm/terminal.rb +33 -0
- data/lib/reterm/version.rb +3 -0
- data/lib/reterm/window.rb +260 -0
- metadata +155 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Horizontal Slider, implemented using Slider CDK component
|
4
|
+
class HSlider < Component
|
5
|
+
include CDKComponent
|
6
|
+
|
7
|
+
# Initialize the HSlider component
|
8
|
+
#
|
9
|
+
# @param [Hash] args slider params
|
10
|
+
# @option args [String] :title title of slider
|
11
|
+
# @option args [String] :label label of slider
|
12
|
+
def initialize(args={})
|
13
|
+
@title = args[:title] || " "
|
14
|
+
@label = args[:label] || " "
|
15
|
+
|
16
|
+
@increment = 1
|
17
|
+
@range = [0, 100]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def _component
|
23
|
+
CDK::SLIDER.new(window.cdk_scr, # cdkscreen,
|
24
|
+
CDK::CENTER, CDK::CENTER, # xplace, yplace
|
25
|
+
@title, @label, '#'.ord, # title, label, filler,
|
26
|
+
window.cols-6, @range[0], @range[0], # field_width, start, low,
|
27
|
+
@range[1], @increment, @increment*2, # high, inc, fast_inc,
|
28
|
+
false, false) # box, shadow
|
29
|
+
end
|
30
|
+
end # VSlider
|
31
|
+
end # module Components
|
32
|
+
end # module RETerm
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Renders and image to the screen using drawille and chunkpng.
|
4
|
+
class Image < Component
|
5
|
+
|
6
|
+
# Initialize the Image component
|
7
|
+
#
|
8
|
+
# @param [Hash] args image params
|
9
|
+
# @option args [String] :file path to the file containing
|
10
|
+
# the image
|
11
|
+
def initialize(args={})
|
12
|
+
@file = args[:file]
|
13
|
+
end
|
14
|
+
|
15
|
+
def draw!
|
16
|
+
refresh_win
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def canvas
|
22
|
+
require 'drawille'
|
23
|
+
@canvas ||= Drawille::Canvas.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def image
|
27
|
+
require 'chunky_png'
|
28
|
+
@image ||= ChunkyPNG::Image.from_file(@file)
|
29
|
+
end
|
30
|
+
|
31
|
+
def refresh_win
|
32
|
+
w = [image.dimension.width-1, window.cols].min
|
33
|
+
h = [image.dimension.height-1, window.rows].min
|
34
|
+
|
35
|
+
(0..w).each do |x|
|
36
|
+
(0..h).each do |y|
|
37
|
+
r = ChunkyPNG::Color.r(image[x,y])
|
38
|
+
g = ChunkyPNG::Color.g(image[x,y])
|
39
|
+
b = ChunkyPNG::Color.b(image[x,y])
|
40
|
+
canvas.set(x, y) if (r + b + g) > 100
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
y = 1
|
45
|
+
canvas.frame.split("\n").each { |line|
|
46
|
+
window.mvaddstr(y, 1, line)
|
47
|
+
y += 1
|
48
|
+
}
|
49
|
+
|
50
|
+
window.refresh
|
51
|
+
update_reterm
|
52
|
+
end
|
53
|
+
end # class Canvas
|
54
|
+
end # module Components
|
55
|
+
end # module RETerm
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Simply renders text to window
|
4
|
+
class Label < Component
|
5
|
+
|
6
|
+
# Initialize the Label component
|
7
|
+
#
|
8
|
+
# @param [Hash] args label params
|
9
|
+
# @option args [String] :text text of button
|
10
|
+
def initialize(args={})
|
11
|
+
@text = args[:text] || ""
|
12
|
+
end
|
13
|
+
|
14
|
+
def draw!
|
15
|
+
window.mvaddstr(1, 1, @text)
|
16
|
+
update_reterm
|
17
|
+
end
|
18
|
+
end # Label
|
19
|
+
end # module Components
|
20
|
+
end # module RETerm
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# CDK Matrix Component
|
4
|
+
class Matrix < Component
|
5
|
+
include CDKComponent
|
6
|
+
|
7
|
+
# Initialize the Matrix component
|
8
|
+
#
|
9
|
+
# @param [Hash] args matrix params
|
10
|
+
def initialize(args={})
|
11
|
+
@rows = args[:rows]
|
12
|
+
@cols = args[:cols]
|
13
|
+
@title = args[:title]
|
14
|
+
|
15
|
+
@rowtitles = args[:rowtitles] || args[:row_titles] || Array.new(@rows) { "" }
|
16
|
+
@coltitles = args[:coltitles] || args[:col_titles] || Array.new(@cols+1) { "" }
|
17
|
+
@colwidths = args[:colwidths] || args[:col_widths] || Array.new(@cols+1) { 5 }
|
18
|
+
@coltypes = args[:coltypes] || args[:col_types] || Array.new(@cols+1) { :UMIXED }
|
19
|
+
end
|
20
|
+
|
21
|
+
def get(x, y)
|
22
|
+
component.getCell(x, y)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def _component
|
28
|
+
CDK::MATRIX.new(window.cdk_scr,
|
29
|
+
2, 2, # xpos, ypos
|
30
|
+
@rows, @cols, # matrix rows, cols
|
31
|
+
[(window.rows - 2), @rows].min, # screen rows
|
32
|
+
[(window.cols - 2), @cols].min, # screen cols
|
33
|
+
@title, # title
|
34
|
+
@rowtitles, @coltitles, # row/col titles
|
35
|
+
@colwidths, @coltypes, # col widths and types
|
36
|
+
-1, -1, # row/col spacing
|
37
|
+
'.', # filler
|
38
|
+
2, # dominant attribute
|
39
|
+
true, true, false) # box matrix, box cell, shadow
|
40
|
+
end
|
41
|
+
end # Matrix
|
42
|
+
end # module Components
|
43
|
+
end # module RETerm
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# CDK Radio Component
|
4
|
+
class Radio < Component
|
5
|
+
include CDKComponent
|
6
|
+
|
7
|
+
# Initialize the Radio component
|
8
|
+
#
|
9
|
+
# @param [Hash] args radio params
|
10
|
+
# @option args [String] :title title of radio
|
11
|
+
# @option args [Array<String>] :items items to
|
12
|
+
# populate radio with
|
13
|
+
def initialize(args={})
|
14
|
+
@title = args[:title] || ""
|
15
|
+
@items = args[:items] || []
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def _component
|
21
|
+
CDK::RADIO.new(window.cdk_scr, # cdkscreen,
|
22
|
+
2, 1, CDK::RIGHT, # xplace, yplace, scroll pos
|
23
|
+
window.rows - 2, # widget height
|
24
|
+
window.cols - 2, # widget width
|
25
|
+
@title, @items, @items.size, # title and items
|
26
|
+
'#'.ord | Ncurses::A_REVERSE, # choice char
|
27
|
+
true, # default item
|
28
|
+
Ncurses::A_REVERSE, # highlight
|
29
|
+
true, false) # box, shadow
|
30
|
+
end
|
31
|
+
end # Radio
|
32
|
+
end # module Components
|
33
|
+
end # module RETerm
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Rocker component, allowing use to select one of several values
|
4
|
+
class Rocker < Component
|
5
|
+
include ComponentInput
|
6
|
+
|
7
|
+
attr_accessor :values, :index, :labels
|
8
|
+
|
9
|
+
# Initialize the Rocker component
|
10
|
+
#
|
11
|
+
# @param [Hash] args rocker params
|
12
|
+
#
|
13
|
+
# @example using the Rocker
|
14
|
+
# win = Window.new
|
15
|
+
# rocker = Rocker.new
|
16
|
+
# win.component = rocker
|
17
|
+
# rocker.values = ['Foo', 'Bar', 'Baz']
|
18
|
+
# val = rocker.activate!
|
19
|
+
#
|
20
|
+
def initialize(args={})
|
21
|
+
@values = []
|
22
|
+
@index = nil
|
23
|
+
@labels = true
|
24
|
+
@index = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def draw!
|
28
|
+
refresh_win
|
29
|
+
end
|
30
|
+
|
31
|
+
def activatable?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def activate!
|
36
|
+
refresh_win
|
37
|
+
handle_input
|
38
|
+
@values[@index]
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def on_inc
|
44
|
+
@index += 1
|
45
|
+
@index = @values.size - 1 if @index == @values.size
|
46
|
+
refresh_win
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_dec
|
50
|
+
@index -= 1
|
51
|
+
@index = 0 if @index < 0
|
52
|
+
refresh_win
|
53
|
+
end
|
54
|
+
|
55
|
+
def refresh_win
|
56
|
+
pre = post = ' '
|
57
|
+
pre = '-' if @labels
|
58
|
+
post = '+' if @labels
|
59
|
+
|
60
|
+
window.mvaddstr(1, 1, " |#{pre}|")
|
61
|
+
@values.each_with_index { |v, i|
|
62
|
+
sel = @index == i ? "#" : " "
|
63
|
+
window.mvaddstr(i+2, 1, " |" + sel + "|" + @values[i])
|
64
|
+
}
|
65
|
+
window.mvaddstr(@values.size+2, 1, " |#{post}|")
|
66
|
+
window.refresh
|
67
|
+
update_reterm
|
68
|
+
end
|
69
|
+
end # Rocker
|
70
|
+
end # module Components
|
71
|
+
end # module RETerm
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Scrolling List CDK Component
|
4
|
+
class SList < Component
|
5
|
+
include CDKComponent
|
6
|
+
|
7
|
+
# Initialize the SList component
|
8
|
+
#
|
9
|
+
# @param [Hash] args list params
|
10
|
+
# @option args [String] :title title of list
|
11
|
+
# @option args [Array<String>] :items items to
|
12
|
+
# populate list with
|
13
|
+
def initialize(args={})
|
14
|
+
@title = args[:title] || ""
|
15
|
+
@items = args[:items] || []
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def _component
|
21
|
+
CDK::SCROLL.new(window.cdk_scr, # cdkscreen,
|
22
|
+
2, 1, CDK::RIGHT, # xplace, yplace, scroll pos
|
23
|
+
window.rows - 2, # widget height
|
24
|
+
window.cols - 2, # widget width
|
25
|
+
@title, @items, @items.size, # title and items
|
26
|
+
false, # prefix numbers
|
27
|
+
Ncurses::A_REVERSE, # highlight
|
28
|
+
true, false) # box, shadow
|
29
|
+
end
|
30
|
+
end # SList
|
31
|
+
end # module Components
|
32
|
+
end # module RETerm
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Template which may be used as the basis for other components
|
4
|
+
class Template < Component
|
5
|
+
# All components must accept args hash (specified via loader)
|
6
|
+
def initialize(args={})
|
7
|
+
end
|
8
|
+
|
9
|
+
# Override this method to draw component on screen
|
10
|
+
def draw!
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return true if the user should be able to focus and
|
14
|
+
# interact with this component, default to false
|
15
|
+
def activatable?
|
16
|
+
end
|
17
|
+
|
18
|
+
# Method call when this component is activated
|
19
|
+
def activate!
|
20
|
+
end
|
21
|
+
end # class Template
|
22
|
+
end # module Components
|
23
|
+
end # module RETerm
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RETerm
|
2
|
+
module Components
|
3
|
+
# Vertical Slider Component
|
4
|
+
class VSlider < Component
|
5
|
+
include ComponentInput
|
6
|
+
|
7
|
+
attr_accessor :initial_value, :increment, :range, :labels
|
8
|
+
|
9
|
+
# Initialize the slider component
|
10
|
+
#
|
11
|
+
# @param [Hash] args slider params
|
12
|
+
def initialize(args={})
|
13
|
+
@initial_value = 0
|
14
|
+
@increment = 0.01
|
15
|
+
@range = [0, 1]
|
16
|
+
@labels = true
|
17
|
+
@value = initial_value
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw!
|
21
|
+
refresh_win
|
22
|
+
end
|
23
|
+
|
24
|
+
def activatable?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def activate!
|
29
|
+
refresh_win
|
30
|
+
handle_input
|
31
|
+
(range[1] - range[0]) * @value
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def on_inc
|
37
|
+
@value += increment
|
38
|
+
@value = 1 if @value > 1
|
39
|
+
refresh_win
|
40
|
+
end
|
41
|
+
|
42
|
+
def on_dec
|
43
|
+
@value -= increment
|
44
|
+
@value = 0 if @value < 0
|
45
|
+
refresh_win
|
46
|
+
end
|
47
|
+
|
48
|
+
def refresh_win
|
49
|
+
0.upto(window.rows) do |l|
|
50
|
+
pre = " "
|
51
|
+
pre = "+" if @labels && l == 0
|
52
|
+
pre = "-" if @labels && l == (window.rows-1)
|
53
|
+
fill = (l.to_f / window.rows) >= (1-@value)
|
54
|
+
window.mvaddstr(l, 0, pre + (fill ? "#" : " ") + "\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
window.refresh
|
58
|
+
end
|
59
|
+
end # VSlider
|
60
|
+
end # module Components
|
61
|
+
end # module RETerm
|
data/lib/reterm/init.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'ncursesw'
|
2
|
+
require_relative './resize'
|
3
|
+
|
4
|
+
module RETerm
|
5
|
+
# Initializes the RETerm subsystem before invoking block.
|
6
|
+
# After block is finished regardless of execution state
|
7
|
+
# (return, exception, etc) this will cleanup the terminal
|
8
|
+
# environment before returning control to the TTY.
|
9
|
+
#
|
10
|
+
# This method is the first method the user should invoke
|
11
|
+
# after requiring the reterm library.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# init_reterm {
|
15
|
+
# win = Window.new :rows => 20, :cols => 40
|
16
|
+
# # ... more UI logic
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
def init_reterm(opts={}, &bl)
|
20
|
+
begin
|
21
|
+
Terminal.load # XXX: not sure why but loading terminal
|
22
|
+
# info after changing terminal settings via
|
23
|
+
# ncurses seems to corrupt the terminal
|
24
|
+
# state to the point it cannot be restored
|
25
|
+
# without a 'reset' (see below).
|
26
|
+
# So just preload terminal info here.
|
27
|
+
|
28
|
+
stdscr = Ncurses::initscr
|
29
|
+
Ncurses::start_color
|
30
|
+
Ncurses::noecho
|
31
|
+
Ncurses::cbreak
|
32
|
+
Ncurses::curs_set(0)
|
33
|
+
Ncurses::keypad(stdscr, true)
|
34
|
+
|
35
|
+
track_resize if opts[:resize]
|
36
|
+
|
37
|
+
bl.call
|
38
|
+
|
39
|
+
#ensure
|
40
|
+
stop_track_resize
|
41
|
+
Ncurses.curs_set(1)
|
42
|
+
Window.all.each { |w| w.finalize! }
|
43
|
+
CDK::SCREEN.endCDK if cdk_enabled?
|
44
|
+
Ncurses.endwin()
|
45
|
+
#`reset -Q` # XXX only way to guarantee a full reset (see above)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# This method resyncs the visible terminal with the internal
|
50
|
+
# RETerm environment. It should be called any time the user
|
51
|
+
# needs to update the UI after making changes.
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# init_reterm {
|
55
|
+
# win = Window.new
|
56
|
+
# win.border! # draw window border
|
57
|
+
# update_rti # resync terminal ouput
|
58
|
+
# win.getch # wait for input
|
59
|
+
# }
|
60
|
+
#
|
61
|
+
def update_reterm
|
62
|
+
Window.top.each { |w| w.refresh }
|
63
|
+
Ncurses::Panel.update_panels
|
64
|
+
Ncurses.doupdate
|
65
|
+
end
|
66
|
+
|
67
|
+
# XXX Ncurses is exposed so that users
|
68
|
+
# may employ any constants if desired.
|
69
|
+
# This should not be needed though and
|
70
|
+
# is discouraged to maintain portability
|
71
|
+
NC = Ncurses
|
72
|
+
|
73
|
+
# Enable the CDK subsystem. Used by CDKbased components
|
74
|
+
#
|
75
|
+
# @see #cdk_enabled?
|
76
|
+
def enable_cdk!
|
77
|
+
return if @cdk_enabled
|
78
|
+
|
79
|
+
@cdk_enabled = true
|
80
|
+
require 'cdk'
|
81
|
+
|
82
|
+
# XXX defines standard color pairs, but we use our own
|
83
|
+
# for standarization across components, but we need
|
84
|
+
# to set cdk components to the correct color scheme
|
85
|
+
# manually
|
86
|
+
# CDK::Draw.initCDKColor
|
87
|
+
end
|
88
|
+
|
89
|
+
# Return boolean indicating if the CDK subsystem is enabled.
|
90
|
+
# CDK is a library used by various components providing
|
91
|
+
# many various ready to use ncurses widgets.
|
92
|
+
def cdk_enabled?
|
93
|
+
!!@cdk_enabled
|
94
|
+
end
|
95
|
+
end # module RETerm
|