Class: Device::IO

Inherits:
IO
  • Object
show all
Includes:
DaFunk::Helper
Defined in:
lib/device/io.rb

Constant Summary collapse

F1 =
"\001"
F2 =
"\002"
F3 =
"\003"
F4 =
"\004"
FUNC =
"\006"
UP =
"\007"
DOWN =
"\008"
"\009"
ENTER =
0x0D.chr
CLEAR =
0x0F.chr
ALPHA =
0x10.chr
SHARP =
0x11.chr
KEY_TIMEOUT =
0x12.chr
BACK =
"\017"
CANCEL =
0x1B.chr
IO_INPUT_NUMBERS =
:numbers
IO_INPUT_LETTERS =
:letters
IO_INPUT_ALPHA =
:alpha
IO_INPUT_SECRET =
:secret
IO_INPUT_DECIMAL =
:decimal
IO_INPUT_MONEY =
:money
IO_INPUT_MASK =
:mask
MASK_ALPHA =
:alpha
MASK_LETTERS =
:letters
MASK_NUMBERS =
:number
DEFAULT_TIMEOUT =
30000
NUMBERS =
%w(1 2 3 4 5 6 7 8 9 0)
ONE_NUMBER =
"1"
TWO_NUMBER =
"2"
THREE_NUMBER =
"3"
FOUR_NUMBER =
"4"
FIVE_NUMBER =
"5"
SIX_NUMBER =
"6"
SEVEN_NUMBER =
"7"
EIGHT_NUMBER =
"8"
NINE_NUMBER =
"9"
ZERO_NUMBER =
"0"
KEYBOARD_DEFAULT =
["qzQZ.", "abcABC", "defDEF", "ghiGHI", "jklJKL",
"mnoMNO", "prsPRS", "tuvTUV", "wxyWXY", ", *\#_$%-+="]

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.back_keyObject

Returns the value of attribute back_key.



51
52
53
# File 'lib/device/io.rb', line 51

def back_key
  @back_key
end

.back_key_labelObject

Returns the value of attribute back_key_label.



51
52
53
# File 'lib/device/io.rb', line 51

def back_key_label
  @back_key_label
end

.forward_keyObject

Returns the value of attribute forward_key.



51
52
53
# File 'lib/device/io.rb', line 51

def forward_key
  @forward_key
end

.forward_key_labelObject

Returns the value of attribute forward_key_label.



51
52
53
# File 'lib/device/io.rb', line 51

def forward_key_label
  @forward_key_label
end

.keys_rangeObject

Returns the value of attribute keys_range.



51
52
53
# File 'lib/device/io.rb', line 51

def keys_range
  @keys_range
end

.keys_validObject

Returns the value of attribute keys_valid.



51
52
53
# File 'lib/device/io.rb', line 51

def keys_valid
  @keys_valid
end

.timeoutObject

Returns the value of attribute timeout.



51
52
53
# File 'lib/device/io.rb', line 51

def timeout
  @timeout
end

Class Method Details

.change_next(text, mask_type = Device::IO::MASK_ALPHA) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/device/io.rb', line 241

def self.change_next(text, mask_type = Device::IO::MASK_ALPHA)
  char = text[-1]
  if char
    range = self.keys_range[mask_type].detect { |range| range.include?(char) }
    if range
      index = range.index(char)
      new_value = range[index+1]
      if new_value
        text[-1] = new_value
      else
        text[-1] = range[0]
      end
    end
  end
  text
end

.check_mask(char) ⇒ Object



295
296
297
298
299
300
301
302
303
304
# File 'lib/device/io.rb', line 295

def self.check_mask(char)
  case char
  when "9"
    Device::IO::MASK_NUMBERS
  when "A"
    Device::IO::MASK_LETTERS
  else # "a"
    Device::IO::MASK_ALPHA
  end
end

.check_mask_type(text, options) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/device/io.rb', line 227

def self.check_mask_type(text, options)
  if options[:mode] == Device::IO::IO_INPUT_ALPHA
    Device::IO::MASK_ALPHA
  elsif options[:mode] == Device::IO::IO_INPUT_LETTERS
    Device::IO::MASK_LETTERS
  elsif options[:mode] == Device::IO::IO_INPUT_NUMBERS
    Device::IO::MASK_NUMBERS
  elsif options[:mode] == Device::IO::IO_INPUT_MASK
    check_mask(options[:mask_clean].to_s[text.size - 1])
  else
    Device::IO::MASK_ALPHA
  end
