rbcurse 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,6 @@
1
+ require 'rbcurse/listselectable'
2
+ ##
3
+ # Added ListSelectionEvents on 2009-02-13 23:33
1
4
  module RubyCurses
2
5
  class DefaultListSelectionModel
3
6
  include EventHandler
@@ -9,10 +12,15 @@ module RubyCurses
9
12
  @anchor_selection_index = -1
10
13
  @lead_selection_index = -1
11
14
  @selection_mode = :MULTIPLE
15
+ $log.debug " created DefaultListSelectionModel XXX"
12
16
  end
13
17
 
14
18
  def clear_selection
19
+ ix0 = @selected_indices.first
20
+ ix1 = @selected_indices.last
15
21
  @selected_indices=[]
22
+ lse = ListSelectionEvent.new(ix0, ix1, self, :DELETE)
23
+ fire_handler :LIST_SELECTION_EVENT, lse
16
24
  end
17
25
  def is_selected_index ix
18
26
  @selected_indices.include? ix
@@ -28,17 +36,23 @@ module RubyCurses
28
36
  end
29
37
  ## TODO should go in sorted, and no dupes
30
38
  def add_selection_interval ix0, ix1
39
+ $log.debug " def add_selection_interval #{ix0}, ix1"
31
40
  if @selection_mode != :MULTIPLE
32
41
  clear_selection
33
42
  end
34
43
  @anchor_selection_index = ix0
35
44
  @lead_selection_index = ix1
36
45
  ix0.upto(ix1) {|i| @selected_indices << i unless @selected_indices.include? i }
46
+ lse = ListSelectionEvent.new(ix0, ix1, self, :INSERT)
47
+ fire_handler :LIST_SELECTION_EVENT, lse
48
+ $log.debug " DLSM firing LIST_SELECTION EVENT #{lse}"
37
49
  end
38
50
  def remove_selection_interval ix0, ix1
39
51
  @anchor_selection_index = ix0
40
52
  @lead_selection_index = ix1
41
53
  @selected_indices.delete_if {|x| x >= ix0 and x <= ix1}
54
+ lse = ListSelectionEvent.new(ix0, ix1, self, :DELETE)
55
+ fire_handler :LIST_SELECTION_EVENT, lse
42
56
  end
43
57
  def insert_index_interval ix0, len
44
58
  @anchor_selection_index = ix0
@@ -93,6 +93,13 @@ module RubyCurses
93
93
  graphic.printstring r, c, str % [len, _value], @color_pair,@attr
94
94
  r += 1
95
95
  end
96
+ =begin
97
+ if @parent.search_found_ix == row_index
98
+ if !@parent.find_offset.nil?
99
+ graphic.mvchgat(y=r, x=@parent.find_offset, @parent.find_offset1, Ncurses::A_NORMAL, $reversecolor, nil)
100
+ end
101
+ end
102
+ =end
96
103
  end
97
104
  # ADD HERE
98
105
  end
@@ -5,14 +5,17 @@ module RubyCurses
5
5
  # any changes to the vars after construction won't have an effect.
6
6
  def install_list_keys
7
7
  @KEY_ROW_SELECTOR ||= ?\C-x
8
+ @KEY_BLOCK_SELECTOR ||= ?\M-x
8
9
  @KEY_GOTO_TOP ||= ?\M-0
9
10
  @KEY_GOTO_BOTTOM ||= ?\M-9
10
- @KEY_ASK_FIND_FORWARD ||= ?\M-f
11
- @KEY_ASK_FIND_BACKWARD ||= ?\M-F
12
- @KEY_FIND_NEXT ||= ?\M-g
13
- @KEY_FIND_PREV ||= ?\M-G
11
+ #@KEY_ASK_FIND_FORWARD ||= ?\M-f
12
+ #@KEY_ASK_FIND_BACKWARD ||= ?\M-F
13
+ #@KEY_FIND_NEXT ||= ?\M-g
14
+ #@KEY_FIND_PREV ||= ?\M-G
14
15
  @KEY_SCROLL_FORWARD ||= ?\C-n
15
16
  @KEY_SCROLL_BACKWARD ||= ?\C-p
17
+ @KEY_SCROLL_RIGHT ||= ?\M-8
18
+ @KEY_SCROLL_LEFT ||= ?\M-7
16
19
 
