Class: RNDK::Scale

Inherits:
Widget show all
Defined in:
lib/rndk/scale.rb

Direct Known Subclasses

Fscale

Instance Attribute Summary

Attributes inherited from Widget

#BXAttr, #HZChar, #LLChar, #LRChar, #ULChar, #URChar, #VTChar, #accepts_focus, #binding_list, #border_size, #box, #exit_type, #has_focus, #is_visible, #screen, #screen_index, #supported_signals, #widget_type

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Widget

#Screen_XPOS, #Screen_YPOS, #after_processing, #before_processing, #bind_key, #bind_signal, #bindable_widget, #clean_bindings, #clean_title, #draw_title, #get_box, #getch, #is_bound?, #refresh_data, #run_key_binding, #run_signal_binding, #save_data, #setBXattr, #setHZchar, #setLLchar, #setLRchar, #setULchar, #setURchar, #setVTchar, #set_box, #set_exit_type, #set_title, #unbind_key, #valid?, #valid_type?

Constructor Details

#initialize(screen, config = {}) ⇒ Scale

Returns a new instance of Scale.



7
8
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rndk/scale.rb', line 7

def initialize(screen, config={})
  super()
  @widget_type = :scale
  @supported_signals += [:before_input, :after_input]

  x              = 0
  y              = 0
  title          = "scale"
  label          = "label"
  field_color    = RNDK::Color[:normal]
  field_width    = 0
  start          = 0
  low            = 0
  high           = 100
  inc            = 1
  fast_increment = 5
  box            = true
  shadow         = false

  config.each do |key, val|
    x              = val if key == :x
    y              = val if key == :y
    title          = val if key == :title
    label          = val if key == :label
    field_color    = val if key == :field_color
    field_width    = val if key == :field_width
    start          = val if key == :start
    low            = val if key == :low
    high           = val if key == :high
    inc            = val if key == :inc
    fast_increment = val if key == :fast_increment
    box            = val if key == :box
    shadow         = val if key == :shadow
  end

  parent_width  = Ncurses.getmaxx screen.window
  parent_height = Ncurses.getmaxy screen.window

  self.set_box box

  box_width  = field_width + 2 * @border_size
  box_height = @border_size * 2 + 1

  # Set some basic values of the widget's data field.
  @label = []
  @label_len = 0
  @label_win = nil

  # 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 = RNDK.set_widget_dimension(parent_width,
                                          field_width,
                                          0)
  box_width = field_width + 2 * @border_size

  # Translate the label string to a chtype array
  unless label.nil?
    label_len = []
    @label = RNDK.char2Chtype(label, label_len, [])
    @label_len = label_len[0]
    box_width = @label_len + field_width + 2
  end

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

  box_height += @title_lines

  # Make sure we didn't extend beyond the dimensions 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 = [x]
  ytmp = [y]
  RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
  xpos = xtmp[0]
  ypos = ytmp[0]

  # Make the widget's window.
  @win = Ncurses.newwin(box_height, box_width, ypos, xpos)

  # Is the main window nil?
  if @win.nil?
    self.destroy
    return nil
  end

  # Create the widget's label window.
  if @label.size > 0
    @label_win = Ncurses.subwin(@win,
                                1,
                                @label_len,
                                ypos + @title_lines + @border_size,
                                xpos + horizontal_adjust + @border_size)
    if @label_win.nil?
      self.destroy
      return nil
    end
  end

  # Create the widget's data field window.
  @field_win = Ncurses.subwin(@win,
                              1,
                              field_width,
                              ypos + @title_lines + @border_size,
                              xpos + @label_len + horizontal_adjust + @border_size)
  if @field_win.nil?
    self.destroy
    return nil
  end

  Ncurses.keypad(@field_win, true)
  Ncurses.keypad(@win, true)

  # Create the widget's data field.
  @screen = screen
  @parent = screen.window
  @shadow_win = nil
  @box_width = box_width
  @box_height = box_height
  @field_width = field_width
  @field_color = field_color
  @current = low
  @low = low
  @high = high
  @current = start
  @inc = inc
  @fastinc = fast_increment
  @accepts_focus = true
  @input_window = @win
  @shadow = shadow
  @field_edit = 0

  # Do we want a shadow?
  if shadow
    @shadow_win = Ncurses.newwin(box_height,
                                 box_width,
                                 ypos + 1,
                                 xpos + 1)
    if @shadow_win.nil?
      self.destroy
      return nil
    end
  end

  # Setup the key bindings.

  self.bind_key('u') { self.increment @inc     }
  self.bind_key('U') { self.increment @fastinc }
  self.bind_key('g') { @current = @low         }
  self.bind_key('^') { @current = @low         }
  self.bind_key('G') { @current = @high        }
  self.bind_key('$') { @current = @high        }

  screen.register(self.widget_type, self)
