rbcurse 0.1.3 → 1.1.1
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.
- 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
|