canis 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,7 +7,7 @@
7
7
  # Author: jkepler http://github.com/mare-imbrium/canis/
8
8
  # Date: 07.11.11 - 13:17
9
9
  # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
10
- # Last update: 2014-05-19 12:56
10
+ # Last update: 2014-09-01 11:47
11
11
  # ----------------------------------------------------------------------------- #
12
12
  # == TODO
13
13
  # - perhaps we can compile the regexp once and reuse
@@ -30,8 +30,12 @@ module Canis
30
30
  # 187compat 2013-03-20 - 19:33 not working in 187 so added ,1 in some cases for string
31
31
  def parse_format s # yields attribs or text
32
32
  ## set default colors
33
- color = :white
34
- bgcolor = :black
33
+ # 2014-09-01 - 11:46 setting default fg and bg is wrong, it should either set the
34
+ # objects default (which we do not know in case of statusline, or maybe remain nil)
35
+ color = $def_fg_color
36
+ bgcolor = $def_bg_color
37
+ color = nil
38
+ bgcolor = nil
35
39
  attrib = FFI::NCurses::A_NORMAL
36
40
  text = ""
37
41
 
@@ -60,6 +60,23 @@ def textdialog mess, config={}
60
60
  tv.unbind_key(KEY_ENTER)
61
61
  tp.run
62
62
  end
63
+
64
+ # Used to popup and view a hash in a dialog. User may press ENTER or o to expand nodes
65
+ # and other keys such as "x" to close nodes.
66
+ def treedialog hash, config={}
67
+ config[:title] ||= "Alert"
68
+ tp = MessageBox.new config do
69
+ button_type :ok
70
+ tree hash
71
+ end
72
+ # Not having as default means i can only press SPACE and that is confusing since we are used to pressing
73
+ # ENTER on textdialog
74
+ #tp.default_button = 10 # i don't want a default since ENTER is trapped by tree
75
+ #tv = tp.form.by_name["message_label"]
76
+ # 2014-04-15 so that ENTER can hit okay without tabbing to button. FIX IN RBC
77
+ #tv.unbind_key(KEY_ENTER)
78
+ tp.run
79
+ end
63
80
  #
64
81
  # This uses the new messagebox 2011-11-19 v 1.5.0
65
82
  # NOTE: The earlier get_string had only an OK button, this seems to have a CANCEL
@@ -68,6 +85,7 @@ end
68
85
  # @yield [Field] field created by messagebox
69
86
  def get_string label, config={} # yield Field
70
87
  config[:title] ||= "Entry"
88
+ config[:title_color] ||= $reversecolor
71
89
  label_config = config[:label_config] || {}
72
90
  label_config[:row] ||= 2
73
91
  label_config[:col] ||= 2
@@ -76,7 +94,9 @@ def get_string label, config={} # yield Field
76
94
  field_config = config[:field_config] || {}
77
95
  field_config[:row] ||= 3
78
96
  field_config[:col] ||= 2
79
- field_config[:attr] = :reverse
97
+ #field_config[:attr] = :reverse
98
+ field_config[:color] ||= :black
99
+ field_config[:bgcolor] ||= :cyan
80
100
  field_config[:maxlen] ||= config[:maxlen]
81
101
  field_config[:default] ||= config[:default]
82
102
  field_config[:default] = field_config[:default].chomp if field_config[:default]
@@ -119,6 +139,69 @@ def get_string label, config={} # yield Field
119
139
  return nil
120
140
  end
121
141
  end