end

Class Method Details

.removeChar(string, col) ⇒ Object

Remove the character from the string at the given column, if it is blank. Returns true if a change was made.



255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/rndk/scale.rb', line 255

def self.removeChar(string, col)
  result = false
  if col >= 0 && string[col] != ' '
    while col < string.size - 1
      string[col] = string[col + 1]
      col += 1
    end
    string.chop!
    result = true
  end
  return result
end

Instance Method Details

#activate(actions = []) ⇒ Object

This allows the person to use the widget's data field.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/rndk/scale.rb', line 170

def activate(actions=[])
  ret = false

  self.draw

  if actions.nil? || actions.size == 0
    input = 0
    while true
      input = self.getch

      # Inject the character into the widget.
      ret = self.inject(input)

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

    return ret if @exit_type != :EARLY_EXIT
  end

  # Set the exit type and return.
  self.set_exit_type(0)
  ret
end

#decrement(by) ⇒ Object



302
303
304
# File 'lib/rndk/scale.rb', line 302

def decrement by
  @current = @current - by if (@current - by) < @current
end

#destroyObject

This function destroys the widget.



455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/rndk/scale.rb', line 455

def destroy
  self.clean_title
  @label = []

  # Clean up the windows.
  RNDK.window_delete @field_win
  RNDK.window_delete @label_win
  RNDK.window_delete @shadow_win
  RNDK.window_delete @win

  # Clean the key bindings.
  self.clean_bindings

  # Unregister this widget
  @screen.unregister(self.widget_type, self)
end

#drawObject

This function draws the widget.



405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/rndk/scale.rb', line 405

def draw
  Draw.drawShadow(@shadow_win) unless @shadow_win.nil?

  Draw.drawObjBox(@win, self) if @box

  self.draw_title @win

  # Draw the label.
  unless @label_win.nil?
    Draw.writeChtype(@label_win,
                     0,
                     0,
                     @label, RNDK::HORIZONTAL,
                     0,
                     @label_len)
    Ncurses.wrefresh @label_win
  end
  Ncurses.wrefresh @win

  # Draw the field window.
  self.draw_field
end

#draw_fieldObject

This draws the widget.



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/rndk/scale.rb', line 429

def draw_field
  Ncurses.werase(@field_win)

  # Draw the value in the field.
  temp = @current.to_s
  Draw.writeCharAttrib(@field_win,
                       @field_width - temp.size - 1,
                       0,
                       temp,
                       @field_color,
                       RNDK::HORIZONTAL,
                       0,
                       temp.size)

  self.moveToEditPosition(@field_edit)
  Ncurses.wrefresh(@field_win)
end

#eraseObject

This function erases the widget from the screen.



473
474
475
476
477
478
479
480
# File 'lib/rndk/scale.rb', line 473

def erase
  if self.valid?
    RNDK.window_erase @label_win
    RNDK.window_erase @field_win
    RNDK.window_erase @win
    RNDK.window_erase @shadow_win
  end
end

#focusObject



