cdk 0.9.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/lib/cdk.rb +916 -0
- data/lib/cdk/alphalist.rb +562 -0
- data/lib/cdk/buttonbox.rb +354 -0
- data/lib/cdk/calendar.rb +770 -0
- data/lib/cdk/cdk_objs.rb +463 -0
- data/lib/cdk/dialog.rb +727 -0
- data/lib/cdk/display.rb +63 -0
- data/lib/cdk/draw.rb +233 -0
- data/lib/cdk/dscale.rb +13 -0
- data/lib/cdk/entry.rb +556 -0
- data/lib/cdk/fscale.rb +44 -0
- data/lib/cdk/fselect.rb +940 -0
- data/lib/cdk/fslider.rb +61 -0
- data/lib/cdk/histogram.rb +410 -0
- data/lib/cdk/itemlist.rb +475 -0
- data/lib/cdk/label.rb +207 -0
- data/lib/cdk/marquee.rb +241 -0
- data/lib/cdk/matrix.rb +1176 -0
- data/lib/cdk/mentry.rb +614 -0
- data/lib/cdk/menu.rb +448 -0
- data/lib/cdk/radio.rb +533 -0
- data/lib/cdk/scale.rb +525 -0
- data/lib/cdk/screen.rb +280 -0
- data/lib/cdk/scroll.rb +994 -0
- data/lib/cdk/scroller.rb +183 -0
- data/lib/cdk/selection.rb +619 -0
- data/lib/cdk/slider.rb +541 -0
- data/lib/cdk/swindow.rb +762 -0
- data/lib/cdk/template.rb +562 -0
- data/lib/cdk/traverse.rb +289 -0
- data/lib/cdk/uscale.rb +14 -0
- data/lib/cdk/uslider.rb +14 -0
- data/lib/cdk/viewer.rb +812 -0
- metadata +91 -0
data/lib/cdk/display.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module CDK
|
2
|
+
module Display
|
3
|
+
# Given a string, returns the equivalent display type
|
4
|
+
def Display.char2DisplayType(string)
|
5
|
+
table = {
|
6
|
+
"CHAR" => :CHAR,
|
7
|
+
"HCHAR" => :HCHAR,
|
8
|
+
"INT" => :INT,
|
9
|
+
"HINT" => :HINT,
|
10
|
+
"UCHAR" => :UCHAR,
|
11
|
+
"LCHAR" => :LCHAR,
|
12
|
+
"UHCHAR" => :UHCHAR,
|
13
|
+
"LHCHAR" => :LHCHAR,
|
14
|
+
"MIXED" => :MIXED,
|
15
|
+
"HMIXED" => :HMIXED,
|
16
|
+
"UMIXED" => :UMIXED,
|
17
|
+
"LMIXED" => :LMIXED,
|
18
|
+
"UHMIXED" => :UHMIXED,
|
19
|
+
"LHMIXED" => :LHMIXED,
|
20
|
+
"VIEWONLY" => :VIEWONLY,
|
21
|
+
0 => :INVALID
|
22
|
+
}
|
23
|
+
|
24
|
+
if table.include?(string)
|
25
|
+
table[string]
|
26
|
+
else
|
27
|
+
:INVALID
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Tell if a display type is "hidden"
|
32
|
+
def Display.isHiddenDisplayType(type)
|
33
|
+
case type
|
34
|
+
when :HCHAR, :HINT, :HMIXED, :LHCHAR, :LHMIXED, :UHCHAR, :UHMIXED
|
35
|
+
true
|
36
|
+
when :CHAR, :INT, :INVALID, :LCHAR, :LMIXED, :MIXED, :UCHAR,
|
37
|
+
:UMIXED, :VIEWONLY
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Given a character input, check if it is allowed by the display type
|
43
|
+
# and return the character to apply to the display, or ERR if not
|
44
|
+
def Display.filterByDisplayType(type, input)
|
45
|
+
result = input
|
46
|
+
if !CDK.isChar(input)
|
47
|
+
result = Ncurses::ERR
|
48
|
+
elsif [:INT, :HINT].include?(type) && !CDK.digit?(result.chr)
|
49
|
+
result = Ncurses::ERR
|
50
|
+
elsif [:CHAR, :UCHAR, :LCHAR, :UHCHAR, :LHCHAR].include?(type) && CDK.digit?(result.chr)
|
51
|
+
result = Ncurses::ERR
|
52
|
+
elsif type == :VIEWONLY
|
53
|
+
result = ERR
|
54
|
+
elsif [:UCHAR, :UHCHAR, :UMIXED, :UHMIXED].include?(type) && CDK.alpha?(result.chr)
|
55
|
+
result = result.chr.upcase.ord
|
56
|
+
elsif [:LCHAR, :LHCHAR, :LMIXED, :LHMIXED].include?(type) && CDK.alpha?(result.chr)
|
57
|
+
result = result.chr.downcase.ord
|
58
|
+
end
|
59
|
+
|
60
|
+
return result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/cdk/draw.rb
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
module CDK
|
2
|
+
module Draw
|
3
|
+
# This sets up a basic set of color pairs. These can be redefined if wanted
|
4
|
+
def Draw.initCDKColor
|
5
|
+
color = [Ncurses::COLOR_WHITE, Ncurses::COLOR_RED, Ncurses::COLOR_GREEN,
|
6
|
+
Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLUE, Ncurses::COLOR_MAGENTA,
|
7
|
+
Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK]
|
8
|
+
pair = 1
|
9
|
+
|
10
|
+
if Ncurses.has_colors?
|
11
|
+
# XXX: Only checks if terminal has colours not if colours are started
|
12
|
+
Ncurses.start_color
|
13
|
+
limit = if Ncurses.COLORS < 8 then Ncurses.COLORS else 8 end
|
14
|
+
|
15
|
+
# Create the color pairs
|
16
|
+
(0...limit).each do |fg|
|
17
|
+
(0...limit).each do |bg|
|
18
|
+
Ncurses.init_pair(pair, color[fg], color[bg])
|
19
|
+
pair += 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# This prints out a box around a window with attributes
|
26
|
+
def Draw.boxWindow(window, attr)
|
27
|
+
tlx = 0
|
28
|
+
tly = 0
|
29
|
+
brx = window.getmaxx - 1
|
30
|
+
bry = window.getmaxy - 1
|
31
|
+
|
32
|
+
# Draw horizontal lines.
|
33
|
+
window.mvwhline(tly, 0, Ncurses::ACS_HLINE | attr, window.getmaxx)
|
34
|
+
window.mvwhline(bry, 0, Ncurses::ACS_HLINE | attr, window.getmaxx)
|
35
|
+
|
36
|
+
# Draw horizontal lines.
|
37
|
+
window.mvwvline(0, tlx, Ncurses::ACS_VLINE | attr, window.getmaxy)
|
38
|
+
window.mvwvline(0, brx, Ncurses::ACS_VLINE | attr, window.getmaxy)
|
39
|
+
|
40
|
+
# Draw in the corners.
|
41
|
+
window.mvwaddch(tly, tlx, Ncurses::ACS_ULCORNER | attr)
|
42
|
+
window.mvwaddch(tly, brx, Ncurses::ACS_URCORNER | attr)
|
43
|
+
window.mvwaddch(bry, tlx, Ncurses::ACS_LLCORNER | attr)
|
44
|
+
window.mvwaddch(bry, brx, Ncurses::ACS_LRCORNER | attr)
|
45
|
+
window.wrefresh
|
46
|
+
end
|
47
|
+
|
48
|
+
# This draws a box with attributes and lets the user define each
|
49
|
+
# element of the box
|
50
|
+
def Draw.attrbox(win, tlc, trc, blc, brc, horz, vert, attr)
|
51
|
+
x1 = 0
|
52
|
+
y1 = 0
|
53
|
+
y2 = win.getmaxy - 1
|
54
|
+
x2 = win.getmaxx - 1
|
55
|
+
count = 0
|
56
|
+
|
57
|
+
# Draw horizontal lines
|
58
|
+
if horz != 0
|
59
|
+
win.mvwhline(y1, 0, horz | attr, win.getmaxx)
|
60
|
+
win.mvwhline(y2, 0, horz | attr, win.getmaxx)
|
61
|
+
count += 1
|
62
|
+
end
|
63
|
+
|
64
|
+
# Draw vertical lines
|
65
|
+
if vert != 0
|
66
|
+
win.mvwvline(0, x1, vert | attr, win.getmaxy)
|
67
|
+
win.mvwvline(0, x2, vert | attr, win.getmaxy)
|
68
|
+
count += 1
|
69
|
+
end
|
70
|
+
|
71
|
+
# Draw in the corners.
|
72
|
+
if tlc != 0
|
73
|
+
win.mvwaddch(y1, x1, tlc | attr)
|
74
|
+
count += 1
|
75
|
+
end
|
76
|
+
if trc != 0
|
77
|
+
win.mvwaddch(y1, x2, trc | attr)
|
78
|
+
count += 1
|
79
|
+
end
|
80
|
+
if blc != 0
|
81
|
+
win.mvwaddch(y2, x1, blc | attr)
|
82
|
+
count += 1
|
83
|
+
end
|
84
|
+
if brc != 0
|
85
|
+
win.mvwaddch(y2, x2, brc | attr)
|
86
|
+
count += 1
|
87
|
+
end
|
88
|
+
if count != 0
|
89
|
+
win.wrefresh
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Draw a box around the given window using the object's defined
|
94
|
+
# line-drawing characters
|
95
|
+
def Draw.drawObjBox(win, object)
|
96
|
+
Draw.attrbox(win,
|
97
|
+
object.ULChar, object.URChar, object.LLChar, object.LRChar,
|
98
|
+
object.HZChar, object.VTChar, object.BXAttr)
|
99
|
+
end
|
100
|
+
|
101
|
+
# This draws a line on the given window. (odd angle lines not working yet)
|
102
|
+
def Draw.drawLine(window, startx, starty, endx, endy, line)
|
103
|
+
xdiff = endx - startx
|
104
|
+
ydiff = endy - starty
|
105
|
+
x = 0
|
106
|
+
y = 0
|
107
|
+
|
108
|
+
# Determine if we're drawing a horizontal or vertical line.
|
109
|
+
if ydiff == 0
|
110
|
+
if xdiff > 0
|
111
|
+
window.mvwhline(starty, startx, line, xdiff)
|
112
|
+
end
|
113
|
+
elsif xdiff == 0
|
114
|
+
if ydiff > 0
|
115
|
+
window.mvwvline(starty, startx, line, ydiff)
|
116
|
+
end
|
117
|
+
else
|
118
|
+
# We need to determine the angle of the line.
|
119
|
+
height = xdiff
|
120
|
+
width = ydiff
|
121
|
+
xratio = if height > width then 1 else width / height end
|
122
|
+
yration = if width > height then width / height else 1 end
|
123
|
+
xadj = 0
|
124
|
+
yadj = 0
|
125
|
+
|
126
|
+
# Set the vars
|
127
|
+
x = startx
|
128
|
+
y = starty
|
129
|
+
while x!= endx && y != endy
|
130
|
+
# Add the char to the window
|
131
|
+
window.mvwaddch(y, x, line)
|
132
|
+
|
133
|
+
# Make the x and y adjustments.
|
134
|
+
if xadj != xratio
|
135
|
+
x = if xdiff < 0 then x - 1 else x + 1 end
|
136
|
+
xadj += 1
|
137
|
+
else
|
138
|
+
xadj = 0
|
139
|
+
end
|
140
|
+
if yadj != yratio
|
141
|
+
y = if ydiff < 0 then y - 1 else y + 1 end
|
142
|
+
yadj += 1
|
143
|
+
else
|
144
|
+
yadj = 0
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# This draws a shadow around a window.
|
151
|
+
def Draw.drawShadow(shadow_win)
|
152
|
+
unless shadow_win.nil?
|
153
|
+
x_hi = shadow_win.getmaxx - 1
|
154
|
+
y_hi = shadow_win.getmaxy - 1
|
155
|
+
|
156
|
+
# Draw the line on the bottom.
|
157
|
+
shadow_win.mvwhline(y_hi, 1, Ncurses::ACS_HLINE | Ncurses::A_DIM, x_hi)
|
158
|
+
|
159
|
+
# Draw the line on teh right.
|
160
|
+
shadow_win.mvwvline(0, x_hi, Ncurses::ACS_VLINE | Ncurses::A_DIM, y_hi)
|
161
|
+
|
162
|
+
shadow_win.mvwaddch(0, x_hi, Ncurses::ACS_URCORNER | Ncurses::A_DIM)
|
163
|
+
shadow_win.mvwaddch(y_hi, 0, Ncurses::ACS_LLCORNER | Ncurses::A_DIM)
|
164
|
+
shadow_win.mvwaddch(y_hi, x_hi, Ncurses::ACS_LRCORNER | Ncurses::A_DIM)
|
165
|
+
shadow_win.wrefresh
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Write a string of blanks using writeChar()
|
170
|
+
def Draw.writeBlanks(window, xpos, ypos, align, start, endn)
|
171
|
+
if start < endn
|
172
|
+
want = (endn - start) + 1000
|
173
|
+
blanks = ''
|
174
|
+
|
175
|
+
CDK.cleanChar(blanks, want - 1, ' ')
|
176
|
+
Draw.writeChar(window, xpos, ypos, blanks, align, start, endn)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# This writes out a char string with no attributes
|
181
|
+
def Draw.writeChar(window, xpos, ypos, string, align, start, endn)
|
182
|
+
Draw.writeCharAttrib(window, xpos, ypos, string, Ncurses::A_NORMAL,
|
183
|
+
align, start, endn)
|
184
|
+
end
|
185
|
+
|
186
|
+
# This writes out a char string with attributes
|
187
|
+
def Draw.writeCharAttrib(window, xpos, ypos, string, attr, align,
|
188
|
+
start, endn)
|
189
|
+
display = endn - start
|
190
|
+
|
191
|
+
if align == CDK::HORIZONTAL
|
192
|
+
# Draw the message on a horizontal axis
|
193
|
+
display = [display, window.getmaxx - 1].min
|
194
|
+
(0...display).each do |x|
|
195
|
+
window.mvwaddch(ypos, xpos + x, string[x + start].ord | attr)
|
196
|
+
end
|
197
|
+
else
|
198
|
+
# Draw the message on a vertical axis
|
199
|
+
display = [display, window.getmaxy - 1].min
|
200
|
+
(0...display).each do |x|
|
201
|
+
window.mvwaddch(ypos + x, xpos, string[x + start].ord | attr)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# This writes out a chtype string
|
207
|
+
def Draw.writeChtype (window, xpos, ypos, string, align, start, endn)
|
208
|
+
Draw.writeChtypeAttrib(window, xpos, ypos, string, Ncurses::A_NORMAL,
|
209
|
+
align, start, endn)
|
210
|
+
end
|
211
|
+
|
212
|
+
# This writes out a chtype string with the given attributes added.
|
213
|
+
def Draw.writeChtypeAttrib(window, xpos, ypos, string, attr,
|
214
|
+
align, start, endn)
|
215
|
+
diff = endn - start
|
216
|
+
display = 0
|
217
|
+
x = 0
|
218
|
+
if align == CDK::HORIZONTAL
|
219
|
+
# Draw the message on a horizontal axis.
|
220
|
+
display = [diff, window.getmaxx - xpos].min
|
221
|
+
(0...display).each do |x|
|
222
|
+
window.mvwaddch(ypos, xpos + x, string[x + start].ord | attr)
|
223
|
+
end
|
224
|
+
else
|
225
|
+
# Draw the message on a vertical axis.
|
226
|
+
display = [diff, window.getmaxy - ypos].min
|
227
|
+
(0...display).each do |x|
|
228
|
+
window.mvwaddch(ypos + x, xpos, string[x + start].ord | attr)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
data/lib/cdk/dscale.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'fscale'
|
2
|
+
|
3
|
+
module CDK
|
4
|
+
class DSCALE < CDK::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/cdk/entry.rb
ADDED
@@ -0,0 +1,556 @@
|
|
1
|
+
require_relative 'cdk_objs'
|
2
|
+
|
3
|
+
module CDK
|
4
|
+
class ENTRY < CDK::CDKOBJS
|
5
|
+
attr_accessor :info, :left_char, :screen_col
|
6
|
+
attr_reader :win, :box_height, :box_width, :max, :field_width
|
7
|
+
attr_reader :min, :max
|
8
|
+
|
9
|
+
def initialize(cdkscreen, xplace, yplace, title, label, field_attr, filler,
|
10
|
+
disp_type, f_width, min, max, box, shadow)
|
11
|
+
super()
|
12
|
+
parent_width = cdkscreen.window.getmaxx
|
13
|
+
parent_height = cdkscreen.window.getmaxy
|
14
|
+
field_width = f_width
|
15
|
+
box_width = 0
|
16
|
+
xpos = xplace
|
17
|
+
ypos = yplace
|
18
|
+
|
19
|
+
self.setBox(box)
|
20
|
+
box_height = @border_size * 2 + 1
|
21
|
+
|
22
|
+
# If the field_width is a negative value, the field_width will be
|
23
|
+
# COLS-field_width, otherwise the field_width will be the given width.
|
24
|
+
field_width = CDK.setWidgetDimension(parent_width, field_width, 0)
|
25
|
+
box_width = field_width + 2 * @border_size
|
26
|
+
|
27
|
+
# Set some basic values of the entry field.
|
28
|
+
@label = 0
|
29
|
+
@label_len = 0
|
30
|
+
@label_win = nil
|
31
|
+
|
32
|
+
# Translate the label string to a chtype array
|
33
|
+
if !(label.nil?) && label.size > 0
|
34
|
+
label_len = [@label_len]
|
35
|
+
@label = CDK.char2Chtype(label, label_len, [])
|
36
|
+
@label_len = label_len[0]
|
37
|
+
box_width += @label_len
|
38
|
+
end
|
39
|
+
|
40
|
+
old_width = box_width
|
41
|
+
box_width = self.setTitle(title, box_width)
|
42
|
+
horizontal_adjust = (box_width - old_width) / 2
|
43
|
+
|
44
|
+
box_height += @title_lines
|
45
|
+
|
46
|
+
# Make sure we didn't extend beyond the dimensinos of the window.
|
47
|
+
box_width = [box_width, parent_width].min
|
48
|
+
box_height = [box_height, parent_height].min
|
49
|
+
field_width = [field_width,
|
50
|
+
box_width - @label_len - 2 * @border_size].min
|
51
|
+
|
52
|
+
# Rejustify the x and y positions if we need to.
|
53
|
+
xtmp = [xpos]
|
54
|
+
ytmp = [ypos]
|
55
|
+
CDK.alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
|
56
|
+
xpos = xtmp[0]
|
57
|
+
ypos = ytmp[0]
|
58
|
+
|
59
|
+
# Make the label window.
|
60
|
+
@win = cdkscreen.window.subwin(box_height, box_width, ypos, xpos)
|
61
|
+
if @win.nil?
|
62
|
+
self.destroy
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
@win.keypad(true)
|
66
|
+
|
67
|
+
# Make the field window.
|
68
|
+
@field_win = @win.subwin(1, field_width,
|
69
|
+
ypos + @title_lines + @border_size,
|
70
|
+
xpos + @label_len + horizontal_adjust + @border_size)
|
71
|
+
|
72
|
+
if @field_win.nil?
|
73
|
+
self.destroy
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
@field_win.keypad(true)
|
77
|
+
|
78
|
+
# make the label win, if we need to
|
79
|
+
if !(label.nil?) && label.size > 0
|
80
|
+
@label_win = @win.subwin(1, @label_len,
|
81
|
+
ypos + @title_lines + @border_size,
|
82
|
+
xpos + horizontal_adjust + @border_size)
|
83
|
+
end
|
84
|
+
|
85
|
+
# cleanChar (entry->info, max + 3, '\0');
|
86
|
+
@info = ''
|
87
|
+
@info_width = max + 3
|
88
|
+
|
89
|
+
# Set up the rest of the structure.
|
90
|
+
@screen = cdkscreen
|
91
|
+
@parent = cdkscreen.window
|
92
|
+
@shadow_win = nil
|
93
|
+
@field_attr = field_attr
|
94
|
+
@field_width = field_width
|
95
|
+
@filler = filler
|
96
|
+
@hidden = filler
|
97
|
+
@input_window = @field_win
|
98
|
+
@accepts_focus = true
|
99
|
+
@data_ptr = nil
|
100
|
+
@shadow = shadow
|
101
|
+
@screen_col = 0
|
102
|
+
@left_char = 0
|
103
|
+
@min = min
|
104
|
+
@max = max
|
105
|
+
@box_width = box_width
|
106
|
+
@box_height = box_height
|
107
|
+
@disp_type = disp_type
|
108
|
+
@callbackfn = lambda do |entry, character|
|
109
|
+
plainchar = Display.filterByDisplayType(entry, character)
|
110
|
+
|
111
|
+
if plainchar == Ncurses::ERR || entry.info.size >= entry.max
|
112
|
+
CDK.Beep
|
113
|
+
else
|
114
|
+
# Update the screen and pointer
|
115
|
+
if entry.screen_col != entry.field_width - 1
|
116
|
+
front = (entry.info[0...(entry.screen_col + entry.left_char)] or '')
|
117
|
+
back = (entry.info[(entry.screen_col + entry.left_char)..-1] or '')
|
118
|
+
entry.info = front + plainchar.chr + back
|
119
|
+
entry.screen_col += 1
|
120
|
+
else
|
121
|
+
# Update the character pointer.
|
122
|
+
entry.info << plainchar
|
123
|
+
# Do not update the pointer if it's the last character
|
124
|
+
if entry.info.size < entry.max
|
125
|
+
entry.left_char += 1
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Update the entry field.
|
130
|
+
entry.drawField
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Do we want a shadow?
|
135
|
+
if shadow
|
136
|
+
@shadow_win = cdkscreen.window.subwin(box_height, box_width,
|
137
|
+
ypos + 1, xpos + 1)
|
138
|
+
end
|
139
|
+
|
140
|
+
cdkscreen.register(:ENTRY, self)
|
141
|
+
end
|
142
|
+
|
143
|
+
# This means you want to use the given entry field. It takes input
|
144
|
+
# from the keyboard, and when it's done, it fills the entry info
|
145
|
+
# element of the structure with what was typed.
|
146
|
+
def activate(actions)
|
147
|
+
input = 0
|
148
|
+
ret = 0
|
149
|
+
|
150
|
+
# Draw the widget.
|
151
|
+
self.draw(@box)
|
152
|
+
|
153
|
+
if actions.nil? or actions.size == 0
|
154
|
+
while true
|
155
|
+
input = self.getch([])
|
156
|
+
|
157
|
+
# Inject the character into the widget.
|
158
|
+
ret = self.inject(input)
|
159
|
+
if @exit_type != :EARLY_EXIT
|
160
|
+
return ret
|
161
|
+
end
|
162
|
+
end
|
163
|
+
else
|
164
|
+
# Inject each character one at a time.
|
165
|
+
actions.each do |action|
|
166
|
+
ret = self.inject(action)
|
167
|
+
if @exit_type != :EARLY_EXIT
|
168
|
+
return ret
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Make sure we return the correct info.
|
174
|
+
if @exit_type == :NORMAL
|
175
|
+
return @info
|
176
|
+
else
|
177
|
+
return 0
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def setPositionToEnd
|
182
|
+
if @info.size >= @field_width
|
183
|
+
if @info.size < @max
|
184
|
+
char_count = @field_width - 1
|
185
|
+
@left_char = @info.size - char_count
|
186
|
+
@screen_col = char_count
|
187
|
+
else
|
188
|
+
@left_char = @info.size - @field_width
|
189
|
+
@screen_col = @info.size - 1
|
190
|
+
end
|
191
|
+
else
|
192
|
+
@left_char = 0
|
193
|
+
@screen_col = @info.size
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# This injects a single character into the widget.
|
198
|
+
def inject(input)
|
199
|
+
pp_return = 1
|
200
|
+
ret = 1
|
201
|
+
complete = false
|
202
|
+
|
203
|
+
# Set the exit type
|
204
|
+
self.setExitType(0)
|
205
|
+
|
206
|
+
# Refresh the widget field.
|
207
|
+
self.drawField
|
208
|
+
|
209
|
+
unless @pre_process_func.nil?
|
210
|
+
pp_return = @pre_process_func.call(:ENTRY, self,
|
211
|
+
@pre_process_data, input)
|
212
|
+
end
|
213
|
+
|
214
|
+
# Should we continue?
|
215
|
+
if pp_return != 0
|
216
|
+
# Check a predefined binding
|
217
|
+
if self.checkBind(:ENTRY, input)
|
218
|
+
complete = true
|
219
|
+
else
|
220
|
+
curr_pos = @screen_col + @left_char
|
221
|
+
|
222
|
+
case input
|
223
|
+
when Ncurses::KEY_UP, Ncurses::KEY_DOWN
|
224
|
+
CDK.Beep
|
225
|
+
when Ncurses::KEY_HOME
|
226
|
+
@left_char = 0
|
227
|
+
@screen_col = 0
|
228
|
+
self.drawField
|
229
|
+
when CDK::TRANSPOSE
|
230
|
+
if curr_pos >= @info.size - 1
|
231
|
+
CDK.Beep
|
232
|
+
else
|
233
|
+
holder = @info[curr_pos]
|
234
|
+
@info[curr_pos] = @info[curr_pos + 1]
|
235
|
+
@info[curr_pos + 1] = holder
|
236
|
+
self.drawField
|
237
|
+
end
|
238
|
+
when Ncurses::KEY_END
|
239
|
+
self.setPositionToEnd
|
240
|
+
self.drawField
|
241
|
+
when Ncurses::KEY_LEFT
|
242
|
+
if curr_pos <= 0
|
243
|
+
CDK.Beep
|
244
|
+
elsif @screen_col == 0
|
245
|
+
# Scroll left.
|
246
|
+
@left_char -= 1
|
247
|
+
self.drawField
|
248
|
+
else
|
249
|
+
@screen_col -= 1
|
250
|
+
@field_win.wmove(0, @screen_col)
|
251
|
+
end
|
252
|
+
when Ncurses::KEY_RIGHT
|
253
|
+
if curr_pos >= @info.size
|
254
|
+
CDK.Beep
|
255
|
+
elsif @screen_col == @field_width - 1
|
256
|
+
# Scroll to the right.
|
257
|
+
@left_char += 1
|
258
|
+
self.drawField
|
259
|
+
else
|
260
|
+
# Move right.
|
261
|
+
@screen_col += 1
|
262
|
+
@field_win.wmove(0, @screen_col)
|
263
|
+
end
|
264
|
+
when Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC
|
265
|
+
if @disp_type == :VIEWONLY
|
266
|
+
CDK.Beep
|
267
|
+
else
|
268
|
+
success = false
|
269
|
+
if input == Ncurses::KEY_BACKSPACE
|
270
|
+
curr_pos -= 1
|
271
|
+
end
|
272
|
+
|
273
|
+
if curr_pos >= 0 && @info.size > 0
|
274
|
+
if curr_pos < @info.size
|
275
|
+
@info = @info[0...curr_pos] + @info[curr_pos+1..-1]
|
276
|
+
success = true
|
277
|
+
elsif input == Ncurses::KEY_BACKSPACE
|
278
|
+
@info = @info[0...-1]
|
279
|
+
success = true
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
if success
|
284
|
+
if input == Ncurses::KEY_BACKSPACE
|
285
|
+
if @screen_col > 0
|
286
|
+
@screen_col -= 1
|
287
|
+
else
|
288
|
+
@left_char -= 1
|
289
|
+
end
|
290
|
+
end
|
291
|
+
self.drawField
|
292
|
+
else
|
293
|
+
CDK.Beep
|
294
|
+
end
|
295
|
+
end
|
296
|
+
when CDK::KEY_ESC
|
297
|
+
self.setExitType(input)
|
298
|
+
complete = true
|
299
|
+
when CDK::ERASE
|
300
|
+
if @info.size != 0
|
301
|
+
self.clean
|
302
|
+
self.drawField
|
303
|
+
end
|
304
|
+
when CDK::CUT
|
305
|
+
if @info.size != 0
|
306
|
+
@@g_paste_buffer = @info.clone
|
307
|
+
self.clean
|
308
|
+
self.drawField
|
309
|
+
else
|
310
|
+
CDK.Beep
|
311
|
+
end
|
312
|
+
when CDK::COPY
|
313
|
+
if @info.size != 0
|
314
|
+
@@g_paste_buffer = @info.clone
|
315
|
+
else
|
316
|
+
CDK.Beep
|
317
|
+
end
|
318
|
+
when CDK::PASTE
|
319
|
+
if @@g_paste_buffer != 0
|
320
|
+
self.setValue(@@g_paste_buffer)
|
321
|
+
self.drawField
|
322
|
+
else
|
323
|
+
CDK.Beep
|
324
|
+
end
|
325
|
+
when CDK::KEY_TAB, CDK::KEY_RETURN, Ncurses::KEY_ENTER
|
326
|
+
if @info.size >= @min
|
327
|
+
self.setExitType(input)
|
328
|
+
ret = @info
|
329
|
+
complete = true
|
330
|
+
else
|
331
|
+
CDK.Beep
|
332
|
+
end
|
333
|
+
when Ncurses::ERR
|
334
|
+
self.setExitType(input)
|
335
|
+
complete = true
|
336
|
+
when CDK::REFRESH
|
337
|
+
@screen.erase
|
338
|
+
@screen.refresh
|
339
|
+
else
|
340
|
+
@callbackfn.call(self, input)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
if !complete && !(@post_process_func.nil?)
|
345
|
+
@post_process_func.call(:ENTRY, self, @post_process_data, input)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
unless complete
|
350
|
+
self.setExitType(0)
|
351
|
+
end
|
352
|
+
|
353
|
+
@result_data = ret
|
354
|
+
return ret
|
355
|
+
end
|
356
|
+
|
357
|
+
# This moves the entry field to the given location.
|
358
|
+
def move(xplace, yplace, relative, refresh_flag)
|
359
|
+
windows = [@win, @field_win, @label_win, @shadow_win]
|
360
|
+
self.move_specific(xplace, yplace, relative, refresh_flag,
|
361
|
+
windows, [])
|
362
|
+
end
|
363
|
+
|
364
|
+
# This erases the information in the entry field and redraws
|
365
|
+
# a clean and empty entry field.
|
366
|
+
def clean
|
367
|
+
width = @field_width
|
368
|
+
|
369
|
+
@info = ''
|
370
|
+
|
371
|
+
# Clean the entry screen field.
|
372
|
+
@field_win.mvwhline(0, 0, @filler.ord, width)
|
373
|
+
|
374
|
+
# Reset some variables
|
375
|
+
@screen_col = 0
|
376
|
+
@left_char = 0
|
377
|
+
|
378
|
+
# Refresh the entry field.
|
379
|
+
@field_win.wrefresh
|
380
|
+
end
|
381
|
+
|
382
|
+
# This draws the entry field.
|
383
|
+
def draw(box)
|
384
|
+
# Did we ask for a shadow?
|
385
|
+
unless @shadow_win.nil?
|
386
|
+
Draw.drawShadow(@shadow_win)
|
387
|
+
end
|
388
|
+
|
389
|
+
# Box the widget if asked.
|
390
|
+
if box
|
391
|
+
Draw.drawObjBox(@win, self)
|
392
|
+
end
|
393
|
+
|
394
|
+
self.drawTitle(@win)
|
395
|
+
|
396
|
+
@win.wrefresh
|
397
|
+
|
398
|
+
# Draw in the label to the widget.
|
399
|
+
unless @label_win.nil?
|
400
|
+
Draw.writeChtype(@label_win, 0, 0, @label, CDK::HORIZONTAL, 0,
|
401
|
+
@label_len)
|
402
|
+
@label_win.wrefresh
|
403
|
+
end
|
404
|
+
|
405
|
+
self.drawField
|
406
|
+
end
|
407
|
+
|
408
|
+
def drawField
|
409
|
+
# Draw in the filler characters.
|
410
|
+
@field_win.mvwhline(0, 0, @filler.ord, @field_width)
|
411
|
+
|
412
|
+
# If there is information in the field then draw it in.
|
413
|
+
if !(@info.nil?) && @info.size > 0
|
414
|
+
# Redraw the field.
|
415
|
+
if Display.isHiddenDisplayType(@disp_type)
|
416
|
+
(@left_char...@info.size).each do |x|
|
417
|
+
@field_win.mvwaddch(0, x - @left_char, @hidden)
|
418
|
+
end
|
419
|
+
else
|
420
|
+
(@left_char...@info.size).each do |x|
|
421
|
+
@field_win.mvwaddch(0, x - @left_char, @info[x].ord | @field_attr)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
@field_win.wmove(0, @screen_col)
|
425
|
+
end
|
426
|
+
|
427
|
+
@field_win.wrefresh
|
428
|
+
end
|
429
|
+
|
430
|
+
# This erases an entry widget from the screen.
|
431
|
+
def erase
|
432
|
+
if self.validCDKObject
|
433
|
+
CDK.eraseCursesWindow(@field_win)
|
434
|
+
CDK.eraseCursesWindow(@label_win)
|
435
|
+
CDK.eraseCursesWindow(@win)
|
436
|
+
CDK.eraseCursesWindow(@shadow_win)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
# This destroys an entry widget.
|
441
|
+
def destroy
|
442
|
+
self.cleanTitle
|
443
|
+
|
444
|
+
CDK.deleteCursesWindow(@field_win)
|
445
|
+
CDK.deleteCursesWindow(@label_win)
|
446
|
+
CDK.deleteCursesWindow(@shadow_win)
|
447
|
+
CDK.deleteCursesWindow(@win)
|
448
|
+
|
449
|
+
self.cleanBindings(:ENTRY)
|
450
|
+
|
451
|
+
CDK::SCREEN.unregister(:ENTRY, self)
|
452
|
+
end
|
453
|
+
|
454
|
+
# This sets specific attributes of the entry field.
|
455
|
+
def set(value, min, max, box)
|
456
|
+
self.setValue(value)
|
457
|
+
self.setMin(min)
|
458
|
+
self.setMax(max)
|
459
|
+
end
|
460
|
+
|
461
|
+
# This removes the old information in the entry field and keeps
|
462
|
+
# the new information given.
|
463
|
+
def setValue(new_value)
|
464
|
+
if new_value.nil?
|
465
|
+
@info = ''
|
466
|
+
|
467
|
+
@left_char = 0
|
468
|
+
@screen_col = 0
|
469
|
+
else
|
470
|
+
@info = new_value.clone
|
471
|
+
|
472
|
+
self.setPositionToEnd
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
def getValue
|
477
|
+
return @info
|
478
|
+
end
|
479
|
+
|
480
|
+
# This sets the maximum length of the string that will be accepted
|
481
|
+
def setMax(max)
|
482
|
+
@max = max
|
483
|
+
end
|
484
|
+
|
485
|
+
def getMax
|
486
|
+
@max
|
487
|
+
end
|
488
|
+
|
489
|
+
# This sets the minimum length of the string that will be accepted.
|
490
|
+
def setMin(min)
|
491
|
+
@min = min
|
492
|
+
end
|
493
|
+
|
494
|
+
def getMin
|
495
|
+
@min
|
496
|
+
end
|
497
|
+
|
498
|
+
# This sets the filler character to be used in the entry field.
|
499
|
+
def setFillerChar(filler_char)
|
500
|
+
@filler = filler_char
|
501
|
+
end
|
502
|
+
|
503
|
+
def getFillerChar
|
504
|
+
@filler
|
505
|
+
end
|
506
|
+
|
507
|
+
# This sets the character to use when a hidden type is used.
|
508
|
+
def setHiddenChar(hidden_characer)
|
509
|
+
@hidden = hidden_character
|
510
|
+
end
|
511
|
+
|
512
|
+
def getHiddenChar
|
513
|
+
@hidden
|
514
|
+
end
|
515
|
+
|
516
|
+
# This sets the background attribute of the widget.
|
517
|
+
def setBKattr(attrib)
|
518
|
+
@win.wbkgd(attrib)
|
519
|
+
@field_win.wbkgd(attrib)
|
520
|
+
unless @label_win.nil?
|
521
|
+
@label_win.wbkgd(attrib)
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
# This sets the attribute of the entry field.
|
526
|
+
def setHighlight(highlight, cursor)
|
527
|
+
@field_win.wbkgd(highlight)
|
528
|
+
@field_attr = highlight
|
529
|
+
Ncurses.curs_set(cursor)
|
530
|
+
# FIXME(original) - if (cursor) { move the cursor to this widget }
|
531
|
+
end
|
532
|
+
|
533
|
+
# This sets the entry field callback function.
|
534
|
+
def setCB(callback)
|
535
|
+
@callbackfn = callback
|
536
|
+
end
|
537
|
+
|
538
|
+
def focus
|
539
|
+
@field_win.wmove(0, @screen_col)
|
540
|
+
@field_win.wrefresh
|
541
|
+
end
|
542
|
+
|
543
|
+
def unfocus
|
544
|
+
self.draw(box)
|
545
|
+
@field_win.wrefresh
|
546
|
+
end
|
547
|
+
|
548
|
+
def position
|
549
|
+
super(@win)
|
550
|
+
end
|
551
|
+
|
552
|
+
def object_type
|
553
|
+
:ENTRY
|
554
|
+
end
|
555
|
+
end
|
556
|
+
end
|