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.
- checksums.yaml +7 -0
- data/.gitignore +45 -0
- data/CHANGES +52 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +24 -0
- data/Rakefile +2 -0
- data/canis.gemspec +25 -0
- data/examples/alpmenu.rb +46 -0
- data/examples/app.sample +19 -0
- data/examples/appemail.rb +191 -0
- data/examples/atree.rb +105 -0
- data/examples/bline.rb +181 -0
- data/examples/common/devel.rb +319 -0
- data/examples/common/file.rb +93 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +59 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +16 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +506 -0
- data/examples/dirtree.rb +177 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +212 -0
- data/examples/tasks.rb +179 -0
- data/examples/term2.rb +88 -0
- data/examples/testbuttons.rb +307 -0
- data/examples/testcombo.rb +102 -0
- data/examples/testdb.rb +182 -0
- data/examples/testfields.rb +208 -0
- data/examples/testflowlayout.rb +43 -0
- data/examples/testkeypress.rb +98 -0
- data/examples/testlistbox.rb +187 -0
- data/examples/testlistbox1.rb +199 -0
- data/examples/testmessagebox.rb +144 -0
- data/examples/testprogress.rb +116 -0
- data/examples/testree.rb +107 -0
- data/examples/testsplitlayout.rb +53 -0
- data/examples/testsplitlayout1.rb +49 -0
- data/examples/teststacklayout.rb +48 -0
- data/examples/testwsshortcuts.rb +68 -0
- data/examples/testwsshortcuts2.rb +129 -0
- data/lib/canis.rb +16 -0
- data/lib/canis/core/docs/index.txt +104 -0
- data/lib/canis/core/docs/list.txt +16 -0
- data/lib/canis/core/docs/style_help.yml +34 -0
- data/lib/canis/core/docs/tabbedpane.txt +15 -0
- data/lib/canis/core/docs/table.txt +31 -0
- data/lib/canis/core/docs/textpad.txt +48 -0
- data/lib/canis/core/docs/tree.txt +23 -0
- data/lib/canis/core/include/.DS_Store +0 -0
- data/lib/canis/core/include/action.rb +83 -0
- data/lib/canis/core/include/actionmanager.rb +49 -0
- data/lib/canis/core/include/appmethods.rb +179 -0
- data/lib/canis/core/include/bordertitle.rb +49 -0
- data/lib/canis/core/include/canisparser.rb +100 -0
- data/lib/canis/core/include/colorparser.rb +437 -0
- data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
- data/lib/canis/core/include/io.rb +320 -0
- data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
- data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
- data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
- data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
- data/lib/canis/core/include/listbindings.rb +89 -0
- data/lib/canis/core/include/listeditable.rb +319 -0
- data/lib/canis/core/include/listoperations.rb +61 -0
- data/lib/canis/core/include/listselectionmodel.rb +388 -0
- data/lib/canis/core/include/multibuffer.rb +173 -0
- data/lib/canis/core/include/ractionevent.rb +73 -0
- data/lib/canis/core/include/rchangeevent.rb +27 -0
- data/lib/canis/core/include/rhistory.rb +95 -0
- data/lib/canis/core/include/rinputdataevent.rb +47 -0
- data/lib/canis/core/include/textdocument.rb +111 -0
- data/lib/canis/core/include/vieditable.rb +175 -0
- data/lib/canis/core/include/widgetmenu.rb +66 -0
- data/lib/canis/core/system/colormap.rb +165 -0
- data/lib/canis/core/system/keydefs.rb +32 -0
- data/lib/canis/core/system/ncurses.rb +237 -0
- data/lib/canis/core/system/panel.rb +129 -0
- data/lib/canis/core/system/window.rb +1081 -0
- data/lib/canis/core/util/ansiparser.rb +119 -0
- data/lib/canis/core/util/app.rb +696 -0
- data/lib/canis/core/util/basestack.rb +412 -0
- data/lib/canis/core/util/defaultcolorparser.rb +84 -0
- data/lib/canis/core/util/extras/README +5 -0
- data/lib/canis/core/util/extras/bottomline.rb +1815 -0
- data/lib/canis/core/util/extras/padreader.rb +192 -0
- data/lib/canis/core/util/focusmanager.rb +31 -0
- data/lib/canis/core/util/helpmanager.rb +160 -0
- data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
- data/lib/canis/core/util/promptmenu.rb +235 -0
- data/lib/canis/core/util/rcommandwindow.rb +933 -0
- data/lib/canis/core/util/rdialogs.rb +520 -0
- data/lib/canis/core/util/textutils.rb +74 -0
- data/lib/canis/core/util/viewer.rb +238 -0
- data/lib/canis/core/util/widgetshortcuts.rb +508 -0
- data/lib/canis/core/widgets/applicationheader.rb +103 -0
- data/lib/canis/core/widgets/box.rb +58 -0
- data/lib/canis/core/widgets/divider.rb +310 -0
- data/lib/canis/core/widgets/extras/README.md +12 -0
- data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
- data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
- data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
- data/lib/canis/core/widgets/listbox.rb +326 -0
- data/lib/canis/core/widgets/listfooter.rb +86 -0
- data/lib/canis/core/widgets/rcombo.rb +210 -0
- data/lib/canis/core/widgets/rcontainer.rb +415 -0
- data/lib/canis/core/widgets/rlink.rb +30 -0
- data/lib/canis/core/widgets/rmenu.rb +970 -0
- data/lib/canis/core/widgets/rmenulink.rb +30 -0
- data/lib/canis/core/widgets/rmessagebox.rb +400 -0
- data/lib/canis/core/widgets/rprogress.rb +118 -0
- data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
- data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
- data/lib/canis/core/widgets/rwidget.rb +3634 -0
- data/lib/canis/core/widgets/scrollbar.rb +147 -0
- data/lib/canis/core/widgets/statusline.rb +113 -0
- data/lib/canis/core/widgets/table.rb +1072 -0
- data/lib/canis/core/widgets/tabular.rb +264 -0
- data/lib/canis/core/widgets/textpad.rb +1674 -0
- data/lib/canis/core/widgets/tree.rb +690 -0
- data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
- data/lib/canis/version.rb +3 -0
- metadata +229 -0
data/examples/dirtree.rb
ADDED
|
@@ -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
|
data/examples/tabular.rb
ADDED
|
@@ -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
|