17
20
  @KEY_CLEAR_SELECTION ||= ?\M-e
18
21
  @KEY_PREV_SELECTION ||= ?\M-"
@@ -8,6 +8,7 @@
8
8
  # @pcol (used for horiz scrolling, starts at 0)
9
9
  #
10
10
  module ListScrollable
11
+ attr_reader :search_found_ix, :find_offset, :find_offset1
11
12
  def previous_row
12
13
  @oldrow = @current_index
13
14
  @current_index -= 1 if @current_index > 0
@@ -61,9 +62,9 @@ module ListScrollable
61
62
  def bounds_check
62
63
  h = scrollatrow()
63
64
  rc = row_count
64
- $log.debug " PRE CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
65
+ #$log.debug " PRE CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
65
66
  @current_index = 0 if @current_index < 0 # not lt 0
66
- @current_index = rc-1 if @current_index >= rc # not gt rowcount
67
+ @current_index = rc-1 if @current_index >= rc and rc>0 # not gt rowcount
67
68
  @toprow = rc-h-1 if rc > h and @toprow > rc - h - 1 # toprow shows full page if possible
68
69
  # curr has gone below table, move toprow forward
69
70
  if @current_index - @toprow > h
@@ -74,11 +75,12 @@ module ListScrollable
74
75
  end
75
76
  #$log.debug " POST CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
76
77
  if @oldrow != @current_index
77
- $log.debug "going to call on leave and on enter"
78
+ #$log.debug "going to call on leave and on enter"
78
79
  on_leave_row @oldrow if respond_to? :on_leave_row # to be defined by widget that has included this
79
80
  on_enter_row @current_index if respond_to? :on_enter_row # to be defined by widget that has included this
80
81
  end
81
82
  set_form_row
83
+ #set_form_col 0 # added 2009-02-15 23:33 # this works for lists but we don't want this in TextArea's
82
84
  @repaint_required = true
83
85
  end
84
86
  # the cursor should be appropriately positioned
@@ -129,13 +131,13 @@ module ListScrollable
129
131
  when KEY_UP
130
132
  #select_prev_row
131
133
  #up
132
- $log.debug " GOT KEY UP NEW SCROLL"
134
+ #$log.debug " GOT KEY UP NEW SCROLL"
133
135
  previous_row
134
136
  when KEY_LEFT
135
137
  when KEY_RIGHT
136
138
  when KEY_DOWN
137
139
  #down
138
- $log.debug " GOT KEY DOWN NEW SCROLL"
140
+ #$log.debug " GOT KEY DOWN NEW SCROLL"
139
141
  next_row
140
142
  when KEY_ENTER, 10, 13
141
143
  if respond_to? :fire
@@ -203,14 +205,149 @@ module ListScrollable
203
205
  sar = scrollatrow + 1
204
206
  @toprow = (@current_index / sar) * sar
205
207
 
206
- $log.debug "1 set_focus #{total}, sar #{sar}, toprow #{@toprow}, current_index #{@current_index}"
208
+ #$log.debug "1 set_focus #{total}, sar #{sar}, toprow #{@toprow}, current_index #{@current_index}"
207
209
  if total - @toprow < sar
208
210
  @toprow = (total - sar)
209
211
  end
210
- $log.debug "2 set_focus #{total}, sar #{sar}, toprow #{@toprow}, current_index #{@current_index}"
212
+ #$log.debug "2 set_focus #{total}, sar #{sar}, toprow #{@toprow}, current_index #{@current_index}"
211
213
  set_form_row # 2009-01-17 12:44
212
214
  @repaint_required = true
213
215
  #bounds_check
214
216
  end
