rbcurse-core 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.md +20 -3
- data/VERSION +1 -1
- data/examples/abasiclist.rb +29 -2
- data/examples/alpmenu.rb +4 -4
- data/examples/dbdemo.rb +1 -0
- data/examples/dirtree.rb +1 -0
- data/examples/tabular.rb +16 -2
- data/examples/tasks.rb +15 -4
- data/examples/term2.rb +2 -1
- data/examples/testkeypress.rb +1 -1
- data/examples/testlistbox.rb +7 -0
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/core/include/appmethods.rb +94 -0
- data/lib/rbcurse/core/include/listbindings.rb +3 -1
- data/lib/rbcurse/core/include/listscrollable.rb +3 -1
- data/lib/rbcurse/core/include/vieditable.rb +2 -2
- data/lib/rbcurse/core/system/ncurses.rb +5 -0
- data/lib/rbcurse/core/system/window.rb +16 -4
- data/lib/rbcurse/core/util/app.rb +8 -2
- data/lib/rbcurse/core/util/basestack.rb +2 -3
- data/lib/rbcurse/core/util/rdialogs.rb +28 -3
- data/lib/rbcurse/core/util/widgetshortcuts.rb +2 -1
- data/lib/rbcurse/core/widgets/applicationheader.rb +6 -6
- data/lib/rbcurse/core/widgets/keylabelprinter.rb +19 -3
- data/lib/rbcurse/core/widgets/rwidget.rb +177 -10
- data/lib/rbcurse/core/widgets/statusline.rb +17 -2
- data/rbcurse-core.gemspec +3 -3
- metadata +10 -5
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
**2012-01- **
|
2
|
+
## 0.0.4 rbcurse-core
|
3
|
+
* added RESIZE event to form, so resizing app components is possible
|
4
|
+
when window/terminal is resized
|
5
|
+
* changes to ncurses setting as a result of above (wtimeout commented off)
|
6
|
+
* Moving help system to Form
|
7
|
+
* minor addition of define_prefix_command to Form - experimental
|
8
|
+
|
1
9
|
**2012-01-04**
|
2
10
|
## 0.0.3 rbcurse-core
|
3
11
|
* ActionManager added to widgets so actions can be
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# rbcurse-core
|
2
2
|
|
3
|
+
** Working on 1.9.3 **
|
4
|
+
|
3
5
|
Contains core widgets and infrastructure of rbcurse ncurses toolkit. rbcurse helps to easily build
|
4
6
|
ncurses application for text terminals.
|
5
7
|
|
@@ -37,6 +39,12 @@ Core intends to be :
|
|
37
39
|
|
38
40
|
* simple, maintainable code
|
39
41
|
|
42
|
+
## Testing Status
|
43
|
+
|
44
|
+
* Working on 1.9.3-p392 (environment is zsh 5.0.x, tmux, TERM=screen-256color, OSX ML)
|
45
|
+
|
46
|
+
## Other
|
47
|
+
|
40
48
|
I shall be standardizing core over the next one or two minor versions. I shall also be simplifying code as much as possible to make it maintainable and more bug-free.
|
41
49
|
|
42
50
|
Method names in some classes may change, and one or two widget names will change. rbasiclistbox will become listbox while the old listbox that has moved to extras will become something like editlistbox. Similarly the old table will become edittable in extras, whereas tabularwidget will becoming table in core.
|
@@ -58,16 +66,25 @@ the core a bit more. The code lies on github.
|
|
58
66
|
|
59
67
|
`gem install rbcurse` # the core, extra and experimental stuff
|
60
68
|
|
61
|
-
##
|
69
|
+
## Examples
|
62
70
|
|
63
|
-
|
71
|
+
Some examples have dependencies.
|
72
|
+
|
73
|
+
* dbdemo requires sqlite3 gem (and sqlite).
|
74
|
+
* testlistbox require ri documentation
|
75
|
+
`rvm docs generate-ri`
|
76
|
+
I have improved this demo and released it as the gem 'ribhu' (ri browser).
|
77
|
+
|
78
|
+
## See also
|
64
79
|
|
65
80
|
* rbcurse-extras - <http://github.com/rkumar/rbcurse-extras/>
|
66
81
|
|
67
82
|
* rbcurse-experimental - <http://github.com/rkumar/rbcurse-experimental/>
|
68
83
|
|
84
|
+
* rbcurse - <http://github.com/rkumar/rbcurse/>
|
85
|
+
|
69
86
|
## License
|
70
87
|
|
71
88
|
Same as ruby license.
|
72
89
|
|
73
|
-
(c) copyright rkumar, 2008-
|
90
|
+
(c) copyright rkumar, 2008-2013.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/examples/abasiclist.rb
CHANGED
@@ -119,13 +119,39 @@ App.new do
|
|
119
119
|
res ||= "Error in command [#{cmd}] [#{name}] "
|
120
120
|
textdialog( res, :title => cmd ) if res
|
121
121
|
end
|
122
|
+
# handle resizing, sadly I am not sure flow and stack can do a resize, i am sure the xperimental one can.
|
123
|
+
def resize
|
124
|
+
lb1 = @form.by_name["lb1"]
|
125
|
+
lb2 = @form.by_name["lb2"]
|
126
|
+
maxc = Ncurses.COLS
|
127
|
+
maxr = Ncurses.LINES
|
128
|
+
lb1.height = maxr-2
|
129
|
+
lb2.height = maxr-2
|
130
|
+
lb1.width = ((lb1.width_pc * maxc) / 100).floor
|
131
|
+
lb2.width = ((lb2.width_pc * maxc) / 100).floor
|
132
|
+
lb2.col = lb1.col + lb1.width
|
133
|
+
lab = @form.by_name["lab"]
|
134
|
+
lab.row = maxr-1
|
135
|
+
end
|
122
136
|
|
123
137
|
colors = Ncurses.COLORS
|
124
138
|
back = :blue
|
125
139
|
back = 234 if colors >= 256
|
126
140
|
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Basic List Demo", :text_right =>"New Improved!", :color => :white, :bgcolor => back #, :attr => :bold
|
127
141
|
message "Press F10 to escape from here"
|
128
|
-
install_help_text my_help_text
|
142
|
+
#install_help_text my_help_text
|
143
|
+
@form.help_manager.help_text = my_help_text
|
144
|
+
|
145
|
+
@form.define_prefix_command :csmap, :scope => self
|
146
|
+
#@form.define_key(:csmap, "r", 'refresh') { refresh }
|
147
|
+
@form.define_key(:csmap, "r", 'refresh', :refresh )
|
148
|
+
@form.define_key(:csmap, "s", 'specification') { specification }
|
149
|
+
@form.bind_key ?\C-s, :csmap
|
150
|
+
#pm = PrefixCommand.new :csmap, self do |p|
|
151
|
+
#p.key("r", 'refresh', :refresh )
|
152
|
+
#p.key("s", 'specification'){ specification }
|
153
|
+
#end
|
154
|
+
#@form.bind_key(?\C-x){ pm.call }
|
129
155
|
|
130
156
|
alist = File.open("data/brew.txt",'r').readlines
|
131
157
|
list2 = File.open("data/gemlist.txt",'r').readlines
|
@@ -141,8 +167,9 @@ App.new do
|
|
141
167
|
end
|
142
168
|
|
143
169
|
|
144
|
-
label({:text => "F1 Help, F10 Quit. : for menu. Press F4 and F5 to test popup, space or enter to select", :row => Ncurses.LINES-1, :col => 0})
|
170
|
+
label({:text => "F1 Help, F10 Quit. : for menu. Press F4 and F5 to test popup, space or enter to select", :row => Ncurses.LINES-1, :col => 0, :name => 'lab'})
|
145
171
|
|
172
|
+
@form.bind(:RESIZE) { resize() }
|
146
173
|
@form.bind_key(FFI::NCurses::KEY_F4) { row = lb.current_index+lb.row; col=lb.col+lb.current_value.length+1; ret = popuplist(%w[ andy berlioz strauss tchaiko matz beethoven], :row => row, :col => col, :title => "Names", :bgcolor => :blue, :color => :white) ; alert "got #{ret} "}
|
147
174
|
|
148
175
|
@form.bind_key(FFI::NCurses::KEY_F5) { list = %x[ls].split("\n");ret = popuplist(list, :title => "Files"); alert "Got #{ret} #{list[ret]} " }
|
data/examples/alpmenu.rb
CHANGED
@@ -8,24 +8,24 @@ require 'rbcurse/core/util/app'
|
|
8
8
|
stack :margin_top => 10, :margin_left => 15 do
|
9
9
|
#w = "Messages".length + 1
|
10
10
|
w = 60
|
11
|
-
menulink :text => "&View
|
11
|
+
menulink :text => "&View Dirs", :width => w, :description => "View Dirs in tree" do |s|
|
12
12
|
message "Pressed #{s.text} "
|
13
13
|
load './dirtree.rb'
|
14
14
|
#require './viewtodo'; todo = ViewTodo::TodoApp.new; todo.run
|
15
15
|
end
|
16
16
|
blank
|
17
|
-
menulink :text => "&
|
17
|
+
menulink :text => "&Tabular", :width => w, :description => "Tabula Rasa" do |s|
|
18
18
|
message "Pressed #{s.text} "
|
19
19
|
load './tabular.rb'
|
20
20
|
#require './testtodo'; todo = TestTodo::TodoApp.new; todo.run
|
21
21
|
end
|
22
22
|
blank
|
23
|
-
menulink :text => "&Messages", :width => w, :description => "View
|
23
|
+
menulink :text => "&Messages", :width => w, :description => "View Tasks" do |s|
|
24
24
|
message "Pressed #{s.text} "
|
25
25
|
load './tasks.rb'
|
26
26
|
end
|
27
27
|
blank
|
28
|
-
menulink :text => "&
|
28
|
+
menulink :text => "&Database", :width => w, :description => "Database Demo" do |s|
|
29
29
|
message "Pressed #{s.getvalue} "
|
30
30
|
load './dbdemo.rb'
|
31
31
|
end
|
data/examples/dbdemo.rb
CHANGED
data/examples/dirtree.rb
CHANGED
@@ -21,6 +21,7 @@ App.new do
|
|
21
21
|
end
|
22
22
|
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Yet Another Dir Lister", :text_right =>"Directory Lister" , :color => :white, :bgcolor => :black #, :attr => Ncurses::A_BLINK
|
23
23
|
message "Press Enter to expand/collapse, <space> to view in lister. <F1> Help"
|
24
|
+
@form.help_manager.help_text = help_text()
|
24
25
|
|
25
26
|
pwd = Dir.getwd
|
26
27
|
entries = _directories pwd
|
data/examples/tabular.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rbcurse/core/util/app'
|
2
2
|
|
3
3
|
App.new do
|
4
|
+
# TODO: combine this with widget menu
|
4
5
|
def app_menu
|
5
6
|
menu = PromptMenu.new self do
|
6
7
|
item :e, :edit
|
@@ -107,18 +108,30 @@ def _edit h, row, title
|
|
107
108
|
row[i] = f.text
|
108
109
|
}
|
109
110
|
row
|
111
|
+
end
|
112
|
+
def resize
|
113
|
+
tab = @form.by_name["tab"]
|
114
|
+
cols = Ncurses.COLS
|
115
|
+
rows = Ncurses.LINES
|
116
|
+
tab.width_pc ||= (1.0*tab.width / $orig_cols)
|
117
|
+
tab.height_pc ||= (1.0*tab.height / $orig_rows)
|
118
|
+
tab.height = (tab.height_pc * rows).floor
|
119
|
+
tab.width = (tab.width_pc * cols).floor
|
110
120
|
end
|
111
121
|
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Tabular Demo", :text_right =>"Fat-free !",
|
112
122
|
:color => :black, :bgcolor => :green #, :attr => :bold
|
113
123
|
message "Press F10 to exit, F1 for help, : for menu"
|
124
|
+
@form.help_manager.help_text = help_text()
|
125
|
+
$orig_cols = Ncurses.COLS
|
126
|
+
$orig_rows = Ncurses.LINES
|
114
127
|
|
115
128
|
h = %w[ Id Title Priority Status]
|
116
129
|
file = "data/table.txt"
|
117
130
|
lines = File.open(file,'r').readlines
|
118
131
|
arr = []
|
119
132
|
lines.each { |l| arr << l.split("|") }
|
120
|
-
flow :margin_top => 1, :height => FFI::NCurses.LINES-
|
121
|
-
tw = tabular_widget :print_footer => true
|
133
|
+
flow :margin_top => 1, :height => FFI::NCurses.LINES-2 do
|
134
|
+
tw = tabular_widget :print_footer => true, :name => "tab"
|
122
135
|
tw.columns = h
|
123
136
|
tw.column_align 0, :right
|
124
137
|
tw.set_content arr
|
@@ -129,4 +142,5 @@ end
|
|
129
142
|
end # stack
|
130
143
|
status_line :row => FFI::NCurses.LINES-1
|
131
144
|
@form.bind_key(?:, 'menu') { app_menu }
|
145
|
+
@form.bind(:RESIZE) { resize }
|
132
146
|
end # app
|
data/examples/tasks.rb
CHANGED
@@ -23,15 +23,25 @@ class CellRenderer
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
App.new do
|
26
|
+
def resize
|
27
|
+
tab = @form.by_name["tasklist"]
|
28
|
+
cols = Ncurses.COLS
|
29
|
+
rows = Ncurses.LINES
|
30
|
+
tab.width_pc ||= (1.0*tab.width / $orig_cols)
|
31
|
+
tab.height_pc ||= (1.0*tab.height / $orig_rows)
|
32
|
+
tab.height = (tab.height_pc * rows).floor
|
33
|
+
tab.width = (tab.width_pc * cols).floor
|
34
|
+
#$log.debug "XXX: RESIZE h w #{tab.height} , #{tab.width} "
|
35
|
+
end
|
26
36
|
@default_prefix = " "
|
27
37
|
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Task List", :text_right =>"New Improved!"
|
28
38
|
|
29
|
-
message "Press F10 or qq to
|
39
|
+
message "Press F10 or qq to quit "
|
30
40
|
|
31
41
|
file = "data/todo.txt"
|
32
42
|
alist = File.open(file,'r').readlines if File.exists? file
|
33
43
|
#flow :margin_top => 1, :item_width => 50 , :height => FFI::NCurses.LINES-2 do
|
34
|
-
stack :margin_top => 1, :width => :expand, :height => FFI::NCurses.LINES-4 do
|
44
|
+
#stack :margin_top => 1, :width => :expand, :height => FFI::NCurses.LINES-4 do
|
35
45
|
|
36
46
|
#task = field :label => " Task:", :display_length => 50, :maxlen => 80, :bgcolor => :cyan, :color => :black
|
37
47
|
#pri = field :label => "Priority:", :display_length => 1, :maxlen => 1, :type => :integer,
|
@@ -39,7 +49,7 @@ App.new do
|
|
39
49
|
#pri.overwrite_mode = true
|
40
50
|
# u,se voerwrite mode for this TODO and catch exception
|
41
51
|
|
42
|
-
lb = listbox :list => alist.sort, :title => "[ todos ]", :
|
52
|
+
lb = listbox :list => alist.sort, :title => "[ todos ]", :name => "tasklist", :row => 1, :height => Ncurses.LINES-4, :width => Ncurses.COLS-1
|
43
53
|
lb.should_show_focus = false
|
44
54
|
lb.cell_renderer CellRenderer.new
|
45
55
|
lb.bind_key(?d, "Delete Row"){
|
@@ -132,8 +142,9 @@ App.new do
|
|
132
142
|
lb.list(lb.list.sort)
|
133
143
|
end
|
134
144
|
}
|
135
|
-
end # stack
|
145
|
+
#end # stack
|
136
146
|
s = status_line
|
147
|
+
@form.bind(:RESIZE) { resize }
|
137
148
|
|
138
149
|
keyarray = [
|
139
150
|
["F1" , "Help"], ["F10" , "Exit"],
|
data/examples/term2.rb
CHANGED
@@ -26,7 +26,8 @@ require 'rbcurse/core/widgets/scrollbar'
|
|
26
26
|
App.new do
|
27
27
|
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Tabular Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
|
28
28
|
message "F10 quit, F1 Help, ? Bindings"
|
29
|
-
install_help_text my_help_text
|
29
|
+
#install_help_text my_help_text
|
30
|
+
@form.help_manager.help_text = my_help_text
|
30
31
|
|
31
32
|
flow :width => FFI::NCurses.COLS , :height => FFI::NCurses.LINES-2 do
|
32
33
|
stack :margin_top => 1, :width_pc => 20 do
|
data/examples/testkeypress.rb
CHANGED
@@ -49,7 +49,7 @@ if $0 == __FILE__
|
|
49
49
|
@form.repaint
|
50
50
|
@window.wrefresh
|
51
51
|
Ncurses::Panel.update_panels
|
52
|
-
while((ch = @window.getchar()) !=
|
52
|
+
while((ch = @window.getchar()) != 0 )
|
53
53
|
str = keycode_tos ch
|
54
54
|
$log.debug "#{ch} got (#{str})"
|
55
55
|
texta << "#{ch} got (#{str})"
|
data/examples/testlistbox.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# NOTE: If the listbox is empty, that could mean that you have not generated
|
2
|
+
# ri documentation for this version of ruby. You can do so by doing:
|
3
|
+
# rvm docs generate-ri
|
4
|
+
# or
|
5
|
+
# rvm docs generate
|
6
|
+
# (This assumes you are using rvm)
|
7
|
+
#
|
1
8
|
# WARNING : IF THIS PROGRAM HANGS check the ri command
|
2
9
|
# Maybe your version of ri has different options and is going interactive.
|
3
10
|
# ruby 1.9.3's ri requires a -l option or else if becomes interactive.
|
data/lib/rbcurse.rb
CHANGED
@@ -116,5 +116,99 @@ module RubyCurses
|
|
116
116
|
return ret
|
117
117
|
end
|
118
118
|
end # utils
|
119
|
+
class PrefixCommand
|
120
|
+
attr_accessor :object
|
121
|
+
def initialize _symbol, calling, config={}, &block
|
122
|
+
@object = calling
|
123
|
+
@symbol = _symbol
|
124
|
+
@descriptions = {}
|
125
|
+
define_prefix_command _symbol
|
126
|
+
yield self if block_given?
|
127
|
+
end
|
128
|
+
def define_prefix_command _name, config={}
|
129
|
+
$rb_prefix_map ||= {}
|
130
|
+
#h = {}
|
131
|
+
#@map = h
|
132
|
+
_name = _name.to_sym unless _name.is_a? Symbol
|
133
|
+
# TODO it may already exist, so retrieve it
|
134
|
+
$rb_prefix_map[_name] ||= {}
|
135
|
+
@map = $rb_prefix_map[_name]
|
136
|
+
# create a variable by name _name
|
137
|
+
# create a method by same name to use
|
138
|
+
@object.instance_eval %{
|
139
|
+
def #{_name.to_s} *args
|
140
|
+
h = $rb_prefix_map["#{_name}".to_sym]
|
141
|
+
raise "No prefix_map named #{_name}, #{$rb_prefix_map.keys} " unless h
|
142
|
+
ch = @window.getchar
|
143
|
+
if ch
|
144
|
+
res = h[ch]
|
145
|
+
if res.is_a? Proc
|
146
|
+
res.call
|
147
|
+
else
|
148
|
+
send(res) if res
|
149
|
+
end
|
150
|
+
else
|
151
|
+
0
|
152
|
+
end
|
153
|
+
end
|
154
|
+
}
|
155
|
+
return _name
|
156
|
+
end
|
157
|
+
def call
|
158
|
+
h = @map
|
159
|
+
ch = @object.window.getch # dicey.
|
160
|
+
$log.debug "XXX: CALLED #{ch} "
|
161
|
+
if ch
|
162
|
+
if ch == KEY_F1
|
163
|
+
text = ["Options are: "]
|
164
|
+
h.keys.each { |e| c = keycode_tos(e); text << " #{c} #{@descriptions[e]} " }
|
165
|
+
textdialog text, :title => " #{@symbol} key bindings "
|
166
|
+
return
|
167
|
+
end
|
168
|
+
res = h[ch]
|
169
|
+
if res.is_a? Proc
|
170
|
+
res.call
|
171
|
+
elsif res.is_a? Symbol
|
172
|
+
@object.send(res) if res
|
173
|
+
else
|
174
|
+
Ncurses.beep
|
175
|
+
@object.window.ungetch(ch)
|
176
|
+
|
177
|
+
:UNHANDLED
|
178
|
+
end
|
179
|
+
else
|
180
|
+
raise "got nothing"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# define a key within a prefix key map such as C-x
|
185
|
+
# Now that i am moving this from global, how will describe bindings get hold of the bindings
|
186
|
+
# and descriptions
|
187
|
+
def define_key _keycode, *args, &blk
|
188
|
+
_symbol = @symbol
|
189
|
+
h = $rb_prefix_map[_symbol]
|
190
|
+
raise ArgumentError, "No such keymap #{_symbol} defined. Use define_prefix_command." unless h
|
191
|
+
_keycode = _keycode[0].getbyte(0) if _keycode[0].class == String
|
192
|
+
arg = args.shift
|
193
|
+
if arg.is_a? String
|
194
|
+
desc = arg
|
195
|
+
arg = args.shift
|
196
|
+
elsif arg.is_a? Symbol
|
197
|
+
# its a symbol
|
198
|
+
desc = arg.to_s
|
199
|
+
elsif arg.nil?
|
200
|
+
desc = "unknown"
|
201
|
+
else
|
202
|
+
raise ArgumentError, "Don't know how to handle #{arg.class} in PrefixManager"
|
203
|
+
end
|
204
|
+
@descriptions[_keycode] = desc
|
205
|
+
|
206
|
+
if !block_given?
|
207
|
+
blk = arg
|
208
|
+
end
|
209
|
+
h[_keycode] = blk
|
210
|
+
end
|
211
|
+
alias :key :define_key
|
212
|
+
end
|
119
213
|
end # module RubyC
|
120
214
|
include RubyCurses::Utils
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# Author: rkumar http://github.com/rkumar/rbcurse/
|
5
5
|
# Date: 2011-12-11 - 12:58
|
6
6
|
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
7
|
-
# Last update:
|
7
|
+
# Last update: 2013-03-04 17:52
|
8
8
|
# ----------------------------------------------------------------------------- #
|
9
9
|
#
|
10
10
|
module RubyCurses
|
@@ -42,6 +42,8 @@ module RubyCurses
|
|
42
42
|
# some of these will not have effect in textarea such as j k, gg and G, search
|
43
43
|
bind_key(?j, 'next row'){ next_row() }
|
44
44
|
bind_key(?k, 'previous row'){ previous_row() }
|
45
|
+
## added 2013-03-04 - 17:52
|
46
|
+
bind_key(?w, 'forward_word'){ forward_word }
|
45
47
|
bind_key(?\C-d, 'scroll forward'){ scroll_forward() }
|
46
48
|
bind_key(?\C-b, 'scroll backward'){ scroll_backward() }
|
47
49
|
bind_key([?g,?g], 'goto start'){ goto_start } # mapping double keys like vim
|
@@ -455,7 +455,9 @@ module ListScrollable
|
|
455
455
|
return unless buff
|
456
456
|
pos = @curpos || 0 # list does not have curpos
|
457
457
|
$multiplier.times {
|
458
|
-
found = buff.index(/[[:punct:][:space:]]
|
458
|
+
#found = buff.index(/[[:punct:][:space:]]+/, pos)
|
459
|
+
# 2013-03-04 - 17:35 modified so it skips spaces and puncts
|
460
|
+
found = buff.index(/[[:punct:][:space:]]\w/, pos)
|
459
461
|
if !found
|
460
462
|
# if not found, we've lost a counter
|
461
463
|
if line+1 < @list.length
|
@@ -34,7 +34,7 @@ module ViEditable
|
|
34
34
|
bind_key( [?y, ?y] , :kill_ring_save )
|
35
35
|
bind_key( ?p, :yank ) # paste after this line
|
36
36
|
bind_key( ?P ) { yank(@current_index - 1) } # should be before this line
|
37
|
-
bind_key(
|
37
|
+
bind_key(?w, :forward_word)
|
38
38
|
bind_key(?f, :forward_char)
|
39
39
|
bind_key(?\M-y, :yank_pop)
|
40
40
|
bind_key(?\M-w, :kill_ring_save)
|
@@ -61,7 +61,7 @@ module ViEditable
|
|
61
61
|
#bind_key( ?P ) { yank(@current_index - 1) } # should be before this line
|
62
62
|
# seems -1 was pasting 2 lines before
|
63
63
|
bind_key( ?P ) { yank(@current_index - 0) } # should be before this line
|
64
|
-
bind_key(
|
64
|
+
bind_key(?w, :forward_word)
|
65
65
|
bind_key(?\M-y, :yank_pop)
|
66
66
|
bind_key(?\C-y, :yank)
|
67
67
|
bind_key(?\M-w, :kill_ring_save)
|
@@ -100,6 +100,11 @@ module VER
|
|
100
100
|
# I am disableing this 2011-12-20 since it does not work with combinations
|
101
101
|
# such as gg. Any routine that does a getch will just immediatelt return an ERR.
|
102
102
|
#Ncurses::nodelay(stdscr.pointer, bf = true)
|
103
|
+
|
104
|
+
# added these 2 so we can do resizing based on original and current size when terminal resized
|
105
|
+
# 2012-01-8
|
106
|
+
$orig_cols = FFI::NCurses.COLS
|
107
|
+
$orig_rows = FFI::NCurses.LINES
|
103
108
|
end
|
104
109
|
|
105
110
|
# this should happen only in outermost program that started ncurses
|
@@ -83,7 +83,8 @@ module VER
|
|
83
83
|
# 2011-12-20 half-delay crashes system as does cbreak
|
84
84
|
#This causes us to be unable to process gg qq since getch won't wait.
|
85
85
|
#Ncurses::nodelay(@window, bf = true)
|
86
|
-
|
86
|
+
# wtimeout was causing RESIZE sigwinch to only happen after pressing a key
|
87
|
+
#Ncurses::wtimeout(@window, $ncurses_timeout || 500) # will wait a second on wgetch so we can get gg and qq
|
87
88
|
@stack = []
|
88
89
|
@name ||="#{self}"
|
89
90
|
@modified = true
|
@@ -247,19 +248,20 @@ module VER
|
|
247
248
|
# is 0
|
248
249
|
def print_empty_line
|
249
250
|
return unless visible?
|
250
|
-
w =
|
251
|
+
w = getmaxx == 0? Ncurses.COLS : getmaxx
|
251
252
|
printw(' ' * w)
|
252
253
|
end
|
253
254
|
|
254
255
|
# NOTE: many of these methods using width will not work since root windows width
|
255
256
|
# is 0
|
256
257
|
def print_line(string)
|
257
|
-
w =
|
258
|
+
w = getmaxx == 0? Ncurses.COLS : getmaxx
|
258
259
|
print(string.ljust(w))
|
259
260
|
end
|
260
261
|
|
261
262
|
# returns the actual width in case you've used a root window
|
262
263
|
# which returns a 0 for wid and ht
|
264
|
+
# NOTE: this does not work when resize , use getmaxx instead
|
263
265
|
#
|
264
266
|
def actual_width
|
265
267
|
width == 0? Ncurses.COLS : width
|
@@ -334,6 +336,15 @@ module VER
|
|
334
336
|
def getch
|
335
337
|
#c = @window.getch
|
336
338
|
c = FFI::NCurses.wgetch(@window)
|
339
|
+
# the only reason i am doing this is so ESC can be returned if no key is pressed
|
340
|
+
# after that, not sure how this effects everything. most likely I should just
|
341
|
+
# go back to using a wtimeout, and not worry about resize requiring a keystroke
|
342
|
+
if c == 27
|
343
|
+
Ncurses::wtimeout(@window, $ncurses_timeout || 500) # will wait a second on wgetch so we can get gg and qq
|
344
|
+
else
|
345
|
+
Ncurses::nowtimeout(@window, true)
|
346
|
+
end
|
347
|
+
c
|
337
348
|
# 2011-12-20 - i am trying setting a timer on wgetch, see timeout
|
338
349
|
#c = FFI::NCurses.getch # this will keep waiting, nodelay won't be used on it, since
|
339
350
|
# we've put nodelay on window
|
@@ -662,7 +673,8 @@ module VER
|
|
662
673
|
#
|
663
674
|
def printstring_formatted_right(r,c,content, color, att = Ncurses::A_NORMAL)
|
664
675
|
clean = content.gsub /#\[[^\]]*\]/,'' # clean out all markup
|
665
|
-
c = actual_width() - clean.length
|
676
|
+
#c = actual_width() - clean.length # actual width not working if resize
|
677
|
+
c = getmaxx() - clean.length
|
666
678
|
printstring_formatted(r,c,content, color, att )
|
667
679
|
end
|
668
680
|
|
@@ -383,7 +383,8 @@ module RubyCurses
|
|
383
383
|
# Actually, this is naive, you would want to pass some values in like current data value
|
384
384
|
# or lines ??
|
385
385
|
# Also may want command completion, or help so all commands can be displayed
|
386
|
-
|
386
|
+
# NOTE: This is gonna change very soon - 2012-01-8
|
387
|
+
def get_command_from_user choices=["quit","help", "suspend", "shell_output"]
|
387
388
|
@_command_history ||= Array.new
|
388
389
|
str = rb_gets("Cmd: ", choices) { |q| q.default = @_previous_command; q.history = @_command_history }
|
389
390
|
@_command_history << str unless @_command_history.include? str
|
@@ -966,10 +967,15 @@ module RubyCurses
|
|
966
967
|
# this is a very rudimentary default command executer, it does not
|
967
968
|
# allow tab completion. App should use M-x with names of commands
|
968
969
|
# as in appgmail
|
970
|
+
# NOTE: This is gonna change very soon - 2012-01-8
|
969
971
|
@form.bind_key(?:, 'prompt') {
|
970
972
|
str = get_command_from_user
|
971
973
|
}
|
972
974
|
|
975
|
+
# this M-x stuff has to be moved out so it can be used by all. One should be able
|
976
|
+
# to add_commands properly to this, and to C-x. I am thinking how to go about this,
|
977
|
+
# and what function M-x actually serves.
|
978
|
+
|
973
979
|
@form.bind_key(?\M-x, 'M-x commands'){
|
974
980
|
# TODO previous command to be default
|
975
981
|
opts = get_all_commands()
|
@@ -1008,7 +1014,7 @@ module RubyCurses
|
|
1008
1014
|
end
|
1009
1015
|
end
|
1010
1016
|
}
|
1011
|
-
|
1017
|
+
#@form.bind_key(KEY_F1, 'help'){ display_app_help } # NOT REQUIRED NOW 2012-01-7 since form does it
|
1012
1018
|
@form.bind_key([?q,?q], 'quit' ){ throw :close } if $log.debug?
|
1013
1019
|
|
1014
1020
|
#@message = Variable.new
|
@@ -322,7 +322,6 @@ module RubyCurses
|
|
322
322
|
end
|
323
323
|
# module level
|
324
324
|
private
|
325
|
-
private
|
326
325
|
def _add s
|
327
326
|
if @active.empty?
|
328
327
|
$log.debug "XXX: ADDING TO components #{s} "
|
@@ -337,7 +336,6 @@ module RubyCurses
|
|
337
336
|
end
|
338
337
|
|
339
338
|
# module level
|
340
|
-
private
|
341
339
|
public
|
342
340
|
def stack config={}, &block
|
343
341
|
_stack :stack, config, &block
|
@@ -383,7 +381,8 @@ module RubyCurses
|
|
383
381
|
@ctr -= 1
|
384
382
|
end
|
385
383
|
# module level
|
386
|
-
private
|
384
|
+
#private
|
385
|
+
public
|
387
386
|
# given an widget, return the item, so we can change weight or some other config
|
388
387
|
def item_for widget
|
389
388
|
each do |e|
|
@@ -445,8 +445,14 @@ def longest_in_list list #:nodoc:
|
|
445
445
|
end
|
446
446
|
longest
|
447
447
|
end
|
448
|
+
# would like to deprecate this and use
|
449
|
+
# @form.help_manager.help_text = text
|
448
450
|
def install_help_text text
|
449
451
|
@_help_text = text
|
452
|
+
if @form
|
453
|
+
hm = @form.help_manager
|
454
|
+
hm.help_text = text
|
455
|
+
end
|
450
456
|
end
|
451
457
|
# this routine prints help_text for an application
|
452
458
|
# If help_text has been set using install_help_text
|
@@ -455,7 +461,25 @@ end
|
|
455
461
|
# user may use <next> to see general help.
|
456
462
|
#
|
457
463
|
# earlier in app.rb
|
458
|
-
def display_app_help
|
464
|
+
def display_app_help form=@form
|
465
|
+
if form
|
466
|
+
hm = form.help_manager
|
467
|
+
if !hm.help_text
|
468
|
+
arr = nil
|
469
|
+
# these 2 only made sense from app.rb and should be removed, too implicit
|
470
|
+
if respond_to? :help_text
|
471
|
+
arr = help_text
|
472
|
+
elsif @_help_text
|
473
|
+
arr = @_help_text
|
474
|
+
end
|
475
|
+
hm.help_text(arr) if arr
|
476
|
+
end
|
477
|
+
form.help_manager.display_help
|
478
|
+
else
|
479
|
+
raise "Form needed by display_app_help. Use form.help_manager instead"
|
480
|
+
end
|
481
|
+
end
|
482
|
+
def ORIGdisplay_app_help
|
459
483
|
filename = File.dirname(__FILE__) + "/../docs/index.txt"
|
460
484
|
# defarr contains default help
|
461
485
|
if File.exists?(filename)
|
@@ -467,13 +491,14 @@ def display_app_help
|
|
467
491
|
arr << " --- General help --- "
|
468
492
|
arr << " F10 - exit application "
|
469
493
|
arr << " Alt-x - select commands "
|
470
|
-
arr << " :
|
494
|
+
arr << " : (or M-:) - select commands "
|
495
|
+
arr << " ? (or M-?) - current widget key bindings "
|
471
496
|
arr << " "
|
472
497
|
defarr = arr
|
473
498
|
end
|
474
499
|
defhelp = true
|
475
500
|
if respond_to? :help_text
|
476
|
-
arr = help_text
|
501
|
+
arr = help_text()
|
477
502
|
defhelp = false
|
478
503
|
elsif @_help_text
|
479
504
|
arr = @_help_text
|
@@ -264,18 +264,19 @@ module RubyCurses
|
|
264
264
|
return w
|
265
265
|
end
|
266
266
|
alias :table :tabular_widget
|
267
|
+
# NOTE UNTESTED
|
267
268
|
def vimsplit config={}, &block
|
268
269
|
require 'rbcurse/extras/widgets/rvimsplit'
|
269
270
|
#TODO check these
|
270
271
|
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
271
272
|
block_event = nil
|
272
273
|
config[:height] ||= 10
|
273
|
-
_position(w)
|
274
274
|
# if no width given, expand to flows width
|
275
275
|
#config.delete :title
|
276
276
|
useform = nil
|
277
277
|
|
278
278
|
w = VimSplit.new useform, config # NO BLOCK GIVEN
|
279
|
+
_position(w)
|
279
280
|
if block_given?
|
280
281
|
#@current_object << w
|
281
282
|
#instance_eval &block if block_given?
|
@@ -28,6 +28,7 @@ module RubyCurses
|
|
28
28
|
|
29
29
|
def initialize form, text1, config={}, &block
|
30
30
|
|
31
|
+
@name = "header"
|
31
32
|
@text1 = text1
|
32
33
|
# setting default first or else Widget will place its BW default
|
33
34
|
@color, @bgcolor = ColorMap.get_colors_for_pair $bottomcolor
|
@@ -82,18 +83,17 @@ module RubyCurses
|
|
82
83
|
end
|
83
84
|
def print_center(htext, r = 0, c = 0)
|
84
85
|
win = @window
|
85
|
-
len = win.
|
86
|
-
len = Ncurses.COLS-0 if len == 0
|
86
|
+
len = win.getmaxx
|
87
|
+
len = Ncurses.COLS-0 if len == 0 || len > Ncurses.COLS
|
87
88
|
#
|
88
89
|
#@form.window.printstring r, c, "%-*s" % [len, htext], @color_pair, @attr
|
89
90
|
win.printstring r, ((len-htext.length)/2).floor, htext, @color_pair, @attr
|
90
91
|
end
|
91
92
|
def print_top_right(htext)
|
92
|
-
$log.debug " def print_top_right(#{htext})"
|
93
93
|
hlen = htext.length
|
94
|
-
len =
|
95
|
-
len =
|
96
|
-
|
94
|
+
len = @window.getmaxx # width was not changing when resize happens
|
95
|
+
len = Ncurses.COLS-0 if len == 0 || len > Ncurses.COLS
|
96
|
+
$log.debug " def print_top_right(#{htext}) #{len} #{Ncurses.COLS} "
|
97
97
|
@form.window.printstring 0, len-hlen, htext, @color_pair, @attr
|
98
98
|
end
|
99
99
|
##
|
@@ -23,9 +23,11 @@ module RubyCurses
|
|
23
23
|
dsl_accessor :footer_color_pair
|
24
24
|
# set the color of the mnemonic, overriding the defaults
|
25
25
|
dsl_accessor :footer_mnemonic_color_pair
|
26
|
+
#attr_accessor :row_relative # lets only advertise this when we've tested it out
|
26
27
|
|
27
28
|
def initialize form, key_labels, config={}, &block
|
28
29
|
|
30
|
+
@name = "dock"
|
29
31
|
case key_labels
|
30
32
|
when Hash
|
31
33
|
raise "KeyLabelPrinter: KeyLabels cannot be a hash, Array of key labels required. Perhaps you did not pass labels"
|
@@ -40,9 +42,19 @@ module RubyCurses
|
|
40
42
|
@key_hash[@mode] = key_labels
|
41
43
|
@editable = false
|
42
44
|
@focusable = false
|
43
|
-
@
|
44
|
-
|
45
|
+
unless @row
|
46
|
+
@row_relative = -2
|
47
|
+
@row = Ncurses.LINES + @row_relative
|
48
|
+
end
|
45
49
|
@col ||= 0
|
50
|
+
# if negativ row passed we store as relative to bottom, so we can maintain that.
|
51
|
+
if @row < 0
|
52
|
+
@row_relative = @row
|
53
|
+
@row = Ncurses.LINES - @row
|
54
|
+
else
|
55
|
+
@row_relative = (Ncurses.LINES - @row) * -1
|
56
|
+
end
|
57
|
+
@cols ||= Ncurses.COLS-1
|
46
58
|
@repaint_required = true
|
47
59
|
@footer_color_pair ||= $bottomcolor
|
48
60
|
@footer_mnemonic_color_pair ||= $reversecolor #2
|
@@ -71,6 +83,10 @@ module RubyCurses
|
|
71
83
|
def repaint
|
72
84
|
return unless @repaint_required
|
73
85
|
r,c = rowcol
|
86
|
+
# this should only happen if there's a change in window
|
87
|
+
if @row_relative
|
88
|
+
@row = Ncurses.LINES+@row_relative
|
89
|
+
end
|
74
90
|
arr = key_labels()
|
75
91
|
print_key_labels(arr, mode=@mode)
|
76
92
|
@repaint_required = false
|
@@ -85,7 +101,7 @@ module RubyCurses
|
|
85
101
|
def print_key_labels(arr = key_labels(), mode=@mode)
|
86
102
|
#return if !@show_key_labels # XXX
|
87
103
|
@win ||= @form.window
|
88
|
-
|
104
|
+
#$log.debug "XXX: PKL #{arr.length}, #{arr}"
|
89
105
|
@padding = @cols / (arr.length/2)
|
90
106
|
posx = 0
|
91
107
|
even = []
|
@@ -375,11 +375,13 @@ module RubyCurses
|
|
375
375
|
end
|
376
376
|
case keycode
|
377
377
|
when String
|
378
|
+
# single assignment
|
378
379
|
keycode = keycode.getbyte(0) #if keycode.class==String ## 1.9 2009-10-05 19:40
|
379
380
|
#$log.debug " #{name} Widg String called bind_key BIND #{keycode}, #{keycode_tos(keycode)} "
|
380
|
-
|
381
|
+
#$log.debug " assigning #{keycode} " if $log.debug?
|
381
382
|
@key_handler[keycode] = blk
|
382
383
|
when Array
|
384
|
+
# double assignment
|
383
385
|
# for starters lets try with 2 keys only
|
384
386
|
raise "A one key array will not work. Pass without array" if keycode.size == 1
|
385
387
|
a0 = keycode[0]
|
@@ -387,7 +389,7 @@ module RubyCurses
|
|
387
389
|
a1 = keycode[1]
|
388
390
|
a1 = keycode[1].getbyte(0) if keycode[1].class == String
|
389
391
|
@key_handler[a0] ||= OrderedHash.new
|
390
|
-
|
392
|
+
#$log.debug " assigning #{keycode} , A0 #{a0} , A1 #{a1} " if $log.debug?
|
391
393
|
@key_handler[a0][a1] = blk
|
392
394
|
#$log.debug " XX assigning #{keycode} to key_handler " if $log.debug?
|
393
395
|
else
|
@@ -398,6 +400,85 @@ module RubyCurses
|
|
398
400
|
@key_args[keycode] = args
|
399
401
|
|
400
402
|
end
|
403
|
+
|
404
|
+
def define_prefix_command _name, config={} #_mapvar=nil, _prompt=nil
|
405
|
+
$rb_prefix_map ||= {}
|
406
|
+
_name = _name.to_sym unless _name.is_a? Symbol
|
407
|
+
$rb_prefix_map[_name] ||= {}
|
408
|
+
scope = config[:scope] || self
|
409
|
+
$rb_prefix_map[_name][:scope] = scope
|
410
|
+
|
411
|
+
|
412
|
+
# create a variable by name _name
|
413
|
+
# create a method by same name to use
|
414
|
+
# Don;t let this happen more than once
|
415
|
+
instance_eval %{
|
416
|
+
def #{_name.to_s} *args
|
417
|
+
#$log.debug "XXX: came inside #{_name} "
|
418
|
+
h = $rb_prefix_map["#{_name}".to_sym]
|
419
|
+
raise "No prefix_map named #{_name}, #{$rb_prefix_map.keys} " unless h
|
420
|
+
ch = @window.getchar
|
421
|
+
if ch
|
422
|
+
if ch == KEY_F1
|
423
|
+
text = ["Options are: "]
|
424
|
+
h.keys.each { |e| c = keycode_tos(e); text << c + " " + @descriptions[e] }
|
425
|
+
textdialog text, :title => "#{_name} key bindings"
|
426
|
+
return
|
427
|
+
end
|
428
|
+
res = h[ch]
|
429
|
+
if res.is_a? Proc
|
430
|
+
res.call
|
431
|
+
elsif res.is_a? Symbol
|
432
|
+
scope = h[:scope]
|
433
|
+
scope.send(res)
|
434
|
+
elsif res.nil?
|
435
|
+
Ncurses.beep
|
436
|
+
return :UNHANDLED
|
437
|
+
end
|
438
|
+
else
|
439
|
+
#@window.ungetch(ch)
|
440
|
+
:UNHANDLED
|
441
|
+
end
|
442
|
+
end
|
443
|
+
}
|
444
|
+
return _name
|
445
|
+
end
|
446
|
+
|
447
|
+
def define_key _symbol, _keycode, *args, &blk
|
448
|
+
#_symbol = @symbol
|
449
|
+
h = $rb_prefix_map[_symbol]
|
450
|
+
raise ArgumentError, "No such keymap #{_symbol} defined. Use define_prefix_command." unless h
|
451
|
+
_keycode = _keycode[0].getbyte(0) if _keycode[0].class == String
|
452
|
+
arg = args.shift
|
453
|
+
if arg.is_a? String
|
454
|
+
desc = arg
|
455
|
+
arg = args.shift
|
456
|
+
elsif arg.is_a? Symbol
|
457
|
+
# its a symbol
|
458
|
+
desc = arg.to_s
|
459
|
+
elsif arg.nil?
|
460
|
+
desc = "unknown"
|
461
|
+
else
|
462
|
+
raise ArgumentError, "Don't know how to handle #{arg.class} in PrefixManager"
|
463
|
+
end
|
464
|
+
@descriptions ||= []
|
465
|
+
@descriptions[_keycode] = desc
|
466
|
+
|
467
|
+
if !block_given?
|
468
|
+
blk = arg
|
469
|
+
end
|
470
|
+
h[_keycode] = blk
|
471
|
+
end
|
472
|
+
# define a key within a prefix key map such as C-x
|
473
|
+
def OLDdefine_key _symbol, _keycode, _method=nil, &blk
|
474
|
+
h = $rb_prefix_map[_symbol]
|
475
|
+
raise ArgumentError, "No such keymap #{_symbol} defined. Use define_prefix_command." unless h
|
476
|
+
_keycode = _keycode[0].getbyte(0) if _keycode[0].class == String
|
477
|
+
if !block_given?
|
478
|
+
blk = _method
|
479
|
+
end
|
480
|
+
h[_keycode] = blk
|
481
|
+
end
|
401
482
|
# Display key bindings for current widget and form in dialog
|
402
483
|
def print_key_bindings *args
|
403
484
|
f = get_current_field
|
@@ -455,20 +536,27 @@ module RubyCurses
|
|
455
536
|
def _process_key keycode, object, window
|
456
537
|
return :UNHANDLED if @key_handler.nil?
|
457
538
|
blk = @key_handler[keycode]
|
539
|
+
$log.debug "XXX: _process key keycode #{keycode} #{blk.class}, #{self.class} "
|
458
540
|
return :UNHANDLED if blk.nil?
|
459
|
-
if blk.is_a? OrderedHash
|
541
|
+
if blk.is_a? OrderedHash
|
460
542
|
#Ncurses::nodelay(window.get_window, bf = false)
|
461
543
|
# if you set nodelay in ncurses.rb then this will not
|
462
544
|
# wait for second key press, so you then must either make it blocking
|
463
545
|
# here, or set a wtimeout here.
|
546
|
+
#
|
547
|
+
# This is since i have removed timeout globally since resize was happeing
|
548
|
+
# after a keypress. maybe we can revert to timeout and not worry about resize so much
|
549
|
+
Ncurses::wtimeout(window.get_window, $ncurses_timeout || 500) # will wait a second on wgetch so we can get gg and qq
|
464
550
|
ch = window.getch
|
551
|
+
Ncurses::nowtimeout(window.get_window, true)
|
465
552
|
#Ncurses::nodelay(window.get_window, bf = true)
|
466
553
|
|
467
554
|
$log.debug " process_key: got #{keycode} , #{ch} "
|
468
|
-
|
555
|
+
# next line ignores function keys etc. C-x F1, thus commented 255 2012-01-11
|
556
|
+
if ch < 0 #|| ch > 255
|
469
557
|
return nil
|
470
558
|
end
|
471
|
-
yn = ch.chr
|
559
|
+
#yn = ch.chr
|
472
560
|
blk1 = blk[ch]
|
473
561
|
# FIXME we are only returning the second key, what if form
|
474
562
|
# has mapped first and second combo. We should unget keycode and ch. 2011-12-23
|
@@ -480,8 +568,9 @@ module RubyCurses
|
|
480
568
|
end
|
481
569
|
#$log.debug "called process_key #{object}, kc: #{keycode}, args #{@key_args[keycode]}"
|
482
570
|
if blk.is_a? Symbol
|
483
|
-
|
571
|
+
#$log.debug "SYMBOL #{blk.to_s} " if $log.debug?
|
484
572
|
if respond_to? blk
|
573
|
+
#$log.debug "SYMBOL calling #{blk.to_s} " if $log.debug?
|
485
574
|
return send(blk, *@key_args[keycode])
|
486
575
|
else
|
487
576
|
alert "This ( #{self.class} ) does not respond to #{blk.to_s} "
|
@@ -593,8 +682,8 @@ module RubyCurses
|
|
593
682
|
# Need to inform listeners - done 2010-02-25 23:09
|
594
683
|
# Can throw a FieldValidationException or PropertyVetoException
|
595
684
|
def fire_property_change text, oldvalue, newvalue
|
596
|
-
#$log.debug " FPC #{self}: #{text} #{oldvalue}, #{newvalue}"
|
597
685
|
return if oldvalue.nil? || @_object_created.nil? # added 2010-09-16 so if called by methods it is still effective
|
686
|
+
$log.debug " FPC #{self}: #{text} #{oldvalue}, #{newvalue}"
|
598
687
|
if @pce.nil?
|
599
688
|
@pce = PropertyChangeEvent.new(self, text, oldvalue, newvalue)
|
600
689
|
else
|
@@ -1208,7 +1297,7 @@ module RubyCurses
|
|
1208
1297
|
@modified = false
|
1209
1298
|
@focusable = true
|
1210
1299
|
@navigation_policy ||= :CYCLICAL
|
1211
|
-
@_events = [:ENTER, :LEAVE]
|
1300
|
+
@_events = [:ENTER, :LEAVE, :RESIZE]
|
1212
1301
|
instance_eval &block if block_given?
|
1213
1302
|
## I need some counter so a widget knows it has been panned and can send a correct
|
1214
1303
|
##+ cursor coordinate to system.
|
@@ -1232,6 +1321,8 @@ module RubyCurses
|
|
1232
1321
|
|
1233
1322
|
# what kind of key-bindings do you want, :vim or :emacs
|
1234
1323
|
$key_map ||= :vim ## :emacs or :vim, keys to be defined accordingly. TODO
|
1324
|
+
|
1325
|
+
bind_key(KEY_F1, 'help') { hm = help_manager(); hm.display_help }
|
1235
1326
|
end
|
1236
1327
|
##
|
1237
1328
|
# set this menubar as the form's menu bar.
|
@@ -1746,10 +1837,14 @@ module RubyCurses
|
|
1746
1837
|
cols = Ncurses.COLS
|
1747
1838
|
x = Ncurses.stdscr.getmaxy
|
1748
1839
|
y = Ncurses.stdscr.getmaxx
|
1749
|
-
$log.debug " form RESIZE HK #{ch} #{self}, #{@name}, #{ch} "
|
1750
|
-
alert "SIGWINCH WE NEED TO RECALC AND REPAINT resize #{lines}, #{cols}: #{x}, #{y} "
|
1840
|
+
$log.debug " form RESIZE HK #{ch} #{self}, #{@name}, #{ch}, x #{x} y #{y} "
|
1841
|
+
#alert "SIGWINCH WE NEED TO RECALC AND REPAINT resize #{lines}, #{cols}: #{x}, #{y} "
|
1751
1842
|
Ncurses.endwin
|
1752
1843
|
@window.wrefresh
|
1844
|
+
@widgets.each { |e| e.repaint_all(true) } # trying out
|
1845
|
+
## added RESIZE on 2012-01-5
|
1846
|
+
## stuff that relies on last line such as statusline dock etc will need to be redrawn.
|
1847
|
+
fire_handler :RESIZE, self
|
1753
1848
|
else
|
1754
1849
|
field = get_current_field
|
1755
1850
|
if $log.debug?
|
@@ -1825,6 +1920,7 @@ module RubyCurses
|
|
1825
1920
|
# place given widget below given one, or last added one
|
1826
1921
|
# Does not check for availability or overlap
|
1827
1922
|
def place_below me, other=nil
|
1923
|
+
$log.warn "WARN deprecated form place_below"
|
1828
1924
|
w = widgets
|
1829
1925
|
if other.nil?
|
1830
1926
|
other = w[-1]
|
@@ -1844,6 +1940,7 @@ module RubyCurses
|
|
1844
1940
|
# return location to place next widget (below)
|
1845
1941
|
# Does not check for availability or overlap
|
1846
1942
|
def next_position
|
1943
|
+
$log.warn "WARN deprecated form next_position"
|
1847
1944
|
w = widgets.last
|
1848
1945
|
if w.height.nil? || w.height == 0
|
1849
1946
|
h = 1
|
@@ -1854,9 +1951,79 @@ module RubyCurses
|
|
1854
1951
|
col = w.col
|
1855
1952
|
return row, col
|
1856
1953
|
end
|
1954
|
+
#
|
1955
|
+
# returns in instance of help_manager with which one may install help_text and call help.
|
1956
|
+
# user apps will only supply help_text, form would already have mapped F1 to help.
|
1957
|
+
def help_manager
|
1958
|
+
@help_manager ||= HelpManager.new self
|
1959
|
+
end
|
1857
1960
|
|
1858
1961
|
## ADD HERE FORM
|
1859
1962
|
end
|
1963
|
+
|
1964
|
+
|
1965
|
+
class HelpManager
|
1966
|
+
def initialize form, config={}, &block
|
1967
|
+
@form = form
|
1968
|
+
#super
|
1969
|
+
#instance_eval &block if block_given?
|
1970
|
+
end
|
1971
|
+
def help_text text=nil
|
1972
|
+
if text
|
1973
|
+
@help_text = text
|
1974
|
+
end
|
1975
|
+
return @help_text
|
1976
|
+
end
|
1977
|
+
def help_text=(text); help_text(text); end
|
1978
|
+
def display_help
|
1979
|
+
filename = File.dirname(__FILE__) + "/../docs/index.txt"
|
1980
|
+
# defarr contains default help
|
1981
|
+
if File.exists?(filename)
|
1982
|
+
defarr = File.open(filename,'r').readlines
|
1983
|
+
else
|
1984
|
+
arr = []
|
1985
|
+
arr << " NO HELP SPECIFIED FOR APP "
|
1986
|
+
arr << " "
|
1987
|
+
arr << " --- General help --- "
|
1988
|
+
arr << " F10 - exit application "
|
1989
|
+
arr << " Alt-x - select commands "
|
1990
|
+
arr << " : (or M-:) - select commands "
|
1991
|
+
arr << " ? (or M-?) - current widget key bindings "
|
1992
|
+
arr << " "
|
1993
|
+
defarr = arr
|
1994
|
+
end
|
1995
|
+
defhelp = true
|
1996
|
+
if @help_text
|
1997
|
+
defhelp = false
|
1998
|
+
arr = @help_text
|
1999
|
+
else
|
2000
|
+
arr = defarr
|
2001
|
+
end
|
2002
|
+
case arr
|
2003
|
+
when String
|
2004
|
+
arr = arr.split("\n")
|
2005
|
+
when Array
|
2006
|
+
end
|
2007
|
+
#w = arr.max_by(&:length).length
|
2008
|
+
h = FFI::NCurses.LINES - 4
|
2009
|
+
w = FFI::NCurses.COLS - 10
|
2010
|
+
|
2011
|
+
require 'rbcurse/core/util/viewer'
|
2012
|
+
RubyCurses::Viewer.view(arr, :layout => [2, 4, h, w],:close_key => KEY_F10, :title => "[ Help ]", :print_footer => true) do |t|
|
2013
|
+
# you may configure textview further here.
|
2014
|
+
#t.suppress_borders true
|
2015
|
+
#t.color = :black
|
2016
|
+
#t.bgcolor = :white
|
2017
|
+
# or
|
2018
|
+
#t.attr = :reverse
|
2019
|
+
|
2020
|
+
# help was provided, so default help is provided in second buffer
|
2021
|
+
unless defhelp
|
2022
|
+
t.add_content defarr, :title => ' General Help '
|
2023
|
+
end
|
2024
|
+
end
|
2025
|
+
end
|
2026
|
+
end # class
|
1860
2027
|
## Created and sent to all listeners whenever a property is changed
|
1861
2028
|
# @see fire_property_change
|
1862
2029
|
# @see fire_handler
|
@@ -7,8 +7,10 @@ module RubyCurses
|
|
7
7
|
# at the bottom, typically above the dock (3rd line from last).
|
8
8
|
#
|
9
9
|
class StatusLine < Widget
|
10
|
+
#attr_accessor :row_relative # lets only advertise this when we've tested it out
|
10
11
|
|
11
12
|
def initialize form, config={}, &block
|
13
|
+
@row_relative = -3
|
12
14
|
if form.window.height == 0
|
13
15
|
@row = Ncurses.LINES-3 # fix, what about smaller windows, use window dimensions and watch out for 0,0
|
14
16
|
else
|
@@ -16,7 +18,15 @@ module RubyCurses
|
|
16
18
|
end
|
17
19
|
# in root windows FIXME
|
18
20
|
@col = 0
|
21
|
+
@name = "sl"
|
19
22
|
super
|
23
|
+
# if negativ row passed we store as relative to bottom, so we can maintain that.
|
24
|
+
if @row < 0
|
25
|
+
@row_relative = @row
|
26
|
+
@row = Ncurses.LINES - @row
|
27
|
+
else
|
28
|
+
@row_relative = (Ncurses.LINES - @row) * -1
|
29
|
+
end
|
20
30
|
@focusable = false
|
21
31
|
@editable = false
|
22
32
|
@command = nil
|
@@ -47,8 +57,12 @@ module RubyCurses
|
|
47
57
|
# rather whenever form.repaint is called.
|
48
58
|
def repaint
|
49
59
|
@color_pair ||= get_color($datacolor, @color, @bgcolor)
|
50
|
-
len = @form.window.width
|
51
|
-
len = Ncurses.COLS if len == 0
|
60
|
+
len = @form.window.getmaxx # width does not change upon resizing so useless, fix or do something
|
61
|
+
len = Ncurses.COLS if len == 0 || len > Ncurses.COLS
|
62
|
+
# this should only happen if there's a change in window
|
63
|
+
if @row_relative
|
64
|
+
@row = Ncurses.LINES+@row_relative
|
65
|
+
end
|
52
66
|
|
53
67
|
# first print dashes through
|
54
68
|
@form.window.printstring @row, @col, "%s" % "-" * len, @color_pair, Ncurses::A_REVERSE
|
@@ -80,6 +94,7 @@ module RubyCurses
|
|
80
94
|
else
|
81
95
|
t = Time.now
|
82
96
|
tt = t.strftime "%F %H:%M:%S"
|
97
|
+
r = Ncurses.LINES
|
83
98
|
ftext = "#[fg=green,bg=blue] %-20s" % [tt] # print a default
|
84
99
|
@form.window.printstring_formatted_right @row, nil, ftext, $datacolor, Ncurses::A_REVERSE
|
85
100
|
end
|
data/rbcurse-core.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "rbcurse-core"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rahul Kumar"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-03-05"
|
13
13
|
s.description = "Ruby curses/ncurses widgets for easy application development on text terminals (ruby 1.9, 1.8)"
|
14
14
|
s.email = "sentinel1879@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -119,7 +119,7 @@ Gem::Specification.new do |s|
|
|
119
119
|
s.homepage = "https://github.com/rkumar/rbcurse-core"
|
120
120
|
s.require_paths = ["lib"]
|
121
121
|
s.rubyforge_project = "rbcurse"
|
122
|
-
s.rubygems_version = "1.8.
|
122
|
+
s.rubygems_version = "1.8.25"
|
123
123
|
s.summary = "Ruby Ncurses Toolkit core infrastructure and widgets"
|
124
124
|
|
125
125
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbcurse-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi-ncurses
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,12 @@ dependencies:
|
|
21
21
|
version: 0.4.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.4.0
|
25
30
|
description: Ruby curses/ncurses widgets for easy application development on text
|
26
31
|
terminals (ruby 1.9, 1.8)
|
27
32
|
email: sentinel1879@gmail.com
|
@@ -149,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
154
|
version: '0'
|
150
155
|
requirements: []
|
151
156
|
rubyforge_project: rbcurse
|
152
|
-
rubygems_version: 1.8.
|
157
|
+
rubygems_version: 1.8.25
|
153
158
|
signing_key:
|
154
159
|
specification_version: 3
|
155
160
|
summary: Ruby Ncurses Toolkit core infrastructure and widgets
|