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.
- data/README.md +69 -0
- data/VERSION +1 -0
- data/examples/abasiclist.rb +151 -0
- data/examples/alpmenu.rb +46 -0
- data/examples/app.sample +17 -0
- data/examples/atree.rb +100 -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/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +487 -0
- data/examples/dirtree.rb +90 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +132 -0
- data/examples/tasks.rb +167 -0
- data/examples/term2.rb +83 -0
- data/examples/testkeypress.rb +72 -0
- data/examples/testlistbox.rb +158 -0
- data/examples/testmessagebox.rb +140 -0
- data/examples/testree.rb +106 -0
- data/examples/testwsshortcuts.rb +66 -0
- data/examples/testwsshortcuts2.rb +127 -0
- data/lib/rbcurse.rb +8 -0
- data/lib/rbcurse/core/docs/index.txt +73 -0
- data/lib/rbcurse/core/include/action.rb +40 -0
- data/lib/rbcurse/core/include/appmethods.rb +112 -0
- data/lib/rbcurse/core/include/bordertitle.rb +41 -0
- data/lib/rbcurse/core/include/chunk.rb +182 -0
- data/lib/rbcurse/core/include/io.rb +953 -0
- data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
- data/lib/rbcurse/core/include/listeditable.rb +317 -0
- data/lib/rbcurse/core/include/listscrollable.rb +590 -0
- data/lib/rbcurse/core/include/listselectable.rb +264 -0
- data/lib/rbcurse/core/include/multibuffer.rb +83 -0
- data/lib/rbcurse/core/include/orderedhash.rb +77 -0
- data/lib/rbcurse/core/include/ractionevent.rb +67 -0
- data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
- data/lib/rbcurse/core/include/rhistory.rb +62 -0
- data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
- data/lib/rbcurse/core/include/vieditable.rb +170 -0
- data/lib/rbcurse/core/system/colormap.rb +163 -0
- data/lib/rbcurse/core/system/keyboard.rb +150 -0
- data/lib/rbcurse/core/system/keydefs.rb +30 -0
- data/lib/rbcurse/core/system/ncurses.rb +218 -0
- data/lib/rbcurse/core/system/panel.rb +162 -0
- data/lib/rbcurse/core/system/window.rb +901 -0
- data/lib/rbcurse/core/util/ansiparser.rb +117 -0
- data/lib/rbcurse/core/util/app.rb +1235 -0
- data/lib/rbcurse/core/util/basestack.rb +407 -0
- data/lib/rbcurse/core/util/bottomline.rb +1850 -0
- data/lib/rbcurse/core/util/colorparser.rb +71 -0
- data/lib/rbcurse/core/util/focusmanager.rb +31 -0
- data/lib/rbcurse/core/util/padreader.rb +189 -0
- data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
- data/lib/rbcurse/core/util/rdialogs.rb +619 -0
- data/lib/rbcurse/core/util/viewer.rb +149 -0
- data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
- data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
- data/lib/rbcurse/core/widgets/box.rb +58 -0
- data/lib/rbcurse/core/widgets/divider.rb +310 -0
- data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
- data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
- data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
- data/lib/rbcurse/core/widgets/rlink.rb +30 -0
- data/lib/rbcurse/core/widgets/rlist.rb +723 -0
- data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
- data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
- data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
- data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
- data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
- data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
- data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
- data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
- data/lib/rbcurse/core/widgets/rtree.rb +787 -0
- data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
- data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
- data/lib/rbcurse/core/widgets/statusline.rb +94 -0
- data/lib/rbcurse/core/widgets/tabular.rb +264 -0
- data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
- data/lib/rbcurse/core/widgets/textpad.rb +516 -0
- data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
- metadata +156 -0
|
@@ -0,0 +1,901 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
|
2
|
+
# File: window.rb
|
|
3
|
+
# Description: A wrapper over window
|
|
4
|
+
# Author: rkumar http://github.com/rkumar/rbcurse/
|
|
5
|
+
# Date: Around for a long time
|
|
6
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
7
|
+
# Last update: use ,,L
|
|
8
|
+
#
|
|
9
|
+
# == CHANGED
|
|
10
|
+
# removed Pad and Subwin to lib/ver/rpad.rb - hopefully I've seen the last of both
|
|
11
|
+
#
|
|
12
|
+
# == TODO
|
|
13
|
+
# strip and remove cruft. Now that I've stopped using pad, can we remove
|
|
14
|
+
# the prv_printstring nonsense.
|
|
15
|
+
# ----------------------------------------------------------------------------- #
|
|
16
|
+
#
|
|
17
|
+
require 'rbcurse/core/system/ncurses'
|
|
18
|
+
require 'rbcurse/core/system/panel'
|
|
19
|
+
require 'rbcurse/core/include/chunk'
|
|
20
|
+
# this is since often windows are declared with 0 height or width and this causes
|
|
21
|
+
# crashes in the most unlikely places. This prevceents me from having to write ternary
|
|
22
|
+
# e.g.
|
|
23
|
+
# @layout[:width].ifzero(FFI::NCurses::LINES-2)
|
|
24
|
+
class Fixnum
|
|
25
|
+
def ifzero v
|
|
26
|
+
return self if self != 0
|
|
27
|
+
return v
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module VER
|
|
32
|
+
class Window
|
|
33
|
+
attr_reader :width, :height, :top, :left
|
|
34
|
+
attr_accessor :layout # hash containing hwtl
|
|
35
|
+
attr_reader :panel # reader requires so he can del it in end
|
|
36
|
+
attr_reader :window_type # window or pad to distinguish 2009-11-02 23:11
|
|
37
|
+
attr_accessor :name # more for debugging log files. 2010-02-02 19:58
|
|
38
|
+
attr_accessor :modified # has it been modified and may need a refresh
|
|
39
|
+
#attr_reader :bottomline # experimental here 2010-11-03 22:19
|
|
40
|
+
|
|
41
|
+
# @param [Array, Hash] window coordinates (ht, w, top, left)
|
|
42
|
+
# or
|
|
43
|
+
# @param [int, int, int, int] window coordinates (ht, w, top, left)
|
|
44
|
+
# 2011-09-21 allowing array, or 4 ints, in addition to hash @since 1.3.1
|
|
45
|
+
def initialize(*args)
|
|
46
|
+
|
|
47
|
+
case args.size
|
|
48
|
+
when 1
|
|
49
|
+
case args[0]
|
|
50
|
+
when Array, Hash
|
|
51
|
+
layout = args[0]
|
|
52
|
+
else
|
|
53
|
+
raise ArgumentError, "Window expects 4 ints, array of 4 ints, or Hash in constructor"
|
|
54
|
+
end
|
|
55
|
+
when 4
|
|
56
|
+
layout = { :height => args[0], :width => args[1], :top => args[2], :left => args[3] }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
@visible = true
|
|
60
|
+
reset_layout(layout)
|
|
61
|
+
|
|
62
|
+
#$log.debug "XXX:WINDOW got h #{@height}, w #{@width}, t #{@top}, l #{@left} "
|
|
63
|
+
|
|
64
|
+
@height = FFI::NCurses.LINES if @height == 0 # 2011-11-14 added since tired of checking for zero
|
|
65
|
+
@width = FFI::NCurses.COLS if @width == 0
|
|
66
|
+
|
|
67
|
+
@window = FFI::NCurses.newwin(@height, @width, @top, @left) # added FFI 2011-09-6
|
|
68
|
+
@panel = Ncurses::Panel.new(@window) # added FFI 2011-09-6
|
|
69
|
+
#$error_message_row = $status_message_row = Ncurses.LINES-1
|
|
70
|
+
$error_message_row ||= Ncurses.LINES-1
|
|
71
|
+
$error_message_col ||= 1 # ask (bottomline) uses 0 as default so you can have mismatch. XXX
|
|
72
|
+
$status_message ||= RubyCurses::Variable.new # in case not an App
|
|
73
|
+
init_vars
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
def init_vars
|
|
78
|
+
@window_type = :WINDOW
|
|
79
|
+
Ncurses::keypad(@window, true)
|
|
80
|
+
@stack = []
|
|
81
|
+
@name ||="#{self}"
|
|
82
|
+
@modified = true
|
|
83
|
+
$catch_alt_digits ||= false # is this where is should put globals ? 2010-03-14 14:00 XXX
|
|
84
|
+
end
|
|
85
|
+
##
|
|
86
|
+
# this is an alternative constructor
|
|
87
|
+
def self.root_window(layout = { :height => 0, :width => 0, :top => 0, :left => 0 })
|
|
88
|
+
#VER::start_ncurses
|
|
89
|
+
@layout = layout
|
|
90
|
+
@window = Window.new(@layout)
|
|
91
|
+
@window.name = "Window::ROOTW"
|
|
92
|
+
@window.wrefresh
|
|
93
|
+
Ncurses::Panel.update_panels
|
|
94
|
+
return @window
|
|
95
|
+
end
|
|
96
|
+
# 2009-10-13 12:24
|
|
97
|
+
# not used as yet
|
|
98
|
+
# this is an alternative constructor
|
|
99
|
+
# created if you don't want to create a hash first
|
|
100
|
+
# 2011-09-21 V1.3.1 You can now send an array to Window constructor
|
|
101
|
+
def self.create_window(h=0, w=0, t=0, l=0)
|
|
102
|
+
layout = { :height => h, :width => w, :top => t, :left => l }
|
|
103
|
+
@window = Window.new(layout)
|
|
104
|
+
return @window
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def resize_with(layout)
|
|
108
|
+
$log.debug " DARN ! This awready duz a resize!! if h or w or even top or left changed!!! XXX"
|
|
109
|
+
reset_layout(layout)
|
|
110
|
+
#@window.wresize(height, width)
|
|
111
|
+
wresize(height, width)
|
|
112
|
+
#FFI::NCurses.wresize(@window,height, width)
|
|
113
|
+
# this is dicey since we often change top and left in pads only for panning !! XXX
|
|
114
|
+
#@window.mvwin(top, left)
|
|
115
|
+
mvwin(top, left)
|
|
116
|
+
#FFI::NCurses.mvwin(@window, top, left)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
%w[width height top left].each do |side|
|
|
120
|
+
eval(
|
|
121
|
+
"def #{side}=(n)
|
|
122
|
+
return if n == #{side}
|
|
123
|
+
@layout[:#{side}] = n
|
|
124
|
+
resize_with @layout
|
|
125
|
+
end"
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
# ADDED DUE TO FFI
|
|
129
|
+
def wrefresh
|
|
130
|
+
Ncurses.wrefresh(@window)
|
|
131
|
+
end
|
|
132
|
+
def delwin # 2011-09-7
|
|
133
|
+
Ncurses.delwin(@window)
|
|
134
|
+
end
|
|
135
|
+
def attron *args
|
|
136
|
+
FFI::NCurses.wattron @window, *args
|
|
137
|
+
end
|
|
138
|
+
def attroff *args
|
|
139
|
+
FFI::NCurses.wattroff @window, *args
|
|
140
|
+
end
|
|
141
|
+
#
|
|
142
|
+
# ## END FFI
|
|
143
|
+
|
|
144
|
+
def resize
|
|
145
|
+
resize_with(@layout)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Ncurses
|
|
149
|
+
|
|
150
|
+
def pos
|
|
151
|
+
return y, x
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def y
|
|
155
|
+
Ncurses.getcury(@window)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def x
|
|
159
|
+
Ncurses.getcurx(@window)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def x=(n) move(y, n) end
|
|
163
|
+
def y=(n) move(n, x) end
|
|
164
|
+
|
|
165
|
+
#def move(y, x)
|
|
166
|
+
#return unless @visible
|
|
167
|
+
## Log.debug([y, x] => caller[0,4])
|
|
168
|
+
##@window.wmove(y, x) # bombing since ffi-ncurses 0.4.0 (maybe it was never called
|
|
169
|
+
##earlier. was crashing in appemail.rb testchoose.
|
|
170
|
+
#wmove y,x # can alias it
|
|
171
|
+
#end
|
|
172
|
+
# since include FFI is taking over, i need to force it here. not going into
|
|
173
|
+
# method_missing
|
|
174
|
+
def wmove y,x
|
|
175
|
+
#Ncurses.wmove @window, y, x
|
|
176
|
+
FFI::NCurses.wmove @window, y, x
|
|
177
|
+
end
|
|
178
|
+
alias :move :wmove
|
|
179
|
+
|
|
180
|
+
# while moving from ncurses-ruby to FFI need to pass window pointer
|
|
181
|
+
# for w methods as well as mvw - NOT COMING HERE due to include FFI
|
|
182
|
+
def OLDmethod_missing(meth, *args)
|
|
183
|
+
$log.debug " WWWW method missing #{meth} "
|
|
184
|
+
if meth[0,1]=="w" || meth[0,3] == "mvw"
|
|
185
|
+
$log.debug " WWWW method missing #{meth} adding window in call "
|
|
186
|
+
#return @window.send(meth, @window, *args)
|
|
187
|
+
return FFI::NCurses.send(meth, @window, *args)
|
|
188
|
+
else
|
|
189
|
+
end
|
|
190
|
+
if @window
|
|
191
|
+
if @window.respond_to? meth
|
|
192
|
+
@window.send(meth, *args)
|
|
193
|
+
else
|
|
194
|
+
FFI::NCurses.send( meth, *args)
|
|
195
|
+
end
|
|
196
|
+
else
|
|
197
|
+
FFI::NCurses.send( meth, *args)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def method_missing(name, *args)
|
|
202
|
+
name = name.to_s
|
|
203
|
+
if (name[0,2] == "mv")
|
|
204
|
+
test_name = name.dup
|
|
205
|
+
test_name[2,0] = "w" # insert "w" after"mv"
|
|
206
|
+
if (FFI::NCurses.respond_to?(test_name))
|
|
207
|
+
return FFI::NCurses.send(test_name, @window, *args)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
test_name = "w" + name
|
|
211
|
+
if (FFI::NCurses.respond_to?(test_name))
|
|
212
|
+
return FFI::NCurses.send(test_name, @window, *args)
|
|
213
|
+
end
|
|
214
|
+
FFI::NCurses.send(name, @window, *args)
|
|
215
|
+
end
|
|
216
|
+
def respond_to?(name)
|
|
217
|
+
name = name.to_s
|
|
218
|
+
if (name[0,2] == "mv" && FFI::NCurses.respond_to?("mvw" + name[2..-1]))
|
|
219
|
+
return true
|
|
220
|
+
end
|
|
221
|
+
FFI::NCurses.respond_to?("w" + name) || FFI::NCurses.respond_to?(name)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# NOTE: many of these methods using width will not work since root windows width
|
|
225
|
+
# is 0
|
|
226
|
+
def print(string, width = width)
|
|
227
|
+
return unless visible?
|
|
228
|
+
w = width == 0? Ncurses.COLS : width
|
|
229
|
+
waddnstr(string.to_s, w) # changed 2011 dts
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# NOTE: many of these methods using width will not work since root windows width
|
|
233
|
+
# is 0
|
|
234
|
+
def print_yx(string, y = 0, x = 0)
|
|
235
|
+
w = width == 0? Ncurses.COLS : width
|
|
236
|
+
mvwaddnstr(y, x, string, w) # changed 2011 dts
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# NOTE: many of these methods using width will not work since root windows width
|
|
240
|
+
# is 0
|
|
241
|
+
def print_empty_line
|
|
242
|
+
return unless visible?
|
|
243
|
+
w = width == 0? Ncurses.COLS : width
|
|
244
|
+
printw(' ' * w)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# NOTE: many of these methods using width will not work since root windows width
|
|
248
|
+
# is 0
|
|
249
|
+
def print_line(string)
|
|
250
|
+
w = width == 0? Ncurses.COLS : width
|
|
251
|
+
print(string.ljust(w))
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# returns the actual width in case you've used a root window
|
|
255
|
+
# which returns a 0 for wid and ht
|
|
256
|
+
#
|
|
257
|
+
def actual_width
|
|
258
|
+
width == 0? Ncurses.COLS : width
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
#
|
|
262
|
+
# returns the actual ht in case you've used a root window
|
|
263
|
+
# which returns a 0 for wid and ht
|
|
264
|
+
#
|
|
265
|
+
def actual_height
|
|
266
|
+
height == 0? Ncurses.LINES : height
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# NOTE: many of these methods using width will not work since root windows width
|
|
270
|
+
# is 0
|
|
271
|
+
# Previously this printed a chunk as a full line, I've modified it to print on
|
|
272
|
+
# one line. This can be used for running text.
|
|
273
|
+
def show_colored_chunks(chunks, defcolor = nil, defattr = nil)
|
|
274
|
+
return unless visible?
|
|
275
|
+
chunks.each do |chunk| #|color, chunk, attrib|
|
|
276
|
+
case chunk
|
|
277
|
+
when Chunks::Chunk
|
|
278
|
+
color = chunk.color
|
|
279
|
+
attrib = chunk.attrib
|
|
280
|
+
text = chunk.text
|
|
281
|
+
when Array
|
|
282
|
+
# for earlier demos that used an array
|
|
283
|
+
color = chunk[0]
|
|
284
|
+
attrib = chunk[2]
|
|
285
|
+
text = chunk[1]
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
color ||= defcolor
|
|
289
|
+
attrib ||= defattr
|
|
290
|
+
|
|
291
|
+
cc, bg = ColorMap.get_colors_for_pair color
|
|
292
|
+
$log.debug "XXX: CHUNK window #{text}, cp #{color} , attrib #{attrib}. #{cc}, #{bg} "
|
|
293
|
+
color_set(color,nil) if color
|
|
294
|
+
wattron(attrib) if attrib
|
|
295
|
+
print(text)
|
|
296
|
+
wattroff(attrib) if attrib
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def puts(*strings)
|
|
301
|
+
print(strings.join("\n") << "\n")
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def _refresh
|
|
305
|
+
return unless visible?
|
|
306
|
+
@window.refresh
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def wnoutrefresh
|
|
310
|
+
return unless visible?
|
|
311
|
+
@window.wnoutrefresh
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def color=(color)
|
|
315
|
+
@color = color
|
|
316
|
+
@window.color_set(color, nil)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def highlight_line(color, y, x, max)
|
|
320
|
+
@window.mvchgat(y, x, max, Ncurses::A_NORMAL, color, nil)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def ungetch(ch)
|
|
324
|
+
Ncurses.ungetch(ch)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def getch
|
|
328
|
+
#c = @window.getch
|
|
329
|
+
c = Ncurses.getch
|
|
330
|
+
#if c == Ncurses::KEY_RESIZE
|
|
331
|
+
|
|
332
|
+
rescue Interrupt => ex
|
|
333
|
+
3 # is C-c
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# 2011-09-23 @since 1.3.1
|
|
337
|
+
# Added more combinations here. These 2 are just indicative
|
|
338
|
+
SPECIAL_KEYS = {
|
|
339
|
+
[27, 79, 50, 81] => 20014, # 'F14',
|
|
340
|
+
[27, 79, 50, 82] => 20015 # 'F15',
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
# returns control, alt, alt+ctrl, alt+control+shift, F1 .. etc
|
|
344
|
+
# ALT combinations also send a 27 before the actual key
|
|
345
|
+
# Please test with above combinations before using on your terminal
|
|
346
|
+
# added by rkumar 2008-12-12 23:07
|
|
347
|
+
# 2011-09-23 Redone Control-left, right, and Shift-F5..F10.
|
|
348
|
+
# Checking for quick press of Alt-Sh-O followed by Alt or printable char
|
|
349
|
+
# Checking for quick press of Alt-[ followed by Alt or printable char
|
|
350
|
+
# I attempted keeping a hash of combination arrays but it fails in the above
|
|
351
|
+
# 2 cases, so abandoned.
|
|
352
|
+
def getchar
|
|
353
|
+
while 1
|
|
354
|
+
ch = getch
|
|
355
|
+
$log.debug "window getchar() GOT: #{ch}" if ch != -1
|
|
356
|
+
sf = @stack.first
|
|
357
|
+
if ch == -1
|
|
358
|
+
# the returns escape 27 if no key followed it, so its SLOW if you want only esc
|
|
359
|
+
if @stack.first == 27
|
|
360
|
+
#$log.debug " -1 stack sizze #{@stack.size}: #{@stack.inspect}, ch #{ch}"
|
|
361
|
+
case @stack.size
|
|
362
|
+
when 1
|
|
363
|
+
@stack.clear
|
|
364
|
+
return 27
|
|
365
|
+
when 2 # basically a ALT-O, or alt-[ (79 or 91) this will be really slow since it waits for -1
|
|
366
|
+
ch = 128 + @stack.last
|
|
367
|
+
$log.warn "XXX: WARN #{ch} CLEARING stack #{@stack} "
|
|
368
|
+
@stack.clear
|
|
369
|
+
return ch
|
|
370
|
+
else
|
|
371
|
+
# check up a hash of special keys
|
|
372
|
+
ret = SPECIAL_KEYS(@stack)
|
|
373
|
+
return ret if ret
|
|
374
|
+
$log.warn "INVALID UNKNOWN KEY: SHOULD NOT COME HERE getchar():#{@stack}"
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
# possibly a 49 left over from M3-1
|
|
378
|
+
unless @stack.empty?
|
|
379
|
+
if @stack.size == 1
|
|
380
|
+
@stack.clear
|
|
381
|
+
return sf
|
|
382
|
+
end
|
|
383
|
+
$log.warn "something on stack getchar(): #{@stack} "
|
|
384
|
+
end
|
|
385
|
+
# comemnt after testing keys since this will be called a lot, even stack.clear is called a lot
|
|
386
|
+
$log.warn "ERROR CLEARING STACK WITH STUFF ON IT getchar():#{@stack}" if ($log.debug? && !@stack.empty?)
|
|
387
|
+
@stack.clear
|
|
388
|
+
next
|
|
389
|
+
end # -1
|
|
390
|
+
# this is the ALT combination
|
|
391
|
+
if @stack.first == 27
|
|
392
|
+
# experimental. 2 escapes in quick succession to make exit faster
|
|
393
|
+
if @stack.size == 1 && ch == 27
|
|
394
|
+
@stack.clear
|
|
395
|
+
return ch
|
|
396
|
+
end
|
|
397
|
+
# possible F1..F3 on xterm-color
|
|
398
|
+
if ch == 79 || ch == 91
|
|
399
|
+
#$log.debug " got 27, #{ch}, waiting for one more"
|
|
400
|
+
@stack << ch
|
|
401
|
+
next
|
|
402
|
+
end
|
|
403
|
+
#$log.debug "stack SIZE #{@stack.size}, #{@stack.inspect}, ch: #{ch}"
|
|
404
|
+
if @stack == [27,79]
|
|
405
|
+
# xterm-color
|
|
406
|
+
case ch
|
|
407
|
+
when 80
|
|
408
|
+
ch = FFI::NCurses::KEY_F1
|
|
409
|
+
when 81
|
|
410
|
+
ch = FFI::NCurses::KEY_F2
|
|
411
|
+
when 82
|
|
412
|
+
ch = FFI::NCurses::KEY_F3
|
|
413
|
+
when 83
|
|
414
|
+
ch = FFI::NCurses::KEY_F4
|
|
415
|
+
#when 27 # another alt-char following Alt-Sh-O
|
|
416
|
+
else
|
|
417
|
+
## iterm2 uses these for HOME END num keyboard keys
|
|
418
|
+
@stack.clear
|
|
419
|
+
#@stack << ch # earlier we pushed this but it could be of use
|
|
420
|
+
#return 128 + 79
|
|
421
|
+
return 128 + 79 + ch
|
|
422
|
+
|
|
423
|
+
end
|
|
424
|
+
@stack.clear
|
|
425
|
+
return ch
|
|
426
|
+
elsif @stack == [27, 91]
|
|
427
|
+
# XXX 27, 91 also is Alt-[
|
|
428
|
+
if ch == 90
|
|
429
|
+
@stack.clear
|
|
430
|
+
return KEY_BTAB # backtab
|
|
431
|
+
elsif ch == 53 || ch == 50 || ch == 51
|
|
432
|
+
# control left, right and shift function
|
|
433
|
+
@stack << ch
|
|
434
|
+
next
|
|
435
|
+
elsif ch == 27 # another alt-char immediately after Alt-[
|
|
436
|
+
$log.debug "getchar in 27, will return 128+91 " if $log.debug?
|
|
437
|
+
@stack.clear
|
|
438
|
+
@stack << ch
|
|
439
|
+
return 128 + 91
|
|
440
|
+
else
|
|
441
|
+
$log.debug "getchar in other, will return 128+91: #{ch} " if $log.debug?
|
|
442
|
+
# other cases Alt-[ followed by some char or key - merge with previous
|
|
443
|
+
@stack.clear
|
|
444
|
+
@stack << ch
|
|
445
|
+
return 128 + 91
|
|
446
|
+
end
|
|
447
|
+
elsif @stack == [27, 91, 53]
|
|
448
|
+
if ch == 68
|
|
449
|
+
@stack.clear
|
|
450
|
+
return C_LEFT # control-left
|
|
451
|
+
elsif ch == 67
|
|
452
|
+
@stack.clear
|
|
453
|
+
return C_RIGHT # -control-rt
|
|
454
|
+
end
|
|
455
|
+
elsif @stack == [27, 91, 51]
|
|
456
|
+
if ch == 49 && getch()== 126
|
|
457
|
+
@stack.clear
|
|
458
|
+
return 20009 # sh_f9
|
|
459
|
+
end
|
|
460
|
+
elsif @stack == [27, 91, 50]
|
|
461
|
+
if ch == 50 && getch()== 126
|
|
462
|
+
@stack.clear
|
|
463
|
+
return 20010 # sh-F10
|
|
464
|
+
end
|
|
465
|
+
if ch == 57 && getch()== 126
|
|
466
|
+
@stack.clear
|
|
467
|
+
return 20008 # sh-F8
|
|
468
|
+
elsif ch == 56 && getch()== 126
|
|
469
|
+
@stack.clear
|
|
470
|
+
return 20007 # sh-F7
|
|
471
|
+
elsif ch == 54 && getch()== 126
|
|
472
|
+
@stack.clear
|
|
473
|
+
return 20006 # sh-F6
|
|
474
|
+
elsif ch == 53 && getch()== 126
|
|
475
|
+
@stack.clear
|
|
476
|
+
return 20005 # sh-F5
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
# the usual Meta combos. (alt) - this is screwing it up, just return it in some way
|
|
480
|
+
ch = 128 + ch
|
|
481
|
+
@stack.clear
|
|
482
|
+
return ch
|
|
483
|
+
end # stack.first == 27
|
|
484
|
+
# append a 27 to stack, actually one can use a flag too
|
|
485
|
+
if ch == 27
|
|
486
|
+
@stack << 27
|
|
487
|
+
next
|
|
488
|
+
end
|
|
489
|
+
return ch
|
|
490
|
+
end # while
|
|
491
|
+
end # def
|
|
492
|
+
|
|
493
|
+
# doesn't seem to work, clears first line, not both
|
|
494
|
+
def clear
|
|
495
|
+
# return unless visible?
|
|
496
|
+
move 0, 0
|
|
497
|
+
puts *Array.new(height){ ' ' * (width - 1) }
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
# setup and reset
|
|
501
|
+
|
|
502
|
+
## allow user to send an array
|
|
503
|
+
# I am tired of the hash layout (taken from ver).
|
|
504
|
+
def reset_layout(layout)
|
|
505
|
+
case layout
|
|
506
|
+
when Array
|
|
507
|
+
$log.error "NIL in window constructor" if layout.include? nil
|
|
508
|
+
raise ArgumentError, "Nil in window constructor" if layout.include? nil
|
|
509
|
+
@height, @width, @top, @left = *layout
|
|
510
|
+
raise ArgumentError, "Nil in window constructor" if @top.nil? || @left.nil?
|
|
511
|
+
|
|
512
|
+
@layout = { :height => @height, :width => @width, :top => @top, :left => @top }
|
|
513
|
+
when Hash
|
|
514
|
+
@layout = layout
|
|
515
|
+
|
|
516
|
+
[:height, :width, :top, :left].each do |name|
|
|
517
|
+
instance_variable_set("@#{name}", layout_value(name))
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
# removed ref to default_for since giving error in FFI 2011-09-8
|
|
523
|
+
def layout_value(name)
|
|
524
|
+
value = @layout[name]
|
|
525
|
+
default = default_for(name)
|
|
526
|
+
|
|
527
|
+
value = value.call(default) if value.respond_to?(:call)
|
|
528
|
+
return (value || default).to_i
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# this gives error since stdscr is only a pointer at this time
|
|
532
|
+
def default_for(name)
|
|
533
|
+
case name
|
|
534
|
+
when :height, :top
|
|
535
|
+
#Ncurses.stdscr.getmaxy(stdscr)
|
|
536
|
+
FFI::NCurses.LINES
|
|
537
|
+
when :width, :left
|
|
538
|
+
#Ncurses.stdscr.getmaxx(stdscr)
|
|
539
|
+
FFI::NCurses.COLS
|
|
540
|
+
else
|
|
541
|
+
0
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
# Ncurses panel
|
|
546
|
+
|
|
547
|
+
def hide
|
|
548
|
+
#return unless visible? # added 2011-10-14 these 2 are not behaving properly
|
|
549
|
+
Ncurses::Panel.hide_panel @panel.pointer
|
|
550
|
+
#Ncurses.refresh # wnoutrefresh
|
|
551
|
+
Ncurses::Panel.update_panels # added so below window does not need to do this 2011-10-1
|
|
552
|
+
@visible = false
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def show
|
|
556
|
+
#return if visible? # added 2011-10-14 these 2 are not behaving properly
|
|
557
|
+
Ncurses::Panel.show_panel @panel.pointer
|
|
558
|
+
#Ncurses.refresh # wnoutrefresh
|
|
559
|
+
Ncurses::Panel.update_panels # added so below window does not need to do this 2011-10-1
|
|
560
|
+
@visible = true
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
def on_top
|
|
564
|
+
Ncurses::Panel.top_panel @panel.pointer
|
|
565
|
+
wnoutrefresh
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
def visible?
|
|
569
|
+
@visible
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
##
|
|
573
|
+
# destroy window, panel and any pads that were requested
|
|
574
|
+
#
|
|
575
|
+
def destroy
|
|
576
|
+
# typically the ensure block should have this
|
|
577
|
+
|
|
578
|
+
$log.debug "win destroy start"
|
|
579
|
+
|
|
580
|
+
Ncurses::Panel.del_panel(@panel.pointer) if @panel
|
|
581
|
+
delwin() if @window
|
|
582
|
+
Ncurses::Panel.update_panels # added so below window does not need to do this 2011-10-1
|
|
583
|
+
|
|
584
|
+
# destroy any pads that were created by widgets using get_pad
|
|
585
|
+
@pads.each { |pad|
|
|
586
|
+
FFI::NCurses.delwin(pad) if pad
|
|
587
|
+
pad = nil
|
|
588
|
+
} if @pads
|
|
589
|
+
$log.debug "win destroy end"
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
#
|
|
593
|
+
# 2011-11-13 since 1.4.1
|
|
594
|
+
# Widgets can get window to create a pad for them. This way when the window
|
|
595
|
+
# is destroyed, it will delete all the pads. A widget wold not be able to do this.
|
|
596
|
+
# The destroy method of the widget will be called.
|
|
597
|
+
def get_pad content_row, content_cols
|
|
598
|
+
pad = FFI::NCurses.newpad(content_rows, content_cols)
|
|
599
|
+
@pads ||= []
|
|
600
|
+
@pads << pad
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
#
|
|
604
|
+
# Allows user to send data as normal string or chunks for printing
|
|
605
|
+
# An array is assumed to be a chunk containing color and attrib info
|
|
606
|
+
#
|
|
607
|
+
def printstring_or_chunks(r,c,content, color, att = Ncurses::A_NORMAL)
|
|
608
|
+
if content.is_a? String
|
|
609
|
+
printstring(r,c,content, color, att)
|
|
610
|
+
elsif content.is_a? Chunks::ChunkLine
|
|
611
|
+
$log.debug "XXX: using chunkline"
|
|
612
|
+
wmove r, c
|
|
613
|
+
a = get_attrib att
|
|
614
|
+
show_colored_chunks content, color, a
|
|
615
|
+
elsif content.is_a? Array
|
|
616
|
+
# several chunks in one row - NOTE Very experimental may change
|
|
617
|
+
if content[0].is_a? Array
|
|
618
|
+
$log.warn "XXX: WARNING outdated should send in a chunkline"
|
|
619
|
+
wmove r, c
|
|
620
|
+
a = get_attrib att
|
|
621
|
+
show_colored_chunks content, color, a
|
|
622
|
+
else
|
|
623
|
+
# a single row chunk - NOTE Very experimental may change
|
|
624
|
+
text = content[1].dup
|
|
625
|
+
printstring r, c, text, content[0] || color, content[2] || att
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
#
|
|
630
|
+
# prints a string formatted in our new experimental coloring format
|
|
631
|
+
# taken from tmux. Currently, since i have chunks workings, i convert
|
|
632
|
+
# to chunks and use the existing print function. This could change.
|
|
633
|
+
# An example of a formatted string is:
|
|
634
|
+
# s="#[fg=green]testing chunks #[fg=yellow, bg=red, bold]yellow #[reverse] reverseme \
|
|
635
|
+
# #[normal]normal#[bg = black]just yellow#[fg=blue],blue now #[underline] underlined text"
|
|
636
|
+
# Ideally I should push and pop colors which the shell does not do with ansi terminal sequences.
|
|
637
|
+
# That way i can have a line in red,
|
|
638
|
+
# with some word in yellow, and then the line continues in red.
|
|
639
|
+
#
|
|
640
|
+
def printstring_formatted(r,c,content, color, att = Ncurses::A_NORMAL)
|
|
641
|
+
att = get_attrib att unless att.is_a? Fixnum
|
|
642
|
+
chunkline = convert_to_chunk(content, color, att)
|
|
643
|
+
printstring_or_chunks r,c, chunkline, color, att
|
|
644
|
+
end # print
|
|
645
|
+
#
|
|
646
|
+
# print a formatted line right aligned
|
|
647
|
+
# c (col) is ignored and calculated based on width and unformatted string length
|
|
648
|
+
#
|
|
649
|
+
def printstring_formatted_right(r,c,content, color, att = Ncurses::A_NORMAL)
|
|
650
|
+
clean = content.gsub /#\[[^\]]*\]/,'' # clean out all markup
|
|
651
|
+
c = actual_width() - clean.length
|
|
652
|
+
printstring_formatted(r,c,content, color, att )
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
private
|
|
656
|
+
def get_default_color_parser
|
|
657
|
+
require 'rbcurse/core/util/colorparser'
|
|
658
|
+
@color_parser || DefaultColorParser.new
|
|
659
|
+
end
|
|
660
|
+
# supply with a color parser, if you supplied formatted text
|
|
661
|
+
public
|
|
662
|
+
def color_parser f
|
|
663
|
+
$log.debug "XXX: color_parser setting in window to #{f} "
|
|
664
|
+
if f == :tmux
|
|
665
|
+
@color_parser = get_default_color_parser()
|
|
666
|
+
else
|
|
667
|
+
@color_parser = f
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
#
|
|
671
|
+
# Takes a formatted string and converts the parsed parts to chunks.
|
|
672
|
+
#
|
|
673
|
+
# @param [String] takes the entire line or string and breaks into an array of chunks
|
|
674
|
+
# @yield chunk if block
|
|
675
|
+
# @return [ChunkLine] # [Array] array of chunks
|
|
676
|
+
# @since 1.4.1 2011-11-3 experimental, can change
|
|
677
|
+
public
|
|
678
|
+
def convert_to_chunk s, colorp=$datacolor, att=FFI::NCurses::A_NORMAL
|
|
679
|
+
unless @color_parser
|
|
680
|
+
@color_parser = get_default_color_parser()
|
|
681
|
+
@converter = Chunks::ColorParser.new @color_parser
|
|
682
|
+
end
|
|
683
|
+
@converter.convert_to_chunk s, colorp, att
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
##
|
|
687
|
+
# prints a string at row, col, with given color and attribute
|
|
688
|
+
# added by rk 2008-11-29 19:01
|
|
689
|
+
# I usually use this, not the others ones here
|
|
690
|
+
# @param r - row
|
|
691
|
+
# @param c - col
|
|
692
|
+
# @param string - text to print
|
|
693
|
+
# @param color - color pair
|
|
694
|
+
# @ param att - ncurses attribute: normal, bold, reverse, blink,
|
|
695
|
+
# underline
|
|
696
|
+
public
|
|
697
|
+
def printstring(r,c,string, color, att = Ncurses::A_NORMAL)
|
|
698
|
+
raise "Nil passed to peintstring row:#{r}, col:#{c}, #{color} " if r.nil? || c.nil? || color.nil?
|
|
699
|
+
#raise "Zero or less passed to printstring row:#{r}, col:#{c} " if $log.debug? && (r <=0 || c <=0)
|
|
700
|
+
prv_printstring(r,c,string, color, att )
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
## name changed from printstring to prv_prinstring
|
|
704
|
+
def prv_printstring(r,c,string, color, att = Ncurses::A_NORMAL)
|
|
705
|
+
|
|
706
|
+
#$log.debug " #{@name} inside window printstring r #{r} c #{c} #{string} "
|
|
707
|
+
if att.nil?
|
|
708
|
+
att = Ncurses::A_NORMAL
|
|
709
|
+
else
|
|
710
|
+
att = get_attrib att
|
|
711
|
+
end
|
|
712
|
+
#att = att.downcase.to_sym if att.is_a? String
|
|
713
|
+
#case att
|
|
714
|
+
#when :normal
|
|
715
|
+
#att = Ncurses::A_NORMAL
|
|
716
|
+
#when :underline
|
|
717
|
+
#att = Ncurses::A_UNDERLINE
|
|
718
|
+
#when :bold
|
|
719
|
+
#att = Ncurses::A_BOLD
|
|
720
|
+
#when :reverse
|
|
721
|
+
#att = Ncurses::A_REVERSE
|
|
722
|
+
#when :dim
|
|
723
|
+
#att = Ncurses::A_DIM
|
|
724
|
+
#when :blink
|
|
725
|
+
#att = Ncurses::A_BLINK # unlikely to work
|
|
726
|
+
#end
|
|
727
|
+
|
|
728
|
+
wattron(Ncurses.COLOR_PAIR(color) | att)
|
|
729
|
+
mvwprintw(r, c, "%s", :string, string);
|
|
730
|
+
wattroff(Ncurses.COLOR_PAIR(color) | att)
|
|
731
|
+
end
|
|
732
|
+
# @deprecated
|
|
733
|
+
def print_error_message text=$error_message.get_value
|
|
734
|
+
alert text
|
|
735
|
+
end
|
|
736
|
+
# added by rk 2008-11-29 19:01
|
|
737
|
+
# @deprecated. use global method of same name in rdialog
|
|
738
|
+
def print_status_message text=$status_message
|
|
739
|
+
#VER::print_status_message text
|
|
740
|
+
alert text
|
|
741
|
+
end
|
|
742
|
+
# added by rk 2008-11-29 19:01
|
|
743
|
+
# Since these methods write directly to window they are not advised
|
|
744
|
+
# since clearing previous message we don't know how much to clear.
|
|
745
|
+
# Best to map error_message to a label.
|
|
746
|
+
# 2010-09-13 00:22 WE should not use these any longer.
|
|
747
|
+
# Application should create a label and map a Variable named
|
|
748
|
+
# $errormessage to it. We should only update the Variable
|
|
749
|
+
def DEPRECATED_print_error_message text=$error_message.get_value
|
|
750
|
+
r = $error_message_row || Ncurses.LINES-1
|
|
751
|
+
c = $error_message_col || (Ncurses.COLS-text.length)/2
|
|
752
|
+
|
|
753
|
+
$log.debug "got ERROR MESSAGE #{text} row #{r} "
|
|
754
|
+
clear_error r, $datacolor
|
|
755
|
+
printstring r, c, text, color = $promptcolor
|
|
756
|
+
$error_message_clear_pending = true
|
|
757
|
+
end
|
|
758
|
+
# added by rk 2008-11-29 19:01
|
|
759
|
+
# @deprecated. use global method of same name
|
|
760
|
+
def DEPRECATED_print_status_message text=$status_message
|
|
761
|
+
r = $status_message_row || Ncurses.LINES-1
|
|
762
|
+
clear_error r, $datacolor
|
|
763
|
+
# print it in centre
|
|
764
|
+
printstring r, (Ncurses.COLS-text.length)/2, text, color = $promptcolor
|
|
765
|
+
end
|
|
766
|
+
# Clear error message printed
|
|
767
|
+
# I am not only clearing if something was printed. This is since
|
|
768
|
+
# certain small forms like TabbedForm top form throw an error on printstring.
|
|
769
|
+
# @deprecated
|
|
770
|
+
def clear_error r = $error_message_row, color = $datacolor
|
|
771
|
+
return unless $error_message_clear_pending
|
|
772
|
+
c = $error_message_col || (Ncurses.COLS-text.length)/2
|
|
773
|
+
sz = $error_message_size || Ncurses.COLS
|
|
774
|
+
printstring(r, c, "%-*s" % [sz, " "], color)
|
|
775
|
+
$error_message_clear_pending = false
|
|
776
|
+
end
|
|
777
|
+
##
|
|
778
|
+
# NOTE : FOR MESSAGEBOXES ONLY !!!!
|
|
779
|
+
def print_border_mb row, col, height, width, color, attr
|
|
780
|
+
# the next is for xterm-256
|
|
781
|
+
att = get_attrib attr
|
|
782
|
+
len = width
|
|
783
|
+
len = Ncurses.COLS-0 if len == 0
|
|
784
|
+
# print a bar across the screen
|
|
785
|
+
#attron(Ncurses.COLOR_PAIR(color) | att)
|
|
786
|
+
# this works for newmessagebox but not for old one.
|
|
787
|
+
# Even now in some cases some black shows through, if the widget is printing spaces
|
|
788
|
+
# such as field or textview on a messagebox.
|
|
789
|
+
(row-1).upto(row+height-1) do |r|
|
|
790
|
+
mvwhline(r, col, 1, len)
|
|
791
|
+
end
|
|
792
|
+
#attroff(Ncurses.COLOR_PAIR(color) | att)
|
|
793
|
+
|
|
794
|
+
mvwaddch row, col, Ncurses::ACS_ULCORNER
|
|
795
|
+
mvwhline( row, col+1, Ncurses::ACS_HLINE, width-6)
|
|
796
|
+
mvwaddch row, col+width-5, Ncurses::ACS_URCORNER
|
|
797
|
+
mvwvline( row+1, col, Ncurses::ACS_VLINE, height-4)
|
|
798
|
+
|
|
799
|
+
mvwaddch row+height-3, col, Ncurses::ACS_LLCORNER
|
|
800
|
+
mvwhline(row+height-3, col+1, Ncurses::ACS_HLINE, width-6)
|
|
801
|
+
mvwaddch row+height-3, col+width-5, Ncurses::ACS_LRCORNER
|
|
802
|
+
mvwvline( row+1, col+width-5, Ncurses::ACS_VLINE, height-4)
|
|
803
|
+
end
|
|
804
|
+
##
|
|
805
|
+
# prints a border around a widget, CLEARING the area.
|
|
806
|
+
# If calling with a pad, you would typically use 0,0, h-1, w-1.
|
|
807
|
+
def print_border row, col, height, width, color, att=Ncurses::A_NORMAL
|
|
808
|
+
raise "height needs to be supplied." if height.nil?
|
|
809
|
+
raise "width needs to be supplied." if width.nil?
|
|
810
|
+
att ||= Ncurses::A_NORMAL
|
|
811
|
+
|
|
812
|
+
$log.debug " inside window print_border r #{row} c #{col} h #{height} w #{width} "
|
|
813
|
+
|
|
814
|
+
# 2009-11-02 00:45 made att nil for blanking out
|
|
815
|
+
# FIXME - in tabbedpanes this clears one previous line ??? XXX when using a textarea/view
|
|
816
|
+
# when using a pad this calls pads printstring which again reduces top and left !!! 2010-01-26 23:53
|
|
817
|
+
ww=width-2
|
|
818
|
+
(row+1).upto(row+height-1) do |r|
|
|
819
|
+
prv_printstring( r, col+1," "*ww , color, att)
|
|
820
|
+
end
|
|
821
|
+
prv_print_border_only row, col, height, width, color, att
|
|
822
|
+
end
|
|
823
|
+
def print_border_only row, col, height, width, color, att=Ncurses::A_NORMAL
|
|
824
|
+
prv_print_border_only row, col, height, width, color, att
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
## print just the border, no cleanup
|
|
829
|
+
#+ Earlier, we would clean up. Now in some cases, i'd like
|
|
830
|
+
#+ to print border over what's been done.
|
|
831
|
+
# XXX this reduces 1 from width but not height !!! FIXME
|
|
832
|
+
def prv_print_border_only row, col, height, width, color, att=Ncurses::A_NORMAL
|
|
833
|
+
if att.nil?
|
|
834
|
+
att = Ncurses::A_NORMAL
|
|
835
|
+
else
|
|
836
|
+
att = get_attrib att
|
|
837
|
+
end
|
|
838
|
+
wattron(Ncurses.COLOR_PAIR(color) | att)
|
|
839
|
+
mvwaddch row, col, Ncurses::ACS_ULCORNER
|
|
840
|
+
mvwhline( row, col+1, Ncurses::ACS_HLINE, width-2)
|
|
841
|
+
mvwaddch row, col+width-1, Ncurses::ACS_URCORNER
|
|
842
|
+
mvwvline( row+1, col, Ncurses::ACS_VLINE, height-1)
|
|
843
|
+
|
|
844
|
+
mvwaddch row+height-0, col, Ncurses::ACS_LLCORNER
|
|
845
|
+
mvwhline(row+height-0, col+1, Ncurses::ACS_HLINE, width-2)
|
|
846
|
+
mvwaddch row+height-0, col+width-1, Ncurses::ACS_LRCORNER
|
|
847
|
+
mvwvline( row+1, col+width-1, Ncurses::ACS_VLINE, height-1)
|
|
848
|
+
wattroff(Ncurses.COLOR_PAIR(color) | att)
|
|
849
|
+
end
|
|
850
|
+
# This used to return an Ncurses window object, and you could call methods on it
|
|
851
|
+
# Now it returns a FFI::NCurses.window pointer which you cannot call methods on.
|
|
852
|
+
# You have to pass it to FFI::NCurses.<method>
|
|
853
|
+
def get_window; @window; end
|
|
854
|
+
def to_s; @name || self; end
|
|
855
|
+
# use in place of mvwhline if your widget could be using a pad or window
|
|
856
|
+
def rb_mvwhline row, col, char, width
|
|
857
|
+
mvwhline row, col, char, width
|
|
858
|
+
end
|
|
859
|
+
# use in place of mvwvline if your widget could be using a pad or window
|
|
860
|
+
def rb_mvwvline row, col, char, width
|
|
861
|
+
mvwvline row, col, char, width
|
|
862
|
+
end
|
|
863
|
+
# use in place of mvaddch if your widget could be using a pad or window
|
|
864
|
+
def rb_mvaddch row, col, char
|
|
865
|
+
mvaddch row, col, char
|
|
866
|
+
end
|
|
867
|
+
def close_command *args, &block
|
|
868
|
+
@close_command ||= []
|
|
869
|
+
@close_args ||= []
|
|
870
|
+
@close_command << block
|
|
871
|
+
@close_args << args
|
|
872
|
+
end
|
|
873
|
+
alias :command :close_command
|
|
874
|
+
|
|
875
|
+
# set a single command to confirm whether window shoud close or not
|
|
876
|
+
# Block should return true or false for closing or not
|
|
877
|
+
def confirm_close_command *args, &block
|
|
878
|
+
@confirm_close_command = block
|
|
879
|
+
@confirm_close_args = args
|
|
880
|
+
end
|
|
881
|
+
|
|
882
|
+
# need a way of lettign user decide whether he wishes to close
|
|
883
|
+
# in which case we return false. However, there could be several commands
|
|
884
|
+
# mapped. how do we know which is the one that has this authority
|
|
885
|
+
def fire_close_handler
|
|
886
|
+
if @confirm_close_command
|
|
887
|
+
comm = @confirm_close_command
|
|
888
|
+
ret = comm.call(self, *@confirm_close_args)
|
|
889
|
+
return ret unless ret # only return if false returned
|
|
890
|
+
end
|
|
891
|
+
if @close_command
|
|
892
|
+
@close_command.each_with_index do |comm, ix|
|
|
893
|
+
comm.call(self, *@close_args[ix]) if comm
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
@close_command = nil
|
|
897
|
+
@close_args = nil
|
|
898
|
+
return true
|
|
899
|
+
end
|
|
900
|
+
end
|
|
901
|
+
end
|