rbhex-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +2000 -0
  4. data/LICENSE +56 -0
  5. data/README.md +44 -0
  6. data/examples/abasiclist.rb +179 -0
  7. data/examples/alpmenu.rb +50 -0
  8. data/examples/app.sample +19 -0
  9. data/examples/atree.rb +100 -0
  10. data/examples/bline.rb +136 -0
  11. data/examples/common/file.rb +45 -0
  12. data/examples/data/README.markdown +9 -0
  13. data/examples/data/brew.txt +38 -0
  14. data/examples/data/color.2 +37 -0
  15. data/examples/data/gemlist.txt +60 -0
  16. data/examples/data/lotr.txt +12 -0
  17. data/examples/data/ports.txt +136 -0
  18. data/examples/data/table.txt +37 -0
  19. data/examples/data/tasks.csv +88 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/data/todo.txt +10 -0
  22. data/examples/data/todo.txt.bak +10 -0
  23. data/examples/data/todocsv.csv +28 -0
  24. data/examples/data/unix1.txt +21 -0
  25. data/examples/data/unix2.txt +11 -0
  26. data/examples/dbdemo.rb +502 -0
  27. data/examples/dirtree.rb +94 -0
  28. data/examples/newtabbedwindow.rb +100 -0
  29. data/examples/newtesttabp.rb +92 -0
  30. data/examples/tabular.rb +146 -0
  31. data/examples/tasks.rb +178 -0
  32. data/examples/term2.rb +84 -0
  33. data/examples/testbuttons.rb +296 -0
  34. data/examples/testcombo.rb +102 -0
  35. data/examples/testfields.rb +195 -0
  36. data/examples/testkeypress.rb +72 -0
  37. data/examples/testlistbox.rb +170 -0
  38. data/examples/testmessagebox.rb +140 -0
  39. data/examples/testprogress.rb +116 -0
  40. data/examples/testree.rb +106 -0
  41. data/examples/testwsshortcuts.rb +66 -0
  42. data/examples/testwsshortcuts2.rb +128 -0
  43. data/lib/rbhex.rb +6 -0
  44. data/lib/rbhex/core/docs/index.txt +73 -0
  45. data/lib/rbhex/core/include/action.rb +80 -0
  46. data/lib/rbhex/core/include/actionmanager.rb +49 -0
  47. data/lib/rbhex/core/include/appmethods.rb +214 -0
  48. data/lib/rbhex/core/include/bordertitle.rb +48 -0
  49. data/lib/rbhex/core/include/chunk.rb +203 -0
  50. data/lib/rbhex/core/include/io.rb +553 -0
  51. data/lib/rbhex/core/include/listbindings.rb +74 -0
  52. data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
  53. data/lib/rbhex/core/include/listeditable.rb +317 -0
  54. data/lib/rbhex/core/include/listscrollable.rb +663 -0
  55. data/lib/rbhex/core/include/listselectable.rb +271 -0
  56. data/lib/rbhex/core/include/multibuffer.rb +83 -0
  57. data/lib/rbhex/core/include/orderedhash.rb +77 -0
  58. data/lib/rbhex/core/include/ractionevent.rb +73 -0
  59. data/lib/rbhex/core/include/rchangeevent.rb +27 -0
  60. data/lib/rbhex/core/include/rhistory.rb +95 -0
  61. data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
  62. data/lib/rbhex/core/include/vieditable.rb +172 -0
  63. data/lib/rbhex/core/include/widgetmenu.rb +66 -0
  64. data/lib/rbhex/core/system/colormap.rb +165 -0
  65. data/lib/rbhex/core/system/keyboard.rb +150 -0
  66. data/lib/rbhex/core/system/keydefs.rb +30 -0
  67. data/lib/rbhex/core/system/ncurses.rb +236 -0
  68. data/lib/rbhex/core/system/panel.rb +162 -0
  69. data/lib/rbhex/core/system/window.rb +913 -0
  70. data/lib/rbhex/core/util/ansiparser.rb +119 -0
  71. data/lib/rbhex/core/util/app.rb +1228 -0
  72. data/lib/rbhex/core/util/basestack.rb +410 -0
  73. data/lib/rbhex/core/util/bottomline.rb +1859 -0
  74. data/lib/rbhex/core/util/colorparser.rb +77 -0
  75. data/lib/rbhex/core/util/focusmanager.rb +31 -0
  76. data/lib/rbhex/core/util/padreader.rb +192 -0
  77. data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
  78. data/lib/rbhex/core/util/rdialogs.rb +574 -0
  79. data/lib/rbhex/core/util/viewer.rb +149 -0
  80. data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
  81. data/lib/rbhex/core/version.rb +5 -0
  82. data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
  83. data/lib/rbhex/core/widgets/box.rb +58 -0
  84. data/lib/rbhex/core/widgets/divider.rb +310 -0
  85. data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
  86. data/lib/rbhex/core/widgets/rcombo.rb +253 -0
  87. data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
  88. data/lib/rbhex/core/widgets/rlink.rb +30 -0
  89. data/lib/rbhex/core/widgets/rlist.rb +696 -0
  90. data/lib/rbhex/core/widgets/rmenu.rb +958 -0
  91. data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
  92. data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
  93. data/lib/rbhex/core/widgets/rprogress.rb +118 -0
  94. data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
  95. data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
  96. data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
  97. data/lib/rbhex/core/widgets/rtextview.rb +739 -0
  98. data/lib/rbhex/core/widgets/rtree.rb +768 -0
  99. data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
  100. data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
  101. data/lib/rbhex/core/widgets/statusline.rb +113 -0
  102. data/lib/rbhex/core/widgets/tabular.rb +264 -0
  103. data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
  104. data/lib/rbhex/core/widgets/textpad.rb +995 -0
  105. data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
  106. data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
  107. data/rbhex-core.gemspec +32 -0
  108. metadata +172 -0
