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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/CHANGELOG +2000 -0
- data/LICENSE +56 -0
- data/README.md +44 -0
- data/examples/abasiclist.rb +179 -0
- data/examples/alpmenu.rb +50 -0
- data/examples/app.sample +19 -0
- data/examples/atree.rb +100 -0
- data/examples/bline.rb +136 -0
- data/examples/common/file.rb +45 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +60 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +10 -0
- data/examples/data/todo.txt.bak +10 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +502 -0
- data/examples/dirtree.rb +94 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +146 -0
- data/examples/tasks.rb +178 -0
- data/examples/term2.rb +84 -0
- data/examples/testbuttons.rb +296 -0
- data/examples/testcombo.rb +102 -0
- data/examples/testfields.rb +195 -0
- data/examples/testkeypress.rb +72 -0
- data/examples/testlistbox.rb +170 -0
- data/examples/testmessagebox.rb +140 -0
- data/examples/testprogress.rb +116 -0
- data/examples/testree.rb +106 -0
- data/examples/testwsshortcuts.rb +66 -0
- data/examples/testwsshortcuts2.rb +128 -0
- data/lib/rbhex.rb +6 -0
- data/lib/rbhex/core/docs/index.txt +73 -0
- data/lib/rbhex/core/include/action.rb +80 -0
- data/lib/rbhex/core/include/actionmanager.rb +49 -0
- data/lib/rbhex/core/include/appmethods.rb +214 -0
- data/lib/rbhex/core/include/bordertitle.rb +48 -0
- data/lib/rbhex/core/include/chunk.rb +203 -0
- data/lib/rbhex/core/include/io.rb +553 -0
- data/lib/rbhex/core/include/listbindings.rb +74 -0
- data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
- data/lib/rbhex/core/include/listeditable.rb +317 -0
- data/lib/rbhex/core/include/listscrollable.rb +663 -0
- data/lib/rbhex/core/include/listselectable.rb +271 -0
- data/lib/rbhex/core/include/multibuffer.rb +83 -0
- data/lib/rbhex/core/include/orderedhash.rb +77 -0
- data/lib/rbhex/core/include/ractionevent.rb +73 -0
- data/lib/rbhex/core/include/rchangeevent.rb +27 -0
- data/lib/rbhex/core/include/rhistory.rb +95 -0
- data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
- data/lib/rbhex/core/include/vieditable.rb +172 -0
- data/lib/rbhex/core/include/widgetmenu.rb +66 -0
- data/lib/rbhex/core/system/colormap.rb +165 -0
- data/lib/rbhex/core/system/keyboard.rb +150 -0
- data/lib/rbhex/core/system/keydefs.rb +30 -0
- data/lib/rbhex/core/system/ncurses.rb +236 -0
- data/lib/rbhex/core/system/panel.rb +162 -0
- data/lib/rbhex/core/system/window.rb +913 -0
- data/lib/rbhex/core/util/ansiparser.rb +119 -0
- data/lib/rbhex/core/util/app.rb +1228 -0
- data/lib/rbhex/core/util/basestack.rb +410 -0
- data/lib/rbhex/core/util/bottomline.rb +1859 -0
- data/lib/rbhex/core/util/colorparser.rb +77 -0
- data/lib/rbhex/core/util/focusmanager.rb +31 -0
- data/lib/rbhex/core/util/padreader.rb +192 -0
- data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
- data/lib/rbhex/core/util/rdialogs.rb +574 -0
- data/lib/rbhex/core/util/viewer.rb +149 -0
- data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
- data/lib/rbhex/core/version.rb +5 -0
- data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
- data/lib/rbhex/core/widgets/box.rb +58 -0
- data/lib/rbhex/core/widgets/divider.rb +310 -0
- data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
- data/lib/rbhex/core/widgets/rcombo.rb +253 -0
- data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
- data/lib/rbhex/core/widgets/rlink.rb +30 -0
- data/lib/rbhex/core/widgets/rlist.rb +696 -0
- data/lib/rbhex/core/widgets/rmenu.rb +958 -0
- data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
- data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
- data/lib/rbhex/core/widgets/rprogress.rb +118 -0
- data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
- data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
- data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
- data/lib/rbhex/core/widgets/rtextview.rb +739 -0
- data/lib/rbhex/core/widgets/rtree.rb +768 -0
- data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
- data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
- data/lib/rbhex/core/widgets/statusline.rb +113 -0
- data/lib/rbhex/core/widgets/tabular.rb +264 -0
- data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
- data/lib/rbhex/core/widgets/textpad.rb +995 -0
- data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
- data/rbhex-core.gemspec +32 -0
- 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
|