217
+ def install_keys
218
+ =begin
219
+ @KEY_ASK_FIND_FORWARD ||= ?\M-f
220
+ @KEY_ASK_FIND_BACKWARD ||= ?\M-F
221
+ @KEY_FIND_NEXT ||= ?\M-g
222
+ @KEY_FIND_PREV ||= ?\M-G
223
+ =end
224
+ @KEY_ASK_FIND ||= ?\M-f
225
+ @KEY_FIND_MORE ||= ?\M-g
226
+ end
227
+ def ask_search
228
+ options = ["Search backwards", "case insensitive", "Wrap around"]
229
+ sel,regex,hash = get_string_with_options("Enter regex to search", 20, @last_regex||"", "checkboxes"=>options, "checkbox_defaults"=>[@search_direction_prev,@search_case,@search_wrap])
230
+ return if sel != 0
231
+ @search_direction_prev = hash[options[0]]
232
+ @search_case = hash[options[1]]
233
+ @search_wrap = hash[options[2]]
234
+ if @search_direction_prev == true
235
+ ix = _find_prev regex, @current_index
236
+ else
237
+ ix = _find_next regex, @current_index
238
+ end
239
+ if ix.nil?
240
+ alert("No matching data for: #{regex}")
241
+ else
242
+ set_focus_on(ix)
243
+ set_form_col @find_offset1
244
+ @cell_editor.component.curpos = (@find_offset||0) if @cell_editing_allowed
245
+ end
246
+ end
247
+ def find_more
248
+ if @search_direction_prev
249
+ find_prev
250
+ else
251
+ find_next
252
+ end
253
+ end
254
+ # find forwards
255
+ # Using this to start a search or continue search
256
+ def _find_next regex=@last_regex, start = @search_found_ix
257
+ raise "No previous search" if regex.nil?
258
+ #$log.debug " _find_next #{@search_found_ix} : #{@current_index}"
259
+ fend = @list.size-1
260
+ if start != fend
261
+ start += 1 unless start == fend
262
+ @last_regex = regex
263
+ @search_start_ix = start
264
+ regex = Regexp.new(regex, Regexp::IGNORECASE) if @search_case
265
+ start.upto(fend) do |ix|
266
+ row = @list[ix]
267
+ m=row.match(regex)
268
+ if !m.nil?
269
+ @find_offset = m.offset(0)[0]
270
+ @find_offset1 = m.offset(0)[1]
271
+ @search_found_ix = ix
272
+ return ix
273
+ end
274
+ end
275
+ end
276
+ fend = start-1
277
+ start = 0
278
+ if @search_wrap
279
+ start.upto(fend) do |ix|
280
+ row = @list[ix]
281
+ m=row.match(regex)
282
+ if !m.nil?
283
+ @find_offset = m.offset(0)[0]
284
+ @find_offset1 = m.offset(0)[1]
285
+ @search_found_ix = ix
286
+ return ix
287
+ end
288
+ end
289
+ end
290
+ return nil
291
+ end
292
+ def find_next
293
+ ix = _find_next
294
+ regex = @last_regex
295
+ if ix.nil?
296
+ alert("No more matching data for: #{regex}")
297
+ else
298
+ set_focus_on(ix)
299
+ set_form_col @find_offset1
300
+ @cell_editor.component.curpos = (@find_offset||0) if @cell_editing_allowed
301
+ end
302
+ end
303
+ def find_prev
304
+ ix = _find_prev
305
+ regex = @last_regex
306
+ if ix.nil?
307
+ alert("No previous matching data for: #{regex}")
308
+ else
309
+ set_focus_on(ix)
310
+ set_form_col @find_offset
311
+ @cell_editor.component.curpos = (@find_offset||0) if @cell_editing_allowed
312
+ end
313
+ end
314
+ ##
315
+ # find backwards
316
+ # Using this to start a search or continue search
317
+ def _find_prev regex=@last_regex, start = @search_found_ix
318
+ raise "No previous search" if regex.nil?
319
+ #$log.debug " _find_prev #{@search_found_ix} : #{@current_index}"
320
+ if start != 0
321
+ start -= 1 unless start == 0
322
+ @last_regex = regex
323
+ @search_start_ix = start
324
+ regex = Regexp.new(regex, Regexp::IGNORECASE) if @search_case
325
+ start.downto(0) do |ix|
326
+ row = @list[ix]
327
+ m=row.match(regex)
328
+ if !m.nil?
329
+ @find_offset = m.offset(0)[0]
330
+ @find_offset1 = m.offset(0)[1]
331
+ @search_found_ix = ix
332
+ return ix
333
+ end
334
+ end
335
+ end
336
+ fend = start-1
337
+ start = @list.size-1
338
+ if @search_wrap
339
+ start.downto(fend) do |ix|
340
+ row = @list[ix]
341
+ m=row.match(regex)
342
+ if !m.nil?
343
+ @find_offset = m.offset(0)[0]
344
+ @find_offset1 = m.offset(0)[1]
345
+ @search_found_ix = ix
346
+ return ix
347
+ end
348
+ end
349
+ end
350
+ return nil
351
+ end
215
352
 
