rkumar-rbcurse 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/CHANGELOG +1577 -0
  2. data/README.txt +310 -0
  3. data/examples/qdfilechooser.rb +68 -0
  4. data/examples/rfe.rb +853 -0
  5. data/examples/rfe_renderer.rb +69 -0
  6. data/examples/test1.rb +242 -0
  7. data/examples/test2.rb +498 -0
  8. data/examples/testcombo.rb +95 -0
  9. data/examples/testkeypress.rb +61 -0
  10. data/examples/testmenu.rb +105 -0
  11. data/examples/testtable.rb +266 -0
  12. data/examples/testtabp.rb +106 -0
  13. data/examples/testtodo.rb +532 -0
  14. data/examples/viewtodo.rb +512 -0
  15. data/lib/rbcurse.rb +7 -0
  16. data/lib/rbcurse/action.rb +31 -0
  17. data/lib/rbcurse/applicationheader.rb +57 -0
  18. data/lib/rbcurse/celleditor.rb +120 -0
  19. data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
  20. data/lib/rbcurse/colormap.rb +133 -0
  21. data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
  22. data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
  23. data/lib/rbcurse/keylabelprinter.rb +143 -0
  24. data/lib/rbcurse/listcellrenderer.rb +99 -0
  25. data/lib/rbcurse/listkeys.rb +33 -0
  26. data/lib/rbcurse/listscrollable.rb +216 -0
  27. data/lib/rbcurse/listselectable.rb +67 -0
  28. data/lib/rbcurse/mapper.rb +108 -0
  29. data/lib/rbcurse/orderedhash.rb +77 -0
  30. data/lib/rbcurse/rcombo.rb +243 -0
  31. data/lib/rbcurse/rdialogs.rb +183 -0
  32. data/lib/rbcurse/rform.rb +845 -0
  33. data/lib/rbcurse/rinputdataevent.rb +36 -0
  34. data/lib/rbcurse/rlistbox.rb +804 -0
  35. data/lib/rbcurse/rmenu.rb +666 -0
  36. data/lib/rbcurse/rmessagebox.rb +325 -0
  37. data/lib/rbcurse/rpopupmenu.rb +754 -0
  38. data/lib/rbcurse/rtabbedpane.rb +259 -0
  39. data/lib/rbcurse/rtable.rb +1296 -0
  40. data/lib/rbcurse/rtextarea.rb +673 -0
  41. data/lib/rbcurse/rtextview.rb +335 -0
  42. data/lib/rbcurse/rwidget.rb +1731 -0
  43. data/lib/rbcurse/scrollable.rb +301 -0
  44. data/lib/rbcurse/selectable.rb +94 -0
  45. data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
  46. data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
  47. data/lib/ver/keyboard.rb +150 -0
  48. data/lib/ver/keyboard2.rb +170 -0
  49. data/lib/ver/ncurses.rb +102 -0
  50. data/lib/ver/window.rb +369 -0
  51. data/test/test_rbcurse.rb +0 -0
  52. metadata +117 -0