142
+ # @param [String] a label such as "Enter name:"
143
+ # @return [Array] value entered by user, nil if cancel pressed
144
+ # @yield [textarea] field created by messagebox
145
+ def get_text label, config={} # yield TextArea
146
+ config[:title] ||= "Entry"
147
+ config[:title_color] ||= $reversecolor
148
+ label_config = config[:label_config] || {}
149
+ label_config[:row] ||= 1
150
+ label_config[:col] ||= 2
151
+ label_config[:text] = label
152
+
153
+ # I am not changing the name from field to text in case user wishes to swtch between the two
154
+ field_config = config[:field_config] || {}
155
+ field_config[:row] ||= 2
156
+ field_config[:col] ||= 2
157
+ #field_config[:attr] = :reverse
158
+ field_config[:color] ||= :black
159
+ field_config[:bgcolor] ||= :cyan
160
+ #field_config[:maxlen] ||= config[:maxlen]
161
+ #field_config[:text] ||= config[:default]
162
+ #field_config[:default] = field_config[:default].chomp if field_config[:default]
163
+ field_config[:name] = :name
164
+ #field_config[:width] ||= 50 # i want it to extend since i don't know the actual width
165
+ #field_config[:width] ||= 50 # i want it to extend since i don't know the actual width
166
+
167
+ defwid = config[:default].nil? ? 30 : config[:default].size + 13
168
+ #w = [label.size + 8, defwid, field_config[:width]+13 ].max
169
+ #config[:width] ||= w
170
+ w = config[:width] = Ncurses.COLS - 5
171
+ h = config[:height] = Ncurses.LINES - 5
172
+ row = ((FFI::NCurses.LINES-h)/2).floor
173
+ col = ((FFI::NCurses.COLS-w)/2).floor
174
+ config[:row] = row
175
+ config[:col] = col
176
+ field_config[:width] ||= w - 7
177
+ field_config[:height] ||= h - 6
178
+ field_config[:suppress_borders] = true
179
+ ## added history 2013-03-06 - 14:25 : we could keep history based on prompt
180
+ $get_string_history ||= []
181
+ #$log.debug "XXX: FIELD SIZE #{w} "
182
+ #$log.debug "XXX: FIELD CONFIG #{field_config} "
183
+ tp = MessageBox.new config do
184
+ button_type :ok_cancel
185
+ default_button 0
186
+ item Label.new nil, label_config
187
+ fld = TextArea.new nil, field_config
188
+ item fld
189
+ ## added field history 2013-03-06 - 14:24
190
+ end
191
+ # added yield to override settings
192
+ yield tp.form.by_name[:name] if block_given?
193
+ index = tp.run
194
+ if index == 0 # OK
195
+ ## added field history 2013-03-06 - 14:24
196
+ t = tp.form.by_name[:name].text
197
+ #$get_string_history << t if t && !$get_string_history.include?(t)
198
+ return t
199
+ else # CANCEL
200
+ # Should i use nil or blank. I am currently opting for nil, as this may imply to caller
201
+ # that user does not wish to override whatever value is being prompted for.
202
+ return nil
203
+ end
204
+ end
122
205
  # new version using new messagebox
123
206
  # @param [String] question
124
207
  # @return [Boolean] true or false
@@ -195,6 +278,7 @@ def _print_message type, text, aconfig={}, &block #:nodoc:
195
278
  color = aconfig[:color]
196
279
  bgcolor = aconfig[:bgcolor]
197
280
  ewin = _create_footer_window #*@layout
281
+ ewin.name = "WINDOW::_print_message"
198
282
  r = 0; c = 1;
199
283
  case type
200
284
  when :error
@@ -246,6 +330,7 @@ def rb_confirm text, aconfig={}, &block
246
330
  text = text.to_s
247
331
  end
248
332
  ewin = _create_footer_window
333
+ ewin.name = "WINDOW::rb_confirm"
249
334
  r = 0; c = 1;
250
335
  #aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
251
336
  # changed on 2011-12-6
@@ -361,6 +446,7 @@ end # }}}
361
446
  # TODO FIXME block got ignored
362
447
  def status_window aconfig={}, &block
363
448
  sw = StatusWindow.new aconfig
449
+ sw.win.name = "WINDOW::status_window"
364
450
  return sw unless block_given?
365
451
  begin
366
452
  yield sw
@@ -377,6 +463,7 @@ def progress_dialog aconfig={}, &block
377
463
  aconfig[:row_offset] ||= 4
378
464
  aconfig[:col_offset] ||= 5
379
465
  window = status_window aconfig
466
+ window.win.name = "WINDOW::progress_dialog"
380
467
  height = 10; width = 60
381
468
  window.win.print_border_mb 1,2, height, width, $normalcolor, FFI::NCurses::A_REVERSE
382
469
  return window unless block_given?
@@ -410,20 +497,24 @@ def popuplist list, config={}, &block
410
497
  col += layout[:left]
411
498
  end
412
499
  config.delete :relative_to
