Class: CDK::ENTRY

Inherits:
CDKOBJS show all
Defined in:
lib/cdk/components/entry.rb

Instance Attribute Summary collapse

Attributes included from HasTitle

#title_attrib

Attributes included from HasScreen

#is_visible, #screen, #screen_index

Attributes included from ExitConditions

#exit_type

Attributes included from Bindings

#binding_list

Attributes included from Focusable

#accepts_focus, #has_focus

Attributes included from Borders

#BXAttr, #HZChar, #LLChar, #LRChar, #ULChar, #URChar, #VTChar, #border_size, #box

Instance Method Summary collapse

Methods inherited from CDKOBJS

#setBackgroundColor, #timeout, #validCDKObject, #validObjType

Methods included from WindowHooks

#refreshData, #saveData

Methods included from WindowInput

#getc, #getch, #setPostProcess, #setPreProcess

Methods included from HasTitle

#cleanTitle, #drawTitle, #init_title, #setTitle

Methods included from HasScreen

#SCREEN_XPOS, #SCREEN_YPOS, #init_screen, #wrefresh

Methods included from ExitConditions

#init_exit_conditions, #resetExitType, #setExitType

Methods included from Bindings

#bind, #bindableObject, #checkBind, #cleanBindings, #init_bindings, #isBind, #unbind

Methods included from Focusable

#init_focus

Methods included from Borders

#getBox, #init_borders, #setBXattr, #setBox, #setHZchar, #setLLchar, #setLRchar, #setULchar, #setURchar, #setVTchar

Methods included from Movement

#move_specific

Methods included from Converters

#char2Chtype, #charOf, #chtype2Char, #chtype2String, #decode_attribute, #encode_attribute

Methods included from Justifications

#justify_string

Methods included from Alignments

#alignxy

Constructor Details

#initialize(cdkscreen, xplace, yplace, title, label, field_attr, filler, disp_type, f_width, min, max, box, shadow) ⇒ ENTRY

Returns a new instance of ENTRY.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/cdk/components/entry.rb', line 9

def initialize(cdkscreen, xplace, yplace, title, label, field_attr, filler,
    disp_type, f_width, min, max, box, shadow)
  super()
  parent_width = cdkscreen.window.getmaxx
  parent_height = cdkscreen.window.getmaxy
  field_width = f_width
  box_width = 0
  xpos = xplace
  ypos = yplace
  
  self.setBox(box)
  box_height = @border_size * 2 + 1

  # If the field_width is a negative value, the field_width will be
  # COLS-field_width, otherwise the field_width will be the given width.
  field_width = CDK.setWidgetDimension(parent_width, field_width, 0)
  box_width = field_width + 2 * @border_size

  # Set some basic values of the entry field.
  @label = 0
  @label_len = 0
  @label_win = nil

  # Translate the label string to a chtype array
  if !(label.nil?) && label.size > 0
    label_len = [@label_len]
    @label = char2Chtype(label, label_len, [])
    @label_len = label_len[0]
    box_width += @label_len
  end

  old_width = box_width
  box_width = self.setTitle(title, box_width)
  horizontal_adjust = (box_width - old_width) / 2

  box_height += @title_lines

  # Make sure we didn't extend beyond the dimensinos of the window.
  box_width = [box_width, parent_width].min
  box_height = [box_height, parent_height].min
  field_width = [field_width,
      box_width - @label_len - 2 * @border_size].min

  # Rejustify the x and y positions if we need to.
  xtmp = [xpos]
  ytmp = [ypos]
  alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
  xpos = xtmp[0]
  ypos = ytmp[0]

  # Make the label window.
  @win = cdkscreen.window.subwin(box_height, box_width, ypos, xpos)
  if @win.nil?
    self.destroy
    return nil
  end
  @win.keypad(true)

  # Make the field window.
  @field_win = @win.subwin(1, field_width,
      ypos + @title_lines + @border_size,
      xpos + @label_len + horizontal_adjust + @border_size)

  if @field_win.nil?
    self.destroy
    return nil
  end
  @field_win.keypad(true)

  # make the label win, if we need to
  if !(label.nil?) && label.size > 0
    @label_win = @win.subwin(1, @label_len,
        ypos + @title_lines + @border_size,
        xpos + horizontal_adjust + @border_size)
  end

  #entry->info += '\0' * (max + 3)
  @info = ''
  @info_width = max + 3

  # Set up the rest of the structure.
  @screen = cdkscreen
  @parent = cdkscreen.window
  @shadow_win = nil
  @field_attr = field_attr
  @field_width = field_width
  @filler = filler
  @hidden = filler
  @input_window = @field_win
  @accepts_focus = true
  @data_ptr = nil
  @shadow = shadow
  @screen_col = 0
  @left_char = 0
  @min = min
  @max = max
  @box_width = box_width
  @box_height = box_height
  @disp_type = disp_type
  @callbackfn = lambda do |entry, character|
    plainchar = Display.filterByDisplayType(entry, character)

    if plainchar == Ncurses::ERR || entry.info.size >= entry.max
      CDK.Beep
    else
      # Update the screen and pointer
      if entry.screen_col != entry.field_width - 1
        front = (entry.info[0...(entry.screen_col + entry.left_char)] or '')
        back = (entry.info[(entry.screen_col + entry.left_char)..-1] or '')
        entry.info = front + plainchar.chr + back
        entry.screen_col += 1
      else
        # Update the character pointer.
        entry.info << plainchar
        # Do not update the pointer if it's the last character
        if entry.info.size < entry.max
          entry.left_char += 1
        end
      end

      # Update the entry field.
      entry.drawField
    end
  end

  # Do we want a shadow?
  if shadow
    @shadow_win = cdkscreen.window.subwin(box_height, box_width,
        ypos + 1, xpos + 1)
  end

  cdkscreen.register(:ENTRY, self)