216
353
  end
@@ -3,8 +3,13 @@
3
3
  module RubyCurses
4
4
  module ListSelectable
5
5
 
6
- def list_selection_model lsm
7
- @list_selection_model = lsm
6
+ ## modified on 2009-02-13 23:41 to return model if no param passed
7
+ def list_selection_model(*lsm)
8
+ if lsm.empty?
9
+ @list_selection_model
10
+ else
11
+ @list_selection_model = lsm[0]
12
+ end
8
13
  #@list_selection_model.selection_mode = @selection_mode || :MULTIPLE
9
14
  end
10
15
  def create_default_list_selection_model
@@ -15,6 +20,7 @@ module RubyCurses
15
20
  end
16
21
 
17
22
  def add_row_selection_interval ix0, ix1
23
+ $log.debug " def add_row_selection_interval #{ix0}, ix1"
18
24
  # if row_selection_allowed
19
25
  @list_selection_model.add_selection_interval ix0, ix1
20
26
  end
@@ -64,4 +70,19 @@ module RubyCurses
64
70
  attr_accessor :row_selection_allowed
65
71
  attr_accessor :column_selection_allowed
66
72
  end
73
+ class ListSelectionEvent
74
+ attr_accessor :firstrow, :lastrow, :source, :type
75
+ def initialize firstrow, lastrow, source, type
76
+ @firstrow = firstrow
77
+ @lastrow = lastrow
78
+ @source = source
79
+ @type = type
80
+ end
81
+ def to_s
82
+ "#{@type.to_s}, firstrow: #{@firstrow}, lastrow: #{@lastrow}, source: #{@source}"
83
+ end
84
+ def inspect
85
+ to_s
86
+ end
87
+ end
67
88
  end
@@ -44,6 +44,7 @@ module RubyCurses
44
44
  include Enumerable
45
45
  include RubyCurses::EventHandler
46
46
  attr_accessor :selected_index
47
+ attr_reader :last_regex # should i really keep here as public or maintain in listbox
47
48
 
48
49
  def initialize anarray
49
50
  @list = anarray.dup
@@ -64,6 +65,7 @@ module RubyCurses
64
65
  @list.index(obj)
65
66
  end
66
67
  def length ; @list.length; end
68
+ alias :size :length
67
69
 
68
70
  def insert off0, *data
69
71
  @list.insert off0, *data
@@ -112,7 +114,7 @@ module RubyCurses
112
114
  @list.dup
113
115
  end
114
116
  def on_enter_row object
115
- $log.debug " XXX on_enter_row of list_data"
117
+ #$log.debug " XXX on_enter_row of list_data"
116
118
  fire_handler :ENTER_ROW, object
117
119
  end
118
120
  # ##
@@ -143,10 +145,10 @@ module RubyCurses
143
145
  return find_match @last_regex, start, @search_end_ix
144
146
  end
145
147
  ##
146
- # find backwards
148
+ # find backwards, list_data_model
147
149
  # Using this to start a search or continue search
148
150
  def find_prev regex=@last_regex, start = @search_found_ix
149
- raise "No previous search" if @last_regex.nil?
151
+ raise "No previous search" if regex.nil? # @last_regex.nil?
150
152
  $log.debug " find_prev #{@search_found_ix} : #{@current_index}"
151
153
  start -= 1 unless start == 0
152
154
  @last_regex = regex
@@ -427,6 +429,7 @@ module RubyCurses
427
429
  select_default_values
428
430
  # when the combo box has a certain row in focus, the popup should have the same row in focus
429
431
 
432
+ install_keys
430
433
  init_vars
431
434
  install_list_keys
432
435
 
@@ -531,7 +534,7 @@ module RubyCurses
531
534
  h = scrollatrow()
532
535
  rc = row_count
533
536
  $log.debug " listbxo got ch #{ch}"
534
- $log.debug " when kps #{@KEY_PREV_SELECTION} "
537
+ #$log.debug " when kps #{@KEY_PREV_SELECTION} "
535
538
  case ch
