canis 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|