reterm 0.4.2 → 0.5.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.
- checksums.yaml +4 -4
- data/designer/src/ComponentParams.rb +89 -42
- data/designer/src/ComponentsList.rb +26 -25
- data/designer/src/CreatedList.rb +9 -0
- data/designer/src/Designer.rb +23 -1
- data/designer/src/ToggleArea.rb +20 -3
- data/designer/src/about.rb +35 -0
- data/designer/src/component_factory.rb +18 -0
- data/designer/src/component_map.rb +7 -0
- data/designer/src/file_chooser.rb +25 -0
- data/designer/src/glade/Designer.glade +1 -19
- data/designer/src/images/{slist.png → scroll_list.png} +0 -0
- data/lib/reterm.rb +10 -1
- data/lib/reterm/color_pair.rb +166 -10
- data/lib/reterm/component.rb +89 -2
- data/lib/reterm/components.rb +16 -1
- data/lib/reterm/components/alphalist.rb +45 -0
- data/lib/reterm/components/ascii_text.rb +14 -1
- data/lib/reterm/components/asciimator.rb +1 -0
- data/lib/reterm/components/button.rb +35 -5
- data/lib/reterm/components/button_box.rb +108 -0
- data/lib/reterm/components/close_button.rb +22 -0
- data/lib/reterm/components/cmd_output.rb +69 -0
- data/lib/reterm/components/dial.rb +11 -2
- data/lib/reterm/components/dialog.rb +41 -1
- data/lib/reterm/components/drop_down_menu.rb +140 -0
- data/lib/reterm/components/entry.rb +42 -14
- data/lib/reterm/components/histogram.rb +55 -0
- data/lib/reterm/components/hslider.rb +9 -0
- data/lib/reterm/components/image.rb +9 -0
- data/lib/reterm/components/isometric.rb +38 -0
- data/lib/reterm/components/label.rb +20 -3
- data/lib/reterm/components/matrix.rb +9 -0
- data/lib/reterm/components/multi_line_entry.rb +54 -0
- data/lib/reterm/components/password_entry.rb +15 -0
- data/lib/reterm/components/radio.rb +10 -0
- data/lib/reterm/components/revealing_label.rb +126 -0
- data/lib/reterm/components/rocker.rb +21 -11
- data/lib/reterm/components/scroll_list.rb +96 -0
- data/lib/reterm/components/scrolling_area.rb +50 -0
- data/lib/reterm/components/select_list.rb +67 -0
- data/lib/reterm/components/splash.rb +85 -0
- data/lib/reterm/components/template.rb +12 -1
- data/lib/reterm/components/treeview.rb +1 -0
- data/lib/reterm/components/vslider.rb +11 -2
- data/lib/reterm/components/youtube.rb +20 -0
- data/lib/reterm/config.rb +22 -0
- data/lib/reterm/init.rb +131 -6
- data/lib/reterm/layout.rb +147 -11
- data/lib/reterm/layouts.rb +1 -0
- data/lib/reterm/layouts/grid.rb +69 -0
- data/lib/reterm/layouts/horizontal.rb +25 -4
- data/lib/reterm/layouts/vertical.rb +26 -5
- data/lib/reterm/loader.rb +2 -2
- data/lib/reterm/mixins/button_helpers.rb +7 -0
- data/lib/reterm/mixins/cdk_component.rb +66 -2
- data/lib/reterm/mixins/common_controls.rb +15 -0
- data/lib/reterm/mixins/common_keys.rb +20 -0
- data/lib/reterm/mixins/component_input.rb +62 -14
- data/lib/reterm/mixins/event_dispatcher.rb +2 -0
- data/lib/reterm/mixins/item_helpers.rb +8 -0
- data/lib/reterm/mixins/key_bindings.rb +23 -0
- data/lib/reterm/mixins/log_helpers.rb +13 -0
- data/lib/reterm/mixins/mouse_input.rb +58 -0
- data/lib/reterm/mixins/nav_controls.rb +33 -0
- data/lib/reterm/mixins/nav_input.rb +161 -69
- data/lib/reterm/terminal.rb +6 -2
- data/lib/reterm/util.rb +121 -0
- data/lib/reterm/version.rb +1 -1
- data/lib/reterm/window.rb +295 -29
- metadata +33 -17
- 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/lib/reterm/components/slist.rb +0 -32
- data/lib/reterm/menu.rb +0 -81
@@ -1,19 +1,40 @@
|
|
1
1
|
module RETerm
|
2
2
|
module Layouts
|
3
|
-
# Layout which
|
3
|
+
# Layout which arainges items horizontally across screen cols
|
4
4
|
class Horizontal < Layout
|
5
|
+
def current_rows
|
6
|
+
return 1 if empty?
|
7
|
+
child_windows.max { |w1, w2| w1.rows <=> w2.rows }.rows
|
8
|
+
end
|
9
|
+
|
5
10
|
def current_cols
|
6
|
-
|
11
|
+
return 1 if empty?
|
12
|
+
child_windows.sum { |c| c.cols } + 1
|
7
13
|
end
|
8
14
|
|
9
|
-
def
|
10
|
-
|
15
|
+
def exceeds_bounds_with?(child)
|
16
|
+
rows = child.is_a?(Hash) ?
|
17
|
+
[current_rows, child[:rows]].compact.max :
|
18
|
+
[current_rows, child.rows].max
|
19
|
+
|
20
|
+
cols = child.is_a?(Hash) ?
|
21
|
+
current_cols + child[:cols] :
|
22
|
+
current_cols + child.cols
|
23
|
+
|
24
|
+
rows > window.rows ||
|
25
|
+
cols > window.cols
|
11
26
|
end
|
12
27
|
|
13
28
|
def add_child(h={})
|
14
29
|
# set x/y to next appropriate location
|
15
30
|
super(h.merge(:y => 1, :x => current_cols))
|
16
31
|
end
|
32
|
+
|
33
|
+
def valid_input?(ch, from_parent)
|
34
|
+
return true unless from_parent
|
35
|
+
!((UP_CONTROLS.include?(ch) && window.first_child?) ||
|
36
|
+
(DOWN_CONTROLS.include?(ch) && window.last_child?))
|
37
|
+
end
|
17
38
|
end # class Horizontal
|
18
39
|
end # module Layouts
|
19
40
|
end # module RETerm
|
@@ -1,19 +1,40 @@
|
|
1
1
|
module RETerm
|
2
2
|
module Layouts
|
3
|
-
# Layout which
|
3
|
+
# Layout which arainges items vertically down screen rows
|
4
4
|
class Vertical < Layout
|
5
5
|
def current_rows
|
6
|
-
|
6
|
+
return 1 if empty?
|
7
|
+
child_windows.sum { |c| c.rows } + 1
|
7
8
|
end
|
8
9
|
|
9
|
-
def
|
10
|
-
|
10
|
+
def current_cols
|
11
|
+
return 1 if empty?
|
12
|
+
child_windows.max { |w1, w2| w1.cols <=> w2.cols }.cols
|
13
|
+
end
|
14
|
+
|
15
|
+
def exceeds_bounds_with?(child)
|
16
|
+
cols = child.is_a?(Hash) ?
|
17
|
+
[current_cols, child[:cols]].compact.max :
|
18
|
+
[current_cols, child.cols].max
|
19
|
+
|
20
|
+
rows = child.is_a?(Hash) ?
|
21
|
+
current_rows + child[:rows] :
|
22
|
+
current_rows + child.rows
|
23
|
+
|
24
|
+
cols > window.cols ||
|
25
|
+
rows > window.rows
|
11
26
|
end
|
12
27
|
|
13
28
|
def add_child(h={})
|
14
29
|
# set x/y to next appropriate location
|
15
30
|
super(h.merge(:y => current_rows, :x => 1))
|
16
31
|
end
|
17
|
-
|
32
|
+
|
33
|
+
def valid_input?(ch, from_parent)
|
34
|
+
return true unless from_parent
|
35
|
+
!((LEFT_CONTROLS.include?(ch) && window.first_child?) ||
|
36
|
+
(RIGHT_CONTROLS.include?(ch) && window.last_child?))
|
37
|
+
end
|
38
|
+
end # class Vertical
|
18
39
|
end # module Layouts
|
19
40
|
end # module RETerm
|
data/lib/reterm/loader.rb
CHANGED
@@ -49,7 +49,7 @@ module RETerm
|
|
49
49
|
parse_child(w, win)
|
50
50
|
|
51
51
|
w.border! if win.key?('border') && !!win['border']
|
52
|
-
w.colors = ColorPair.for(win['colors']) if win.key?('colors')
|
52
|
+
w.colors = ColorPair.for(win['colors']).first if win.key?('colors')
|
53
53
|
|
54
54
|
w
|
55
55
|
end
|
@@ -113,7 +113,7 @@ module RETerm
|
|
113
113
|
:cols => cols
|
114
114
|
|
115
115
|
cw.border! if child.key?('border') && !!child['border']
|
116
|
-
cw.colors = ColorPair.for(child['colors']) if child.key?('colors')
|
116
|
+
cw.colors = ColorPair.for(child['colors']).first if child.key?('colors')
|
117
117
|
|
118
118
|
cw.component = parse_child(cw, child)
|
119
119
|
}
|
@@ -1,6 +1,20 @@
|
|
1
1
|
module RETerm
|
2
2
|
# Mixin used by CDK based component defining cdk-specific helpers
|
3
3
|
module CDKComponent
|
4
|
+
def init_cdk(args={})
|
5
|
+
self.title_attrib = args[:title_attrib] if args.key?(:title_attrib)
|
6
|
+
end
|
7
|
+
|
8
|
+
def title_attrib=(a)
|
9
|
+
@title_attrib = a
|
10
|
+
component.title_attrib = a if defined?(@component)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Boolean indicating this component is a cdk component
|
14
|
+
def cdk?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
4
18
|
# Should be implemented in subclass to initialize component
|
5
19
|
def _component
|
6
20
|
raise "NotImplemented"
|
@@ -12,10 +26,28 @@ module RETerm
|
|
12
26
|
@component ||= begin
|
13
27
|
c = _component
|
14
28
|
c.setBackgroundColor("</#{@colors.id}>") if colored?
|
29
|
+
c.timeout(SYNC_TIMEOUT) if sync_enabled? # XXX
|
30
|
+
c.title_attrib = @title_attrib if @title_attrib
|
15
31
|
c
|
16
32
|
end
|
17
33
|
end
|
18
34
|
|
35
|
+
# Return boolean indicating if escape was hit
|
36
|
+
def escape_hit?
|
37
|
+
component.exit_type == :ESCAPE_HIT
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return boolean indicating early exit occurred
|
41
|
+
def early_exit?
|
42
|
+
component.exit_type == :EARLY_EXIT
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return boolean indicating if user selection made / normal
|
46
|
+
# exit was invoked
|
47
|
+
def normal_exit?
|
48
|
+
component.exit_type == :NORMAL
|
49
|
+
end
|
50
|
+
|
19
51
|
# Assign {ColorPair} to component
|
20
52
|
def colors=(c)
|
21
53
|
super
|
@@ -27,19 +59,51 @@ module RETerm
|
|
27
59
|
component.draw([])
|
28
60
|
end
|
29
61
|
|
62
|
+
def erase
|
63
|
+
component.erase
|
64
|
+
end
|
65
|
+
|
30
66
|
# CDK components may be activated
|
31
67
|
def activatable?
|
32
68
|
true
|
33
69
|
end
|
34
70
|
|
35
71
|
# Invoke CDK activation routine
|
36
|
-
def activate!
|
37
|
-
|
72
|
+
def activate!(*input)
|
73
|
+
dispatch :activated
|
74
|
+
component.resetExitType
|
75
|
+
|
76
|
+
r = nil
|
77
|
+
|
78
|
+
while [:EARLY_EXIT, :NEVER_ACTIVATED, :TIMEOUT].include?(component.exit_type) &&
|
79
|
+
!shutdown?
|
80
|
+
r = component.activate(input)
|
81
|
+
run_sync! if sync_enabled?
|
82
|
+
end
|
83
|
+
|
84
|
+
dispatch :deactivated
|
85
|
+
r
|
86
|
+
end
|
87
|
+
|
88
|
+
def deactivate!
|
89
|
+
component.activate [CDK::KEY_ESC]
|
90
|
+
dispatch :deactivated
|
38
91
|
end
|
39
92
|
|
40
93
|
# Return stored value of cdk component
|
41
94
|
def value
|
42
95
|
component.getValue
|
43
96
|
end
|
97
|
+
|
98
|
+
# Override bind_key to use cdk bindings mechanism
|
99
|
+
def bind_key(key, kcb=nil, &bl)
|
100
|
+
kcb = bl if kcb.nil? && !bl.nil?
|
101
|
+
|
102
|
+
cb = lambda do |cdktype, widget, component, key|
|
103
|
+
kcb.call component, key
|
104
|
+
end
|
105
|
+
|
106
|
+
component.bind(:ENTRY, key, cb, self)
|
107
|
+
end
|
44
108
|
end # module CDKComponent
|
45
109
|
end # module RETerm
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RETerm
|
2
|
+
# XXX copied from CDK
|
3
|
+
module CommonControls
|
4
|
+
attr_reader :quit_on_enter
|
5
|
+
|
6
|
+
def quit_on_enter=(v)
|
7
|
+
@quit_on_enter_set = true
|
8
|
+
@quit_on_enter = v
|
9
|
+
end
|
10
|
+
|
11
|
+
def quit_on_enter?
|
12
|
+
@quit_on_enter_set ? @quit_on_enter : true
|
13
|
+
end
|
14
|
+
end # module CommonControls
|
15
|
+
end # module CDK
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RETerm
|
2
|
+
module CommonKeys
|
3
|
+
# Key which if pressed cause the component to
|
4
|
+
# lose focus / become deactivated
|
5
|
+
QUIT_CONTROLS = [10, 27, Ncurses::KEY_ENTER] # 10 = enter, 27 = ESC,
|
6
|
+
|
7
|
+
# \033 = CDK::KEY_ESC
|
8
|
+
# 343 = NCURSES::KEY_ENTER
|
9
|
+
|
10
|
+
ENTER_CONTROLS = [10, Ncurses::KEY_ENTER] # quit controls with out esc
|
11
|
+
|
12
|
+
# Keys if pressed invoked the increment operation
|
13
|
+
INC_CONTROLS = ['+'.ord, Ncurses::KEY_UP, Ncurses::KEY_RIGHT]
|
14
|
+
|
15
|
+
# Keys if pressed invoked the decrement operation
|
16
|
+
DEC_CONTROLS = ['-'.ord, Ncurses::KEY_DOWN, Ncurses::KEY_LEFT]
|
17
|
+
|
18
|
+
# TODO add page/scroll controls
|
19
|
+
end # module CommonKeys
|
20
|
+
end # module CDK
|
@@ -3,35 +3,83 @@ module RETerm
|
|
3
3
|
# components. 'In House' components included in the project
|
4
4
|
# may used this to standarding their usage.
|
5
5
|
module ComponentInput
|
6
|
-
|
7
|
-
|
8
|
-
QUIT_CONTROLS = [10, 27] # 10 = enter, 27 = ESC
|
6
|
+
include CommonControls
|
7
|
+
include CommonKeys
|
9
8
|
|
10
|
-
#
|
11
|
-
|
9
|
+
# TODO include / incorporate MouseInput mixin
|
10
|
+
# (scroll sliders/dials, click buttons, etc) ...
|
12
11
|
|
13
|
-
#
|
14
|
-
DEC_CONTROLS = ['-'.ord, Ncurses::KEY_DOWN, Ncurses::KEY_LEFT]
|
15
|
-
|
16
|
-
# May be overrideen in subclass, invoked when the user requests
|
12
|
+
# May be overridden in subclass, invoked when the user requests
|
17
13
|
# an 'increment'
|
18
14
|
def on_inc
|
19
15
|
end
|
20
16
|
|
21
|
-
# May be
|
17
|
+
# May be overridden in subclass, invoked when the user
|
22
18
|
# requests a decrement
|
23
19
|
def on_dec
|
24
20
|
end
|
25
21
|
|
22
|
+
# May be overridden in subclass, invoked when the user inputs
|
23
|
+
# the enter key (unless quit_on_enter is true)
|
24
|
+
def on_enter
|
25
|
+
end
|
26
|
+
|
27
|
+
# May be overridden in subclass, invoked with every key entered
|
28
|
+
def on_key(ch)
|
29
|
+
end
|
30
|
+
|
26
31
|
# Helper to be internally invoked by component on activation
|
27
|
-
def handle_input
|
28
|
-
while
|
29
|
-
|
32
|
+
def handle_input(*input)
|
33
|
+
while ch = next_ch(input)
|
34
|
+
quit = QUIT_CONTROLS.include?(ch)
|
35
|
+
enter = ENTER_CONTROLS.include?(ch)
|
36
|
+
inc = INC_CONTROLS.include?(ch)
|
37
|
+
dec = DEC_CONTROLS.include?(ch)
|
38
|
+
|
39
|
+
break if shutdown? ||
|
40
|
+
(quit && (!enter || quit_on_enter?))
|
41
|
+
|
42
|
+
if enter
|
43
|
+
on_enter
|
44
|
+
|
45
|
+
elsif inc
|
30
46
|
on_inc
|
31
|
-
|
47
|
+
|
48
|
+
elsif dec
|
32
49
|
on_dec
|
33
50
|
end
|
51
|
+
|
52
|
+
if key_bound?(ch)
|
53
|
+
invoke_key_bindings(ch)
|
54
|
+
end
|
55
|
+
|
56
|
+
on_key(ch)
|
34
57
|
end
|
58
|
+
|
59
|
+
ch
|
60
|
+
end
|
61
|
+
|
62
|
+
def bind_key(key, kcb)
|
63
|
+
@bound_keys ||= {}
|
64
|
+
@bound_keys[key] ||= []
|
65
|
+
@bound_keys[key] << kcb
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def key_bound?(key)
|
70
|
+
@bound_keys ||= {}
|
71
|
+
@bound_keys.key?(key)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def next_ch(input)
|
77
|
+
return sync_getch if input.empty?
|
78
|
+
input.shift
|
79
|
+
end
|
80
|
+
|
81
|
+
def invoke_key_bindings(key)
|
82
|
+
@bound_keys[key].each { |b| b.call self, key }
|
35
83
|
end
|
36
84
|
end # module ComponentInput
|
37
85
|
end # module RETerm
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RETerm
|
2
|
+
# Similar to the bindings mixin in the CDK library
|
3
|
+
module KeyBindings
|
4
|
+
def key_bindings
|
5
|
+
@key_bindings ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def bind_key(key, kcb=nil, &bl)
|
9
|
+
key_bindings[key] ||= []
|
10
|
+
kcb = bl if kcb.nil? && !bl.nil?
|
11
|
+
key_bindings[key] << kcb
|
12
|
+
end
|
13
|
+
|
14
|
+
def key_bound?(key)
|
15
|
+
key_bindings.key?(key)
|
16
|
+
end
|
17
|
+
|
18
|
+
def invoke_key_bindings(key)
|
19
|
+
o = self
|
20
|
+
key_bindings[key].all? { |kcb| kcb.call(o, key) }
|
21
|
+
end
|
22
|
+
end # module ButtonBindings
|
23
|
+
end # module RETerm
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module RETerm
|
2
|
+
module MouseInput
|
3
|
+
ALL_EVENTS = Ncurses::ALL_MOUSE_EVENTS |
|
4
|
+
Ncurses::REPORT_MOUSE_POSITION
|
5
|
+
|
6
|
+
MOUSE_MAP = {
|
7
|
+
:PRESSED => :pressed,
|
8
|
+
:RELEASED => :released,
|
9
|
+
:CLICKED => :click,
|
10
|
+
:DOUBLE_CLICKED => :dclick,
|
11
|
+
:TRIPLE_CLICKED => :tclick,
|
12
|
+
}
|
13
|
+
|
14
|
+
def mouse_paste?
|
15
|
+
!!reterm_opts[:mouse_paste]
|
16
|
+
end
|
17
|
+
|
18
|
+
# May be overridden in subclass, invoked when
|
19
|
+
# the user interacts with a button.
|
20
|
+
#
|
21
|
+
# @param [Integer] b number of the button that was invoked
|
22
|
+
# @param [Symbol] evnt button event, may be :press, :release,
|
23
|
+
# :click, :dclick (double click), :tclick (triple click)
|
24
|
+
def on_button(b, evnt, coords)
|
25
|
+
#puts "B#{b} #{evnt}, #{coords}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def process_mouse(ch)
|
29
|
+
return nil unless ch == Ncurses::KEY_MOUSE
|
30
|
+
|
31
|
+
mev = Ncurses::MEVENT.new
|
32
|
+
Ncurses.getmouse(mev)
|
33
|
+
|
34
|
+
if mev.bstate == Ncurses::BUTTON2_CLICKED && mouse_paste?
|
35
|
+
# TODO grab clipboard buffer & return character array
|
36
|
+
# (need to handle seperately in invoker)
|
37
|
+
#
|
38
|
+
# use https://github.com/janlelis/clipboard
|
39
|
+
# but note this requires external programs!
|
40
|
+
end
|
41
|
+
|
42
|
+
# TODO 5 button support (requiest "--enable-ext-mouse" ncurses flag
|
43
|
+
# which is not specified in many major distrubtions)
|
44
|
+
1.upto(4).each { |b|
|
45
|
+
MOUSE_MAP.each { |n, e|
|
46
|
+
if mev.bstate == Ncurses.const_get("BUTTON#{b}_#{n}")
|
47
|
+
x,y,z = mev.x, mev.y, mev.z
|
48
|
+
on_button(b, e, [x,y,z])
|
49
|
+
end
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
# TODO wrap MEVENT w/ our own class,
|
54
|
+
# w/ high levels helpers for buttons, coords, etc
|
55
|
+
mev
|
56
|
+
end
|
57
|
+
end # module MouseInput
|
58
|
+
end # module RETerm
|