@@ -0,0 +1,301 @@
1
+ #### ---------------------- ####
2
+ # CAUTION: This is the worst piece of code ever written, pls do not
3
+ # go further. I will remove this very soon.
4
+ # -- Shamefully yours.
5
+ #### ---------------------- ####
6
+ # Provides the ability to scroll content, typically an array
7
+ # widget that includes may override on_enter_row and on_leave_row
8
+ # This was essentially copied and modifed from the pad scroller
9
+ # i think i can redo it and make it much simpler XXX
10
+ module Scrollable
11
+ def init_scrollable
12
+ @toprow = @prow = @winrow = @pcol = 0
13
+ @oldwinrow = @oldprow = @oldtoprow = 0
14
+ @startrow = 1 # from where we start prniting, taking header row into account
15
+ @cols = @width
16
+ @left_margin ||= 2
17
+ @show_focus = true if @show_focus.nil?
18
+
19
+ # @right_margin ||= @left_margin
20
+ # @scrollatrow ||= @height-2
21
+ end
22
+ def goto_start
23
+ @prow = 0
24
+ @toprow = @prow
25
+ @winrow = 0
26
+ end
27
+ def goto_end
28
+ @prow = get_content().length-1
29
+ #@toprow = @prow
30
+ #@winrow = 0 # not putting this was cause prow < toprow !!
31
+ @toprow = @prow - @scrollatrow # ensure screen is filled when we show last. so clear not required
32
+ @toprow = 0 if @toprow < 0
33
+ ## except what if very few rows
34
+ @winrow = @scrollatrow
35
+ end
36
+ def right
37
+ @hscrollcols ||= @cols/2
38
+ @pcol += @hscrollcols if @pcol + @hscrollcols < @padcols
39
+ # window_erase @win XXX
40
+ end
41
+ def left
42
+ @hscrollcols ||= @cols/2
43
+ @pcol -= @hscrollcols if @pcol > 0
44
+ @pcol = 0 if @pcol < 0
45
+ end
46
+ # not that saving content_rows is buggy since we add rows.
47
+ def down num=1
48
+ # $log.debug "inside down"
49
+ num.times do
50
+ if @prow >= get_content().length-1
51
+ #Ncurses.beep
52
+ @message = "No more rows"
53
+ return -1
54
+ end
55
+ if @winrow < @scrollatrow # 20
56
+ @winrow += 1 # move cursor down
57
+ else
58
+ @toprow += 1 # scroll down a row
59
+ end
60
+ @prow += 1 # incr pad row
61
+ end
62
+ end
63
+ def up num=1 # UP
64
+ num.times do
65
+ if @prow <= 0
66
+ #Ncurses.beep
67
+ @message = "This is the first row"
68
+ @prow = 0
69
+ return -1
70
+ else
71
+ @prow -= 1
72
+ end
73
+ if @winrow > 0
74
+ @winrow -= 1
75
+ else
76
+ @toprow -= 1 if @toprow > 0
77
+ end
78
+ @toprow = @prow if @prow < @toprow
79
+ end
80
+ end
81
+ def scroll_forward
82
+ if @toprow + @scrollatrow+1 >= get_content().length
83
+ # so cursor goes to last line
84
+ @prow += get_content().length - @prow - 1 # XXX 2008-11-27 14:18
85
+ else
86
+ @toprow += @scrollatrow+1 # @rows-2 2008-11-13 23:41 put toprow here too
87
+ $log.debug "space pr #{@prow}"
88
+ @prow = @toprow
89
+ end
90
+ end
91
+ def scroll_backward
92
+ if @prow <= 0
93
+ @message = "This is the first row"
94
+ @prow = 0
95
+ #next
96
+ else
97
+ @prow -= (@scrollatrow+1) #(@rows-2)
98
+ @prow = 0 if @prow < 0
99
+ end
100
+ @toprow = @prow
101
+ end
102
+ def pre_key
103
+ @oldprow = @prow
104
+ @oldtoprow = @toprow
105
+ @oldwinrow = @winrow
106
+ end
107
+ # prior to repaint. but after keypress
108
+ def post_key
109
+ # $log.debug "1 post_key w:#{@winrow} p:#{@prow} t:#{@toprow}"
110
+ @toprow = @prow if @prow < @toprow # ensre search could be
111
+ @toprow = @prow if @prow > @toprow + @scrollatrow
112
+ @winrow = @prow - @toprow
113
+ # $log.debug "2 post_key w:#{@winrow} p:#{@prow} t:#{@toprow}"
114
+ # wont work first time - added 2008-11-26 20:56
115
+ if @oldprow != @prow
116
+ $log.debug "going to call on leave and on enter"
117
+ on_leave_row @oldprow if respond_to? :on_leave_row # to be defined by widget that has included this
118
+ on_enter_row @prow if respond_to? :on_enter_row # to be defined by widget that has included this
119
+ end
120
+ #@form.row = @winrow
121
+ set_form_row
122
+
123
+ end
124
+ ##
125
+ # caution, this now uses winrow not prow
126
+ def show_focus_on_row row0, _prow, tf=true
127
+ # color = tf ? $reversecolor : $datacolor
128
+ # if cursor on row, reverse else normal
129
+ attr = tf ? Ncurses::A_REVERSE : Ncurses::A_NORMAL
130
+ color = @color_pair
131
+ r = row0+1
132
+ #check if row is selected or not
133
+ row_att = @list_attribs[_prow] unless @list_attribs.nil?
134
+ if !row_att.nil?
135
+ status = row_att.fetch(:status, " ")
136
+ attr1 = row_att[:bgcolor]
137
+ color = attr1 unless attr1.nil?
138
+ end
139
+ @datawidth ||= @width-2
140
+ return if r > get_content().length
141
+ @form.window.mvchgat(y=r+@row, x=1+@col, max=@datawidth, attr, color, nil)
142
+ end
143
+ ##
144
+ # unfocus the previous row cursor was on
145
+ # and put focus on currrent row
146
+ # Called after repaint
147
+ def show_focus
148
+ show_focus_on_row(@oldwinrow, @oldprow, false)
149
+ show_focus_on_row(@winrow, @prow, true)
150
+ # printstr @form.window, 23, 10, @prow
151
+ end
152
+ ## call from repaint
153
+ # TODO i can simplif, i think
154
+ # - if user scrolls horizontally, use column as starting point
155
+ def paint
156
+ #$log.debug "called paint t:#{@toprow} p:#{@prow} w:#{@winrow}"
157
+ list = get_content
158
+ @content_rows = list.length # rows can be added at any time
159
+ win = get_window
160
+ maxlen = @maxlen ||= @width-2
161
+ if @bgcolor.is_a? String and @color.is_a? String
162
+ acolor = ColorMap.get_color(@color, @bgcolor)
163
+ else
164
+ acolor = $datacolor
165
+ end
166
+ @color_pair = acolor
167
+ 0.upto(@height-2) {|r|
168
+ if @toprow + r < @content_rows
169
+ # this relates to selection of a row, as yet
170
+ # check if any status of attribs for this row
171
+ row_att = @list_attribs[@toprow+r] unless @list_attribs.nil?
172
+ status = " "
173
+ #bgcolor = $datacolor
174
+ bgcolor = nil
175
+ if !row_att.nil?
176
+ status = row_att.fetch(:status, " ")
177
+ bgcolor = row_att[:bgcolor]
178
+ end
179
+ # sanitize
180
+ content = list[@toprow+r].chomp # don't display newline
181
+ content.gsub!(/\t/, ' ') # don't display tab
182
+ content.gsub!(/[^[:print:]]/, '') # don't display non print characters
183
+
184
+ #content = content[0..maxlen-1] if !content.nil? && content.length > maxlen # only show maxlen
185
+ if !content.nil?
186
+ if content.length > maxlen # only show maxlen
187
+ content = content[@pcol..@pcol+maxlen-1]
188
+ else
189
+ content = content[@pcol..-1]
190
+ end
191
+ end
192
+
193
+ width = @width-(@left_margin+1)
194
+ @form.window.printstring @row+r+1, @col+@left_margin-1, "%s" % status, acolor, @attr if @implements_selectable
195
+ @form.window.printstring @row+r+1, @col+@left_margin, "%-*s" % [width,content], acolor, @attr
196
+ win.mvchgat(y=r+@row+1, x=@col+@left_margin, max=width, Ncurses::A_NORMAL, bgcolor, nil) unless bgcolor.nil?
197
+ dollar = "|"
198
+ dollar = "$" if list[@toprow+r][-1,1]=="\r"
199
+ @form.window.printstring @row+r+1, @col+@width-1, dollar, acolor, @attr
200
+
201
+ else
202
+ # clear the displayed area
203
+ @form.window.printstring @row+r+1, @col+@left_margin, " "*(@width-(@left_margin+1)), acolor
204
+ dollar = "|"
205
+ @form.window.printstring @row+r+1, @col+@width-1, dollar, acolor, @attr
206
+ end
207
+ }
208
+ show_focus if @show_focus
209
+ end
210
+ ## for user to know which row is being focussed on
211
+ def focussed_index
212
+ @prow
213
+ end
214
+ # only to be used in single selection cases as focussed item FIXME.
215
+ def selected_item
216
+ get_content()[focussed_index()]
217
+ end
218
+ alias :current_index :focussed_index
219
+ alias :selected_index :focussed_index
220
+ def scrollable_handle_key ch
221
+ begin
222
+ pre_key
223
+ case ch
224
+ when ?\C-n
225
+ scroll_forward
226
+ when 32
227
+ scroll_forward
228
+ when ?\C-p
229
+ scroll_backward
230
+ when ?0
231
+ goto_start
232
+ when ?9
233
+ goto_end
234
+ when ?[
235
+ when ?[
236
+ when KEY_UP
237
+ #select_prev_row
238
+ up
239
+ when KEY_LEFT
240
+ when KEY_RIGHT
241
+ when KEY_DOWN
242
+ down
243
+ # select_next_row
244
+ when KEY_ENTER, 10, 13
245
+ if respond_to? :fire
246
+ fire
247
+ end
248
+ when ?A..?Z, ?a..?z
249
+ ret = set_selection_for_char ch.chr
250
+ else
251
+ return :UNHANDLED #if ret == -1
252
+ end
253
+ ensure
254
+ post_key
255
+ end
256
+ end # handle_k listb
257
+ ## 2008-12-18 18:03
258
+ # finds the next match for the char pressed
259
+ # returning the index
260
+ def next_match char
261
+ data = get_content
262
+ row = focussed_index
263
+ currval = data[row].chomp
264
+ row.upto(data.length-1) do |ix|
265
+ val = data[ix].chomp
266
+ if val[0,1] == char and val != currval
267
+ return ix
268
+ end
269
+ end
270
+ 0.upto(row) do |ix|
271
+ val = data[ix].chomp
272
+ if val[0,1] == char and val != currval
273
+ return ix
274
+ end
275
+ end
276
+ return -1
277
+ end
278
+ ## 2008-12-18 18:03
279
+ # sets the selection to the next row starting with char
280
+ def set_selection_for_char char
281
+ ix = next_match char
282
+ @prow = ix if ix != -1
283
+ return ix
284
+ end
285
+ ##
286
+ # 2008-12-18 18:05
287
+ # set focus on given index
288
+ def set_focus_on arow
289
+ return if arow > get_content().length-1 or arow < 0
290
+ total = get_content().length
291
+ @prow = arow
292
+ sar = @scrollatrow + 1
293
+ @toprow = (@prow / sar) * sar
294
+
295
+ if total - @toprow < sar
296
+ @toprow = (total - sar)
297
+ end
298
+ @winrow = @prow - @toprow
299
+ end
300
+
301
+ end
@@ -0,0 +1,94 @@
1
+ ##
2
+ # give the ability to a list, to allow for selection of rows.
3
+ #
4
+ module Selectable
5
+ SELECT_CHAR = '>'
6
+ # @param index of row in list, offset 0
7
+ # This puts an > character on the first col of the selected row
8
+ def do_select arow=@prow
9
+ @implements_selectable = true
10
+ win = get_window
11
+ visual_index = row_visual_index arow
12
+ sel = " "; r = arow+1;
13
+ @selected ||= []
14
+ if @selected.include? arow
15
+ @selected.delete arow
16
+ @list_attribs[arow] = {:status=> " ", :bgcolor => nil}
17
+ sel = " "; color = $datacolor
18
+ else
19
+ $log.debug("Adding #{arow} #{@select_mode}")
20
+ do_clear_selection if @select_mode != 'multiple'
21
+ @selected << arow
22
+ # 2008-11-25 21:00 added this just to see if it make things better
23
+ @list_attribs[arow] = {:status=> SELECT_CHAR, :bgcolor => $selectedcolor}
24
+ sel = SELECT_CHAR; color = $selectedcolor
25
+ end
26
+ # remember to erase these skidmarks when the user scrolls
27
+ win.printstring @row+1+visual_index, @col+@left_margin-1, sel, color unless visual_index.nil?
28
+ # fire ListComboSelect event, added TODO to test out.
29
+ fire_handler :LIST_COMBO_SELECT, arow
30
+ end
31
+ ## is the row in view, if so, return index, else nil
32
+ def row_visual_index arow
33
+ if arow >= @toprow and arow <= @toprow+@scrollatrow
34
+ $log.debug "return visual #{arow-@toprow} "
35
+ return arow-@toprow
36
+ end
37
+ $log.debug "return visual NIL #{arow-@toprow} "
38
+ nil
39
+ end
40
+ def do_next_selection
41
+ return if @selected.length == 0
42
+ row = @selected.sort.find { |i| i > @prow }
43
+ row ||= @prow
44
+ @prow = row
45
+ end
46
+ def do_prev_selection
47
+ return if @selected.length == 0
48
+ row = @selected.sort{|a,b| b <=> a}.find { |i| i < @prow }
49
+ row ||= @prow
50
+ @prow = row
51
+ end
52
+ # FIXME not clearing properly
53
+ def do_clear_selection
54
+ $log.debug " CALLED clear_sel "
55
+ @selected.each {|sel|
56
+ $log.debug " CLAER for #{sel}"
57
+ do_select(sel)}
58
+ end
59
+ def get_selected_data
60
+ return nil if @selected.nil?
61
+ ret = []
62
+ list = get_content
63
+ @selected.each { |sel| ret << list[sel] }
64
+ return ret
65
+ end
66
+ alias :get_selected_items :get_selected_data # data should be deprecated
67
+ ##
68
+ # XXX in case of single selection popup, only ENTER selects and it closes too firing PRESS.
69
+ # in case of multiple selection and popup, space selects and fires COMBO_SELECT, but enter closes and fires
70
+ # a different event, PRESS. This needs to be regularized.
71
+ def selectable_handle_key ch
72
+ begin
73
+ case ch
74
+ when ?;, 32 # x no more selecting since we now jump to row matching char 2008-12-18 13:13
75
+ return if is_popup and @select_mode == 'single' # not allowing select this way since there will be a difference
76
+ # between pressing ENTER and space. Enter is trapped by Listbox!
77
+ do_select
78
+ when ?'
79
+ $log.debug "insdie next selection"
80
+ do_next_selection if @select_mode == 'multiple'
81
+ when ?"
82
+ $log.debug "insdie prev selection"
83
+ do_prev_selection if @select_mode == 'multiple'
84
+ when ?\C-e
85
+ do_clear_selection if @select_mode == 'multiple'
86
+ else
87
+ return :UNHANDLED
88
+ end
89
+ ensure
90
+ #### post_key 2009-01-07 13:43
91
+ end
92
+ 0
93
+ end
94
+ end
@@ -0,0 +1,85 @@
1
+ require 'rubygems'
2
+ require 'ncurses'
3
+ require 'logger'
4
+ module RubyCurses
5
+ class TableCellRenderer
6
+ include DSL
7
+ #include EventHandler
8
+ include ConfigSetup
9
+ include RubyCurses::Utils
10
+ dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
11
+ dsl_accessor :display_length # please give this to ensure the we only print this much
12
+ dsl_accessor :height # if you want a multiline label.
13
+ dsl_accessor :text # text of label
14
+ dsl_accessor :color, :bgcolor
15
+ dsl_accessor :row, :col
16
+ dsl_accessor :parent #usuall the table to get colors and other default info
17
+
18
+ def initialize text="", config={}, &block
19
+ @text = text
20
+ @editable = false
21
+ @focusable = false
22
+ config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
23
+ instance_eval &block if block_given?
24
+ init_vars
25
+ end
26
+ def init_vars
27
+ @justify ||= :left
28
+ @display_length ||= 10
29
+ end
30
+ def transform value
31
+ return value.to_s
32
+ end
33
+
34
+ ##
35
+ # XXX need to move wrapping etc up and done once.
36
+ def repaint graphic, r=@row,c=@col, value=@text, focussed=false, selected=false
37
+ lablist = []
38
+ #value=value.to_s # ??
39
+ value=transform value
40
+ if @height && @height > 1
41
+ lablist = wrap_text(value, @display_length).split("\n")
42
+ else
43
+ # ensure we do not exceed
44
+ if !@display_length.nil?
45
+ if value.length > @display_length
46
+ dlen = @display_length - 1
47
+ dlen = 0 if dlen < 0
48
+ value = value[0..dlen]
49
+ end
50
+ end
51
+ lablist << value
52
+ end
53
+ len = @display_length || value.length
54
+ acolor = get_color $datacolor
55
+ #acolor =get_color $datacolor, @color || @parent.color, @bgcolor || @parent.bgcolor #unless @parent.nil?
56
+ _attr = Ncurses::A_NORMAL
57
+ if selected
58
+ _attr = Ncurses::A_BOLD if selected
59
+ acolor =get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor unless @parent.nil?
60
+ end
61
+ if focussed
62
+ _attr |= Ncurses::A_REVERSE
63
+ end
64
+ #$log.debug "label :#{@text}, #{value}, #{r}, #{c} col= #{@color}, #{@bgcolor} acolor= #{acolor} j:#{@justify} dlL: #{@display_length} "
65
+ _height = @height || 1
66
+ str = @justify.to_sym == :right ? "%*s" : "%-*s" # added 2008-12-22 19:05
67
+ # loop added for labels that are wrapped.
68
+ # TODO clear separately since value can change in status like labels
69
+ 0.upto(_height-1) { |i|
70
+ graphic.printstring r+i, c, " " * len , acolor,_attr
71
+ }
72
+ lablist.each_with_index do |_value, ix|
73
+ break if ix >= _height
74
+ if @justify.to_sym == :center
75
+ padding = (@display_length - _value.length)/2
76
+ padding = 0 if padding < 0
77
+ _value = " "*padding + _value + " "*padding # so its cleared if we change it midway
78
+ end
79
+ graphic.printstring r, c, str % [len, _value], acolor,_attr
80
+ r += 1
81
+ end
82
+ end
83
+ # ADD HERE LABEL
84
+ end
85
+ end