536
539
  when KEY_UP # show previous value
537
540
  previous_row
@@ -565,14 +568,21 @@ module RubyCurses
565
568
  @repaint_required = true
566
569
  when 27, ?\C-c:
567
570
  editing_canceled @current_index if @cell_editing_allowed
571
+ cancel_block # block
568
572
  when @KEY_ASK_FIND_FORWARD
569
- ask_search_forward
573
+ # ask_search_forward
570
574
  when @KEY_ASK_FIND_BACKWARD
571
- ask_search_backward
575
+ # ask_search_backward
572
576
  when @KEY_FIND_NEXT
573
- find_next
577
+ # find_next
574
578
  when @KEY_FIND_PREV
575
- find_prev
579
+ # find_prev
580
+ when @KEY_ASK_FIND
581
+ ask_search
582
+ when @KEY_FIND_MORE
583
+ find_more
584
+ when @KEY_BLOCK_SELECTOR
585
+ mark_block #selection
576
586
  else
577
587
  # this has to be fixed, if compo does not handle key it has to continue into next part FIXME
578
588
  ret = :UNHANDLED # changed on 2009-01-27 13:14 not going into unhandled, tab not released
@@ -606,8 +616,10 @@ module RubyCurses
606
616
  set_focus_on(ix)
607
617
  end
608
618
  end
619
+ # gets string to search and calls data models find prev
609
620
  def ask_search_backward
610
621
  regex = get_string("Enter regex to search (backward)")
622
+ @last_regex = regex
611
623
  ix = @list.find_prev regex, @current_index
612
624
  if ix.nil?
613
625
  alert("No matching data for: #{regex}")
@@ -615,7 +627,8 @@ module RubyCurses
615
627
  set_focus_on(ix)
616
628
  end
617
629
  end
618
- def find_prev
630
+ ## listbox find_prev
631
+ def OLDfind_prev
619
632
  ix = @list.find_prev
620
633
  regex = @last_regex
621
634
  if ix.nil?
@@ -627,7 +640,7 @@ module RubyCurses
627
640
  end
628
641
  end
629
642
  # table find_next
630
- def find_next
643
+ def OLDfind_next
631
644
  ix = @list.find_next
632
645
  regex = @last_regex
633
646
  if ix.nil?
@@ -639,12 +652,12 @@ module RubyCurses
639
652
  def on_enter
640
653
  on_enter_row @current_index
641
654
  set_form_row # added 2009-01-11 23:41
642
- $log.debug " ONE ENTER LIST #{@current_index}, #{@form.row}"
643
- @repaint_required
655
+ #$log.debug " ONE ENTER LIST #{@current_index}, #{@form.row}"
656
+ @repaint_required = true
644
657
  fire_handler :ENTER, self
645
658
  end
646
659
  def on_enter_row arow
647
- $log.debug " Listbox #{self} ENTER_ROW with curr #{@current_index}. row: #{arow} H: #{@handler.keys}"
660
+ #$log.debug " Listbox #{self} ENTER_ROW with curr #{@current_index}. row: #{arow} H: #{@handler.keys}"
648
661
  #fire_handler :ENTER_ROW, arow
649
662
  fire_handler :ENTER_ROW, self
650
663
  @list.on_enter_row self
@@ -668,7 +681,8 @@ module RubyCurses
668
681
  col = c+@left_margin # @form.col
669
682
  # unfortunately 2009-01-11 19:47 combo boxes editable allows changing value
670
683
  editor.prepare_editor self, row, col, value
671
- set_form_col @left_margin
684
+ editor.component.curpos = 0 # reset it after search, if user scrols down
685
+ set_form_col 0 #@left_margin
672
686
 
673
687
  # set original value so we can cancel
674
688
  # set row and col,
@@ -676,7 +690,7 @@ module RubyCurses
676
690
  end
677
691
  def on_leave_row arow
678
692
  #$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: list[row]:#{@list[arow]}"
679
- $log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: "
693
+ #$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: "
680
694
  #fire_handler :LEAVE_ROW, arow
681
695
  fire_handler :LEAVE_ROW, self
682
696
  editing_completed arow
@@ -797,7 +811,47 @@ module RubyCurses
797
811
  end
798
812
  @repaint_required = true
799
813
  end
