rbcurse-core 0.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 (94) hide show
  1. data/README.md +69 -0
  2. data/VERSION +1 -0
  3. data/examples/abasiclist.rb +151 -0
  4. data/examples/alpmenu.rb +46 -0
  5. data/examples/app.sample +17 -0
  6. data/examples/atree.rb +100 -0
  7. data/examples/common/file.rb +45 -0
  8. data/examples/data/README.markdown +9 -0
  9. data/examples/data/brew.txt +38 -0
  10. data/examples/data/color.2 +37 -0
  11. data/examples/data/gemlist.txt +60 -0
  12. data/examples/data/lotr.txt +12 -0
  13. data/examples/data/ports.txt +136 -0
  14. data/examples/data/table.txt +37 -0
  15. data/examples/data/tasks.csv +88 -0
  16. data/examples/data/tasks.txt +27 -0
  17. data/examples/data/todo.txt +10 -0
  18. data/examples/data/todocsv.csv +28 -0
  19. data/examples/data/unix1.txt +21 -0
  20. data/examples/data/unix2.txt +11 -0
  21. data/examples/dbdemo.rb +487 -0
  22. data/examples/dirtree.rb +90 -0
  23. data/examples/newtabbedwindow.rb +100 -0
  24. data/examples/newtesttabp.rb +92 -0
  25. data/examples/tabular.rb +132 -0
  26. data/examples/tasks.rb +167 -0
  27. data/examples/term2.rb +83 -0
  28. data/examples/testkeypress.rb +72 -0
  29. data/examples/testlistbox.rb +158 -0
  30. data/examples/testmessagebox.rb +140 -0
  31. data/examples/testree.rb +106 -0
  32. data/examples/testwsshortcuts.rb +66 -0
  33. data/examples/testwsshortcuts2.rb +127 -0
  34. data/lib/rbcurse.rb +8 -0
  35. data/lib/rbcurse/core/docs/index.txt +73 -0
  36. data/lib/rbcurse/core/include/action.rb +40 -0
  37. data/lib/rbcurse/core/include/appmethods.rb +112 -0
  38. data/lib/rbcurse/core/include/bordertitle.rb +41 -0
  39. data/lib/rbcurse/core/include/chunk.rb +182 -0
  40. data/lib/rbcurse/core/include/io.rb +953 -0
  41. data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
  42. data/lib/rbcurse/core/include/listeditable.rb +317 -0
  43. data/lib/rbcurse/core/include/listscrollable.rb +590 -0
  44. data/lib/rbcurse/core/include/listselectable.rb +264 -0
  45. data/lib/rbcurse/core/include/multibuffer.rb +83 -0
  46. data/lib/rbcurse/core/include/orderedhash.rb +77 -0
  47. data/lib/rbcurse/core/include/ractionevent.rb +67 -0
  48. data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
  49. data/lib/rbcurse/core/include/rhistory.rb +62 -0
  50. data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
  51. data/lib/rbcurse/core/include/vieditable.rb +170 -0
  52. data/lib/rbcurse/core/system/colormap.rb +163 -0
  53. data/lib/rbcurse/core/system/keyboard.rb +150 -0
  54. data/lib/rbcurse/core/system/keydefs.rb +30 -0
  55. data/lib/rbcurse/core/system/ncurses.rb +218 -0
  56. data/lib/rbcurse/core/system/panel.rb +162 -0
  57. data/lib/rbcurse/core/system/window.rb +901 -0
  58. data/lib/rbcurse/core/util/ansiparser.rb +117 -0
  59. data/lib/rbcurse/core/util/app.rb +1235 -0
  60. data/lib/rbcurse/core/util/basestack.rb +407 -0
  61. data/lib/rbcurse/core/util/bottomline.rb +1850 -0
  62. data/lib/rbcurse/core/util/colorparser.rb +71 -0
  63. data/lib/rbcurse/core/util/focusmanager.rb +31 -0
  64. data/lib/rbcurse/core/util/padreader.rb +189 -0
  65. data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
  66. data/lib/rbcurse/core/util/rdialogs.rb +619 -0
  67. data/lib/rbcurse/core/util/viewer.rb +149 -0
  68. data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
  69. data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
  70. data/lib/rbcurse/core/widgets/box.rb +58 -0
  71. data/lib/rbcurse/core/widgets/divider.rb +310 -0
  72. data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
  73. data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
  74. data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
  75. data/lib/rbcurse/core/widgets/rlink.rb +30 -0
  76. data/lib/rbcurse/core/widgets/rlist.rb +723 -0
  77. data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
  78. data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
  79. data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
  80. data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
  81. data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
  82. data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
  83. data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
  84. data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
  85. data/lib/rbcurse/core/widgets/rtree.rb +787 -0
  86. data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
  87. data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
  88. data/lib/rbcurse/core/widgets/statusline.rb +94 -0
  89. data/lib/rbcurse/core/widgets/tabular.rb +264 -0
  90. data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
  91. data/lib/rbcurse/core/widgets/textpad.rb +516 -0
  92. data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
  93. data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
  94. metadata +156 -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,218 @@
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
+ # The initscr code determines the terminal type and initializes all curses
11
+ # data structures.
12
+ # initscr also causes the first call to refresh to clear the screen.
13
+ # If errors occur, initscr writes an appropriate error message to standard
14
+ # error and exits; otherwise, a pointer is returned to stdscr.
15
+ stdscr = Ncurses.initscr ## FFI
16
+
17
+ # Color.start if Ncurses.has_colors?
18
+ Ncurses.start_color();
19
+ ColorMap.setup # added by RK 2008-11-30 00:48
20
+ # The keypad option enables the keypad of the user's terminal.
21
+ # If enabled (bf is TRUE), the user can press a function key (such as an
22
+ # arrow key) and wgetch returns a single value representing the function
23
+ # key, as in KEY_LEFT.
24
+ # If disabled (bf is FALSE), curses does not treat function keys specially
25
+ # and the program has to interpret the escape sequences itself.
26
+ # If the keypad in the terminal can be turned on (made to transmit) and off
27
+ # (made to work locally), turning on this option causes the terminal keypad
28
+ # to be turned on when wgetch is called.
29
+ # The default value for keypad is false.
30
+ Ncurses.keypad(stdscr.pointer, bf = true) # FFIWINDOW
31
+ #Ncurses.keypad(stdscr, bf = true)
32
+ #Ncurses.stdscr.keypad(true) # turn on keypad mode FFI
33
+ #Ncurses.keypad(stdscr, bf = 1)
34
+
35
+ # The nl and nonl routines control whether the underlying display device
36
+ # translates the return key into newline on input, and whether it
37
+ # translates newline into return and line-feed on output (in either case,
38
+ # the call addch('\n') does the equivalent of return and line feed on the
39
+ # virtual screen).
40
+ # Initially, these translations do occur.
41
+ # If you disable them using nonl, curses will be able to make better use of
42
+ # the line-feed capability, resulting in faster cursor motion.
43
+ # Also, curses will then be able to detect the return key.
44
+ Ncurses.nonl
45
+
46
+ # The raw and noraw routines place the terminal into or out of raw mode.
47
+ # Raw mode is similar to cbreak mode, in that characters typed are
48
+ # immediately passed through to the user program.
49
+ # The differences are that in raw mode, the interrupt, quit, suspend, and
50
+ # flow control characters are all passed through uninterpreted, instead of
51
+ # generating a signal.
52
+ # The behavior of the BREAK key depends on other bits in the tty driver
53
+ # that are not set by curses.
54
+ Ncurses.raw
55
+
56
+ # Normally, the tty driver buffers typed characters until a newline or
57
+ # carriage return is typed.
58
+ # The cbreak routine disables line buffering and
59
+ # erase/kill character-processing (interrupt and flow control characters
60
+ # are unaffected), making characters typed by the user immediately
61
+ # available to the program.
62
+ Ncurses.cbreak
63
+
64
+ # The echo and noecho routines control whether characters typed by the user
65
+ # are echoed by getch as they are typed.
66
+ # Echoing by the tty driver is always disabled, but initially getch is in
67
+ # echo mode, so characters typed are echoed.
68
+ Ncurses.noecho
69
+
70
+ # The curs_set routine sets the cursor state is set to invisible, normal,
71
+ # or very visible for visibility equal to 0, 1, or 2 respectively.
72
+ # If the terminal supports the visibility requested, the previous cursor
73
+ # state is returned; otherwise, ERR is returned.
74
+ Ncurses.curs_set(1)
75
+
76
+ # The halfdelay routine is used for half-delay mode, which is similar to
77
+ # cbreak mode in that characters typed by the user are immediately
78
+ # available to the program.
79
+ # However, after blocking for tenths tenths of seconds, ERR is returned if
80
+ # nothing has been typed.
81
+ # The value of tenths must be a number between 1 and 255.
82
+ # Use nocbreak to leave half-delay mode.
83
+ Ncurses::halfdelay(tenths = 10)
84
+
85
+ # The nodelay option causes getch to be a non-blocking call. If no input is
86
+ # ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a
87
+ # key is pressed.
88
+ # Ncurses::nodelay(Ncurses::stdscr, bf = true)
89
+ end
90
+
91
+ # this should happen only in outermost program that started ncurses
92
+ # if a called program does this, the calling program can have a display freeze
93
+ def stop_ncurses
94
+ Ncurses.echo
95
+ Ncurses.nocbreak
96
+ Ncurses.nl
97
+ Ncurses.endwin
98
+ $ncurses_started = false
99
+ #puts "curses over"
100
+ ensure
101
+ return unless error = @last_error
102
+ log = Config[:logfile].value
103
+
104
+ Kernel.warn "There may have been fatal errors logged to: #{log}."
105
+ Kernel.warn "The most recent was:"
106
+
107
+ $stderr.puts ''
108
+ $stderr.puts @last_error_message if @last_error_message
109
+ $stderr.puts @last_error, *@last_error.backtrace
110
+ end
111
+ require 'rbcurse/core/system/colormap'
112
+ include ColorMap
113
+ end
114
+ module Ncurses
115
+ extend self
116
+ FALSE = 0
117
+ TRUE = 1
118
+ module NCX
119
+ def COLS
120
+ FFI::NCurses.getmaxx(FFI::NCurses.stdscr)
121
+ end
122
+ def LINES
123
+ # #FFI::NCurses.getmaxy(FFI::NCurses.stdscr)
124
+ FFI::NCurses.LINES
125
+ end
126
+ # # supposed to be picked up at runtime
127
+ def COLORS
128
+ FFI::NCurses.COLORS
129
+ end
130
+
131
+ # jsut trying this so i can do Ncurses.stdscr.getmax
132
+ def _stdscr
133
+ FFI::NCurses.stdscr
134
+ end
135
+ # this allows me to refer to them as Ncurses::A_REVERSE as is the case everywhere
136
+ A_REVERSE = FFI::NCurses::A_REVERSE
137
+ A_STANDOUT = FFI::NCurses::A_STANDOUT
138
+ A_BOLD = FFI::NCurses::A_BOLD
139
+ A_UNDERLINE = FFI::NCurses::A_UNDERLINE
140
+ A_BLINK = FFI::NCurses::A_BLINK
141
+ A_NORMAL = FFI::NCurses::A_NORMAL
142
+ KEY_F1 = FFI::NCurses::KEY_F1
143
+ end
144
+ include NCX
145
+ extend NCX
146
+ # i think we can knock this off
147
+ def method_missing meth, *args
148
+ if (FFI::NCurses.respond_to?(meth))
149
+ FFI::NCurses.send meth, *args
150
+ end
151
+ end
152
+ # FFINC.constants.each { |e| Ncurses.const_set(e, FFINC.const_get(e) ) }
153
+ def const_missing name
154
+ val = FFI::NCurses.const_get(name)
155
+ const_set(name, val)
156
+ return val
157
+ end
158
+
159
+ # This is a window pointer wrapper, to be used for stdscr and others.
160
+ # Ideally ffi-ncurses should do this, if it returns a pointer, I'll do this.
161
+ class FFIWINDOW
162
+ attr_accessor :pointer
163
+ def initialize(*args, &block)
164
+ if block_given?
165
+ @pointer = args.first
166
+ else
167
+ @pointer = FFI::NCurses.newwin(*args)
168
+ end
169
+ end
170
+ def method_missing(name, *args)
171
+ name = name.to_s
172
+ if (name[0,2] == "mv")
173
+ test_name = name.dup
174
+ test_name[2,0] = "w" # insert "w" after"mv"
175
+ if (FFI::NCurses.respond_to?(test_name))
176
+ return FFI::NCurses.send(test_name, @pointer, *args)
177
+ end
178
+ end
179
+ test_name = "w" + name
180
+ if (FFI::NCurses.respond_to?(test_name))
181
+ return FFI::NCurses.send(test_name, @pointer, *args)
182
+ end
183
+ FFI::NCurses.send(name, @pointer, *args)
184
+ end
185
+ def respond_to?(name)
186
+ name = name.to_s
187
+ if (name[0,2] == "mv" && FFI::NCurses.respond_to?("mvw" + name[2..-1]))
188
+ return true
189
+ end
190
+ FFI::NCurses.respond_to?("w" + name) || FFI::NCurses.respond_to?(name)
191
+ end
192
+ def del
193
+ FFI::NCurses.delwin(@pointer)
194
+ end
195
+ alias delete del
196
+ end
197
+ # if ffi-ncurses returns a pointer wrap it.
198
+ # or we can check for whether it responds_to? refresh and getch
199
+ def self.initscr
200
+ #@stdscr = Ncurses::FFIWINDOW.new(FFI::NCurses.initscr) { }
201
+ stdscr = FFI::NCurses.initscr
202
+ if stdscr.is_a? FFI::Pointer
203
+ @stdscr = Ncurses::FFIWINDOW.new(stdscr) { }
204
+ else
205
+ @stdscr = stdscr
206
+ end
207
+ end
208
+ def self.stdscr
209
+ @stdscr
210
+ end
211
+ # commented off on 2011-09-15 FFIWINDOW results in errors
212
+ # class << self
213
+ # def method_missing(method, *args, &block)
214
+ # FFI::NCurses.send(method, *args, &block)
215
+ # end
216
+ # end
217
+ # ---
218
+ 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