end

.format(string, options) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/device/io.rb', line 267

def self.format(string, options)
  options[:label].to_s +
  if options[:mode] == IO_INPUT_MONEY || options[:mode] == IO_INPUT_DECIMAL
    number_to_currency(string, options)
  elsif options[:mode] == IO_INPUT_SECRET
    "*" * string.size
  elsif options[:mode] == IO_INPUT_MASK
    string.to_mask(options[:mask])
  else
    string
  end
end

.get_format(min, max, options = {}) ⇒ String

Restricted to terminals, get strings and numbers. The switch method between uppercase, lowercase and number characters is to keep pressing a same button quickly. The timeout of this operation is 1 second.

:value - Represent the current value, to be initially used.

:precision - Sets the level of precision (defaults to 2).

:separator - Sets the separator between the units (defaults to “.”).

:delimiter - Sets the thousands delimiter (defaults to “,”).

:label - Sets the label display before currency, eg.: “U$:”, “R$:”

:mask - If mode IO_INPUT_MASK a mask should send

(only numbers and letters are allowed), eg.: "9999-AAAA"

:mode - Define input modes:

:numbers (IO_INPUT_NUMBERS) - Only number.
:letters (IO_INPUT_LETTERS) - Only Letters.
:alpha (IO_INPUT_ALPHA) - Letters and numbers.
:secret (IO_INPUT_SECRET) - Secret *.
:decimal (IO_INPUT_DECIMAL) - Decimal input, only number.
:money (IO_INPUT_MONEY) - Money input, only number.
:mask (IO_INPUT_MASK) - Custom mask.

Parameters:

  • min (Fixnum)

    Minimum length of the input string.

  • max (Fixnum)

    Maximum length of the input string (127 bytes maximum).

  • options (Hash) (defaults to: {})

Returns:

  • (String)

    buffer read from keyboard



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
# File 'lib/device/io.rb', line 137

def self.get_format(min, max, options = {})
  set_default_format_option(options)
  key = text = options[:value] || ""

  while key != CANCEL
    Device::Display.clear options[:line]
    Device::Display.print_line format(text, options), options[:line], options[:column]
    key = getc
    if key == BACK
      text = text[0..-2]
    elsif key == KEY_TIMEOUT
      return KEY_TIMEOUT
    elsif key == ENTER
      return text
    elsif key == CANCEL
      return CANCEL
    elsif key == F1 || key == DOWN || key == UP || key == ALPHA
      change_next(text, check_mask_type(text, options))
      next
    elsif text.size >= max
      next
    elsif insert_key?(key, options)
      text << key
    end
  end
end

.get_format_or_touchscreen_action(max, touch_map, options = {}) ⇒ Object



164
165
166
167
168
169
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
198
199
200
201
202
203
204
# File 'lib/device/io.rb', line 164

def self.get_format_or_touchscreen_action(max, touch_map, options = {})
  set_default_format_option(options)
  key = text = options[:value] || ""
  time = Time.now + (options[:timeout] || 30000) / 1000
  ret = {}
  touch_clear
  Device::Display.clear options[:line]
  Device::Display.print_line format(text, options), options[:line], options[:column]
  loop do
    line_x, line_y = getxy_stream(100)
    if line_x && line_y
      ret = parse_touchscreen(touch_map, line_x, line_y)
      break(ret) if ret.include?(:touch_action)
    else
      key = getc(100)
      if key == BACK
        text = text[0..-2]
        Device::Display.clear options[:line]
        Device::Display.print_line format(text, options), options[:line], options[:column]
      elsif options[:timeout_enabled] && time < Time.now
        ret[:timeout] = Device::IO::KEY_TIMEOUT
        break(ret)
      elsif key == ENTER
        ret[:text] = text
        break(ret)
      elsif key == CANCEL
        ret[:cancel] = Device::IO::CANCEL
        break(ret)
      elsif key == F1 || key == DOWN || key == UP || key == ALPHA
        change_next(text, check_mask_type(text, options))
        next
      elsif text.size >= max
        next
      elsif insert_key?(key, options)
        text << key
        Device::Display.clear options[:line]
        Device::Display.print_line format(text, options), options[:line], options[:column]
      end
    end
  end
end

.getc(timeout = self.timeout) ⇒ String

Read 1 byte on keyboard, wait until be pressed

If not sent the default timeout is 30_000. If nil should be blocking.

