rbcurse 1.4.1 → 1.5.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/CHANGELOG +31 -0
  2. data/README.markdown +69 -11
  3. data/VERSION +1 -1
  4. data/lib/rbcurse.rb +5 -5
  5. metadata +10 -198
  6. data/Makefile +0 -21
  7. data/Manifest.txt +0 -91
  8. data/TODO +0 -372
  9. data/TODO2.txt +0 -118
  10. data/examples/README.txt +0 -67
  11. data/examples/abasiclist.rb +0 -33
  12. data/examples/alpmenu.rb +0 -42
  13. data/examples/app.rb +0 -859
  14. data/examples/app.sample +0 -10
  15. data/examples/appdirtree.rb +0 -75
  16. data/examples/appemail.rb +0 -191
  17. data/examples/appemaillb.rb +0 -308
  18. data/examples/appgcompose.rb +0 -315
  19. data/examples/atree.rb +0 -64
  20. data/examples/common/file.rb +0 -40
  21. data/examples/common/rmail.rb +0 -257
  22. data/examples/data.txt +0 -683
  23. data/examples/data/README.markdown +0 -9
  24. data/examples/data/brew.txt +0 -38
  25. data/examples/data/color.2 +0 -37
  26. data/examples/data/gemlist.txt +0 -60
  27. data/examples/data/lotr.txt +0 -12
  28. data/examples/data/ports.txt +0 -136
  29. data/examples/data/tasks.txt +0 -27
  30. data/examples/data/todocsv.csv +0 -28
  31. data/examples/data/unix1.txt +0 -21
  32. data/examples/data/unix2.txt +0 -11
  33. data/examples/dbdemo.rb +0 -495
  34. data/examples/deprecated/appgmail.rb +0 -952
  35. data/examples/deprecated/splitp.rb +0 -56
  36. data/examples/deprecated/testscrolllb.rb +0 -86
  37. data/examples/deprecated/testscrollp.rb +0 -88
  38. data/examples/deprecated/testscrollta.rb +0 -80
  39. data/examples/deprecated/testscrolltable.rb +0 -165
  40. data/examples/deprecated/testsplit.rb +0 -87
  41. data/examples/deprecated/testsplit2.rb +0 -123
  42. data/examples/deprecated/testsplit3.rb +0 -215
  43. data/examples/deprecated/testsplit3_1.rb +0 -244
  44. data/examples/deprecated/testsplit3a.rb +0 -215
  45. data/examples/deprecated/testsplit3b.rb +0 -237
  46. data/examples/deprecated/testsplitta.rb +0 -148
  47. data/examples/deprecated/testsplittv.rb +0 -142
  48. data/examples/deprecated/testsplittvv.rb +0 -144
  49. data/examples/deprecated/testtpane.rb +0 -215
  50. data/examples/deprecated/testtpane2.rb +0 -145
  51. data/examples/deprecated/testtpanetable.rb +0 -203
  52. data/examples/dirtree.rb +0 -88
  53. data/examples/experimental/resultsetdemo.rb +0 -280
  54. data/examples/experimental/testmform.rb +0 -35
  55. data/examples/experimental/testscroller.rb +0 -117
  56. data/examples/experimental/teststackflow.rb +0 -111
  57. data/examples/menu1.rb +0 -112
  58. data/examples/multispl.rb +0 -86
  59. data/examples/newmessagebox.rb +0 -130
  60. data/examples/newtabbedwindow.rb +0 -100
  61. data/examples/newtesttabp.rb +0 -121
  62. data/examples/qdfilechooser.rb +0 -68
  63. data/examples/rfe.rb +0 -1195
  64. data/examples/rfe_renderer.rb +0 -121
  65. data/examples/sqlc.rb +0 -454
  66. data/examples/sqlm.rb +0 -437
  67. data/examples/sqlt.rb +0 -408
  68. data/examples/status.txt +0 -68
  69. data/examples/table1.rb +0 -24
  70. data/examples/term2.rb +0 -84
  71. data/examples/test1.rb +0 -239
  72. data/examples/test2.rb +0 -674
  73. data/examples/testapp.rb +0 -44
  74. data/examples/testapp2.rb +0 -58
  75. data/examples/testchars.rb +0 -137
  76. data/examples/testcombo.rb +0 -91
  77. data/examples/testkeypress.rb +0 -66
  78. data/examples/testlistbox.rb +0 -113
  79. data/examples/testmenu.rb +0 -101
  80. data/examples/testmulticomp.rb +0 -70
  81. data/examples/testmulticontainer.rb +0 -94
  82. data/examples/testmultispl.rb +0 -199
  83. data/examples/testree.rb +0 -106
  84. data/examples/testtable.rb +0 -263
  85. data/examples/testtabp.rb +0 -107
  86. data/examples/testtodo.rb +0 -584
  87. data/examples/testvimsplit.rb +0 -112
  88. data/examples/testwsshortcuts.rb +0 -64
  89. data/examples/testwsshortcuts2.rb +0 -126
  90. data/examples/todo.db +0 -0
  91. data/examples/todo.yml +0 -191
  92. data/examples/viewtodo.rb +0 -574
  93. data/lib/rbcurse/action.rb +0 -40
  94. data/lib/rbcurse/app.rb +0 -1374
  95. data/lib/rbcurse/applicationheader.rb +0 -102
  96. data/lib/rbcurse/celleditor.rb +0 -112
  97. data/lib/rbcurse/checkboxcellrenderer.rb +0 -57
  98. data/lib/rbcurse/colormap.rb +0 -159
  99. data/lib/rbcurse/comboboxcellrenderer.rb +0 -30
  100. data/lib/rbcurse/common/ansiparser.rb +0 -117
  101. data/lib/rbcurse/common/appmethods.rb +0 -112
  102. data/lib/rbcurse/common/basestack.rb +0 -407
  103. data/lib/rbcurse/common/bordertitle.rb +0 -41
  104. data/lib/rbcurse/common/chunk.rb +0 -177
  105. data/lib/rbcurse/common/colorparser.rb +0 -71
  106. data/lib/rbcurse/common/keydefs.rb +0 -30
  107. data/lib/rbcurse/common/widgetshortcuts.rb +0 -302
  108. data/lib/rbcurse/defaultlistselectionmodel.rb +0 -79
  109. data/lib/rbcurse/deprecated/README.markdown +0 -12
  110. data/lib/rbcurse/deprecated/rscrollpane.rb +0 -512
  111. data/lib/rbcurse/deprecated/rsplitpane.rb +0 -894
  112. data/lib/rbcurse/deprecated/rsplitpane2.rb +0 -1009
  113. data/lib/rbcurse/deprecated/rviewport.rb +0 -204
  114. data/lib/rbcurse/experimental/README.markdown +0 -14
  115. data/lib/rbcurse/experimental/resultsettextview.rb +0 -585
  116. data/lib/rbcurse/experimental/stackflow.rb +0 -478
  117. data/lib/rbcurse/extras/bottomline.rb +0 -1850
  118. data/lib/rbcurse/extras/box.rb +0 -58
  119. data/lib/rbcurse/extras/directorylist.rb +0 -467
  120. data/lib/rbcurse/extras/directorytree.rb +0 -69
  121. data/lib/rbcurse/extras/divider.rb +0 -310
  122. data/lib/rbcurse/extras/focusmanager.rb +0 -31
  123. data/lib/rbcurse/extras/horizlist.rb +0 -203
  124. data/lib/rbcurse/extras/listselectable.rb +0 -264
  125. data/lib/rbcurse/extras/masterdetail.rb +0 -166
  126. data/lib/rbcurse/extras/menutree.rb +0 -63
  127. data/lib/rbcurse/extras/multiform.rb +0 -330
  128. data/lib/rbcurse/extras/multilinelabel.rb +0 -142
  129. data/lib/rbcurse/extras/newmessagebox.rb +0 -328
  130. data/lib/rbcurse/extras/newtabbedpane.rb +0 -612
  131. data/lib/rbcurse/extras/newtabbedwindow.rb +0 -68
  132. data/lib/rbcurse/extras/padreader.rb +0 -189
  133. data/lib/rbcurse/extras/rcomboedit.rb +0 -256
  134. data/lib/rbcurse/extras/resultsetbrowser.rb +0 -281
  135. data/lib/rbcurse/extras/rlink.rb +0 -27
  136. data/lib/rbcurse/extras/rmenulink.rb +0 -21
  137. data/lib/rbcurse/extras/scrollbar.rb +0 -143
  138. data/lib/rbcurse/extras/statusline.rb +0 -94
  139. data/lib/rbcurse/extras/stdscrwindow.rb +0 -309
  140. data/lib/rbcurse/extras/tableextended.rb +0 -40
  141. data/lib/rbcurse/extras/tabular.rb +0 -264
  142. data/lib/rbcurse/extras/tabularwidget.rb +0 -1150
  143. data/lib/rbcurse/extras/textpad.rb +0 -516
  144. data/lib/rbcurse/extras/viewer.rb +0 -136
  145. data/lib/rbcurse/io.rb +0 -850
  146. data/lib/rbcurse/keylabelprinter.rb +0 -178
  147. data/lib/rbcurse/listcellrenderer.rb +0 -140
  148. data/lib/rbcurse/listeditable.rb +0 -310
  149. data/lib/rbcurse/listkeys.rb +0 -37
  150. data/lib/rbcurse/listscrollable.rb +0 -564
  151. data/lib/rbcurse/listselectable.rb +0 -142
  152. data/lib/rbcurse/mapper.rb +0 -130
  153. data/lib/rbcurse/orderedhash.rb +0 -77
  154. data/lib/rbcurse/ractionevent.rb +0 -67
  155. data/lib/rbcurse/rbasiclistbox.rb +0 -768
  156. data/lib/rbcurse/rchangeevent.rb +0 -27
  157. data/lib/rbcurse/rcombo.rb +0 -238
  158. data/lib/rbcurse/rcommandwindow.rb +0 -587
  159. data/lib/rbcurse/rcontainer.rb +0 -415
  160. data/lib/rbcurse/rdialogs.rb +0 -451
  161. data/lib/rbcurse/rinputdataevent.rb +0 -47
  162. data/lib/rbcurse/rlistbox.rb +0 -1196
  163. data/lib/rbcurse/rmenu.rb +0 -939
  164. data/lib/rbcurse/rmessagebox.rb +0 -348
  165. data/lib/rbcurse/rmulticontainer.rb +0 -304
  166. data/lib/rbcurse/rmultisplit.rb +0 -722
  167. data/lib/rbcurse/rmultitextview.rb +0 -306
  168. data/lib/rbcurse/rpopupmenu.rb +0 -755
  169. data/lib/rbcurse/rprogress.rb +0 -118
  170. data/lib/rbcurse/rscrollform.rb +0 -418
  171. data/lib/rbcurse/rtabbedpane.rb +0 -1158
  172. data/lib/rbcurse/rtabbedwindow.rb +0 -167
  173. data/lib/rbcurse/rtable.rb +0 -1718
  174. data/lib/rbcurse/rtextarea.rb +0 -920
  175. data/lib/rbcurse/rtextview.rb +0 -761
  176. data/lib/rbcurse/rtree.rb +0 -780
  177. data/lib/rbcurse/rvimsplit.rb +0 -763
  178. data/lib/rbcurse/rwidget.rb +0 -2915
  179. data/lib/rbcurse/scrollable.rb +0 -301
  180. data/lib/rbcurse/table/tablecellrenderer.rb +0 -86
  181. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -98
  182. data/lib/rbcurse/tree/treecellrenderer.rb +0 -150
  183. data/lib/rbcurse/tree/treemodel.rb +0 -428
  184. data/lib/rbcurse/undomanager.rb +0 -188
  185. data/lib/rbcurse/vieditable.rb +0 -144
  186. data/lib/ver/keyboard.rb +0 -150
  187. data/lib/ver/keyboard2.rb +0 -170
  188. data/lib/ver/ncurses.rb +0 -218
  189. data/lib/ver/panel.rb +0 -162
  190. data/lib/ver/rpad.rb +0 -375
  191. data/lib/ver/window.rb +0 -882
  192. data/test/test_rbcurse.rb +0 -0
