rbcurse 1.5.0 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
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