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.
Files changed (123) hide show
  1. data/CHANGELOG +45 -0
  2. data/Makefile +1 -1
  3. data/Manifest.txt +91 -0
  4. data/NOTES +349 -2
  5. data/README.markdown +12 -0
  6. data/VERSION +1 -1
  7. data/examples/abasiclist.rb +25 -0
  8. data/examples/alpmenu.rb +42 -0
  9. data/examples/app.rb +883 -0
  10. data/examples/appcombo.rb +17 -0
  11. data/examples/appdirtree.rb +73 -0
  12. data/examples/appemail.rb +164 -0
  13. data/examples/appemaillb.rb +308 -0
  14. data/examples/appgcompose.rb +303 -0
  15. data/examples/appgmail.rb +951 -0
  16. data/examples/atree.rb +56 -0
  17. data/examples/dirtree.rb +78 -0
  18. data/examples/focusmanager.rb +31 -0
  19. data/examples/imap.rb +48 -0
  20. data/examples/menu1.rb +79 -0
  21. data/examples/multispl.rb +86 -0
  22. data/examples/rfe.rb +3 -4
  23. data/examples/rmail.rb +188 -0
  24. data/examples/s.rb +10 -0
  25. data/examples/scrollbar.rb +104 -0
  26. data/examples/splitp.rb +56 -0
  27. data/examples/table1.rb +30 -0
  28. data/examples/term.rb +48 -0
  29. data/examples/term2.rb +54 -0
  30. data/examples/test1.rb +4 -2
  31. data/examples/test2.rb +9 -9
  32. data/examples/testapp.rb +44 -0
  33. data/examples/testapp2.rb +51 -0
  34. data/examples/testcombo.rb +2 -2
  35. data/examples/testgmail.rb +46 -0
  36. data/examples/testlistbox.rb +0 -1
  37. data/examples/testmultispl.rb +199 -0
  38. data/examples/testree.rb +127 -0
  39. data/examples/testscroller.rb +0 -1
  40. data/examples/testscrolllb.rb +1 -1
  41. data/examples/testscrollp.rb +2 -1
  42. data/examples/testscrollta.rb +1 -1
  43. data/examples/testscrolltable.rb +1 -2
  44. data/examples/testsplit.rb +1 -1
  45. data/examples/testsplit2.rb +1 -1
  46. data/examples/testsplit3.rb +1 -1
  47. data/examples/testsplit3_1.rb +1 -1
  48. data/examples/testsplit3a.rb +1 -1
  49. data/examples/testsplit3b.rb +1 -1
  50. data/examples/testsplitta.rb +1 -1
  51. data/examples/testsplittv.rb +1 -1
  52. data/examples/testsplittvv.rb +1 -1
  53. data/examples/testtodo.rb +491 -488
  54. data/examples/testvimsplit.rb +111 -0
  55. data/examples/todo.db +0 -0
  56. data/examples/todocsv.csv +28 -0
  57. data/examples/viewtodo.rb +408 -403
  58. data/lib/rbcurse/action.rb +1 -0
  59. data/lib/rbcurse/app.rb +1294 -0
  60. data/lib/rbcurse/applicationheader.rb +7 -2
  61. data/lib/rbcurse/checkboxcellrenderer.rb +0 -12
  62. data/lib/rbcurse/colormap.rb +34 -8
  63. data/lib/rbcurse/comboboxcellrenderer.rb +0 -11
  64. data/lib/rbcurse/defaultlistselectionmodel.rb +23 -7
  65. data/lib/rbcurse/extras/bottomline.rb +1681 -0
  66. data/lib/rbcurse/extras/directorylist.rb +445 -0
  67. data/lib/rbcurse/extras/directorytree.rb +69 -0
  68. data/lib/rbcurse/extras/divider.rb +310 -0
  69. data/lib/rbcurse/extras/focusmanager.rb +31 -0
  70. data/lib/rbcurse/extras/listselectable.rb +222 -0
  71. data/lib/rbcurse/extras/masterdetail.rb +164 -0
  72. data/lib/rbcurse/extras/menutree.rb +63 -0
  73. data/lib/rbcurse/extras/rlink.rb +27 -0
  74. data/lib/rbcurse/extras/rmenulink.rb +21 -0
  75. data/lib/rbcurse/extras/scrollbar.rb +134 -0
  76. data/lib/rbcurse/extras/stdscrwindow.rb +247 -0
  77. data/lib/rbcurse/extras/tabular.rb +258 -0
  78. data/lib/rbcurse/extras/tabularwidget.rb +1070 -0
  79. data/lib/rbcurse/extras/viewer.rb +106 -0
  80. data/lib/rbcurse/io.rb +137 -80
  81. data/lib/rbcurse/keylabelprinter.rb +4 -0
  82. data/lib/rbcurse/listcellrenderer.rb +91 -59
  83. data/lib/rbcurse/listscrollable.rb +93 -95
  84. data/lib/rbcurse/listselectable.rb +60 -7
  85. data/lib/rbcurse/ractionevent.rb +67 -0
  86. data/lib/rbcurse/rbasiclistbox.rb +688 -0
  87. data/lib/rbcurse/rcombo.rb +5 -5
  88. data/lib/rbcurse/rcommandwindow.rb +555 -0
  89. data/lib/rbcurse/rinputdataevent.rb +12 -0
  90. data/lib/rbcurse/rlistbox.rb +305 -124
  91. data/lib/rbcurse/rmenu.rb +99 -46
  92. data/lib/rbcurse/rmessagebox.rb +13 -6
  93. data/lib/rbcurse/rmulticontainer.rb +54 -93
  94. data/lib/rbcurse/rmultisplit.rb +731 -0
  95. data/lib/rbcurse/rmultitextview.rb +3 -2
  96. data/lib/rbcurse/rpopupmenu.rb +0 -1
  97. data/lib/rbcurse/rprogress.rb +117 -0
  98. data/lib/rbcurse/rscrollpane.rb +2 -1
  99. data/lib/rbcurse/rsplitpane.rb +94 -20
  100. data/lib/rbcurse/rsplitpane2.rb +1009 -0
  101. data/lib/rbcurse/rtabbedpane.rb +3 -2
  102. data/lib/rbcurse/rtabbedwindow.rb +0 -1
  103. data/lib/rbcurse/rtable.rb +92 -64
  104. data/lib/rbcurse/rtextarea.rb +91 -57
  105. data/lib/rbcurse/rtextview.rb +223 -70
  106. data/lib/rbcurse/rtree.rb +723 -0
  107. data/lib/rbcurse/rviewport.rb +2 -1
  108. data/lib/rbcurse/rvimsplit.rb +768 -0
  109. data/lib/rbcurse/rwidget.rb +524 -325
  110. data/lib/rbcurse/table/tablecellrenderer.rb +1 -1
  111. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -1
  112. data/lib/rbcurse/tree/treecellrenderer.rb +137 -0
  113. data/lib/rbcurse/tree/treemodel.rb +428 -0
  114. data/lib/rbcurse/vieditable.rb +14 -13
  115. data/lib/ver/ncurses.rb +6 -0
  116. data/lib/ver/window.rb +67 -32
  117. metadata +99 -23
  118. data/bin/rbcurse +0 -0
  119. data/examples/rvimsplit.rb +0 -376
  120. data/examples/todo.rb +0 -1
  121. data/lib/rbcurse/rform.rb +0 -845
  122. data/lib/rbcurse/selectable.rb +0 -94
  123. data/rbcurse.gemspec +0 -188
data/bin/rbcurse DELETED
File without changes
@@ -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