413
- width = config[:width] || longest_in_list(list)+2 # borders take 2
500
+ extra = 2 # trying to space the popup slightly, too narrow
501
+ width = config[:width] || longest_in_list(list)+4 # borders take 2
414
502
  if config[:title]
415
- width = config[:title].size + 2 if width < config[:title].size
503
+ width = config[:title].size + 4 if width < config[:title].size + 4
416
504
  end
417
505
  height = config[:height]
418
506
  height ||= [max_visible_items || 10+2, list.length+2].min
419
507
  #layout(1+height, width+4, row, col)
420
508
  layout = { :height => 0+height, :width => 0+width, :top => row, :left => col }
421
509
  window = Canis::Window.new(layout)
510
+ window.name = "WINDOW:popuplist"
511
+ window.wbkgd(Ncurses.COLOR_PAIR($reversecolor));
422
512
  form = Canis::Form.new window
423
513
 
514
+ less = 0 # earlier 0
424
515
  listconfig = config[:listconfig] || {}
425
516
  listconfig[:list] = list
426
- listconfig[:width] = width
517
+ listconfig[:width] = width - less
427
518
  listconfig[:height] = height
428
519
  listconfig[:selection_mode] ||= :single
429
520
  listconfig.merge!(config)
@@ -436,7 +527,6 @@ def popuplist list, config={}, &block
436
527
  # events such as ENTER_ROW, LEAVE_ROW or LIST_SELECTION_EVENT or PRESS
437
528
  # 2011-11-11
438
529
  #yield lb if block_given? # No it won't work since this returns
439
- window.bkgd(Ncurses.COLOR_PAIR($reversecolor));
440
530
  window.wrefresh
441
531
  Ncurses::Panel.update_panels
442
532
  form.repaint
@@ -503,6 +593,236 @@ def display_app_help form=@form
503
593
  raise "Form needed by display_app_help. Use form.help_manager instead"
504
594
  end
505
595
  end