@@ -1,142 +0,0 @@
1
- # this is a companion file to defaultlistselectionmodel
2
- # if you use that, include this to get all the methods to use it
3
- module RubyCurses
4
- module ListSelectable
5
-
6
- ## modified on 2009-02-13 23:41 to return model if no param passed
7
- # sets or returns a list selection model
8
- # Also listbox listens to it for selections, so it can tell those
9
- # who are interested 2010-09-21 16:02
10
- def list_selection_model(*lsm)
11
- if lsm.empty?
12
- @list_selection_model
13
- else
14
- @list_selection_model = lsm[0]
15
- # the listbox is listening to selection events on the
16
- # selection model and will inform any listeners of the same.
17
- @list_selection_model.bind :LIST_SELECTION_EVENT do |ev|
18
- fire_handler :LIST_SELECTION_EVENT, ev
19
- end
20
- end
21
- #@list_selection_model.selection_mode = @selection_mode || :MULTIPLE
22
- end
23
- def is_selected? row
24
- @list_selection_model.is_selected_index row
25
- end
26
- # this is the old name, should be deprecated
27
- alias :is_row_selected :is_selected?
28
-
29
- def add_row_selection_interval ix0, ix1
30
- $log.debug " def add_row_selection_interval #{ix0}, #{ix1}"
31
- # if row_selection_allowed
32
- @list_selection_model.add_selection_interval ix0, ix1
33
- @repaint_required = true
34
- end
35
- def remove_row_selection_interval ix0, ix1
36
- @list_selection_model.remove_selection_interval ix0, ix1
37
- end
38
- def toggle_row_selection row=@current_index
39
- if is_selected? row
40
- #$log.debug " deleting row #{row}"
41
- remove_row_selection_interval(row, row)
42
- else
43
- #$log.debug " adding row #{row}"
44
- add_row_selection_interval(row, row)
45
- end
46
- @repaint_required = true
47
- end
48
-
49
- def clear_selection
50
- @list_selection_model.clear_selection
51
- @repaint_required = true
52
- end
53
- # why is this commented off XXX could it override listscrollable
54
- #def selected_item
55
- #$log.warn "came in dummy selected_item of listselectable.rb"
56
- # @list[@current_index]
57
- #end
58
- # returns selected indices
59
- # TODO : if array passed, set those as selected indices
60
- def selected_rows
61
- @list_selection_model.get_selected_rows
62
- end
63
- def selected_row_count
64
- selected_rows.size
65
- end
66
- # returns index of first selected row (lowest index)
67
- # TODO: if param passed set that as selected_index
68
- def selected_row
69
- @list_selection_model.get_min_selection_index
70
- end
71
- alias :selected_index :selected_row
72
-
73
- # returns value of first selected row (lowest index)
74
- def selected_value
75
- #@list[@current_index].to_s # old behavior since curr row was in reverse
76
- return nil if selected_row().nil?
77
- @list[selected_row()].to_s
78
- end
79
- # returns an array of selected values
80
- # or yields values to given block
81
- def selected_values &block
82
- ar = []
83
- selected_rows().each do |i|
84
- val = @list[i]
85
- if block_given?
86
- yield val
87
- else
88
- ar << val
89
- end
90
- end
91
- return ar unless block_given?
92
- end
93
-
94
- def do_next_selection
95
- return if selected_rows().length == 0
96
- row = selected_rows().sort.find { |i| i > @current_index }
97
- row ||= @current_index
98
- @current_index = row
99
- @repaint_required = true # fire list_select XXX
100
- end
101
- def do_prev_selection
102
- return if selected_rows().length == 0
103
- row = selected_rows().sort{|a,b| b <=> a}.find { |i| i < @current_index }
104
- row ||= @current_index
105
- @current_index = row
106
- @repaint_required = true # fire list_select XXX
107
- end
108
- # NOTE: I HAD removed this and put in listbox, but its required by rtable also
109
- # create a default list selection model and set it
110
- # NOTE: I am now checking if one is not already created, since
111
- # a second creation would wipe out any listeners on it.
112
- # @see ListSelectable
113
- # @see DefaultListSelectionModel
114
- def create_default_list_selection_model
115
- if @list_selection_model.nil?
116
- list_selection_model DefaultListSelectionModel.new(self)
117
- end
118
- end
119
- alias :selected_index :selected_row
120
- attr_accessor :row_selection_allowed
121
- attr_accessor :column_selection_allowed
122
- end
123
- # class containing information relating to selections on a list
124
- # 2010-09-21 19:46 NOTE: Earlier source contained the model object, now it returns the parent
125
- # You may do source.list_data_model() to get the model
126
- # Typical operations on source would get selected_value(s), or selected_index
127
- class ListSelectionEvent
128
- attr_accessor :firstrow, :lastrow, :source, :type
129
- def initialize firstrow, lastrow, source, type
130
- @firstrow = firstrow
131
- @lastrow = lastrow
132
- @source = source
133
- @type = type
134
- end
135
- def to_s
136
- "#{@type.to_s}, firstrow: #{@firstrow}, lastrow: #{@lastrow}, source: #{@source}"
137
- end
138
- def inspect
139
- to_s
140
- end
141
- end
142
- end
@@ -1,130 +0,0 @@
1
- ## this class allows us to do multiple key mappings such as emacs
2
- # See the example keytest.rb
3
- # However, integrating this into our library seems a little difficult now
4
- # since each widget handles keys and often there are heirachies of widgets.
5
- # However, this being a terminal app, mouseless, we really need to make it key-friendly.
6
- require 'rbcurse/orderedhash'
7
- class Mapper
8
- attr_reader :keymap
9
- attr_reader :view
10
- attr_accessor :mode
11
- attr_reader :keys
12
- def initialize handler
13
- #@handler = handler
14
- @view = handler # caller program
15
- @keys = {}
16
- @mode = nil # used when defining
17
- @pendingkeys = nil
18
- @prevkey = nil # in case of a key sequence such as C-x C-c, will have C-x
19
- @arg = nil # regex matched this key.
20
- end
21
- def let mode, &block
22
- h = OrderedHash.new
23
- @keys[mode] = h
24
- @mode = mode
25
- instance_eval(&block)
26
- $log.debug("KEYS: #{@keys[mode].inspect}")
27
- end
28
-
29
- ## mapping keys to blocks or symbols
30
- # 2010-02-23 19:17 added check for string, so no required to use getbyte everywhere, esp for existing app
31
- # However, this means that we can't map an actual string, which we may want to for commands
32
- # which cuold be passed outside keys, or as aliases.
33
- def map(*args, &block)
34
- if block_given?
35
-
36
- # We check for cases like C-x C-c etc. Only 2 levels.
37
- #args = arg.split(/ +/)
38
- arg0 = args[0]
39
- arg0 = args[0].getbyte(0) if args[0].class.to_s == 'String'
40
- if args.length == 2
41
- arg1 = args[1]
42
- arg1 = args[1].getbyte(0) if args[1].class.to_s == 'String'
43
- $log.debug " KEY2 #{args[0]} , #{args[0].class}, #{args[1]} , #{args[1].class} "
44
- @keys[@mode][arg0] ||= OrderedHash.new
45
- @keys[@mode][arg0][arg1]=block
46
- else
47
- # single key or control key
48
- $log.debug " KEY #{args[0]} , #{args[0].class} "
49
- @keys[@mode][arg0]=block
50
- end
51
- else
52
- #no block, last arg shold be a symbol
53
- symb = args.pop
54
- raise "If block not passed, last arg should be a method symbol" if !symb.is_a? Symbol
55
- arg0 = args[0]
56
- arg0 = args[0].getbyte(0) if args[0].class.to_s == 'String'
57
- if args.length == 2
58
- arg1 = args[1]
59
- arg1 = args[1].getbyte(0) if args[1].class.to_s == 'String'
60
- @keys[@mode][arg0] ||= OrderedHash.new
61
- @keys[@mode][arg0][arg1]=symb
62
- else
63
- # single key or control key
64
- @keys[@mode][arg0]=symb
65
- end
66
- end
67
- end
68
-
69
- ## manages key pressing
70
- # takes care of multiple key combos too
71
- def press key
72
- #$log.debug("press Got: #{key}")
73
- # for a double key combination such as C-x C-c this has the set of pending keys to check against
74
- if @pendingkeys != nil
75
- blk = @pendingkeys[key]
76
- else
77
- # this is the regular single key mode
78
- #blk = @keys[@view.mode][key]
79
- blk = match(key)
80
- end
81
- # this means this key expects more keys to follow such as C-x could
82
- if blk.is_a? OrderedHash
83
- @pendingkeys = blk
84
- @prevkey = key
85
- return
86
- end
87
- if blk.nil? # this should go up XXX
88
- if !@pendingkeys.nil?
89
- # this error message to be modified if using numeric keys -- need to convert to char
90
- view.info("%p not valid in %p. Try: #{@pendingkeys.keys.join(', ')}" % [key, @prevkey]) # XXX
91
- else
92
- view.info("%p not valid in %p. " % [key, @view.mode])
93
- end
94
- return
95
- end
96
- # call the block or symbol - our user defined key mappings use symbols
97
- if blk.is_a? Symbol
98
- @view.send(blk)
99
- else
100
- blk.call
101
- end
102
- @prevkey = nil
103
- @pendingkeys = nil
104
- end
105
- def match key
106
- #$log.debug "MATCH #{key} "
107
- #blk = @keys[@view.mode][key]
108
- @keys[@view.mode].each_pair do |k,v|
109
- #$log.debug "LOOP #{k.class}, #{k}, #{v} "
110
- case k.class.to_s
111
- when "String"
112
- return v if k == key
113
- when "Fixnum" # for keyboard2
114
- #$log.debug "FIXNUM LOOP #{k.class}, #{k}, #{v} "
115
- return v if k == key
116
- when "Regexp"
117
- # $log.debug "REGEX #key , #k, #{k.match(key)}"
118
- key1 = key.chr if key.is_a? Fixnum
119
- if !k.match(key1).nil?
120
- @arg = key1
121
- return v
122
- end
123
- else
124
- $log.error "MATCH: Unhandled class #{k.class} "
125
- end
126
- end
127
- $log.debug "MATCH #{key} ret nil "
128
- return nil
129
- end
130
- end
@@ -1,77 +0,0 @@
1
- ## Insert order preserving hash
2
- # Thanks to Bill Kelly, posted on http://www.ruby-forum.com/topic/166075
3
- #
4
- class OrderedHash
5
- include Enumerable
6
-
7
- def initialize(*args, &block)
8
- @h = Hash.new(*args, &block)
9
- @ordered_keys = []
10
- end
11
-
12
- def []=(key, val)
13
- @ordered_keys << key unless @h.has_key? key
14
- @h[key] = val
15
- end
16
-
17
- def each
18
- @ordered_keys.each {|k| yield(k, @h[k])}
19
- end
20
- alias :each_pair :each
21
-
22
- def each_value
23
- @ordered_keys.each {|k| yield(@h[k])}
24
- end
25
-
26
- def each_key
27
- @ordered_keys.each {|k| yield k}
28
- end
29
-
30
- def keys
31
- @ordered_keys
32
- end
33
-
34
- def values
35
- @ordered_keys.map {|k| @h[k]}
36
- end
37
-
38
- def clear
39
- @ordered_keys.clear
40
- @h.clear
41
- end
42
-
43
- def delete(k, &block)
44
- @ordered_keys.delete k
45
- @h.delete(k, &block)
46
- end
47
-
48
- def reject!
49
- del = []
50
- each_pair {|k,v| del << k if yield k,v}
51
- del.each {|k| delete k}
52
- del.empty? ? nil : self
53
- end
54
-
55
- def delete_if(&block)
56
- reject!(&block)
57
- self
58
- end
59
- ## added since the normal hash will give it in unordered. so debugging sucks
60
- def inspect
61
- out = []
62
- each do | k,v |
63
- out << " #{k} => #{v} "
64
- end
65
- res = %Q[ { #{out.join(",\n ")} } ]
66
- end
67
-
68
- %w(merge!).each do |name|
69
- define_method(name) do |*args|
70
- raise NotImplementedError, "#{name} not implemented"
71
- end
72
- end
73
-
74
- def method_missing(*args)
75
- @h.send(*args)
76
- end
77
- end
@@ -1,67 +0,0 @@
1
- =begin
2
- * Name: ActionEvent
3
- * Description: Event used to notify interested parties that an action has happened on component
4
- Usually a button press. Nothing more.
5
- * Author: rkumar (arunachalesha)
6
-
7
- --------
8
- * Date: 2010-09-12 18:53
9
- * License:
10
- Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
11
-
12
- =end
13
-
14
- # Event created when state changed (as in ViewPort)
15
- module RubyCurses
16
- # source - as always is the object whose event has been fired
17
- # id - event identifier (seems redundant since we bind events often separately.
18
- # event - is :PRESS
19
- # action_command - command string associated with event (such as title of button that changed
20
- ActionEvent = Struct.new(:source, :event, :action_command) do
21
- # This should always return the most relevant text associated with this object
22
- # so the user does not have to go through the source object's documentation.
23
- # It should be a user-friendly string
24
- # @return text associated with source (label of button)
25
- def text
26
- source.text
27
- end
28
-
29
- # This is similar to text and can often be just an alias.
30
- # However, i am putting this for backward compatibility with programs
31
- # that received the object and called it's getvalue. It is better to use text.
32
- # @return text associated with source (label of button)
33
- def getvalue
34
- source.getvalue
35
- end
36
- end
37
- # a derivative of Action Event for textviews
38
- # We allow a user to press ENTER on a row and use that for processing.
39
- # We are basically using TextView as a list in which user can scroll around
40
- # and move cursor at will.
41
- class TextActionEvent < ActionEvent
42
- # current_index or line number starting 0
43
- attr_accessor :current_index
44
- # cursor position on the line
45
- attr_accessor :curpos
46
- def initialize source, event, action_command, current_index, curpos
47
- super source, event, action_command
48
- @current_index = current_index
49
- @curpos = curpos
50
- end
51
- # the text of the line on which the user is
52
- def text
53
- source.current_value
54
- end
55
- # the word under the cursor TODO
56
- # if its a text with pipe delim, then ??
57
- def word_under_cursor line=text(), pos=@curpos, delim=" "
58
- line ||= text()
59
- pos ||= @curpos
60
- finish = line.index(delim, pos)
61
- start = line.rindex(delim,pos)
62
- finish = -1 if finish.nil?
63
- start = 0 if start.nil?
64
- return line[start..finish]
65
- end
66
- end
67
- end
@@ -1,768 +0,0 @@
1
- =begin
2
- * Name: rlistbox: basic scrollable lists - no editing, see editablelistbox of more
3
- * Description
4
- * Author: rkumar (arunachalesha)
5
- * Date: 2010-09-26 16:00
6
- * License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
7
- *
8
- TODO
9
- [x] removed Popup, ListDataEvent and ListDataModel !
10
- [x] XXX Can we separate editing out. Make a ReadonlyList, and extend it as EditableList. This way the usual
11
- use case remains cleaner.
12
- =end
13
- require 'rbcurse'
14
- require 'rbcurse/listcellrenderer'
15
- #require 'rbcurse/listkeys'
16
- require 'forwardable'
17
-
18
-
19
- module RubyCurses
20
- extend self
21
- ##
22
- ##
23
- # scrollable, selectable list of items
24
- # - @selected contains indices of selected objects.
25
- ##
26
- ##
27
- # A readonly control for displaying a list of data or values.
28
- # Although user editing is not allowed, but the list may be repopulated
29
- # as in a directory listing, or a list dependent on some other control's value.
30
- # This is not a drop-in replacement for Listbox as it drops many methods that are redundant.
31
- # Default selection is single, as opposed to Listbox.
32
- #
33
- class BasicListbox < Widget
34
-
35
- require 'rbcurse/listscrollable'
36
- require 'rbcurse/extras/listselectable' # added 2011-10-8
37
- include ListScrollable
38
- include NewListSelectable # added 2011-10-8
39
- extend Forwardable
40
- dsl_accessor :height
41
- dsl_accessor :title
42
- dsl_property :title_attrib # bold, reverse, normal
43
- # dsl_accessor :list # the array of data to be sent by user
44
- attr_reader :toprow
45
- #dsl_accessor :default_values # array of default values
46
- dsl_accessor :is_popup # if it is in a popup and single select, selection closes
47
- attr_accessor :current_index
48
- dsl_accessor :selection_mode
49
- dsl_accessor :selected_color, :selected_bgcolor, :selected_attr
50
- dsl_accessor :max_visible_items # how many to display 2009-01-11 16:15
51
- #dsl_accessor :cell_editing_allowed
52
- dsl_property :show_selector # boolean
53
- dsl_property :row_selected_symbol # 2009-01-12 12:01 changed from selector to selected
54
- dsl_property :row_unselected_symbol # added 2009-01-12 12:00
55
- dsl_property :left_margin
56
- # please set these in he constructor block. Settin them later will have no effect
57
- # since i would have bound them to actions
58
- attr_accessor :one_key_selection # will pressing a single key select or not
59
- dsl_accessor :border_attrib, :border_color #
60
- # set to true if data could have newlines, tabs, and other stuff, def true
61
- dsl_accessor :sanitization_required
62
- # set to true if cell-renderer data can exceed width of listbox, default true
63
- # if you are absolutely sure that data is constant width, set to false.
64
- dsl_accessor :truncation_required
65
- dsl_accessor :suppress_borders #to_print_borders
66
- dsl_accessor :justify # will be picked up by renderer
67
- # index of selected row
68
- attr_accessor :selected_index
69
- # index of selected rows, if multiple selection asked for
70
- attr_reader :selected_indices
71
-
72
- dsl_accessor :should_show_focus
73
-
74
- # basic listbox constructor
75
- #
76
- def initialize form, config={}, &block
77
- @focusable = true
78
- @editable = false
79
- @sanitization_required = true # cleanup control and non print chars
80
- @truncation_required = true
81
- @suppress_borders = false #to_print_borders = 1
82
- #@row_selected_symbol = '' # thi sprevents default value from being set
83
- @row = 0
84
- @col = 0
85
- # data of listbox this is not an array, its a pointer to the listdatamodel
86
- @list = nil
87
- # any special attribs such as status to be printed in col1, or color (selection)
88
- @list_attribs = {}
89
- @current_index = 0
90
- @selected_indices = []
91
- @selected_index = nil
92
- @row_offset = @col_offset = 1
93
- @should_show_focus = true # Here's its on since the cellrenderer will show it on repaint
94
- super
95
- @_events.push(*[:ENTER_ROW, :LEAVE_ROW, :LIST_SELECTION_EVENT, :PRESS])
96
- @selection_mode ||= :multiple # default is multiple, anything else given becomes single
97
- @win = @graphic # 2010-01-04 12:36 BUFFERED replace form.window with graphic
98
- @win_left = 0
99
- @win_top = 0
100
-
101
- init_vars
102
- @internal_width = 2
103
- @internal_width = 0 if @suppress_borders
104
-
105
- if @list && !@selected_index.nil? # XXX
106
- set_focus_on @selected_index # the new version
107
- end
108
- end
109
- # this is called several times, from constructor
110
- # and when list data changed, so only put relevant resets here.
111
- def init_vars
112
- @repaint_required = true
113
- @widget_scrolled = true # 2011-10-15
114
- @toprow = @pcol = 0
115
- if @show_selector
116
- @row_selected_symbol ||= '>'
117
- @row_unselected_symbol ||= ' '
118
- @left_margin ||= @row_selected_symbol.length
119
- end
120
- @row_selected_symbol ||= ''
121
- #@left_margin ||= 0
122
- @one_key_selection = false if @one_key_selection.nil?
123
- @row_offset = @col_offset = 0 if @suppress_borders
124
-
125
- end
126
- def map_keys
127
- return if @keys_mapped
128
- bind_key(?f){ ask_selection_for_char() }
129
- bind_key(?\M-v){ @one_key_selection = false }
130
- bind_key(?j){ next_row() }
131
- bind_key(?k){ previous_row() }
132
- bind_key(?\C-d){ scroll_forward() }
133
- bind_key(?\C-b){ scroll_backward() }
134
- bind_key(?G){ goto_bottom() }
135
- bind_key([?g,?g]){ goto_top() }
136
- bind_key([?',?']){ goto_last_position() }
137
- bind_key(?/){ ask_search() }
138
- bind_key(?n){ find_more() }
139
- bind_key(32){ toggle_row_selection() }
140
- bind_key(10){ fire_action_event }
141
- bind_key(13){ fire_action_event }
142
- list_bindings
143
- @keys_mapped = true
144
-
145
- end
146
-
147
- ## returns count of row, needed by scrollbar and others.
148
- def row_count
149
- return 0 if @list.nil?
150
- @list.length
151
- end
152
- # start scrolling when user reaches this row
153
- def scrollatrow #:nodoc:
154
- if @suppress_borders
155
- return @height - 1
156
- else
157
- return @height - 3
158
- end
159
- end
160
- # provide data to List in the form of an Array or Variable or
161
- # ListDataModel. This will create a default ListSelectionModel.
162
- #
163
- # CHANGE as on 2010-09-21 12:53:
164
- # If explicit nil passed then dummy datamodel and selection model created
165
- # From now on, constructor will call this, so this can always
166
- # happen.
167
- #
168
- # NOTE: sometimes this can be added much after its painted.
169
- # Do not expect this to be called from constructor, although that
170
- # is the usual case. it can be dependent on some other list or tree.
171
- # @param [Array, Variable, ListDataModel] data to populate list with
172
- # @return [ListDataModel] just created or assigned
173
-
174
- def list *val
175
- return @list if val.empty?
176
- alist = val[0]
177
- case alist
178
- when Array
179
- @list = alist
180
- @current_index = 0
181
- when NilClass
182
- @list = [] # or nil ?
183
- when Variable
184
- @list = alist.value
185
- else
186
- raise ArgumentError, "Listbox list(): do not know how to handle #{alist.class} "
187
- end
188
- clear_selection
189
-
190
- @repaint_required = true
191
- @widget_scrolled = true # 2011-10-15
192
- @list
193
- end
194
- def list_data_model; @list; end
195
- # conv method to insert data, trying to keep names same across along with Tabular, TextView,
196
- # TextArea and listbox. Don;t use this till i am certain.
197
- def data=(val)
198
- list(val)
199
- end
200
- # get element at
201
- # @param [Fixnum] index for element
202
- # @return [Object] element
203
- # @since 1.2.0 2010-09-06 14:33 making life easier for others.
204
- def [](off0)
205
- @list[off0]
206
- end
207
- # return object under cursor
208
- # Note: this should not be confused with selected row/s. User may not have selected this.
209
- # This is only useful since in some demos we like to change a status bar as a user scrolls down
210
- # @since 1.2.0 2010-09-06 14:33 making life easier for others.
211
- def current_value
212
- @list[@current_index]
213
- end
214
- def remove_all
215
- return if @list.nil? || @list.empty?
216
- @list = []
217
- init_vars
218
- end
219
- # avoid using "row", i'd rather stick with "index" and "value".
220
- alias :current_row :current_value
221
- alias :text :current_value # thanks to shoes, not sure how this will impact since widget has text.
222
-
223
- def print_borders #:nodoc:
224
- width = @width
225
- height = @height-1 # 2010-01-04 15:30 BUFFERED HEIGHT
226
- window = @graphic # 2010-01-04 12:37 BUFFERED
227
- startcol = @col
228
- startrow = @row
229
- #@color_pair = get_color($datacolor)
230
- bordercolor = @border_color || $datacolor
231
- borderatt = @border_attrib || Ncurses::A_NORMAL
232
-
233
- window.print_border startrow, startcol, height, width, bordercolor, borderatt
234
- print_title
235
- end
236
- def print_title #:nodoc:
237
- @color_pair ||= get_color($datacolor)
238
- # TODO check title.length and truncate if exceeds width
239
- @graphic.printstring( @row, @col+(@width-@title.length)/2, @title, @color_pair, @title_attrib) unless @title.nil?
240
- end
241
- ### START FOR scrollable ###
242
- def get_content
243
- @list
244
- end
245
- def get_window #:nodoc:
246
- @graphic
247
- end
248
- ### END FOR scrollable ###
249
- # override widgets text
250
- # returns indices of selected rows
251
- def getvalue
252
- selected_rows
253
- end
254
- # Listbox
255
- def handle_key(ch) #:nodoc:
256
- map_keys unless @keys_mapped
257
- @current_index ||= 0
258
- @toprow ||= 0
259
- h = scrollatrow()
260
- rc = row_count
261
- $log.debug " basiclistbox got ch #{ch}"
262
- #$log.debug " when kps #{@KEY_PREV_SELECTION} "
263
- case ch
264
- when KEY_UP # show previous value
265
- return previous_row
266
- when KEY_DOWN # show previous value
267
- return next_row
268
- when 32
269
- return if is_popup and @selection_mode == 'single' # not allowing select this way since there will be a difference
270
- toggle_row_selection @current_index #, @current_index
271
- @repaint_required = true
272
- when 0 # c-space
273
- add_to_selection
274
- when @KEY_NEXT_SELECTION # ?'
275
- $log.debug "insdie next selection"
276
- @oldrow = @current_index
277
- do_next_selection
278
- bounds_check
279
- when @KEY_PREV_SELECTION # ?"
280
- @oldrow = @current_index
281
- $log.debug "insdie prev selection"
282
- do_prev_selection
283
- bounds_check
284
- when @KEY_CLEAR_SELECTION
285
- clear_selection
286
- @repaint_required = true
287
- when 27, ?\C-c.getbyte(0)
288
- #editing_canceled @current_index if @cell_editing_allowed
289
- #cancel_block # block NW XXX don't think its required. 2011-09-9 FFI
290
- $multiplier = 0
291
- when @KEY_ASK_FIND_FORWARD
292
- # ask_search_forward
293
- when @KEY_ASK_FIND_BACKWARD
294
- # ask_search_backward
295
- when @KEY_FIND_NEXT
296
- # find_next
297
- when @KEY_FIND_PREV
298
- # find_prev
299
- when @KEY_ASK_FIND
300
- ask_search
301
- when @KEY_FIND_MORE
302
- find_more
303
- when @KEY_BLOCK_SELECTOR
304
- mark_block #selection
305
- #when ?\C-u.getbyte(0)
306
- # multiplier. Series is 4 16 64
307
- # TESTING @multiplier = (@multiplier == 0 ? 4 : @multiplier *= 4)
308
- # return 0
309
- when ?\C-c.getbyte(0)
310
- @multiplier = 0
311
- return 0
312
- else
313
- # this has to be fixed, if compo does not handle key it has to continue into next part FIXME
314
- ret = :UNHANDLED # changed on 2009-01-27 13:14 not going into unhandled, tab not released
315
- if ret == :UNHANDLED
316
- # beware one-key eats up numbers. we'll be wondering why
317
- if @one_key_selection
318
- case ch
319
- #when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0), ?0.getbyte(0)..?9.getbyte(0)
320
- when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0)
321
- # simple motion, key press defines motion
322
- ret = set_selection_for_char ch.chr
323
- else
324
- ret = process_key ch, self
325
- @multiplier = 0
326
- return :UNHANDLED if ret == :UNHANDLED
327
- end
328
- else
329
- # no motion on single key, we can freak out like in vim, pref f <char> for set_selection
330
- case ch
331
- when ?0.getbyte(0)..?9.getbyte(0)
332
- $multiplier *= 10 ; $multiplier += (ch-48)
333
- #$log.debug " setting mult to #{$multiplier} in list "
334
- return 0
335
- end
336
- ret = process_key ch, self
337
- return :UNHANDLED if ret == :UNHANDLED
338
- end
339
- end
340
- end
341
- $multiplier = 0
342
- end
343
- def fire_action_event
344
- require 'rbcurse/ractionevent'
345
- # should have been callled :ACTION_EVENT !!!
346
- fire_handler :PRESS, ActionEvent.new(self, :PRESS, text)
347
- end
348
- # get a keystroke from user and go to first item starting with that key
349
- def ask_selection_for_char
350
- ch = @graphic.getch
351
- if ch < 0 || ch > 255
352
- return :UNHANDLED
353
- end
354
- ret = set_selection_for_char ch.chr
355
- end
356
- def ask_search_forward
357
- regex = get_string("Enter regex to search")
358
- ix = @list.find_match regex
359
- if ix.nil?
360
- alert("No matching data for: #{regex}")
361
- else
362
- set_focus_on(ix)
363
- end
364
- end
365
- # gets string to search and calls data models find prev
366
- def ask_search_backward
367
- regex = get_string("Enter regex to search (backward)")
368
- @last_regex = regex
369
- ix = @list.find_prev regex, @current_index
370
- if ix.nil?
371
- alert("No matching data for: #{regex}")
372
- else
373
- set_focus_on(ix)
374
- end
375
- end
376
- # please check for error before proceeding
377
- # @return [Boolean] false if no data
378
- def on_enter
379
- if @list.nil? || @list.size == 0
380
- Ncurses.beep
381
- return :UNHANDLED
382
- end
383
- super # forgot this 2011-10-9 that's why events not firign
384
- on_enter_row @current_index
385
- set_form_row # added 2009-01-11 23:41
386
- true
387
- end
388
- def on_enter_row arow
389
- # copied from resultsettextview, can this not be in one place like listscrollable ? FIXME
390
- if @should_show_focus
391
- highlight_focussed_row :FOCUSSED
392
- unless @oldrow == @selected_index
393
- highlight_focussed_row :UNFOCUSSED
394
- end
395
- end
396
- fire_handler :ENTER_ROW, self
397
- @repaint_required = true
398
- end
399
- def on_leave_row arow
400
- fire_handler :LEAVE_ROW, self
401
- end
402
- # getter and setter for cell_renderer
403
- def cell_renderer(*val)
404
- if val.empty?
405
- @cell_renderer ||= create_default_cell_renderer
406
- else
407
- @cell_renderer = val[0]
408
- end
409
- end
410
- def create_default_cell_renderer
411
- return ListCellRenderer.new "", {"color"=>@color, "bgcolor"=>@bgcolor, "parent" => self, "display_length"=> @width-@internal_width-@left_margin}
412
- #return BasicListCellRenderer.new "", {"color"=>@color, "bgcolor"=>@bgcolor, "parent" => self, "display_length"=> @width-2-@left_margin}
413
- end
414
- ##
415
- # this method chops the data to length before giving it to the
416
- # renderer, this can cause problems if the renderer does some
417
- # processing. also, it pans the data horizontally giving the renderer
418
- # a section of it.
419
- def repaint #:nodoc:
420
- return unless @repaint_required
421
- #
422
- # TRYING OUT dangerous 2011-10-15
423
- @repaint_required = false
424
- @repaint_required = true if @widget_scrolled || @pcol != @old_pcol || @record_changed || @property_changed
425
-
426
- unless @repaint_required
427
- unhighlight_row @old_selected_index
428
- highlight_selected_row
429
- end
430
- return unless @repaint_required
431
- $log.debug "BASICLIST REPAINT WILL HAPPEN #{current_index} "
432
- # not sure where to put this, once for all or repeat 2010-02-17 23:07 RFED16
433
- my_win = @form ? @form.window : @target_window
434
- @graphic = my_win unless @graphic
435
- raise " #{@name} neither form, nor target window given LB paint " unless my_win
436
- raise " #{@name} NO GRAPHIC set as yet LB paint " unless @graphic
437
- raise "width or height not given w:#{@width} , h:#{@height} " if @width.nil? || @height.nil?
438
- @win_left = my_win.left
439
- @win_top = my_win.top
440
- @left_margin ||= @row_selected_symbol.length
441
- # we are making sure display len does not exceed width XXX hope this does not wreak havoc elsewhere
442
- _dl = [@display_length || 100, @width-@internal_width-@left_margin].min # 2011-09-17 RK overwriting when we move grabbar in vimsplit
443
-
444
- $log.debug "basiclistbox repaint #{@name} graphic #{@graphic}"
445
- #$log.debug "XXX repaint to_print #{@to_print_borders} "
446
- print_borders unless @suppress_borders # do this once only, unless everything changes
447
- #maxlen = @maxlen || @width-2
448
- tm = list()
449
- rc = row_count
450
- @longest_line = @width
451
- $log.debug " rbasiclistbox #{row_count}, w:#{@width} , maxlen:#{@maxlen} "
452
- if rc > 0 # just added in case no data passed
453
- tr = @toprow
454
- acolor = get_color $datacolor
455
- h = scrollatrow()
456
- r,c = rowcol
457
- 0.upto(h) do |hh|
458
- crow = tr+hh
459
- if crow < rc
460
- _focussed = @current_index == crow ? true : false # row focussed ?
461
- focus_type = _focussed
462
- focus_type = :SOFT_FOCUS if _focussed && !@focussed
463
- selected = is_row_selected crow
464
- content = tm[crow] # 2009-01-17 18:37 chomp giving error in some cases says frozen
465
- content = convert_value_to_text content, crow # 2010-09-23 20:12
466
- # by now it has to be a String
467
- if content.is_a? String
468
- content = content.dup
469
- sanitize content if @sanitization_required
470
- truncate content if @truncation_required
471
- end
472
- ## set the selector symbol if requested
473
- selection_symbol = ''
474
- if @show_selector
475
- if selected
476
- selection_symbol = @row_selected_symbol
477
- else
478
- selection_symbol = @row_unselected_symbol
479
- end
480
- @graphic.printstring r+hh, c, selection_symbol, acolor,@attr
481
- end
482
- #renderer = get_default_cell_renderer_for_class content.class.to_s
483
- renderer = cell_renderer()
484
- renderer.display_length = _dl # 2011-09-17 RK overwriting when we move grabbar in vimsplit
485
- renderer.repaint @graphic, r+hh, c+@left_margin, crow, content, focus_type, selected
486
- else
487
- # clear rows
488
- @graphic.printstring r+hh, c, " " * (@width-@internal_width), acolor,@attr
489
- end
490
- end
491
- end # rc == 0
492
- @repaint_required = false
493
- # 2011-10-13
494
- @widget_scrolled = false
495
- @record_changed = false
496
- @property_changed = false
497
- @old_pcol = @pcol
498
- end
499
- def highlight_selected_row r=nil, c=nil, acolor=nil
500
- return unless @selected_index # no selection
501
- r = _convert_index_to_printable_row(@selected_index) unless r
502
- return unless r # not on screen
503
- unless c
504
- _r, c = rowcol
505
- end
506
- acolor ||= get_color $datacolor, @selected_color, @selected_bgcolor
507
- att = FFI::NCurses::A_REVERSE
508
- att = get_attrib(@selected_attrib) if @selected_attrib
509
- @graphic.mvchgat(y=r, x=c, @width-@internal_width-@left_margin, att , acolor , nil)
510
- end
511
- def unhighlight_row index, r=nil, c=nil, acolor=nil
512
- return unless index # no selection
513
- r = _convert_index_to_printable_row(index) unless r
514
- return unless r # not on screen
515
- unless c
516
- _r, c = rowcol
517
- end
518
- acolor ||= get_color $datacolor
519
- att = FFI::NCurses::A_NORMAL
520
- att = get_attrib(@normal_attrib) if @normal_attrib
521
- @graphic.mvchgat(y=r, x=c, @width-@internal_width-@left_margin, att , acolor , nil)
522
- end
523
- # the idea here is to allow users who subclass Listbox to easily override parts of the cumbersome repaint
524
- # method. This assumes your List has some data, but you print a lot more. Now you don't need to
525
- # change the data in the renderer, or keep formatted data in the list itself.
526
- # e.g. @list contains file names, or File objects, and this converts to a long listing.
527
- # If the renderer did that, the truncation would be on wrong data.
528
- # @since 1.2.0
529
- def convert_value_to_text value, crow
530
- case value
531
- when TrueClass, FalseClass
532
- value
533
- else
534
- value.to_s if value
535
- end
536
- end
537
- # takes a block, this way anyone extending this klass can just pass a block to do his job
538
- # This modifies the string
539
- def sanitize content #:nodoc:
540
- if content.is_a? String
541
- content.chomp!
542
- content.gsub!(/\t/, ' ') # don't display tab
543
- content.gsub!(/[^[:print:]]/, '') # don't display non print characters
544
- else
545
- content
546
- end
547
- end
548
- # returns only the visible portion of string taking into account display length
549
- # and horizontal scrolling. MODIFIES STRING
550
- def truncate content # :nodoc:
551
- maxlen = @maxlen || @width-@internal_width
552
- maxlen = @width-@internal_width if maxlen > @width-@internal_width
553
- if maxlen == 0 # (otherwise it becoems -1 below)
554
- content.replace ""
555
- return
556
- end
557
- if !content.nil?
558
- if content.length > maxlen # only show maxlen
559
- @longest_line = content.length if content.length > @longest_line
560
- #content = content[@pcol..@pcol+maxlen-1]
561
- content.replace content[@pcol..@pcol+maxlen-1]
562
- else
563
- # can this be avoided if pcol is 0 XXX
564
- content.replace content[@pcol..-1] if @pcol > 0
565
- end
566
- end
567
- content
568
- end
569
-
570
- # be informed when data has changed. required here, was being called by listdatamodel earlier
571
- def list_data_changed
572
- if row_count == 0 # added on 2009-02-02 17:13 so cursor not hanging on last row which could be empty
573
- init_vars
574
- @current_index = 0
575
- set_form_row
576
- end
577
- @widget_scrolled = true # 2011-10-15
578
- @repaint_required = true
579
- end
580
-
581
- # set cursor column position
582
- # if i set col1 to @curpos, i can move around left right if key mapped
583
- def set_form_col col1=0 #:nodoc:
584
- @cols_panned ||= 0
585
- # editable listboxes will involve changing cursor and the form issue
586
- win_col = 0
587
- col2 = win_col + @col + @col_offset + col1 + @cols_panned + @left_margin
588
- $log.debug " set_form_col in rlistbox #{@col}+ left_margin #{@left_margin} ( #{col2} ) "
589
- setrowcol nil, col2
590
- end
591
-
592
- # @group selection related
593
-
594
- # change selection of current row on pressing space bar
595
- # If mode is multiple, then other selections are cleared and this is added
596
- # NOTE: 2011-10-8 allow multiple select on spacebar. Using C-Space was quite unfriendly
597
- # although it will still work
598
- def OLDtoggle_row_selection crow=@current_index
599
- @repaint_required = true
600
- row = crow
601
- case @selection_mode
602
- when :multiple
603
- add_to_selection
604
- #clear_selection
605
- #@selected_indices[0] = crow #@current_index
606
- else
607
- if @selected_index == crow #@current_index
608
- @selected_index = nil
609
- lse = ListSelectionEvent.new(crow, crow, self, :DELETE)
610
- fire_handler :LIST_SELECTION_EVENT, lse
611
- else
612
- @selected_index = crow #@current_index
613
- lse = ListSelectionEvent.new(crow, crow, self, :INSERT)
614
- fire_handler :LIST_SELECTION_EVENT, lse
615
- end
616
- end
617
- end
618
- #
619
- # Only for multiple mode.
620
- # add an item to selection, if selection mode is multiple
621
- # if item already selected, it is deselected, else selected
622
- # typically bound to Ctrl-Space
623
- def OLDadd_to_selection
624
- crow = @current_index
625
- case @selection_mode
626
- when :multiple
627
- if @selected_indices.include? @current_index
628
- @selected_indices.delete @current_index
629
- lse = ListSelectionEvent.new(crow, crow, self, :DELETE)
630
- fire_handler :LIST_SELECTION_EVENT, lse
631
- else
632
- @selected_indices << @current_index
633
- lse = ListSelectionEvent.new(crow, crow, self, :INSERT)
634
- fire_handler :LIST_SELECTION_EVENT, lse
635
- end
636
- else
637
- end
638
- @repaint_required = true
639
- end
640
- # clears selected indices
641
- def OLDclear_selection
642
- @selected_indices = []
643
- @repaint_required = true
644
- end
645
- def OLDis_row_selected crow=@current_index
646
- case @selection_mode
647
- when :multiple
648
- @selected_indices.include? crow
649
- else
650
- crow == @selected_index
651
- end
652
- end
653
- alias :is_selected? is_row_selected
654
- def goto_next_selection
655
- return if selected_rows().length == 0
656
- row = selected_rows().sort.find { |i| i > @current_index }
657
- row ||= @current_index
658
- @current_index = row
659
- @repaint_required = true # fire list_select XXX
660
- end
661
- def goto_prev_selection
662
- return if selected_rows().length == 0
663
- row = selected_rows().sort{|a,b| b <=> a}.find { |i| i < @current_index }
664
- row ||= @current_index
665
- @current_index = row
666
- @repaint_required = true # fire list_select XXX
667
- end
668
- # Returns selected indices
669
- # Indices are often required since the renderer may modify the values displayed
670
- #
671
- def get_selected_indices; @selected_indices; end
672
-
673
- # Returns selected values
674
- #
675
- def get_selected_values
676
- selected = []
677
- @selected_indices.each { |i| selected << @list[i] }
678
- return selected
679
- end
680
- alias :selected_values :get_selected_values
681
-
682
-
683
-
684
- # ADD HERE
685
- end # class listb
686
-
687
- ##
688
- # This is a basic list cell renderer that will render the to_s value of anything.
689
- # Using alignment one can use for numbers too.
690
- # However, for booleans it will print true and false. If editing, you may want checkboxes
691
- # I've copied this into ListCellRenderer and added justify, so use that.
692
- class BasicListCellRenderer
693
- include RubyCurses::ConfigSetup
694
- include RubyCurses::Utils
695
- #dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
696
- dsl_accessor :display_length # please give this to ensure the we only print this much
697
- dsl_accessor :height # if you want a multiline label.
698
- dsl_accessor :text # text of label
699
- dsl_accessor :color, :bgcolor
700
- dsl_accessor :row, :col
701
- dsl_accessor :parent #usuall the table to get colors and other default info
702
-
703
- def initialize text="", config={}, &block
704
- @text = text
705
- @editable = false
706
- @focusable = false
707
- config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
708
- instance_eval &block if block_given?
709
- init_vars
710
- end
711
- def init_vars
712
- #@justify ||= :left
713
- #str = @justify.to_sym == :right ? "%*s" : "%-*s" # added 2008-12-22 19:05
714
- @display_length ||= 10
715
- # create color pairs once for this 2010-09-26 20:53
716
- @color_pair = get_color $datacolor
717
- @pairs = Hash.new(@color_pair)
718
- @attrs = Hash.new(Ncurses::A_NORMAL)
719
- color_pair = get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor
720
- @pairs[:normal] = @color_pair
721
- @pairs[:selected] = color_pair
722
- @pairs[:focussed] = @pairs[:normal]
723
- @attrs[:selected] = $row_selected_attr
724
- @attrs[:focussed] = $row_focussed_attr
725
-
726
- end
727
- ##
728
- # sets @color_pair and @attr
729
- def select_colors focussed, selected
730
- @color_pair = @pairs[:normal]
731
- @attr = $row_attr
732
- # give precedence to a selected row
733
- if selected
734
- @color_pair = @pairs[:selected]
735
- @attr = @attrs[:selected]
736
- elsif focussed
737
- @color_pair = @pairs[:focussed]
738
- @attr = @attrs[:focussed]
739
- end
740
- end
741
-
742
- ##
743
- # paint a list box cell
744
- #
745
- # @param [Buffer] window or buffer object used for printing
746
- # @param [Fixnum] row
747
- # @param [Fixnum] column
748
- # @param [Fixnum] actual index into data, some lists may have actual data elsewhere and
749
- # display data separate. e.g. rfe_renderer (directory listing)
750
- # @param [String] text to print in cell
751
- # @param [Boolean, cell focussed, not focussed
752
- # @param [Boolean] cell selected or not
753
- def repaint graphic, r=@row,c=@col, row_index=-1,value=@text, focussed=false, selected=false
754
-
755
- select_colors focussed, selected
756
-
757
- value=value.to_s
758
- if !@display_length.nil?
759
- if value.length > @display_length
760
- value = value[0..@display_length-1]
761
- end
762
- end
763
- len = @display_length || value.length
764
- graphic.printstring r, c, "%-*s" % [len, value], @color_pair, @attr
765
- end # repaint
766
- end # class
767
-
768
- end # module