Parameters:

  • timeout (Fixnum) (defaults to: self.timeout)

    Timeout in milliseconds to wait for key.

Returns:

  • (String)

    key read from keyboard



265
# File 'lib/device/io.rb', line 265

def self.getc(timeout = self.timeout); super(timeout); end

.getxyObject

> => 1, “x” => 10, “y” => 50



281
282
283
# File 'lib/device/io.rb', line 281

def self.getxy
  super
end

.insert_key?(key, options) ⇒ Boolean

Returns:

  • (Boolean)


285
286
287
288
289
290
291
292
293
# File 'lib/device/io.rb', line 285

def self.insert_key?(key, options)
  if options[:mode] == IO_INPUT_MONEY || options[:mode] == IO_INPUT_DECIMAL || options[:mode] == IO_INPUT_NUMBERS
    NUMBERS.include?(key)
  elsif options[:mode] != IO_INPUT_NUMBERS && options[:mode] != IO_INPUT_MONEY && options[:mode] != IO_INPUT_DECIMAL
    self.keys_valid.include? key
  else
    false
  end
end

.parse_touchscreen(touch_map, line_x, line_y) ⇒ Object



206
207
208
209
210
211
212
213
214
215
# File 'lib/device/io.rb', line 206

def self.parse_touchscreen(touch_map, line_x, line_y)
  ret = {}
  touch_map.each do |key, value|
    if value[:x].include?(line_x) && value[:y].include?(line_y)
      Device::Audio.beep(7, 60)
      ret[:touch_action] = key
    end
  end
  ret
end

.set_default_format_option(options) ⇒ Object



217
218
219
220
221
222
223
224
225
# File 'lib/device/io.rb', line 217

def self.set_default_format_option(options)
  options[:mode]   ||= IO_INPUT_LETTERS
  options[:line]   ||= 2
  options[:column] ||= 0

  if options[:mask]
    options[:mask_clean] = options[:mask].chars.reject{|ch| ch.match(/[^0-9A-Za-z]/) }.join
  end
end

.setup_keyboard(map, options = {}) ⇒ NilClass

Setup Keyboard Map

Examples:

one_letters   = "qzQZ _,."
two_letters   = "abcABC"
three_letters = "defDEF"
four_letters  = "ghiGHI"
five_letters  = "jklJKL"
six_letters   = "mnoMNO"
seven_letters = "prsPRS"
eight_letters = "tuvTUV"
nine_letters  = "wxyWXY"
zero_letters  = "spSP"
map = [one_letters, two_letters, three_letters, four_letters, five_letters,
six_letters, seven_letters, eight_letters, nine_letters, zero_letters]
Device::IO.setup_keyboard(map)

Parameters:

  • map (Array)

    contains the key map from 1 to 0 (0..9)

Returns:

  • (NilClass)

    nil.



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
# File 'lib/device/io.rb', line 74

def self.setup_keyboard(map, options = {})
  one_letters, two_letters, three_letters, four_letters, five_letters,
    six_letters, seven_letters, eight_letters, nine_letters, zero_letters =
    map

  range_number  = [
    ONE_NUMBER , TWO_NUMBER   , THREE_NUMBER , FOUR_NUMBER , FIVE_NUMBER ,
    SIX_NUMBER , SEVEN_NUMBER , EIGHT_NUMBER , NINE_NUMBER , ZERO_NUMBER
  ]
  range_letters = [
    one_letters, two_letters, three_letters, four_letters, five_letters,
    six_letters, seven_letters, eight_letters, nine_letters, zero_letters
  ]
  range_alpha = [
    ONE_NUMBER   + one_letters, TWO_NUMBER     + two_letters,
    THREE_NUMBER + three_letters, FOUR_NUMBER  + four_letters,
    FIVE_NUMBER  + five_letters, SIX_NUMBER    + six_letters,
    SEVEN_NUMBER + seven_letters, EIGHT_NUMBER + eight_letters,
    NINE_NUMBER  + nine_letters, ZERO_NUMBER   + zero_letters
  ]
  @keys_range = {MASK_ALPHA => range_alpha, MASK_LETTERS => range_letters, MASK_NUMBERS => range_number}
  @keys_valid = range_alpha.flatten.join

  self.back_key          = options[:back_key]          || Device::IO::F1
  self.back_key_label    = options[:back_key_label]    || " F1 "
  self.forward_key       = options[:forward_key]       || Device::IO::F2
  self.forward_key_label = options[:forward_key_label] || " F2 "
end