@@ -0,0 +1,271 @@
1
+ # File created: 2010-10-29 14:09
2
+ # Author : rkumar
3
+ #
4
+ # this is a new, simpler version of listselectable
5
+ # the original gets into models and has complicated operation as well
6
+ # as difficult to remember method names. This attempts to be a simple plugin.
7
+ # Currently being used by rbasiclistbox (rlist) and now tabularwidget.
8
+ # NOTE: pls define @_header_adjustment to 0 if you don't use it or know what it means.
9
+ # TODO: of course we need to fire events so user can do something.
10
+ module RubyCurses
11
+ module NewListSelectable
12
+
13
+ # @group selection related
14
+
15
+ # change selection of current row on pressing space bar
16
+ # If mode is multiple, then other selections are cleared and this is added
17
+ # @example
18
+ # bind_key(32) { toggle_row_selection }
19
+ # current_index is not account for header_adjustment
20
+ # if current row is selected in mulitple we should deselect ?? FIXME
21
+ def toggle_row_selection crow=@current_index-@_header_adjustment
22
+ @last_clicked = crow
23
+ @repaint_required = true
24
+ case @selection_mode
25
+ when :multiple
26
+ @widget_scrolled = true # FIXME we need a better name
27
+ if @selected_indices.include? crow
28
+ @selected_indices.delete crow
29
+ lse = ListSelectionEvent.new(crow, crow, self, :DELETE)
30
+ fire_handler :LIST_SELECTION_EVENT, lse
31
+ else
32
+ @selected_indices << crow
33
+ lse = ListSelectionEvent.new(crow, crow, self, :INSERT)
34
+ fire_handler :LIST_SELECTION_EVENT, lse
35
+ end
36
+ else
37
+ if @selected_index == crow
38
+ @old_selected_index = @selected_index # 2011-10-15 so we can unhighlight
39
+ @selected_index = nil
40
+ lse = ListSelectionEvent.new(crow, crow, self, :DELETE)
41
+ fire_handler :LIST_SELECTION_EVENT, lse
42
+ else
43
+ @old_selected_index = @selected_index # 2011-10-15 so we can unhighlight
44
+ @selected_index = crow
45
+ lse = ListSelectionEvent.new(crow, crow, self, :INSERT)
46
+ fire_handler :LIST_SELECTION_EVENT, lse
47
+ end
48
+ end
49
+ end
50
+ #
51
+ # Only for multiple mode.
52
+ # add an item to selection, if selection mode is multiple
53
+ # if item already selected, it is deselected, else selected
54
+ # typically bound to Ctrl-Space
55
+ # @example
56
+ # bind_key(0) { add_to_selection }
57
+ def add_to_selection crow=@current_index-@_header_adjustment
58
+ @last_clicked ||= crow
59
+ min = [@last_clicked, crow].min
60
+ max = [@last_clicked, crow].max
61
+ case @selection_mode
62
+ when :multiple
63
+ @widget_scrolled = true # FIXME we need a better name
64
+ if @selected_indices.include? crow
65
+ # delete from last_clicked until this one in any direction
66
+ min.upto(max){ |i| @selected_indices.delete i }
67
+ lse = ListSelectionEvent.new(min, max, self, :DELETE)
68
+ fire_handler :LIST_SELECTION_EVENT, lse
69
+ else
70
+ # add to selection from last_clicked until this one in any direction
71
+ min.upto(max){ |i| @selected_indices << i unless @selected_indices.include?(i) }
72
+ lse = ListSelectionEvent.new(min, max, self, :INSERT)
73
+ fire_handler :LIST_SELECTION_EVENT, lse
74
+ end
75
+ else
76
+ end
77
+ @repaint_required = true
78
+ self
79
+ end
80
+ # clears selected indices, typically called when multiple select
81
+ # Key binding is application specific
82
+ def clear_selection
83
+ return if @selected_indices.nil? || @selected_indices.empty?
84
+ @selected_indices = []
85
+ @selected_index = nil
86
+ @old_selected_index = nil
87
+ # Not sure what event type I should give, DELETE or a new one, user should
88
+ # understand that selection has been cleared, and ignore first two params
89
+ lse = ListSelectionEvent.new(0, @list.size, self, :CLEAR)
90
+ fire_handler :LIST_SELECTION_EVENT, lse
91
+ @repaint_required = true
92
+ @widget_scrolled = true # FIXME we need a better name
93
+ end
94
+ def is_row_selected crow=@current_index-@_header_adjustment
95
+ case @selection_mode
96
+ when :multiple
97
+ @selected_indices.include? crow
98
+ else
99
+ crow == @selected_index
100
+ end
101
+ end
102
+ alias :is_selected? is_row_selected
103
+ # FIXME add adjustment and test
104
+ def goto_next_selection
105
+ return if selected_rows().length == 0
106
+ row = selected_rows().sort.find { |i| i > @current_index }
107
+ row ||= @current_index
108
+ @current_index = row
109
+ @repaint_required = true # fire list_select XXX
110
+ end
111
+ # FIXME add adjustment and test
112
+ def goto_prev_selection
113
+ return if selected_rows().length == 0
114
+ row = selected_rows().sort{|a,b| b <=> a}.find { |i| i < @current_index }
115
+ row ||= @current_index
116
+ @current_index = row
117
+ @repaint_required = true # fire list_select XXX
118
+ end
119
+ # add the following range to selected items, unless already present
120
+ # should only be used if multiple selection interval
121
+ def add_selection_interval ix0, ix1
122
+ return if @selection_mode != :multiple
123
+ @widget_scrolled = true # FIXME we need a better name
124
+ @anchor_selection_index = ix0
125
+ @lead_selection_index = ix1
126
+ ix0.upto(ix1) {|i| @selected_indices << i unless @selected_indices.include? i }
127
+ lse = ListSelectionEvent.new(ix0, ix1, self, :INSERT)
128
+ fire_handler :LIST_SELECTION_EVENT, lse
129
+ #$log.debug " DLSM firing LIST_SELECTION EVENT #{lse}"
130
+ end
131
+ alias :add_row_selection_interval :add_selection_interval
132
+ def remove_selection_interval ix0, ix1
133
+ @anchor_selection_index = ix0
134
+ @lead_selection_index = ix1
135
+ @selected_indices.delete_if {|x| x >= ix0 and x <= ix1}
136
+ lse = ListSelectionEvent.new(ix0, ix1, self, :DELETE)
137
+ fire_handler :LIST_SELECTION_EVENT, lse
138
+ end
139
+ alias :remove_row_selection_interval :remove_selection_interval
140
+ # convenience method to select next len rows
141
+ def insert_index_interval ix0, len
142
+ @anchor_selection_index = ix0
143
+ @lead_selection_index = ix0+len
144
+ add_selection_interval @anchor_selection_index, @lead_selection_index
145
+ end
146
+ # select all rows, you may specify starting row.
147
+ # if header row, then 1 else should be 0. Actually we should have a way to determine
148
+ # this, and the default should be zero.
149
+ def select_all start_row=0 #+@_header_adjustment
150
+ @repaint_required = true
151
+ # don't select header row - need to make sure this works for all cases. we may
152
+ # need a variable instead of hardoded value
153
+ add_row_selection_interval start_row, row_count()
154
+ end
155
+ def invert_selection start_row=0 #+@_header_adjustment
156
+ start_row.upto(row_count()){|i| invert_row_selection i }
157
+ end
158
+
159
+ def invert_row_selection row=@current_index-@_header_adjustment
160
+ @repaint_required = true
161
+ if is_selected? row
162
+ remove_row_selection_interval(row, row)
163
+ else
164
+ add_row_selection_interval(row, row)
165
+ end
166
+ end
167
+ # selects all rows with the values given, leaving existing selections
168
+ # intact. Typically used after accepting search criteria, and getting a list of values
169
+ # to select (such as file names). Will not work with tables (array or array)
170
+ def select_values values
171
+ return unless values
172
+ values.each do |val|
173
+ row = @list.index val
174
+ add_row_selection_interval row, row unless row.nil?
175
+ end
176
+ end
177
+ # unselects all rows with the values given, leaving all other rows intact
178
+ # You can map "-" to ask_select and call this from there.
179
+ # bind_key(?+, :ask_select) # --> calls select_values
180
+ # bind_key(?-, :ask_unselect)
181
+ def unselect_values values
182
+ return unless values
183
+ values.each do |val|
184
+ row = @list.index val
185
+ remove_row_selection_interval row, row unless row.nil?
186
+ end
187
+ end
188
+ # please override this, this is just very basic and default
189
+ # Please implement get_matching_indices(String).
190
+ def ask_select prompt="Enter selection pattern: "
191
+ ret = ask(prompt, String) {|q| yield q if block_given? }
192
+ return if ret.nil? || ret == ""
193
+ indices = get_matching_indices ret
194
+ return if indices.nil? || indices.empty?
195
+ indices.each { |e|
196
+ # will not work if single select !! FIXME
197
+ add_row_selection_interval e,e
198
+ }
199
+ @repaint_required = true
200
+ end
201
+ def get_matching_indices pattern
202
+ alert "please implement this method get_matching_indices(pattern)->[] in your class "
203
+ return []
204
+ end # mod
205
+ # Applications may call this or just copy and modify
206
+
207
+ ##
208
+ # bindings related to selection
209
+ #
210
+ def list_bindings
211
+ # what about users wanting 32 and ENTER to also go to next row automatically
212
+ # should make that optional, TODO
213
+ bind_key($row_selector || 32, 'toggle selection') { toggle_row_selection }
214
+ # 2013-03-24 - 14:46 added condition so single select does not get these
215
+ if @selection_mode == :multiple
216
+ bind_key(0, 'range select') { add_to_selection }
217
+ bind_key(?+, :ask_select) # --> calls select_values
218
+ bind_key(?-, :ask_unselect) # please implement FIXME TODO
219
+ bind_key(?a, :select_all)
220
+ bind_key(?*, :invert_selection)
221
+ bind_key(?u, :clear_selection)
222
+ end
223
+ @_header_adjustment ||= 0 # incase caller does not use
224
+ @_events << :LIST_SELECTION_EVENT unless @_events.include? :LIST_SELECTION_EVENT
225
+ end
226
+ def list_init_vars
227
+ @selected_indices = []
228
+ @selected_index = nil
229
+ @old_selected_index = nil
230
+ #@row_selected_symbol = ''
231
+ if @show_selector
232
+ @row_selected_symbol ||= '*'
233
+ @row_unselected_symbol ||= ' '
234
+ @left_margin ||= @row_selected_symbol.length
235
+ end
236
+ end
237
+ # paint the selector. Called from repaint, prior to printing data row
238
+ # remember to set left_margin at top of repaint method as:
239
+ # @left_margin ||= @row_selected_symbol.length
240
+ def paint_selector crow, r, c, acolor, attrib
241
+ selected = is_row_selected crow
242
+ selection_symbol = ''
243
+ if @show_selector
244
+ if selected
245
+ selection_symbol = @row_selected_symbol
246
+ else
247
+ selection_symbol = @row_unselected_symbol
248
+ end
249
+ @graphic.printstring r, c, selection_symbol, acolor,attrib
250
+ end
251
+ end
252
+ def selected_rows
253
+ @selected_indices
254
+ end
255
+ end # mod
256
+ class ListSelectionEvent
257
+ attr_accessor :firstrow, :lastrow, :source, :type
258
+ def initialize firstrow, lastrow, source, type
259
+ @firstrow = firstrow
260
+ @lastrow = lastrow
261
+ @source = source
262
+ @type = type
263
+ end
264
+ def to_s
265
+ "#{@type.to_s}, firstrow: #{@firstrow}, lastrow: #{@lastrow}, source: #{@source}"
266
+ end
267
+ def inspect
268
+ to_s
269
+ end
270
+ end
271
+ end # mod
@@ -0,0 +1,83 @@
1
+ module RubyCurses
2
+ # this module makes it possible for a textview to maintain multiple buffers
3
+ # The first buffer has been placed using set_content(lines, config).
4
+ # After this, additional buffers mst be supplied with add_content text, config.
5
+ # Also, please note that after you call set_content the first time, you must call
6
+ # add_content so the buffer can be accessed while cycling. will try to fix this.
7
+ # (I don't want to touch textview, would prefer not to write a decorator).
8
+
9
+ # TODO allow setting of a limit, so in some cases where we keep adding
10
+ # programatically, the
11
+ module MultiBuffers
12
+ extend self
13
+
14
+ # add content to buffers of a textview
15
+ # @param [Array] text
16
+ # @param [Hash] options, typically :content_type => :ansi or :tmux
17
+ def add_content text, config={}
18
+ unless @_buffers
19
+ bind_key(?\M-n, :buffer_next)
20
+ bind_key(?\M-p, :buffer_prev)
21
+ bind_key(KEY_BACKSPACE, :buffer_prev) # backspace, already hardcoded in textview !
22
+ bind_key(?:, :buffer_menu)
23
+ end
24
+ @_buffers ||= []
25
+ @_buffers_conf ||= []
26
+ @_buffers << text
27
+ @_buffers_conf << config
28
+ @_buffer_ctr ||= 0
29
+ $log.debug "XXX: HELP adding text #{@_buffers.size} "
30
+ end
31
+
32
+ # display next buffer
33
+ def buffer_next
34
+ @_buffer_ctr += 1
35
+ x = @_buffer_ctr
36
+ l = @_buffers[x]
37
+ @_buffer_ctr = 0 unless l
38
+ set_content @_buffers[@_buffer_ctr], @_buffers_conf[@_buffer_ctr]
39
+ end
40
+ #
41
+ # display previous buffer if any
42
+ def buffer_prev
43
+ if @_buffer_ctr < 1
44
+ buffer_last
45
+ return
46
+ end
47
+ @_buffer_ctr -= 1 if @_buffer_ctr > 0
48
+ x = @_buffer_ctr
49
+ l = @_buffers[x]
50
+ if l
51
+ set_content l, @_buffers_conf[x]
52
+ end
53
+ end
54
+ def buffer_last
55
+ @_buffer_ctr = @_buffers.count - 1
56
+ l = @_buffers.last
57
+ set_content l, @_buffers_conf.last
58
+ end
59
+ # close window, a bit clever
60
+ def close
61
+ @graphic.ungetch(?q.ord)
62
+ end
63
+ # display a menu so user can do buffer management
64
+ # However, how can application add to these. Or disable, such as when we
65
+ # add buffer delete or buffer insert or edit
66
+ def buffer_menu
67
+ menu = PromptMenu.new self do
68
+ item :n, :buffer_next
69
+ item :p, :buffer_prev
70
+ item :b, :scroll_backward
71
+ item :f, :scroll_forward
72
+ item :q, :close
73
+ submenu :m, "submenu..." do
74
+ item :p, :goto_last_position
75
+ item :r, :scroll_right
76
+ item :l, :scroll_left
77
+ end
78
+ end
79
+ menu.display_new :title => "Buffer Menu"
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,77 @@
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
@@ -0,0 +1,73 @@
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.to_s
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
+ # if pressed on a space, try to go to next word to make easier 2013-03-24
61
+ if line[pos,1] == delim
62
+ while line[pos,1] == delim
63
+ pos += 1
64
+ end
65
+ end
66
+ finish = line.index(delim, pos)
67
+ start = line.rindex(delim,pos)
68
+ finish = -1 if finish.nil?
69
+ start = 0 if start.nil?
70
+ return line[start..finish]
71
+ end
72
+ end
73
+ end