596
+
597
+ ## this is a quick dirty menu/popup menu thing, hopnig to replace the complex menubar with something simpler.
598
+ # However, the cursor visually is confusing. since the display takes over the cursor visually. When we display on the right
599
+ # it looks as tho the right menu is active. When we actually move into it with RIGHT, it looks like the left on is active.
600
+ # OKAY, we temporarily fixed that by not opening it until you actually press RIGHT
601
+ # FIXME : there is the issue of when one level is destroyed then the main one has a blank. all need to be
602
+ # repainted.
603
+ # FIXME : when diong a LEFT, cursor shows at last row of previous , we need a curpos or setrow for that lb
604
+ def popupmenu hash, config={}, &block
605
+ if hash.is_a? Hash
606
+ list = hash.keys
607
+ else
608
+ list = hash
609
+ end
610
+ raise ArgumentError, "Nil list received by popuplist" unless list
611
+ #require 'canis/core/widgets/rlist'
612
+
613
+ max_visible_items = config[:max_visible_items]
614
+ # FIXME have to ensure that row and col don't exceed FFI::NCurses.LINES and cols that is the window
615
+ # should not FINISH outside or padrefresh will fail.
616
+ row = config[:row] || 5
617
+ col = config[:col] || 5
618
+ relative_to = config[:relative_to]
619
+ if relative_to
620
+ layout = relative_to.form.window.layout
621
+ row += layout[:top]
622
+ col += layout[:left]
623
+ end
624
+ config.delete :relative_to
625
+ extra = 2 # trying to space the popup slightly, too narrow
626
+ width = config[:width] || longest_in_list(list)+4 # borders take 2
627
+ if config[:title]
628
+ width = config[:title].size + 4 if width < config[:title].size + 4
629
+ end
630
+ height = config[:height]
631
+ height ||= [max_visible_items || 10+2, list.length+2].min
632
+ #layout(1+height, width+4, row, col)
633
+ layout = { :height => 0+height, :width => 0+width, :top => row, :left => col }
634
+ window = Canis::Window.new(layout)
635
+ window.name = "WINDOW:popuplist"
636
+ window.wbkgd(Ncurses.COLOR_PAIR($reversecolor));
637
+ form = Canis::Form.new window
638
+
639
+ right_actions = config[:right_actions] || {}
640
+ config.delete(:right_actions)
641
+ less = 0 # earlier 0
642
+ listconfig = config[:listconfig] || {}
643
+ listconfig[:list] = list
644
+ listconfig[:width] = width - less
645
+ listconfig[:height] = height
646
+ listconfig[:selection_mode] ||= :single
647
+ listconfig.merge!(config)
648
+ listconfig.delete(:row);
649
+ listconfig.delete(:col);
650
+ # trying to pass populists block to listbox
651
+ lb = Canis::Listbox.new form, listconfig, &block
652
+ #lb.should_show_focus = true
653
+ #$row_focussed_attr = REVERSE
654
+
655
+
656
+ # added next line so caller can configure listbox with
657
+ # events such as ENTER_ROW, LEAVE_ROW or LIST_SELECTION_EVENT or PRESS
658
+ # 2011-11-11
659
+ #yield lb if block_given? # No it won't work since this returns
660
+ window.wrefresh
661
+ Ncurses::Panel.update_panels
662
+ form.repaint
663
+ window.wrefresh
664
+ display_on_enter = false
665
+ begin
666
+ windows = []
667
+ lists = []
668
+ hashes = []
669
+ choices = []
670
+ unentered_window = nil
671
+ _list = nil
672
+ while((ch = window.getchar()) != 999 )
673
+ case ch
674
+ when -1
675
+ next
676
+ when ?\C-q.getbyte(0)
677
+ break
678
+ else
679
+ lb.handle_key ch
680
+ lb.form.repaint
681
+ if ch == Ncurses::KEY_DOWN or ch == Ncurses::KEY_UP
682
+ if unentered_window
683
+ unentered_window.destroy
684
+ unentered_window = nil
685
+ end
686
+ # we need to update hash as we go along and back it up.
687
+ if display_on_enter
688
+ # removed since cursor goes in
689
+ end
690
+ elsif ch == Ncurses::KEY_RIGHT
691
+ if hash.is_a? Hash
692
+ val = hash[lb.current_value]
693
+ if val.is_a? Hash or val.is_a? Array
694
+ unentered_hash = val
695
+ choices << lb.current_value
696
+ unentered_window, _list = display_submenu val, :row => lb.current_index, :col => lb.width, :relative_to => lb,
697
+ :bgcolor => :cyan
698
+ end
699
+ else
700
+ x = right_actions[lb.current_value]
701
+ val = nil
702
+ if x.respond_to? :call
703
+ val = x.call
704
+ elsif x.is_a? Symbol
705
+ val = send(x)
706
+ end
707
+ if val
708
+ choices << lb.current_value
709
+ unentered_hash = val
710
+ unentered_window, _list = display_submenu val, :row => lb.current_index, :col => lb.width, :relative_to => lb,
711
+ :bgcolor => :cyan
712
+ end
713
+
714
+ end
715
+ # move into unentered
716
+ if unentered_window
717
+ lists << lb
718
+ hashes << hash
719
+ hash = unentered_hash
720
+ lb = _list
721
+ windows << unentered_window
722
+ unentered_window = nil
723
+ _list = nil
724
+ end
725
+ elsif ch == Ncurses::KEY_LEFT
726
+ if unentered_window
727
+ unentered_window.destroy
728
+ unentered_window = nil
729
+ end
730
+ # close current window
731
+ curr = nil
732
+ curr = windows.pop unless windows.empty?
733
+ curr.destroy if curr
734
+ lb = lists.pop unless lists.empty?
735
+ hash = hashes.pop unless hashes.empty?
736
+ choices.pop unless choices.empty?
737
+ unless windows.empty?
738
+ #form = windows.last
739
+ #lb - lists.pop
740
+ end
741
+ end
742
+ if ch == 13 || ch == 10
743
+ val = lb.current_value
744
+ if hash.is_a? Hash
745
+ val = hash[val]
746
+ if val.is_a? Symbol
747
+ #alert "got #{val}"
748
+ #return val
749
+ choices << val
750
+ return choices
751
+ end
752
+ else
753
+ #alert "got value #{val}"
754
+ #return val
755
+ choices << val
756
+ return choices
757
+ end
758
+ break
759
+ end
760
+ end
761
+ end
762
+ ensure
763
+ window.destroy if window
764
+ windows.each do |w| w.destroy if w ; end
765
+ end
766
+ return nil
767
+ end
768
+ def display_submenu hash, config={}, &block
769
+ raise ArgumentError, "Nil list / hash received by popuplist" unless hash
770
+ if hash.is_a? Hash
771
+ list = hash.keys
772
+ else
773
+ list = hash
774
+ end
775
+ raise ArgumentError, "Nil list received by popuplist" unless list
776
+
777
+ max_visible_items = config[:max_visible_items]
778
+ # FIXME have to ensure that row and col don't exceed FFI::NCurses.LINES and cols that is the window
779
+ # should not FINISH outside or padrefresh will fail.
780
+ row = config[:row] || 1
781
+ col = config[:col] || 0
782
+ relative_to = config[:relative_to]
783
+ if relative_to
784
+ layout = relative_to.form.window.layout
785
+ row += layout[:top]
786
+ col += layout[:left]
787
+ end
788
+ config.delete :relative_to
789
+ extra = 2 # trying to space the popup slightly, too narrow
790
+ width = config[:width] || longest_in_list(list)+4 # borders take 2
791
+ if config[:title]
792
+ width = config[:title].size + 4 if width < config[:title].size + 4
793
+ end
794
+ height = config[:height]
795
+ height ||= [max_visible_items || 10+2, list.length+2].min
796
+ #layout(1+height, width+4, row, col)
797
+ layout = { :height => 0+height, :width => 0+width, :top => row, :left => col }
798
+ window = Canis::Window.new(layout)
799
+ window.name = "WINDOW:popuplist"
800
+ window.wbkgd(Ncurses.COLOR_PAIR($reversecolor));
801
+ form = Canis::Form.new window
802
+
803
+ less = 0 # earlier 0
804
+ listconfig = config[:listconfig] || {}
805
+ listconfig[:list] = list
806
+ listconfig[:width] = width - less
807
+ listconfig[:height] = height
808
+ listconfig[:selection_mode] ||= :single
809
+ listconfig.merge!(config)
810
+ listconfig.delete(:row);
811
+ listconfig.delete(:col);
812
+ # trying to pass populists block to listbox
813
+ lb = Canis::Listbox.new form, listconfig, &block
814
+
815
+
816
+ # added next line so caller can configure listbox with
817
+ # events such as ENTER_ROW, LEAVE_ROW or LIST_SELECTION_EVENT or PRESS
818
+ # 2011-11-11
819
+ #yield lb if block_given? # No it won't work since this returns
820
+ window.wrefresh
821
+ Ncurses::Panel.update_panels
822
+ form.repaint
823
+ window.wrefresh
824
+ return window, lb
825
+ end
506
826
  #
