rndk 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -4
- data/TODO +21 -1
- data/demos/appointment.rb +279 -299
- data/demos/clock.rb +13 -8
- data/demos/rss-reader.rb +84 -0
- data/examples/01-hello-world.rb +13 -11
- data/examples/02-colors.rb +14 -21
- data/examples/03-markup.rb +7 -7
- data/examples/04-quick-widgets.rb +2 -2
- data/examples/05-position-widget.rb +50 -31
- data/examples/06-callbacks.rb +77 -0
- data/examples/07-traverse.rb +90 -0
- data/examples/10-all-widgets.rb +165 -0
- data/examples/calendar.rb +20 -32
- data/examples/entry.rb +15 -20
- data/examples/label.rb +11 -11
- data/examples/scroll.rb +16 -60
- data/examples/slider.rb +18 -19
- data/examples/viewer.rb +65 -0
- data/lib/rndk.rb +28 -7
- data/lib/rndk/alphalist.rb +309 -313
- data/lib/rndk/button.rb +239 -157
- data/lib/rndk/buttonbox.rb +136 -103
- data/lib/rndk/calendar.rb +246 -203
- data/lib/rndk/core/color.rb +63 -13
- data/lib/rndk/core/display.rb +1 -1
- data/lib/rndk/core/draw.rb +11 -11
- data/lib/rndk/core/markup.rb +21 -21
- data/lib/rndk/core/quick_widgets.rb +75 -96
- data/lib/rndk/core/screen.rb +145 -102
- data/lib/rndk/core/traverse.rb +150 -136
- data/lib/rndk/core/utils.rb +5 -6
- data/lib/rndk/core/widget.rb +207 -191
- data/lib/rndk/core/widget_bind.rb +108 -0
- data/lib/rndk/dialog.rb +88 -56
- data/lib/rndk/entry.rb +79 -64
- data/lib/rndk/fscale.rb +38 -20
- data/lib/rndk/fslider.rb +38 -23
- data/lib/rndk/graph.rb +92 -53
- data/lib/rndk/itemlist.rb +80 -62
- data/lib/rndk/label.rb +111 -77
- data/lib/rndk/radio.rb +138 -128
- data/lib/rndk/scale.rb +123 -122
- data/lib/rndk/scroll.rb +444 -391
- data/lib/rndk/scroller.rb +21 -21
- data/lib/rndk/slider.rb +149 -140
- data/lib/rndk/template.rb +74 -61
- data/lib/rndk/version.rb +1 -1
- data/lib/rndk/viewer.rb +499 -298
- metadata +8 -14
- data/demos/fileview.rb +0 -141
- data/lib/rndk/dscale.rb +0 -13
- data/lib/rndk/fselect.rb +0 -938
- data/lib/rndk/histogram.rb +0 -412
- data/lib/rndk/marquee.rb +0 -244
- data/lib/rndk/matrix.rb +0 -1189
- data/lib/rndk/mentry.rb +0 -619
- data/lib/rndk/menu.rb +0 -478
- data/lib/rndk/selection.rb +0 -630
- data/lib/rndk/swindow.rb +0 -766
- data/lib/rndk/uscale.rb +0 -14
- data/lib/rndk/uslider.rb +0 -14
data/lib/rndk/buttonbox.rb
CHANGED
@@ -1,14 +1,43 @@
|
|
1
1
|
require 'rndk'
|
2
2
|
|
3
3
|
module RNDK
|
4
|
-
class
|
4
|
+
class Buttonbox < Widget
|
5
5
|
attr_reader :current_button
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
buttons, button_count, highlight, box, shadow)
|
7
|
+
def initialize(screen, config={})
|
9
8
|
super()
|
10
|
-
|
11
|
-
|
9
|
+
@widget_type = :buttonbox
|
10
|
+
@supported_signals += [:before_pressing, :pressed]
|
11
|
+
|
12
|
+
x = 0
|
13
|
+
y = 0
|
14
|
+
width = 0
|
15
|
+
height = 0
|
16
|
+
title = "buttonbox"
|
17
|
+
buttons = []
|
18
|
+
button_rows = 0
|
19
|
+
button_cols = 0
|
20
|
+
highlight = RNDK::Color[:reverse]
|
21
|
+
box = true
|
22
|
+
shadow = false
|
23
|
+
|
24
|
+
config.each do |key, val|
|
25
|
+
x = val if key == :x
|
26
|
+
y = val if key == :y
|
27
|
+
width = val if key == :width
|
28
|
+
height = val if key == :height
|
29
|
+
title = val if key == :title
|
30
|
+
button_rows = val if key == :button_rows
|
31
|
+
button_cols = val if key == :button_cols
|
32
|
+
buttons = val if key == :buttons
|
33
|
+
highlight = val if key == :highlight
|
34
|
+
box = val if key == :box
|
35
|
+
shadow = val if key == :shadow
|
36
|
+
end
|
37
|
+
|
38
|
+
button_count = buttons.size
|
39
|
+
parent_width = Ncurses.getmaxx(screen.window)
|
40
|
+
parent_height = Ncurses.getmaxy(screen.window)
|
12
41
|
col_width = 0
|
13
42
|
current_button = 0
|
14
43
|
@button = []
|
@@ -28,12 +57,12 @@ module RNDK
|
|
28
57
|
@col_adjust = 0
|
29
58
|
|
30
59
|
# If the height is a negative value, the height will be
|
31
|
-
#
|
32
|
-
box_height = RNDK.
|
60
|
+
# BUTTON_ROWS-height, otherwise the height will be the given height.
|
61
|
+
box_height = RNDK.set_widget_dimension(parent_height, height, button_rows + 1)
|
33
62
|
|
34
63
|
# If the width is a negative value, the width will be
|
35
64
|
# COLS-width, otherwise the width will be the given width.
|
36
|
-
box_width = RNDK.
|
65
|
+
box_width = RNDK.set_widget_dimension(parent_width, width, 0)
|
37
66
|
|
38
67
|
box_width = self.set_title(title, box_width)
|
39
68
|
|
@@ -45,11 +74,11 @@ module RNDK
|
|
45
74
|
end
|
46
75
|
|
47
76
|
# Set the button positions.
|
48
|
-
(0...
|
77
|
+
(0...button_cols).each do |x|
|
49
78
|
max_col_width = -2**31
|
50
79
|
|
51
80
|
# Look for the widest item in this column.
|
52
|
-
(0...
|
81
|
+
(0...button_rows).each do |y|
|
53
82
|
if current_button < button_count
|
54
83
|
max_col_width = [@button_len[current_button], max_col_width].max
|
55
84
|
current_button += 1
|
@@ -67,37 +96,37 @@ module RNDK
|
|
67
96
|
box_height = [box_height, parent_height].min
|
68
97
|
|
69
98
|
# Now we have to readjust the x and y positions
|
70
|
-
xtmp = [
|
71
|
-
ytmp = [
|
72
|
-
RNDK.alignxy(
|
99
|
+
xtmp = [x]
|
100
|
+
ytmp = [y]
|
101
|
+
RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
|
73
102
|
xpos = xtmp[0]
|
74
103
|
ypos = ytmp[0]
|
75
104
|
|
76
105
|
# Set up the buttonbox box attributes.
|
77
|
-
@screen =
|
78
|
-
@parent =
|
106
|
+
@screen = screen
|
107
|
+
@parent = screen.window
|
79
108
|
@win = Ncurses.newwin(box_height, box_width, ypos, xpos)
|
80
109
|
@shadow_win = nil
|
81
110
|
@button_count = button_count
|
82
111
|
@current_button = 0
|
83
|
-
@
|
84
|
-
@
|
112
|
+
@button_rows = button_rows
|
113
|
+
@button_cols = [button_count, button_cols].min
|
85
114
|
@box_height = box_height
|
86
115
|
@box_width = box_width
|
87
116
|
@highlight = highlight
|
88
117
|
@accepts_focus = true
|
89
118
|
@input_window = @win
|
90
119
|
@shadow = shadow
|
91
|
-
@
|
120
|
+
@button_color = RNDK::Color[:normal]
|
92
121
|
|
93
122
|
# Set up the row adjustment.
|
94
|
-
if box_height -
|
95
|
-
@row_adjust = (box_height -
|
123
|
+
if box_height - button_rows - @title_lines > 0
|
124
|
+
@row_adjust = (box_height - button_rows - @title_lines) / @button_rows
|
96
125
|
end
|
97
126
|
|
98
127
|
# Set the col adjustment
|
99
128
|
if box_width - col_width > 0
|
100
|
-
@col_adjust = ((box_width - col_width) / @
|
129
|
+
@col_adjust = ((box_width - col_width) / @button_cols) - 1
|
101
130
|
end
|
102
131
|
|
103
132
|
# If we couldn't create the window, we should return a null value.
|
@@ -114,17 +143,17 @@ module RNDK
|
|
114
143
|
end
|
115
144
|
|
116
145
|
# Register this baby.
|
117
|
-
|
146
|
+
screen.register(@widget_type, self)
|
118
147
|
end
|
119
148
|
|
120
149
|
# This activates the widget.
|
121
|
-
def activate(actions)
|
150
|
+
def activate(actions=[])
|
122
151
|
# Draw the buttonbox box.
|
123
|
-
self.draw
|
152
|
+
self.draw
|
124
153
|
|
125
154
|
if actions.nil? || actions.size == 0
|
126
155
|
while true
|
127
|
-
input = self.getch
|
156
|
+
input = self.getch
|
128
157
|
|
129
158
|
# Inject the characer into the widget.
|
130
159
|
ret = self.inject(input)
|
@@ -148,39 +177,39 @@ module RNDK
|
|
148
177
|
end
|
149
178
|
|
150
179
|
# This injects a single character into the widget.
|
151
|
-
def inject
|
180
|
+
def inject input
|
152
181
|
first_button = 0
|
153
182
|
last_button = @button_count - 1
|
154
|
-
pp_return =
|
155
|
-
ret =
|
183
|
+
pp_return = true
|
184
|
+
ret = false
|
156
185
|
complete = false
|
157
186
|
|
158
187
|
# Set the exit type
|
159
188
|
self.set_exit_type(0)
|
160
189
|
|
161
|
-
|
162
|
-
pp_return = @pre_process_func.call(:BUTTONBOX, self,
|
163
|
-
@pre_process_data, input)
|
164
|
-
end
|
190
|
+
keep_going = self.run_signal_binding(:before_input, input)
|
165
191
|
|
166
192
|
# Should we continue?
|
167
|
-
if
|
193
|
+
if keep_going
|
194
|
+
|
168
195
|
# Check for a key binding.
|
169
|
-
if self.
|
170
|
-
|
196
|
+
if self.is_bound? input
|
197
|
+
self.run_key_binding input
|
198
|
+
#complete = true
|
199
|
+
|
171
200
|
else
|
172
201
|
case input
|
173
202
|
when Ncurses::KEY_LEFT, Ncurses::KEY_BTAB, Ncurses::KEY_BACKSPACE
|
174
|
-
if @current_button - @
|
203
|
+
if @current_button - @button_rows < first_button
|
175
204
|
@current_button = last_button
|
176
205
|
else
|
177
|
-
@current_button -= @
|
206
|
+
@current_button -= @button_rows
|
178
207
|
end
|
179
208
|
when Ncurses::KEY_RIGHT, RNDK::KEY_TAB, ' '.ord
|
180
|
-
if @current_button + @
|
209
|
+
if @current_button + @button_rows > last_button
|
181
210
|
@current_button = first_button
|
182
211
|
else
|
183
|
-
@current_button += @
|
212
|
+
@current_button += @button_rows
|
184
213
|
end
|
185
214
|
when Ncurses::KEY_UP
|
186
215
|
if @current_button -1 < first_button
|
@@ -197,28 +226,32 @@ module RNDK
|
|
197
226
|
when RNDK::REFRESH
|
198
227
|
@screen.erase
|
199
228
|
@screen.refresh
|
229
|
+
|
200
230
|
when RNDK::KEY_ESC
|
201
231
|
self.set_exit_type(input)
|
202
232
|
complete = true
|
233
|
+
|
203
234
|
when Ncurses::ERR
|
204
235
|
self.set_exit_type(input)
|
205
236
|
complete = true
|
237
|
+
|
206
238
|
when RNDK::KEY_RETURN, Ncurses::KEY_ENTER
|
207
|
-
self.
|
208
|
-
ret = @current_button
|
209
|
-
complete = true
|
210
|
-
end
|
211
|
-
end
|
239
|
+
keep_going = self.run_signal_binding(:before_pressing)
|
212
240
|
|
213
|
-
|
214
|
-
|
215
|
-
input
|
241
|
+
if keep_going
|
242
|
+
self.run_signal_binding(:pressed)
|
243
|
+
self.set_exit_type input
|
244
|
+
ret = @current_button
|
245
|
+
complete = true
|
246
|
+
end
|
247
|
+
end
|
216
248
|
end
|
217
249
|
|
250
|
+
self.run_signal_binding(:after_input) if not complete
|
218
251
|
end
|
219
252
|
|
220
253
|
unless complete
|
221
|
-
self.
|
254
|
+
self.draw_buttons
|
222
255
|
self.set_exit_type(0)
|
223
256
|
end
|
224
257
|
|
@@ -242,12 +275,12 @@ module RNDK
|
|
242
275
|
end
|
243
276
|
|
244
277
|
# This sets th background attribute of the widget.
|
245
|
-
def
|
278
|
+
def set_bg_color(attrib)
|
246
279
|
Ncurses.wbkgd(@win, attrib)
|
247
280
|
end
|
248
281
|
|
249
282
|
# This draws the buttonbox box widget.
|
250
|
-
def draw
|
283
|
+
def draw
|
251
284
|
# Is there a shadow?
|
252
285
|
unless @shadow_win.nil?
|
253
286
|
Draw.drawShadow(@shadow_win)
|
@@ -259,56 +292,15 @@ module RNDK
|
|
259
292
|
end
|
260
293
|
|
261
294
|
# Draw in the title if there is one.
|
262
|
-
self.
|
295
|
+
self.draw_title @win
|
263
296
|
|
264
297
|
# Draw in the buttons.
|
265
|
-
self.
|
266
|
-
end
|
267
|
-
|
268
|
-
# This draws the buttons on the button box widget.
|
269
|
-
def drawButtons
|
270
|
-
row = @title_lines + 1
|
271
|
-
col = @col_adjust / 2
|
272
|
-
current_button = 0
|
273
|
-
cur_row = -1
|
274
|
-
cur_col = -1
|
275
|
-
|
276
|
-
# Draw the buttons.
|
277
|
-
while current_button < @button_count
|
278
|
-
(0...@cols).each do |x|
|
279
|
-
row = @title_lines + @border_size
|
280
|
-
|
281
|
-
(0...@rows).each do |y|
|
282
|
-
attr = @button_attrib
|
283
|
-
if current_button == @current_button
|
284
|
-
attr = @highlight
|
285
|
-
cur_row = row
|
286
|
-
cur_col = col
|
287
|
-
end
|
288
|
-
Draw.writeChtypeAttrib(@win,
|
289
|
-
col,
|
290
|
-
row,
|
291
|
-
@button[current_button],
|
292
|
-
attr,
|
293
|
-
RNDK::HORIZONTAL,
|
294
|
-
0,
|
295
|
-
@button_len[current_button])
|
296
|
-
row += (1 + @row_adjust)
|
297
|
-
current_button += 1
|
298
|
-
end
|
299
|
-
col += @column_widths[x] + @col_adjust + @border_size
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
if cur_row >= 0 && cur_col >= 0
|
304
|
-
Ncurses.wmove(@win, cur_row, cur_col)
|
305
|
-
end
|
306
|
-
Ncurses.wrefresh @win
|
298
|
+
self.draw_buttons
|
307
299
|
end
|
308
300
|
|
309
301
|
# This erases the buttonbox box from the screen.
|
310
302
|
def erase
|
311
|
-
if self.
|
303
|
+
if self.valid?
|
312
304
|
RNDK.window_erase @win
|
313
305
|
RNDK.window_erase @shadow_win
|
314
306
|
end
|
@@ -316,14 +308,14 @@ module RNDK
|
|
316
308
|
|
317
309
|
# This destroys the widget
|
318
310
|
def destroy
|
319
|
-
self.
|
311
|
+
self.clean_title
|
320
312
|
|
321
313
|
RNDK.window_delete @shadow_win
|
322
314
|
RNDK.window_delete @win
|
323
315
|
|
324
|
-
self.clean_bindings
|
316
|
+
self.clean_bindings
|
325
317
|
|
326
|
-
|
318
|
+
@screen.unregister self
|
327
319
|
end
|
328
320
|
|
329
321
|
def setCurrentButton(button)
|
@@ -341,19 +333,60 @@ module RNDK
|
|
341
333
|
end
|
342
334
|
|
343
335
|
def focus
|
344
|
-
self.draw
|
336
|
+
self.draw
|
345
337
|
end
|
346
338
|
|
347
339
|
def unfocus
|
348
|
-
self.draw
|
349
|
-
end
|
350
|
-
|
351
|
-
def object_type
|
352
|
-
:BUTTONBOX
|
340
|
+
self.draw
|
353
341
|
end
|
354
342
|
|
355
343
|
def position
|
356
344
|
super(@win)
|
357
345
|
end
|
346
|
+
|
347
|
+
protected
|
348
|
+
|
349
|
+
# This draws the buttons on the button box widget.
|
350
|
+
def draw_buttons
|
351
|
+
row = @title_lines + 1
|
352
|
+
col = @col_adjust / 2
|
353
|
+
current_button = 0
|
354
|
+
cur_row = -1
|
355
|
+
cur_col = -1
|
356
|
+
|
357
|
+
# Draw the buttons.
|
358
|
+
while current_button < @button_count
|
359
|
+
(0...@button_cols).each do |x|
|
360
|
+
row = @title_lines + @border_size
|
361
|
+
|
362
|
+
(0...@button_rows).each do |y|
|
363
|
+
attr = @button_color
|
364
|
+
if current_button == @current_button
|
365
|
+
attr = @highlight
|
366
|
+
cur_row = row
|
367
|
+
cur_col = col
|
368
|
+
end
|
369
|
+
Draw.writeChtypeAttrib(@win,
|
370
|
+
col,
|
371
|
+
row,
|
372
|
+
@button[current_button],
|
373
|
+
attr,
|
374
|
+
RNDK::HORIZONTAL,
|
375
|
+
0,
|
376
|
+
@button_len[current_button])
|
377
|
+
row += (1 + @row_adjust)
|
378
|
+
current_button += 1
|
379
|
+
end
|
380
|
+
col += @column_widths[x] + @col_adjust + @border_size
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
if cur_row >= 0 && cur_col >= 0
|
385
|
+
Ncurses.wmove(@win, cur_row, cur_col)
|
386
|
+
end
|
387
|
+
Ncurses.wrefresh @win
|
388
|
+
end
|
389
|
+
|
390
|
+
|
358
391
|
end
|
359
392
|
end
|
data/lib/rndk/calendar.rb
CHANGED
@@ -117,52 +117,66 @@ module RNDK
|
|
117
117
|
|
118
118
|
# Creates a Calendar Widget.
|
119
119
|
#
|
120
|
-
# * `
|
120
|
+
# * `x` is the x position - can be an integer or
|
121
121
|
# `RNDK::LEFT`, `RNDK::RIGHT`, `RNDK::CENTER`.
|
122
|
-
# * `
|
122
|
+
# * `y` is the y position - can be an integer or
|
123
123
|
# `RNDK::TOP`, `RNDK::BOTTOM`, `RNDK::CENTER`.
|
124
|
-
# * `day`, `month` and `year` are integers
|
125
|
-
#
|
124
|
+
# * `day`, `month` and `year` are integers on the
|
125
|
+
# format `dd`, `mm`, `yyyy`.
|
126
126
|
# * `title` can be more than one line - just split them
|
127
127
|
# with `\n`s.
|
128
|
-
# * `*
|
128
|
+
# * `*_color` are specific colors.
|
129
129
|
#
|
130
130
|
# @note If `day`, `month` or `year` are zero, we'll use
|
131
|
-
# the current date for it.
|
131
|
+
# the current date for it (`Time.now.gmtime`).
|
132
132
|
# If all of them are 0, will use the complete date
|
133
133
|
# of today.
|
134
|
-
def initialize(
|
135
|
-
xplace,
|
136
|
-
yplace,
|
137
|
-
title,
|
138
|
-
day,
|
139
|
-
month,
|
140
|
-
year,
|
141
|
-
day_attrib,
|
142
|
-
month_attrib,
|
143
|
-
year_attrib,
|
144
|
-
highlight,
|
145
|
-
box,
|
146
|
-
shadow)
|
134
|
+
def initialize(screen, config={})
|
147
135
|
super()
|
136
|
+
@widget_type = :calendar
|
137
|
+
@supported_signals += [:before_input, :after_input]
|
138
|
+
|
139
|
+
# This is UGLY AS HELL
|
140
|
+
# But I don't have time to clean this up right now
|
141
|
+
# (lots of widgets, you know) :(
|
142
|
+
x = 0
|
143
|
+
y = 0
|
144
|
+
title = "calendar"
|
145
|
+
day = 0
|
146
|
+
month = 0
|
147
|
+
year = 0
|
148
|
+
day_color = 0
|
149
|
+
month_color = 0
|
150
|
+
year_color = 0
|
151
|
+
highlight = RNDK::Color[:reverse]
|
152
|
+
box = true
|
153
|
+
shadow = false
|
154
|
+
|
155
|
+
config.each do |key, val|
|
156
|
+
x = val if key == :x
|
157
|
+
y = val if key == :y
|
158
|
+
title = val if key == :title
|
159
|
+
day = val if key == :day
|
160
|
+
month = val if key == :month
|
161
|
+
year = val if key == :year
|
162
|
+
day_color = val if key == :day_color
|
163
|
+
month_color = val if key == :month_color
|
164
|
+
year_color = val if key == :year_color
|
165
|
+
highlight = val if key == :highlight
|
166
|
+
box = val if key == :box
|
167
|
+
shadow = val if key == :shadow
|
168
|
+
end
|
169
|
+
|
148
170
|
self.set_date(day, month, year)
|
149
171
|
self.set_box box
|
150
172
|
|
151
|
-
parent_width = Ncurses.getmaxx(
|
152
|
-
parent_height = Ncurses.getmaxy(
|
173
|
+
parent_width = Ncurses.getmaxx(screen.window)
|
174
|
+
parent_height = Ncurses.getmaxy(screen.window)
|
153
175
|
|
154
176
|
box_width = 24
|
155
177
|
box_height = 11
|
156
178
|
|
157
179
|
dayname = 'Su Mo Tu We Th Fr Sa '
|
158
|
-
bindings = {
|
159
|
-
'T' => Ncurses::KEY_HOME,
|
160
|
-
't' => Ncurses::KEY_HOME,
|
161
|
-
'n' => Ncurses::KEY_NPAGE,
|
162
|
-
RNDK::FORCHAR => Ncurses::KEY_NPAGE,
|
163
|
-
'p' => Ncurses::KEY_PPAGE,
|
164
|
-
RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
|
165
|
-
}
|
166
180
|
|
167
181
|
box_width = self.set_title(title, box_width)
|
168
182
|
box_height += @title_lines
|
@@ -173,9 +187,9 @@ module RNDK
|
|
173
187
|
box_height = [box_height, parent_height].min
|
174
188
|
|
175
189
|
# Rejustify the x and y positions if we need to.
|
176
|
-
xtmp = [
|
177
|
-
ytmp = [
|
178
|
-
RNDK.alignxy(
|
190
|
+
xtmp = [x]
|
191
|
+
ytmp = [y]
|
192
|
+
RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
|
179
193
|
xpos = xtmp[0]
|
180
194
|
ypos = ytmp[0]
|
181
195
|
|
@@ -198,8 +212,8 @@ module RNDK
|
|
198
212
|
@day_name = dayname
|
199
213
|
|
200
214
|
# Set the rest of the widget values.
|
201
|
-
@screen =
|
202
|
-
@parent =
|
215
|
+
@screen = screen
|
216
|
+
@parent = screen.window
|
203
217
|
|
204
218
|
@xpos = xpos
|
205
219
|
@ypos = ypos
|
@@ -208,9 +222,9 @@ module RNDK
|
|
208
222
|
@box_width = box_width
|
209
223
|
@box_height = box_height
|
210
224
|
|
211
|
-
@
|
212
|
-
@
|
213
|
-
@
|
225
|
+
@day_color = day_color
|
226
|
+
@month_color = month_color
|
227
|
+
@year_color = year_color
|
214
228
|
@highlight = highlight
|
215
229
|
|
216
230
|
@accepts_focus = true
|
@@ -255,17 +269,16 @@ module RNDK
|
|
255
269
|
xpos + 1)
|
256
270
|
end
|
257
271
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
272
|
+
self.bind_key('t') { self.set_date(0, 0, 0) }
|
273
|
+
self.bind_key('T') { self.set_date(0, 0, 0) }
|
274
|
+
self.bind_key('n') { self.incrementCalendarMonth 1 }
|
275
|
+
self.bind_key('p') { self.decrementCalendarMonth 1 }
|
276
|
+
self.bind_key('N') { self.incrementCalendarMonth 6 }
|
277
|
+
self.bind_key('P') { self.decrementCalendarMonth 6 }
|
278
|
+
self.bind_key('-') { self.decrementCalendarYear 1 }
|
279
|
+
self.bind_key('+') { self.incrementCalendarYear 1 }
|
262
280
|
|
263
|
-
|
264
|
-
end
|
265
|
-
|
266
|
-
# Returns the specific internal index of `d`/`m`/`y`.
|
267
|
-
def self.calendar_index(d, m, y)
|
268
|
-
(y * Calendar::MAX_MONTHS + m) * Calendar::MAX_DAYS + d
|
281
|
+
screen.register(:calendar, self)
|
269
282
|
end
|
270
283
|
|
271
284
|
# Sets `d`/`m`/`y` cell to have `value`.
|
@@ -286,12 +299,12 @@ module RNDK
|
|
286
299
|
# @return The date or `nil` if something bad happened.
|
287
300
|
def activate(actions=[])
|
288
301
|
ret = nil
|
289
|
-
self.draw
|
302
|
+
self.draw
|
290
303
|
|
291
304
|
if actions.nil? || actions.size == 0
|
292
305
|
# Interacting with the user
|
293
306
|
loop do
|
294
|
-
input = self.getch
|
307
|
+
input = self.getch
|
295
308
|
|
296
309
|
# Inject the character into the widget.
|
297
310
|
ret = self.inject input
|
@@ -311,57 +324,53 @@ module RNDK
|
|
311
324
|
end
|
312
325
|
|
313
326
|
# @see Widget#inject
|
314
|
-
def inject
|
315
|
-
pp_return =
|
327
|
+
def inject input
|
328
|
+
pp_return = true
|
316
329
|
ret = nil
|
317
330
|
complete = false
|
318
331
|
|
319
|
-
# Set the exit type
|
320
332
|
self.set_exit_type(0)
|
321
|
-
|
322
|
-
# Refresh the widget field.
|
323
|
-
self.drawField
|
333
|
+
self.draw_field
|
324
334
|
|
325
335
|
# Check if there is a pre-process function to be called.
|
326
|
-
|
327
|
-
|
328
|
-
|
336
|
+
keep_going = self.run_signal_binding(:before_input, input)
|
337
|
+
|
338
|
+
if keep_going
|
329
339
|
|
330
|
-
# Should we continue?
|
331
|
-
if pp_return != 0
|
332
340
|
# Check a predefined binding
|
333
|
-
if self.
|
341
|
+
if self.is_bound? input
|
342
|
+
self.run_key_binding input
|
334
343
|
|
335
344
|
## FIXME What the heck? Missing method?
|
336
345
|
#self.checkEarlyExit
|
337
346
|
|
338
|
-
complete = true
|
347
|
+
#complete = true
|
339
348
|
|
340
349
|
else
|
341
|
-
case
|
342
|
-
when Ncurses::KEY_UP
|
343
|
-
|
344
|
-
when Ncurses::
|
345
|
-
|
350
|
+
case input
|
351
|
+
when Ncurses::KEY_UP, RNDK::PREV
|
352
|
+
self.decrementCalendarDay 7
|
353
|
+
when Ncurses::KEY_DOWN, RNDK::NEXT
|
354
|
+
self.incrementCalendarDay 7
|
355
|
+
when Ncurses::KEY_LEFT, RNDK::BACKCHAR
|
356
|
+
self.decrementCalendarDay 1
|
357
|
+
when Ncurses::KEY_RIGHT, RNDK::FORCHAR
|
358
|
+
self.incrementCalendarDay 1
|
346
359
|
when Ncurses::KEY_NPAGE then self.incrementCalendarMonth 1
|
347
360
|
when Ncurses::KEY_PPAGE then self.decrementCalendarMonth 1
|
348
|
-
when 'N'.ord then self.incrementCalendarMonth 6
|
349
|
-
when 'P'.ord then self.decrementCalendarMonth 6
|
350
|
-
when '-'.ord then self.decrementCalendarYear 1
|
351
|
-
when '+'.ord then self.incrementCalendarYear 1
|
352
361
|
|
353
362
|
when Ncurses::KEY_HOME
|
354
363
|
self.set_date(0, 0, 0)
|
355
364
|
|
356
365
|
when RNDK::KEY_ESC
|
357
|
-
self.set_exit_type
|
366
|
+
self.set_exit_type input
|
358
367
|
complete = true
|
359
368
|
when Ncurses::ERR
|
360
|
-
self.set_exit_type
|
369
|
+
self.set_exit_type input
|
361
370
|
complete = true
|
362
371
|
when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
|
363
|
-
self.set_exit_type
|
364
|
-
ret = self.
|
372
|
+
self.set_exit_type input
|
373
|
+
ret = self.get_current_time
|
365
374
|
complete = true
|
366
375
|
when RNDK::REFRESH
|
367
376
|
@screen.erase
|
@@ -370,9 +379,7 @@ module RNDK
|
|
370
379
|
end
|
371
380
|
|
372
381
|
# Should we do a post-process?
|
373
|
-
if
|
374
|
-
@post_process_func.call(:calendar, self, @post_process_data, char)
|
375
|
-
end
|
382
|
+
self.run_signal_binding(:after_input) if not complete
|
376
383
|
end
|
377
384
|
|
378
385
|
if !complete
|
@@ -384,16 +391,16 @@ module RNDK
|
|
384
391
|
end
|
385
392
|
|
386
393
|
# @see Widget#move
|
387
|
-
def move(
|
394
|
+
def move(x, y, relative, refresh_flag)
|
388
395
|
windows = [@win, @field_win, @label_win, @shadow_win]
|
389
396
|
|
390
|
-
self.move_specific(
|
397
|
+
self.move_specific(x, y, relative, refresh_flag, windows, [])
|
391
398
|
end
|
392
399
|
|
393
400
|
# Draws the Widget on the Screen.
|
394
401
|
#
|
395
402
|
# If `box` is true, it is drawn with a box.
|
396
|
-
def draw
|
403
|
+
def draw
|
397
404
|
|
398
405
|
header_len = @day_name.size
|
399
406
|
col_len = (6 + header_len) / 7
|
@@ -402,9 +409,9 @@ module RNDK
|
|
402
409
|
Draw.drawShadow(@shadow_win) unless @shadow_win.nil?
|
403
410
|
|
404
411
|
# Box the widget if asked.
|
405
|
-
Draw.drawObjBox(@win, self) if box
|
412
|
+
Draw.drawObjBox(@win, self) if @box
|
406
413
|
|
407
|
-
self.
|
414
|
+
self.draw_title @win
|
408
415
|
|
409
416
|
# Draw in the day-of-the-week header.
|
410
417
|
(0...7).each do |col|
|
@@ -420,77 +427,51 @@ module RNDK
|
|
420
427
|
end
|
421
428
|
|
422
429
|
Ncurses.wrefresh @win
|
423
|
-
self.
|
424
|
-
end
|
425
|
-
|
426
|
-
# Draws the month field.
|
427
|
-
def drawField
|
428
|
-
month_name = @month_name[@month]
|
429
|
-
month_length = Calendar.days_in_month(@year, @month)
|
430
|
-
year_index = Calendar.global_year_index(@year)
|
431
|
-
year_len = 0
|
432
|
-
save_y = -1
|
433
|
-
save_x = -1
|
434
|
-
|
435
|
-
day = (1 - @week_day + (@week_base % 7))
|
436
|
-
if day > 0
|
437
|
-
day -= 7
|
438
|
-
end
|
439
|
-
|
440
|
-
(1..6).each do |row|
|
441
|
-
(0...7).each do |col|
|
442
|
-
if day >= 1 && day <= month_length
|
443
|
-
xpos = col * 3
|
444
|
-
ypos = row
|
445
|
-
|
446
|
-
marker = @day_attrib
|
447
|
-
temp = '%02d' % day
|
448
|
-
|
449
|
-
if @day == day
|
450
|
-
marker = @highlight
|
451
|
-
save_y = ypos + Ncurses.getbegy(@field_win) - Ncurses.getbegy(@input_window)
|
452
|
-
save_x = 1
|
453
|
-
else
|
454
|
-
marker |= self.getMarker(day, @month, year_index)
|
455
|
-
end
|
456
|
-
Draw.writeCharAttrib(@field_win, xpos, ypos, temp, marker, RNDK::HORIZONTAL, 0, 2)
|
457
|
-
end
|
458
|
-
day += 1
|
459
|
-
end
|
460
|
-
end
|
461
|
-
Ncurses.wrefresh @field_win
|
462
|
-
|
463
|
-
# Draw the month in.
|
464
|
-
if !(@label_win.nil?)
|
465
|
-
temp = '%s %d,' % [month_name, @day]
|
466
|
-
Draw.writeChar(@label_win, 0, 0, temp, RNDK::HORIZONTAL, 0, temp.size)
|
467
|
-
Ncurses.wclrtoeol @label_win
|
468
|
-
|
469
|
-
# Draw the year in.
|
470
|
-
temp = '%d' % [@year]
|
471
|
-
year_len = temp.size
|
472
|
-
Draw.writeChar(@label_win, @field_width - year_len, 0, temp,
|
473
|
-
RNDK::HORIZONTAL, 0, year_len)
|
474
|
-
|
475
|
-
Ncurses.wmove(@label_win, 0, 0)
|
476
|
-
Ncurses.wrefresh @label_win
|
477
|
-
|
478
|
-
elsif save_y >= 0
|
479
|
-
Ncurses.wmove(@input_window, save_y, save_x)
|
480
|
-
Ncurses.wrefresh @input_window
|
481
|
-
end
|
430
|
+
self.draw_field
|
482
431
|
end
|
483
432
|
|
484
433
|
# Sets multiple attributes of the Widget.
|
485
434
|
#
|
486
435
|
# See Calendar#initialize.
|
487
|
-
def set(
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
436
|
+
def set(config)
|
437
|
+
# This is UGLY AS HELL
|
438
|
+
# But I don't have time to clean this up right now
|
439
|
+
# (lots of widgets, you know) :(
|
440
|
+
x = 0
|
441
|
+
y = 0
|
442
|
+
title = "calendar"
|
443
|
+
day = 0
|
444
|
+
month = 0
|
445
|
+
year = 0
|
446
|
+
day_color = 0
|
447
|
+
month_color = 0
|
448
|
+
year_color = 0
|
449
|
+
highlight = RNDK::Color[:reverse]
|
450
|
+
box = false
|
451
|
+
shadow = false
|
452
|
+
|
453
|
+
config.each do |key, val|
|
454
|
+
x = val if key == :x
|
455
|
+
y = val if key == :y
|
456
|
+
title = val if key == :title
|
457
|
+
day = val if key == :day
|
458
|
+
month = val if key == :month
|
459
|
+
year = val if key == :year
|
460
|
+
day_color = val if key == :day_color
|
461
|
+
month_color = val if key == :month_color
|
462
|
+
year_color = val if key == :year_color
|
463
|
+
highlight = val if key == :highlight
|
464
|
+
box = val if key == :box
|
465
|
+
shadow = val if key == :shadow
|
466
|
+
end
|
467
|
+
|
468
|
+
self.set_date(day, month, year) if not day.zero? and month.zero? and year.zero?
|
469
|
+
self.set_day_color(day_color) if not day_color.zero?
|
470
|
+
self.set_month_color(month_color) if not month_color.zero?
|
471
|
+
self.set_year_color(year_color) if not year_color.zero?
|
472
|
+
self.set_highlight(highlight) if highlight != RNDK::Color[:reverse]
|
473
|
+
self.set_box(box) if box
|
474
|
+
@box_width = self.set_title(title, @box_width) if title != "calendar"
|
494
475
|
end
|
495
476
|
|
496
477
|
# Sets the current date.
|
@@ -523,30 +504,30 @@ module RNDK
|
|
523
504
|
end
|
524
505
|
|
525
506
|
# Sets the appearance/color of the days.
|
526
|
-
def
|
527
|
-
@
|
507
|
+
def set_day_color attribute
|
508
|
+
@day_color = attribute
|
528
509
|
end
|
529
510
|
|
530
|
-
def
|
531
|
-
return @
|
511
|
+
def get_day_color
|
512
|
+
return @day_color
|
532
513
|
end
|
533
514
|
|
534
515
|
# Sets the appearance/color of the month name.
|
535
|
-
def
|
536
|
-
@
|
516
|
+
def set_month_color attribute
|
517
|
+
@month_color = attribute
|
537
518
|
end
|
538
519
|
|
539
|
-
def
|
540
|
-
return @
|
520
|
+
def get_month_color
|
521
|
+
return @month_color
|
541
522
|
end
|
542
523
|
|
543
524
|
# Sets the appearance/color of the year number.
|
544
|
-
def
|
545
|
-
@
|
525
|
+
def set_year_color attribute
|
526
|
+
@year_color = attribute
|
546
527
|
end
|
547
528
|
|
548
|
-
def
|
549
|
-
return @
|
529
|
+
def get_year_color
|
530
|
+
return @year_color
|
550
531
|
end
|
551
532
|
|
552
533
|
# Sets the attribute/color of the highlight bar of the scrolling list.
|
@@ -554,12 +535,12 @@ module RNDK
|
|
554
535
|
@highlight = highlight
|
555
536
|
end
|
556
537
|
|
557
|
-
def
|
538
|
+
def get_highlight
|
558
539
|
return @highlight
|
559
540
|
end
|
560
541
|
|
561
542
|
# Sets the background attribute/color of the widget.
|
562
|
-
def
|
543
|
+
def set_bg_color attrib
|
563
544
|
Ncurses.wbkgd(@win, attrib)
|
564
545
|
Ncurses.wbkgd(@field_win, attrib)
|
565
546
|
Ncurses.wbkgd(@label_win, attrib) unless @label_win.nil?
|
@@ -567,7 +548,7 @@ module RNDK
|
|
567
548
|
|
568
549
|
# @see Widget#erase
|
569
550
|
def erase
|
570
|
-
return unless self.
|
551
|
+
return unless self.valid?
|
571
552
|
|
572
553
|
RNDK.window_erase @label_win
|
573
554
|
RNDK.window_erase @field_win
|
@@ -577,26 +558,26 @@ module RNDK
|
|
577
558
|
|
578
559
|
# @see Widget#destroy
|
579
560
|
def destroy
|
580
|
-
self.
|
561
|
+
self.clean_title
|
581
562
|
|
582
563
|
RNDK.window_delete @label_win
|
583
564
|
RNDK.window_delete @field_win
|
584
565
|
RNDK.window_delete @shadow_win
|
585
566
|
RNDK.window_delete @win
|
586
567
|
|
587
|
-
self.clean_bindings
|
568
|
+
self.clean_bindings
|
588
569
|
|
589
|
-
|
570
|
+
@screen.unregister self
|
590
571
|
end
|
591
572
|
|
592
573
|
# Sets a marker on a specific date.
|
593
|
-
def
|
574
|
+
def set_marker(day, month, year, marker)
|
594
575
|
year_index = Calendar.global_year_index(year)
|
595
576
|
oldmarker = self.getMarker(day, month, year)
|
596
577
|
|
597
578
|
# Check to see if a marker has not already been set
|
598
579
|
if oldmarker != 0
|
599
|
-
self.setCalendarCell(day, month, year_index, oldmarker |
|
580
|
+
self.setCalendarCell(day, month, year_index, oldmarker | RNDK::Color[:blink])
|
600
581
|
else
|
601
582
|
self.setCalendarCell(day, month, year_index, marker)
|
602
583
|
end
|
@@ -609,7 +590,7 @@ module RNDK
|
|
609
590
|
if @marker != 0
|
610
591
|
result = self.getCalendarCell(day, month, year)
|
611
592
|
end
|
612
|
-
|
593
|
+
result
|
613
594
|
end
|
614
595
|
|
615
596
|
# Removes a marker from the Calendar.
|
@@ -625,7 +606,6 @@ module RNDK
|
|
625
606
|
end
|
626
607
|
end
|
627
608
|
|
628
|
-
|
629
609
|
# Sets the names of the days of the week.
|
630
610
|
#
|
631
611
|
# `days` is a String listing the 2-character
|
@@ -646,17 +626,57 @@ module RNDK
|
|
646
626
|
# Makes sure that the internal dates exist, capping
|
647
627
|
# the values if too big/small.
|
648
628
|
def normalize_date
|
629
|
+
max = 1900 + MAX_YEARS - 1
|
630
|
+
@year = max if @year > max
|
631
|
+
|
649
632
|
@year = 1900 if @year < 1900
|
650
633
|
@month = 12 if @month > 12
|
651
634
|
@month = 1 if @month < 1
|
652
635
|
@day = 1 if @day < 1
|
653
636
|
|
637
|
+
|
654
638
|
# Make sure the day given is within range of the month.
|
655
639
|
month_length = Calendar.days_in_month(@year, @month)
|
656
640
|
|
657
641
|
@day = month_length if @day > month_length
|
658
642
|
end
|
659
643
|
|
644
|
+
# This returns what day of the week the month starts on.
|
645
|
+
def get_current_time
|
646
|
+
# Determine the current time and determine if we are in DST.
|
647
|
+
return Time.mktime(@year, @month, @day, 0, 0, 0).gmtime
|
648
|
+
end
|
649
|
+
|
650
|
+
def focus
|
651
|
+
# Original: drawRNDKFscale(widget, ObjOf (widget)->box);
|
652
|
+
self.draw
|
653
|
+
end
|
654
|
+
|
655
|
+
def unfocus
|
656
|
+
# Original: drawRNDKFscale(widget, ObjOf (widget)->box);
|
657
|
+
self.draw
|
658
|
+
end
|
659
|
+
|
660
|
+
# @see Widget#position
|
661
|
+
def position
|
662
|
+
super(@win)
|
663
|
+
end
|
664
|
+
|
665
|
+
protected
|
666
|
+
|
667
|
+
# Returns the internal widget `year` index.
|
668
|
+
# Minimum year is 1900.
|
669
|
+
def self.global_year_index year
|
670
|
+
return (year - 1900) if year >= 1900
|
671
|
+
|
672
|
+
year
|
673
|
+
end
|
674
|
+
|
675
|
+
# Returns the specific internal index of `d`/`m`/`y`.
|
676
|
+
def self.calendar_index(d, m, y)
|
677
|
+
(y * Calendar::MAX_MONTHS + m) * Calendar::MAX_DAYS + d
|
678
|
+
end
|
679
|
+
|
660
680
|
# This increments the current day by the given value.
|
661
681
|
def incrementCalendarDay(adjust)
|
662
682
|
month_length = Calendar.days_in_month(@year, @month)
|
@@ -668,7 +688,7 @@ module RNDK
|
|
668
688
|
self.incrementCalendarMonth(1)
|
669
689
|
else
|
670
690
|
@day += adjust
|
671
|
-
self.
|
691
|
+
self.draw_field
|
672
692
|
end
|
673
693
|
end
|
674
694
|
|
@@ -699,7 +719,7 @@ module RNDK
|
|
699
719
|
self.decrementCalendarMonth(1)
|
700
720
|
else
|
701
721
|
@day -= adjust
|
702
|
-
self.
|
722
|
+
self.draw_field
|
703
723
|
end
|
704
724
|
end
|
705
725
|
|
@@ -724,7 +744,7 @@ module RNDK
|
|
724
744
|
|
725
745
|
# Redraw the calendar.
|
726
746
|
self.erase
|
727
|
-
self.draw
|
747
|
+
self.draw
|
728
748
|
end
|
729
749
|
|
730
750
|
# This decrements the current month by the given value.
|
@@ -758,7 +778,7 @@ module RNDK
|
|
758
778
|
|
759
779
|
# Redraw the calendar.
|
760
780
|
self.erase
|
761
|
-
self.draw
|
781
|
+
self.draw
|
762
782
|
end
|
763
783
|
|
764
784
|
# This increments the current year by the given value.
|
@@ -779,7 +799,7 @@ module RNDK
|
|
779
799
|
|
780
800
|
# Redraw the calendar.
|
781
801
|
self.erase
|
782
|
-
self.draw
|
802
|
+
self.draw
|
783
803
|
end
|
784
804
|
|
785
805
|
# This decrements the current year by the given value.
|
@@ -811,42 +831,65 @@ module RNDK
|
|
811
831
|
|
812
832
|
# Redraw the calendar.
|
813
833
|
self.erase
|
814
|
-
self.draw
|
834
|
+
self.draw
|
815
835
|
end
|
816
836
|
|
817
|
-
#
|
818
|
-
def
|
819
|
-
|
820
|
-
|
821
|
-
|
837
|
+
# Draws the month field.
|
838
|
+
def draw_field
|
839
|
+
month_name = @month_name[@month]
|
840
|
+
month_length = Calendar.days_in_month(@year, @month)
|
841
|
+
year_index = Calendar.global_year_index(@year)
|
842
|
+
year_len = 0
|
843
|
+
save_y = -1
|
844
|
+
save_x = -1
|
822
845
|
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
846
|
+
day = (1 - @week_day + (@week_base % 7))
|
847
|
+
if day > 0
|
848
|
+
day -= 7
|
849
|
+
end
|
827
850
|
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
851
|
+
(1..6).each do |row|
|
852
|
+
(0...7).each do |col|
|
853
|
+
if day >= 1 && day <= month_length
|
854
|
+
xpos = col * 3
|
855
|
+
ypos = row
|
832
856
|
|
833
|
-
|
834
|
-
|
835
|
-
super(@win)
|
836
|
-
end
|
857
|
+
marker = @day_color
|
858
|
+
temp = '%02d' % day
|
837
859
|
|
838
|
-
|
839
|
-
|
840
|
-
|
860
|
+
if @day == day
|
861
|
+
marker = @highlight
|
862
|
+
save_y = ypos + Ncurses.getbegy(@field_win) - Ncurses.getbegy(@input_window)
|
863
|
+
save_x = 1
|
864
|
+
else
|
865
|
+
marker |= self.getMarker(day, @month, year_index)
|
866
|
+
end
|
867
|
+
Draw.writeCharAttrib(@field_win, xpos, ypos, temp, marker, RNDK::HORIZONTAL, 0, 2)
|
868
|
+
end
|
869
|
+
day += 1
|
870
|
+
end
|
871
|
+
end
|
872
|
+
Ncurses.wrefresh @field_win
|
841
873
|
|
842
|
-
|
874
|
+
# Draw the month in.
|
875
|
+
if !(@label_win.nil?)
|
876
|
+
temp = '%s %d,' % [month_name, @day]
|
877
|
+
Draw.writeChar(@label_win, 0, 0, temp, RNDK::HORIZONTAL, 0, temp.size)
|
878
|
+
Ncurses.wclrtoeol @label_win
|
843
879
|
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
880
|
+
# Draw the year in.
|
881
|
+
temp = '%d' % [@year]
|
882
|
+
year_len = temp.size
|
883
|
+
Draw.writeChar(@label_win, @field_width - year_len, 0, temp,
|
884
|
+
RNDK::HORIZONTAL, 0, year_len)
|
848
885
|
|
849
|
-
|
886
|
+
Ncurses.wmove(@label_win, 0, 0)
|
887
|
+
Ncurses.wrefresh @label_win
|
888
|
+
|
889
|
+
elsif save_y >= 0
|
890
|
+
Ncurses.wmove(@input_window, save_y, save_x)
|
891
|
+
Ncurses.wrefresh @input_window
|
892
|
+
end
|
850
893
|
end
|
851
894
|
|
852
895
|
end
|