522
523
524
# File 'lib/rndk/scale.rb', line 522

def focus
  self.draw
end

#getHighValueObject



518
519
520
# File 'lib/rndk/scale.rb', line 518

def getHighValue
  return @high
end

#getLowValueObject



514
515
516
# File 'lib/rndk/scale.rb', line 514

def getLowValue
  return @low
end

#getValueObject



495
496
497
# File 'lib/rndk/scale.rb', line 495

def getValue
  return @current
end

#increment(by) ⇒ Object



306
307
308
# File 'lib/rndk/scale.rb', line 306

def increment by
  @current = @current + by if (@current + by) > @current
end

#inject(input) ⇒ Object

This function injects a single character into the widget.



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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/rndk/scale.rb', line 311

def inject input
  pp_return = true
  ret = false
  complete = false

  # Set the exit type.
  self.set_exit_type(0)

  # Draw the field.
  self.draw_field

  # Check if there is a pre-process function to be called.
  keep_going = self.run_signal_binding(:before_input, input)

  if keep_going

    # Check for a key bindings.
    if self.is_bound? input
      self.run_key_binding input
      #complete = true

    else
      case input
      when Ncurses::KEY_LEFT
        self.setEditPosition(@field_edit + 1)
      when Ncurses::KEY_RIGHT
        self.setEditPosition(@field_edit - 1)

      when Ncurses::KEY_DOWN  then self.decrement @inc
      when Ncurses::KEY_UP    then self.increment @inc
      when Ncurses::KEY_HOME  then @current = @low
      when Ncurses::KEY_END   then @current = @high
      when Ncurses::KEY_PPAGE, RNDK::BACKCHAR
        self.increment @fastinc
      when Ncurses::KEY_NPAGE, RNDK::FORCHAR
        self.decrement @fastinc
      when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
        self.set_exit_type(input)
        ret = @current
        complete = true
      when RNDK::KEY_ESC
        self.set_exit_type(input)
        complete = true
      when Ncurses::ERR
        self.set_exit_type(input)
        complete = true
      when RNDK::REFRESH
        @screen.erase
        @screen.refresh
      else
        if @field_edit != 0
          if !self.performEdit(input)
            RNDK.beep
          end
        else
          # The cursor is not within the editable text. Interpret
          # input as commands.
          case input
          when 'd'.ord, '-'.ord
            return self.inject(Ncurses::KEY_DOWN)
          when '+'.ord
            return self.inject(Ncurses::KEY_UP)
          when 'D'.ord
            return self.inject(Ncurses::KEY_NPAGE)
          when '0'.ord
            return self.inject(Ncurses::KEY_HOME)
          else
            RNDK.beep
          end
        end
      end
    end
    self.limitCurrentValue

    self.run_signal_binding(:after_input) if not complete
  end

  if not complete
    self.draw_field
    self.set_exit_type 0
  end

  @result_data = ret
  return ret
end

#limitCurrentValueObject

Check if the value lies outsid the low/high range. If so, force it in.



200
201
202
203
204
205
206
207
# File 'lib/rndk/scale.rb', line 200

def limitCurrentValue
  if @current < @low
    @current = @low
  elsif @current > @high
    @current = @high
  end
  RNDK.beep
end

#move(x, y, relative, refresh_flag) ⇒ Object

This moves the widget's data field to the given location.



398
399
400
401
402
# File 'lib/rndk/scale.rb', line 398

def move(x, y, relative, refresh_flag)
  windows = [@win, @label_win, @field_win, @shadow_win]

  self.move_specific(x, y, relative, refresh_flag, windows, [])
end

#moveToEditPosition(new_position) ⇒ Object

Move the cursor to the given edit-position



210
211
212
# File 'lib/rndk/scale.rb', line 210

def moveToEditPosition(new_position)
  Ncurses.wmove(@field_win, 0, @field_width - new_position - 1)
end

#performEdit(input) ⇒ Object

