canis 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
@@ -0,0 +1,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