end

Instance Attribute Details

#box_heightObject (readonly)

Returns the value of attribute box_height.



6
7
8
# File 'lib/cdk/components/entry.rb', line 6

def box_height
  @box_height
end

#box_widthObject (readonly)

Returns the value of attribute box_width.



6
7
8
# File 'lib/cdk/components/entry.rb', line 6

def box_width
  @box_width
end

#field_widthObject (readonly)

Returns the value of attribute field_width.



6
7
8
# File 'lib/cdk/components/entry.rb', line 6

def field_width
  @field_width
end

#infoObject

Returns the value of attribute info.



5
6
7
# File 'lib/cdk/components/entry.rb', line 5

def info
  @info
end

#left_charObject

Returns the value of attribute left_char.



5
6
7
# File 'lib/cdk/components/entry.rb', line 5

def left_char
  @left_char
end

#maxObject (readonly)

Returns the value of attribute max.



6
7
8
# File 'lib/cdk/components/entry.rb', line 6

def max
  @max
end

#minObject (readonly)

Returns the value of attribute min.



7
8
9
# File 'lib/cdk/components/entry.rb', line 7

def min
  @min
end

#screen_colObject

Returns the value of attribute screen_col.



5
6
7
# File 'lib/cdk/components/entry.rb', line 5

def screen_col
  @screen_col
end

#winObject (readonly)

Returns the value of attribute win.



6
7
8
# File 'lib/cdk/components/entry.rb', line 6

def win
  @win
end

Instance Method Details

#activate(actions) ⇒ Object

This means you want to use the given entry field. It takes input from the keyboard, and when it’s done, it fills the entry info element of the structure with what was typed.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/cdk/components/entry.rb', line 146

def activate(actions)
  input = 0
  ret = 0

  # Draw the widget.
  self.draw(@box)

  if actions.nil? or actions.size == 0
    while true
      input = self.getch([])

      # Inject the character into the widget.
      ret = self.inject(input)
      if @exit_type != :EARLY_EXIT
        return ret
      end
    end
  else
    # Inject each character one at a time.
    actions.each do |action|
      ret = self.inject(action)
      if @exit_type != :EARLY_EXIT
        return ret
      end
    end
  end

  # Make sure we return the correct info.
  if @exit_type == :NORMAL
    return @info
  else
    return 0
  end
end

#cleanObject

This erases the information in the entry field and redraws a clean and empty entry field.



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/cdk/components/entry.rb', line 366

def clean
  width = @field_width

  @info = ''

  # Clean the entry screen field.
  @field_win.mvwhline(0, 0, @filler.ord, width)

  # Reset some variables
  @screen_col = 0
  @left_char = 0

  # Refresh the entry field.
  wrefresh(@field_win)
end

#destroyObject

This destroys an entry widget.



441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/cdk/components/entry.rb', line 441

def destroy
  self.cleanTitle

  CDK.deleteCursesWindow(@field_win)
  CDK.deleteCursesWindow(@label_win)
  CDK.deleteCursesWindow(@shadow_win)
  CDK.deleteCursesWindow(@win)

  self.cleanBindings(:ENTRY)

  CDK::SCREEN.unregister(:ENTRY, self)
end

#draw(box) ⇒ Object

This draws the entry field.



383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/cdk/components/entry.rb', line 383

def draw(box)
  # Did we ask for a shadow?
  unless @shadow_win.nil?
    Draw.drawShadow(@shadow_win)
  end

  # Box the widget if asked.
  if box
    Draw.drawObjBox(@win, self)
  end

  self.drawTitle(@win)

  wrefresh

  # Draw in the label to the widget.
  unless @label_win.nil?
    Draw.writeChtype(@label_win, 0, 0, @label, CDK::HORIZONTAL, 0,
        @label_len)
    wrefresh(@label_win)
  end

  self.drawField
