canis 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
@@ -0,0 +1,177 @@
1
+ require 'canis/core/util/app'
2
+ require 'fileutils'
3
+ require 'canis/core/widgets/tree/treemodel'
4
+ #require 'canis/common/file'
5
+ require './common/file'
6
+ require './common/devel'
7
+
8
+ def _directories wd
9
+ $log.debug " directories got :#{wd}: "
10
+ wd ||= ""
11
+ return [] if wd == ""
12
+ d = Dir.new(wd)
13
+ ent = d.entries.reject{|e| !File.directory? File.join(wd,e)}
14
+ $log.debug " directories got XXX: #{ent} "
15
+ ent.delete(".");ent.delete("..")
16
+ return ent
17
+ end
18
+ $log = create_logger "canis14.log"
19
+ App.new do
20
+ def help_text
21
+ <<-eos
22
+
23
+ =========================================================================
24
+ ## Basic Usage
25
+
26
+ ### Left Window
27
+
28
+ <ENTER> expand/collapse directories
29
+ v select and list a directory in other window
30
+
31
+ See also [tree]
32
+
33
+ ### Right Window
34
+
35
+ <ENTER> enter a directory
36
+ <ENTER> open a file in 'EDITOR'
37
+ v page a file using 'PAGER'
38
+
39
+ See also [list]
40
+
41
+ [index]
42
+ eos
43
+ end
44
+ # print the dir list on the right listbox upon pressing ENTER or row_selector (v)
45
+ # separated here so it can be called from two places.
46
+ def lister node
47
+ path = File.join(*node.user_object_path)
48
+ populate path
49
+ end
50
+
51
+ def populate path
52
+ ll = @form.by_name["ll"]
53
+ return unless ll
54
+ if File.exists? path
55
+ files = Dir.new(path).entries
56
+ files.delete(".")
57
+ #files = file_listing path, :mode => :LONG
58
+ ll.clear_selection
59
+ ll.list files
60
+ ll.title path
61
+ #TODO show all details in filelist
62
+ @current_path = path
63
+ return path
64
+ end
65
+ end
66
+ header = app_header "canis #{Canis::VERSION}", :text_center => "Dorado", :text_right =>"Directory Lister" , :color => :white, :bgcolor => 242 #, :attr => Ncurses::A_BLINK
67
+ message "Press Enter to expand/collapse, v to view in lister. <F1> Help"
68
+ @form.help_manager.help_text = help_text()
69
+
70
+ pwd = Dir.getwd
71
+ entries = _directories pwd
72
+ patharray = pwd.split("/")
73
+ # we have an array of path, to add recursively, one below the other
74
+ nodes = []
75
+ nodes << TreeNode.new(patharray.shift)
76
+ patharray.each do |e|
77
+ nodes << nodes.last.add(e)
78
+ end
79
+ last = nodes.last
80
+ nodes.last.add entries
81
+ model = DefaultTreeModel.new nodes.first
82
+ model.root_visible = false
83
+
84
+
85
+
86
+ ht = FFI::NCurses.LINES - 2
87
+ borderattrib = :normal
88
+ flow :margin_top => 1, :margin_left => 0, :width => :expand, :height => ht do
89
+ @t = tree :data => model, :width_pc => 30, :border_attrib => borderattrib
90
+ rend = @t.renderer # just test method out.
91
+ rend.row_selected_attr = BOLD
92
+ @t.bind :TREE_WILL_EXPAND_EVENT do |node|
93
+ path = File.join(*node.user_object_path)
94
+ dirs = _directories path
95
+ ch = node.children
96
+ ch.each do |e|
97
+ o = e.user_object
98
+ if dirs.include? o
99
+ dirs.delete o
100
+ else
101
+ # delete this child since its no longer present TODO
102
+ end
103
+ end
104
+ #message " #{node} will expand: #{path}, #{dirs} "
105
+ node.add dirs
106
+ lister node
107
+ end
108
+ @t.bind :TREE_WILL_COLLAPSE_EVENT do |node|
109
+ # FIXME do if ony not already showing on other side
110
+ lister node
111
+ end
112
+ @t.bind :TREE_SELECTION_EVENT do |ev|
113
+ if ev.state == :SELECTED
114
+ node = ev.node
115
+ lister node
116
+ end
117
+ end # select
118
+ #$def_bg_color = :blue
119
+ @form.bgcolor = :blue
120
+ @t.expand_node last #
121
+ @t.mark_parents_expanded last # make parents visible
122
+ @l = listbox :width_pc => 70, :border_attrib => borderattrib, :selection_mode => :single, :name => 'll',
123
+ :left_margin => 1
124
+ @l.renderer directory_renderer(@l)
125
+ @l.renderer().row_focussed_attr = REVERSE
126
+
127
+ @l.bind :LIST_SELECTION_EVENT do |ev|
128
+ message ev.source.current_value #selected_value
129
+ # FIXME if ".." then remove basename
130
+ e = ev.source.current_value
131
+ if e == ".."
132
+ _f = File.dirname(@current_path)
133
+ else
134
+ _f = File.join(@current_path, e)
135
+ end
136
+ file_page _f if ev.type == :INSERT
137
+ #TODO when selects drill down
138
+ #TODO when selecting, sync tree with this
139
+ end
140
+ # on pressing enter, we edit the file using vi or EDITOR
141
+ @l.bind :PRESS do |ev|
142
+ # FIXME if ".." then remove basename
143
+ e = ev.source.current_value
144
+ if e == ".."
145
+ _f = File.dirname(@current_path)
146
+ else
147
+ _f = File.join(@current_path, e)
148
+ end
149
+ #_f = File.join(@current_path, ev.source.current_value)
150
+ if File.directory? _f
151
+ populate _f
152
+ else
153
+ file_edit _f if File.exists? _f
154
+ end
155
+ end
156
+ @form.bind_key([?\\, ?l, ?1]){
157
+ ll = @form.by_name["ll"]
158
+ ll.renderer.formatter = proc do | fname, stat, prefix|
159
+ "%s%-40s | %10d | %s " % [prefix, fname, stat.size, stat.mtime.strftime("%Y-%m-%d")]
160
+ end
161
+ # why is repaint all not enough ? is repaint not being called ?
162
+ ll.repaint_all
163
+ #ll.render_all
164
+ ll.repaint
165
+ #ll.fire_dimension_changed
166
+ }
167
+ @form.bind_key([?\\, ?l, ?2]){
168
+ ll = @form.by_name["ll"]
169
+ ll.renderer.formatter = nil
170
+ #ll.fire_dimension_changed
171
+ ll.repaint_all
172
+ #ll.render_all
173
+ ll.repaint
174
+ }
175
+ end
176
+ status_line :row => FFI::NCurses.LINES - 1
177
+ end # app
@@ -0,0 +1,100 @@
1
+ # this is a test program, tests out tabbed panes. type F1 to exit
2
+ #
3
+ require 'logger'
4
+ require 'canis'
5
+ require 'canis/core/widgets/rtabbedpane'
6
+ require 'canis/core/widgets/rcontainer'
7
+ require 'canis/core/widgets/rcombo'
8
+ require 'canis/core/widgets/rtabbedwindow'
9
+
10
+ include Canis
11
+ class SetupTabbedPane
12
+ def run
13
+ $config_hash ||= Variable.new Hash.new
14
+ #configvar.update_command(){ |v| $config_hash[v.source()] = v.value }
15
+
16
+ r = Container.new nil, :suppress_borders => true
17
+ l1 = Label.new nil, :name => "profile", :attr => 'bold', :text => "Profile"
18
+ f1 = LabeledField.new nil, :name => "name", :maxlen => 20, :width => 20, :bgcolor => :white,
19
+ :color => :black, :text => "abc", :label => ' Name: '
20
+ f2 = LabeledField.new nil, :name => "email", :width => 20, :bgcolor => :white,
21
+ :color => :blue, :text => "me@google.com", :label => 'Email: '
22
+ f3 = RadioButton.new nil, :variable => $config_hash, :text => "red", :value => "RED", :color => :red
23
+ f4 = RadioButton.new nil, :variable => $config_hash, :text => "blue", :value => "BLUE", :color => :blue
24
+ f5 = RadioButton.new nil, :variable => $config_hash, :text => "green", :value => "GREEN", :color => :green
25
+ r.add(l1,f1)
26
+ r.add(f2)
27
+ r.add(f3,f4,f5)
28
+
29
+ tp = TabbedWindow.new :row => 3, :col => 7, :width => 60, :height => 20 do
30
+ title "User Setup"
31
+ button_type :ok_apply_cancel
32
+ tab "&Profile" do
33
+ item LabeledField.new nil, :row => 2, :col => 2, :text => "enter your name", :label => ' Name: '
34
+ item LabeledField.new nil, :row => 3, :col => 2, :text => "enter your email", :label => 'Email: '
35
+ end
36
+ tab "&Settings" do
37
+ item Label.new nil, :text => "Text", :row => 1, :col => 2, :attr => 'bold'
38
+ item CheckBox.new nil, :row => 2, :col => 2, :text => "Antialias text"
39
+ item CheckBox.new nil, :row => 3, :col => 2, :text => "Use bold fonts"
40
+ item CheckBox.new nil, :row => 4, :col => 2, :text => "Allow blinking text"
41
+ item CheckBox.new nil, :row => 5, :col => 2, :text => "Display ANSI Colors"
42
+ item Label.new nil, :text => "Cursor", :row => 7, :col => 2, :attr => 'bold'
43
+ $config_hash.set_value Variable.new, :cursor
44
+ item RadioButton.new nil, :row => 8, :col => 2, :text => "Block", :value => "block", :variable => $config_hash[:cursor]
45
+ item RadioButton.new nil, :row => 9, :col => 2, :text => "Blink", :value => "blink", :variable => $config_hash[:cursor]
46
+ item RadioButton.new nil, :row => 10, :col => 2, :text => "Underline", :value => "underline", :variable => $config_hash[:cursor]
47
+ end
48
+ tab "&Term" do
49
+
50
+ item Label.new nil, :text => "Arrow Key in Combos", :row => 2, :col => 2, :attr => 'bold'
51
+ x = Variable.new
52
+ $config_hash.set_value x, :term
53
+ item RadioButton.new nil, :row => 3, :col => 2, :text => "ignore", :value => "ignore", :variable => $config_hash[:term]
54
+ item RadioButton.new nil, :row => 4, :col => 2, :text => "popup", :value => "popup", :variable => $config_hash[:term]
55
+ item RadioButton.new nil, :row => 5, :col => 2, :text => "next", :value => "next", :variable => $config_hash[:term]
56
+ cb = ComboBox.new nil, :row => 7, :col => 2, :width => 20,
57
+ :list => %w[xterm xterm-color xterm-256color screen vt100 vt102],
58
+ :label => "Declare terminal as: "
59
+ #radio.update_command() {|rb| ENV['TERM']=rb.value }
60
+ item cb
61
+ x.update_command do |rb|
62
+ cb.arrow_key_policy=rb.value.to_sym
63
+ end
64
+
65
+ end
66
+ tab "Conta&iner" do
67
+ item r
68
+ end
69
+ # tell tabbedpane what to do if a button is pressed (ok/apply/cancel)
70
+ command do |eve|
71
+ alert "user pressed button index:#{eve.event} , Name: #{eve.action_command}, Tab: #{eve.source.current_tab} "
72
+ case eve.event
73
+ when 0,2 # ok cancel
74
+ throw :close, eve.event
75
+ when 1 # apply
76
+ end
77
+ end
78
+ end
79
+ tp.run
80
+ end
81
+
82
+ end
83
+ if $0 == __FILE__
84
+ # Initialize curses
85
+ begin
86
+ # XXX update with new color and kb
87
+ Canis::start_ncurses # this is initializing colors via ColorMap.setup
88
+ $log = Logger.new((File.join(ENV["LOGDIR"] || "./" ,"canis14.log")))
89
+ $log.level = Logger::DEBUG
90
+ tp = SetupTabbedPane.new()
91
+ buttonindex = tp.run
92
+ rescue => ex
93
+ ensure
94
+ Canis::stop_ncurses
95
+ p ex if ex
96
+ p(ex.backtrace.join("\n")) if ex
97
+ $log.debug( ex) if ex
98
+ $log.debug(ex.backtrace.join("\n")) if ex
99
+ end
100
+ end
@@ -0,0 +1,92 @@
1
+ # this is a test program, tests out tabbed panes. type F1 to exit
2
+ #
3
+ require 'logger'
4
+ require 'canis'
5
+ #require 'canis/core/widgets/newtabbedpane'
6
+ require 'canis/core/widgets/rtabbedpane'
7
+ require 'canis/core/widgets/rcontainer' # tempo FIXME remove this since we arent using afterfixing rtabbedp
8
+
9
+ class TestTabbedPane
10
+ def initialize
11
+ acolor = $reversecolor
12
+ #$config_hash ||= {}
13
+ end
14
+ def run
15
+ $config_hash ||= Variable.new Hash.new
16
+ #configvar.update_command(){ |v| $config_hash[v.source()] = v.value }
17
+ @window = Canis::Window.root_window
18
+ @form = Form.new @window
19
+ r = 1; c = 30;
20
+ tp = Canis::TabbedPane.new @form, :height => 12, :width => 50,
21
+ :row => 13, :col => 10 do
22
+ button_type :ok
23
+ end
24
+ tp.add_tab "&Language" do
25
+ _r = 2
26
+ colors = [:red, :green, :cyan]
27
+ %w[ ruby jruby macruby].each_with_index { |e, i|
28
+ item RadioButton.new nil,
29
+ :variable => $config_hash,
30
+ :name => "radio1",
31
+ :text => e,
32
+ :value => e,
33
+ :color => colors[i],
34
+ :row => _r+i,
35
+ :col => 5
36
+ }
37
+ end
38
+ tp.add_tab "&Settings" do
39
+ r = 2
40
+ butts = [ "Use &HTTP/1.0", "Use &frames", "&Use SSL" ]
41
+ bcodes = %w[ HTTP, FRAMES, SSL ]
42
+ butts.each_with_index do |t, i|
43
+ item Canis::CheckBox.new nil,
44
+ :text => butts[i],
45
+ :variable => $config_hash,
46
+ :name => bcodes[i],
47
+ :row => r+i,
48
+ :col => 5
49
+ end
50
+ end
51
+ tp.add_tab "&Editors" do
52
+ butts = %w[ &Vim E&macs &Jed &Other ]
53
+ bcodes = %w[ VIM EMACS JED OTHER]
54
+ row = 2
55
+ butts.each_with_index do |name, i|
56
+ item Canis::CheckBox.new nil ,
57
+ :text => name,
58
+ :variable => $config_hash,
59
+ :name => bcodes[i],
60
+ :row => row+i,
61
+ :col => 5
62
+ end
63
+ end
64
+ help = "q to quit. <TAB> through tabs, Space or Enter to select Tab."
65
+ Canis::Label.new @form, {:text => help, :row => 1, :col => 2, :color => :yellow}
66
+ @form.repaint
67
+ @window.wrefresh
68
+ Ncurses::Panel.update_panels
69
+ while((ch = @window.getchar()) != ?q.getbyte(0) )
70
+ @form.handle_key(ch)
71
+ @window.wrefresh
72
+ end
73
+ end
74
+ end
75
+ if $0 == __FILE__
76
+ # Initialize curses
77
+ begin
78
+ # XXX update with new color and kb
79
+ Canis::start_ncurses # this is initializing colors via ColorMap.setup
80
+ $log = Logger.new("canis14.log")
81
+ $log.level = Logger::DEBUG
82
+ n = TestTabbedPane.new
83
+ n.run
84
+ rescue => ex
85
+ ensure
86
+ Canis::stop_ncurses
87
+ p ex if ex
88
+ p(ex.backtrace.join("\n")) if ex
89
+ $log.debug( ex) if ex
90
+ $log.debug(ex.backtrace.join("\n")) if ex
91
+ end
92
+ end
@@ -0,0 +1,212 @@
1
+ require 'canis/core/util/app'
2
+ require 'canis/core/widgets/listfooter'
3
+ require 'canis/core/util/promptmenu'
4
+
5
+ App.new do
6
+ # TODO: combine this with widget menu
7
+ def app_menu
8
+ menu = PromptMenu.new self do
9
+ item :e, :edit
10
+ item :o, :open_new
11
+ item :d, :delete_row
12
+ item :u, :undo_delete
13
+ #item :y, :yank
14
+ #item :p, :paste
15
+ item :/, :search
16
+ item :w, :write
17
+ end
18
+ menu.display_new :title => "Menu"
19
+ end
20
+ # to execute when app_menu is invoked
21
+ # very tricky , this depends on the keys that have been mapped
22
+ # Here we are pushing the mapped key to trigger a method.
23
+ # FIXME NOTE these have stopped working since I think i now clear keys
24
+ # after a key is processed, so unget will not work.
25
+ # Use +handle_key+ instead of +ungetch+, although that won't work if multiple
26
+ # keys involved.
27
+ def execute_this *cmd
28
+ cmd = cmd[0][0] # extract first letter of command
29
+ cmdi = cmd.getbyte(0)
30
+ tw = @form.by_name["tab"]
31
+ case cmd
32
+ when 'e','o','p'
33
+ #@window.ungetch cmdi
34
+ tw.handle_key cmdi
35
+ when 'd'
36
+ tw.delete_row
37
+ when 'y','d'
38
+ # won't work FIXME
39
+ tw.handle_key cmdi
40
+ #tw.handle_key cmdi
41
+ @window.ungetch cmdi
42
+ #@window.ungetch cmdi
43
+ when 'u'
44
+ tw.undo_delete
45
+ #tw.handle_key cmd.upcase.getbyte(0)
46
+ #@window.ungetch cmd.upcase.getbyte(0)
47
+ when 's'
48
+ tw.handle_key ?\/.getbyte(0)
49
+ #@window.ungetch ?\/.getbyte(0)
50
+ when 'w'
51
+ # this depends too much on mappings which can change
52
+ #@window.ungetch ?\C-s.getbyte(0)
53
+ tw = @form.by_name["tab"]
54
+ tw.save_as(nil)
55
+ end
56
+ end
57
+ def help_text
58
+ <<-eos
59
+ Help for Tables
60
+ ---------------
61
+
62
+ Keys that can be used on header
63
+
64
+ <ENTER> - sort given field (press on header)
65
+
66
+ Keys that can be used on data rows
67
+
68
+ <v> - select a row
69
+ <V> - range select
70
+ <u> - unselect all (conflicts with vim keys!!)
71
+ <a> - select all
72
+ <*> - invert selection
73
+
74
+ </> - <slash> for searching,
75
+ <n> to continue searching
76
+
77
+ Keys specific to this example
78
+
79
+ <e> - edit current row
80
+ <dd> - delete current row or <num> rows
81
+ <o> - insert a row after current one
82
+ <U> - undo delete
83
+
84
+ Motion keys
85
+
86
+ Usual for [[list]] and [[textpad]] such as :
87
+ j, k, h, l
88
+ w and b for (next/prev) column
89
+ C-d and C-b
90
+ gg and G
91
+
92
+ [[table]] | [[index]]
93
+ eos
94
+ end
95
+ def edit_row tw
96
+ row = tw.current_value
97
+ h = tw.columns
98
+ ret = _edit h, row, " Edit "
99
+ if ret
100
+ tw[tw.current_index] = row
101
+ end
102
+ end
103
+ def insert_row tw
104
+ h = tw.columns
105
+ row = []
106
+ h.each { |e| row << "" }
107
+ ret = _edit h, row, "Insert"
108
+ loc = tw.current_index
109
+ # don't insert above header
110
+ loc = 1 if loc == 0
111
+ if ret
112
+ tw.insert loc, row
113
+ end
114
+ end
115
+
116
+ # making a generic edit messagebox - quick dirty
117
+ def _edit h, row, title
118
+ _l = longest_in_list h
119
+ _w = _l.size
120
+ config = { :width => 70, :title => title }
121
+ bw = get_color $datacolor, :black, :white
122
+ mb = MessageBox.new config do
123
+ h.each_with_index { |f, i|
124
+ add LabeledField.new :label => "%*s:" % [_w, f], :text => row[i].chomp, :name => i.to_s,
125
+ :bgcolor => :cyan,
126
+ :width => 50,
127
+ :label_color_pair => bw
128
+ }
129
+ button_type :ok_cancel
130
+ end
131
+ index = mb.run
132
+ return nil if index != 0
133
+ h.each_with_index { |e, i|
134
+ f = mb.widget(i.to_s)
135
+ row[i] = f.text
136
+ }
137
+ row
138
+ end
139
+ # delete current row
140
+ # ideally one should include listeditable to get events also
141
+ def delete_row tw=nil
142
+ tw ||= @form.by_name["tab"]
143
+ @undo_buffer = tw.current_value
144
+ tw.delete_at tw.current_index
145
+ end
146
+ # very minimal undo, just for a demo
147
+ # Keeps pasting undo buffer back. @see listeditable.rb
148
+ def undo_delete tw=nil
149
+ return unless @undo_buffer
150
+ tw ||= @form.by_name["tab"]
151
+ tw.insert tw.current_index, @undo_buffer
152
+ end
153
+ def resize
154
+ tab = @form.by_name["tab"]
155
+ cols = Ncurses.COLS
156
+ rows = Ncurses.LINES
157
+ tab.width_pc ||= (1.0*tab.width / $orig_cols)
158
+ tab.height_pc ||= (1.0*tab.height / $orig_rows)
159
+ tab.height = (tab.height_pc * rows).floor
160
+ tab.width = (tab.width_pc * cols).floor
161
+ end
162
+
163
+ =begin
164
+
165
+ lf = Canis::ListFooter.new :attrib => BOLD
166
+ lf.command(lf){ |comp, lf|
167
+ f = lf[0]
168
+ if comp.current_index == 0
169
+ f.attrib = REVERSE
170
+ " Header "
171
+ else
172
+ f.attrib = BOLD
173
+ "#{comp.current_index} of #{comp.size} "
174
+ end
175
+ }
176
+ lf.command_right(){ |comp|
177
+ " [#{comp.size} tasks]"
178
+ }
179
+ =end
180
+ header = app_header "canis #{Canis::VERSION}", :text_center => "Table Demo", :text_right =>": menu",
181
+ :color => :black, :bgcolor => :green #, :attr => :bold
182
+ message "Press F10 to exit, F1 for help, : for menu"
183
+ @form.help_manager.help_text = help_text()
184
+ $orig_cols = Ncurses.COLS
185
+ $orig_rows = Ncurses.LINES
186
+
187
+ h = %w[ Id Title Priority Status]
188
+ file = "data/table.txt"
189
+
190
+ flow :margin_top => 1, :height => FFI::NCurses.LINES-2 do
191
+ tw = table :print_footer => true, :name => "tab"
192
+ tw.filename(file, :delimiter => '|', :columns => h)
193
+ #tw.columns h
194
+ #tw.text arr
195
+ tw.column_align 0, :right
196
+ tw.model_row 1
197
+ #tw.list_footer lf
198
+ tw.estimate_column_widths
199
+ #tw.selection_mode :single
200
+ # set_content goes to textpads text which overwrites @list
201
+ #tw.set_content arr
202
+ tw.bind_key([?d,?d], 'delete row') { delete_row tw }
203
+ tw.bind_key(?U, 'undo delete') { undo_delete tw }
204
+ tw.bind_key(?e, 'edit row') { edit_row tw }
205
+ tw.bind_key(?o, 'insert row') { insert_row tw }
206
+ tw.create_default_sorter
207
+
208
+ end # stack
209
+ status_line :row => FFI::NCurses.LINES-1
210
+ @form.bind_key(?:, 'menu') { app_menu }
211
+ @form.bind(:RESIZE) { resize }
212
+ end # app