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.
@@ -0,0 +1,354 @@
1
+ require_relative 'cdk_objs'
2
+
3
+ module CDK
4
+ class BUTTONBOX < CDK::CDKOBJS
5
+ attr_reader :current_button
6
+
7
+ def initialize(cdkscreen, x_pos, y_pos, height, width, title, rows, cols,
8
+ buttons, button_count, highlight, box, shadow)
9
+ super()
10
+ parent_width = cdkscreen.window.getmaxx
11
+ parent_height = cdkscreen.window.getmaxy
12
+ col_width = 0
13
+ current_button = 0
14
+ @button = []
15
+ @button_len = []
16
+ @button_pos = []
17
+ @column_widths = []
18
+
19
+ if button_count <= 0
20
+ self.destroy
21
+ return nil
22
+ end
23
+
24
+ self.setBox(box)
25
+
26
+ # Set some default values for the widget.
27
+ @row_adjust = 0
28
+ @col_adjust = 0
29
+
30
+ # If the height is a negative value, the height will be
31
+ # ROWS-height, otherwise the height will be the given height.
32
+ box_height = CDK.setWidgetDimension(parent_height, height, rows + 1)
33
+
34
+ # If the width is a negative value, the width will be
35
+ # COLS-width, otherwise the width will be the given width.
36
+ box_width = CDK.setWidgetDimension(parent_width, width, 0)
37
+
38
+ box_width = self.setTitle(title, box_width)
39
+
40
+ # Translate the buttons string to a chtype array
41
+ (0...button_count).each do |x|
42
+ button_len = []
43
+ @button << CDK.char2Chtype(buttons[x], button_len ,[])
44
+ @button_len << button_len[0]
45
+ end
46
+
47
+ # Set the button positions.
48
+ (0...cols).each do |x|
49
+ max_col_width = -2**31
50
+
51
+ # Look for the widest item in this column.
52
+ (0...rows).each do |y|
53
+ if current_button < button_count
54
+ max_col_width = [@button_len[current_button], max_col_width].max
55
+ current_button += 1
56
+ end
57
+ end
58
+
59
+ # Keep the maximum column width for this column.
60
+ @column_widths << max_col_width
61
+ col_width += max_col_width
62
+ end
63
+ box_width += 1
64
+
65
+ # Make sure we didn't extend beyond the dimensions of the window.
66
+ box_width = [box_width, parent_width].min
67
+ box_height = [box_height, parent_height].min
68
+
69
+ # Now we have to readjust the x and y positions
70
+ xtmp = [x_pos]
71
+ ytmp = [y_pos]
72
+ CDK.alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
73
+ xpos = xtmp[0]
74
+ ypos = ytmp[0]
75
+
76
+ # Set up the buttonbox box attributes.
77
+ @screen = cdkscreen
78
+ @parent = cdkscreen.window
79
+ @win = Ncurses::WINDOW.new(box_height, box_width, ypos, xpos)
80
+ @shadow_win = nil
81
+ @button_count = button_count
82
+ @current_button = 0
83
+ @rows = rows
84
+ @cols = [button_count, cols].min
85
+ @box_height = box_height
86
+ @box_width = box_width
87
+ @highlight = highlight
88
+ @accepts_focus = true
89
+ @input_window = @win
90
+ @shadow = shadow
91
+ @button_attrib = Ncurses::A_NORMAL
92
+
93
+ # Set up the row adjustment.
94
+ if box_height - rows - @title_lines > 0
95
+ @row_adjust = (box_height - rows - @title_lines) / @rows
96
+ end
97
+
98
+ # Set the col adjustment
99
+ if box_width - col_width > 0
100
+ @col_adjust = ((box_width - col_width) / @cols) - 1
101
+ end
102
+
103
+ # If we couldn't create the window, we should return a null value.
104
+ if @win.nil?
105
+ self.destroy
106
+ return nil
107
+ end
108
+ @win.keypad(true)
109
+
110
+ # Was there a shadow?
111
+ if shadow
112
+ @shadow_win = Ncurses::WINDOW.new(box_height, box_width,
113
+ ypos + 1, xpos + 1)
114
+ end
115
+
116
+ # Register this baby.
117
+ cdkscreen.register(:BUTTONBOX, self)
118
+ end
119
+
120
+ # This activates the widget.
121
+ def activate(actions)
122
+ # Draw the buttonbox box.
123
+ self.draw(@box)
124
+
125
+ if actions.nil? || actions.size == 0
126
+ while true
127
+ input = self.getch([])
128
+
129
+ # Inject the characer into the widget.
130
+ ret = self.inject(input)
131
+ if @exit_type != :EARLY_EXIT
132
+ return ret
133
+ end
134
+ end
135
+ else
136
+ # Inject each character one at a time.
137
+ actions.each do |action|
138
+ ret = self.inject(action)
139
+ if @exit_type != :EARLY_EXIT
140
+ return ret
141
+ end
142
+ end
143
+ end
144
+
145
+ # Set the exit type and exit
146
+ self.setExitType(0)
147
+ return -1
148
+ end
149
+
150
+ # This injects a single character into the widget.
151
+ def inject(input)
152
+ first_button = 0
153
+ last_button = @button_count - 1
154
+ pp_return = 1
155
+ ret = -1
156
+ complete = false
157
+
158
+ # Set the exit type
159
+ self.setExitType(0)
160
+
161
+ unless @pre_process_func.nil?
162
+ pp_return = @pre_process_func.call(:BUTTONBOX, self,
163
+ @pre_process_data, input)
164
+ end
165
+
166
+ # Should we continue?
167
+ if pp_return != 0
168
+ # Check for a key binding.
169
+ if self.checkBind(:BUTTONBOX, input)
170
+ complete = true
171
+ else
172
+ case input
173
+ when Ncurses::KEY_LEFT, Ncurses::KEY_BTAB, Ncurses::KEY_BACKSPACE
174
+ if @current_button - @rows < first_button
175
+ @current_button = last_button
176
+ else
177
+ @current_button -= @rows
178
+ end
179
+ when Ncurses::KEY_RIGHT, CDK::KEY_TAB, ' '.ord
180
+ if @current_button + @rows > last_button
181
+ @current_button = first_button
182
+ else
183
+ @current_button += @rows
184
+ end
185
+ when Ncurses::KEY_UP
186
+ if @current_button -1 < first_button
187
+ @current_button = last_button
188
+ else
189
+ @current_button -= 1
190
+ end
191
+ when Ncurses::KEY_DOWN
192
+ if @current_button + 1 > last_button
193
+ @current_button = first_button
194
+ else
195
+ @current_button += 1
196
+ end
197
+ when CDK::REFRESH
198
+ @screen.erase
199
+ @screen.refresh
200
+ when CDK::KEY_ESC
201
+ self.setExitType(input)
202
+ complete = true
203
+ when Ncurses::ERR
204
+ self.setExitType(input)
205
+ complete = true
206
+ when CDK::KEY_RETURN, Ncurses::KEY_ENTER
207
+ self.setExitType(input)
208
+ ret = @current_button
209
+ complete = true
210
+ end
211
+ end
212
+
213
+ if !complete && !(@post_process_func.nil?)
214
+ @post_process_func.call(:BUTTONBOX, self, @post_process_data,
215
+ input)
216
+ end
217
+
218
+ end
219
+
220
+ unless complete
221
+ self.drawButtons
222
+ self.setExitType(0)
223
+ end
224
+
225
+ @result_data = ret
226
+ return ret
227
+ end
228
+
229
+ # This sets multiple attributes of the widget.
230
+ def set(highlight, box)
231
+ self.setHighlight(highlight)
232
+ self.setBox(box)
233
+ end
234
+
235
+ # This sets the highlight attribute for the buttonboxes
236
+ def setHighlight(highlight)
237
+ @highlight = highlight
238
+ end
239
+
240
+ def getHighlight
241
+ return @highlight
242
+ end
243
+
244
+ # This sets th background attribute of the widget.
245
+ def setBKattr(attrib)
246
+ @win.wbkgd(attrib)
247
+ end
248
+
249
+ # This draws the buttonbox box widget.
250
+ def draw(box)
251
+ # Is there a shadow?
252
+ unless @shadow_win.nil?
253
+ Draw.drawShadow(@shadow_win)
254
+ end
255
+
256
+ # Box the widget if they asked.
257
+ if box
258
+ Draw.drawObjBox(@win, self)
259
+ end
260
+
261
+ # Draw in the title if there is one.
262
+ self.drawTitle(@win)
263
+
264
+ # Draw in the buttons.
265
+ self.drawButtons
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, col, row,
289
+ @button[current_button], attr, CDK::HORIZONTAL, 0,
290
+ @button_len[current_button])
291
+ row += (1 + @row_adjust)
292
+ current_button += 1
293
+ end
294
+ col += @column_widths[x] + @col_adjust + @border_size
295
+ end
296
+ end
297
+
298
+ if cur_row >= 0 && cur_col >= 0
299
+ @win.wmove(cur_row, cur_col)
300
+ end
301
+ @win.wrefresh
302
+ end
303
+
304
+ # This erases the buttonbox box from the screen.
305
+ def erase
306
+ if self.validCDKObject
307
+ CDK.eraseCursesWindow(@win)
308
+ CDK.eraseCursesWindow(@shadow_win)
309
+ end
310
+ end
311
+
312
+ # This destroys the widget
313
+ def destroy
314
+ self.cleanTitle
315
+
316
+ CDK.deleteCursesWindow(@shadow_win)
317
+ CDK.deleteCursesWindow(@win)
318
+
319
+ self.cleanBindings(:BUTTONBOX)
320
+
321
+ CDK::SCREEN.unregister(:BUTTONBOX, self)
322
+ end
323
+
324
+ def setCurrentButton(button)
325
+ if button >= 0 && button < @button_count
326
+ @current_button = button
327
+ end
328
+ end
329
+
330
+ def getCurrentButton
331
+ @current_button
332
+ end
333
+
334
+ def getButtonCount
335
+ @button_count
336
+ end
337
+
338
+ def focus
339
+ self.draw(@box)
340
+ end
341
+
342
+ def unfocus
343
+ self.draw(@box)
344
+ end
345
+
346
+ def object_type
347
+ :BUTTONBOX
348
+ end
349
+
350
+ def position
351
+ super(@win)
352
+ end
353
+ end
354
+ end
@@ -0,0 +1,770 @@
1
+ require_relative 'cdk_objs'
2
+
3
+ module CDK
4
+ class CALENDAR < CDK::CDKOBJS
5
+ attr_accessor :week_base
6
+ attr_reader :day, :month, :year
7
+
8
+ MONTHS_OF_THE_YEAR = [
9
+ 'NULL',
10
+ 'January',
11
+ 'February',
12
+ 'March',
13
+ 'April',
14
+ 'May',
15
+ 'June',
16
+ 'July',
17
+ 'August',
18
+ 'September',
19
+ 'October',
20
+ 'November',
21
+ 'December',
22
+ ]
23
+
24
+ DAYS_OF_THE_MONTH = [
25
+ -1,
26
+ 31,
27
+ 28,
28
+ 31,
29
+ 30,
30
+ 31,
31
+ 30,
32
+ 31,
33
+ 31,
34
+ 30,
35
+ 31,
36
+ 30,
37
+ 31,
38
+ ]
39
+
40
+ MAX_DAYS = 32
41
+ MAX_MONTHS = 13
42
+ MAX_YEARS = 140
43
+
44
+ CALENDAR_LIMIT = MAX_DAYS * MAX_MONTHS * MAX_YEARS
45
+
46
+ def self.CALENDAR_INDEX(d, m, y)
47
+ (y * CDK::CALENDAR::MAX_MONTHS + m) * CDK::CALENDAR::MAX_DAYS + d
48
+ end
49
+
50
+ def setCalendarCell(d, m, y, value)
51
+ @marker[CDK::CALENDAR.CALENDAR_INDEX(d, m, y)] = value
52
+ end
53
+
54
+ def getCalendarCell(d, m, y)
55
+ @marker[CDK::CALENDAR.CALENDAR_INDEX(d, m, y)]
56
+ end
57
+
58
+ def initialize(cdkscreen, xplace, yplace, title, day, month, year,
59
+ day_attrib, month_attrib, year_attrib, highlight, box, shadow)
60
+ super()
61
+ parent_width = cdkscreen.window.getmaxx
62
+ parent_height = cdkscreen.window.getmaxy
63
+ box_width = 24
64
+ box_height = 11
65
+ dayname = 'Su Mo Tu We Th Fr Sa '
66
+ bindings = {
67
+ 'T' => Ncurses::KEY_HOME,
68
+ 't' => Ncurses::KEY_HOME,
69
+ 'n' => Ncurses::KEY_NPAGE,
70
+ CDK::FORCHAR => Ncurses::KEY_NPAGE,
71
+ 'p' => Ncurses::KEY_PPAGE,
72
+ CDK::BACKCHAR => Ncurses::KEY_PPAGE,
73
+ }
74
+
75
+ self.setBox(box)
76
+
77
+ box_width = self.setTitle(title, box_width)
78
+ box_height += @title_lines
79
+
80
+ # Make sure we didn't extend beyond the dimensions of the window.
81
+ box_width = [box_width, parent_width].min
82
+ box_height = [box_height, parent_height].min
83
+
84
+ # Rejustify the x and y positions if we need to.
85
+ xtmp = [xplace]
86
+ ytmp = [yplace]
87
+ CDK.alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
88
+ xpos = xtmp[0]
89
+ ypos = ytmp[0]
90
+
91
+ # Create the calendar window.
92
+ @win = Ncurses::WINDOW.new(box_height, box_width, ypos, xpos)
93
+
94
+ # Is the window nil?
95
+ if @win.nil?
96
+ self.destroy
97
+ return nil
98
+ end
99
+ @win.keypad(true)
100
+
101
+ # Set some variables.
102
+ @x_offset = (box_width - 20) / 2
103
+ @field_width = box_width - 2 * (1 + @border_size)
104
+
105
+ # Set months and day names
106
+ @month_name = CDK::CALENDAR::MONTHS_OF_THE_YEAR.clone
107
+ @day_name = dayname
108
+
109
+ # Set the rest of the widget values.
110
+ @screen = cdkscreen
111
+ @parent = cdkscreen.window
112
+ @shadow_win = nil
113
+ @xpos = xpos
114
+ @ypos = ypos
115
+ @box_width = box_width
116
+ @box_height = box_height
117
+ @day = day
118
+ @month = month
119
+ @year = year
120
+ @day_attrib = day_attrib
121
+ @month_attrib = month_attrib
122
+ @year_attrib = year_attrib
123
+ @highlight = highlight
124
+ @width = box_width
125
+ @accepts_focus = true
126
+ @input_window = @win
127
+ @week_base = 0
128
+ @shadow = shadow
129
+ @label_win = @win.subwin(1, @field_width,
130
+ ypos + @title_lines + 1, xpos + 1 + @border_size)
131
+ if @label_win.nil?
132
+ self.destroy
133
+ return nil
134
+ end
135
+
136
+ @field_win = @win.subwin(7, 20,
137
+ ypos + @title_lines + 3, xpos + @x_offset)
138
+ if @field_win.nil?
139
+ self.destroy
140
+ return nil
141
+ end
142
+ self.setBox(box)
143
+
144
+ @marker = [0] * CDK::CALENDAR::CALENDAR_LIMIT
145
+
146
+ # If the day/month/year values were 0, then use today's date.
147
+ if @day == 0 && @month == 0 && @year == 0
148
+ date_info = Time.new.gmtime
149
+ @day = date_info.day
150
+ @month = date_info.month
151
+ @year = date_info
152
+ end
153
+
154
+ # Verify the dates provided.
155
+ self.verifyCalendarDate
156
+
157
+ # Determine which day the month starts on.
158
+ @week_day = CDK::CALENDAR.getMonthStartWeekday(@year, @month)
159
+
160
+ # If a shadow was requested, then create the shadow window.
161
+ if shadow
162
+ @shadow_win = Ncurses::WINDOW.new(box_height, box_width,
163
+ ypos + 1, xpos + 1)
164
+ end
165
+
166
+ # Setup the key bindings.
167
+ bindings.each do |from, to|
168
+ self.bind(:CALENDAR, from, :getc, to)
169
+ end
170
+
171
+ cdkscreen.register(:CALENDAR, self)
172
+ end
173
+
174
+ # This function lets the user play with this widget.
175
+ def activate(actions)
176
+ ret = -1
177
+ self.draw(@box)
178
+
179
+ if actions.nil? || actions.size == 0
180
+ while true
181
+ input = self.getch([])
182
+
183
+ # Inject the character into the widget.
184
+ ret = self.inject(input)
185
+ if @exit_type != :EARLY_EXIT
186
+ return ret
187
+ end
188
+ end
189
+ else
190
+ # Inject each character one at a time.
191
+ actions.each do |action|
192
+ ret = self.inject(action)
193
+ if @exit_type != :EARLY_EXIT
194
+ return ret
195
+ end
196
+ end
197
+ end
198
+ return ret
199
+ end
200
+
201
+ # This injects a single character into the widget.
202
+ def inject(input)
203
+ # Declare local variables
204
+ pp_return = 1
205
+ ret = -1
206
+ complete = false
207
+
208
+ # Set the exit type
209
+ self.setExitType(0)
210
+
211
+ # Refresh the widget field.
212
+ self.drawField
213
+
214
+ # Check if there is a pre-process function to be called.
215
+ unless @pre_process_func.nil?
216
+ pp_return = @pre_process_func.call(:CALENDAR, self,
217
+ @pre_process_data, input)
218
+ end
219
+
220
+ # Should we continue?
221
+ if pp_return != 0
222
+ # Check a predefined binding
223
+ if self.checkBind(:CALENDAR, input)
224
+ self.checkEarlyExit
225
+ complete = true
226
+ else
227
+ case input
228
+ when Ncurses::KEY_UP
229
+ self.decrementCalendarDay(7)
230
+ when Ncurses::KEY_DOWN
231
+ self.incrementCalendarDay(7)
232
+ when Ncurses::KEY_LEFT
233
+ self.decrementCalendarDay(1)
234
+ when Ncurses::KEY_RIGHT
235
+ self.incrementCalendarDay(1)
236
+ when Ncurses::KEY_NPAGE
237
+ self.incrementCalendarMonth(1)
238
+ when Ncurses::KEY_PPAGE
239
+ self.decrementCalendarMonth(1)
240
+ when 'N'.ord
241
+ self.incrementCalendarMonth(6)
242
+ when 'P'.ord
243
+ self.decrementCalendarMonth(6)
244
+ when '-'.ord
245
+ self.decrementCalendarYear(1)
246
+ when '+'.ord
247
+ self.incrementCalendarYear(1)
248
+ when Ncurses::KEY_HOME
249
+ self.setDate(-1, -1, -1)
250
+ when CDK::KEY_ESC
251
+ self.setExitType(input)
252
+ complete = true
253
+ when Ncurses::ERR
254
+ self.setExitType(input)
255
+ complete = true
256
+ when CDK::KEY_TAB, CDK::KEY_RETURN, Ncurses::KEY_ENTER
257
+ self.setExitType(input)
258
+ ret = self.getCurrentTime
259
+ complete = true
260
+ when CDK::REFRESH
261
+ @screen.erase
262
+ @screen.refresh
263
+ end
264
+ end
265
+
266
+ # Should we do a post-process?
267
+ if !complete && !(@post_process_func.nil?)
268
+ @post_process_func.call(:CALENDAR, self, @post_process_data, input)
269
+ end
270
+ end
271
+
272
+ if !complete
273
+ self.setExitType(0)
274
+ end
275
+
276
+ @result_data = ret
277
+ return ret
278
+ end
279
+
280
+ # This moves the calendar field to the given location.
281
+ def move(xplace, yplace, relative, refresh_flag)
282
+ windows = [@win, @field_win, @label_win, @shadow_win]
283
+ self.move_specific(xplace, yplace, relative, refresh_flag,
284
+ windows, [])
285
+ end
286
+
287
+ # This draws the calendar widget.
288
+ def draw(box)
289
+ header_len = @day_name.size
290
+ col_len = (6 + header_len) / 7
291
+
292
+ # Is there a shadow?
293
+ unless @shadow_win.nil?
294
+ Draw.drawShadow(@shadow_win)
295
+ end
296
+
297
+ # Box the widget if asked.
298
+ if box
299
+ Draw.drawObjBox(@win, self)
300
+ end
301
+
302
+ self.drawTitle(@win)
303
+
304
+ # Draw in the day-of-the-week header.
305
+ (0...7).each do |col|
306
+ src = col_len * ((col + (@week_base % 7)) % 7)
307
+ dst = col_len * col
308
+ Draw.writeChar(@win, @x_offset + dst, @title_lines + 2,
309
+ @day_name[src..-1], CDK::HORIZONTAL, 0, col_len)
310
+ end
311
+
312
+ @win.wrefresh
313
+ self.drawField
314
+ end
315
+
316
+ # This draws the month field.
317
+ def drawField
318
+ month_name = @month_name[@month]
319
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
320
+ year_index = CDK::CALENDAR.YEAR2INDEX(@year)
321
+ year_len = 0
322
+ save_y = -1
323
+ save_x = -1
324
+
325
+ day = (1 - @week_day + (@week_base % 7))
326
+ if day > 0
327
+ day -= 7
328
+ end
329
+
330
+ (1..6).each do |row|
331
+ (0...7).each do |col|
332
+ if day >= 1 && day <= month_length
333
+ xpos = col * 3
334
+ ypos = row
335
+
336
+ marker = @day_attrib
337
+ temp = '%02d' % day
338
+
339
+ if @day == day
340
+ marker = @highlight
341
+ save_y = ypos + @field_win.getbegy - @input_window.getbegy
342
+ save_x = 1
343
+ else
344
+ marker |= self.getMarker(day, @month, year_index)
345
+ end
346
+ Draw.writeCharAttrib(@field_win, xpos, ypos, temp, marker,
347
+ CDK::HORIZONTAL, 0, 2)
348
+ end
349
+ day += 1
350
+ end
351
+ end
352
+ @field_win.wrefresh
353
+
354
+ # Draw the month in.
355
+ if !(@label_win.nil?)
356
+ temp = '%s %d,' % [month_name, @day]
357
+ Draw.writeChar(@label_win, 0, 0, temp, CDK::HORIZONTAL, 0, temp.size)
358
+ @label_win.wclrtoeol
359
+
360
+ # Draw the year in.
361
+ temp = '%d' % [@year]
362
+ year_len = temp.size
363
+ Draw.writeChar(@label_win, @field_width - year_len, 0, temp,
364
+ CDK::HORIZONTAL, 0, year_len)
365
+
366
+ @label_win.wmove(0, 0)
367
+ @label_win.wrefresh
368
+ elsif save_y >= 0
369
+ @input_window.wmove(save_y, save_x)
370
+ @input_window.wrefresh
371
+ end
372
+ end
373
+
374
+ # This sets multiple attributes of the widget
375
+ def set(day, month, year, day_attrib, month_attrib, year_attrib,
376
+ highlight, box)
377
+ self.setDate(day, month, yar)
378
+ self.setDayAttribute(day_attrib)
379
+ self.setMonthAttribute(month_attrib)
380
+ self.setYearAttribute(year_attrib)
381
+ self.setHighlight(highlight)
382
+ self.setBox(box)
383
+ end
384
+
385
+ # This sets the date and some attributes.
386
+ def setDate(day, month, year)
387
+ # Get the current dates and set the default values for the
388
+ # day/month/year values for the calendar
389
+ date_info = Time.new.gmtime
390
+
391
+ # Set the date elements if we need to.
392
+ @day = if day == -1 then date_info.day else day end
393
+ @month = if month == -1 then date_info.month else month end
394
+ @year = if year == -1 then date_info.year else year end
395
+
396
+ # Verify the date information.
397
+ self.verifyCalendarDate
398
+
399
+ # Get the start of the current month.
400
+ @week_day = CDK::CALENDAR.getMonthStartWeekday(@year, @month)
401
+ end
402
+
403
+ # This returns the current date on the calendar.
404
+ def getDate(day, month, year)
405
+ day << @day
406
+ month << @month
407
+ year << @year
408
+ end
409
+
410
+ # This sets the attribute of the days in the calendar.
411
+ def setDayAttribute(attribute)
412
+ @day_attrib = attribute
413
+ end
414
+
415
+ def getDayAttribute
416
+ return @day_attrib
417
+ end
418
+
419
+ # This sets the attribute of the month names in the calendar.
420
+ def setMonthAttribute(attribute)
421
+ @month_attrib = attribute
422
+ end
423
+
424
+ def getMonthAttribute
425
+ return @month_attrib
426
+ end
427
+
428
+ # This sets the attribute of the year in the calendar.
429
+ def setYearAttribute(attribute)
430
+ @year_attrib = attribute
431
+ end
432
+
433
+ def getYearAttribute
434
+ return @year_attrib
435
+ end
436
+
437
+ # This sets the attribute of the highlight box.
438
+ def setHighlight(highlight)
439
+ @highlight = highlight
440
+ end
441
+
442
+ def getHighlight
443
+ return @highlight
444
+ end
445
+
446
+ # This sets the background attribute of the widget.
447
+ def setBKattr(attrib)
448
+ @win.wbkgd(attrib)
449
+ @field_win.wbkgd(attrib)
450
+ unless @label_win.nil?
451
+ @label_win.wbkgd(attrib)
452
+ end
453
+ end
454
+
455
+ # This erases the calendar widget.
456
+ def erase
457
+ if self.validCDKObject
458
+ CDK.eraseCursesWindow(@label_win)
459
+ CDK.eraseCursesWindow(@field_win)
460
+ CDK.eraseCursesWindow(@win)
461
+ CDK.eraseCursesWindow(@shadow_win)
462
+ end
463
+ end
464
+
465
+ # This destroys the calendar
466
+ def destroy
467
+ self.cleanTitle
468
+
469
+ CDK.deleteCursesWindow(@label_win)
470
+ CDK.deleteCursesWindow(@field_win)
471
+ CDK.deleteCursesWindow(@shadow_win)
472
+ CDK.deleteCursesWindow(@win)
473
+
474
+ # Clean the key bindings.
475
+ self.cleanBindings(:CALENDAR)
476
+
477
+ # Unregister the object.
478
+ CDK::SCREEN.unregister(:CALENDAR, self)
479
+ end
480
+
481
+ # This sets a marker on the calendar.
482
+ def setMarker(day, month, year, marker)
483
+ year_index = CDK::CALENDAR.YEAR2INDEX(year)
484
+ oldmarker = self.getMarker(day, month, year)
485
+
486
+ # Check to see if a marker has not already been set
487
+ if oldmarker != 0
488
+ self.setCalendarCell(day, month, year_index,
489
+ oldmarker | Ncurses::A_BLINK)
490
+ else
491
+ self.setCalendarCell(day, month, year_index, marker)
492
+ end
493
+ end
494
+
495
+ def getMarker(day, month, year)
496
+ result = 0
497
+ year = CDK::CALENDAR.YEAR2INDEX(year)
498
+ if @marker != 0
499
+ result = self.getCalendarCell(day, month, year)
500
+ end
501
+ return result
502
+ end
503
+
504
+ # This sets a marker on the calendar.
505
+ def removeMarker(day, month, year)
506
+ year_index = CDK::CALENDAR.YEAR2INDEX(year)
507
+ self.setCalendarCell(day, month, year_index, 0)
508
+ end
509
+
510
+ # THis function sets the month name.
511
+ def setMonthNames(months)
512
+ (1...[months.size, @month_name.size].min).each do |x|
513
+ @month_name[x] = months[x]
514
+ end
515
+ end
516
+
517
+ # This function sets the day's name
518
+ def setDaysNames(days)
519
+ @day_name = days.clone
520
+ end
521
+
522
+ # This makes sure that the dates provided exist.
523
+ def verifyCalendarDate
524
+ # Make sure the given year is not less than 1900.
525
+ if @year < 1900
526
+ @year = 1900
527
+ end
528
+
529
+ # Make sure the month is within range.
530
+ if @month > 12
531
+ @month = 12
532
+ end
533
+ if @month < 1
534
+ @month = 1
535
+ end
536
+
537
+ # Make sure the day given is within range of the month.
538
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
539
+ if @day < 1
540
+ @day = 1
541
+ end
542
+ if @day > month_length
543
+ @day = month_length
544
+ end
545
+ end
546
+
547
+ # This returns what day of the week the month starts on.
548
+ def self.getMonthStartWeekday(year, month)
549
+ return Time.mktime(year, month, 1, 10, 0, 0).wday
550
+ end
551
+
552
+ # This function returns a 1 if it's a leap year and 0 if not.
553
+ def self.isLeapYear(year)
554
+ result = false
555
+ if year % 4 == 0
556
+ if year % 100 == 0
557
+ if year % 400 == 0
558
+ result = true
559
+ end
560
+ else
561
+ result = true
562
+ end
563
+ end
564
+ return result
565
+ end
566
+
567
+ # This increments the current day by the given value.
568
+ def incrementCalendarDay(adjust)
569
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
570
+
571
+ # Make sure we adjust the day correctly.
572
+ if adjust + @day > month_length
573
+ # Have to increment the month by one.
574
+ @day = @day + adjust - month_length
575
+ self.incrementCalendarMonth(1)
576
+ else
577
+ @day += adjust
578
+ self.drawField
579
+ end
580
+ end
581
+
582
+ # This decrements the current day by the given value.
583
+ def decrementCalendarDay(adjust)
584
+ # Make sure we adjust the day correctly.
585
+ if @day - adjust < 1
586
+ # Set the day according to the length of the month.
587
+ if @month == 1
588
+ # make sure we aren't going past the year limit.
589
+ if @year == 1900
590
+ mesg = [
591
+ '<C></U>Error',
592
+ 'Can not go past the year 1900'
593
+ ]
594
+ CDK.Beep
595
+ @screen.popupLabel(mesg, 2)
596
+ return
597
+ end
598
+ month_length = CDK::CALENDAR.getMonthLength(@year - 1, 12)
599
+ else
600
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month - 1)
601
+ end
602
+
603
+ @day = month_length - (adjust - @day)
604
+
605
+ # Have to decrement the month by one.
606
+ self.decrementCalendarMonth(1)
607
+ else
608
+ @day -= adjust
609
+ self.drawField
610
+ end
611
+ end
612
+
613
+ # This increments the current month by the given value.
614
+ def incrementCalendarMonth(adjust)
615
+ # Are we at the end of the year.
616
+ if @month + adjust > 12
617
+ @month = @month + adjust - 12
618
+ @year += 1
619
+ else
620
+ @month += adjust
621
+ end
622
+
623
+ # Get the length of the current month.
624
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
625
+ if @day > month_length
626
+ @day = month_length
627
+ end
628
+
629
+ # Get the start of the current month.
630
+ @week_day = CDK::CALENDAR.getMonthStartWeekday(@year, @month)
631
+
632
+ # Redraw the calendar.
633
+ self.erase
634
+ self.draw(@box)
635
+ end
636
+
637
+ # This decrements the current month by the given value.
638
+ def decrementCalendarMonth(adjust)
639
+ # Are we at the end of the year.
640
+ if @month <= adjust
641
+ if @year == 1900
642
+ mesg = [
643
+ '<C></U>Error',
644
+ 'Can not go past the year 1900',
645
+ ]
646
+ CDK.Beep
647
+ @screen.popupLabel(mesg, 2)
648
+ return
649
+ else
650
+ @month = 13 - adjust
651
+ @year -= 1
652
+ end
653
+ else
654
+ @month -= adjust
655
+ end
656
+
657
+ # Get the length of the current month.
658
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
659
+ if @day > month_length
660
+ @day = month_length
661
+ end
662
+
663
+ # Get the start o the current month.
664
+ @week_day = CDK::CALENDAR.getMonthStartWeekday(@year, @month)
665
+
666
+ # Redraw the calendar.
667
+ self.erase
668
+ self.draw(@box)
669
+ end
670
+
671
+ # This increments the current year by the given value.
672
+ def incrementCalendarYear(adjust)
673
+ # Increment the year.
674
+ @year += adjust
675
+
676
+ # If we are in Feb make sure we don't trip into voidness.
677
+ if @month == 2
678
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
679
+ if @day > month_length
680
+ @day = month_length
681
+ end
682
+ end
683
+
684
+ # Get the start of the current month.
685
+ @week_day = CDK::CALENDAR.getMonthStartWeekday(@year, @month)
686
+
687
+ # Redraw the calendar.
688
+ self.erase
689
+ self.draw(@box)
690
+ end
691
+
692
+ # This decrements the current year by the given value.
693
+ def decrementCalendarYear(adjust)
694
+ # Make sure we don't go out o bounds.
695
+ if @year - adjust < 1900
696
+ mesg = [
697
+ '<C></U>Error',
698
+ 'Can not go past the year 1900',
699
+ ]
700
+ CDK.Beep
701
+ @screen.popupLabel(mesg, 2)
702
+ return
703
+ end
704
+
705
+ # Decrement the year.
706
+ @year -= adjust
707
+
708
+ # If we are in Feb make sure we don't trip into voidness.
709
+ if @month == 2
710
+ month_length = CDK::CALENDAR.getMonthLength(@year, @month)
711
+ if @day > month_length
712
+ @day = month_length
713
+ end
714
+ end
715
+
716
+ # Get the start of the current month.
717
+ @week_day = CDK::CALENDAR.getMonthStartWeekday(@year, @month)
718
+
719
+ # Redraw the calendar.
720
+ self.erase
721
+ self.draw(@box)
722
+ end
723
+
724
+ # This returns the length of the current month.
725
+ def self.getMonthLength(year, month)
726
+ month_length = DAYS_OF_THE_MONTH[month]
727
+
728
+ if month == 2
729
+ month_length += if CDK::CALENDAR.isLeapYear(year)
730
+ then 1
731
+ else 0
732
+ end
733
+ end
734
+
735
+ return month_length
736
+ end
737
+
738
+ # This returns what day of the week the month starts on.
739
+ def getCurrentTime
740
+ # Determine the current time and determine if we are in DST.
741
+ return Time.mktime(@year, @month, @day, 0, 0, 0).gmtime
742
+ end
743
+
744
+ def focus
745
+ # Original: drawCDKFscale(widget, ObjOf (widget)->box);
746
+ self.draw(@box)
747
+ end
748
+
749
+ def unfocus
750
+ # Original: drawCDKFscale(widget, ObjOf (widget)->box);
751
+ self.draw(@box)
752
+ end
753
+
754
+ def self.YEAR2INDEX(year)
755
+ if year >= 1900
756
+ year - 1900
757
+ else
758
+ year
759
+ end
760
+ end
761
+
762
+ def position
763
+ super(@win)
764
+ end
765
+
766
+ def object_type
767
+ :CALENDAR
768
+ end
769
+ end
770
+ end