rbhex-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +2000 -0
  4. data/LICENSE +56 -0
  5. data/README.md +44 -0
  6. data/examples/abasiclist.rb +179 -0
  7. data/examples/alpmenu.rb +50 -0
  8. data/examples/app.sample +19 -0
  9. data/examples/atree.rb +100 -0
  10. data/examples/bline.rb +136 -0
  11. data/examples/common/file.rb +45 -0
  12. data/examples/data/README.markdown +9 -0
  13. data/examples/data/brew.txt +38 -0
  14. data/examples/data/color.2 +37 -0
  15. data/examples/data/gemlist.txt +60 -0
  16. data/examples/data/lotr.txt +12 -0
  17. data/examples/data/ports.txt +136 -0
  18. data/examples/data/table.txt +37 -0
  19. data/examples/data/tasks.csv +88 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/data/todo.txt +10 -0
  22. data/examples/data/todo.txt.bak +10 -0
  23. data/examples/data/todocsv.csv +28 -0
  24. data/examples/data/unix1.txt +21 -0
  25. data/examples/data/unix2.txt +11 -0
  26. data/examples/dbdemo.rb +502 -0
  27. data/examples/dirtree.rb +94 -0
  28. data/examples/newtabbedwindow.rb +100 -0
  29. data/examples/newtesttabp.rb +92 -0
  30. data/examples/tabular.rb +146 -0
  31. data/examples/tasks.rb +178 -0
  32. data/examples/term2.rb +84 -0
  33. data/examples/testbuttons.rb +296 -0
  34. data/examples/testcombo.rb +102 -0
  35. data/examples/testfields.rb +195 -0
  36. data/examples/testkeypress.rb +72 -0
  37. data/examples/testlistbox.rb +170 -0
  38. data/examples/testmessagebox.rb +140 -0
  39. data/examples/testprogress.rb +116 -0
  40. data/examples/testree.rb +106 -0
  41. data/examples/testwsshortcuts.rb +66 -0
  42. data/examples/testwsshortcuts2.rb +128 -0
  43. data/lib/rbhex.rb +6 -0
  44. data/lib/rbhex/core/docs/index.txt +73 -0
  45. data/lib/rbhex/core/include/action.rb +80 -0
  46. data/lib/rbhex/core/include/actionmanager.rb +49 -0
  47. data/lib/rbhex/core/include/appmethods.rb +214 -0
  48. data/lib/rbhex/core/include/bordertitle.rb +48 -0
  49. data/lib/rbhex/core/include/chunk.rb +203 -0
  50. data/lib/rbhex/core/include/io.rb +553 -0
  51. data/lib/rbhex/core/include/listbindings.rb +74 -0
  52. data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
  53. data/lib/rbhex/core/include/listeditable.rb +317 -0
  54. data/lib/rbhex/core/include/listscrollable.rb +663 -0
  55. data/lib/rbhex/core/include/listselectable.rb +271 -0
  56. data/lib/rbhex/core/include/multibuffer.rb +83 -0
  57. data/lib/rbhex/core/include/orderedhash.rb +77 -0
  58. data/lib/rbhex/core/include/ractionevent.rb +73 -0
  59. data/lib/rbhex/core/include/rchangeevent.rb +27 -0
  60. data/lib/rbhex/core/include/rhistory.rb +95 -0
  61. data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
  62. data/lib/rbhex/core/include/vieditable.rb +172 -0
  63. data/lib/rbhex/core/include/widgetmenu.rb +66 -0
  64. data/lib/rbhex/core/system/colormap.rb +165 -0
  65. data/lib/rbhex/core/system/keyboard.rb +150 -0
  66. data/lib/rbhex/core/system/keydefs.rb +30 -0
  67. data/lib/rbhex/core/system/ncurses.rb +236 -0
  68. data/lib/rbhex/core/system/panel.rb +162 -0
  69. data/lib/rbhex/core/system/window.rb +913 -0
  70. data/lib/rbhex/core/util/ansiparser.rb +119 -0
  71. data/lib/rbhex/core/util/app.rb +1228 -0
  72. data/lib/rbhex/core/util/basestack.rb +410 -0
  73. data/lib/rbhex/core/util/bottomline.rb +1859 -0
  74. data/lib/rbhex/core/util/colorparser.rb +77 -0
  75. data/lib/rbhex/core/util/focusmanager.rb +31 -0
  76. data/lib/rbhex/core/util/padreader.rb +192 -0
  77. data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
  78. data/lib/rbhex/core/util/rdialogs.rb +574 -0
  79. data/lib/rbhex/core/util/viewer.rb +149 -0
  80. data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
  81. data/lib/rbhex/core/version.rb +5 -0
  82. data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
  83. data/lib/rbhex/core/widgets/box.rb +58 -0
  84. data/lib/rbhex/core/widgets/divider.rb +310 -0
  85. data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
  86. data/lib/rbhex/core/widgets/rcombo.rb +253 -0
  87. data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
  88. data/lib/rbhex/core/widgets/rlink.rb +30 -0
  89. data/lib/rbhex/core/widgets/rlist.rb +696 -0
  90. data/lib/rbhex/core/widgets/rmenu.rb +958 -0
  91. data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
  92. data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
  93. data/lib/rbhex/core/widgets/rprogress.rb +118 -0
  94. data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
  95. data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
  96. data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
  97. data/lib/rbhex/core/widgets/rtextview.rb +739 -0
  98. data/lib/rbhex/core/widgets/rtree.rb +768 -0
  99. data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
  100. data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
  101. data/lib/rbhex/core/widgets/statusline.rb +113 -0
  102. data/lib/rbhex/core/widgets/tabular.rb +264 -0
  103. data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
  104. data/lib/rbhex/core/widgets/textpad.rb +995 -0
  105. data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
  106. data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
  107. data/rbhex-core.gemspec +32 -0
  108. metadata +172 -0
