rbcurse 1.5.0 → 1.5.2

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 (104) hide show
  1. data/Makefile +21 -0
  2. data/Manifest.txt +6 -0
  3. data/README.markdown +6 -4
  4. data/TODO +372 -0
  5. data/TODO2.txt +121 -0
  6. data/VERSION +1 -1
  7. data/examples/README.txt +67 -0
  8. data/examples/abasiclist.rb +33 -0
  9. data/examples/alpmenu.rb +42 -0
  10. data/examples/app.rb +859 -0
  11. data/examples/app.sample +17 -0
  12. data/examples/appdirtree.rb +74 -0
  13. data/examples/appemail.rb +191 -0
  14. data/examples/appemaillb.rb +308 -0
  15. data/examples/appgcompose.rb +315 -0
  16. data/examples/atree.rb +64 -0
  17. data/examples/common/file.rb +40 -0
  18. data/examples/common/rmail.rb +257 -0
  19. data/examples/data.txt +683 -0
  20. data/examples/data/README.markdown +9 -0
  21. data/examples/data/brew.txt +38 -0
  22. data/examples/data/color.2 +37 -0
  23. data/examples/data/gemlist.txt +60 -0
  24. data/examples/data/lotr.txt +12 -0
  25. data/examples/data/ports.txt +136 -0
  26. data/examples/data/tasks.txt +27 -0
  27. data/examples/data/todocsv.csv +28 -0
  28. data/examples/data/unix1.txt +21 -0
  29. data/examples/data/unix2.txt +11 -0
  30. data/examples/dbdemo.rb +495 -0
  31. data/examples/deprecated/appgmail.rb +952 -0
  32. data/examples/deprecated/splitp.rb +56 -0
  33. data/examples/deprecated/testscrolllb.rb +86 -0
  34. data/examples/deprecated/testscrollp.rb +88 -0
  35. data/examples/deprecated/testscrollta.rb +80 -0
  36. data/examples/deprecated/testscrolltable.rb +165 -0
  37. data/examples/deprecated/testsplit.rb +87 -0
  38. data/examples/deprecated/testsplit2.rb +123 -0
  39. data/examples/deprecated/testsplit3.rb +215 -0
  40. data/examples/deprecated/testsplit3_1.rb +244 -0
  41. data/examples/deprecated/testsplit3a.rb +215 -0
  42. data/examples/deprecated/testsplit3b.rb +237 -0
  43. data/examples/deprecated/testsplitta.rb +148 -0
  44. data/examples/deprecated/testsplittv.rb +142 -0
  45. data/examples/deprecated/testsplittvv.rb +144 -0
  46. data/examples/deprecated/testtpane.rb +215 -0
  47. data/examples/deprecated/testtpane2.rb +145 -0
  48. data/examples/deprecated/testtpanetable.rb +203 -0
  49. data/examples/dirtree.rb +88 -0
  50. data/examples/experimental/resultsetdemo.rb +280 -0
  51. data/examples/experimental/testmform.rb +35 -0
  52. data/examples/experimental/testscroller.rb +117 -0
  53. data/examples/experimental/teststackflow.rb +111 -0
  54. data/examples/menu1.rb +112 -0
  55. data/examples/multispl.rb +86 -0
  56. data/examples/newmessagebox.rb +131 -0
  57. data/examples/newtabbedwindow.rb +100 -0
  58. data/examples/newtesttabp.rb +121 -0
  59. data/examples/qdfilechooser.rb +68 -0
  60. data/examples/rfe.rb +1239 -0
  61. data/examples/rfe_renderer.rb +121 -0
  62. data/examples/sqlc.rb +454 -0
  63. data/examples/sqlm.rb +437 -0
  64. data/examples/sqlt.rb +408 -0
  65. data/examples/status.txt +68 -0
  66. data/examples/table1.rb +24 -0
  67. data/examples/term2.rb +84 -0
  68. data/examples/test1.rb +239 -0
  69. data/examples/test2.rb +674 -0
  70. data/examples/testapp.rb +44 -0
  71. data/examples/testapp2.rb +58 -0
  72. data/examples/testchars.rb +137 -0
  73. data/examples/testcombo.rb +91 -0
  74. data/examples/testkeypress.rb +66 -0
  75. data/examples/testlistbox.rb +113 -0
  76. data/examples/testmenu.rb +101 -0
  77. data/examples/testmulticomp.rb +70 -0
  78. data/examples/testmulticontainer.rb +94 -0
  79. data/examples/testmultispl.rb +199 -0
  80. data/examples/testree.rb +106 -0
  81. data/examples/testtable.rb +264 -0
  82. data/examples/testtabp.rb +107 -0
  83. data/examples/testtodo.rb +584 -0
  84. data/examples/testvimsplit.rb +112 -0
  85. data/examples/testwsshortcuts.rb +64 -0
  86. data/examples/testwsshortcuts2.rb +126 -0
  87. data/examples/todo.db +0 -0
  88. data/examples/todo.yml +191 -0
  89. data/examples/viewtodo.rb +574 -0
  90. data/lib/rbcurse/deprecated/README.markdown +12 -0
  91. data/lib/rbcurse/deprecated/rpad.rb +375 -0
  92. data/lib/rbcurse/deprecated/rscrollpane.rb +512 -0
  93. data/lib/rbcurse/deprecated/rsplitpane.rb +894 -0
  94. data/lib/rbcurse/deprecated/rsplitpane2.rb +1009 -0
  95. data/lib/rbcurse/deprecated/rviewport.rb +204 -0
  96. data/lib/rbcurse/deprecated/widgets/mapper.rb +130 -0
  97. data/lib/rbcurse/deprecated/widgets/rmessagebox.rb +348 -0
  98. data/lib/rbcurse/deprecated/widgets/rtabbedpane.rb +1158 -0
  99. data/lib/rbcurse/deprecated/widgets/rtabbedwindow.rb +167 -0
  100. data/lib/rbcurse/deprecated/widgets/scrollable.rb +301 -0
  101. data/lib/rbcurse/deprecated/widgets/stdscrwindow.rb +309 -0
  102. data/lib/ver/keyboard2.rb +170 -0
  103. data/test/test_rbcurse.rb +0 -0
  104. metadata +131 -9