Perform an editing function for the field.



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
# File 'lib/rndk/scale.rb', line 269

def performEdit(input)
  result = false
  modify = true
  base = 0
  need = @field_width
  temp = ''
  col = need - @field_edit - 1

  Ncurses.wmove(@field_win, 0, base)
  Ncurses.winnstr(@field_win, temp, need)
  temp << ' '
  if RNDK.is_char?(input)  # Replace the char at the cursor
    temp[col] = input.chr
  elsif input == Ncurses::KEY_BACKSPACE
    # delete the char before the cursor
    modify = Scale.removeChar(temp, col - 1)
  elsif input == Ncurses::KEY_DC
    # delete the char at the cursor
    modify = Scale.removeChar(temp, col)
  else
    modify = false
  end
  if modify &&
      ((value, test) = temp.scanf(self.SCAN_FMT)).size == 2 &&
      test == ' ' &&
      value >= @low && value <= @high
    self.setValue(value)
    result = true
  end

  return result
end

#positionObject



530
531
532
# File 'lib/rndk/scale.rb', line 530

def position
  super(@win)
end

#SCAN_FMTObject



534
535
536
# File 'lib/rndk/scale.rb', line 534

def SCAN_FMT
  '%d%c'
end

#set(low, high, value, box) ⇒ Object

This function sets the low/high/current values of the widget.



483
484
485
486
487
# File 'lib/rndk/scale.rb', line 483

def set(low, high, value, box)
  self.setLowHigh(low, high)
  self.setValue value
  self.set_box box
end

#set_bg_color(attrib) ⇒ Object

This sets the background attribute of teh widget.



448
449
450
451
452
# File 'lib/rndk/scale.rb', line 448

def set_bg_color attrib
  Ncurses.wbkgd(@win, attrib)
  Ncurses.wbkgd(@field_win, attrib)
  Ncurses.wbkgd(@label_win, attrib) unless @label_win.nil?
end

#setEditPosition(new_position) ⇒ Object

Set the edit position. Normally the cursor is one cell to the right of the editable field. Moving it left over the field allows the user to modify cells by typing in replacement characters for the field's value.



241
242
243
244
245
246
247
248
249
250
251
# File 'lib/rndk/scale.rb', line 241

def setEditPosition(new_position)
  if new_position < 0
    RNDK.beep
  elsif new_position == 0
    @field_edit = new_position
  elsif self.validEditPosition(new_position)
    @field_edit = new_position
  else
    RNDK.beep
  end
end

#setLowHigh(low, high) ⇒ Object

This function sets the low/high values of the widget.



500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/rndk/scale.rb', line 500

def setLowHigh(low, high)
  # Make sure the values aren't out of bounds.
  if low <= high
    @low = low
    @high = high
  elsif low > high
    @low = high
    @high = low
  end

  # Make sure the user hasn't done something silly.
  self.limitCurrentValue
end

#setValue(value) ⇒ Object

This sets the widget's value



490
491
492
493
# File 'lib/rndk/scale.rb', line 490

def setValue value
  @current = value
  self.limitCurrentValue
end

#unfocusObject



526
527
528
# File 'lib/rndk/scale.rb', line 526

def unfocus
  self.draw
end

#validEditPosition(new_position) ⇒ Object

Check if the cursor is on a valid edit-position. This must be one of the non-blank cells in the field.



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/rndk/scale.rb', line 216

def validEditPosition(new_position)
  if new_position <= 0 || new_position >= @field_width
    return false
  end
  if self.moveToEditPosition(new_position) == Ncurses::ERR
    return false
  end
  ch = Ncurses.winch(@field_win)
  if ch.chr != ' '
    return true
  end
  if new_position > 1
    # Don't use recursion - only one level is wanted
    if self.moveToEditPosition(new_position - 1) == Ncurses::ERR
      return false
    end
    ch = Ncurses.winch(@field_win)
    return ch.chr != ' '
  end
  return false
end