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
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#**************************************************************
|
|
2
|
+
# Author: jkepler (ABCD)
|
|
3
|
+
# Date: 2010-03-11 22:18
|
|
4
|
+
# Provides the caller ability to do some edit operations
|
|
5
|
+
# on list widgets using either keys (vim largely)
|
|
6
|
+
# or a menu. made originally for textview and multitextview
|
|
7
|
+
#
|
|
8
|
+
#**************************************************************
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
require 'canis/core/include/listeditable'
|
|
12
|
+
module Canis
|
|
13
|
+
module ViEditable
|
|
14
|
+
include ListEditable
|
|
15
|
+
|
|
16
|
+
def vieditable_init
|
|
17
|
+
$log.debug " inside vieditable_init "
|
|
18
|
+
@editable = true
|
|
19
|
+
bind_key( ?C, :edit_line)
|
|
20
|
+
#bind_key( ?o, :insert_line)
|
|
21
|
+
#bind_key( ?O) { insert_line(@current_index-1) }
|
|
22
|
+
bind_key( ?o) { insert_line(@current_index+1) }
|
|
23
|
+
bind_key( ?O) { insert_line(@current_index) }
|
|
24
|
+
bind_key( ?D, :delete_eol)
|
|
25
|
+
bind_key( [?d, ?$], :delete_eol)
|
|
26
|
+
bind_key( [?d, ?d] , :delete_line )
|
|
27
|
+
bind_key( [?d, ?w], :delete_word )
|
|
28
|
+
bind_key( [?d, ?t], :delete_till )
|
|
29
|
+
bind_key( [?d, ?f], :delete_forward )
|
|
30
|
+
bind_key( ?\C-_ ) { @undo_handler.undo if @undo_handler }
|
|
31
|
+
bind_key( ?u ) { @undo_handler.undo if @undo_handler }
|
|
32
|
+
bind_key( ?\C-r ) { @undo_handler.redo if @undo_handler }
|
|
33
|
+
bind_key( ?x, :delete_curr_char )
|
|
34
|
+
bind_key( ?X, :delete_prev_char )
|
|
35
|
+
bind_key( [?y, ?y] , :kill_ring_save )
|
|
36
|
+
bind_key( ?p, :yank ) # paste after this line
|
|
37
|
+
bind_key( ?P ) { yank(@current_index - 1) } # should be before this line
|
|
38
|
+
bind_key(?w, :forward_word)
|
|
39
|
+
bind_key(?f, :forward_char)
|
|
40
|
+
bind_key(?\M-y, :yank_pop)
|
|
41
|
+
bind_key(?\M-w, :kill_ring_save)
|
|
42
|
+
@_events.push :CHANGE # thru vieditable
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
##
|
|
46
|
+
# Separate mappings for listboxes.
|
|
47
|
+
# Some methods don;'t make sense for listboxes and are crashing
|
|
48
|
+
# since not present for them. f was being overwritten, too.
|
|
49
|
+
# Sorry for duplication, need to clean this somehow.
|
|
50
|
+
def vieditable_init_listbox
|
|
51
|
+
$log.debug " inside vieditable_init_listbox "
|
|
52
|
+
@editable = true
|
|
53
|
+
bind_key( ?C, :edit_line)
|
|
54
|
+
bind_key( ?o) { insert_line(@current_index+1) }
|
|
55
|
+
bind_key( ?O) { insert_line(@current_index) }
|
|
56
|
+
bind_key( [?d, ?d] , :delete_line )
|
|
57
|
+
bind_key( ?\C-_ ) { @undo_handler.undo if @undo_handler }
|
|
58
|
+
bind_key( ?u ) { @undo_handler.undo if @undo_handler }
|
|
59
|
+
bind_key( ?\C-r ) { @undo_handler.redo if @undo_handler }
|
|
60
|
+
bind_key( [?y, ?y] , :kill_ring_save )
|
|
61
|
+
bind_key( ?p, :yank ) # paste after this line
|
|
62
|
+
#bind_key( ?P ) { yank(@current_index - 1) } # should be before this line
|
|
63
|
+
# seems -1 was pasting 2 lines before
|
|
64
|
+
bind_key( ?P ) { yank(@current_index - 0) } # should be before this line
|
|
65
|
+
bind_key(?w, :forward_word)
|
|
66
|
+
bind_key(?\M-y, :yank_pop)
|
|
67
|
+
bind_key(?\C-y, :yank)
|
|
68
|
+
bind_key(?\M-w, :kill_ring_save)
|
|
69
|
+
@_events.push :CHANGE # thru vieditable
|
|
70
|
+
#bind_key( ?D, :delete_eol)
|
|
71
|
+
#bind_key( [?d, ?$], :delete_eol)
|
|
72
|
+
#bind_key(?f, :forward_char)
|
|
73
|
+
#bind_key( ?x, :delete_curr_char )
|
|
74
|
+
#bind_key( ?X, :delete_prev_char )
|
|
75
|
+
#bind_key( [?d, ?w], :delete_word )
|
|
76
|
+
#bind_key( [?d, ?t], :delete_till )
|
|
77
|
+
#bind_key( [?d, ?f], :delete_forward )
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# currently only adding delete_line and some yank pop functions
|
|
82
|
+
# These will all give wrong results in table due to _header_offset
|
|
83
|
+
def vieditable_init_tabular
|
|
84
|
+
$log.debug " inside vieditable_init tabular"
|
|
85
|
+
@editable = true
|
|
86
|
+
#bind_key( ?C, :edit_line)
|
|
87
|
+
#bind_key( ?o, :insert_line)
|
|
88
|
+
#bind_key( ?O) { insert_line(@current_index-1) }
|
|
89
|
+
#bind_key( ?o) { insert_line(@current_index+1) }
|
|
90
|
+
#bind_key( ?O) { insert_line(@current_index) }
|
|
91
|
+
bind_key( [?d, ?d] , :delete_line )
|
|
92
|
+
#bind_key( ?\C-_ ) { @undo_handler.undo if @undo_handler }
|
|
93
|
+
#bind_key( ?u ) { @undo_handler.undo if @undo_handler }
|
|
94
|
+
#bind_key( ?\C-r ) { @undo_handler.redo if @undo_handler }
|
|
95
|
+
bind_key( [?y, ?y] , :kill_ring_save )
|
|
96
|
+
bind_key( ?p, :yank ) # paste after this line
|
|
97
|
+
bind_key( ?P ) { yank(@current_index - 1) } # should be before this line
|
|
98
|
+
bind_key(?\M-y, :yank_pop)
|
|
99
|
+
bind_key(?\M-w, :kill_ring_save)
|
|
100
|
+
@_events.push :CHANGE # thru vieditable
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
##
|
|
104
|
+
# edit current or given line
|
|
105
|
+
def edit_line lineno=@current_index
|
|
106
|
+
line = self[lineno]
|
|
107
|
+
prompt = "Edit: "
|
|
108
|
+
maxlen = 80
|
|
109
|
+
config={};
|
|
110
|
+
oldline = line.dup
|
|
111
|
+
config[:default] = line
|
|
112
|
+
ret, str = rb_getstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
|
113
|
+
$log.debug " rb_getstr returned #{ret} , #{str} "
|
|
114
|
+
return if ret != 0
|
|
115
|
+
# we possibly cou;d have done []= but maybe in textpad or something that would replace a row pointer ??
|
|
116
|
+
self[lineno].replace(str)
|
|
117
|
+
fire_handler :CHANGE, InputDataEvent.new(0,oldline.length, self, :DELETE_LINE, lineno, oldline) # 2008-12-24 18:34
|
|
118
|
+
fire_handler :CHANGE, InputDataEvent.new(0,str.length, self, :INSERT_LINE, lineno, str)
|
|
119
|
+
fire_row_changed lineno
|
|
120
|
+
end
|
|
121
|
+
##
|
|
122
|
+
# insert a line
|
|
123
|
+
# FIXME needs to fire handler 2010-05-23 11:40
|
|
124
|
+
def insert_line lineno=@current_index
|
|
125
|
+
prompt = "Insert: "
|
|
126
|
+
maxlen = 80
|
|
127
|
+
#config={};
|
|
128
|
+
#config[:default] = line
|
|
129
|
+
#ret, str = rb_getstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
|
130
|
+
ret, str = input_string prompt
|
|
131
|
+
#ret, str = rb_getstr(@form.window, @row+@height-1, @col+1, prompt, maxlen, config)
|
|
132
|
+
$log.debug " rb_getstr returned #{ret} , #{str} "
|
|
133
|
+
return if ret != 0
|
|
134
|
+
|
|
135
|
+
# pad based expect @content not list
|
|
136
|
+
# remove list after a while FIXME
|
|
137
|
+
@list ||= @content
|
|
138
|
+
@list.insert lineno, str
|
|
139
|
+
## added handler on 2010-05-23 11:46 - undo works - tested in testlistbox.rb
|
|
140
|
+
fire_handler :CHANGE, InputDataEvent.new(0,str.length, self, :INSERT_LINE, lineno, str)
|
|
141
|
+
fire_dimension_changed
|
|
142
|
+
end
|
|
143
|
+
##
|
|
144
|
+
# common method to edit given string
|
|
145
|
+
# @param [String] string to edit/modify
|
|
146
|
+
# @param [String] prompt to display before string
|
|
147
|
+
# @param [int] max length of input
|
|
148
|
+
# @return [0, -1] return value 0 if okay, -1 if error
|
|
149
|
+
#
|
|
150
|
+
def edit_string string, prompt="Edit: ", maxlen=80
|
|
151
|
+
config={};
|
|
152
|
+
config[:default] = string
|
|
153
|
+
ret, str = rb_getstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
|
154
|
+
#return str if ret == 0
|
|
155
|
+
#return ""
|
|
156
|
+
end
|
|
157
|
+
##
|
|
158
|
+
# common method to input a blank string
|
|
159
|
+
# @param [String] prompt to display before string
|
|
160
|
+
# @param [int] max length of input
|
|
161
|
+
# @return [0, -1] return value 0 if okay, -1 if error
|
|
162
|
+
def input_string prompt="Insert: ", maxlen=80
|
|
163
|
+
#ret, str = rb_getstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
|
164
|
+
ret, str = rb_getstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
|
165
|
+
#return str if ret == 0
|
|
166
|
+
#return ""
|
|
167
|
+
end
|
|
168
|
+
def edit_chars
|
|
169
|
+
|
|
170
|
+
end
|
|
171
|
+
def edit_word
|
|
172
|
+
|
|
173
|
+
end
|
|
174
|
+
end # module
|
|
175
|
+
end # module
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
|
2
|
+
# File: widgetmenu.rb
|
|
3
|
+
# Description: a module that displays a menu for customization of a field
|
|
4
|
+
# e.g.,
|
|
5
|
+
# field.extend(WidgetMenu)
|
|
6
|
+
#
|
|
7
|
+
# Author: jkepler http://github.com/mare-imbrium/canis/
|
|
8
|
+
# Date: 2011-12-2x
|
|
9
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
10
|
+
# Last update: 2011-12-26 - 20:25
|
|
11
|
+
# ----------------------------------------------------------------------------- #
|
|
12
|
+
#
|
|
13
|
+
# Provide a system for us to define a menu for customizing a widget, such that
|
|
14
|
+
# applicatin can also add more menuitems
|
|
15
|
+
module Canis
|
|
16
|
+
extend self
|
|
17
|
+
module WidgetMenu
|
|
18
|
+
include Io # added 2011-12-26
|
|
19
|
+
# add a menu item which can any one of
|
|
20
|
+
# @param key, label, desc, action | symbol
|
|
21
|
+
# key, symbol
|
|
22
|
+
# Action
|
|
23
|
+
# Action[] (maybe)
|
|
24
|
+
def self.extended(obj)
|
|
25
|
+
# don't want this executed each time
|
|
26
|
+
@objects ||= []
|
|
27
|
+
return if @objects.include? obj
|
|
28
|
+
@objects << obj
|
|
29
|
+
|
|
30
|
+
obj.instance_exec {
|
|
31
|
+
@_menuitems ||= []
|
|
32
|
+
# callign this method means that no other programs can use those actions else
|
|
33
|
+
# that method will be called more than once, so it must either be called in the constructor
|
|
34
|
+
# or else have a check that it is only called once.
|
|
35
|
+
obj.init_menu if obj.respond_to? :init_menu
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
def add_menu_item *val
|
|
40
|
+
#@_menuitems ||= []
|
|
41
|
+
@_menuitems << val
|
|
42
|
+
end
|
|
43
|
+
#
|
|
44
|
+
# insert an item at given position (index)
|
|
45
|
+
def insert_menu_item pos, *val
|
|
46
|
+
#@_menuitems ||= []
|
|
47
|
+
@_menuitems[pos] = val
|
|
48
|
+
end
|
|
49
|
+
def create_menuitem *args
|
|
50
|
+
PromptMenu.create_menuitem *args
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# popup the hist
|
|
54
|
+
#
|
|
55
|
+
def _show_menu
|
|
56
|
+
return if @_menuitems.nil? || @_menuitems.empty?
|
|
57
|
+
list = @_menuitems
|
|
58
|
+
menu = PromptMenu.new self do |m|
|
|
59
|
+
list.each { |e|
|
|
60
|
+
m.add *e
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
menu.display_new :title => 'Widget Menu (Press letter)'
|
|
64
|
+
end
|
|
65
|
+
end # mod History
|
|
66
|
+
end # mod RubyC
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require 'canis/core/system/ncurses'
|
|
2
|
+
|
|
3
|
+
module Canis
|
|
4
|
+
module ColorMap
|
|
5
|
+
# 2010-09-20 12:22 changed colors from string to symbol
|
|
6
|
+
## private
|
|
7
|
+
# returns a color constant for a human color string
|
|
8
|
+
def ColorMap.get_color_const colorstring
|
|
9
|
+
# added check for fixnum if we go beyond these constants 2011-11-28
|
|
10
|
+
# e.g. to use full 256 colors
|
|
11
|
+
return colorstring if colorstring.is_a? Fixnum
|
|
12
|
+
ret = FFI::NCurses.const_get "COLOR_#{colorstring.to_s.upcase}"
|
|
13
|
+
end
|
|
14
|
+
## private
|
|
15
|
+
# creates a new color pair, puts in color map and returns color_pair
|
|
16
|
+
# number
|
|
17
|
+
def ColorMap.install_color fgc, bgc
|
|
18
|
+
#$log.debug " install_color found #{fgc} #{@bgc} "
|
|
19
|
+
@color_id += 1
|
|
20
|
+
fg = ColorMap.get_color_const fgc
|
|
21
|
+
bg = ColorMap.get_color_const bgc
|
|
22
|
+
FFI::NCurses.init_pair(@color_id, fg, bg);
|
|
23
|
+
$color_map[[fgc, bgc]] = @color_id
|
|
24
|
+
return @color_id
|
|
25
|
+
end
|
|
26
|
+
#
|
|
27
|
+
# returns the colors that make up the given pair
|
|
28
|
+
# you may want to find what makes up $bottomcolor and set color and bgcolor with it.
|
|
29
|
+
# @param [Fixnum] color_pair
|
|
30
|
+
# @return [Symbol, Symbol] foreground and backgrounf color
|
|
31
|
+
# @example
|
|
32
|
+
# color, bgcolor = get_colors_for_pair $datacolor
|
|
33
|
+
#
|
|
34
|
+
def ColorMap.get_colors_for_pair pair
|
|
35
|
+
$color_map.invert[pair]
|
|
36
|
+
end
|
|
37
|
+
## public
|
|
38
|
+
# returns a color_pair for a given foreground and background color
|
|
39
|
+
def ColorMap.get_color fgc, bgc=$def_bg_color
|
|
40
|
+
fgc = fgc.to_sym if fgc.is_a? String
|
|
41
|
+
bgc = bgc.to_sym if bgc.is_a? String
|
|
42
|
+
if $color_map.include? [fgc, bgc]
|
|
43
|
+
#$log.debug " get_color found #{fgc} #{@bgc} "
|
|
44
|
+
return $color_map[[fgc, bgc]]
|
|
45
|
+
else
|
|
46
|
+
#$log.debug " get_color NOT found #{fgc} #{@bgc} "
|
|
47
|
+
return ColorMap.install_color fgc, bgc
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
def ColorMap.colors
|
|
51
|
+
@@colors
|
|
52
|
+
end
|
|
53
|
+
# returns true if color is a valid one, else false
|
|
54
|
+
# @param [Symbol] color such as :black :cyan :yellow
|
|
55
|
+
# @return [Boolean] true if valid, else false
|
|
56
|
+
def ColorMap.is_color? color
|
|
57
|
+
return true if color.is_a? Fixnum # so we can use 256 colors
|
|
58
|
+
@@colors.include? color.to_sym
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
## public
|
|
62
|
+
# setup color map at start of application
|
|
63
|
+
def ColorMap.setup
|
|
64
|
+
@color_id = 0
|
|
65
|
+
$color_map = {}
|
|
66
|
+
FFI::NCurses.start_color();
|
|
67
|
+
# Initialize few color pairs
|
|
68
|
+
$def_fg_color = :white # pls set these 2 for your application
|
|
69
|
+
$def_bg_color = :black
|
|
70
|
+
#COLORS = [COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
|
|
71
|
+
# COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE]
|
|
72
|
+
@@colors = [:black, :red, :green, :yellow, :blue, :magenta, :cyan, :white]
|
|
73
|
+
|
|
74
|
+
# make foreground colors
|
|
75
|
+
bg = ColorMap.get_color_const $def_bg_color
|
|
76
|
+
@@colors[0...@@colors.size].each_with_index do |color, i|
|
|
77
|
+
next if color == $def_bg_color # NOTE hope this doesn't do something if you change def_bg
|
|
78
|
+
ColorMap.install_color color, $def_bg_color
|
|
79
|
+
end
|
|
80
|
+
$reversecolor = ColorMap.get_color $def_bg_color, $def_fg_color
|
|
81
|
+
$popupcolor = ColorMap.get_color :cyan, $def_fg_color
|
|
82
|
+
|
|
83
|
+
$errorcolor = ColorMap.get_color :white, :red
|
|
84
|
+
#$promptcolor = $selectedcolor = ColorMap.get_color(:yellow, :red)
|
|
85
|
+
$promptcolor = ColorMap.get_color(:yellow, :red)
|
|
86
|
+
$normalcolor = $datacolor = ColorMap.get_color(:white, :black)
|
|
87
|
+
$bottomcolor = $topcolor = ColorMap.get_color(:white, :blue)
|
|
88
|
+
$selectedcolor = $datacolor # since we now use reverse attr in list
|
|
89
|
+
|
|
90
|
+
$row_selected_attr = Ncurses::A_REVERSE
|
|
91
|
+
$row_focussed_attr = Ncurses::A_BOLD
|
|
92
|
+
$row_attr = Ncurses::A_NORMAL
|
|
93
|
+
|
|
94
|
+
# $log.debug " colormap SETUP: #{$datacolor} #{$reversecolor} "
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end # modul
|
|
98
|
+
if $0 == __FILE__
|
|
99
|
+
require 'logger'
|
|
100
|
+
require 'ver/window'
|
|
101
|
+
#include Ncurses # FFI 2011-09-8
|
|
102
|
+
include ColorMap
|
|
103
|
+
# Initialize curses
|
|
104
|
+
begin
|
|
105
|
+
$log = Logger.new("canis.log")
|
|
106
|
+
Canis::start_ncurses
|
|
107
|
+
@window = Canis::Window.root_window
|
|
108
|
+
$log.level = Logger::DEBUG
|
|
109
|
+
ColorMap.setup
|
|
110
|
+
|
|
111
|
+
# Create the window to be associated with the form
|
|
112
|
+
# Un post form and free the memory
|
|
113
|
+
|
|
114
|
+
catch(:close) do
|
|
115
|
+
# $log.debug "START ---------"
|
|
116
|
+
# need to pass a form, not window.
|
|
117
|
+
r = 1; c = 2; i=0
|
|
118
|
+
attr = Ncurses::A_NORMAL
|
|
119
|
+
@window.printstring 20, c, "press 0-9 to change BG color, F1/q to quit. r-everse, n-ormal,b-old ", ColorMap.get_color('white')
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
while((ch = @window.getchar()) != FFI::NCurses::KEY_F1 )
|
|
124
|
+
next if ch == -1
|
|
125
|
+
break if ch == ?q.getbyte(0)
|
|
126
|
+
case ch
|
|
127
|
+
when ?r.getbyte(0)
|
|
128
|
+
attr |= Ncurses::A_REVERSE
|
|
129
|
+
when ?b.getbyte(0)
|
|
130
|
+
attr |= Ncurses::A_BOLD
|
|
131
|
+
when ?n.getbyte(0)
|
|
132
|
+
attr = Ncurses::A_NORMAL
|
|
133
|
+
when ?u.getbyte(0)
|
|
134
|
+
attr |= Ncurses::A_UNDERLINE
|
|
135
|
+
else
|
|
136
|
+
i = ch.chr.to_i
|
|
137
|
+
i = 1 if i > ColorMap::colors.length-1
|
|
138
|
+
end
|
|
139
|
+
bg = ColorMap::colors[i]
|
|
140
|
+
@@colors = %w[black red green yellow blue magenta cyan white]
|
|
141
|
+
@window.printstring r, c, "%-40s" % "red #{bg} ", ColorMap.get_color('red',bg) , attr
|
|
142
|
+
@window.printstring 2, c, "%-40s" % "blue #{bg} ", ColorMap.get_color('blue',bg) , attr
|
|
143
|
+
@window.printstring 3, c, "%-40s" % "white #{bg} ", ColorMap.get_color('white',bg) , attr
|
|
144
|
+
@window.printstring 4, c, "%-40s" % "green #{bg} ", ColorMap.get_color('green',bg) , attr
|
|
145
|
+
@window.printstring 5, c, "%-40s" % "cyan #{bg} ", ColorMap.get_color('cyan',bg) , attr
|
|
146
|
+
@window.printstring 6, c, "%-40s" % "magenta #{bg} ", ColorMap.get_color('magenta',bg) , attr
|
|
147
|
+
@window.printstring 7, c, "black #{bg} ", ColorMap.get_color('black',bg) , attr
|
|
148
|
+
@window.wrefresh
|
|
149
|
+
end
|
|
150
|
+
# Canis::Keyboard.focus = tp
|
|
151
|
+
end
|
|
152
|
+
rescue => ex
|
|
153
|
+
ensure
|
|
154
|
+
# @panel = @window.panel if @window
|
|
155
|
+
# Ncurses::Panel.del_panel(@panel) if !@panel.nil?
|
|
156
|
+
# @window.delwin if !@window.nil?
|
|
157
|
+
@window.destroy unless @window.nil?
|
|
158
|
+
Canis::stop_ncurses
|
|
159
|
+
p ex if ex
|
|
160
|
+
p(ex.backtrace.join("\n")) if ex
|
|
161
|
+
# $log.debug( ex) if ex
|
|
162
|
+
# $log.debug(ex.backtrace.join("\n")) if ex
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
|
2
|
+
# File: keydefs.rb
|
|
3
|
+
# Description: Some common keys used in app. Earlier part of rwidget.rb
|
|
4
|
+
# Author: jkepler http://github.com/mare-imbrium/canis/
|
|
5
|
+
# Date: 08.11.11 - 14:57
|
|
6
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
7
|
+
# Last update: 2014-04-20 17:28
|
|
8
|
+
# ----------------------------------------------------------------------------- #
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
# some common definition that we use throughout app. Do not add more, only what is common.
|
|
12
|
+
# I should not have added Sh-F9 and C-left since they are rare, but only to show they exist.
|
|
13
|
+
#
|
|
14
|
+
# THESE are now obsolete since we are moving to string based return values
|
|
15
|
+
# else they should be updated.
|
|
16
|
+
KEY_TAB = 9
|
|
17
|
+
KEY_F1 = FFI::NCurses::KEY_F1
|
|
18
|
+
KEY_F10 = FFI::NCurses::KEY_F10
|
|
19
|
+
KEY_ENTER = 13 # FFI::NCurses::KEY_ENTER gives 343
|
|
20
|
+
KEY_RETURN = 10 # FFI gives 10 too
|
|
21
|
+
KEY_BTAB = 353 # nc gives same
|
|
22
|
+
KEY_DELETE = 330
|
|
23
|
+
KEY_BACKSPACE = KEY_BSPACE = 127 # Nc gives 263 for BACKSPACE
|
|
24
|
+
KEY_CC = 3 # C-c
|
|
25
|
+
KEY_LEFT = FFI::NCurses::KEY_LEFT
|
|
26
|
+
KEY_RIGHT = FFI::NCurses::KEY_RIGHT
|
|
27
|
+
KEY_UP = FFI::NCurses::KEY_UP
|
|
28
|
+
KEY_DOWN = FFI::NCurses::KEY_DOWN
|
|
29
|
+
C_LEFT = 18168
|
|
30
|
+
C_RIGHT = 18167
|
|
31
|
+
S_F9 = 17949126
|
|
32
|
+
META_KEY = 128
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
require 'ffi-ncurses'
|
|
2
|
+
#include FFI::NCurses # this pollutes many objects and invalidates method_missing
|
|
3
|
+
module Canis
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
# Setup ncurses, nicely documented by the curses manpages
|
|
7
|
+
def start_ncurses
|
|
8
|
+
return if $ncurses_started
|
|
9
|
+
$ncurses_started = true
|
|
10
|
+
# in case we want a blocking getch, you may want to first
|
|
11
|
+
# set wtimeout to -1, and then reset it to this value.
|
|
12
|
+
# Please first check that we are using this.
|
|
13
|
+
$ncurses_timeout = 500 # used by windows for timeout of wgetch
|
|
14
|
+
|
|
15
|
+
# The initscr code determines the terminal type and initializes all curses
|
|
16
|
+
# data structures.
|
|
17
|
+
# initscr also causes the first call to refresh to clear the screen.
|
|
18
|
+
# If errors occur, initscr writes an appropriate error message to standard
|
|
19
|
+
# error and exits; otherwise, a pointer is returned to stdscr.
|
|
20
|
+
stdscr = Ncurses.initscr ## FFI
|
|
21
|
+
|
|
22
|
+
# Color.start if Ncurses.has_colors?
|
|
23
|
+
Ncurses.start_color();
|
|
24
|
+
ColorMap.setup # added by RK 2008-11-30 00:48
|
|
25
|
+
# The keypad option enables the keypad of the user's terminal.
|
|
26
|
+
# If enabled (bf is TRUE), the user can press a function key (such as an
|
|
27
|
+
# arrow key) and wgetch returns a single value representing the function
|
|
28
|
+
# key, as in KEY_LEFT.
|
|
29
|
+
# If disabled (bf is FALSE), curses does not treat function keys specially
|
|
30
|
+
# and the program has to interpret the escape sequences itself.
|
|
31
|
+
# If the keypad in the terminal can be turned on (made to transmit) and off
|
|
32
|
+
# (made to work locally), turning on this option causes the terminal keypad
|
|
33
|
+
# to be turned on when wgetch is called.
|
|
34
|
+
# The default value for keypad is false.
|
|
35
|
+
Ncurses.keypad(stdscr.pointer, bf = true) # FFIWINDOW
|
|
36
|
+
#Ncurses.keypad(stdscr, bf = true)
|
|
37
|
+
#Ncurses.stdscr.keypad(true) # turn on keypad mode FFI
|
|
38
|
+
#Ncurses.keypad(stdscr, bf = 1)
|
|
39
|
+
|
|
40
|
+
# The nl and nonl routines control whether the underlying display device
|
|
41
|
+
# translates the return key into newline on input, and whether it
|
|
42
|
+
# translates newline into return and line-feed on output (in either case,
|
|
43
|
+
# the call addch('\n') does the equivalent of return and line feed on the
|
|
44
|
+
# virtual screen).
|
|
45
|
+
# Initially, these translations do occur.
|
|
46
|
+
# If you disable them using nonl, curses will be able to make better use of
|
|
47
|
+
# the line-feed capability, resulting in faster cursor motion.
|
|
48
|
+
# Also, curses will then be able to detect the return key.
|
|
49
|
+
Ncurses.nonl
|
|
50
|
+
|
|
51
|
+
# The raw and noraw routines place the terminal into or out of raw mode.
|
|
52
|
+
# Raw mode is similar to cbreak mode, in that characters typed are
|
|
53
|
+
# immediately passed through to the user program.
|
|
54
|
+
# The differences are that in raw mode, the interrupt, quit, suspend, and
|
|
55
|
+
# flow control characters are all passed through uninterpreted, instead of
|
|
56
|
+
# generating a signal.
|
|
57
|
+
# The behavior of the BREAK key depends on other bits in the tty driver
|
|
58
|
+
# that are not set by curses.
|
|
59
|
+
Ncurses.raw
|
|
60
|
+
|
|
61
|
+
# Normally, the tty driver buffers typed characters until a newline or
|
|
62
|
+
# carriage return is typed.
|
|
63
|
+
# The cbreak routine disables line buffering and
|
|
64
|
+
# erase/kill character-processing (interrupt and flow control characters
|
|
65
|
+
# are unaffected), making characters typed by the user immediately
|
|
66
|
+
# available to the program.
|
|
67
|
+
#Ncurses.cbreak
|
|
68
|
+
# I have removed cbreak and halfdelay since they were causing C-c
|
|
69
|
+
# to crash if i pressed it in succession
|
|
70
|
+
|
|
71
|
+
# The echo and noecho routines control whether characters typed by the user
|
|
72
|
+
# are echoed by getch as they are typed.
|
|
73
|
+
# Echoing by the tty driver is always disabled, but initially getch is in
|
|
74
|
+
# echo mode, so characters typed are echoed.
|
|
75
|
+
Ncurses.noecho
|
|
76
|
+
|
|
77
|
+
# The curs_set routine sets the cursor state is set to invisible, normal,
|
|
78
|
+
# or very visible for visibility equal to 0, 1, or 2 respectively.
|
|
79
|
+
# If the terminal supports the visibility requested, the previous cursor
|
|
80
|
+
# state is returned; otherwise, ERR is returned.
|
|
81
|
+
Ncurses.curs_set(1)
|
|
82
|
+
|
|
83
|
+
# The halfdelay routine is used for half-delay mode, which is similar to
|
|
84
|
+
# cbreak mode in that characters typed by the user are immediately
|
|
85
|
+
# available to the program.
|
|
86
|
+
# However, after blocking for tenths tenths of seconds, ERR is returned if
|
|
87
|
+
# nothing has been typed.
|
|
88
|
+
# The value of tenths must be a number between 1 and 255.
|
|
89
|
+
# Use nocbreak to leave half-delay mode.
|
|
90
|
+
#Ncurses::halfdelay(tenths = 10)
|
|
91
|
+
# See above why switched off, halfdelay puts into cbreak mode, in which C-c pressed in quick
|
|
92
|
+
# succession crashes the program.
|
|
93
|
+
|
|
94
|
+
# The nodelay option causes getch to be a non-blocking call. If no input is
|
|
95
|
+
# ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a
|
|
96
|
+
# key is pressed.
|
|
97
|
+
# I am using the next line for the window when creating, this does not
|
|
98
|
+
# have any impact on window.
|
|
99
|
+
# For this to have any effect your getch should be Ncurses.getch and not
|
|
100
|
+
# wgetch(@window), For that do this with window.
|
|
101
|
+
# I am disableing this 2011-12-20 since it does not work with combinations
|
|
102
|
+
# such as gg. Any routine that does a getch will just immediatelt return an ERR.
|
|
103
|
+
#Ncurses::nodelay(stdscr.pointer, bf = true)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# added these 2 so we can do resizing based on original and current size when terminal resized
|
|
107
|
+
# 2012-01-8
|
|
108
|
+
$orig_cols = FFI::NCurses.COLS
|
|
109
|
+
$orig_rows = FFI::NCurses.LINES
|
|
110
|
+
# cache of keycode (int) and string result
|
|
111
|
+
$key_cache ||= {}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# this should happen only in outermost program that started ncurses
|
|
115
|
+
# if a called program does this, the calling program can have a display freeze
|
|
116
|
+
def stop_ncurses
|
|
117
|
+
Ncurses.echo
|
|
118
|
+
Ncurses.nocbreak
|
|
119
|
+
Ncurses.nl
|
|
120
|
+
Ncurses.endwin
|
|
121
|
+
$ncurses_started = false
|
|
122
|
+
#puts "curses over"
|
|
123
|
+
ensure
|
|
124
|
+
return unless error = @last_error
|
|
125
|
+
|
|
126
|
+
$stderr.puts ''
|
|
127
|
+
$stderr.puts @last_error_message if @last_error_message
|
|
128
|
+
$stderr.puts @last_error, *@last_error.backtrace
|
|
129
|
+
end
|
|
130
|
+
require 'canis/core/system/colormap'
|
|
131
|
+
include Canis::ColorMap
|
|
132
|
+
end
|
|
133
|
+
module Ncurses
|
|
134
|
+
extend self
|
|
135
|
+
FALSE = 0
|
|
136
|
+
TRUE = 1
|
|
137
|
+
module NCX
|
|
138
|
+
def COLS
|
|
139
|
+
FFI::NCurses.getmaxx(FFI::NCurses.stdscr)
|
|
140
|
+
end
|
|
141
|
+
def LINES
|
|
142
|
+
# #FFI::NCurses.getmaxy(FFI::NCurses.stdscr)
|
|
143
|
+
FFI::NCurses.LINES
|
|
144
|
+
end
|
|
145
|
+
# # supposed to be picked up at runtime
|
|
146
|
+
def COLORS
|
|
147
|
+
FFI::NCurses.COLORS
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# jsut trying this so i can do Ncurses.stdscr.getmax
|
|
151
|
+
def _stdscr
|
|
152
|
+
FFI::NCurses.stdscr
|
|
153
|
+
end
|
|
154
|
+
# this allows me to refer to them as Ncurses::A_REVERSE as is the case everywhere
|
|
155
|
+
A_REVERSE = FFI::NCurses::A_REVERSE
|
|
156
|
+
A_STANDOUT = FFI::NCurses::A_STANDOUT
|
|
157
|
+
A_BOLD = FFI::NCurses::A_BOLD
|
|
158
|
+
A_UNDERLINE = FFI::NCurses::A_UNDERLINE
|
|
159
|
+
A_BLINK = FFI::NCurses::A_BLINK
|
|
160
|
+
A_NORMAL = FFI::NCurses::A_NORMAL
|
|
161
|
+
KEY_F1 = FFI::NCurses::KEY_F1
|
|
162
|
+
end
|
|
163
|
+
include NCX
|
|
164
|
+
extend NCX
|
|
165
|
+
# i think we can knock this off
|
|
166
|
+
def method_missing meth, *args
|
|
167
|
+
if (FFI::NCurses.respond_to?(meth))
|
|
168
|
+
FFI::NCurses.send meth, *args
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
# FFINC.constants.each { |e| Ncurses.const_set(e, FFINC.const_get(e) ) }
|
|
172
|
+
def const_missing name
|
|
173
|
+
val = FFI::NCurses.const_get(name)
|
|
174
|
+
const_set(name, val)
|
|
175
|
+
return val
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# This is a window pointer wrapper, to be used for stdscr and others.
|
|
179
|
+
# Ideally ffi-ncurses should do this, if it returns a pointer, I'll do this.
|
|
180
|
+
class FFIWINDOW
|
|
181
|
+
attr_accessor :pointer
|
|
182
|
+
def initialize(*args, &block)
|
|
183
|
+
if block_given?
|
|
184
|
+
@pointer = args.first
|
|
185
|
+
else
|
|
186
|
+
@pointer = FFI::NCurses.newwin(*args)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
def method_missing(name, *args)
|
|
190
|
+
name = name.to_s
|
|
191
|
+
if (name[0,2] == "mv")
|
|
192
|
+
test_name = name.dup
|
|
193
|
+
test_name[2,0] = "w" # insert "w" after"mv"
|
|
194
|
+
if (FFI::NCurses.respond_to?(test_name))
|
|
195
|
+
return FFI::NCurses.send(test_name, @pointer, *args)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
test_name = "w" + name
|
|
199
|
+
if (FFI::NCurses.respond_to?(test_name))
|
|
200
|
+
return FFI::NCurses.send(test_name, @pointer, *args)
|
|
201
|
+
end
|
|
202
|
+
FFI::NCurses.send(name, @pointer, *args)
|
|
203
|
+
end
|
|
204
|
+
def respond_to?(name)
|
|
205
|
+
name = name.to_s
|
|
206
|
+
if (name[0,2] == "mv" && FFI::NCurses.respond_to?("mvw" + name[2..-1]))
|
|
207
|
+
return true
|
|
208
|
+
end
|
|
209
|
+
FFI::NCurses.respond_to?("w" + name) || FFI::NCurses.respond_to?(name)
|
|
210
|
+
end
|
|
211
|
+
def del
|
|
212
|
+
FFI::NCurses.delwin(@pointer)
|
|
213
|
+
end
|
|
214
|
+
alias delete del
|
|
215
|
+
end
|
|
216
|
+
# if ffi-ncurses returns a pointer wrap it.
|
|
217
|
+
# or we can check for whether it responds_to? refresh and getch
|
|
218
|
+
def self.initscr
|
|
219
|
+
#@stdscr = Ncurses::FFIWINDOW.new(FFI::NCurses.initscr) { }
|
|
220
|
+
stdscr = FFI::NCurses.initscr
|
|
221
|
+
if stdscr.is_a? FFI::Pointer
|
|
222
|
+
@stdscr = Ncurses::FFIWINDOW.new(stdscr) { }
|
|
223
|
+
else
|
|
224
|
+
@stdscr = stdscr
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
def self.stdscr
|
|
228
|
+
@stdscr
|
|
229
|
+
end
|
|
230
|
+
# commented off on 2011-09-15 FFIWINDOW results in errors
|
|
231
|
+
# class << self
|
|
232
|
+
# def method_missing(method, *args, &block)
|
|
233
|
+
# FFI::NCurses.send(method, *args, &block)
|
|
234
|
+
# end
|
|
235
|
+
# end
|
|
236
|
+
# ---
|
|
237
|
+
end
|