end

#drawFieldObject



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/cdk/components/entry.rb', line 408

def drawField
  # Draw in the filler characters.
  @field_win.mvwhline(0, 0, @filler.ord, @field_width)

  # If there is information in the field then draw it in.
  if !(@info.nil?) && @info.size > 0
    # Redraw the field.
    if Display.isHiddenDisplayType(@disp_type)
      (@left_char...@info.size).each do |x|
        @field_win.mvwaddch(0, x - @left_char, @hidden)
      end
    else
      (@left_char...@info.size).each do |x|
        @field_win.mvwaddch(0, x - @left_char, @info[x].ord | @field_attr)
      end
    end
    @field_win.wmove(0, @screen_col)
  end

  wrefresh(@field_win)
end

#eraseObject

This erases an entry widget from the screen.



431
432
433
434
435
436
437
438
# File 'lib/cdk/components/entry.rb', line 431

def erase
  if self.validCDKObject
    CDK.eraseCursesWindow(@field_win)
    CDK.eraseCursesWindow(@label_win)
    CDK.eraseCursesWindow(@win)
    CDK.eraseCursesWindow(@shadow_win)
  end
end

#focusObject



538
539
540
541
# File 'lib/cdk/components/entry.rb', line 538

def focus
  @field_win.wmove(0, @screen_col)
  wrefresh(@field_win)
end

#getFillerCharObject



503
504
505
# File 'lib/cdk/components/entry.rb', line 503

def getFillerChar
  @filler
end

#getHiddenCharObject



512
513
514
# File 'lib/cdk/components/entry.rb', line 512

def getHiddenChar
  @hidden
end

#getMaxObject



485
486
487
# File 'lib/cdk/components/entry.rb', line 485

def getMax
  @max
end

#getMinObject



494
495
496
# File 'lib/cdk/components/entry.rb', line 494

def getMin
  @min
end

#getValueObject



476
477
478
# File 'lib/cdk/components/entry.rb', line 476

def getValue
  return @info
end

#inject(input) ⇒ Object

This injects a single character into the widget.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/cdk/components/entry.rb', line 198

def inject(input)
  pp_return = 1
  ret = 1
  @complete = false

  # Set the exit type
  self.setExitType(0)
  
  # Refresh the widget field.
  self.drawField

  unless @pre_process_func.nil?
    pp_return = @pre_process_func.call(:ENTRY, self,
        @pre_process_data, input)
  end

  # Should we continue?
  if pp_return != 0
    # Check a predefined binding
    if self.checkBind(:ENTRY, input)
      @complete = true
    else
      curr_pos = @screen_col + @left_char

      case input
      when Ncurses::KEY_UP, Ncurses::KEY_DOWN
        CDK.Beep
      when Ncurses::KEY_HOME
        @left_char = 0
        @screen_col = 0
        self.drawField
      when CDK::TRANSPOSE
        if curr_pos >= @info.size - 1
          CDK.Beep
        else
          holder = @info[curr_pos]
          @info[curr_pos] = @info[curr_pos + 1]
          @info[curr_pos + 1] = holder
          self.drawField
        end
      when Ncurses::KEY_END
        self.setPositionToEnd
        self.drawField
      when Ncurses::KEY_LEFT
        if curr_pos <= 0
          CDK.Beep
        elsif @screen_col == 0
          # Scroll left.
          @left_char -= 1
          self.drawField
        else
          @screen_col -= 1
          @field_win.wmove(0, @screen_col)
        end
      when Ncurses::KEY_RIGHT
        if curr_pos >= @info.size
          CDK.Beep
        elsif @screen_col == @field_width - 1
          # Scroll to the right.
          @left_char += 1
          self.drawField
        else
          # Move right.
          @screen_col += 1
          @field_win.wmove(0, @screen_col)
        end
      when Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC
        if @disp_type == :VIEWONLY
          CDK.Beep
        else
          success = false
          if input == Ncurses::KEY_BACKSPACE
            curr_pos -= 1
          end

          if curr_pos >= 0 && @info.size > 0
            if curr_pos < @info.size
              @info = @info[0...curr_pos] + @info[curr_pos+1..-1]
              success = true
            elsif input == Ncurses::KEY_BACKSPACE
              @info = @info[0...-1]
              success = true
            end
          end
          
          if success
            if input == Ncurses::KEY_BACKSPACE
              if @screen_col > 0
                @screen_col -= 1
              else
                @left_char -= 1
              end
            end
            self.drawField
          else
            CDK.Beep
          end
        end
      when CDK::KEY_ESC
        self.setExitType(input)
        @complete = true
      when CDK::ERASE
        if @info.size != 0
          self.clean
          self.drawField
        end
      when CDK::CUT
        if @info.size != 0
          @@g_paste_buffer = @info.clone
          self.clean
          self.drawField
        else
          CDK.Beep
        end
      when CDK::COPY
        if @info.size != 0
          @@g_paste_buffer = @info.clone
        else
          CDK.Beep
        end
      when CDK::PASTE
        if @@g_paste_buffer != 0
          self.setValue(@@g_paste_buffer)
          self.drawField
        else
          CDK.Beep
        end
      when CDK::KEY_TAB, CDK::KEY_RETURN, Ncurses::KEY_ENTER
        if @info.size >= @min
          self.setExitType(input)
          ret = @info
          @complete = true
        else
          CDK.Beep
        end
      when Ncurses::ERR
        self.setExitType(input)
        @complete = true
      when CDK::REFRESH
        @screen.erase
        @screen.refresh
      else
        @callbackfn.call(self, input)
      end
    end

    if !@complete && !(@post_process_func.nil?)
      @post_process_func.call(:ENTRY, self, @post_process_data, input)
    end
  end

  unless @complete
    self.setExitType(0)
  end

  @result_data = ret
  return ret