@@ -0,0 +1,150 @@
1
+ module VER
2
+ module Keyboard # avoid initialize
3
+ ESC = 27 # keycode
4
+ @polling = false
5
+
6
+ module_function
7
+
8
+ def focus=(receiver)
9
+ @stack = []
10
+ @focus = receiver
11
+ poll unless @polling
12
+ end
13
+
14
+ def poll
15
+ @polling = true
16
+
17
+ while char = @focus.window.getch
18
+ break if @focus.stopping? # XXX
19
+ #break if VER.stopping?
20
+ $log.debug("char: #{char} stakc: #{@stack.inspect}") if char != Ncurses::ERR
21
+ if char == Ncurses::ERR # timeout or signal
22
+ @focus.press('esc') if @stack == [ESC]
23
+ @stack.clear
24
+ elsif ready = resolve(char)
25
+ $log.debug("char: #{char} ready: #{ready}")
26
+ @stack.clear
27
+ @focus.press(ready)
28
+ end
29
+ end
30
+
31
+ ensure
32
+ @polling = false
33
+ end
34
+
35
+ def resolve(char)
36
+ @stack << char
37
+
38
+ if @stack.first == ESC
39
+ MOD_KEYS[@stack] || SPECIAL_KEYS[@stack]
40
+ else
41
+ NCURSES_KEYS[char] || CONTROL_KEYS[char] || PRINTABLE_KEYS[char]
42
+ end
43
+ end
44
+
45
+ # TODO: make this section sane
46
+
47
+ ASCII = (0..255).map{|c| c.chr }
48
+ CONTROL = ASCII.grep(/[[:cntrl:]]/)
49
+ PRINTABLE = ASCII.grep(/[[:print:]]/)
50
+
51
+ SPECIAL_KEYS = {
52
+ [27, 79, 50, 81] => 'F14',
53
+ [27, 79, 50, 82] => 'F15',
54
+ [27, 79, 70] => 'end',
55
+ [27, 79, 70] => 'end',
56
+ [27, 79, 72] => 'home',
57
+ [27, 79, 80] => 'F1',
58
+ [27, 79, 81] => 'F2',
59
+ [27, 79, 82] => 'F3',
60
+ [27, 79, 83] => 'F4',
61
+ [27, 91, 49, 126] => 'end',
62
+ [27, 91, 49, 126] => 'home',
63
+ [27, 91, 49, 49, 126] => 'F1',
64
+ [27, 91, 49, 50, 126] => 'F2',
65
+ [27, 91, 49, 51, 126] => 'F3',
66
+ [27, 91, 49, 52, 126] => 'F4',
67
+ [27, 91, 49, 52, 126] => 'F4',
68
+ [27, 91, 49, 53, 126] => 'F5',
69
+ [27, 91, 49, 55, 126] => 'F6',
70
+ [27, 91, 49, 56, 59, 50, 126] => 'F19',
71
+ [27, 91, 49, 56, 59, 51, 126] => 'F7',
72
+ [27, 91, 49, 59, 51, 65] => 'ppage',
73
+ [27, 91, 49, 59, 51, 66] => 'npage',
74
+ [27, 91, 49, 59, 53, 65] => 'ppage',
75
+ [27, 91, 49, 59, 53, 66] => 'npage',
76
+ [27, 91, 49, 59, 53, 70] => 'M-<',
77
+ [27, 91, 49, 59, 53, 72] => 'M->',
78
+ [27, 91, 50, 54, 126] => 'F14',
79
+ [27, 91, 50, 56, 126] => 'F15',
80
+ [27, 91, 51, 59, 51, 126] => 'del',
81
+ [27, 91, 52, 126] => 'end',
82
+ [27, 91, 55, 126] => 'home',
83
+ [27, 91, 55, 126] => 'home',
84
+ [27, 91, 56, 126] => 'end',
85
+ [27, 91, 56, 126] => 'end',
86
+ [27, 91, 65] => 'up',
87
+ [27, 91, 66] => 'down',
88
+ [27, 91, 67] => 'right',
89
+ [27, 91, 68] => 'left',
90
+ [27, 91, 70] => 'end',
91
+ [27, 91, 72] => 'end',
92
+ [27, 91, 72] => 'home',
93
+ [27, 91, 91, 65] => 'F1',
94
+ [27, 91, 91, 66] => 'F2',
95
+ [27, 91, 91, 67] => 'F3',
96
+ [27, 91, 91, 68] => 'F4',
97
+ [27, 91, 91, 69] => 'F5',
98
+ }
99
+
100
+ CONTROL_KEYS = {
101
+ 0 => 'C-space',
102
+ 1 => 'C-a',
103
+ 2 => 'C-b',
104
+ 3 => 'C-c',
105
+ 4 => 'C-d',
106
+ 5 => 'C-e',
107
+ 6 => 'C-f',
108
+ 7 => 'C-g',
109
+ 8 => 'C-h',
110
+ 9 => 'tab',
111
+ 10 => 'return', # C-j
112
+ 11 => 'C-k',
113
+ 12 => 'C-l',
114
+ 13 => 'return', # C-m
115
+ 14 => 'C-n',
116
+ 15 => 'C-o',
117
+ 16 => 'C-p',
118
+ 17 => 'C-q',
119
+ 18 => 'C-r',
120
+ 19 => 'C-s',
121
+ 20 => 'C-t',
122
+ 21 => 'C-u',
123
+ 22 => 'C-v',
124
+ 23 => 'C-w',
125
+ 24 => 'C-x',
126
+ 25 => 'C-y',
127
+ 26 => 'C-z', # FIXME: is usually suspend in shell job control
128
+ # 27 => 'esc',
129
+ 32 => 'space',
130
+ 127 => 'backspace',
131
+ }
132
+
133
+ PRINTABLE_KEYS = {}
134
+ MOD_KEYS = {}
135
+
136
+ PRINTABLE.each do |key|
137
+ code = key.unpack('c')[0] # using unpack to be compatible with 1.9
138
+ PRINTABLE_KEYS[code] = key
139
+ MOD_KEYS[[ESC, code]] = "M-#{key}" unless key == '[' # don't map esc
140
+ end
141
+
142
+ NCURSES_KEYS = {}
143
+ Ncurses.constants.grep(/^KEY_/).each do |const|
144
+ value = Ncurses.const_get(const)
145
+ key = const[/^KEY_(.*)/, 1]
146
+ key = key =~ /^F/ ? key : key.downcase # function keys
147
+ NCURSES_KEYS[value] = key
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,30 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: keydefs.rb
3
+ # Description: Some common keys used in app. Earlier part of rwidget.rb
4
+ # Author: rkumar http://github.com/rkumar/rbcurse/
5
+ # Date: 08.11.11 - 14:57
6
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
7
+ # Last update: 08.11.11 - 14:57
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
+ KEY_TAB = 9
15
+ KEY_F1 = FFI::NCurses::KEY_F1
16
+ KEY_F10 = FFI::NCurses::KEY_F10
17
+ KEY_ENTER = 13 # FFI::NCurses::KEY_ENTER gives 343
18
+ KEY_RETURN = 10 # FFI gives 10 too
19
+ KEY_BTAB = 353 # nc gives same
20
+ KEY_DELETE = 330
21
+ KEY_BACKSPACE = KEY_BSPACE = 127 # Nc gives 263 for BACKSPACE
22
+ KEY_CC = 3 # C-c
23
+ KEY_LEFT = FFI::NCurses::KEY_LEFT
24
+ KEY_RIGHT = FFI::NCurses::KEY_RIGHT
25
+ KEY_UP = FFI::NCurses::KEY_UP
26
+ KEY_DOWN = FFI::NCurses::KEY_DOWN
27
+ C_LEFT = 18168
28
+ C_RIGHT = 18167
29
+ S_F9 = 17949126
30
+ META_KEY = 128
@@ -0,0 +1,236 @@
1
+ require 'ffi-ncurses'
2
+ #include FFI::NCurses # this pollutes many objects and invalidates method_missing
3
+ module VER
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_wtimeout = 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
92
+
93
+ # The nodelay option causes getch to be a non-blocking call. If no input is
94
+ # ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a
95
+ # key is pressed.
96
+ # I am using the next line for the window when creating, this does not
97
+ # have any impact on window.
98
+ # For this to have any effect your getch should be Ncurses.getch and not
99
+ # wgetch(@window), For that do this with window.
100
+ # I am disableing this 2011-12-20 since it does not work with combinations
101
+ # such as gg. Any routine that does a getch will just immediatelt return an ERR.
102
+ #Ncurses::nodelay(stdscr.pointer, bf = true)
103
+
104
+ # added these 2 so we can do resizing based on original and current size when terminal resized
105
+ # 2012-01-8
106
+ $orig_cols = FFI::NCurses.COLS
107
+ $orig_rows = FFI::NCurses.LINES
108
+ end
109
+
110
+ # this should happen only in outermost program that started ncurses
111
+ # if a called program does this, the calling program can have a display freeze
112
+ def stop_ncurses
113
+ Ncurses.echo
114
+ Ncurses.nocbreak
115
+ Ncurses.nl
116
+ Ncurses.endwin
117
+ $ncurses_started = false
118
+ #puts "curses over"
119
+ ensure
120
+ return unless error = @last_error
121
+ #log = RbConfig[:logfile].value
122
+ #Kernel.warn "There may have been fatal errors logged to: #{log}."
123
+ #Kernel.warn "The most recent was:"
124
+
125
+ $stderr.puts ''
126
+ $stderr.puts @last_error_message if @last_error_message
127
+ $stderr.puts @last_error, *@last_error.backtrace
128
+ end
129
+ require 'rbhex/core/system/colormap'
130
+ include RubyCurses::ColorMap
131
+ end
132
+ module Ncurses
133
+ extend self
134
+ FALSE = 0
135
+ TRUE = 1
136
+ module NCX
137
+ def COLS
138
+ FFI::NCurses.getmaxx(FFI::NCurses.stdscr)
139
+ end
140
+ def LINES
141
+ # #FFI::NCurses.getmaxy(FFI::NCurses.stdscr)
142
+ FFI::NCurses.LINES
143
+ end
144
+ # # supposed to be picked up at runtime
145
+ def COLORS
146
+ FFI::NCurses.COLORS
147
+ end
148
+
149
+ # jsut trying this so i can do Ncurses.stdscr.getmax
150
+ def _stdscr
151
+ FFI::NCurses.stdscr
152
+ end
153
+ # this allows me to refer to them as Ncurses::A_REVERSE as is the case everywhere
154
+ A_REVERSE = FFI::NCurses::A_REVERSE
155
+ A_STANDOUT = FFI::NCurses::A_STANDOUT
156
+ A_BOLD = FFI::NCurses::A_BOLD
157
+ A_UNDERLINE = FFI::NCurses::A_UNDERLINE
158
+ A_BLINK = FFI::NCurses::A_BLINK
159
+ A_NORMAL = FFI::NCurses::A_NORMAL
160
+ KEY_F1 = FFI::NCurses::KEY_F1
161
+ end
162
+ include NCX
163
+ extend NCX
164
+ # i think we can knock this off
165
+ def method_missing meth, *args
166
+ if (FFI::NCurses.respond_to?(meth))
167
+ FFI::NCurses.send meth, *args
168
+ end
169
+ end
170
+ # FFINC.constants.each { |e| Ncurses.const_set(e, FFINC.const_get(e) ) }
171
+ def const_missing name
172
+ val = FFI::NCurses.const_get(name)
173
+ const_set(name, val)
174
+ return val
175
+ end
176
+
177
+ # This is a window pointer wrapper, to be used for stdscr and others.
178
+ # Ideally ffi-ncurses should do this, if it returns a pointer, I'll do this.
179
+ class FFIWINDOW
180
+ attr_accessor :pointer
181
+ def initialize(*args, &block)
182
+ if block_given?
183
+ @pointer = args.first
184
+ else
185
+ @pointer = FFI::NCurses.newwin(*args)
186
+ end
187
+ end
188
+ def method_missing(name, *args)
189
+ name = name.to_s
190
+ if (name[0,2] == "mv")
191
+ test_name = name.dup
192
+ test_name[2,0] = "w" # insert "w" after"mv"
193
+ if (FFI::NCurses.respond_to?(test_name))
194
+ return FFI::NCurses.send(test_name, @pointer, *args)
195
+ end
196
+ end
197
+ test_name = "w" + name
198
+ if (FFI::NCurses.respond_to?(test_name))
199
+ return FFI::NCurses.send(test_name, @pointer, *args)
200
+ end
201
+ FFI::NCurses.send(name, @pointer, *args)
202
+ end
203
+ def respond_to?(name)
204
+ name = name.to_s
205
+ if (name[0,2] == "mv" && FFI::NCurses.respond_to?("mvw" + name[2..-1]))
206
+ return true
207
+ end
208
+ FFI::NCurses.respond_to?("w" + name) || FFI::NCurses.respond_to?(name)
209
+ end
210
+ def del
211
+ FFI::NCurses.delwin(@pointer)
212
+ end
213
+ alias delete del
214
+ end
215
+ # if ffi-ncurses returns a pointer wrap it.
216
+ # or we can check for whether it responds_to? refresh and getch
217
+ def self.initscr
218
+ #@stdscr = Ncurses::FFIWINDOW.new(FFI::NCurses.initscr) { }
219
+ stdscr = FFI::NCurses.initscr
220
+ if stdscr.is_a? FFI::Pointer
221
+ @stdscr = Ncurses::FFIWINDOW.new(stdscr) { }
222
+ else
223
+ @stdscr = stdscr
224
+ end
225
+ end
226
+ def self.stdscr
227
+ @stdscr
228
+ end
229
+ # commented off on 2011-09-15 FFIWINDOW results in errors
230
+ # class << self
231
+ # def method_missing(method, *args, &block)
232
+ # FFI::NCurses.send(method, *args, &block)
233
+ # end
234
+ # end
235
+ # ---
236
+ end
@@ -0,0 +1,162 @@
1
+ require "ffi-ncurses"
2
+ module Ncurses # changed on 2011-09-8
3
+ # making minimal changes as per ffi-ncurses 0.4.0 which implements panels
4
+ #module VER # too many places call Ncurses::Panel
5
+ class Panel #< Struct.new(:pointer)
6
+ # extend FFI::Library
7
+ #
8
+ # # use RUBY_FFI_NCURSES_LIB to specify exactly which lib you want, e.g.
9
+ # # ncursesw, XCurses (from PDCurses)
10
+ # if ENV["RUBY_FFI_PANEL_LIB"].to_s != ""
11
+ # LIB_HANDLE = ffi_lib( ENV["RUBY_FFI_PANEL_LIB"] ).first
12
+ # else
13
+ # # next works but not when ENV, maybe since 'panel' not in code above
14
+ # LIB_HANDLE = ffi_lib( 'panel', '/opt/local/lib/libpanelw.5.dylib' ).first
15
+ # #LIB_HANDLE = ffi_lib( 'panel', 'libpanel' ).first # this also works
16
+ # end
17
+ #
18
+ # functions = [
19
+ # [:new_panel, [:pointer], :pointer],
20
+ # [:bottom_panel, [:pointer], :int],
21
+ # [:top_panel, [:pointer], :int],
22
+ # [:show_panel, [:pointer], :int],
23
+ # [:update_panels, [], :void],
24
+ # [:hide_panel, [:pointer], :int],
25
+ # [:panel_window, [:pointer], :pointer],
26
+ # [:replace_panel, [:pointer, :pointer], :int],
27
+ # [:move_panel, [:pointer, :int, :int], :int],
28
+ # [:panel_hidden, [:pointer], :int],
29
+ # [:panel_above, [:pointer], :pointer],
30
+ # [:panel_below, [:pointer], :pointer],
31
+ # [:set_panel_userptr, [:pointer, :pointer], :int],
32
+ # [:panel_userptr, [:pointer], :pointer],
33
+ # [:del_panel, [:pointer], :int],
34
+ # ]
35
+ #
36
+ # functions.each do |function|
37
+ # attach_function(*function)
38
+ # end
39
+
40
+ def initialize(window)
41
+ if window.respond_to?(:pointer)
42
+ @pointer = FFI::NCurses.new_panel(window.pointer)
43
+ else
44
+ @pointer = FFI::NCurses.new_panel(window)
45
+ end
46
+ end
47
+ def pointer
48
+ @pointer
49
+ end
50
+
51
+ # Puts panel below all other panels.
52
+ def bottom_panel
53
+ FFI::NCurses.bottom_panel(@pointer)
54
+ end
55
+ alias bottom bottom_panel
56
+
57
+ # Put the visible panel on top of all other panels in the stack.
58
+ #
59
+ # To ensure compatibility across platforms, use this method instead of
60
+ # {show_panel} when the panel is shown.
61
+ def top_panel
62
+ FFI::NCurses.top_panel(@pointer)
63
+ end
64
+ alias top top_panel
65
+
66
+ # Makes hidden panel visible by placing it on the top of the stack.
67
+ #
68
+ # To ensure compatibility across platforms, use this method instead of
69
+ # {top_panel} when the panel is hidden.
70
+ def show_panel
71
+ FFI::NCurses.show_panel(@pointer)
72
+ end
73
+ alias show show_panel
74
+
75
+ # Removes the given panel from the panel stack and thus hides it from
76
+ # view.
77
+ # The PANEL structure is not lost, merely removed from the stack.
78
+ def hide_panel
79
+ FFI::NCurses.hide_panel(@pointer)
80
+ end
81
+ alias hide hide_panel
82
+
83
+ # Returns a pointer to the window of the given panel.
84
+ def panel_window
85
+ FFI::NCurses.panel_window(@pointer)
86
+ end
87
+ alias window panel_window
88
+
89
+ # Replace the window of the panel with the given window.
90
+ # Useful, for example, if you want to resize a panel.
91
+ # You can call {replace_panel} on the output of {wresize}.
92
+ # It does not change the position of the panel in the stack.
93
+ def replace_panel(window)
94
+ FFI::NCurses.replace_panel(@pointer, window)
95
+ end
96
+ alias replace replace_panel
97
+
98
+ # Move the panel window so that its upper-left corner is at
99
+ # (+starty+,+startx+).
100
+ # It does not change the position of the panel in the stack.
101
+ # Be sure to use this method instead of {mvwin}, to move a panel window.
102
+ def move_panel(starty = 0, startx = 0)
103
+ FFI::NCurses.move_panel(@pointer, starty, startx)
104
+ end
105
+ alias move move_panel
106
+
107
+ # Returns true if the panel is in the panel stack, false if not.
108
+ # Returns ERR if the panel pointer is a null pointer.
109
+ def panel_hidden
110
+ FFI::NCurses.panel_hidden(@pointer) == 0
111
+ end
112
+ alias hidden? panel_hidden
113
+
114
+ # Returns pointer to the panel above.
115
+ def panel_above
116
+ FFI::NCurses.panel_above(@pointer)
117
+ end
118
+ alias above panel_above
119
+
120
+ # Return a pointer to the panel just below panel.
121
+ # If the panel argument is a pointer to 0, it returns a pointer to the
122
+ # top panel in the stack.
123
+ def panel_below
124
+ FFI::NCurses.panel_below(@pointer)
125
+ end
126
+ alias below panel_below
127
+
128
+ # Returns the user pointer for a given panel.
129
+ def panel_userptr
130
+ FFI::NCurses.panel_userptr(@pointer)
131
+ end
132
+ alias userptr panel_userptr
133
+
134
+ # sets the panel's user pointer.
135
+ def set_panel_userptr(user_pointer)
136
+ FFI::NCurses.set_panel_userptr(@pointer, user_pointer)
137
+ end
138
+ alias userptr= set_panel_userptr
139
+
140
+ # Remove the panel from the stack and deallocate the PANEL structure.
141
+ # Doesn't remove the associated window.
142
+ def del_panel
143
+ FFI::NCurses.del_panel(@pointer)
144
+ end
145
+ alias del del_panel
146
+ alias delete del_panel
147
+
148
+ class << self
149
+ # these will be used when you say Ncurses::Panel.del_panel(@panel.pointer)
150
+ # You could directly say FFI:NCurses or even @panel.del_panel.
151
+ def update_panels
152
+ FFI::NCurses.update_panels
153
+ end
154
+ def method_missing(name, *args)
155
+ if (FFI::NCurses.respond_to?(name))
156
+ return FFI::NCurses.send(name, *args)
157
+ end
158
+ raise "Panel did not respond_to #{name} "
159
+ end
160
+ end
161
+ end
162
+ end