@@ -0,0 +1,167 @@
1
+ =begin
2
+ * Name: tabbed pane: can have multiple forms overlapping.
3
+ * Description: This embeds a tabbedpane inside a window - a retake on tabbedwindow
4
+ * Author: rkumar
5
+
6
+ * Consists of a main window and form that contains the TabbedPane and several buttons
7
+ below.
8
+ The tabbedpane itself contains a Form for the buttons, and then one form and Pad
9
+ each for the tab. Check TabbedPane for details since it can change.
10
+
11
+ --------
12
+ * Date: 2011-10-17 3:38 PM
13
+ * License:
14
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
15
+
16
+ =end
17
+ require 'logger'
18
+ require 'rbcurse'
19
+ require 'rbcurse/rtabbedpane'
20
+
21
+ include RubyCurses
22
+ module RubyCurses
23
+ extend self
24
+
25
+ # TODO : insert_tab, remove_tab, disable/hide tab
26
+ # Hotkeys should be defined with ampersand, too.
27
+ #
28
+ class TabbedWindow
29
+ include EventHandler
30
+ dsl_accessor :row, :col
31
+ dsl_accessor :height, :width
32
+ dsl_accessor :button_type # ok, ok_cancel, yes_no
33
+ dsl_accessor :buttons # used if type :custom
34
+ attr_reader :selected_index
35
+ def initialize win, aconfig={}, &block
36
+ @parent = win
37
+ @bgcolor ||= "black" # 0
38
+ @color ||= "white" # $datacolor
39
+ @attr = nil
40
+
41
+ @config = aconfig
42
+ @config.each_pair { |k,v| variable_set(k,v) }
43
+ instance_eval &block if block_given?
44
+ @tp = nil
45
+ end
46
+ def tabbed_pane
47
+ return @tp if @tp
48
+ @layout = { :height => @height, :width => @width, :top => @row, :left => @col }
49
+ #@layout = { :height => 0, :width => 0, :top => 0, :left => 0 }
50
+ @window = VER::Window.new(@layout)
51
+ @form = RubyCurses::Form.new @window
52
+ @form.name = "TWindow"
53
+ @form.navigation_policy = :CYCLICAL
54
+ h = @layout[:height] == 0 ? FFI::NCurses.LINES-2 : @layout[:height]-2
55
+ w = @layout[:width] == 0 ? FFI::NCurses.COLS : @layout[:width]-0
56
+ h -= 0
57
+ w -= 0
58
+ r = 0 # @row-0
59
+ c =0 # @col
60
+ @tp = RubyCurses::TabbedPane.new @form, :height => h, :width =>w, :row => r, :col => c
61
+ return @tp
62
+ end
63
+ #
64
+ # I am honestly not sure what block anyone is gonna pass to Tab
65
+ # I confess i may have been even more ignorant than I am today. We
66
+ # could use the block here, pass form here, if component not given especially
67
+ def add_tab text, component = nil, aconfig={}, &block
68
+ @tp ||= tabbed_pane
69
+ t = @tp.add_tab text, component, aconfig #, &block # NOTE, not passing block there
70
+ if block_given?
71
+ yield @tp.form(t)
72
+ end
73
+ return t
74
+ end
75
+ alias :tab :add_tab
76
+ alias :new_tab :add_tab
77
+ ##
78
+ def repaint
79
+ end
80
+ def show
81
+ # first create the main top window with the tab buttons on it.
82
+ @window.bkgd(Ncurses.COLOR_PAIR($datacolor));
83
+ @window.box( 0, 0);
84
+ @window.wrefresh
85
+ Ncurses::Panel.update_panels
86
+ create_buttons
87
+ @form.repaint
88
+ #handle_keys
89
+ # need to convey button pressed
90
+ end
91
+ def handle_keys
92
+ begin
93
+ while (( ch=@window.getchar()) != 999)
94
+ break if ch == ?\C-q.getbyte(0) || @stop
95
+ ret = @form.handle_key(ch)
96
+ if ret == :UNHANDLED
97
+ ret = @form.process_key ch, self # field
98
+ @form.repaint
99
+ end
100
+ @window.wrefresh
101
+ break if @stop # 2011-10-21 somehow not coming out
102
+ end
103
+ return if @stop
104
+ ensure
105
+ destroy
106
+ end
107
+ end
108
+ def destroy
109
+ @window.destroy
110
+ end
111
+ def create_buttons
112
+ case @button_type.to_s.downcase
113
+ when "ok"
114
+ make_buttons ["&OK"]
115
+ when "ok_cancel" #, "input", "list", "field_list"
116
+ make_buttons %w[&OK &Cancel]
117
+ when "yes_no"
118
+ make_buttons %w[&Yes &No]
119
+ when "yes_no_cancel"
120
+ make_buttons ["&Yes", "&No", "&Cancel"]
121
+ when "custom"
122
+ raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
123
+ make_buttons @buttons
124
+ else
125
+ $log.debug "No buttontype passed for creating tabbedpane. Using default (OK)"
126
+ make_buttons ["&OK"]
127
+ end
128
+ end
129
+ def make_buttons names
130
+ $log.debug "XXX: came to TW make buttons FORM= #{@form.name} "
131
+ total = names.inject(0) {|total, item| total + item.length + 4}
132
+ bcol = center_column total
133
+
134
+ # this craps out when height is zero
135
+ brow = @layout[:height]-2
136
+ brow = FFI::NCurses.LINES-2 if brow < 0
137
+ button_ct=0
138
+ names.each_with_index do |bname, ix|
139
+ text = bname
140
+ #underline = @underlines[ix] if !@underlines.nil?
141
+
142
+ button = Button.new @form do
143
+ text text
144
+ name bname
145
+ row brow
146
+ col bcol
147
+ #underline underline
148
+ highlight_background $reversecolor
149
+ color $datacolor
150
+ bgcolor $datacolor
151
+ end
152
+ index = button_ct
153
+ button.command { |form| @selected_index = index; @stop = true; $log.debug "Pressed Button #{bname}";}
154
+ button_ct += 1
155
+ bcol += text.length+6
156
+ end
157
+ end
158
+ def center_column textlen
159
+ width = @layout[:width].ifzero( FFI::NCurses.COLS )
160
+ return (width-textlen)/2
161
+ end
162
+
163
+
164
+ end # class TabbedWindow
165
+
166
+
167
+ end # module
@@ -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.getbyte(0)
225
+ scroll_forward
226
+ when 32
227
+ scroll_forward
228
+ when ?\C-p.getbyte(0)
229
+ scroll_backward
230
+ when ?0.getbyte(0)
231
+ goto_start
232
+ when ?9.getbyte(0)
233
+ goto_end
234
+ when ?[.getbyte(0)
235
+ when ?[.getbyte(0)
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.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0)
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