end

#move(xplace, yplace, relative, refresh_flag) ⇒ Object

This moves the entry field to the given location.



358
359
360
361
362
# File 'lib/cdk/components/entry.rb', line 358

def move(xplace, yplace, relative, refresh_flag)
  windows = [@win, @field_win, @label_win, @shadow_win]
  self.move_specific(xplace, yplace, relative, refresh_flag,
      windows, [])
end

#object_typeObject



552
553
554
# File 'lib/cdk/components/entry.rb', line 552

def object_type
  :ENTRY
end

#positionObject



548
549
550
# File 'lib/cdk/components/entry.rb', line 548

def position
  super(@win)
end

#set(value, min, max, box) ⇒ Object

This sets specific attributes of the entry field.



455
456
457
458
459
# File 'lib/cdk/components/entry.rb', line 455

def set(value, min, max, box)
  self.setValue(value)
  self.setMin(min)
  self.setMax(max)
end

#setBKattr(attrib) ⇒ Object

This sets the background attribute of the widget.



517
518
519
520
521
522
523
# File 'lib/cdk/components/entry.rb', line 517

def setBKattr(attrib)
  @win.wbkgd(attrib)
  @field_win.wbkgd(attrib)
  unless @label_win.nil?
    @label_win.wbkgd(attrib)
  end
end

#setCB(callback) ⇒ Object

This sets the entry field callback function.



534
535
536
# File 'lib/cdk/components/entry.rb', line 534

def setCB(callback)
  @callbackfn = callback
end

#setFillerChar(filler_char) ⇒ Object

This sets the filler character to be used in the entry field.



499
500
501
# File 'lib/cdk/components/entry.rb', line 499

def setFillerChar(filler_char)
  @filler = filler_char
end

#setHiddenChar(hidden_character) ⇒ Object

This sets the character to use when a hidden type is used.



508
509
510
# File 'lib/cdk/components/entry.rb', line 508

def setHiddenChar(hidden_character)
  @hidden = hidden_character
end

#setHighlight(highlight, cursor) ⇒ Object

This sets the attribute of the entry field.



526
527
528
529
530
531
# File 'lib/cdk/components/entry.rb', line 526

def setHighlight(highlight, cursor)
  @field_win.wbkgd(highlight)
  @field_attr = highlight
  Ncurses.curs_set(cursor)
  # FIXME(original) - if (cursor) { move the cursor to this widget }
end

#setMax(max) ⇒ Object

This sets the maximum length of the string that will be accepted



481
482
483
# File 'lib/cdk/components/entry.rb', line 481

def setMax(max)
  @max = max
end

#setMin(min) ⇒ Object

This sets the minimum length of the string that will be accepted.



490
491
492
# File 'lib/cdk/components/entry.rb', line 490

def setMin(min)
  @min = min
end

#setPositionToEndObject



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/cdk/components/entry.rb', line 181

def setPositionToEnd
  if @info.size >= @field_width
    if @info.size < @max
      char_count = @field_width - 1
      @left_char = @info.size - char_count
      @screen_col = char_count
    else
      @left_char = @info.size - @field_width
      @screen_col = @info.size - 1
    end
  else
    @left_char = 0
    @screen_col = @info.size
  end
end

#setValue(new_value) ⇒ Object

This removes the old information in the entry field and keeps the new information given.



463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/cdk/components/entry.rb', line 463

def setValue(new_value)
  if new_value.nil?
    @info = ''

    @left_char = 0
    @screen_col = 0
  else
    @info = new_value.clone

    self.setPositionToEnd
  end
end

#unfocusObject



543
544
545
546
# File 'lib/cdk/components/entry.rb', line 543

def unfocus
  self.draw(box)
  wrefresh(@field_win)
end