814
+ def set_form_col col=0
815
+ super col+@left_margin
816
+ end
817
+ # experimental selection of multiple rows via block
818
+ # specify a block start and then a block end
819
+ # usage: bind mark_selection to a key. It works as a toggle.
820
+ # C-c will cancel any selection that has begun.
821
+ # added on 2009-02-19 22:37
822
+ def mark_block #selection
823
+ if @inside_block
824
+ @inside_block = false
825
+ end_block #selection
826
+ else
827
+ @inside_block = true
828
+ start_block #selection
829
+ end
830
+ end
831
+ # added on 2009-02-19 22:37
832
+ def cancel_block
833
+ @first_index = @last_index = nil
834
+ @inside_block = false
835
+ end
836
+ # sets marker for start of block
837
+ # added on 2009-02-19 22:37
838
+ def start_block #selection
839
+ @first_index = @current_index
840
+ @last_index = nil
841
+ end
842
+ # sets marker for end of block
843
+ # added on 2009-02-19 22:37
844
+ def end_block #selection
845
+ @last_index = current_index
846
+ lower = [@first_index, @last_index].min
847
+ higher = [@first_index, @last_index].max
848
+ #lower.upto(higher) do |i| @list.toggle_row_selection i; end
849
+ add_row_selection_interval(lower, higher)
850
+ @repaint_required = true
851
+ end
852
+
800
853
 
854
+ # ADD HERE
801
855
  end # class listb
802
856
 
803
857
 
@@ -111,8 +111,14 @@ module RubyCurses
111
111
  make_buttons ["&OK"]
112
112
  when "ok_cancel" #, "input", "list", "field_list"
113
113
  make_buttons %w[&OK &Cancel]
114
+ # experience 2009-02-22 12:52 trapping y and n - hopefully wont cause an edit problem
115
+ @form.bind_key(?o){ press(?\M-o) }
116
+ @form.bind_key(?c){ press(?\M-c) }
114
117
  when "yes_no"
115
118
  make_buttons %w[&Yes &No]
119
+ # experience 2009-02-22 12:52 trapping y and n - hopefully wont cause an edit problem
120
+ @form.bind_key(?y){ press(?\M-y) }
121
+ @form.bind_key(?n){ press(?\M-n) }
116
122
  when "yes_no_cancel"
117
123
  make_buttons ["&Yes", "&No", "&Cancel"]
118
124
  when "custom"
@@ -170,7 +176,6 @@ module RubyCurses
170
176
  return @selected_index
171
177
  end
172
178
  def press ch
173
- #$log.debug "message box handle_keys : #{ch}" if ch != -1
174
179
  case ch
175
180
  when -1
176
181
  return
@@ -183,12 +188,14 @@ module RubyCurses
183
188
  if field.respond_to? :fire
184
189
  field.fire
185
190
  end
186
- $log.debug "popup ENTER : #{@selected_index} "
187
- $log.debug "popup ENTER : #{field.name}" if !field.nil?
191
+ #$log.debug "popup ENTER : #{@selected_index} "
192
+ #$log.debug "popup ENTER : #{field.name}" if !field.nil?
188
193
  @stop = true
189
194
  return
190
195
  when 9
191
196
  @form.select_next_field
197
+ when 353
198
+ @form.select_prev_field
192
199
  else
193
200
  # fields must return unhandled else we will miss hotkeys.
194
201
  # On messageboxes, often if no edit field, then O and C are hot.
@@ -234,7 +241,7 @@ module RubyCurses
234
241
  # XXX this needs to go up and decide height of window
235
242
  if @message_height.nil?
236
243
  @message_height = (message.length/display_length)+1
237
- $log.debug " print_message: mh:#{@message_height}"
244
+ $log.debug " print_message: mh:#{@message_height}, ml: #{message.length}"
238
245
  end
239
246
  @message_height ||= 1
240
247
  width = @layout[:width]
@@ -251,6 +258,7 @@ module RubyCurses
251
258
  @message_col = (width-message.length)/2
252
259
  end
253
260
  @message_row = row
261
+ # FIXME : wont print if newline at end of message !!!
254
262
  #@window.printstring( row, @message_col , message, color=$reversecolor)
255
263
  # 2008-12-30 19:45 experimenting with label so we can get justify and wrapping.
