rbhex-core 1.0.0

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