rndk 0.0.1
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 +23 -0
- data/COPYING +137 -0
- data/Gemfile +4 -0
- data/README.md +100 -0
- data/Rakefile +3 -0
- data/TODO +68 -0
- data/demos/appointment.rb +346 -0
- data/demos/clock.rb +56 -0
- data/examples/01-hello-world.rb +56 -0
- data/examples/05-position-widget.rb +108 -0
- data/lib/rndk.rb +912 -0
- data/lib/rndk/alphalist.rb +572 -0
- data/lib/rndk/button.rb +370 -0
- data/lib/rndk/buttonbox.rb +359 -0
- data/lib/rndk/calendar.rb +766 -0
- data/lib/rndk/core/display.rb +63 -0
- data/lib/rndk/core/draw.rb +238 -0
- data/lib/rndk/core/quick_widgets.rb +106 -0
- data/lib/rndk/core/screen.rb +269 -0
- data/lib/rndk/core/traverse.rb +289 -0
- data/lib/rndk/core/widget.rb +506 -0
- data/lib/rndk/dialog.rb +367 -0
- data/lib/rndk/dscale.rb +13 -0
- data/lib/rndk/entry.rb +575 -0
- data/lib/rndk/fscale.rb +61 -0
- data/lib/rndk/fselect.rb +940 -0
- data/lib/rndk/fslider.rb +80 -0
- data/lib/rndk/graph.rb +401 -0
- data/lib/rndk/histogram.rb +412 -0
- data/lib/rndk/itemlist.rb +474 -0
- data/lib/rndk/label.rb +218 -0
- data/lib/rndk/marquee.rb +244 -0
- data/lib/rndk/matrix.rb +1189 -0
- data/lib/rndk/mentry.rb +619 -0
- data/lib/rndk/menu.rb +478 -0
- data/lib/rndk/radio.rb +538 -0
- data/lib/rndk/scale.rb +538 -0
- data/lib/rndk/scroll.rb +633 -0
- data/lib/rndk/scroller.rb +183 -0
- data/lib/rndk/selection.rb +630 -0
- data/lib/rndk/slider.rb +545 -0
- data/lib/rndk/swindow.rb +766 -0
- data/lib/rndk/template.rb +560 -0
- data/lib/rndk/uscale.rb +14 -0
- data/lib/rndk/uslider.rb +14 -0
- data/lib/rndk/version.rb +6 -0
- data/lib/rndk/viewer.rb +825 -0
- data/rndk.gemspec +35 -0
- metadata +141 -0
data/lib/rndk/dialog.rb
ADDED
@@ -0,0 +1,367 @@
|
|
1
|
+
require 'rndk'
|
2
|
+
|
3
|
+
module RNDK
|
4
|
+
class DIALOG < RNDK::Widget
|
5
|
+
attr_reader :current_button
|
6
|
+
MIN_DIALOG_WIDTH = 10
|
7
|
+
|
8
|
+
def initialize(rndkscreen, xplace, yplace, mesg, rows, button_label,
|
9
|
+
button_count, highlight, separator, box, shadow)
|
10
|
+
super()
|
11
|
+
box_width = DIALOG::MIN_DIALOG_WIDTH
|
12
|
+
max_message_width = -1
|
13
|
+
button_width = 0
|
14
|
+
xpos = xplace
|
15
|
+
ypos = yplace
|
16
|
+
temp = 0
|
17
|
+
buttonadj = 0
|
18
|
+
@info = []
|
19
|
+
@info_len = []
|
20
|
+
@info_pos = []
|
21
|
+
@button_label = []
|
22
|
+
@button_len = []
|
23
|
+
@button_pos = []
|
24
|
+
|
25
|
+
if rows <= 0 || button_count <= 0
|
26
|
+
self.destroy
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
self.setBox(box)
|
31
|
+
box_height = if separator then 1 else 0 end
|
32
|
+
box_height += rows + 2 * @border_size + 1
|
33
|
+
|
34
|
+
# Translate the string message to a chtype array
|
35
|
+
(0...rows).each do |x|
|
36
|
+
info_len = []
|
37
|
+
info_pos = []
|
38
|
+
@info << RNDK.char2Chtype(mesg[x], info_len, info_pos)
|
39
|
+
@info_len << info_len[0]
|
40
|
+
@info_pos << info_pos[0]
|
41
|
+
max_message_width = [max_message_width, info_len[0]].max
|
42
|
+
end
|
43
|
+
|
44
|
+
# Translate the button label string to a chtype array
|
45
|
+
(0...button_count).each do |x|
|
46
|
+
button_len = []
|
47
|
+
@button_label << RNDK.char2Chtype(button_label[x], button_len, [])
|
48
|
+
@button_len << button_len[0]
|
49
|
+
button_width += button_len[0] + 1
|
50
|
+
end
|
51
|
+
|
52
|
+
button_width -= 1
|
53
|
+
|
54
|
+
# Determine the final dimensions of the box.
|
55
|
+
box_width = [box_width, max_message_width, button_width].max
|
56
|
+
box_width = box_width + 2 + 2 * @border_size
|
57
|
+
|
58
|
+
# Now we have to readjust the x and y positions.
|
59
|
+
xtmp = [xpos]
|
60
|
+
ytmp = [ypos]
|
61
|
+
RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
|
62
|
+
xpos = xtmp[0]
|
63
|
+
ypos = ytmp[0]
|
64
|
+
|
65
|
+
# Set up the dialog box attributes.
|
66
|
+
@screen = rndkscreen
|
67
|
+
@parent = rndkscreen.window
|
68
|
+
@win = Ncurses.newwin(box_height, box_width, ypos, xpos)
|
69
|
+
@shadow_win = nil
|
70
|
+
@button_count = button_count
|
71
|
+
@current_button = 0
|
72
|
+
@message_rows = rows
|
73
|
+
@box_height = box_height
|
74
|
+
@box_width = box_width
|
75
|
+
@highlight = highlight
|
76
|
+
@separator = separator
|
77
|
+
@accepts_focus = true
|
78
|
+
@input_window = @win
|
79
|
+
@shadow = shadow
|
80
|
+
|
81
|
+
# If we couldn't create the window, we should return a nil value.
|
82
|
+
if @win.nil?
|
83
|
+
self.destroy
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
Ncurses.keypad(@win, true)
|
87
|
+
|
88
|
+
# Find the button positions.
|
89
|
+
buttonadj = (box_width - button_width) / 2
|
90
|
+
(0...button_count).each do |x|
|
91
|
+
@button_pos[x] = buttonadj
|
92
|
+
buttonadj = buttonadj + @button_len[x] + @border_size
|
93
|
+
end
|
94
|
+
|
95
|
+
# Create the string alignments.
|
96
|
+
(0...rows).each do |x|
|
97
|
+
@info_pos[x] = RNDK.justifyString(box_width - 2 * @border_size,
|
98
|
+
@info_len[x], @info_pos[x])
|
99
|
+
end
|
100
|
+
|
101
|
+
# Was there a shadow?
|
102
|
+
if shadow
|
103
|
+
@shadow_win = Ncurses.newwin(box_height, box_width,
|
104
|
+
ypos + 1, xpos + 1)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Register this baby.
|
108
|
+
rndkscreen.register(:DIALOG, self)
|
109
|
+
end
|
110
|
+
|
111
|
+
# This lets the user select the button.
|
112
|
+
def activate(actions)
|
113
|
+
input = 0
|
114
|
+
|
115
|
+
# Draw the dialog box.
|
116
|
+
self.draw(@box)
|
117
|
+
|
118
|
+
# Lets move to the first button.
|
119
|
+
Draw.writeChtypeAttrib(@win,
|
120
|
+
@button_pos[@current_button],
|
121
|
+
@box_height - 1 - @border_size, @button_label[@current_button],
|
122
|
+
@highlight,
|
123
|
+
RNDK::HORIZONTAL,
|
124
|
+
0,
|
125
|
+
@button_len[@current_button])
|
126
|
+
Ncurses.wrefresh @win
|
127
|
+
|
128
|
+
if actions.nil? || actions.size == 0
|
129
|
+
while true
|
130
|
+
input = self.getch([])
|
131
|
+
|
132
|
+
# Inject the character into the widget.
|
133
|
+
ret = self.inject(input)
|
134
|
+
if @exit_type != :EARLY_EXIT
|
135
|
+
return ret
|
136
|
+
end
|
137
|
+
end
|
138
|
+
else
|
139
|
+
# Inject each character one at a time.
|
140
|
+
actions.each do |action|
|
141
|
+
ret = self.inject(action)
|
142
|
+
if @exit_type != :EARLY_EXIT
|
143
|
+
return ret
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Set the exit type and exit
|
149
|
+
self.setExitType(0)
|
150
|
+
return -1
|
151
|
+
end
|
152
|
+
|
153
|
+
# This injects a single character into the dialog widget
|
154
|
+
def inject(input)
|
155
|
+
first_button = 0
|
156
|
+
last_button = @button_count - 1
|
157
|
+
pp_return = 1
|
158
|
+
ret = -1
|
159
|
+
complete = false
|
160
|
+
|
161
|
+
# Set the exit type.
|
162
|
+
self.setExitType(0)
|
163
|
+
|
164
|
+
# Check if there is a pre-process function to be called.
|
165
|
+
unless @pre_process_func.nil?
|
166
|
+
pp_return = @pre_process_func.call(:DIALOG, self,
|
167
|
+
@pre_process_data, input)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Should we continue?
|
171
|
+
if pp_return != 0
|
172
|
+
# Check for a key binding.
|
173
|
+
if self.checkBind(:DIALOG, input)
|
174
|
+
complete = true
|
175
|
+
else
|
176
|
+
case input
|
177
|
+
when Ncurses::KEY_LEFT, Ncurses::KEY_BTAB, Ncurses::KEY_BACKSPACE
|
178
|
+
if @current_button == first_button
|
179
|
+
@current_button = last_button
|
180
|
+
else
|
181
|
+
@current_button -= 1
|
182
|
+
end
|
183
|
+
when Ncurses::KEY_RIGHT, RNDK::KEY_TAB, ' '.ord
|
184
|
+
if @current_button == last_button
|
185
|
+
@current_button = first_button
|
186
|
+
else
|
187
|
+
@current_button += 1
|
188
|
+
end
|
189
|
+
when Ncurses::KEY_UP, Ncurses::KEY_DOWN
|
190
|
+
RNDK.beep
|
191
|
+
when RNDK::REFRESH
|
192
|
+
@screen.erase
|
193
|
+
@screen.refresh
|
194
|
+
when RNDK::KEY_ESC
|
195
|
+
self.setExitType(input)
|
196
|
+
complete = true
|
197
|
+
when Ncurses::ERR
|
198
|
+
self.setExitType(input)
|
199
|
+
when Ncurses::KEY_ENTER, RNDK::KEY_RETURN
|
200
|
+
self.setExitType(input)
|
201
|
+
ret = @current_button
|
202
|
+
complete = true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Should we call a post_process?
|
207
|
+
if !complete && !(@post_process_func.nil?)
|
208
|
+
@post_process_func.call(:DIALOG, self,
|
209
|
+
@post_process_data, input)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
unless complete
|
214
|
+
self.drawButtons
|
215
|
+
Ncurses.wrefresh @win
|
216
|
+
self.setExitType(0)
|
217
|
+
end
|
218
|
+
|
219
|
+
@result_data = ret
|
220
|
+
return ret
|
221
|
+
end
|
222
|
+
|
223
|
+
# This moves the dialog field to the given location.
|
224
|
+
# Inherited
|
225
|
+
# def move(xplace, yplace, relative, refresh_flag)
|
226
|
+
# end
|
227
|
+
|
228
|
+
# This function draws the dialog widget.
|
229
|
+
def draw(box)
|
230
|
+
# Is there a shadow?
|
231
|
+
unless @shadow_win.nil?
|
232
|
+
Draw.drawShadow(@shadow_win)
|
233
|
+
end
|
234
|
+
|
235
|
+
# Box the widget if they asked.
|
236
|
+
if box
|
237
|
+
Draw.drawObjBox(@win, self)
|
238
|
+
end
|
239
|
+
|
240
|
+
# Draw in the message.
|
241
|
+
(0...@message_rows).each do |x|
|
242
|
+
Draw.writeChtype(@win,
|
243
|
+
@info_pos[x] + @border_size,
|
244
|
+
x + @border_size,
|
245
|
+
@info[x],
|
246
|
+
RNDK::HORIZONTAL,
|
247
|
+
0,
|
248
|
+
@info_len[x])
|
249
|
+
end
|
250
|
+
|
251
|
+
# Draw in the buttons.
|
252
|
+
self.drawButtons
|
253
|
+
|
254
|
+
Ncurses.wrefresh @win
|
255
|
+
end
|
256
|
+
|
257
|
+
# This function destroys the dialog widget.
|
258
|
+
def destroy
|
259
|
+
# Clean up the windows.
|
260
|
+
RNDK.deleteCursesWindow(@win)
|
261
|
+
RNDK.deleteCursesWindow(@shadow_win)
|
262
|
+
|
263
|
+
# Clean the key bindings
|
264
|
+
self.cleanBindings(:DIALOG)
|
265
|
+
|
266
|
+
# Unregister this object
|
267
|
+
RNDK::Screen.unregister(:DIALOG, self)
|
268
|
+
end
|
269
|
+
|
270
|
+
# This function erases the dialog widget from the screen.
|
271
|
+
def erase
|
272
|
+
if self.validRNDKObject
|
273
|
+
RNDK.eraseCursesWindow(@win)
|
274
|
+
RNDK.eraseCursesWindow(@shadow_win)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# This sets attributes of the dialog box.
|
279
|
+
def set(highlight, separator, box)
|
280
|
+
self.setHighlight(highlight)
|
281
|
+
self.setSeparator(separator)
|
282
|
+
self.setBox(box)
|
283
|
+
end
|
284
|
+
|
285
|
+
# This sets the highlight attribute for the buttons.
|
286
|
+
def setHighlight(highlight)
|
287
|
+
@highlight = highlight
|
288
|
+
end
|
289
|
+
|
290
|
+
def getHighlight
|
291
|
+
return @highlight
|
292
|
+
end
|
293
|
+
|
294
|
+
# This sets whether or not the dialog box will have a separator line.
|
295
|
+
def setSeparator(separator)
|
296
|
+
@separator = separator
|
297
|
+
end
|
298
|
+
|
299
|
+
def getSeparator
|
300
|
+
return @separator
|
301
|
+
end
|
302
|
+
|
303
|
+
# This sets the background attribute of the widget.
|
304
|
+
def setBKattr(attrib)
|
305
|
+
Ncurses.wbkgd(@win, attrib)
|
306
|
+
end
|
307
|
+
|
308
|
+
# This draws the dialog buttons and the separation line.
|
309
|
+
def drawButtons
|
310
|
+
(0...@button_count).each do |x|
|
311
|
+
Draw.writeChtype(@win,
|
312
|
+
@button_pos[x],
|
313
|
+
@box_height -1 - @border_size,
|
314
|
+
@button_label[x],
|
315
|
+
RNDK::HORIZONTAL,
|
316
|
+
0,
|
317
|
+
@button_len[x])
|
318
|
+
end
|
319
|
+
|
320
|
+
# Draw the separation line.
|
321
|
+
if @separator
|
322
|
+
boxattr = @BXAttr
|
323
|
+
|
324
|
+
(1...@box_width).each do |x|
|
325
|
+
Ncurses.mvwaddch(@win,
|
326
|
+
@box_height - 2 - @border_size,
|
327
|
+
x,
|
328
|
+
Ncurses::ACS_HLINE | boxattr)
|
329
|
+
end
|
330
|
+
|
331
|
+
Ncurses.mvwaddch(@win,
|
332
|
+
@box_height - 2 - @border_size,
|
333
|
+
0,
|
334
|
+
Ncurses::ACS_LTEE | boxattr)
|
335
|
+
Ncurses.mvwaddch(@win,
|
336
|
+
@box_height - 2 - @border_size,
|
337
|
+
Ncurses.getmaxx(@win) - 1,
|
338
|
+
Ncurses::ACS_RTEE | boxattr)
|
339
|
+
end
|
340
|
+
Draw.writeChtypeAttrib(@win,
|
341
|
+
@button_pos[@current_button],
|
342
|
+
@box_height - 1 - @border_size,
|
343
|
+
@button_label[@current_button],
|
344
|
+
@highlight,
|
345
|
+
RNDK::HORIZONTAL,
|
346
|
+
0,
|
347
|
+
@button_len[@current_button])
|
348
|
+
end
|
349
|
+
|
350
|
+
def focus
|
351
|
+
self.draw @box
|
352
|
+
end
|
353
|
+
|
354
|
+
def unfocus
|
355
|
+
self.draw @box
|
356
|
+
end
|
357
|
+
|
358
|
+
def object_type
|
359
|
+
:DIALOG
|
360
|
+
end
|
361
|
+
|
362
|
+
def position
|
363
|
+
super(@win)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
data/lib/rndk/dscale.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rndk/fscale'
|
2
|
+
|
3
|
+
module RNDK
|
4
|
+
class DSCALE < RNDK::FSCALE
|
5
|
+
# The original DScale handled unsigned values.
|
6
|
+
# Since Ruby's typing is different this is really just FSCALE
|
7
|
+
# but is nice it's nice to have this for compatibility/completeness
|
8
|
+
# sake.
|
9
|
+
def object_type
|
10
|
+
:DSCALE
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/rndk/entry.rb
ADDED
@@ -0,0 +1,575 @@
|
|
1
|
+
require 'rndk'
|
2
|
+
|
3
|
+
module RNDK
|
4
|
+
|
5
|
+
class ENTRY < RNDK::Widget
|
6
|
+
attr_accessor :info, :left_char, :screen_col
|
7
|
+
attr_reader :win, :box_height, :box_width, :max, :field_width
|
8
|
+
attr_reader :min, :max
|
9
|
+
|
10
|
+
def initialize(rndkscreen,
|
11
|
+
xplace,
|
12
|
+
yplace,
|
13
|
+
title,
|
14
|
+
label,
|
15
|
+
field_attr,
|
16
|
+
filler,
|
17
|
+
disp_type,
|
18
|
+
f_width,
|
19
|
+
min,
|
20
|
+
max,
|
21
|
+
box,
|
22
|
+
shadow)
|
23
|
+
super()
|
24
|
+
parent_width = Ncurses.getmaxx rndkscreen.window
|
25
|
+
parent_height = Ncurses.getmaxy rndkscreen.window
|
26
|
+
field_width = f_width
|
27
|
+
box_width = 0
|
28
|
+
xpos = xplace
|
29
|
+
ypos = yplace
|
30
|
+
|
31
|
+
self.setBox(box)
|
32
|
+
box_height = @border_size * 2 + 1
|
33
|
+
|
34
|
+
# If the field_width is a negative value, the field_width will be
|
35
|
+
# COLS-field_width, otherwise the field_width will be the given width.
|
36
|
+
field_width = RNDK.setWidgetDimension(parent_width, field_width, 0)
|
37
|
+
box_width = field_width + 2 * @border_size
|
38
|
+
|
39
|
+
# Set some basic values of the entry field.
|
40
|
+
@label = 0
|
41
|
+
@label_len = 0
|
42
|
+
@label_win = nil
|
43
|
+
|
44
|
+
# Translate the label string to a chtype array
|
45
|
+
if !(label.nil?) && label.size > 0
|
46
|
+
label_len = [@label_len]
|
47
|
+
@label = RNDK.char2Chtype(label, label_len, [])
|
48
|
+
@label_len = label_len[0]
|
49
|
+
box_width += @label_len
|
50
|
+
end
|
51
|
+
|
52
|
+
old_width = box_width
|
53
|
+
box_width = self.setTitle(title, box_width)
|
54
|
+
horizontal_adjust = (box_width - old_width) / 2
|
55
|
+
|
56
|
+
box_height += @title_lines
|
57
|
+
|
58
|
+
# Make sure we didn't extend beyond the dimensinos of the window.
|
59
|
+
box_width = [box_width, parent_width].min
|
60
|
+
box_height = [box_height, parent_height].min
|
61
|
+
field_width = [field_width,
|
62
|
+
box_width - @label_len - 2 * @border_size].min
|
63
|
+
|
64
|
+
# Rejustify the x and y positions if we need to.
|
65
|
+
xtmp = [xpos]
|
66
|
+
ytmp = [ypos]
|
67
|
+
RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
|
68
|
+
xpos = xtmp[0]
|
69
|
+
ypos = ytmp[0]
|
70
|
+
|
71
|
+
# Make the label window.
|
72
|
+
@win = Ncurses.subwin(rndkscreen.window, box_height, box_width, ypos, xpos)
|
73
|
+
if @win.nil?
|
74
|
+
self.destroy
|
75
|
+
return nil
|
76
|
+
end
|
77
|
+
Ncurses.keypad(@win, true)
|
78
|
+
|
79
|
+
# Make the field window.
|
80
|
+
@field_win = Ncurses.subwin(@win,
|
81
|
+
1,
|
82
|
+
field_width,
|
83
|
+
ypos + @title_lines + @border_size,
|
84
|
+
xpos + @label_len + horizontal_adjust + @border_size)
|
85
|
+
|
86
|
+
if @field_win.nil?
|
87
|
+
self.destroy
|
88
|
+
return nil
|
89
|
+
end
|
90
|
+
Ncurses.keypad(@field_win, true)
|
91
|
+
|
92
|
+
# make the label win, if we need to
|
93
|
+
if !(label.nil?) && label.size > 0
|
94
|
+
@label_win = Ncurses.subwin(@win, 1, @label_len,
|
95
|
+
ypos + @title_lines + @border_size,
|
96
|
+
xpos + horizontal_adjust + @border_size)
|
97
|
+
end
|
98
|
+
|
99
|
+
# cleanChar (entry->info, max + 3, '\0');
|
100
|
+
@info = ''
|
101
|
+
@info_width = max + 3
|
102
|
+
|
103
|
+
# Set up the rest of the structure.
|
104
|
+
@screen = rndkscreen
|
105
|
+
@parent = rndkscreen.window
|
106
|
+
@shadow_win = nil
|
107
|
+
@field_attr = field_attr
|
108
|
+
@field_width = field_width
|
109
|
+
@filler = filler
|
110
|
+
@hidden = filler
|
111
|
+
@input_window = @field_win
|
112
|
+
@accepts_focus = true
|
113
|
+
@data_ptr = nil
|
114
|
+
@shadow = shadow
|
115
|
+
@screen_col = 0
|
116
|
+
@left_char = 0
|
117
|
+
@min = min
|
118
|
+
@max = max
|
119
|
+
@box_width = box_width
|
120
|
+
@box_height = box_height
|
121
|
+
@disp_type = disp_type
|
122
|
+
@callbackfn = lambda do |entry, character|
|
123
|
+
plainchar = Display.filterByDisplayType(entry, character)
|
124
|
+
|
125
|
+
if plainchar == Ncurses::ERR || entry.info.size >= entry.max
|
126
|
+
RNDK.beep
|
127
|
+
else
|
128
|
+
# Update the screen and pointer
|
129
|
+
if entry.screen_col != entry.field_width - 1
|
130
|
+
front = (entry.info[0...(entry.screen_col + entry.left_char)] or '')
|
131
|
+
back = (entry.info[(entry.screen_col + entry.left_char)..-1] or '')
|
132
|
+
entry.info = front + plainchar.chr + back
|
133
|
+
entry.screen_col += 1
|
134
|
+
else
|
135
|
+
# Update the character pointer.
|
136
|
+
entry.info << plainchar
|
137
|
+
# Do not update the pointer if it's the last character
|
138
|
+
if entry.info.size < entry.max
|
139
|
+
entry.left_char += 1
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Update the entry field.
|
144
|
+
entry.drawField
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Do we want a shadow?
|
149
|
+
if shadow
|
150
|
+
@shadow_win = Ncurses.subwin(rndkscreen.window, box_height, box_width,
|
151
|
+
ypos + 1, xpos + 1)
|
152
|
+
end
|
153
|
+
|
154
|
+
rndkscreen.register(:ENTRY, self)
|
155
|
+
end
|
156
|
+
|
157
|
+
# This means you want to use the given entry field. It takes input
|
158
|
+
# from the keyboard, and when it's done, it fills the entry info
|
159
|
+
# element of the structure with what was typed.
|
160
|
+
def activate(actions)
|
161
|
+
input = 0
|
162
|
+
ret = 0
|
163
|
+
|
164
|
+
# Draw the widget.
|
165
|
+
self.draw(@box)
|
166
|
+
|
167
|
+
if actions.nil? or actions.size == 0
|
168
|
+
while true
|
169
|
+
input = self.getch([])
|
170
|
+
|
171
|
+
# Inject the character into the widget.
|
172
|
+
ret = self.inject(input)
|
173
|
+
if @exit_type != :EARLY_EXIT
|
174
|
+
return ret
|
175
|
+
end
|
176
|
+
end
|
177
|
+
else
|
178
|
+
# Inject each character one at a time.
|
179
|
+
actions.each do |action|
|
180
|
+
ret = self.inject(action)
|
181
|
+
if @exit_type != :EARLY_EXIT
|
182
|
+
return ret
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Make sure we return the correct info.
|
188
|
+
if @exit_type == :NORMAL
|
189
|
+
return @info
|
190
|
+
else
|
191
|
+
return 0
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def setPositionToEnd
|
196
|
+
if @info.size >= @field_width
|
197
|
+
if @info.size < @max
|
198
|
+
char_count = @field_width - 1
|
199
|
+
@left_char = @info.size - char_count
|
200
|
+
@screen_col = char_count
|
201
|
+
else
|
202
|
+
@left_char = @info.size - @field_width
|
203
|
+
@screen_col = @info.size - 1
|
204
|
+
end
|
205
|
+
else
|
206
|
+
@left_char = 0
|
207
|
+
@screen_col = @info.size
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# This injects a single character into the widget.
|
212
|
+
def inject(input)
|
213
|
+
pp_return = 1
|
214
|
+
ret = 1
|
215
|
+
complete = false
|
216
|
+
|
217
|
+
# Set the exit type
|
218
|
+
self.setExitType(0)
|
219
|
+
|
220
|
+
# Refresh the widget field.
|
221
|
+
self.drawField
|
222
|
+
|
223
|
+
unless @pre_process_func.nil?
|
224
|
+
pp_return = @pre_process_func.call(:ENTRY, self,
|
225
|
+
@pre_process_data, input)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Should we continue?
|
229
|
+
if pp_return != 0
|
230
|
+
# Check a predefined binding
|
231
|
+
if self.checkBind(:ENTRY, input)
|
232
|
+
complete = true
|
233
|
+
else
|
234
|
+
curr_pos = @screen_col + @left_char
|
235
|
+
|
236
|
+
case input
|
237
|
+
when Ncurses::KEY_UP, Ncurses::KEY_DOWN
|
238
|
+
RNDK.beep
|
239
|
+
when Ncurses::KEY_HOME
|
240
|
+
@left_char = 0
|
241
|
+
@screen_col = 0
|
242
|
+
self.drawField
|
243
|
+
when RNDK::TRANSPOSE
|
244
|
+
if curr_pos >= @info.size - 1
|
245
|
+
RNDK.beep
|
246
|
+
else
|
247
|
+
holder = @info[curr_pos]
|
248
|
+
@info[curr_pos] = @info[curr_pos + 1]
|
249
|
+
@info[curr_pos + 1] = holder
|
250
|
+
self.drawField
|
251
|
+
end
|
252
|
+
when Ncurses::KEY_END
|
253
|
+
self.setPositionToEnd
|
254
|
+
self.drawField
|
255
|
+
when Ncurses::KEY_LEFT
|
256
|
+
if curr_pos <= 0
|
257
|
+
RNDK.beep
|
258
|
+
elsif @screen_col == 0
|
259
|
+
# Scroll left.
|
260
|
+
@left_char -= 1
|
261
|
+
self.drawField
|
262
|
+
else
|
263
|
+
@screen_col -= 1
|
264
|
+
Ncurses.wmove(@field_win, 0, @screen_col)
|
265
|
+
end
|
266
|
+
when Ncurses::KEY_RIGHT
|
267
|
+
if curr_pos >= @info.size
|
268
|
+
RNDK.beep
|
269
|
+
elsif @screen_col == @field_width - 1
|
270
|
+
# Scroll to the right.
|
271
|
+
@left_char += 1
|
272
|
+
self.drawField
|
273
|
+
else
|
274
|
+
# Move right.
|
275
|
+
@screen_col += 1
|
276
|
+
Ncurses.wmove(@field_win, 0, @screen_col)
|
277
|
+
end
|
278
|
+
when Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC
|
279
|
+
if @disp_type == :VIEWONLY
|
280
|
+
RNDK.beep
|
281
|
+
else
|
282
|
+
success = false
|
283
|
+
if input == Ncurses::KEY_BACKSPACE
|
284
|
+
curr_pos -= 1
|
285
|
+
end
|
286
|
+
|
287
|
+
if curr_pos >= 0 && @info.size > 0
|
288
|
+
if curr_pos < @info.size
|
289
|
+
@info = @info[0...curr_pos] + @info[curr_pos+1..-1]
|
290
|
+
success = true
|
291
|
+
elsif input == Ncurses::KEY_BACKSPACE
|
292
|
+
@info = @info[0...-1]
|
293
|
+
success = true
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
if success
|
298
|
+
if input == Ncurses::KEY_BACKSPACE
|
299
|
+
if @screen_col > 0
|
300
|
+
@screen_col -= 1
|
301
|
+
else
|
302
|
+
@left_char -= 1
|
303
|
+
end
|
304
|
+
end
|
305
|
+
self.drawField
|
306
|
+
else
|
307
|
+
RNDK.beep
|
308
|
+
end
|
309
|
+
end
|
310
|
+
when RNDK::KEY_ESC
|
311
|
+
self.setExitType(input)
|
312
|
+
complete = true
|
313
|
+
when RNDK::ERASE
|
314
|
+
if @info.size != 0
|
315
|
+
self.clean
|
316
|
+
self.drawField
|
317
|
+
end
|
318
|
+
when RNDK::CUT
|
319
|
+
if @info.size != 0
|
320
|
+
@@g_paste_buffer = @info.clone
|
321
|
+
self.clean
|
322
|
+
self.drawField
|
323
|
+
else
|
324
|
+
RNDK.beep
|
325
|
+
end
|
326
|
+
when RNDK::COPY
|
327
|
+
if @info.size != 0
|
328
|
+
@@g_paste_buffer = @info.clone
|
329
|
+
else
|
330
|
+
RNDK.beep
|
331
|
+
end
|
332
|
+
when RNDK::PASTE
|
333
|
+
if @@g_paste_buffer != 0
|
334
|
+
self.setValue(@@g_paste_buffer)
|
335
|
+
self.drawField
|
336
|
+
else
|
337
|
+
RNDK.beep
|
338
|
+
end
|
339
|
+
when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
|
340
|
+
if @info.size >= @min
|
341
|
+
self.setExitType(input)
|
342
|
+
ret = @info
|
343
|
+
complete = true
|
344
|
+
else
|
345
|
+
RNDK.beep
|
346
|
+
end
|
347
|
+
when Ncurses::ERR
|
348
|
+
self.setExitType(input)
|
349
|
+
complete = true
|
350
|
+
when RNDK::REFRESH
|
351
|
+
@screen.erase
|
352
|
+
@screen.refresh
|
353
|
+
else
|
354
|
+
@callbackfn.call(self, input)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
if !complete && !(@post_process_func.nil?)
|
359
|
+
@post_process_func.call(:ENTRY, self, @post_process_data, input)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
unless complete
|
364
|
+
self.setExitType(0)
|
365
|
+
end
|
366
|
+
|
367
|
+
@result_data = ret
|
368
|
+
return ret
|
369
|
+
end
|
370
|
+
|
371
|
+
# This moves the entry field to the given location.
|
372
|
+
def move(xplace, yplace, relative, refresh_flag)
|
373
|
+
windows = [@win, @field_win, @label_win, @shadow_win]
|
374
|
+
self.move_specific(xplace, yplace, relative, refresh_flag,
|
375
|
+
windows, [])
|
376
|
+
end
|
377
|
+
|
378
|
+
# This erases the information in the entry field and redraws
|
379
|
+
# a clean and empty entry field.
|
380
|
+
def clean
|
381
|
+
width = @field_width
|
382
|
+
|
383
|
+
@info = ''
|
384
|
+
|
385
|
+
# Clean the entry screen field.
|
386
|
+
Ncurses.mvwhline(@field_win, 0, 0, @filler.ord, width)
|
387
|
+
|
388
|
+
# Reset some variables
|
389
|
+
@screen_col = 0
|
390
|
+
@left_char = 0
|
391
|
+
|
392
|
+
# Refresh the entry field.
|
393
|
+
Ncurses.wrefresh @field_win
|
394
|
+
end
|
395
|
+
|
396
|
+
# This draws the entry field.
|
397
|
+
def draw(box)
|
398
|
+
# Did we ask for a shadow?
|
399
|
+
unless @shadow_win.nil?
|
400
|
+
Draw.drawShadow @shadow_win
|
401
|
+
end
|
402
|
+
|
403
|
+
# Box the widget if asked.
|
404
|
+
if box
|
405
|
+
Draw.drawObjBox(@win, self)
|
406
|
+
end
|
407
|
+
|
408
|
+
self.drawTitle @win
|
409
|
+
|
410
|
+
Ncurses.wrefresh @win
|
411
|
+
|
412
|
+
# Draw in the label to the widget.
|
413
|
+
unless @label_win.nil?
|
414
|
+
Draw.writeChtype(@label_win,
|
415
|
+
0,
|
416
|
+
0,
|
417
|
+
@label,
|
418
|
+
RNDK::HORIZONTAL,
|
419
|
+
0,
|
420
|
+
@label_len)
|
421
|
+
Ncurses.wrefresh @label_win
|
422
|
+
end
|
423
|
+
|
424
|
+
self.drawField
|
425
|
+
end
|
426
|
+
|
427
|
+
def drawField
|
428
|
+
# Draw in the filler characters.
|
429
|
+
Ncurses.mvwhline(@field_win, 0, 0, @filler.ord, @field_width)
|
430
|
+
|
431
|
+
# If there is information in the field then draw it in.
|
432
|
+
if !(@info.nil?) && @info.size > 0
|
433
|
+
# Redraw the field.
|
434
|
+
if Display.isHiddenDisplayType(@disp_type)
|
435
|
+
(@left_char...@info.size).each do |x|
|
436
|
+
Ncurses.mvwaddch(@field_win, 0, x - @left_char, @hidden)
|
437
|
+
end
|
438
|
+
else
|
439
|
+
(@left_char...@info.size).each do |x|
|
440
|
+
Ncurses.mvwaddch(@field_win, 0, x - @left_char, @info[x].ord | @field_attr)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
Ncurses.wmove(@field_win, 0, @screen_col)
|
444
|
+
end
|
445
|
+
|
446
|
+
Ncurses.wrefresh @field_win
|
447
|
+
end
|
448
|
+
|
449
|
+
# This erases an entry widget from the screen.
|
450
|
+
def erase
|
451
|
+
if self.validRNDKObject
|
452
|
+
RNDK.eraseCursesWindow(@field_win)
|
453
|
+
RNDK.eraseCursesWindow(@label_win)
|
454
|
+
RNDK.eraseCursesWindow(@win)
|
455
|
+
RNDK.eraseCursesWindow(@shadow_win)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
# This destroys an entry widget.
|
460
|
+
def destroy
|
461
|
+
self.cleanTitle
|
462
|
+
|
463
|
+
RNDK.deleteCursesWindow(@field_win)
|
464
|
+
RNDK.deleteCursesWindow(@label_win)
|
465
|
+
RNDK.deleteCursesWindow(@shadow_win)
|
466
|
+
RNDK.deleteCursesWindow(@win)
|
467
|
+
|
468
|
+
self.cleanBindings(:ENTRY)
|
469
|
+
|
470
|
+
RNDK::Screen.unregister(:ENTRY, self)
|
471
|
+
end
|
472
|
+
|
473
|
+
# This sets specific attributes of the entry field.
|
474
|
+
def set(value, min, max, box)
|
475
|
+
self.setValue(value)
|
476
|
+
self.setMin(min)
|
477
|
+
self.setMax(max)
|
478
|
+
end
|
479
|
+
|
480
|
+
# This removes the old information in the entry field and keeps
|
481
|
+
# the new information given.
|
482
|
+
def setValue(new_value)
|
483
|
+
if new_value.nil?
|
484
|
+
@info = ''
|
485
|
+
|
486
|
+
@left_char = 0
|
487
|
+
@screen_col = 0
|
488
|
+
else
|
489
|
+
@info = new_value.clone
|
490
|
+
|
491
|
+
self.setPositionToEnd
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
def getValue
|
496
|
+
return @info
|
497
|
+
end
|
498
|
+
|
499
|
+
# This sets the maximum length of the string that will be accepted
|
500
|
+
def setMax(max)
|
501
|
+
@max = max
|
502
|
+
end
|
503
|
+
|
504
|
+
def getMax
|
505
|
+
@max
|
506
|
+
end
|
507
|
+
|
508
|
+
# This sets the minimum length of the string that will be accepted.
|
509
|
+
def setMin(min)
|
510
|
+
@min = min
|
511
|
+
end
|
512
|
+
|
513
|
+
def getMin
|
514
|
+
@min
|
515
|
+
end
|
516
|
+
|
517
|
+
# This sets the filler character to be used in the entry field.
|
518
|
+
def setFillerChar(filler_char)
|
519
|
+
@filler = filler_char
|
520
|
+
end
|
521
|
+
|
522
|
+
def getFillerChar
|
523
|
+
@filler
|
524
|
+
end
|
525
|
+
|
526
|
+
# This sets the character to use when a hidden type is used.
|
527
|
+
def setHiddenChar(hidden_characer)
|
528
|
+
@hidden = hidden_character
|
529
|
+
end
|
530
|
+
|
531
|
+
def getHiddenChar
|
532
|
+
@hidden
|
533
|
+
end
|
534
|
+
|
535
|
+
# This sets the background attribute of the widget.
|
536
|
+
def setBKattr(attrib)
|
537
|
+
Ncurses.wbkgd(@win, attrib)
|
538
|
+
Ncurses.wbkgd(@field_win, attrib)
|
539
|
+
unless @label_win.nil?
|
540
|
+
@label_win.wbkgd(attrib)
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
# This sets the attribute of the entry field.
|
545
|
+
def setHighlight(highlight, cursor)
|
546
|
+
Ncurses.wbkgd(@field_win, highlight)
|
547
|
+
@field_attr = highlight
|
548
|
+
Ncurses.curs_set(cursor)
|
549
|
+
# FIXME(original) - if (cursor) { move the cursor to this widget }
|
550
|
+
end
|
551
|
+
|
552
|
+
# This sets the entry field callback function.
|
553
|
+
def setCB(callback)
|
554
|
+
@callbackfn = callback
|
555
|
+
end
|
556
|
+
|
557
|
+
def focus
|
558
|
+
Ncurses.wmove(@field_win, 0, @screen_col)
|
559
|
+
Ncurses.wrefresh @field_win
|
560
|
+
end
|
561
|
+
|
562
|
+
def unfocus
|
563
|
+
self.draw(box)
|
564
|
+
Ncurses.wrefresh @field_win
|
565
|
+
end
|
566
|
+
|
567
|
+
def position
|
568
|
+
super(@win)
|
569
|
+
end
|
570
|
+
|
571
|
+
def object_type
|
572
|
+
:ENTRY
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|