rbcurse 1.1.5 → 1.2.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +45 -0
- data/Makefile +1 -1
- data/Manifest.txt +91 -0
- data/NOTES +349 -2
- data/README.markdown +12 -0
- data/VERSION +1 -1
- data/examples/abasiclist.rb +25 -0
- data/examples/alpmenu.rb +42 -0
- data/examples/app.rb +883 -0
- data/examples/appcombo.rb +17 -0
- data/examples/appdirtree.rb +73 -0
- data/examples/appemail.rb +164 -0
- data/examples/appemaillb.rb +308 -0
- data/examples/appgcompose.rb +303 -0
- data/examples/appgmail.rb +951 -0
- data/examples/atree.rb +56 -0
- data/examples/dirtree.rb +78 -0
- data/examples/focusmanager.rb +31 -0
- data/examples/imap.rb +48 -0
- data/examples/menu1.rb +79 -0
- data/examples/multispl.rb +86 -0
- data/examples/rfe.rb +3 -4
- data/examples/rmail.rb +188 -0
- data/examples/s.rb +10 -0
- data/examples/scrollbar.rb +104 -0
- data/examples/splitp.rb +56 -0
- data/examples/table1.rb +30 -0
- data/examples/term.rb +48 -0
- data/examples/term2.rb +54 -0
- data/examples/test1.rb +4 -2
- data/examples/test2.rb +9 -9
- data/examples/testapp.rb +44 -0
- data/examples/testapp2.rb +51 -0
- data/examples/testcombo.rb +2 -2
- data/examples/testgmail.rb +46 -0
- data/examples/testlistbox.rb +0 -1
- data/examples/testmultispl.rb +199 -0
- data/examples/testree.rb +127 -0
- data/examples/testscroller.rb +0 -1
- data/examples/testscrolllb.rb +1 -1
- data/examples/testscrollp.rb +2 -1
- data/examples/testscrollta.rb +1 -1
- data/examples/testscrolltable.rb +1 -2
- data/examples/testsplit.rb +1 -1
- data/examples/testsplit2.rb +1 -1
- data/examples/testsplit3.rb +1 -1
- data/examples/testsplit3_1.rb +1 -1
- data/examples/testsplit3a.rb +1 -1
- data/examples/testsplit3b.rb +1 -1
- data/examples/testsplitta.rb +1 -1
- data/examples/testsplittv.rb +1 -1
- data/examples/testsplittvv.rb +1 -1
- data/examples/testtodo.rb +491 -488
- data/examples/testvimsplit.rb +111 -0
- data/examples/todo.db +0 -0
- data/examples/todocsv.csv +28 -0
- data/examples/viewtodo.rb +408 -403
- data/lib/rbcurse/action.rb +1 -0
- data/lib/rbcurse/app.rb +1294 -0
- data/lib/rbcurse/applicationheader.rb +7 -2
- data/lib/rbcurse/checkboxcellrenderer.rb +0 -12
- data/lib/rbcurse/colormap.rb +34 -8
- data/lib/rbcurse/comboboxcellrenderer.rb +0 -11
- data/lib/rbcurse/defaultlistselectionmodel.rb +23 -7
- data/lib/rbcurse/extras/bottomline.rb +1681 -0
- data/lib/rbcurse/extras/directorylist.rb +445 -0
- data/lib/rbcurse/extras/directorytree.rb +69 -0
- data/lib/rbcurse/extras/divider.rb +310 -0
- data/lib/rbcurse/extras/focusmanager.rb +31 -0
- data/lib/rbcurse/extras/listselectable.rb +222 -0
- data/lib/rbcurse/extras/masterdetail.rb +164 -0
- data/lib/rbcurse/extras/menutree.rb +63 -0
- data/lib/rbcurse/extras/rlink.rb +27 -0
- data/lib/rbcurse/extras/rmenulink.rb +21 -0
- data/lib/rbcurse/extras/scrollbar.rb +134 -0
- data/lib/rbcurse/extras/stdscrwindow.rb +247 -0
- data/lib/rbcurse/extras/tabular.rb +258 -0
- data/lib/rbcurse/extras/tabularwidget.rb +1070 -0
- data/lib/rbcurse/extras/viewer.rb +106 -0
- data/lib/rbcurse/io.rb +137 -80
- data/lib/rbcurse/keylabelprinter.rb +4 -0
- data/lib/rbcurse/listcellrenderer.rb +91 -59
- data/lib/rbcurse/listscrollable.rb +93 -95
- data/lib/rbcurse/listselectable.rb +60 -7
- data/lib/rbcurse/ractionevent.rb +67 -0
- data/lib/rbcurse/rbasiclistbox.rb +688 -0
- data/lib/rbcurse/rcombo.rb +5 -5
- data/lib/rbcurse/rcommandwindow.rb +555 -0
- data/lib/rbcurse/rinputdataevent.rb +12 -0
- data/lib/rbcurse/rlistbox.rb +305 -124
- data/lib/rbcurse/rmenu.rb +99 -46
- data/lib/rbcurse/rmessagebox.rb +13 -6
- data/lib/rbcurse/rmulticontainer.rb +54 -93
- data/lib/rbcurse/rmultisplit.rb +731 -0
- data/lib/rbcurse/rmultitextview.rb +3 -2
- data/lib/rbcurse/rpopupmenu.rb +0 -1
- data/lib/rbcurse/rprogress.rb +117 -0
- data/lib/rbcurse/rscrollpane.rb +2 -1
- data/lib/rbcurse/rsplitpane.rb +94 -20
- data/lib/rbcurse/rsplitpane2.rb +1009 -0
- data/lib/rbcurse/rtabbedpane.rb +3 -2
- data/lib/rbcurse/rtabbedwindow.rb +0 -1
- data/lib/rbcurse/rtable.rb +92 -64
- data/lib/rbcurse/rtextarea.rb +91 -57
- data/lib/rbcurse/rtextview.rb +223 -70
- data/lib/rbcurse/rtree.rb +723 -0
- data/lib/rbcurse/rviewport.rb +2 -1
- data/lib/rbcurse/rvimsplit.rb +768 -0
- data/lib/rbcurse/rwidget.rb +524 -325
- data/lib/rbcurse/table/tablecellrenderer.rb +1 -1
- data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -1
- data/lib/rbcurse/tree/treecellrenderer.rb +137 -0
- data/lib/rbcurse/tree/treemodel.rb +428 -0
- data/lib/rbcurse/vieditable.rb +14 -13
- data/lib/ver/ncurses.rb +6 -0
- data/lib/ver/window.rb +67 -32
- metadata +99 -23
- data/bin/rbcurse +0 -0
- data/examples/rvimsplit.rb +0 -376
- data/examples/todo.rb +0 -1
- data/lib/rbcurse/rform.rb +0 -845
- data/lib/rbcurse/selectable.rb +0 -94
- data/rbcurse.gemspec +0 -188
data/bin/rbcurse
DELETED
File without changes
|
data/examples/rvimsplit.rb
DELETED
@@ -1,376 +0,0 @@
|
|
1
|
-
# this is a test program,
|
2
|
-
# testing out if subwins can help in splitpanes
|
3
|
-
# derwins, although easy to use flunk movement and resizing
|
4
|
-
# So i've changed Window to use subwins, so top and left are maintained
|
5
|
-
# We need to create events for resizing so refreshing window can be done.
|
6
|
-
#
|
7
|
-
# FIXME - resizing, divider change
|
8
|
-
# FIXME - left top 2 splits are not expanding to full height. check in draw box mode
|
9
|
-
# TODO = when resixing a split, if the other one has been split, its children need to be resized.
|
10
|
-
#
|
11
|
-
#$LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
|
12
|
-
require 'rubygems'
|
13
|
-
require 'ncurses'
|
14
|
-
require 'logger'
|
15
|
-
require 'rbcurse'
|
16
|
-
|
17
|
-
class Split
|
18
|
-
def initialize type, first, second, win
|
19
|
-
@c1 = first
|
20
|
-
@c2 = second
|
21
|
-
@type = type # :VERTICAL or :HORIZONTAL
|
22
|
-
@parent = win # needed to draw divider on
|
23
|
-
end
|
24
|
-
def first_win; @c1; end
|
25
|
-
def second_win; @c2; end
|
26
|
-
def divider_location y,x
|
27
|
-
@y = y
|
28
|
-
@x = x
|
29
|
-
end
|
30
|
-
|
31
|
-
# change the size of a split
|
32
|
-
# still to redo the line etc.
|
33
|
-
def increase comp, units=1
|
34
|
-
$log.debug " increase got #{comp}, #{comp.class}, #{units} "
|
35
|
-
if @type == :HORIZONTAL
|
36
|
-
if comp == @c1
|
37
|
-
else
|
38
|
-
comp = @c1
|
39
|
-
units *= -1
|
40
|
-
end
|
41
|
-
other = @c2
|
42
|
-
#comp.wclear
|
43
|
-
#other.wclear
|
44
|
-
#comp.wrefresh
|
45
|
-
#other.wrefresh
|
46
|
-
# increase h
|
47
|
-
layout = comp.layout
|
48
|
-
$log.debug " layout #{layout} "
|
49
|
-
h = layout[:height]
|
50
|
-
w = layout[:width]
|
51
|
-
top = layout[:top]
|
52
|
-
left = layout[:left]
|
53
|
-
$log.debug "H1 ht change #{h} , #{h} + #{units} "
|
54
|
-
layout[:height]= h + units
|
55
|
-
divloc = h + units + 1
|
56
|
-
comp.resize_with(layout)
|
57
|
-
# decrease second, and push inc top
|
58
|
-
layout = other.layout
|
59
|
-
h = layout[:height]
|
60
|
-
w = layout[:width]
|
61
|
-
top = layout[:top]
|
62
|
-
left = layout[:left]
|
63
|
-
h = layout[:height]
|
64
|
-
top = layout[:top]
|
65
|
-
layout[:top] = top + units
|
66
|
-
layout[:height] = h- units
|
67
|
-
$log.debug "H1 c2 ht change #{h} , #{h} - #{units}, top #{top} + #{units} "
|
68
|
-
other.resize_with(layout)
|
69
|
-
h = @parent.height
|
70
|
-
w = @parent.width
|
71
|
-
#@parent.mvwhline( divloc, 0, ACS_HLINE, w+2)
|
72
|
-
@y += units
|
73
|
-
#@parent.werase #wclear
|
74
|
-
@parent.wclear
|
75
|
-
# FIXME double line printing ??? after tabbing or hitting a key
|
76
|
-
@parent.mvwhline( @y, 0, ACS_HLINE, w)
|
77
|
-
comp.wrefresh
|
78
|
-
other.wrefresh
|
79
|
-
@parent.wrefresh
|
80
|
-
# do wnoutrefresh and doupdate
|
81
|
-
return
|
82
|
-
end
|
83
|
-
if @type == :VERTICAL
|
84
|
-
if comp == @c1
|
85
|
-
else
|
86
|
-
units *= -1
|
87
|
-
comp = @c1
|
88
|
-
end
|
89
|
-
other = @c2
|
90
|
-
# increase w
|
91
|
-
layout = comp.layout
|
92
|
-
h = layout[:width]
|
93
|
-
layout[:width]= h + units
|
94
|
-
$log.debug "V1 ht change #{h} , #{h} + #{units} "
|
95
|
-
comp.resize_with(layout)
|
96
|
-
# decrease second, and push inc top
|
97
|
-
layout = other.layout
|
98
|
-
h = layout[:width]
|
99
|
-
top = layout[:left]
|
100
|
-
layout[:left] = top + units
|
101
|
-
layout[:width] = h - units
|
102
|
-
$log.debug "V c2 ht change #{h} , #{h} - #{units}, top #{top} + #{units} "
|
103
|
-
other.resize_with(layout)
|
104
|
-
# TODO add line here
|
105
|
-
comp.wclear
|
106
|
-
other.wclear
|
107
|
-
return
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
112
|
-
class VimSplit
|
113
|
-
def initialize window, lay
|
114
|
-
# array of window, to delete later
|
115
|
-
@wins = []
|
116
|
-
# mapping of a subwin and its Split, so i can resize
|
117
|
-
@splits = {}
|
118
|
-
|
119
|
-
# hash of windows and component attached
|
120
|
-
@win_comp = {}
|
121
|
-
@children = {} # parent and children array, since we have not designed this properly
|
122
|
-
# only those windows that can be focused, child windows when split, parent is invisible
|
123
|
-
@focusables = []
|
124
|
-
# main window
|
125
|
-
@window = window
|
126
|
-
@splouter = @window._subwin(lay)
|
127
|
-
# (0..@splouter.height).each {|i| @splouter.highlight_line($reversecolor,i,0,@splouter.width)}
|
128
|
-
@wins << @splouter
|
129
|
-
#@focusables << @splouter
|
130
|
-
@splouter.box(0,0)
|
131
|
-
@draw_boxes = false
|
132
|
-
|
133
|
-
@str = "" # dummy
|
134
|
-
end
|
135
|
-
def self.color_window win, color=$datacolor
|
136
|
-
(0..win.height).each {|i| win.highlight_line(color,i,0,win.width)}
|
137
|
-
end
|
138
|
-
# focussed component
|
139
|
-
def current
|
140
|
-
@current || _switch_split
|
141
|
-
end
|
142
|
-
# when we make the first split we want to keep the borders. AFter that we always want to start with zero
|
143
|
-
# so the window we split is "consumed".
|
144
|
-
def get_offset
|
145
|
-
if @wins.length == 1
|
146
|
-
return 1
|
147
|
-
end
|
148
|
-
0
|
149
|
-
end
|
150
|
-
def get_win; @splouter; end
|
151
|
-
|
152
|
-
# splits horizontally at centre
|
153
|
-
# We need to give an initial weight or location for divider
|
154
|
-
def split_h win
|
155
|
-
h = win.height
|
156
|
-
w = win.width
|
157
|
-
off = get_offset()
|
158
|
-
#lay1 = { :height => h/2-0, :width => w-2, :top => 0, :left => off }
|
159
|
-
#lay2 = { :height => h/2-1, :width => w-2, :top => h/2+1, :left => 1 }
|
160
|
-
lay1 = { :height => h/2-0, :width => w-2, :top => off, :left => off }
|
161
|
-
lay2 = { :height => h/2-1, :width => w-2, :top => h/2+1, :left => off }
|
162
|
-
split1 = win._subwin(lay1)
|
163
|
-
split2 = win._subwin(lay2)
|
164
|
-
win.mvwhline( h/2, 0, ACS_HLINE, w+2)
|
165
|
-
|
166
|
-
if @draw_boxes
|
167
|
-
split1.box(0,0)
|
168
|
-
split2.box(0,0)
|
169
|
-
end
|
170
|
-
# if a window is split, then tab doesn't go there, it goes to its two subwins
|
171
|
-
@focusables.delete win
|
172
|
-
@wins << split1
|
173
|
-
@wins << split2
|
174
|
-
@focusables << split1 << split2
|
175
|
-
spl = Split.new :HORIZONTAL, split1, split2, win
|
176
|
-
spl.divider_location(h/2,0)
|
177
|
-
@splits[split1] = spl
|
178
|
-
@splits[split2] = spl
|
179
|
-
@children[win] = [ split1, split2 ]
|
180
|
-
#return split1, split2
|
181
|
-
return spl
|
182
|
-
end
|
183
|
-
def split_v win
|
184
|
-
h = win.height
|
185
|
-
w = win.width
|
186
|
-
off = get_offset()
|
187
|
-
lay1 = { :height => h-2, :width => w/2-1, :top => off, :left => off }
|
188
|
-
lay2 = { :height => h-2, :width => w/2-1, :top => off, :left => w/2+1 }
|
189
|
-
split1 = win._subwin(lay1)
|
190
|
-
split2 = win._subwin(lay2)
|
191
|
-
win.mvwvline( 0, w/2, ACS_VLINE, h+2)
|
192
|
-
if @draw_boxes
|
193
|
-
split1.box(0,0)
|
194
|
-
split2.box(0,0)
|
195
|
-
end
|
196
|
-
@focusables.delete win
|
197
|
-
@wins << split1
|
198
|
-
@wins << split2
|
199
|
-
@focusables << split1 << split2
|
200
|
-
spl = Split.new :VERTICAL, split1, split2, win
|
201
|
-
spl.divider_location(0,h/2)
|
202
|
-
@splits[split1] = spl
|
203
|
-
@splits[split2] = spl
|
204
|
-
@children[win] = [ split1, split2 ]
|
205
|
-
#return split1, split2
|
206
|
-
return spl
|
207
|
-
end
|
208
|
-
def set_focus_on split
|
209
|
-
raise "Given split not focusable" if @focusables.index.nil?
|
210
|
-
# actually we can take it's split and keep going down till first. But we don;t have a tree
|
211
|
-
@current = split
|
212
|
-
end
|
213
|
-
|
214
|
-
def destroy
|
215
|
-
@wins.each {|w| w.destroy}
|
216
|
-
super
|
217
|
-
end
|
218
|
-
## attach a component to a window/split, so that all keys to that win go to the window
|
219
|
-
# create the comp without a form.
|
220
|
-
def attach win, comp
|
221
|
-
# i need to set the window to win.
|
222
|
-
comp.override_graphic(win) # i think XXX
|
223
|
-
@win_comp[win] = comp
|
224
|
-
end
|
225
|
-
def _switch_split
|
226
|
-
index = @focusables.index @current
|
227
|
-
index ||= 0
|
228
|
-
index+=1
|
229
|
-
if index >= @focusables.length
|
230
|
-
index = 0
|
231
|
-
end
|
232
|
-
@current = @focusables.at index
|
233
|
-
@current.wmove 0,0
|
234
|
-
@current.wrefresh
|
235
|
-
@current
|
236
|
-
end
|
237
|
-
def handle_key ch
|
238
|
-
case ch
|
239
|
-
when 9
|
240
|
-
_switch_split
|
241
|
-
return 0
|
242
|
-
#when 32..126
|
243
|
-
#char = ch.chr
|
244
|
-
#@str << char
|
245
|
-
#@current.printstring 0,0, @str, 0
|
246
|
-
#@current.wrefresh
|
247
|
-
#when 330, 127
|
248
|
-
#@str = @str[0..-2]
|
249
|
-
##@current.wclear # casuses a flash
|
250
|
-
#@current.printstring 0,0, @str, 0
|
251
|
-
#@current.wrefresh
|
252
|
-
#when 10,13
|
253
|
-
#@str << "\n"
|
254
|
-
when ?\M-v.getbyte(0)
|
255
|
-
# allow user to split but this does not give the user programmatic control over the splits ??
|
256
|
-
# unless we call some events
|
257
|
-
split_v @current
|
258
|
-
@current.wrefresh
|
259
|
-
set_focus_on @focusables.last
|
260
|
-
@window.wrefresh
|
261
|
-
when ?\M-h.getbyte(0)
|
262
|
-
split_h @current
|
263
|
-
@current.wrefresh
|
264
|
-
set_focus_on @focusables.last
|
265
|
-
@window.wrefresh
|
266
|
-
when ?\M-+.getbyte(0)
|
267
|
-
spl = @splits[@current]
|
268
|
-
spl.increase(@current)
|
269
|
-
when ?\M--.getbyte(0)
|
270
|
-
spl = @splits[@current]
|
271
|
-
spl.increase(@current,-1)
|
272
|
-
else
|
273
|
-
comp = @win_comp[@current]
|
274
|
-
ret = :UNHANDLED
|
275
|
-
ret = comp.handle_key(ch) unless comp.nil?
|
276
|
-
return ret
|
277
|
-
end
|
278
|
-
ret = :UNHANDLED
|
279
|
-
end
|
280
|
-
|
281
|
-
end
|
282
|
-
class TestSubwin
|
283
|
-
def initialize
|
284
|
-
acolor = $reversecolor
|
285
|
-
end
|
286
|
-
def run
|
287
|
-
@window = VER::Window.root_window
|
288
|
-
|
289
|
-
h = 20; w = 75; t = 3; l = 4
|
290
|
-
@layoutouter = { :height => h, :width => w, :top => t, :left => l }
|
291
|
-
|
292
|
-
@vim = VimSplit.new @window, @layoutouter
|
293
|
-
@splouter = @vim.get_win
|
294
|
-
spl = @vim.split_v @splouter
|
295
|
-
@splleft = spl.first_win
|
296
|
-
@splright = spl.second_win
|
297
|
-
spl = @vim.split_h @splleft
|
298
|
-
@splleft1 = spl.first_win
|
299
|
-
@splleft2 = spl.second_win
|
300
|
-
@vim.split_h @splright
|
301
|
-
@vim.split_v @splleft1
|
302
|
-
|
303
|
-
@window.printstring(1,10,"Ncurses Subwindow test - splitpanes emulation using subwin",0)
|
304
|
-
@splouter.printstring(0,2, " Outer ", 0)
|
305
|
-
@splleft.printstring(0,2, "-Left ", 0)
|
306
|
-
@splleft1.printstring(0,1, "Top ", 0)
|
307
|
-
@splleft2.printstring(0,1, "Bottom ", 0)
|
308
|
-
#@vim.set_focus_on @splleft1
|
309
|
-
|
310
|
-
@window.printstring(2,10,"q to quit",2)
|
311
|
-
#
|
312
|
-
@form = Form.new @window
|
313
|
-
@help = "q to quit. "
|
314
|
-
RubyCurses::Label.new @form, {'text' => @help, "row" => 1, "col" => 2, "color" => "yellow"}
|
315
|
-
@form.repaint
|
316
|
-
@window.wrefresh
|
317
|
-
Ncurses::Panel.update_panels
|
318
|
-
ctr = 0
|
319
|
-
row = 2
|
320
|
-
str = "Hello"
|
321
|
-
buffers = {}
|
322
|
-
while((ch = @window.getchar()) != KEY_F1 )
|
323
|
-
ret = @vim.handle_key ch
|
324
|
-
if ret == :UNHANDLED
|
325
|
-
curr = @vim.current
|
326
|
-
buff = buffers[curr]
|
327
|
-
if buff.nil?
|
328
|
-
buff ||= ""
|
329
|
-
buffers[curr] = buff
|
330
|
-
end
|
331
|
-
case ch
|
332
|
-
when 32..126
|
333
|
-
char = ch.chr
|
334
|
-
buff << char
|
335
|
-
curr.printstring 0,0, buff, 0
|
336
|
-
curr.wrefresh
|
337
|
-
when 330, 127
|
338
|
-
buff = buff[0..-2]
|
339
|
-
buffers[curr] = buff
|
340
|
-
#@current.wclear # casuses a flash
|
341
|
-
curr.printstring 0,0, buff, 0
|
342
|
-
curr.clrtobot
|
343
|
-
curr.wrefresh
|
344
|
-
when 10,13
|
345
|
-
buff << "\n"
|
346
|
-
curr.printstring 0,0, buff, 0
|
347
|
-
curr.wrefresh
|
348
|
-
end
|
349
|
-
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
@window.destroy
|
354
|
-
|
355
|
-
end
|
356
|
-
end
|
357
|
-
if $0 == __FILE__
|
358
|
-
include RubyCurses
|
359
|
-
include RubyCurses::Utils
|
360
|
-
# Initialize curses
|
361
|
-
begin
|
362
|
-
# XXX update with new color and kb
|
363
|
-
VER::start_ncurses # this is initializing colors via ColorMap.setup
|
364
|
-
$log = Logger.new("view.log")
|
365
|
-
$log.level = Logger::DEBUG
|
366
|
-
n = TestSubwin.new
|
367
|
-
n.run
|
368
|
-
rescue => ex
|
369
|
-
ensure
|
370
|
-
VER::stop_ncurses
|
371
|
-
p ex if ex
|
372
|
-
p(ex.backtrace.join("\n")) if ex
|
373
|
-
$log.debug( ex) if ex
|
374
|
-
$log.debug(ex.backtrace.join("\n")) if ex
|
375
|
-
end
|
376
|
-
end
|
data/examples/todo.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
S
|
data/lib/rbcurse/rform.rb
DELETED
@@ -1,845 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
* Name: TextView and TextArea
|
3
|
-
* $Id$
|
4
|
-
* Description Our own form with own simple field to make life easier. Ncurses forms are great, but
|
5
|
-
* honestly the sequence sucks and is a pain after a while for larger scale work.
|
6
|
-
* We need something less restrictive.
|
7
|
-
* Author: rkumar (arunachalesha)
|
8
|
-
TODO
|
9
|
-
* Field/entry
|
10
|
-
- textvariable - bding field to a var so the var is updated
|
11
|
-
*
|
12
|
-
|
13
|
-
2008-12-24 18:01 moved menu etc to rmenu.rb
|
14
|
-
--------
|
15
|
-
* Date: 2008-11-14 23:43
|
16
|
-
* License:
|
17
|
-
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
18
|
-
|
19
|
-
=end
|
20
|
-
require 'rubygems'
|
21
|
-
require 'ncurses'
|
22
|
-
require 'logger'
|
23
|
-
require 'rbcurse'
|
24
|
-
require 'rbcurse/scrollable'
|
25
|
-
require 'rbcurse/selectable'
|
26
|
-
require 'rbcurse/rinputdataevent'
|
27
|
-
|
28
|
-
include Ncurses
|
29
|
-
include RubyCurses
|
30
|
-
module RubyCurses
|
31
|
-
extend self
|
32
|
-
|
33
|
-
## a multiline text editing widget
|
34
|
-
# TODO - giving data to user - adding newlines, and withog adding.
|
35
|
-
# - respect newlines for incoming data
|
36
|
-
#
|
37
|
-
class OldTextArea < Widget
|
38
|
-
include Scrollable
|
39
|
-
dsl_accessor :height
|
40
|
-
dsl_accessor :title
|
41
|
-
dsl_accessor :title_attrib # bold, reverse, normal
|
42
|
-
dsl_accessor :list # the array of data to be sent by user
|
43
|
-
dsl_accessor :maxlen # the array of data to be sent by user
|
44
|
-
attr_reader :toprow
|
45
|
-
attr_reader :prow
|
46
|
-
attr_reader :winrow
|
47
|
-
dsl_accessor :auto_scroll # boolean, keeps view at end as data is inserted.
|
48
|
-
dsl_accessor :print_footer
|
49
|
-
dsl_accessor :editable # allow editing
|
50
|
-
attr_accessor :modified # boolean, value modified or not 2009-01-08 12:29
|
51
|
-
|
52
|
-
def initialize form, config={}, &block
|
53
|
-
@focusable = true
|
54
|
-
@editable = true
|
55
|
-
@left_margin = 1
|
56
|
-
@row = 0
|
57
|
-
@col = 0
|
58
|
-
@curpos = 0
|
59
|
-
@show_focus = false
|
60
|
-
@list = []
|
61
|
-
super
|
62
|
-
@row_offset = @col_offset = 1
|
63
|
-
@orig_col = @col
|
64
|
-
# this does result in a blank line if we insert after creating. That's required at
|
65
|
-
# present if we wish to only insert
|
66
|
-
if @list.empty?
|
67
|
-
@list << "\r"
|
68
|
-
end
|
69
|
-
@scrollatrow = @height-2
|
70
|
-
@content_rows = @list.length
|
71
|
-
@win = @form.window
|
72
|
-
init_scrollable
|
73
|
-
print_borders
|
74
|
-
@maxlen ||= @width-2
|
75
|
-
end
|
76
|
-
def rowcol
|
77
|
-
# $log.debug "textarea rowcol : #{@row+@row_offset+@winrow}, #{@col+@col_offset}"
|
78
|
-
return @row+@row_offset+@winrow, @col+@col_offset
|
79
|
-
end
|
80
|
-
##
|
81
|
-
# this avoids wrapping. Better to use the <<.
|
82
|
-
def Oinsert off0, *data
|
83
|
-
@list.insert off0, *data
|
84
|
-
# fire_handler :CHANGE, self # 2008-12-09 14:56 NOT SURE
|
85
|
-
end
|
86
|
-
# private
|
87
|
-
def wrap_text(txt, col = @maxlen)
|
88
|
-
$log.debug "inside wrap text for :#{txt}"
|
89
|
-
txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/,
|
90
|
-
"\\1\\3\n")
|
91
|
-
end
|
92
|
-
def remove_all
|
93
|
-
@list = []
|
94
|
-
end
|
95
|
-
##
|
96
|
-
# trying to wrap and insert
|
97
|
-
def insert off0, data
|
98
|
-
if data.length > @maxlen
|
99
|
-
data = wrap_text data
|
100
|
-
# $log.debug "after wrap text done :#{data}"
|
101
|
-
data = data.split("\n")
|
102
|
-
data[-1] << "\r" #XXXX
|
103
|
-
else
|
104
|
-
data << "\r" if data[-1,1] != "\r" #XXXX
|
105
|
-
end
|
106
|
-
data.each do |row|
|
107
|
-
@list.insert off0, row
|
108
|
-
off0 += 1
|
109
|
-
end
|
110
|
-
#$log.debug " AFTER INSERT: #{@list}"
|
111
|
-
end
|
112
|
-
##
|
113
|
-
# wraps line sent in if longer than maxlen
|
114
|
-
# Typically a line is sent in. We wrap and put a hard return at end.
|
115
|
-
def << data
|
116
|
-
if data.length > @maxlen
|
117
|
-
$log.debug "wrapped append for #{data}"
|
118
|
-
data = wrap_text data
|
119
|
-
$log.debug "after wrap text for :#{data}"
|
120
|
-
data = data.split("\n")
|
121
|
-
# 2009-01-01 22:24 the \n was needed so we would put a space at time of writing.
|
122
|
-
# we need a soft return so a space can be added when pushing down.
|
123
|
-
# commented off 2008-12-28 21:59
|
124
|
-
#data.each {|line| @list << line+"\n"}
|
125
|
-
data.each {|line| @list << line}
|
126
|
-
@list[-1] << "\r" #XXXX
|
127
|
-
else
|
128
|
-
$log.debug "normal append for #{data}"
|
129
|
-
data << "\r" if data[-1,1] != "\r" #XXXX
|
130
|
-
@list << data
|
131
|
-
end
|
132
|
-
goto_end if @auto_scroll # to test out.
|
133
|
-
self
|
134
|
-
end
|
135
|
-
def wrap_para line=@prow
|
136
|
-
line ||= 0
|
137
|
-
l=[]
|
138
|
-
while true
|
139
|
-
if @list[line].nil? or @list[line]=="" or @list[line]==13 #"\r"
|
140
|
-
break
|
141
|
-
end
|
142
|
-
$log.debug "lastchar #{@list[line][-1]}, appending: #{@list[line]}]"
|
143
|
-
t = @list[line]
|
144
|
-
l << t.strip
|
145
|
-
@list.delete_at line
|
146
|
-
break if t[-1]==13 # "\r"
|
147
|
-
# line += 1
|
148
|
-
end
|
149
|
-
str=l.join(" ")
|
150
|
-
$log.debug " sending insert : #{str}."
|
151
|
-
insert line, str
|
152
|
-
end
|
153
|
-
##
|
154
|
-
# private
|
155
|
-
def print_borders
|
156
|
-
window = @form.window
|
157
|
-
color = $datacolor
|
158
|
-
window.print_border @row, @col, @height, @width, color
|
159
|
-
print_title
|
160
|
-
=begin
|
161
|
-
hline = "+%s+" % [ "-"*(width-((1)*2)) ]
|
162
|
-
hline2 = "|%s|" % [ " "*(width-((1)*2)) ]
|
163
|
-
window.printstring( row=startrow, col=startcol, hline, color)
|
164
|
-
print_title
|
165
|
-
(startrow+1).upto(startrow+height-1) do |row|
|
166
|
-
window.printstring(row, col=startcol, hline2, color)
|
167
|
-
end
|
168
|
-
window.printstring(startrow+height, col=startcol, hline, color)
|
169
|
-
=end
|
170
|
-
|
171
|
-
end
|
172
|
-
# private
|
173
|
-
def print_title
|
174
|
-
@form.window.printstring( @row, @col+(@width-@title.length)/2, @title, $datacolor, @title_attrib) unless @title.nil?
|
175
|
-
end
|
176
|
-
# text_area print footer
|
177
|
-
def print_foot
|
178
|
-
@footer_attrib ||= Ncurses::A_REVERSE
|
179
|
-
footer = "R: #{@prow+1}, C: #{@curpos}, #{@list.length} lines "
|
180
|
-
@form.window.printstring( @row + @height, @col+2, footer, $datacolor, @footer_attrib)
|
181
|
-
end
|
182
|
-
### FOR scrollable ###
|
183
|
-
def get_content
|
184
|
-
@list
|
185
|
-
end
|
186
|
-
def get_window
|
187
|
-
@form.window
|
188
|
-
end
|
189
|
-
### FOR scrollable ###
|
190
|
-
def repaint # textarea
|
191
|
-
paint
|
192
|
-
print_foot if @print_footer
|
193
|
-
end
|
194
|
-
def getvalue
|
195
|
-
@list
|
196
|
-
end
|
197
|
-
# textarea
|
198
|
-
|
199
|
-
def handle_key ch
|
200
|
-
@buffer = @list[@prow]
|
201
|
-
if @buffer.nil? and @list.length == 0
|
202
|
-
@list << "\n" # changed space to newline so wrapping puts a line.
|
203
|
-
@buffer = @list[@prow]
|
204
|
-
end
|
205
|
-
return if @buffer.nil?
|
206
|
-
$log.debug "TA: before: curpos #{@curpos} blen: #{@buffer.length}"
|
207
|
-
# on any line if the cursor is ahead of buffer length, ensure its on last position
|
208
|
-
# what if the buffer is somehow gt maxlen ??
|
209
|
-
if @curpos > @buffer.length
|
210
|
-
addcol(@buffer.length-@curpos)+1
|
211
|
-
@curpos = @buffer.length
|
212
|
-
end
|
213
|
-
$log.debug "TA: after : curpos #{@curpos} blen: #{@buffer.length}, w: #{@width} max #{@maxlen}"
|
214
|
-
pre_key
|
215
|
-
case ch
|
216
|
-
when ?\C-n.getbyte(0)
|
217
|
-
scroll_forward
|
218
|
-
when ?\C-p.getbyte(0)
|
219
|
-
scroll_backward
|
220
|
-
when ?\C-[.getbyte(0)
|
221
|
-
goto_start #cursor_start of buffer
|
222
|
-
when ?\C-].getbyte(0)
|
223
|
-
goto_end # cursor_end of buffer
|
224
|
-
when KEY_UP
|
225
|
-
#select_prev_row
|
226
|
-
ret = up
|
227
|
-
when KEY_DOWN
|
228
|
-
ret = down
|
229
|
-
when KEY_ENTER, 10, 13
|
230
|
-
insert_break
|
231
|
-
when KEY_LEFT
|
232
|
-
cursor_backward
|
233
|
-
when KEY_RIGHT
|
234
|
-
cursor_forward
|
235
|
-
when KEY_BACKSPACE, 127
|
236
|
-
if @editable # checking here means that i can programmatically bypass!!
|
237
|
-
delete_prev_char
|
238
|
-
#fire_handler :CHANGE, self # 2008-12-22 15:23
|
239
|
-
end
|
240
|
-
when 330, ?\C-d.getbyte(0) # delete char
|
241
|
-
if @editable
|
242
|
-
delete_curr_char
|
243
|
-
#fire_handler :CHANGE, self # 2008-12-22 15:23
|
244
|
-
end
|
245
|
-
when ?\C-k.getbyte(0) # delete till eol
|
246
|
-
if @editable
|
247
|
-
if @buffer == ""
|
248
|
-
delete_line
|
249
|
-
#fire_handler :CHANGE, self # 2008-12-22 15:23
|
250
|
-
else
|
251
|
-
delete_eol
|
252
|
-
#fire_handler :CHANGE, self # 2008-12-22 15:23
|
253
|
-
end
|
254
|
-
end
|
255
|
-
when ?\C-u.getbyte(0)
|
256
|
-
undo_delete
|
257
|
-
when ?\C-a.getbyte(0)
|
258
|
-
cursor_bol
|
259
|
-
when ?\C-e.getbyte(0)
|
260
|
-
cursor_eol
|
261
|
-
#set_form_col @buffer.length
|
262
|
-
else
|
263
|
-
#$log.debug(" textarea ch #{ch}")
|
264
|
-
ret = putc ch
|
265
|
-
return ret if ret == :UNHANDLED
|
266
|
-
end
|
267
|
-
post_key
|
268
|
-
set_form_row
|
269
|
-
set_form_col # testing 2008-12-26 19:37
|
270
|
-
end
|
271
|
-
def undo_delete
|
272
|
-
# added 2008-11-27 12:43 paste delete buffer into insertion point
|
273
|
-
@buffer.insert @curpos, @delete_buffer unless @delete_buffer.nil?
|
274
|
-
fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :INSERT, @prow, @delete_buffer) # 2008-12-24 18:34
|
275
|
-
end
|
276
|
-
def insert_break
|
277
|
-
return -1 unless @editable
|
278
|
-
# insert a blank row and append rest of this line to cursor
|
279
|
-
$log.debug "ENTER PRESSED at #{@curpos}, on row #{@prow}"
|
280
|
-
@delete_buffer = (delete_eol || "")
|
281
|
-
@list[@prow] << "\r"
|
282
|
-
$log.debug "DELETE BUFFER #{@delete_buffer}"
|
283
|
-
@list.insert @prow+1, @delete_buffer
|
284
|
-
@curpos = 0
|
285
|
-
down
|
286
|
-
@form.col = @orig_col + @col_offset
|
287
|
-
#addrowcol 1,0
|
288
|
-
@form.row = @row + 1 + @winrow
|
289
|
-
#fire_handler :CHANGE, self # 2008-12-09 14:56
|
290
|
-
fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :INSERT, @prow, @delete_buffer) # 2008-12-24 18:34
|
291
|
-
end
|
292
|
-
# puts cursor on correct row.
|
293
|
-
def set_form_row
|
294
|
-
@form.row = @row + 1 + @winrow
|
295
|
-
end
|
296
|
-
# set cursor on correct column
|
297
|
-
def set_form_col col1=@curpos
|
298
|
-
@curpos = col1
|
299
|
-
cursor_bounds_check
|
300
|
-
@form.col = @orig_col + @col_offset + @curpos
|
301
|
-
$log.debug "sfc: #{@orig_col}, #{@col_offset}. #{@curpos}. "
|
302
|
-
end
|
303
|
-
def cursor_bounds_check
|
304
|
-
max = buffer_len()
|
305
|
-
@curpos = max if @curpos > max # check 2008-12-27 00:02
|
306
|
-
end
|
307
|
-
def buffer_len
|
308
|
-
@list[@prow].nil? ? 0 : @list[@prow].chomp().length
|
309
|
-
end
|
310
|
-
def do_current_row # :yields current row
|
311
|
-
yield @list[@prow]
|
312
|
-
@buffer = @list[@prow]
|
313
|
-
end
|
314
|
-
def delete_eol
|
315
|
-
return -1 unless @editable
|
316
|
-
pos = @curpos-1
|
317
|
-
@delete_buffer = @buffer[@curpos..-1]
|
318
|
-
# if pos is 0, pos-1 becomes -1, end of line!
|
319
|
-
@list[@prow] = pos == -1 ? "" : @buffer[0..pos]
|
320
|
-
$log.debug "delete EOL :pos=#{pos}, #{@delete_buffer}: row: #{@list[@prow]}:"
|
321
|
-
@buffer = @list[@prow]
|
322
|
-
cursor_backward if @curpos > 0 # now cursor back goes up to prev line
|
323
|
-
#fire_handler :CHANGE, self # 2008-12-09 14:56
|
324
|
-
fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, @prow, @delete_buffer) # 2008-12-24 18:34
|
325
|
-
return @delete_buffer
|
326
|
-
end
|
327
|
-
def cursor_forward num=1
|
328
|
-
$log.debug "next char cp #{@curpos}, #{@buffer.length}. wi: #{@width}"
|
329
|
-
#if @curpos < @width and @curpos < @maxlen-1 # else it will do out of box
|
330
|
-
if @curpos < buffer_len()
|
331
|
-
@curpos += 1
|
332
|
-
addcol 1
|
333
|
-
else # trying this out 2008-12-26 20:18
|
334
|
-
@curpos = 0
|
335
|
-
down
|
336
|
-
end
|
337
|
-
cursor_bounds_check
|
338
|
-
end
|
339
|
-
def addcol num
|
340
|
-
@form.addcol num
|
341
|
-
end
|
342
|
-
def addrowcol row,col
|
343
|
-
@form.addrowcol row, col
|
344
|
-
end
|
345
|
-
def cursor_backward
|
346
|
-
if @curpos > 0
|
347
|
-
@curpos -= 1
|
348
|
-
addcol -1
|
349
|
-
else # trying this out 2008-12-26 20:18
|
350
|
-
ret = up
|
351
|
-
cursor_eol if ret != -1
|
352
|
-
end
|
353
|
-
end
|
354
|
-
def delete_line line=@prow
|
355
|
-
return -1 unless @editable
|
356
|
-
$log.debug "called delete line"
|
357
|
-
@delete_buffer = @list.delete_at line
|
358
|
-
@buffer = @list[@prow]
|
359
|
-
if @buffer.nil?
|
360
|
-
up
|
361
|
-
@form.row = @row + 1 + @winrow
|
362
|
-
end
|
363
|
-
#fire_handler :CHANGE, self # 2008-12-09 14:56
|
364
|
-
fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, @prow, @delete_buffer) # 2008-12-24 18:34
|
365
|
-
end
|
366
|
-
def delete_curr_char num=1
|
367
|
-
return -1 unless @editable
|
368
|
-
num.times do
|
369
|
-
delete_at
|
370
|
-
set_modified
|
371
|
-
end
|
372
|
-
end
|
373
|
-
def delete_prev_char num=1
|
374
|
-
return -1 if !@editable
|
375
|
-
num.times do
|
376
|
-
if @curpos <= 0
|
377
|
-
join_to_prev_line
|
378
|
-
return
|
379
|
-
end
|
380
|
-
@curpos -= 1 if @curpos > 0
|
381
|
-
delete_at
|
382
|
-
set_modified
|
383
|
-
addcol -1
|
384
|
-
end
|
385
|
-
end
|
386
|
-
# private
|
387
|
-
# when backspace pressed in position zero if the previous line is filled we may have to bring
|
388
|
-
# down the last word and join, rather than go up
|
389
|
-
def join_to_prev_line
|
390
|
-
return -1 unless @editable
|
391
|
-
return if @prow == 0
|
392
|
-
oldcurpos = @curpos
|
393
|
-
oldprow = @prow
|
394
|
-
prev = @list[@prow-1].chomp
|
395
|
-
prevlen = prev.length
|
396
|
-
# 2008-12-26 21:37 delete previous line if nothing there. This moves entire buffer up.
|
397
|
-
if prevlen == 0
|
398
|
-
delete_line @prow-1
|
399
|
-
up
|
400
|
-
return
|
401
|
-
end
|
402
|
-
space_left = @maxlen - prev.length
|
403
|
-
# BUG. carry full words up, or if no space then bring down last word of prev lien and join with first
|
404
|
-
carry_up = words_in_length @buffer, space_left #@buffer[0..space_left] # XXX
|
405
|
-
if carry_up.nil?
|
406
|
-
# carry down last word
|
407
|
-
prev_wd = remove_last_word @prow-1
|
408
|
-
@buffer.insert 0, prev_wd
|
409
|
-
@curpos = prev_wd.length
|
410
|
-
$log.debug " carry up nil! prev_wd (#{prev_wd}) len:#{prev_wd.length}"
|
411
|
-
fire_handler :CHANGE, InputDataEvent.new(0,prev_wd.length, self, :INSERT, oldprow, prev_wd) # 2008-12-26 23:07
|
412
|
-
else
|
413
|
-
$log.debug " carrying up #{carry_up.length} #{carry_up}, space: #{space_left}"
|
414
|
-
@list[@prow-1]=prev + carry_up
|
415
|
-
space_left2 = @buffer[(carry_up.length+1)..-1]
|
416
|
-
@list[@prow]=space_left2 #if !space_left2.nil?
|
417
|
-
@list[@prow] ||= ""
|
418
|
-
up
|
419
|
-
addrowcol -1,0
|
420
|
-
@curpos = prevlen
|
421
|
-
fire_handler :CHANGE, InputDataEvent.new(oldcurpos,carry_up.length, self, :DELETE, oldprow, carry_up) # 2008-12-24 18:34
|
422
|
-
fire_handler :CHANGE, InputDataEvent.new(prevlen,carry_up.length, self, :INSERT, oldprow-1, carry_up) # 2008-12-24 18:34
|
423
|
-
end
|
424
|
-
@form.col = @orig_col + @col_offset + @curpos
|
425
|
-
|
426
|
-
# $log.debug "carry up: nil" if carry_up.nil?
|
427
|
-
# $log.debug "listrow nil " if @list[@prow].nil?
|
428
|
-
# $log.debug "carry up: #{carry_up} prow:#{@list[@prow]}"
|
429
|
-
end
|
430
|
-
##
|
431
|
-
# return as many words as fit into len for carrying up..
|
432
|
-
# actually there is a case of when the next char (len+1) is a white space or word boundary. XXX
|
433
|
-
def words_in_length buff, len
|
434
|
-
return nil if len == 0
|
435
|
-
str = buff[0..len]
|
436
|
-
ix = str.rindex(/\s/)
|
437
|
-
$log.debug " str #{str} len #{len} ix #{ix} , buff #{buff}~"
|
438
|
-
return nil if ix.nil?
|
439
|
-
ix = ix > 0 ? ix - 1 : ix
|
440
|
-
$log.debug " str[]:#{str[0..ix]}~ len #{len} ix #{ix} , buff #{buff}~"
|
441
|
-
return str[0..ix]
|
442
|
-
end
|
443
|
-
# push the last word from given line to next
|
444
|
-
# I have modified it to push all words that are exceeding maxlen.
|
445
|
-
# This was needed for if i push 10 chars to next line, and the last word is less then the line will
|
446
|
-
# exceed. So i must push as many words as exceed length.
|
447
|
-
def push_last_word lineno=@prow
|
448
|
-
#lastspace = @buffer.rindex(" ")
|
449
|
-
#lastspace = @list[lineno].rindex(/ \w/)
|
450
|
-
line = @list[lineno]
|
451
|
-
line = @list[lineno][0..@maxlen+1] if line.length > @maxlen
|
452
|
-
lastspace = line.rindex(/ \w/)
|
453
|
-
$log.debug " PUSH:2 #{lastspace},#{line},"
|
454
|
-
if !lastspace.nil?
|
455
|
-
lastchars = @list[lineno][lastspace+1..-1]
|
456
|
-
@list[lineno] = @list[lineno][0..lastspace]
|
457
|
-
$log.debug "PUSH_LAST:ls:#{lastspace},lw:#{lastchars},lc:#{lastchars[-1]},:#{@list[lineno]}$"
|
458
|
-
if lastchars[-1,1] == "\r" or @list[lineno+1].nil?
|
459
|
-
# open a new line and keep the 10 at the end.
|
460
|
-
append_row lineno, lastchars
|
461
|
-
else
|
462
|
-
# check for soft tab \n - NO EVEN THIS LOGIC IS WRONG.
|
463
|
-
#if lastchars[-1,1] == "\n"
|
464
|
-
if lastchars[-1,1] != ' ' and @list[lineno+1][0,1] !=' '
|
465
|
-
#@list[lineno+1].insert 0, lastchars + ' '
|
466
|
-
insert_wrap lineno+1, 0, lastchars + ' '
|
467
|
-
else
|
468
|
-
#@list[lineno+1].insert 0, lastchars
|
469
|
-
insert_wrap lineno+1, 0, lastchars
|
470
|
-
end
|
471
|
-
end
|
472
|
-
return lastchars, lastspace
|
473
|
-
end
|
474
|
-
return nil
|
475
|
-
end
|
476
|
-
##
|
477
|
-
# this attempts to recursively insert into a row, seeing that any stuff exceeding is pushed down further.
|
478
|
-
# Yes, it should check for a para end and insert. Currently it could add to next para.
|
479
|
-
def insert_wrap lineno, pos, lastchars
|
480
|
-
@list[lineno].insert pos, lastchars
|
481
|
-
len = @list[lineno].length
|
482
|
-
if len > @maxlen
|
483
|
-
push_last_word lineno #- sometime i may push down 10 chars but the last word is less
|
484
|
-
end
|
485
|
-
end
|
486
|
-
##
|
487
|
-
# add one char. careful, i shoved a string in yesterday.
|
488
|
-
def putch char
|
489
|
-
@buffer ||= @list[@prow]
|
490
|
-
return -1 if !@editable #or @buffer.length >= @maxlen
|
491
|
-
if @chars_allowed != nil
|
492
|
-
return if char.match(@chars_allowed).nil?
|
493
|
-
end
|
494
|
-
raise "putch expects only one char" if char.length != 1
|
495
|
-
oldcurpos = @curpos
|
496
|
-
$log.debug "putch : pr:#{@prow}, cp:#{@curpos}, char:#{char}, lc:#{@buffer[-1]}, buf:(#{@buffer})"
|
497
|
-
@buffer.insert(@curpos, char)
|
498
|
-
@curpos += 1
|
499
|
-
$log.debug "putch INS: cp:#{@curpos}, max:#{@maxlen}, buf:(#{@buffer.length})"
|
500
|
-
if @curpos-1 > @maxlen or @buffer.length()-1 > @maxlen
|
501
|
-
lastchars, lastspace = push_last_word @prow
|
502
|
-
#$log.debug "last sapce #{lastspace}, lastchars:#{lastchars},lc:#{lastchars[-1]}, #{@list[@prow]} "
|
503
|
-
## wrap on word XX If last char is 10 then insert line
|
504
|
-
@buffer = @list[@prow]
|
505
|
-
if @curpos-1 > @maxlen or @curpos-1 > @buffer.length()-1
|
506
|
-
ret = down
|
507
|
-
# keep the cursor in the same position in the string that was pushed down.
|
508
|
-
@curpos = oldcurpos - lastspace #lastchars.length # 0
|
509
|
-
end
|
510
|
-
end
|
511
|
-
set_form_row
|
512
|
-
@buffer = @list[@prow]
|
513
|
-
set_form_col
|
514
|
-
@modified = true
|
515
|
-
#fire_handler :CHANGE, self # 2008-12-09 14:56
|
516
|
-
fire_handler :CHANGE, InputDataEvent.new(oldcurpos,@curpos, self, :INSERT, @prow, char) # 2008-12-24 18:34
|
517
|
-
0
|
518
|
-
end
|
519
|
-
def append_row lineno=@prow, chars=""
|
520
|
-
$log.debug "append row sapce:#{chars}."
|
521
|
-
@list.insert lineno+1, chars
|
522
|
-
end
|
523
|
-
##
|
524
|
-
# removes and returns last word in given line number, or nil if no whitespace
|
525
|
-
def remove_last_word lineno
|
526
|
-
@list[lineno].chomp!
|
527
|
-
line=@list[lineno]
|
528
|
-
lastspace = line.rindex(" ")
|
529
|
-
if !lastspace.nil?
|
530
|
-
lastchars = line[lastspace+1..-1]
|
531
|
-
@list[lineno].slice!(lastspace..-1)
|
532
|
-
$log.debug " remove_last: lastspace #{lastspace},#{lastchars},#{@list[lineno]}"
|
533
|
-
fire_handler :CHANGE, InputDataEvent.new(lastspace,lastchars.length, self, :DELETE, lineno, lastchars) # 2008-12-26 23:06
|
534
|
-
return lastchars
|
535
|
-
end
|
536
|
-
return nil
|
537
|
-
end
|
538
|
-
|
539
|
-
def putc c
|
540
|
-
if c >= 32 and c <= 126
|
541
|
-
ret = putch c.chr
|
542
|
-
if ret == 0
|
543
|
-
# addcol 1
|
544
|
-
set_modified
|
545
|
-
return 0
|
546
|
-
end
|
547
|
-
end
|
548
|
-
return :UNHANDLED
|
549
|
-
end
|
550
|
-
# DELETE func
|
551
|
-
def delete_at index=@curpos
|
552
|
-
return -1 if !@editable
|
553
|
-
$log.debug "dele : #{@prow} #{@buffer} #{index}"
|
554
|
-
char = @buffer.slice!(@curpos,1) # changed added ,1 and take char for event
|
555
|
-
# if no newline at end of this then bring up prev character/s till maxlen
|
556
|
-
# NO WE DON'T DO THIS ANYLONGER 2008-12-26 21:09 lets see
|
557
|
-
=begin
|
558
|
-
if @buffer[-1,1]!="\r"
|
559
|
-
@buffer[-1]=" " if @buffer[-1,1]=="\n"
|
560
|
-
if !next_line.nil? and next_line.length > 0
|
561
|
-
move_chars_up
|
562
|
-
end
|
563
|
-
end
|
564
|
-
=end
|
565
|
-
#@modified = true 2008-12-22 15:31
|
566
|
-
set_modified true
|
567
|
-
#fire_handler :CHANGE, self # 2008-12-09 14:56
|
568
|
-
fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos, self, :DELETE, @prow, char) # 2008-12-24 18:34
|
569
|
-
end
|
570
|
-
# move up one char from next row to current, used when deleting in a line
|
571
|
-
# should not be called if line ends in "\r"
|
572
|
-
def move_char_up
|
573
|
-
@list[@prow] << @list[@prow+1].slice!(0)
|
574
|
-
delete_line(@prow+1) if next_line().length==0
|
575
|
-
end
|
576
|
-
# tries to move up as many as possible
|
577
|
-
# should not be called if line ends in "\r"
|
578
|
-
def move_chars_up
|
579
|
-
oldprow = @prow
|
580
|
-
oldcurpos = @curpos
|
581
|
-
space_left = @maxlen - @buffer.length
|
582
|
-
can_move = [space_left, next_line.length].min
|
583
|
-
carry_up = @list[@prow+1].slice!(0, can_move)
|
584
|
-
@list[@prow] << carry_up
|
585
|
-
delete_line(@prow+1) if next_line().length==0
|
586
|
-
fire_handler :CHANGE, InputDataEvent.new(oldcurpos,oldcurpos+can_move, self, :INSERT, oldprow, carry_up) # 2008-12-24 18:34
|
587
|
-
end
|
588
|
-
## returns next line, does not move to it,
|
589
|
-
def next_line
|
590
|
-
@list[@prow+1]
|
591
|
-
end
|
592
|
-
def current_line
|
593
|
-
@list[@prow]
|
594
|
-
end
|
595
|
-
def do_relative_row num
|
596
|
-
yield @list[@prow+num]
|
597
|
-
end
|
598
|
-
def set_modified tf=true
|
599
|
-
@modified = tf
|
600
|
-
@form.modified = true if tf
|
601
|
-
end
|
602
|
-
def cursor_eol
|
603
|
-
$log.error "ERROR !!! bufferlen gt maxlen #{@buffer.length}, #{@maxlen}" if @buffer.length > @maxlen
|
604
|
-
set_form_col current_line().chomp().length()-1
|
605
|
-
end
|
606
|
-
def cursor_bol
|
607
|
-
set_form_col 0
|
608
|
-
end
|
609
|
-
def to_s
|
610
|
-
l = getvalue
|
611
|
-
str = ""
|
612
|
-
old = " "
|
613
|
-
l.each_with_index do |line, i|
|
614
|
-
tmp = line.gsub("\n","")
|
615
|
-
tmp.gsub!("\r", "\n")
|
616
|
-
if old[-1,1] !~ /\s/ and tmp[0,1] !~ /\s/
|
617
|
-
str << " "
|
618
|
-
end
|
619
|
-
str << tmp
|
620
|
-
old = tmp
|
621
|
-
end
|
622
|
-
str
|
623
|
-
end
|
624
|
-
end # class textarea
|
625
|
-
##
|
626
|
-
# A viewable read only box. Can scroll.
|
627
|
-
# Intention is to be able to change content dynamically - the entire list.
|
628
|
-
# Use set_content to set content, or just update the list attrib
|
629
|
-
# TODO -
|
630
|
-
# - searching, goto line - DONE
|
631
|
-
class OldTextView < Widget
|
632
|
-
include Scrollable
|
633
|
-
dsl_accessor :height # height of viewport
|
634
|
-
dsl_accessor :title # set this on top
|
635
|
-
dsl_accessor :title_attrib # bold, reverse, normal
|
636
|
-
dsl_accessor :footer_attrib # bold, reverse, normal
|
637
|
-
dsl_accessor :list # the array of data to be sent by user
|
638
|
-
dsl_accessor :maxlen # max len to be displayed
|
639
|
-
attr_reader :toprow # the toprow in the view (offsets are 0)
|
640
|
-
attr_reader :prow # the row on which cursor/focus is
|
641
|
-
attr_reader :winrow # the row in the viewport/window
|
642
|
-
dsl_accessor :print_footer
|
643
|
-
|
644
|
-
def initialize form, config={}, &block
|
645
|
-
@focusable = true
|
646
|
-
@editable = false
|
647
|
-
@left_margin = 1
|
648
|
-
@row = 0
|
649
|
-
@col = 0
|
650
|
-
@show_focus = false # don't highlight row under focus
|
651
|
-
@list = []
|
652
|
-
super
|
653
|
-
@row_offset = @col_offset = 1
|
654
|
-
@orig_col = @col
|
655
|
-
# this does result in a blank line if we insert after creating. That's required at
|
656
|
-
# present if we wish to only insert
|
657
|
-
@scrollatrow = @height-2
|
658
|
-
@content_rows = @list.length
|
659
|
-
@win = @form.window
|
660
|
-
init_scrollable
|
661
|
-
print_borders
|
662
|
-
@maxlen ||= @width-2
|
663
|
-
end
|
664
|
-
##
|
665
|
-
# send in a list
|
666
|
-
# e.g. set_content File.open("README.txt","r").readlines
|
667
|
-
#
|
668
|
-
def set_content list
|
669
|
-
@list = list
|
670
|
-
end
|
671
|
-
## display this row on top
|
672
|
-
def top_row(*val)
|
673
|
-
if val.empty?
|
674
|
-
@toprow
|
675
|
-
else
|
676
|
-
@toprow = val[0] || 0
|
677
|
-
@prow = val[0] || 0
|
678
|
-
end
|
679
|
-
end
|
680
|
-
## ---- for listscrollable ---- ##
|
681
|
-
def scrollatrow
|
682
|
-
@height - 2
|
683
|
-
end
|
684
|
-
def row_count
|
685
|
-
@list.length
|
686
|
-
end
|
687
|
-
##
|
688
|
-
# returns row of first match of given regex (or nil if not found)
|
689
|
-
def find_first_match regex
|
690
|
-
@list.each_with_index do |row, ix|
|
691
|
-
return ix if !row.match(regex).nil?
|
692
|
-
end
|
693
|
-
return nil
|
694
|
-
end
|
695
|
-
def rowcol
|
696
|
-
#$log.debug "textarea rowcol : #{@row+@row_offset+@winrow}, #{@col+@col_offset}"
|
697
|
-
return @row+@row_offset+@winrow, @col+@col_offset
|
698
|
-
end
|
699
|
-
def wrap_text(txt, col = @maxlen)
|
700
|
-
$log.debug "inside wrap text for :#{txt}"
|
701
|
-
txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/,
|
702
|
-
"\\1\\3\n")
|
703
|
-
end
|
704
|
-
def print_borders
|
705
|
-
window = @form.window
|
706
|
-
color = $datacolor
|
707
|
-
window.print_border @row, @col, @height, @width, color
|
708
|
-
print_title
|
709
|
-
=begin
|
710
|
-
hline = "+%s+" % [ "-"*(width-((1)*2)) ]
|
711
|
-
hline2 = "|%s|" % [ " "*(width-((1)*2)) ]
|
712
|
-
window.printstring(row=startrow, col=startcol, hline, color)
|
713
|
-
print_title
|
714
|
-
(startrow+1).upto(startrow+height-1) do |row|
|
715
|
-
window.printstring( row, col=startcol, hline2, color)
|
716
|
-
end
|
717
|
-
window.printstring( startrow+height, col=startcol, hline, color)
|
718
|
-
=end
|
719
|
-
|
720
|
-
end
|
721
|
-
def print_title
|
722
|
-
@form.window.printstring( @row, @col+(@width-@title.length)/2, @title, $datacolor, @title_attrib) unless @title.nil?
|
723
|
-
end
|
724
|
-
def print_foot
|
725
|
-
@footer_attrib ||= Ncurses::A_REVERSE
|
726
|
-
footer = "R: #{@prow+1}, C: #{@curpos}, #{@list.length} lines "
|
727
|
-
@form.window.printstring( @row + @height, @col+2, footer, $datacolor, @footer_attrib)
|
728
|
-
end
|
729
|
-
### FOR scrollable ###
|
730
|
-
def get_content
|
731
|
-
@list
|
732
|
-
end
|
733
|
-
def get_window
|
734
|
-
@form.window
|
735
|
-
end
|
736
|
-
### FOR scrollable ###
|
737
|
-
def repaint # textview
|
738
|
-
paint
|
739
|
-
print_foot if @print_footer
|
740
|
-
end
|
741
|
-
def getvalue
|
742
|
-
@list
|
743
|
-
end
|
744
|
-
# textview
|
745
|
-
# [ ] scroll left right DONE
|
746
|
-
def handle_key ch
|
747
|
-
@buffer = @list[@prow]
|
748
|
-
if @buffer.nil? and @list.length == 0
|
749
|
-
@list << "\r"
|
750
|
-
@buffer = @list[@prow]
|
751
|
-
end
|
752
|
-
return if @buffer.nil?
|
753
|
-
$log.debug " before: curpos #{@curpos} blen: #{@buffer.length}"
|
754
|
-
if @curpos > @buffer.length
|
755
|
-
addcol(@buffer.length-@curpos)+1
|
756
|
-
@curpos = @buffer.length
|
757
|
-
end
|
758
|
-
$log.debug "TV after loop : curpos #{@curpos} blen: #{@buffer.length}"
|
759
|
-
pre_key
|
760
|
-
case ch
|
761
|
-
when ?\C-n.getbyte(0)
|
762
|
-
scroll_forward
|
763
|
-
when ?\C-p.getbyte(0)
|
764
|
-
scroll_backward
|
765
|
-
when ?0.getbyte(0), ?\C-[.getbyte(0)
|
766
|
-
goto_start #start of buffer # cursor_start
|
767
|
-
when ?\C-].getbyte(0)
|
768
|
-
goto_end # end / bottom cursor_end
|
769
|
-
when KEY_UP
|
770
|
-
#select_prev_row
|
771
|
-
ret = up
|
772
|
-
#addrowcol -1,0 if ret != -1 or @winrow != @oldwinrow # positions the cursor up
|
773
|
-
@form.row = @row + 1 + @winrow
|
774
|
-
when KEY_DOWN
|
775
|
-
ret = down
|
776
|
-
@form.row = @row + 1 + @winrow
|
777
|
-
when KEY_LEFT
|
778
|
-
cursor_backward
|
779
|
-
when KEY_RIGHT
|
780
|
-
cursor_forward
|
781
|
-
when KEY_BACKSPACE, 127
|
782
|
-
cursor_backward
|
783
|
-
when 330
|
784
|
-
cursor_backward
|
785
|
-
when ?\C-a.getbyte(0)
|
786
|
-
# take care of data that exceeds maxlen by scrolling and placing cursor at start
|
787
|
-
set_form_col 0
|
788
|
-
@pcol = 0
|
789
|
-
when ?\C-e.getbyte(0)
|
790
|
-
# take care of data that exceeds maxlen by scrolling and placing cursor at end
|
791
|
-
blen = @buffer.rstrip.length
|
792
|
-
if blen < @maxlen
|
793
|
-
set_form_col blen
|
794
|
-
else
|
795
|
-
@pcol = blen-@maxlen
|
796
|
-
set_form_col @maxlen-1
|
797
|
-
end
|
798
|
-
else
|
799
|
-
$log.debug("TEXTVIEW XXX ch #{ch}")
|
800
|
-
return :UNHANDLED
|
801
|
-
end
|
802
|
-
post_key
|
803
|
-
# XXX 2008-11-27 13:57 trying out
|
804
|
-
set_form_row
|
805
|
-
end
|
806
|
-
# puts cursor on correct row.
|
807
|
-
def set_form_row
|
808
|
-
@form.row = @row + 1 + @winrow
|
809
|
-
end
|
810
|
-
# set cursor on correct column tview
|
811
|
-
def set_form_col col=@curpos
|
812
|
-
@curpos = col
|
813
|
-
@form.col = @orig_col + @col_offset + @curpos
|
814
|
-
end
|
815
|
-
def cursor_forward
|
816
|
-
if @curpos < @width and @curpos < @maxlen-1 # else it will do out of box
|
817
|
-
@curpos += 1
|
818
|
-
addcol 1
|
819
|
-
else
|
820
|
-
# XXX 2008-11-26 23:03 trying out
|
821
|
-
@pcol += 1 if @pcol <= @buffer.length
|
822
|
-
end
|
823
|
-
end
|
824
|
-
def addcol num
|
825
|
-
@form.addcol num
|
826
|
-
end
|
827
|
-
def addrowcol row,col
|
828
|
-
@form.addrowcol row, col
|
829
|
-
end
|
830
|
-
def cursor_backward
|
831
|
-
if @curpos > 0
|
832
|
-
@curpos -= 1
|
833
|
-
addcol -1
|
834
|
-
elsif @pcol > 0 # XXX added 2008-11-26 23:05
|
835
|
-
@pcol -= 1
|
836
|
-
end
|
837
|
-
end
|
838
|
-
def next_line
|
839
|
-
@list[@prow+1]
|
840
|
-
end
|
841
|
-
def do_relative_row num
|
842
|
-
yield @list[@prow+num]
|
843
|
-
end
|
844
|
-
end # class textview
|
845
|
-
end # modul
|