507
827
  =begin
508
828
  http://www.kammerl.de/ascii/AsciiSignature.php
@@ -64,7 +64,7 @@ module Canis
64
64
 
65
65
  v_window = Canis::Window.new(layout)
66
66
  v_form = Canis::Form.new v_window
67
- v_window.name = "Viewer"
67
+ v_window.name = "WINDOW::Viewer"
68
68
  if wbg
69
69
  v_window.wbkgd(Ncurses.COLOR_PAIR(wbg)); # does not work on xterm-256color
70
70
  end
@@ -4,7 +4,7 @@
4
4
  # Also, stacks and flows objects
5
5
  # Author: jkepler http://github.com/mare-imbrium/canis/
6
6
  # Date: 05.11.11 - 15:13
7
- # Last update: 2014-07-10 00:40
7
+ # Last update: 2014-08-29 16:16
8
8
  #
9
9
  # I hope this slowly does not become an unmaintainable maze like vimsplit
10
10
  #
@@ -26,8 +26,6 @@
26
26
  # what is the real purpose of the shortcuts, is it to avoid putting nil
27
27
  # for form there if not required.
28
28
  # Or is it positioning, such as in a stack. or just a method ?
29
- #require 'canis/core/widgets/rlist'
30
- ## trying out new list based on textpad 2014-04-07 - 00:02 CANIS
31
29
  module Canis
32
30
  module WidgetShortcuts
33
31
  class Ws
@@ -366,6 +364,8 @@ module Canis
366
364
  end
367
365
  # make it as simple as possible, don't try to be intelligent or
368
366
  # clever, put as much on the user
367
+ #
368
+ # shortcut for a stack.
369
369
  def stack config={}, &block
370
370
  s = WsStack.new config
371
371
  @_ws_active ||= []