256
264
  #@window.printstring( row, @message_col , message, color=$reversecolor)
@@ -264,6 +272,7 @@ module RubyCurses
264
272
  @message_col ||= 2
265
273
  r = @message_row + @message_height + 1
266
274
  c = @message_col
275
+ disp_len = @layout[:width]-8
267
276
  defaultvalue = @default_value || ""
268
277
  input_config = @config["input_config"] || {}
269
278
  case @type.to_s
@@ -272,7 +281,7 @@ module RubyCurses
272
281
  name "input"
273
282
  row r
274
283
  col c
275
- display_length 30
284
+ display_length disp_len
276
285
  set_buffer defaultvalue
277
286
  end
278
287
  when "list"
@@ -74,6 +74,9 @@ module RubyCurses
74
74
  include EventHandler
75
75
  dsl_accessor :row, :col
76
76
  dsl_accessor :height, :width
77
+ dsl_accessor :button_type # ok, ok_cancel, yes_no
78
+ dsl_accessor :buttons # used if type :custom
79
+ attr_reader :selected_index
77
80
  def initialize win, aconfig={}, &block
78
81
  @parent = win
79
82
  @tabs ||= []
@@ -161,6 +164,7 @@ module RubyCurses
161
164
  }
162
165
 
163
166
  end
167
+ create_buttons
164
168
  @form.repaint
165
169
  end
166
170
  def display_form form
@@ -183,7 +187,14 @@ module RubyCurses
183
187
  return form
184
188
  end
185
189
  def handle_keys
186
- while (( ch=@window.getchar()) != KEY_F1)
190
+ begin
191
+ while (( ch=@window.getchar()) != 999)
192
+ if ch == ?\C-q
193
+ @selected_index = -1 # this signifies cancel by ?C-q
194
+ @stop = true
195
+ return
196
+ end
197
+ return if @stop
187
198
  @current_form ||= @form
188
199
  ret = @current_form.handle_key(ch)
189
200
  case ret
@@ -220,15 +231,66 @@ module RubyCurses
220
231
  @form.repaint
221
232
  #return :UNHANDLED if ret == :UNHANDLED
222
233
  end
234
+ return if @stop
223
235
  @current_form.window.wrefresh
224
236
  @window.refresh
225
237
  end
226
- destroy
238
+ ensure
239
+ destroy
240
+ end
227
241
  end
228
242
  def destroy
229
243
  @window.destroy
230
244
  @forms.each { |f| w = f.window; w.destroy unless w.nil? }
231
245
  end
246
+ def create_buttons
247
+ case @button_type.to_s.downcase
248
+ when "ok"
249
+ make_buttons ["&OK"]
250
+ when "ok_cancel" #, "input", "list", "field_list"
251
+ make_buttons %w[&OK &Cancel]
252
+ when "yes_no"
253
+ make_buttons %w[&Yes &No]
254
+ when "yes_no_cancel"
255
+ make_buttons ["&Yes", "&No", "&Cancel"]
256
+ when "custom"
257
+ raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
258
+ make_buttons @buttons
259
+ else
260
+ $log.debug "No buttontype passed for creating tabbedpane. Using default (OK)"
261
+ make_buttons ["&OK"]
262
+ end
263
+ end
264
+ def make_buttons names
265
+ total = names.inject(0) {|total, item| total + item.length + 4}
266
+ bcol = center_column total
267
+
268
+ brow = @layout[:height]-2
269
+ button_ct=0
270
+ names.each_with_index do |bname, ix|
271
+ text = bname
272
+ #underline = @underlines[ix] if !@underlines.nil?
273
+
274
+ button = Button.new @form do
275
+ text text
276
+ name bname
277
+ row brow
278
+ col bcol
279
+ #underline underline
280
+ highlight_background $reversecolor
281
+ color $datacolor
282
+ bgcolor $datacolor
283
+ end
284
+ index = button_ct
285
+ button.command { |form| @selected_index = index; @stop = true; $log.debug "Pressed Button #{bname}";}
286
+ button_ct += 1
287
+ bcol += text.length+6
288
+ end
289
+ end
290
+ def center_column textlen
291
+ width = @layout[:width]
292
+ return (width-textlen)/2
293
+ end
232
294
 
233
295
  ##
234
296
  # nested class tab