rbcurse-experimental 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,75 @@
1
+ # rbcurse-experimental
2
+
3
+ This is related to the rbcurse ncurses toolkit, for building ncurses applications.
4
+
5
+ This provides stuff I've experimented with, and tested to some extent. It can be useful stuff to build upon
6
+ or to even use if it suits your purposes. Most of this stuff has been tested with positive cases and not
7
+ with negative data. It is minimally tested.
8
+
9
+ Use for home or unimportant programs, preferable don't release these widgets for public use.
10
+
11
+ Please submit patches if you find bugs or improve upon it.
12
+
13
+ > We better hurry up and start coding, there are going to be a lot of bugs to fix.
14
+
15
+ Contents as of time of creation of repo:
16
+
17
+ * directorylist.rb - shows directory in a list, allowing various kinds of selection and filtering and ENTER
18
+
19
+ * directorytree.rb - shows directory in a tree, allowing expansion
20
+
21
+ * masterdetail.rb - master detail pattern, two widgets
22
+
23
+ * multiform.rb - do not touch this at all. Should be nuked. It works but in order to keep
24
+ rbcurse simple and maintainable, I advise against using forms within forms. I've spent
25
+ weeks and months tracking cursor placement for forms within forms as in the old
26
+ tabbedpane and some old deprecated widgets.
27
+
28
+ * resultsetbrowser.rb - I am working on database aware widgets, check dbdemo.rb in examples
29
+
30
+ * resultsettextview.rb - same as above
31
+
32
+ * rscrollform.rb - a form that can display more objects than the window, scrolls horiz and vertically.
33
+ Used and tested only with single line widgets like Field, not with textviews and lists.
34
+
35
+ * stackflow.rb - widget that allows complex weightages to be assigned to stacks and flows
36
+ and resizing if window dimension changes. Tested only with weightages and not
37
+ absolute sizes. Expects weightages to be correct. More work can go into this
38
+ to make it robust.
39
+
40
+ * undomanager.rb - used in lists and textareas to support undo and redo. I've used it but
41
+ its a very simple piece of code and I am not too confident how well it will stand
42
+ in heavy use. Certainly use it for lists and textareas in personal applications.
43
+
44
+
45
+
46
+ ## Short story
47
+
48
+ Minimally tested but interesting stuff
49
+
50
+ ## Long story
51
+
52
+ Use stuff here at your own risk. Most of this works, and will work in most situations but may not take care validations, extreme cases, wrong data passed.
53
+
54
+ Its tested for basic use cases. Samples should help you. Don't use in production, or release for others to use. Use for personal use if you have too.
55
+
56
+
57
+ Feel free to fork and further develop stuff in here, or submit patches to me.
58
+
59
+ Some of this stuff may move to extras or core if its really useful and stable.
60
+
61
+ ## See also
62
+
63
+ * rbcurse - <http://github.com/rkumar/rbcurse/>
64
+
65
+ * rbcurse-core - <http://github.com/rkumar/rbcurse-core/>
66
+
67
+ * rbcurse-extras - <http://github.com/rkumar/rbcurse-extras/>
68
+
69
+ ## Install
70
+
71
+ gem install rbcurse-experimental
72
+
73
+ ## License
74
+
75
+ Same as ruby license.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,113 @@
1
+ # #!/usr/bin/env ruby -w
2
+ =begin
3
+ * Name : teststackflow.rb
4
+ * Description : to test Container2.rb (to be renamed)
5
+ * :
6
+ * Author : rkumar http://github.com/rkumar/rbcurse/
7
+ * Date : 25.10.11 - 12:57
8
+ * License :
9
+ * Last update : Use ,,L to update
10
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
11
+
12
+ =end
13
+
14
+
15
+ if __FILE__ == $PROGRAM_NAME
16
+ require 'rbcurse/core/util/app'
17
+ require 'rbcurse/extras/widgets/rlistbox'
18
+ require 'rbcurse/experimental/widgets/stackflow'
19
+ App.new do
20
+
21
+ lb = Listbox.new nil, :list => ["borodin","berlioz","bernstein","balakirev", "elgar"] , :name => "mylist"
22
+ lb1 = Listbox.new nil, :list => ["bach","beethoven","mozart","gorecki", "chopin","wagner","grieg","holst"] , :name => "mylist1"
23
+
24
+ lb2 = Listbox.new nil, :list => `gem list --local`.split("\n") , :name => "mylist2"
25
+
26
+ alist = %w[ ruby perl python java jruby macruby rubinius rails rack sinatra pylons django cakephp grails]
27
+ str = "Hello, people of Earth.\nI am HAL, a textbox.\nUse arrow keys, j/k/h/l/gg/G/C-a/C-e/C-n/C-p\n"
28
+ str << alist.join("\n")
29
+ require 'rbcurse/core/widgets/rtextview'
30
+ tv = TextView.new nil, :name => "text"
31
+ tv.set_content str
32
+ =begin
33
+ f1 = field "name", :maxlen => 20, :display_length => 20, :bgcolor => :white,
34
+ :color => :black, :text => "abc", :label => " Name: ", :label_color_pair => @datacolor
35
+ f2 = field "email", :display_length => 20, :bgcolor => :white,
36
+ :color => :blue, :text => "me@google.com", :label => "Email: ", :label_color_pair => @datacolor
37
+ f3 = radio :group => :grp, :text => "red", :value => "RED", :color => :red
38
+ f4 = radio :group => :grp, :text => "blue", :value => "BLUE", :color => :blue
39
+ f5 = radio :group => :grp, :text => "green", :value => "GREEN", :color => :green
40
+ =end
41
+
42
+ f1 = Field.new nil, :maxlen => 20, :display_length => 20, :bgcolor => :white,
43
+ :color => :black, :text => "abc", :label => " Name: ", :label_color_pair => @datacolor,
44
+ :valid_regex => /[A-Z][a-z]*/
45
+ f2 = Field.new nil, :display_length => 20, :bgcolor => :white,
46
+ :color => :blue, :text => "me@google.com", :label => "Email: ", :label_color_pair => @datacolor
47
+ f3 = Field.new nil, :display_length => 20, :bgcolor => :white,
48
+ :color => :blue, :text => "24", :label => "Age: ", :label_color_pair => @datacolor,
49
+ :valid_range => (20..100)
50
+ w = Ncurses.COLS-1
51
+ h = Ncurses.LINES-3
52
+ r = StackFlow.new @form, :row => 1, :col => 1, :width => w, :height => h, :title => "Stack n Flow with margins" do
53
+ #stack :margin_top => 2, :margin_left => 1 do
54
+ flow :margin_top => 0, :margin_left => 2, :margin_right => 0, :orientation => :right do #:weight => 49 do
55
+ add tv, :weight => 40
56
+ add lb2 , :weight => 50
57
+ end
58
+ stack :margin_top => 0, :orientation => :bottom do #stack :height => 12, :width => 78 do
59
+ add lb, :weight => 40, :margin_left => 1
60
+ add lb1 , :weight => 40
61
+ #add f1
62
+ #stack :weight => 30 do
63
+ #add f1
64
+ #add f2
65
+ #add f3
66
+ end
67
+ #end # stack
68
+ end # r
69
+ def increase_height
70
+ @r.height += 1
71
+ @r.repaint_all(true)
72
+ end
73
+ def increase_width
74
+ @r.width += 1
75
+ @r.repaint_all(true)
76
+ end
77
+ @r = r
78
+ @r.bind_key(?\M-w) {increase_width}
79
+ @r.bind_key(?\M-h) {increase_height}
80
+ @r.bind_key(0) {
81
+ f = @r.item_for tv
82
+ f1 = @r.item_for lb2
83
+ p = @r.parent_of tv
84
+ p1 = @r.parent_of lb2
85
+ $log.debug "XXX: ITEM_FOR tv is #{f}, #{f1} #{p} , #{p1} "
86
+ @ctr ||= 0
87
+ case @ctr
88
+ when 0
89
+ @r.components[0].orientation = :left
90
+ when 1
91
+ @r.components[0].orientation = :right
92
+ when 2
93
+ @r.components[1].orientation = :top
94
+ when 3
95
+ @r.components[1].orientation = :bottom
96
+ else
97
+ @ctr = -1
98
+ end
99
+ $status_message.value =" Flow: #{@r.components[0].orientation} | Stack #{@r.components[1].orientation}. Use C-Space to change "
100
+ @r.repaint_all(true)
101
+ @ctr += 1
102
+
103
+ }
104
+ $status_message.value =" Flow: #{@r.components[0].orientation} | Stack #{@r.components[1].orientation}. Use Ctrl-Space to change "
105
+
106
+ #r.add(f1)
107
+ #r.add(f2)
108
+ #r.add(f3,f4,f5)
109
+ #sl = status_line
110
+
111
+ st = status_line :row => -1
112
+ end # app
113
+ end # if
@@ -0,0 +1,467 @@
1
+ require 'rbcurse'
2
+ require 'fileutils'
3
+ require 'rbcurse/extras/widgets/rlistbox'
4
+ require 'rbcurse/core/include/vieditable'
5
+ require 'rbcurse/experimental/widgets/undomanager'
6
+ ##
7
+ # Created on : Wed Sep 22 22:30:13 IST 2010
8
+ # (c) rkumar (arunachalesha)
9
+ #
10
+ module RubyCurses
11
+ # Display a directory listing, allowing user to drill down on pressing Enter
12
+ # on a directory, or sort when pressing enter on header row.
13
+ class DirectoryList < Listbox
14
+
15
+ include ViEditable
16
+
17
+ def initialize form, config={}, &block
18
+ @hide_dot_files = false
19
+ @hide_others = false
20
+ @curpos = 0
21
+ super
22
+
23
+ #@current_path ||= Dir.getwd # setting it causes selection not to fire if same one
24
+ # is selected first
25
+ @_header_array = [ "Attr", "Size", "Modified" , "Name" , "<Order_by_Extension>" ]
26
+ @_header = " %s %8s %19s %s %s " % @_header_array
27
+ end
28
+ def init_vars
29
+ # which rows are not data, thus don't fire, or give error
30
+ @_non_data_indices = []
31
+ @_header_row_index = 0
32
+ @_first_data_index = 1
33
+ @one_key_selection = false # this allows us to map keys to methods
34
+ vieditable_init_listbox
35
+ undom = SimpleUndo.new self
36
+ bind_key(?\M-h, :scroll_left)
37
+ bind_key(?\M-l, :scroll_right)
38
+ bind_key(KEY_RIGHT, :cursor_forward)
39
+ bind_key(KEY_LEFT, :cursor_backward)
40
+ bind_key(?$, :end_of_line)
41
+ bind_key(?\C-e, :end_of_line)
42
+ bind_key(?\C-a, :start_of_line)
43
+ bind_key(?a, :select_all)
44
+ bind_key(?*, :invert_selection)
45
+ bind_key(?u, :clear_selection)
46
+ bind_key(?+, :ask_select)
47
+ bind_key(?-, :ask_unselect)
48
+ bind_key(?I) { @hide_dot_files = !@hide_dot_files; prune_entries; }
49
+ #bind_key(?v, :view_current) # does not respond to ??? XXX
50
+ bind_key(?v) {view_current}
51
+ super
52
+ end
53
+ # changing the current path, refreshes files
54
+ def current_path(*val)
55
+ if val.empty?
56
+ return @current_path
57
+ else
58
+ raise ArgumentError, "current_path should be a directory:#{val[0]}." unless File.directory? val[0]
59
+ oldvalue = @current_path
60
+ if oldvalue != val[0]
61
+ @current_path = val[0]
62
+ populate @current_path
63
+ fire_property_change(:current_path, oldvalue, @current_path)
64
+ end
65
+ end
66
+ self
67
+ end
68
+ # populate the list with file names
69
+ # @param [String, Array] string is the path name to populate with
70
+ # Array is a list of files
71
+ def populate path
72
+ case path
73
+ when String
74
+ @current_path = path
75
+ @entries = Dir.new(path).entries
76
+ @entries.delete(".")
77
+ # isn;t it a bit late here. it needs to happen to what's already there
78
+ @entries.delete_if {|x| x =~ /^\./} if @hide_dot_files
79
+ @entries.delete_if {|x| x =~ /\.bak$/ || x=~/\.swp$/} if @hide_others
80
+ when Array
81
+ path = @current_path
82
+ # we've been passed @entries so we don't need to put it again ??? XXX
83
+ end
84
+ # TODO K M etc
85
+ list @entries
86
+ @list.insert 0, @_header
87
+ @title = @current_path
88
+ @current_index = @_first_data_index
89
+ set_form_row if @form
90
+ end
91
+ # called by parent's repaint
92
+ def convert_value_to_text file, crow
93
+ if @short
94
+ file
95
+ else
96
+ if crow == @_header_row_index
97
+ return file
98
+ else
99
+ # OUCH i don't know if its a header !!
100
+ fullname = File.join(@current_path, file)
101
+ fname = file
102
+ stat = File::Stat.new fullname
103
+ time = stat.mtime.to_s[0..18]
104
+ attr = stat.directory? ? "d" : "-"
105
+ attr << (stat.writable? ? "w" : "-")
106
+ attr << (stat.readable? ? "r" : "-")
107
+ attr << (stat.executable? ? "x" : "-")
108
+ fname << "/" if stat.directory? && fname[-1] != "/"
109
+ value = " %s %8d %s %s" % [attr, stat.size, time, fname]
110
+ return value
111
+ end
112
+ end
113
+ end
114
+
115
+ def ___create_default_cell_renderer
116
+ cell_renderer( RubyCurses::DirectoryListCellRenderer.new "", {:color=>@color, :bgcolor=>@bgcolor, :parent => self, :display_length=> @width-2-@left_margin})
117
+ end
118
+ def _get_word_under_cursor line=@_header, pos=@curpos
119
+ finish = line.index(" ", pos)
120
+ start = line.rindex(" ",pos)
121
+ finish = -1 if finish.nil?
122
+ start = 0 if start.nil?
123
+ return line[start..finish]
124
+ end
125
+ # sorts entries by various parameters.
126
+ # Not optimal since it creates file stat objects each time rather than cacheing, but this is a demo of widgets
127
+ # not a real directory lister!
128
+ def sort_by key, reverse=false
129
+ # remove parent before sorting, keep at top
130
+ first = @entries.delete_at(0) if @entries[0]==".."
131
+ #key ||= @sort_key
132
+ sort_keys = { 'Name' => :name, 'Modified' => :mtime, "Size" => :size, "<Order_by_Extension>" => :ext, 'Attr' => :attr, "Accessed" => :atime }
133
+ key = sort_keys[key] if sort_keys.has_key? key
134
+ #if key == @sort_key
135
+ #reverse = true
136
+ #end
137
+ cdir=@current_path+"/"
138
+ case key
139
+ when :size
140
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
141
+ if reverse
142
+ xs.size <=> ys.size
143
+ else
144
+ ys.size <=> xs.size
145
+ end
146
+ }
147
+ when :mtime
148
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
149
+ if reverse
150
+ xs.mtime <=> ys.mtime
151
+ else
152
+ ys.mtime <=> xs.mtime
153
+ end
154
+ }
155
+ when :atime
156
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
157
+ if reverse
158
+ xs.atime <=> ys.atime
159
+ else
160
+ ys.atime <=> xs.atime
161
+ end
162
+ }
163
+ when :name
164
+ @entries.sort! {|x,y| x <=> y
165
+ if reverse
166
+ x <=> y
167
+ else
168
+ y <=> x
169
+ end
170
+ }
171
+ when :ext
172
+ @entries.sort! {|x,y|
173
+ if reverse
174
+ File.extname(cdir+x) <=> File.extname(cdir+y)
175
+ else
176
+ File.extname(cdir+y) <=> File.extname(cdir+x)
177
+ end
178
+ }
179
+ when :attr
180
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
181
+ x = xs.directory? ? "d" : "D"
182
+ y = ys.directory? ? "d" : "D"
183
+ if reverse
184
+ x <=> y
185
+ else
186
+ y <=> x
187
+ end
188
+ }
189
+ end
190
+ @sort_key = key
191
+ @entries.insert 0, first unless first.nil? # keep parent on top
192
+ populate @entries
193
+ end
194
+ GIGA_SIZE = 1073741824.0
195
+ MEGA_SIZE = 1048576.0
196
+ KILO_SIZE = 1024.0
197
+
198
+ # Return the file size with a readable style.
199
+ def readable_file_size(size, precision)
200
+ case
201
+ #when size == 1 : "1 B"
202
+ when size < KILO_SIZE then "%d B" % size
203
+ when size < MEGA_SIZE then "%.#{precision}f K" % (size / KILO_SIZE)
204
+ when size < GIGA_SIZE then "%.#{precision}f M" % (size / MEGA_SIZE)
205
+ else "%.#{precision}f G" % (size / GIGA_SIZE)
206
+ end
207
+ end
208
+ def date_format t
209
+ t.strftime "%Y/%m/%d"
210
+ end
211
+
212
+ # on pressing Enter, execute this action.
213
+ # Here we take the current file and if its a directory, we step into it.
214
+ def fire_action_event
215
+ if @_non_data_indices.include? @current_index
216
+ Ncurses.error
217
+ return
218
+ end
219
+ $log.debug "inside fire_action_event of directorylist #{@current_index} #{toprow} "
220
+ if @_header_row_index == @current_index
221
+ # user hit enter on the header row. we determine column and sort.
222
+ header = _get_word_under_cursor
223
+ #@reverse = false
224
+ if header == @_last_header_sorted
225
+ @reverse = !@reverse # clicking 2 times won't reverse again
226
+ else
227
+ @reverse = false
228
+ end
229
+ sort_by header.strip, @reverse
230
+ # this next line will keep the cursor on header after sorting
231
+ # earlier cursor would appear in header but selection would be data row
232
+ @current_index = @_header_row_index # FFI 2011-09-16 keeping cursor synched with selection
233
+ @_last_header_sorted = header
234
+ set_form_row
235
+ return
236
+ end
237
+ value = current_value
238
+ value = value.split.last
239
+ if value == ".."
240
+ _path = File.dirname(@current_path)
241
+ else
242
+ _path = File.join(@current_path, value)
243
+ end
244
+ if File.directory? _path
245
+ populate _path
246
+ end
247
+ $log.debug "after fire_action_event of directorylist #{@current_index} #{toprow} "
248
+
249
+ super
250
+ end
251
+ def addcol num
252
+ #@repaint_required = true
253
+ @repaint_footer_required = true # 2010-01-23 22:41
254
+ if @form
255
+ @form.addcol num
256
+ else
257
+ @parent_component.form.addcol num
258
+ end
259
+ end
260
+ # set cursor column position
261
+ # if i set col1 to @curpos, i can move around left right if key mapped
262
+ def set_form_col col1=@curpos
263
+ col1 ||= 0
264
+ @cols_panned ||= 0 # RFED16 2010-02-17 23:40
265
+ win_col = 0 # 2010-02-17 23:19 RFED16
266
+ col2 = win_col + @col + @col_offset + col1 + @cols_panned + @left_margin
267
+ setrowcol nil, col2 # 2010-02-17 23:19 RFED16
268
+ end
269
+ def start_of_line
270
+ @repaint_required = true if @pcol > 0 # tried other things but did not work
271
+ set_form_col 0
272
+ @pcol = 0
273
+ end
274
+ # this does not work, since the value in list is not the printed value
275
+ def end_of_line
276
+ blen = current_value.rstrip.length
277
+ set_form_col blen
278
+ end
279
+
280
+ def cursor_backward
281
+ repeatm {
282
+ if @curpos > 0
283
+ @curpos -= 1
284
+ set_form_col
285
+ #addcol -1
286
+ elsif @pcol > 0
287
+ @pcol -= 1
288
+ end
289
+ }
290
+ #@repaint_required = true
291
+ @repaint_footer_required = true # 2010-01-23 22:41
292
+ end
293
+
294
+
295
+ def cursor_forward
296
+ @curpos ||= 0
297
+ maxlen = @maxlen || @width-2
298
+ repeatm {
299
+ if @curpos < @width and @curpos < maxlen-1 # else it will do out of box
300
+ @curpos += 1
301
+ addcol 1
302
+ else
303
+ #@pcol += 1 if @pcol <= @buffer.length
304
+ # buffer not eixstent FIXME
305
+ end
306
+ }
307
+ set_form_col
308
+ #@repaint_required = true
309
+ @repaint_footer_required = true # 2010-01-23 22:41
310
+ end
311
+ def [](index)
312
+ @entries[index]
313
+ end
314
+
315
+ @private
316
+ def longest_line=(l)
317
+ @longest_line = l
318
+ end
319
+ def longest_line
320
+ @longest_line
321
+ end
322
+ # modify a file name.
323
+ # call using 'C'
324
+ def edit_line lineno=@current_index
325
+ line = @list[lineno]
326
+ fullname = File.join(@current_path, line)
327
+ prompt = "Rename file [#{line}] to: "
328
+ maxlen = 80
329
+ config={};
330
+ oldline = line.dup
331
+ config[:default] = line
332
+ ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
333
+ $log.debug " rbgetstr returned #{ret} , #{str} "
334
+ return if ret != 0
335
+ @list[lineno].replace(str)
336
+ FileUtils.mv fullname, File.join(@current_path, str)
337
+ fire_handler :CHANGE, InputDataEvent.new(0,oldline.length, self, :DELETE_LINE, lineno, oldline)
338
+ fire_handler :CHANGE, InputDataEvent.new(0,str.length, self, :INSERT_LINE, lineno, str)
339
+ @repaint_required = true
340
+ end
341
+ def ask_select
342
+ prompt = "Select Files: "
343
+ maxlen = 80
344
+ config={}
345
+ config[:default] = @file_pattern if @file_pattern
346
+ ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
347
+ return if ret != 0
348
+ @file_pattern = str
349
+ # 2011-09-19 doesn't work if pwd changed
350
+ if Dir.pwd != @current_path
351
+ Dir.chdir @current_path
352
+ end
353
+ values = Dir.glob(str)
354
+ $log.debug "ask select dir.glob got #{values} "
355
+ select_values values unless values.empty?
356
+ @repaint_required = true
357
+ end
358
+ def ask_unselect
359
+ prompt = "Unselect Files: "
360
+ maxlen = 80
361
+ config={}
362
+ config[:default] = @file_pattern if @file_pattern
363
+ ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
364
+ return if ret != 0
365
+ @file_pattern = str
366
+ if Dir.pwd != @current_path
367
+ Dir.chdir @current_path
368
+ end
369
+ values = Dir.glob(str)
370
+ unselect_values values unless values.empty?
371
+ @repaint_required = true
372
+ end
373
+ def select_all
374
+ # don't select header row
375
+ add_row_selection_interval 1, row_count()
376
+ end
377
+ def invert_selection
378
+ 1.upto(row_count()){|i| toggle_row_selection i }
379
+ end
380
+ # selects all rows with the values given, leaving existing selections
381
+ # intact
382
+ def select_values values
383
+ return unless values
384
+ values.each do |val|
385
+ row = @list.index val
386
+ add_row_selection_interval row, row unless row.nil?
387
+ end
388
+ end
389
+ # unselects all rows with the values given, leaving all other rows intact
390
+ def unselect_values values
391
+ return unless values
392
+ values.each do |val|
393
+ row = @list.index val
394
+ remove_row_selection_interval row, row unless row.nil?
395
+ end
396
+ end
397
+ private
398
+ # was meant to filter rows, but no point. since we can't undo the delete
399
+ # so we just call populate again. this method could get axed
400
+ def prune_entries
401
+ #@entries.delete_if {|x| x =~ /^\./} if @hide_dot_files
402
+ #@entries.delete_if {|x| x =~ /\.bak$/ || x=~/\.swp$/} if @hide_others
403
+ populate @current_path
404
+ set_form_row
405
+ end
406
+ def view_current
407
+ file = self.current_value
408
+ require 'rbcurse/core/util/viewer.rb'
409
+ RubyCurses::Viewer.view("#{current_path}/#{file}", :close_key => KEY_RETURN, :title => "<Enter> to close, M-l M-h to scroll")
410
+ end
411
+ # ADD HERE
412
+ ##
413
+ end # class
414
+
415
+ ##
416
+ # A cell renderer should not changed the length of a line otherwise scrolling etc goes for a toss.
417
+ # The calling repaint method does trimming.
418
+ #
419
+ # A cell renderer can do small modifications, or color changing to data.
420
+ # Here we should color directories or bak files or hidden files, swap files etc differently
421
+ # Should this class do the trimming of data, else its hard to figure out what the extension
422
+ # is if its trimeed out. But then it would have to handle the panning too.
423
+ require 'rbcurse/core/include/listcellrenderer'
424
+ class DirectoryListCellRenderer < ListCellRenderer
425
+ #def initialize text="", config={}, &block
426
+ #super
427
+ #end
428
+ # sets @color_pair and @attr
429
+
430
+ ##
431
+ # paint a list box cell
432
+ # 2010-09-02 15:38 changed focussed to take true, false and :SOFT_FOCUS
433
+ # SOFT_FOCUS means the form focus is no longer on this field, but this row
434
+ # was focussed when use was last on this field. This row will take focus
435
+ # when field is focussed again
436
+ #
437
+ # @param [Buffer] window or buffer object used for printing
438
+ # @param [Fixnum] row
439
+ # @param [Fixnum] column
440
+ # @param [Fixnum] actual index into data, some lists may have actual data elsewhere and
441
+ # display data separate. e.g. rfe_renderer (directory listing)
442
+ # @param [String] text to print in cell
443
+ # @param [Boolean, :SOFT_FOCUS] cell focussed, not focussed, cell focussed but field is not focussed
444
+ # @param [Boolean] cell selected or not
445
+ def repaint graphic, r=@row,c=@col, row_index=-1,value=@text, focussed=false, selected=false
446
+
447
+ prepare_default_colors focussed, selected
448
+ if row_index == 0
449
+ #nvalue = " %s %8s %19s %s %s " % value.split(",")
450
+ graphic.printstring r, c, "%-s" % value, @color_pair,@attr
451
+ else
452
+ $log.debug " CELL XXX GTETING #{row_index} ,#{value}"
453
+
454
+
455
+ # ensure we do not exceed
456
+ if !@display_length.nil?
457
+ if value.length > @display_length
458
+ value = value[0..@display_length-1]
459
+ end
460
+ end
461
+ len = @display_length || value.length
462
+ graphic.printstring r, c, "%-*s" % [len, value], @color_pair,@attr
463
+ end
464
+ end
465
+ end
466
+ end # module
467
+ # set filetype=ruby