rbcurse 0.1.3 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +126 -0
- data/Manifest.txt +53 -20
- data/README.markdown +423 -0
- data/Rakefile +3 -1
- data/examples/keytest.rb +177 -0
- data/examples/mpad2.rb +156 -0
- data/examples/newtesttabp.rb +121 -0
- data/examples/rfe.rb +48 -10
- data/examples/rfe_renderer.rb +4 -4
- data/examples/rvimsplit.rb +376 -0
- data/examples/sqlc.rb +97 -106
- data/examples/sqlm.rb +446 -0
- data/examples/test1.rb +4 -4
- data/examples/test2.rb +12 -12
- data/examples/testchars.rb +140 -0
- data/examples/testkeypress.rb +9 -4
- data/examples/testmulticomp.rb +72 -0
- data/examples/testscroller.rb +136 -0
- data/examples/testscrolllb.rb +86 -0
- data/examples/testscrollp.rb +87 -0
- data/examples/testscrollta.rb +80 -0
- data/examples/testscrolltable.rb +166 -0
- data/examples/testsplit.rb +87 -0
- data/examples/testsplit2.rb +123 -0
- data/examples/testsplit3.rb +215 -0
- data/examples/testsplit3_1.rb +244 -0
- data/examples/testsplit3a.rb +215 -0
- data/examples/testsplit3b.rb +237 -0
- data/examples/testsplitta.rb +148 -0
- data/examples/testsplittv.rb +142 -0
- data/examples/testsplittvv.rb +144 -0
- data/examples/testtable.rb +1 -1
- data/examples/testtabp.rb +3 -2
- data/examples/testtestw.rb +69 -0
- data/examples/testtodo.rb +5 -3
- data/examples/testtpane.rb +203 -0
- data/examples/testtpane2.rb +145 -0
- data/examples/testtpanetable.rb +199 -0
- data/examples/viewtodo.rb +5 -3
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/celleditor.rb +2 -2
- data/lib/rbcurse/colormap.rb +5 -5
- data/lib/rbcurse/defaultlistselectionmodel.rb +3 -3
- data/lib/rbcurse/io.rb +663 -0
- data/lib/rbcurse/listeditable.rb +306 -0
- data/lib/rbcurse/listkeys.rb +15 -15
- data/lib/rbcurse/listscrollable.rb +168 -27
- data/lib/rbcurse/mapper.rb +35 -13
- data/lib/rbcurse/rchangeevent.rb +28 -0
- data/lib/rbcurse/rform.rb +845 -0
- data/lib/rbcurse/rlistbox.rb +144 -34
- data/lib/rbcurse/rmessagebox.rb +10 -5
- data/lib/rbcurse/rmulticontainer.rb +325 -0
- data/lib/rbcurse/rmultitextview.rb +306 -0
- data/lib/rbcurse/rscrollform.rb +369 -0
- data/lib/rbcurse/rscrollpane.rb +511 -0
- data/lib/rbcurse/rsplitpane.rb +820 -0
- data/lib/rbcurse/rtabbedpane.rb +737 -109
- data/lib/rbcurse/rtabbedwindow.rb +326 -0
- data/lib/rbcurse/rtable.rb +220 -64
- data/lib/rbcurse/rtextarea.rb +340 -181
- data/lib/rbcurse/rtextview.rb +237 -101
- data/lib/rbcurse/rviewport.rb +203 -0
- data/lib/rbcurse/rwidget.rb +919 -95
- data/lib/rbcurse/scrollable.rb +7 -7
- data/lib/rbcurse/selectable.rb +4 -4
- data/lib/rbcurse/table/tablecellrenderer.rb +3 -0
- data/lib/rbcurse/undomanager.rb +181 -0
- data/lib/rbcurse/vieditable.rb +100 -0
- data/lib/ver/window.rb +471 -21
- metadata +66 -22
- data/README.txt +0 -312
- data/examples/testd.db +0 -0
- data/examples/todocsv.csv +0 -28
data/lib/rbcurse/rlistbox.rb
CHANGED
@@ -102,8 +102,6 @@ module RubyCurses
|
|
102
102
|
def delete obj
|
103
103
|
off0 = @list.index obj
|
104
104
|
return nil if off0.nil?
|
105
|
-
# 2009-11-04 11:33 next line corrected to delete_at
|
106
|
-
#ret=@list.delete off0
|
107
105
|
ret=@list.delete_at off0
|
108
106
|
lde = ListDataEvent.new(off0, off0, self, :INTERVAL_REMOVED)
|
109
107
|
fire_handler :LIST_DATA_EVENT, lde
|
@@ -207,7 +205,7 @@ module RubyCurses
|
|
207
205
|
instance_eval &block if block_given?
|
208
206
|
@list_config.each_pair { |k,v| instance_variable_set("@#{k}",v) }
|
209
207
|
@height ||= [@max_visible_items || 10, @list.length].min
|
210
|
-
|
208
|
+
$log.debug " POPUP XXX #{@max_visible_items} ll:#{@list.length} h:#{@height}"
|
211
209
|
# get widgets absolute coords
|
212
210
|
if !@relative_to.nil?
|
213
211
|
layout = @relative_to.form.window.layout
|
@@ -232,15 +230,9 @@ module RubyCurses
|
|
232
230
|
@window = VER::Window.new(@layout)
|
233
231
|
@form = RubyCurses::Form.new @window
|
234
232
|
@window.bkgd(Ncurses.COLOR_PAIR($reversecolor));
|
235
|
-
#@window.attron(Ncurses.COLOR_PAIR($reversecolor));
|
236
|
-
#@window.wclear
|
237
|
-
#@window.attroff(Ncurses.COLOR_PAIR($reversecolor));
|
238
233
|
@window.wrefresh
|
239
234
|
@panel = @window.panel # useless line ?
|
240
235
|
Ncurses::Panel.update_panels
|
241
|
-
# @message_row = @message_col = 2
|
242
|
-
# print_borders
|
243
|
-
# print_title
|
244
236
|
print_input # creates the listbox
|
245
237
|
@form.repaint
|
246
238
|
@window.wrefresh
|
@@ -322,8 +314,10 @@ module RubyCurses
|
|
322
314
|
def print_input
|
323
315
|
r = c = 0
|
324
316
|
width = @layout[:width]
|
317
|
+
#$log.debug " print_input POPUP ht:#{@height} lh:#{@layout[:height]} "
|
325
318
|
height = @layout[:height]
|
326
|
-
height = @height
|
319
|
+
#height = @height # 2010-01-06 12:52 why was this overriding previous line. its one less than layout
|
320
|
+
# i am now using layout height since it gives a closer size to whats asked for.
|
327
321
|
parent = @relative_to
|
328
322
|
defaultvalue = @default_value || ""
|
329
323
|
list = @list
|
@@ -345,7 +339,6 @@ module RubyCurses
|
|
345
339
|
default_values default_values
|
346
340
|
is_popup true
|
347
341
|
#add_observer parent
|
348
|
-
|
349
342
|
end
|
350
343
|
end
|
351
344
|
# may need to be upgraded to new one XXX FIXME
|
@@ -410,6 +403,7 @@ module RubyCurses
|
|
410
403
|
dsl_accessor :KEY_NEXT_SELECTION
|
411
404
|
dsl_accessor :KEY_PREV_SELECTION
|
412
405
|
dsl_accessor :valign # 2009-01-17 18:32
|
406
|
+
attr_accessor :one_key_selection # will pressing a single key select or not
|
413
407
|
|
414
408
|
def initialize form, config={}, &block
|
415
409
|
@focusable = true
|
@@ -425,8 +419,15 @@ module RubyCurses
|
|
425
419
|
@row_offset = @col_offset = 1
|
426
420
|
@content_rows = @list.length
|
427
421
|
@selection_mode ||= 'multiple'
|
428
|
-
@win = @form.window
|
429
|
-
|
422
|
+
@win = @graphic # 2010-01-04 12:36 BUFFERED replace form.window with graphic
|
423
|
+
# moving down to repaint so that scrollpane can set should_buffered
|
424
|
+
# added 2010-02-17 23:05 RFED16 so we don't need a form.
|
425
|
+
@win_left = 0
|
426
|
+
@win_top = 0
|
427
|
+
@multiplier = 0 # multiply motion commands
|
428
|
+
|
429
|
+
#x safe_create_buffer # 2010-01-04 12:36 BUFFERED moved here 2010-01-05 18:07
|
430
|
+
#x print_borders unless @win.nil? # in messagebox we don;t have window as yet!
|
430
431
|
# next 2 lines carry a redundancy
|
431
432
|
select_default_values
|
432
433
|
# when the combo box has a certain row in focus, the popup should have the same row in focus
|
@@ -449,6 +450,16 @@ module RubyCurses
|
|
449
450
|
@left_margin ||= @row_selected_symbol.length
|
450
451
|
end
|
451
452
|
@left_margin ||= 0
|
453
|
+
@one_key_selection ||= true
|
454
|
+
bind_key(?f){ ask_selection_for_char() }
|
455
|
+
bind_key(?\M-v){ @one_key_selection = false }
|
456
|
+
bind_key(?j){ next_row() }
|
457
|
+
bind_key(?k){ previous_row() }
|
458
|
+
bind_key(?G){ goto_bottom() }
|
459
|
+
bind_key([?g,?g]){ goto_top() }
|
460
|
+
bind_key(?/){ ask_search() }
|
461
|
+
bind_key(?n){ find_more() }
|
462
|
+
|
452
463
|
end
|
453
464
|
def install_bindings
|
454
465
|
|
@@ -470,7 +481,8 @@ module RubyCurses
|
|
470
481
|
end
|
471
482
|
# added 2009-01-07 13:05 so new scrollable can use
|
472
483
|
def scrollatrow
|
473
|
-
|
484
|
+
#@height - 2
|
485
|
+
@height - 3 # 2010-01-04 15:30 BUFFERED HEIGHT
|
474
486
|
end
|
475
487
|
def list alist=nil
|
476
488
|
return @list if alist.nil?
|
@@ -505,16 +517,22 @@ module RubyCurses
|
|
505
517
|
end
|
506
518
|
def print_borders
|
507
519
|
width = @width
|
508
|
-
height = @height
|
509
|
-
window = @
|
520
|
+
height = @height-1 # 2010-01-04 15:30 BUFFERED HEIGHT
|
521
|
+
window = @graphic # 2010-01-04 12:37 BUFFERED
|
510
522
|
startcol = @col
|
511
523
|
startrow = @row
|
512
524
|
@color_pair = get_color($datacolor)
|
525
|
+
#$log.debug "rlistb: window.print_border #{startrow}, #{startcol} , #{height} , #{width} , @color_pair, @attr "
|
513
526
|
window.print_border startrow, startcol, height, width, @color_pair, @attr
|
514
527
|
print_title
|
515
528
|
end
|
516
529
|
def print_title
|
517
|
-
printstring(@
|
530
|
+
#printstring(@graphic, @row, @col+(@width-@title.length)/2, @title, @color_pair, @title_attrib) unless @title.nil?
|
531
|
+
# 2010-01-04 15:53 BUFFERED
|
532
|
+
# I notice that the old version would print a title that was longer than width,
|
533
|
+
#+ but the new version won't print anything if it exceeds width.
|
534
|
+
# TODO check title.length and truncate if exceeds width
|
535
|
+
@graphic.printstring( @row, @col+(@width-@title.length)/2, @title, @color_pair, @title_attrib) unless @title.nil?
|
518
536
|
end
|
519
537
|
### START FOR scrollable ###
|
520
538
|
def get_content
|
@@ -522,7 +540,7 @@ module RubyCurses
|
|
522
540
|
@list_variable && @list_variable.value || @list
|
523
541
|
end
|
524
542
|
def get_window
|
525
|
-
@
|
543
|
+
@graphic # 2010-01-04 12:37 BUFFERED
|
526
544
|
end
|
527
545
|
### END FOR scrollable ###
|
528
546
|
# override widgets text
|
@@ -542,18 +560,18 @@ module RubyCurses
|
|
542
560
|
previous_row
|
543
561
|
when KEY_DOWN # show previous value
|
544
562
|
next_row
|
545
|
-
when @KEY_ROW_SELECTOR # 32
|
563
|
+
when @KEY_ROW_SELECTOR # 32
|
546
564
|
return if is_popup and @selection_mode == 'single' # not allowing select this way since there will be a difference
|
547
565
|
toggle_row_selection @current_index #, @current_index
|
548
566
|
@repaint_required = true
|
549
|
-
when @KEY_SCROLL_FORWARD # ?\C-n
|
567
|
+
when @KEY_SCROLL_FORWARD # ?\C-n
|
550
568
|
scroll_forward
|
551
|
-
when @KEY_SCROLL_BACKWARD # ?\C-p
|
569
|
+
when @KEY_SCROLL_BACKWARD # ?\C-p
|
552
570
|
scroll_backward
|
553
|
-
when @KEY_GOTO_TOP # 48, ?\C-[
|
571
|
+
when @KEY_GOTO_TOP # 48, ?\C-[
|
554
572
|
# please note that C-[ gives 27, same as esc so will respond after ages
|
555
573
|
goto_top
|
556
|
-
when @KEY_GOTO_BOTTOM # ?\C-]
|
574
|
+
when @KEY_GOTO_BOTTOM # ?\C-]
|
557
575
|
goto_bottom
|
558
576
|
when @KEY_NEXT_SELECTION # ?'
|
559
577
|
$log.debug "insdie next selection"
|
@@ -568,9 +586,10 @@ module RubyCurses
|
|
568
586
|
when @KEY_CLEAR_SELECTION
|
569
587
|
clear_selection #if @select_mode == 'multiple'
|
570
588
|
@repaint_required = true
|
571
|
-
when 27, ?\C-c
|
589
|
+
when 27, ?\C-c.getbyte(0)
|
572
590
|
editing_canceled @current_index if @cell_editing_allowed
|
573
591
|
cancel_block # block
|
592
|
+
@multiplier = 0
|
574
593
|
when @KEY_ASK_FIND_FORWARD
|
575
594
|
# ask_search_forward
|
576
595
|
when @KEY_ASK_FIND_BACKWARD
|
@@ -585,6 +604,13 @@ module RubyCurses
|
|
585
604
|
find_more
|
586
605
|
when @KEY_BLOCK_SELECTOR
|
587
606
|
mark_block #selection
|
607
|
+
when ?\C-u.getbyte(0)
|
608
|
+
# multiplier. Series is 4 16 64
|
609
|
+
@multiplier = (@multiplier == 0 ? 4 : @multiplier *= 4)
|
610
|
+
return 0
|
611
|
+
when ?\C-c.getbyte(0)
|
612
|
+
@multiplier = 0
|
613
|
+
return 0
|
588
614
|
else
|
589
615
|
# this has to be fixed, if compo does not handle key it has to continue into next part FIXME
|
590
616
|
ret = :UNHANDLED # changed on 2009-01-27 13:14 not going into unhandled, tab not released
|
@@ -599,15 +625,37 @@ module RubyCurses
|
|
599
625
|
end
|
600
626
|
end
|
601
627
|
if ret == :UNHANDLED
|
602
|
-
|
603
|
-
|
604
|
-
|
628
|
+
if @one_key_selection
|
629
|
+
case ch
|
630
|
+
when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0), ?0.getbyte(0)..?9.getbyte(0)
|
631
|
+
# simple motion, key press defines motion
|
632
|
+
ret = set_selection_for_char ch.chr
|
633
|
+
else
|
634
|
+
ret = process_key ch, self
|
635
|
+
@multiplier = 0
|
636
|
+
return :UNHANDLED if ret == :UNHANDLED
|
637
|
+
end
|
605
638
|
else
|
639
|
+
# no motion on single key, we can freak out like in vim, pref f <char> for set_selection
|
640
|
+
case ch
|
641
|
+
when ?0.getbyte(0)..?9.getbyte(0)
|
642
|
+
@multiplier *= 10 ; @multiplier += (ch-48)
|
643
|
+
return 0
|
644
|
+
end
|
606
645
|
ret = process_key ch, self
|
646
|
+
@multiplier = 0
|
607
647
|
return :UNHANDLED if ret == :UNHANDLED
|
608
648
|
end
|
609
649
|
end
|
610
650
|
end
|
651
|
+
@multiplier = 0
|
652
|
+
end
|
653
|
+
def ask_selection_for_char
|
654
|
+
ch = @graphic.getch
|
655
|
+
if ch < 0 || ch > 255
|
656
|
+
return :UNHANDLED
|
657
|
+
end
|
658
|
+
ret = set_selection_for_char ch.chr
|
611
659
|
end
|
612
660
|
def ask_search_forward
|
613
661
|
regex = get_string("Enter regex to search")
|
@@ -684,6 +732,12 @@ module RubyCurses
|
|
684
732
|
# unfortunately 2009-01-11 19:47 combo boxes editable allows changing value
|
685
733
|
editor.prepare_editor self, row, col, value
|
686
734
|
editor.component.curpos = 0 # reset it after search, if user scrols down
|
735
|
+
#editor.component.graphic = @graphic # 2010-01-05 00:36 TRYING OUT BUFFERED
|
736
|
+
## override is required if the listbox uses a buffer
|
737
|
+
if @should_create_buffer
|
738
|
+
$log.debug " overriding editors comp with GRAPHIC #{@graphic} "
|
739
|
+
editor.component.override_graphic(@graphic) # 2010-01-05 00:36 TRYING OUT BUFFERED
|
740
|
+
end
|
687
741
|
set_form_col 0 #@left_margin
|
688
742
|
|
689
743
|
# set original value so we can cancel
|
@@ -701,6 +755,7 @@ module RubyCurses
|
|
701
755
|
if @cell_editing_allowed
|
702
756
|
if !@cell_editor.nil?
|
703
757
|
# $log.debug " cell editor (leave) setting value row: #{arow} val: #{@cell_editor.getvalue}"
|
758
|
+
$log.debug " cell editor #{@cell_editor.component.form.window} (leave) setting value row: #{arow} val: #{@cell_editor.getvalue}"
|
704
759
|
@list[arow] = @cell_editor.getvalue #.dup 2009-01-10 21:42 boolean can't duplicate
|
705
760
|
else
|
706
761
|
$log.debug "CELL EDITOR WAS NIL, #{arow} "
|
@@ -744,7 +799,18 @@ module RubyCurses
|
|
744
799
|
# processing. also, it pans the data horizontally giving the renderer
|
745
800
|
# a section of it.
|
746
801
|
def repaint
|
802
|
+
safe_create_buffer # 2010-01-04 12:36 BUFFERED moved here 2010-01-05 18:07
|
747
803
|
return unless @repaint_required
|
804
|
+
# not sure where to put this, once for all or repeat 2010-02-17 23:07 RFED16
|
805
|
+
my_win = @form ? @form.window : @target_window
|
806
|
+
@graphic = my_win unless @graphic
|
807
|
+
#$log.warn "neither form not target window given!!! TV paint 368" unless my_win
|
808
|
+
raise " #{@name} neither form, nor target window given TV paint " unless my_win
|
809
|
+
raise " #{@name} NO GRAPHIC set as yet TV paint " unless @graphic
|
810
|
+
@win_left = my_win.left
|
811
|
+
@win_top = my_win.top
|
812
|
+
|
813
|
+
$log.debug " rlistbox repaint graphic #{@graphic} "
|
748
814
|
print_borders if @to_print_borders == 1 # do this once only, unless everything changes
|
749
815
|
rc = row_count
|
750
816
|
maxlen = @maxlen ||= @width-2
|
@@ -783,20 +849,20 @@ module RubyCurses
|
|
783
849
|
else
|
784
850
|
selection_symbol = @row_unselected_symbol
|
785
851
|
end
|
786
|
-
@
|
852
|
+
@graphic.printstring r+hh, c, selection_symbol, acolor,@attr
|
787
853
|
end
|
788
854
|
#renderer = get_default_cell_renderer_for_class content.class.to_s
|
789
855
|
renderer = cell_renderer()
|
790
856
|
#renderer.show_selector @show_selector
|
791
857
|
#renderer.row_selected_symbol @row_selected_symbol
|
792
858
|
#renderer.left_margin @left_margin
|
793
|
-
#renderer.repaint @
|
859
|
+
#renderer.repaint @graphic, r+hh, c+(colix*11), content, focussed, selected
|
794
860
|
## added crow on 2009-02-06 23:03
|
795
861
|
# since data is being truncated and renderer may need index
|
796
|
-
renderer.repaint @
|
862
|
+
renderer.repaint @graphic, r+hh, c+@left_margin, crow, content, focussed, selected
|
797
863
|
else
|
798
864
|
# clear rows
|
799
|
-
@
|
865
|
+
@graphic.printstring r+hh, c, " " * (@width-2), acolor,@attr
|
800
866
|
end
|
801
867
|
end
|
802
868
|
if @cell_editing_allowed
|
@@ -804,6 +870,8 @@ module RubyCurses
|
|
804
870
|
end
|
805
871
|
@table_changed = false
|
806
872
|
@repaint_required = false
|
873
|
+
@buffer_modified = true # required by form to call buffer_to_screen BUFFERED
|
874
|
+
buffer_to_window # RFED16 2010-02-17 23:16
|
807
875
|
end
|
808
876
|
def list_data_changed
|
809
877
|
if row_count == 0 # added on 2009-02-02 17:13 so cursor not hanging on last row which could be empty
|
@@ -813,9 +881,27 @@ module RubyCurses
|
|
813
881
|
end
|
814
882
|
@repaint_required = true
|
815
883
|
end
|
816
|
-
def set_form_col
|
817
|
-
|
818
|
-
|
884
|
+
def set_form_col col1=0
|
885
|
+
# TODO BUFFERED use setrowcol @form.row, col
|
886
|
+
# TODO BUFFERED use cols_panned
|
887
|
+
@cols_panned ||= 0 # RFED16 2010-02-17 23:40
|
888
|
+
# editable listboxes will involve changing cursor and the form issue
|
889
|
+
## added win_col on 2010-01-04 23:28 for embedded forms BUFFERED TRYING OUT
|
890
|
+
#win_col=@form.window.left
|
891
|
+
win_col = 0 # 2010-02-17 23:19 RFED16
|
892
|
+
#col = win_col + @orig_col + @col_offset + @curpos + @form.cols_panned
|
893
|
+
col2 = win_col + @col + @col_offset + col1 + @cols_panned + @left_margin
|
894
|
+
$log.debug " set_form_col in rlistbox #{@col}+ left_margin #{@left_margin} ( #{col2} ) "
|
895
|
+
#super col+@left_margin
|
896
|
+
#@form.setrowcol @form.row, col2 # added 2009-12-29 18:50 BUFFERED
|
897
|
+
setrowcol nil, col2 # 2010-02-17 23:19 RFED16
|
898
|
+
end
|
899
|
+
#def rowcol
|
900
|
+
## $log.debug "rlistbox rowcol : #{@row+@row_offset+@winrow}, #{@col+@col_offset}"
|
901
|
+
#win_col=@form.window.left
|
902
|
+
#col2 = win_col + @col + @col_offset + @form.cols_panned + @left_margin
|
903
|
+
#return @row+@row_offset, col2
|
904
|
+
#end
|
819
905
|
# experimental selection of multiple rows via block
|
820
906
|
# specify a block start and then a block end
|
821
907
|
# usage: bind mark_selection to a key. It works as a toggle.
|
@@ -851,7 +937,31 @@ module RubyCurses
|
|
851
937
|
add_row_selection_interval(lower, higher)
|
852
938
|
@repaint_required = true
|
853
939
|
end
|
940
|
+
# 2010-02-18 11:40
|
941
|
+
# TRYING OUT - canceling editing if resized otherwise drawing errors can occur
|
942
|
+
# the earlier painted edited comp in yellow keeps showing until a key is pressed
|
854
943
|
|
944
|
+
def set_buffering params
|
945
|
+
super
|
946
|
+
## Ensuring that changes to top get reflect in editing comp
|
947
|
+
#+ otherwise it raises an exception. Still the earlier cell_edit is being
|
948
|
+
#+ printed where it was , until a key is moved
|
949
|
+
# FIXME - do same for col
|
950
|
+
if @cell_editor
|
951
|
+
r,c = rowcol
|
952
|
+
if @cell_editor.component.row < @row_offset + @buffer_params[:screen_top]
|
953
|
+
@cell_editor.component.row = @row_offset + @buffer_params[:screen_top]
|
954
|
+
end
|
955
|
+
# TODO next block to be tested by placing a listbox in right split of vertical
|
956
|
+
if @cell_editor.component.col < @col_offset + @buffer_params[:screen_left]
|
957
|
+
@cell_editor.component.col = @col_offset + @buffer_params[:screen_left]
|
958
|
+
end
|
959
|
+
#editing_canceled @current_index if @cell_editing_allowed and @cell_editor
|
960
|
+
end
|
961
|
+
#set_form_row
|
962
|
+
@repaint_required = true
|
963
|
+
end
|
964
|
+
|
855
965
|
|
856
966
|
# ADD HERE
|
857
967
|
end # class listb
|
data/lib/rbcurse/rmessagebox.rb
CHANGED
@@ -112,13 +112,13 @@ module RubyCurses
|
|
112
112
|
when "ok_cancel" #, "input", "list", "field_list"
|
113
113
|
make_buttons %w[&OK &Cancel]
|
114
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) }
|
115
|
+
@form.bind_key(?o){ press(?\M-o) } # called method takes care of getbyte 1.9
|
116
|
+
@form.bind_key(?c){ press(?\M-c) } # called method takes care of getbyte 1.9
|
117
117
|
when "yes_no"
|
118
118
|
make_buttons %w[&Yes &No]
|
119
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) }
|
120
|
+
@form.bind_key(?y){ press(?\M-y) } # called method takes care of getbyte 1.9
|
121
|
+
@form.bind_key(?n){ press(?\M-n) } # called method takes care of getbyte 1.9
|
122
122
|
when "yes_no_cancel"
|
123
123
|
make_buttons ["&Yes", "&No", "&Cancel"]
|
124
124
|
when "custom"
|
@@ -176,10 +176,11 @@ module RubyCurses
|
|
176
176
|
return @selected_index
|
177
177
|
end
|
178
178
|
def press ch
|
179
|
+
ch = ch.getbyte(0) if ch.class==String ## 1.9
|
179
180
|
case ch
|
180
181
|
when -1
|
181
182
|
return
|
182
|
-
when KEY_F1, 27, ?\C-q
|
183
|
+
when KEY_F1, 27, ?\C-q.getbyte(0)
|
183
184
|
@selected_index = -1
|
184
185
|
@stop = true
|
185
186
|
return
|
@@ -238,6 +239,7 @@ module RubyCurses
|
|
238
239
|
def print_message message=@message, row=nil
|
239
240
|
@message_row = @message_col = 2
|
240
241
|
display_length = @layout[:width]-8
|
242
|
+
$log.debug " print_message: dl:#{display_length} "
|
241
243
|
# XXX this needs to go up and decide height of window
|
242
244
|
if @message_height.nil?
|
243
245
|
@message_height = (message.length/display_length)+1
|
@@ -258,10 +260,13 @@ module RubyCurses
|
|
258
260
|
@message_col = (width-message.length)/2
|
259
261
|
end
|
260
262
|
@message_row = row
|
263
|
+
# added 2009-11-05 14:53 to fix erasure of border
|
264
|
+
display_length -= @message_col
|
261
265
|
# FIXME : wont print if newline at end of message !!!
|
262
266
|
#@window.printstring( row, @message_col , message, color=$reversecolor)
|
263
267
|
# 2008-12-30 19:45 experimenting with label so we can get justify and wrapping.
|
264
268
|
#@window.printstring( row, @message_col , message, color=$reversecolor)
|
269
|
+
$log.debug " print_message: row #{row}, col #{@message_col} "
|
265
270
|
message_label = RubyCurses::Label.new @form, {'text' => message, "name"=>"message_label","row" => row, "col" => @message_col, "display_length" => display_length, "height" => @message_height, "attr"=>"reverse"}
|
266
271
|
|
267
272
|
end
|
@@ -0,0 +1,325 @@
|
|
1
|
+
=begin
|
2
|
+
* Name: MultiContainer
|
3
|
+
* Description View (cycle) multiple components in one container using a key or menu
|
4
|
+
* Author: rkumar (arunachalesha)
|
5
|
+
* file created 2010-03-15 10:40
|
6
|
+
--------
|
7
|
+
* License:
|
8
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
9
|
+
|
10
|
+
=end
|
11
|
+
require 'rubygems'
|
12
|
+
require 'ncurses'
|
13
|
+
require 'logger'
|
14
|
+
require 'rbcurse'
|
15
|
+
|
16
|
+
include Ncurses
|
17
|
+
include RubyCurses
|
18
|
+
module RubyCurses
|
19
|
+
extend self
|
20
|
+
|
21
|
+
##
|
22
|
+
# Extends TextView with ability to load more than one file or content
|
23
|
+
# and switch between files (buffers).
|
24
|
+
# NOTE: ideally, i should be able to dynamically add this functionality to either Textview
|
25
|
+
# or TextArea or even ListBox or Table someday. Should then be a Module rather than a class.
|
26
|
+
class MultiContainer < Widget
|
27
|
+
dsl_accessor :title
|
28
|
+
#include ListScrollable
|
29
|
+
|
30
|
+
def initialize form = nil, config={}, &block
|
31
|
+
@focusable = true
|
32
|
+
@row_offset = @col_offset = 1
|
33
|
+
super
|
34
|
+
@bmanager = BufferManager.new self
|
35
|
+
init_vars
|
36
|
+
|
37
|
+
end
|
38
|
+
def init_vars
|
39
|
+
super
|
40
|
+
bind_key(?\M-:, :buffer_menu)
|
41
|
+
# bind_key([?\C-x, ?f], :file_edit)
|
42
|
+
bind_key([?\C-x, ?k], :buffer_delete)
|
43
|
+
bind_key([?\C-x, ?\C-b], :buffers_list)
|
44
|
+
# easily cycle using p. n is used for next search.
|
45
|
+
#bind_key(?p, :buffer_previous)
|
46
|
+
@suppress_borders = false
|
47
|
+
@repaint_all = true
|
48
|
+
@name ||= "multicontainer"
|
49
|
+
end
|
50
|
+
## returns current buffer
|
51
|
+
# @return [RBuffer] current buffer
|
52
|
+
def current_buffer
|
53
|
+
@bmanager.current
|
54
|
+
end
|
55
|
+
##
|
56
|
+
# multi-container
|
57
|
+
def handle_key ch
|
58
|
+
$log.debug " MULTI handlekey #{ch}, #{@current_component} "
|
59
|
+
ret = :UNHANDLED
|
60
|
+
return :UNHANDLED unless @current_component
|
61
|
+
ret = @current_component.handle_key(ch)
|
62
|
+
$log.debug " MULTI = comp returned #{ret} "
|
63
|
+
if ret == :UNHANDLED
|
64
|
+
# check for bindings, these cannot override above keys since placed at end
|
65
|
+
begin
|
66
|
+
ret = process_key ch, self
|
67
|
+
$log.debug " MULTI = process_key returned #{ret} "
|
68
|
+
rescue => err
|
69
|
+
$error_message = err
|
70
|
+
@form.window.print_error_message
|
71
|
+
$log.error " Multicomponent process_key #{err} "
|
72
|
+
$log.debug(err.backtrace.join("\n"))
|
73
|
+
end
|
74
|
+
return :UNHANDLED if ret == :UNHANDLED
|
75
|
+
end
|
76
|
+
# check for any keys not handled and check our own ones
|
77
|
+
return ret #
|
78
|
+
end
|
79
|
+
def repaint
|
80
|
+
print_border if (@suppress_borders == false && @repaint_all) # do this once only, unless everything changes
|
81
|
+
return unless @current_component
|
82
|
+
$log.debug " MULTI REPAINT "
|
83
|
+
ret = @current_component.repaint
|
84
|
+
end
|
85
|
+
def print_border
|
86
|
+
$log.debug " #{@name} print_borders, #{@graphic.name} "
|
87
|
+
color = $datacolor
|
88
|
+
@graphic.print_border_only @row, @col, @height-1, @width, color #, Ncurses::A_REVERSE
|
89
|
+
print_title
|
90
|
+
end
|
91
|
+
def print_title
|
92
|
+
$log.debug " print_title #{@row}, #{@col}, #{@width} "
|
93
|
+
@graphic.printstring( @row, @col+(@width-@title.length)/2, @title, $datacolor, @title_attrib) unless @title.nil?
|
94
|
+
end
|
95
|
+
# this is just a test of the simple "most" menu
|
96
|
+
# can use this for next, prev, first, last, new, delete, overwrite etc
|
97
|
+
def buffer_menu
|
98
|
+
menu = PromptMenu.new self
|
99
|
+
menu.add(menu.create_mitem( 'l', "list buffers", "list buffers ", :buffers_list ))
|
100
|
+
item = menu.create_mitem( 'b', "Buffer Options", "Buffer Options" )
|
101
|
+
menu1 = PromptMenu.new( self, "Buffer Options")
|
102
|
+
menu1.add(menu1.create_mitem( 'n', "Next", "Switched to next buffer", :buffer_next ))
|
103
|
+
menu1.add(menu1.create_mitem( 'p', "Prev", "Switched to previous buffer", :buffer_previous ))
|
104
|
+
menu1.add(menu1.create_mitem( 'f', "First", "Switched to first buffer", :buffer_first ))
|
105
|
+
menu1.add(menu1.create_mitem( 'l', "Last", "Switched to last buffer", :buffer_last ))
|
106
|
+
menu1.add(menu1.create_mitem( 'd', "Delete", "Deleted buffer", :buffer_delete ))
|
107
|
+
item.action = menu1
|
108
|
+
menu.add(item)
|
109
|
+
# how do i know what's available. the application or window should know where to place
|
110
|
+
menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
|
111
|
+
end
|
112
|
+
|
113
|
+
#%w[next previous first last].each do |pos|
|
114
|
+
#eval(
|
115
|
+
#"def _buffer_#{pos}
|
116
|
+
#@current_buffer = @bmanager.#{pos}
|
117
|
+
#set_current_buffer
|
118
|
+
#end"
|
119
|
+
#)
|
120
|
+
#end
|
121
|
+
|
122
|
+
def buffer_next
|
123
|
+
perror "No other buffer" and return if @bmanager.size < 2
|
124
|
+
|
125
|
+
@current_buffer = @bmanager.next
|
126
|
+
set_current_buffer
|
127
|
+
end
|
128
|
+
def buffer_previous
|
129
|
+
perror "No other buffer" and return if @bmanager.size < 2
|
130
|
+
|
131
|
+
@current_buffer = @bmanager.previous
|
132
|
+
$log.debug " buffer_prev got #{@current_buffer} "
|
133
|
+
set_current_buffer
|
134
|
+
end
|
135
|
+
def buffer_first
|
136
|
+
@current_buffer = @bmanager.first
|
137
|
+
$log.debug " buffer_first got #{@current_buffer} "
|
138
|
+
set_current_buffer
|
139
|
+
end
|
140
|
+
def buffer_last
|
141
|
+
@current_buffer = @bmanager.last
|
142
|
+
$log.debug " buffer_last got #{@current_buffer} "
|
143
|
+
set_current_buffer
|
144
|
+
end
|
145
|
+
def buffer_delete
|
146
|
+
if @bmanager.size > 1
|
147
|
+
@bmanager.delete_at
|
148
|
+
@current_buffer = @bmanager.previous
|
149
|
+
set_current_buffer
|
150
|
+
else
|
151
|
+
perror "Only one buffer. Cannot delete."
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
#%w[next previous first last].each do |pos|
|
156
|
+
#eval(
|
157
|
+
#"def _buffer_#{pos}
|
158
|
+
#@current_buffer = @bmanager.#{pos}
|
159
|
+
#set_current_buffer
|
160
|
+
#end"
|
161
|
+
#)
|
162
|
+
#end
|
163
|
+
|
164
|
+
def buffer_next
|
165
|
+
perror "No other buffer" and return if @bmanager.size < 2
|
166
|
+
|
167
|
+
@current_buffer = @bmanager.next
|
168
|
+
set_current_buffer
|
169
|
+
end
|
170
|
+
def buffer_previous
|
171
|
+
perror "No other buffer" and return if @bmanager.size < 2
|
172
|
+
|
173
|
+
@current_buffer = @bmanager.previous
|
174
|
+
$log.debug " buffer_prev got #{@current_buffer} "
|
175
|
+
set_current_buffer
|
176
|
+
end
|
177
|
+
def buffer_first
|
178
|
+
@current_buffer = @bmanager.first
|
179
|
+
$log.debug " buffer_first got #{@current_buffer} "
|
180
|
+
set_current_buffer
|
181
|
+
end
|
182
|
+
def buffer_last
|
183
|
+
@current_buffer = @bmanager.last
|
184
|
+
$log.debug " buffer_last got #{@current_buffer} "
|
185
|
+
set_current_buffer
|
186
|
+
end
|
187
|
+
def buffer_delete
|
188
|
+
if @bmanager.size > 1
|
189
|
+
@bmanager.delete_at
|
190
|
+
@current_buffer = @bmanager.previous
|
191
|
+
set_current_buffer
|
192
|
+
else
|
193
|
+
perror "Only one buffer. Cannot delete."
|
194
|
+
end
|
195
|
+
end
|
196
|
+
def buffer_at index
|
197
|
+
@current_buffer = @bmanager.element_at index
|
198
|
+
$log.debug " buffer_last got #{@current_buffer} "
|
199
|
+
set_current_buffer
|
200
|
+
end
|
201
|
+
##
|
202
|
+
# Add a component with a title
|
203
|
+
# @param [Widget] component
|
204
|
+
# @param [String] title
|
205
|
+
def add component, title
|
206
|
+
component.row = @row+@row_offset+1
|
207
|
+
component.col = @col+@col_offset+1
|
208
|
+
component.width = @width-2
|
209
|
+
component.height = @height-2
|
210
|
+
component.form = @form
|
211
|
+
component.override_graphic(@graphic)
|
212
|
+
@current_buffer = @bmanager.add component, title
|
213
|
+
set_current_buffer
|
214
|
+
$log.debug " ADD got cb : #{@current_buffer} "
|
215
|
+
end
|
216
|
+
def set_current_buffer
|
217
|
+
@current_component = @current_buffer.component
|
218
|
+
@current_title = @current_buffer.title
|
219
|
+
@current_component.repaint_all true
|
220
|
+
end
|
221
|
+
def perror errmess=$error_message
|
222
|
+
@form.window.print_error_message errmess
|
223
|
+
end
|
224
|
+
def buffers_list
|
225
|
+
$log.debug " TODO buffers_list: #{@bmanager.size} "
|
226
|
+
menu = PromptMenu.new self
|
227
|
+
@bmanager.each_with_index{ |b, ix|
|
228
|
+
aproc = Proc.new { buffer_at(ix) }
|
229
|
+
name = b.title
|
230
|
+
num = ix + 1
|
231
|
+
menu.add(menu.create_mitem( num.to_s, name, "Switched to buffer #{ix}", aproc ))
|
232
|
+
}
|
233
|
+
menu.display @form.window, $error_message_row, $error_message_col, $datacolor
|
234
|
+
end
|
235
|
+
# required otherwise some components may not get correct cursor position on entry
|
236
|
+
# e.g. table
|
237
|
+
def on_enter
|
238
|
+
set_form_row
|
239
|
+
end
|
240
|
+
def set_form_row
|
241
|
+
if !@current_component.nil?
|
242
|
+
$log.debug " #{@name} set_form_row calling sfr for #{@current_component.name} "
|
243
|
+
@current_component.set_form_row
|
244
|
+
@current_component.set_form_col
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end # class multitextview
|
248
|
+
##
|
249
|
+
# Handles multiple buffers, navigation, maintenance etc
|
250
|
+
# Instantiated at startup of MultiTextView
|
251
|
+
#
|
252
|
+
class BufferManager
|
253
|
+
include Enumerable
|
254
|
+
def initialize source
|
255
|
+
@source = source
|
256
|
+
@buffers = [] # contains RBuffer
|
257
|
+
@counter = 0
|
258
|
+
# for each buffer i need to store data, current_index (row), curpos (col offset) and title (filename).
|
259
|
+
end
|
260
|
+
def element_at index
|
261
|
+
@buffers[index]
|
262
|
+
end
|
263
|
+
def each
|
264
|
+
@buffers.each {|k| yield(k)}
|
265
|
+
end
|
266
|
+
|
267
|
+
##
|
268
|
+
# @return [RBuffer] current buffer/file
|
269
|
+
##
|
270
|
+
def current
|
271
|
+
@buffers[@counter]
|
272
|
+
end
|
273
|
+
##
|
274
|
+
# Would have liked to just return next buffer and not get lost in details of caller
|
275
|
+
#
|
276
|
+
# @return [RBuffer] next buffer/file
|
277
|
+
##
|
278
|
+
def next
|
279
|
+
@counter += 1
|
280
|
+
@counter = 0 if @counter >= @buffers.size
|
281
|
+
@buffers[@counter]
|
282
|
+
end
|
283
|
+
##
|
284
|
+
# @return [RBuffer] previous buffer/file
|
285
|
+
##
|
286
|
+
def previous
|
287
|
+
$log.debug " previous bs: #{@buffers.size}, #{@counter} "
|
288
|
+
@counter -= 1
|
289
|
+
return last() if @counter < 0
|
290
|
+
$log.debug " previous ctr #{@counter} "
|
291
|
+
@buffers[@counter]
|
292
|
+
end
|
293
|
+
def first
|
294
|
+
@counter = 0
|
295
|
+
@buffers[@counter]
|
296
|
+
end
|
297
|
+
def last
|
298
|
+
@counter = @buffers.size - 1
|
299
|
+
@buffers[@counter]
|
300
|
+
end
|
301
|
+
##
|
302
|
+
def delete_at index=@counter
|
303
|
+
@buffers.delete_at index
|
304
|
+
end
|
305
|
+
def delete_by_name name
|
306
|
+
@buffers.delete_if {|b| b.filename == name }
|
307
|
+
end
|
308
|
+
def insert component, position, title=nil
|
309
|
+
anew = RComponents.new(component, title)
|
310
|
+
@buffers.insert position, anew
|
311
|
+
@counter = position
|
312
|
+
return anew
|
313
|
+
end
|
314
|
+
def add component, title=nil
|
315
|
+
$log.debug " ADD H: #{component.height} C: #{component.width} "
|
316
|
+
insert component, @buffers.size, title
|
317
|
+
end
|
318
|
+
def size
|
319
|
+
@buffers.size
|
320
|
+
end
|
321
|
+
alias :count :size
|
322
|
+
end
|
323
|
+
RComponents = Struct.new(:component, :title)
|
324
|
+
|
325
|
+
end # modul
|