cura 0.0.1

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.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +15 -0
  3. data/Gemfile.lock +122 -0
  4. data/LICENSE +20 -0
  5. data/README.md +159 -0
  6. data/Rakefile +42 -0
  7. data/cura.gemspec +23 -0
  8. data/examples/box_model/bin/box_model +11 -0
  9. data/examples/box_model/debug.log +0 -0
  10. data/examples/box_model/lib/box_model.rb +21 -0
  11. data/examples/box_model/lib/box_model/application.rb +24 -0
  12. data/examples/hello_world/bin/hello_world +10 -0
  13. data/examples/hello_world/lib/hello_world.rb +201 -0
  14. data/examples/mruby-examples/README.md +10 -0
  15. data/examples/mruby-examples/include/cura_examples.h +6 -0
  16. data/examples/mruby-examples/mrbgem.rake +14 -0
  17. data/examples/mruby-examples/src/gem_init.c +34 -0
  18. data/examples/mruby-examples/tools/hello_world/hello_world.c +6 -0
  19. data/examples/todo_list/app.log +9 -0
  20. data/examples/todo_list/bin/todo_list +26 -0
  21. data/examples/todo_list/data.db +0 -0
  22. data/examples/todo_list/debug.log +0 -0
  23. data/examples/todo_list/lib/todo_list.rb +28 -0
  24. data/examples/todo_list/lib/todo_list/application.rb +54 -0
  25. data/examples/todo_list/lib/todo_list/component/header.rb +27 -0
  26. data/examples/todo_list/lib/todo_list/component/list.rb +50 -0
  27. data/examples/todo_list/lib/todo_list/component/list_item.rb +28 -0
  28. data/examples/todo_list/lib/todo_list/component/list_items.rb +97 -0
  29. data/examples/todo_list/lib/todo_list/component/lists.rb +89 -0
  30. data/examples/todo_list/lib/todo_list/database.rb +50 -0
  31. data/examples/todo_list/lib/todo_list/model/list.rb +9 -0
  32. data/examples/todo_list/lib/todo_list/model/list_item.rb +9 -0
  33. data/examples/todo_list/profile.html +11354 -0
  34. data/lib/cura.rb +13 -0
  35. data/lib/cura/adapter.rb +67 -0
  36. data/lib/cura/application.rb +245 -0
  37. data/lib/cura/attributes/has_ancestry.rb +40 -0
  38. data/lib/cura/attributes/has_application.rb +31 -0
  39. data/lib/cura/attributes/has_attributes.rb +89 -0
  40. data/lib/cura/attributes/has_children.rb +113 -0
  41. data/lib/cura/attributes/has_colors.rb +66 -0
  42. data/lib/cura/attributes/has_coordinates.rb +49 -0
  43. data/lib/cura/attributes/has_dimensions.rb +63 -0
  44. data/lib/cura/attributes/has_events.rb +89 -0
  45. data/lib/cura/attributes/has_focusability.rb +37 -0
  46. data/lib/cura/attributes/has_initialize.rb +15 -0
  47. data/lib/cura/attributes/has_offsets.rb +82 -0
  48. data/lib/cura/attributes/has_orientation.rb +53 -0
  49. data/lib/cura/attributes/has_relative_coordinates.rb +39 -0
  50. data/lib/cura/attributes/has_root.rb +104 -0
  51. data/lib/cura/attributes/has_side_attributes.rb +95 -0
  52. data/lib/cura/attributes/has_windows.rb +70 -0
  53. data/lib/cura/borders.rb +16 -0
  54. data/lib/cura/color.rb +330 -0
  55. data/lib/cura/component/base.rb +180 -0
  56. data/lib/cura/component/button.rb +57 -0
  57. data/lib/cura/component/group.rb +77 -0
  58. data/lib/cura/component/label.rb +224 -0
  59. data/lib/cura/component/listbox.rb +152 -0
  60. data/lib/cura/component/pack.rb +144 -0
  61. data/lib/cura/component/scrollbar.rb +184 -0
  62. data/lib/cura/component/textbox.rb +118 -0
  63. data/lib/cura/cursor.rb +77 -0
  64. data/lib/cura/error/base.rb +10 -0
  65. data/lib/cura/error/invalid_adapter.rb +18 -0
  66. data/lib/cura/error/invalid_application.rb +18 -0
  67. data/lib/cura/error/invalid_color.rb +18 -0
  68. data/lib/cura/error/invalid_component.rb +18 -0
  69. data/lib/cura/error/invalid_middleware.rb +18 -0
  70. data/lib/cura/event.rb +38 -0
  71. data/lib/cura/event/base.rb +108 -0
  72. data/lib/cura/event/click.rb +14 -0
  73. data/lib/cura/event/dispatcher.rb +122 -0
  74. data/lib/cura/event/focus.rb +14 -0
  75. data/lib/cura/event/handler.rb +74 -0
  76. data/lib/cura/event/key_down.rb +68 -0
  77. data/lib/cura/event/middleware/aimer/base.rb +38 -0
  78. data/lib/cura/event/middleware/aimer/dispatcher_target.rb +24 -0
  79. data/lib/cura/event/middleware/aimer/mouse_focus.rb +48 -0
  80. data/lib/cura/event/middleware/aimer/target_option.rb +38 -0
  81. data/lib/cura/event/middleware/base.rb +21 -0
  82. data/lib/cura/event/middleware/dispatch.rb +20 -0
  83. data/lib/cura/event/middleware/translator/base.rb +37 -0
  84. data/lib/cura/event/middleware/translator/mouse_click.rb +44 -0
  85. data/lib/cura/event/mouse.rb +34 -0
  86. data/lib/cura/event/mouse_button.rb +103 -0
  87. data/lib/cura/event/mouse_wheel_down.rb +14 -0
  88. data/lib/cura/event/mouse_wheel_up.rb +14 -0
  89. data/lib/cura/event/resize.rb +17 -0
  90. data/lib/cura/event/selected.rb +14 -0
  91. data/lib/cura/event/unfocus.rb +14 -0
  92. data/lib/cura/focus_controller.rb +89 -0
  93. data/lib/cura/key.rb +313 -0
  94. data/lib/cura/margins.rb +16 -0
  95. data/lib/cura/offsets.rb +91 -0
  96. data/lib/cura/padding.rb +16 -0
  97. data/lib/cura/pencil.rb +29 -0
  98. data/lib/cura/version.rb +6 -0
  99. data/lib/cura/window.rb +85 -0
  100. data/spec/cura/attributes/has_ancestry_spec.rb +108 -0
  101. data/spec/cura/attributes/has_application_spec.rb +59 -0
  102. data/spec/cura/attributes/has_attributes_spec.rb +75 -0
  103. data/spec/cura/attributes/has_children_spec.rb +169 -0
  104. data/spec/cura/attributes/has_colors_spec.rb +20 -0
  105. data/spec/cura/attributes/has_coordinates_spec.rb +19 -0
  106. data/spec/cura/attributes/has_dimensions_spec.rb +19 -0
  107. data/spec/cura/attributes/has_events_spec.rb +18 -0
  108. data/spec/cura/attributes/has_focusability_spec.rb +58 -0
  109. data/spec/cura/attributes/has_offsets_spec.rb +18 -0
  110. data/spec/cura/attributes/has_orientation_spec.rb +102 -0
  111. data/spec/cura/attributes/has_relative_coordinates_spec.rb +18 -0
  112. data/spec/cura/attributes/has_side_attributes_spec.rb +19 -0
  113. data/spec/spec_helper.rb +12 -0
  114. data/spec/support/shared_examples_for_attributes.rb +122 -0
  115. metadata +211 -0
@@ -0,0 +1,21 @@
1
+ module Cura
2
+ module Event
3
+ module Middleware
4
+
5
+ # The base class for event middleware.
6
+ class Base
7
+
8
+ # Call this middleware.
9
+ #
10
+ # @param [#to_h] options
11
+ # @option options [Event::Dispatcher] :dispatcher
12
+ # @option options [Event::Base] :event
13
+ def call(_options={})
14
+ # Does nothing on purpose
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Cura
2
+ module Event
3
+ module Middleware
4
+
5
+ # Dispatches the event.
6
+ class Dispatch < Base
7
+
8
+ # Dispatch the event.
9
+ #
10
+ # @param [#to_h] options
11
+ # @option options [Event::Base] :event
12
+ def call(options={})
13
+ options[:dispatch_queue] << options[:event]
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/middleware/base"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+ module Middleware
8
+ module Translator
9
+
10
+ # The base class for event middleware which detects multiple events and dispatches a new one when found.
11
+ class Base
12
+
13
+ # Call this middleware.
14
+ #
15
+ # @param [#to_h] options
16
+ # @option options [Event::Dispatcher] :dispatcher
17
+ # @option options [Event::Base] :event
18
+ def call(options={})
19
+ translate_event(options) if should_translate?(options)
20
+ end
21
+
22
+ protected
23
+
24
+ def should_translate?(_options={})
25
+ false
26
+ end
27
+
28
+ def translate_event(_options={})
29
+ # Does nothing on purpose
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,44 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/mouse_button"
3
+ require "cura/event/middleware/translator/base"
4
+ end
5
+
6
+ module Cura
7
+ module Event
8
+ module Middleware
9
+ module Translator
10
+
11
+ # Translates MouseDown and MouseUp events into a MouseClick event.
12
+ class MouseClick < Base
13
+
14
+ def initialize
15
+ @last_mouse_down_at = Time.now
16
+ end
17
+
18
+ # Call this middleware.
19
+ #
20
+ # @param [#to_h] options
21
+ # @option options [Event::Dispatcher] :dispatcher
22
+ # @option options [Event::Base] :event
23
+ def call(options={})
24
+ event = options[:event]
25
+
26
+ return unless event.is_a?(Event::Mouse)
27
+
28
+ if event.down?
29
+ @last_mouse_down_at = event.created_at
30
+ @last_target = event.target
31
+ elsif event.up? && event.created_at > @last_mouse_down_at && @last_target.respond_to?(:contains_coordinates) && @last_target.contains_coordinates?(x: event.x, y: event.y)
32
+ @last_mouse_down_at = nil
33
+ @last_target = nil
34
+
35
+ options[:dispatch_queue] << Event.new_from_name(:mouse_button, state: :click, target: event.target, x: event.x, y: event.y) # TODO: Left? Right? Termbox can't tell..
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/base"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+
8
+ # Dispatched when a mouse's button state changes.
9
+ class Mouse < Base
10
+
11
+ # Get the X coordinate where the mouse button was pressed.
12
+ #
13
+ # @return [Integer]
14
+ attr_reader :x
15
+
16
+ # Get the Y coordinate where the mouse button was pressed.
17
+ #
18
+ # @return [Integer]
19
+ attr_reader :y
20
+
21
+ protected
22
+
23
+ def x=(value)
24
+ @x = value.to_i
25
+ end
26
+
27
+ def y=(value)
28
+ @y = value.to_i
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,103 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/mouse"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+
8
+ # Dispatched when a mouse's button state changes.
9
+ class MouseButton < Mouse
10
+
11
+ VALID_NAMES = [:left, :middle, :right]
12
+ VALID_STATES = [:up, :down, :click, :double_click]
13
+
14
+ def initialize(attributes={})
15
+ super
16
+
17
+ # raise ArgumentError, "name must be set" if @name.nil? # TODO: Termbox doesn't support which button was released yet
18
+ raise ArgumentError, "state must be set" if @state.nil?
19
+ end
20
+
21
+ # @method state
22
+ # Get the mouse button state.
23
+ # Will return `:up`, `:down`, `:click`, or `:double_click`.
24
+ #
25
+ # @return [Symbol]
26
+
27
+ # @method state=(value)
28
+ # Set the mouse button state.
29
+ #
30
+ # @param [#to_sym] value
31
+ # @return [Symbol]
32
+
33
+ attribute(:state) { |value| validate_list(value, VALID_STATES) }
34
+
35
+ # @method name
36
+ # Get the mouse button name.
37
+ # Will return `:left`, `:middle`, or `:right`.
38
+ #
39
+ # @return [Symbol]
40
+
41
+ # @method name=(value)
42
+ # Set the mouse button name.
43
+ #
44
+ # @param [#to_sym] value
45
+ # @return [Symbol]
46
+
47
+ attribute(:name) { |value| validate_list(value, VALID_NAMES) }
48
+
49
+ # @method left?
50
+ # Get whether the mouse button state occurred the left button.
51
+ #
52
+ # @return [Boolean]
53
+
54
+ # @method middle?
55
+ # Get whether the mouse button state occurred the middle button.
56
+ #
57
+ # @return [Boolean]
58
+
59
+ # @method right?
60
+ # Get whether the mouse button state occurred the right button.
61
+ #
62
+ # @return [Boolean]
63
+
64
+ VALID_NAMES.each do |name|
65
+ define_method("#{name}?") { @name == name }
66
+ end
67
+
68
+ # @method up?
69
+ # Get whether the mouse button state is up.
70
+ #
71
+ # @return [Boolean]
72
+
73
+ # @method down?
74
+ # Get whether the mouse button state is down.
75
+ #
76
+ # @return [Boolean]
77
+
78
+ # @method click?
79
+ # Get whether the mouse button state is click.
80
+ #
81
+ # @return [Boolean]
82
+
83
+ # @method click?
84
+ # Get whether the mouse button state is double_click.
85
+ #
86
+ # @return [Boolean]
87
+
88
+ VALID_STATES.each do |state|
89
+ define_method("#{state}?") { @state == state }
90
+ end
91
+
92
+ protected
93
+
94
+ def validate_list(value, list)
95
+ raise ArgumentError, "must be one of #{list.join(', ')}" unless list.include?(value)
96
+
97
+ value.to_sym
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,14 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/mouse"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+
8
+ # Dispatched when a mouse's wheel is scrolled down.
9
+ class MouseWheelDown < Mouse
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/mouse"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+
8
+ # Dispatched when a mouse's wheel is scrolled up.
9
+ class MouseWheelUp < Mouse
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/attributes/has_dimensions"
3
+ require "cura/event/base"
4
+ end
5
+
6
+ module Cura
7
+ module Event
8
+
9
+ # Dispatched when an object is resized.
10
+ class Resize < Base
11
+
12
+ include Attributes::HasDimensions
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/base"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+
8
+ # Dispatched when a component is selected.
9
+ class Selected < Base
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/event/base"
3
+ end
4
+
5
+ module Cura
6
+ module Event
7
+
8
+ # Dispatched when a component is unfocused.
9
+ class Unfocus < Base
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,89 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/attributes/has_initialize"
3
+ require "cura/attributes/has_attributes"
4
+ require "cura/attributes/has_application"
5
+ end
6
+
7
+ module Cura
8
+
9
+ class FocusController
10
+
11
+ include Attributes::HasInitialize
12
+ include Attributes::HasAttributes
13
+ include Attributes::HasApplication
14
+
15
+ def initialize(attributes={})
16
+ @index = 0
17
+
18
+ super
19
+
20
+ # TODO: raise error if window or application is nil
21
+ end
22
+
23
+ # @method window
24
+ # Get the window of the currently focused component.
25
+ #
26
+ # @return [Window]
27
+
28
+ # @method window=(value)
29
+ # Set the window of the currently focused component.
30
+ #
31
+ # @param [#to_i] value
32
+ # @return [Window]
33
+
34
+ attribute(:window) { |value| validate_window(value) }
35
+
36
+ # @method index
37
+ # Get the index of the currently focused component.
38
+ #
39
+ # @return [Integer]
40
+
41
+ # @method index=(value)
42
+ # Set the index of the currently focused component.
43
+ # This will dispatch a Event::Focus instance to the object.
44
+ #
45
+ # @param [#to_i] value
46
+ # @return [Integer]
47
+
48
+ attribute(:index) { |value| set_index(value) }
49
+
50
+ protected
51
+
52
+ def validate_window(window)
53
+ raise TypeError, "must be a Cura::Window" unless window.is_a?(Window)
54
+
55
+ window
56
+ end
57
+
58
+ def set_index(value)
59
+ index = value.to_i
60
+ focusable_children = focusable_children_of(@window.root)
61
+ index %= focusable_children.length
62
+
63
+ @window.application.dispatcher.target = focusable_children[index]
64
+
65
+ index
66
+ end
67
+
68
+ # TODO: When on a focusable component, set the index. When not on a focusable component, find nearest focusable component and set the index.
69
+ # def update_focused_index(component)
70
+ # focusable_children = focusable_children_of(@window.root)
71
+ #
72
+ # @index = focusable_children.index(component)
73
+ # end
74
+
75
+ # Recursively find all children which are focusable.
76
+ def focusable_children_of(component)
77
+ result = []
78
+
79
+ component.children.each do |child|
80
+ result << child if child.focusable?
81
+ result << focusable_children_of(child) if child.respond_to?(:children)
82
+ end
83
+
84
+ result.flatten
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,313 @@
1
+ module Cura
2
+
3
+ # Helpers for dealing with keyboard keys.
4
+ module Key
5
+
6
+ NAMES = { # Name => Character
7
+ :ac_back => nil,
8
+ :ac_bookmarks => nil,
9
+ :ac_forward => nil,
10
+ :ac_home => nil,
11
+ :ac_refresh => nil,
12
+ :ac_search => nil,
13
+ :ac_stop => nil,
14
+ :again => nil,
15
+ :alterase => nil,
16
+ :ampersand => "&",
17
+ :apostrophe => nil,
18
+ :application => nil,
19
+ :asterisk => "*",
20
+ :at => "@",
21
+ :audio_mute => nil,
22
+ :audio_next => nil,
23
+ :audio_play => nil,
24
+ :audio_prev => nil,
25
+ :audio_previous => nil,
26
+ :audio_stop => nil,
27
+ :backquote => "`",
28
+ :backslash => '\\',
29
+ :backspace => nil,
30
+ :binary => nil,
31
+ :brightness_down => nil,
32
+ :brightness_up => nil,
33
+ :calculator => nil,
34
+ :cancel => nil,
35
+ :capslock => nil,
36
+ :caret => "^",
37
+ :clear => nil,
38
+ :clear_again => nil,
39
+ :clear_entry => nil,
40
+ :colon => ":",
41
+ :comma => ",",
42
+ :computer => nil,
43
+ :copy => nil,
44
+ :crsel => nil, # TODO: Clear selection?
45
+ :currency_subunit => nil,
46
+ :currency_unit => nil,
47
+ :cut => nil,
48
+ :decimal => nil, # See: hexadecimal
49
+ :decimal_separator => nil,
50
+ :delete => nil,
51
+ :display_switch => nil,
52
+ :divide => "%",
53
+ :dollar => "$", # TODO: i18n?
54
+ :double_ampersand => nil,
55
+ :double_quote => '"',
56
+ :double_vertical_bar => nil,
57
+ :down => nil,
58
+ :eject => nil,
59
+ :end => nil,
60
+ :enter => nil,
61
+ :equals => "=",
62
+ :equalsas400 => nil,
63
+ :escape => nil,
64
+ :exclamation => "!",
65
+ :execute => nil,
66
+ :exsel => nil,
67
+ :f1 => nil,
68
+ :f10 => nil,
69
+ :f11 => nil,
70
+ :f12 => nil,
71
+ :f13 => nil,
72
+ :f14 => nil,
73
+ :f15 => nil,
74
+ :f16 => nil,
75
+ :f17 => nil,
76
+ :f18 => nil,
77
+ :f19 => nil,
78
+ :f2 => nil,
79
+ :f20 => nil,
80
+ :f21 => nil,
81
+ :f22 => nil,
82
+ :f23 => nil,
83
+ :f24 => nil,
84
+ :f3 => nil,
85
+ :f4 => nil,
86
+ :f5 => nil,
87
+ :f6 => nil,
88
+ :f7 => nil,
89
+ :f8 => nil,
90
+ :f9 => nil,
91
+ :find => nil,
92
+ :grave => nil,
93
+ :greater => ">",
94
+ :hash => "#",
95
+ :help => nil,
96
+ :hexadecimal => nil,
97
+ :home => nil,
98
+ :insert => nil,
99
+ :international_1 => nil,
100
+ :international_2 => nil,
101
+ :international_3 => nil,
102
+ :international_4 => nil,
103
+ :international_5 => nil,
104
+ :international_6 => nil,
105
+ :international_7 => nil,
106
+ :international_8 => nil,
107
+ :international_9 => nil,
108
+ :kbdillum_down => nil,
109
+ :kbdillum_toggle => nil,
110
+ :kbdillum_up => nil,
111
+ :language_1 => nil,
112
+ :language_2 => nil,
113
+ :language_3 => nil,
114
+ :language_4 => nil,
115
+ :language_5 => nil,
116
+ :language_6 => nil,
117
+ :language_7 => nil,
118
+ :language_8 => nil,
119
+ :language_9 => nil,
120
+ :left => nil,
121
+ :left_alt => nil,
122
+ :left_brace => "{",
123
+ :left_bracket => "[",
124
+ :left_control => nil,
125
+ :left_ctrl => nil,
126
+ :left_gui => nil,
127
+ :left_parenthesis => "(",
128
+ :left_race => nil,
129
+ :left_shift => nil,
130
+ :less => "<",
131
+ :a => "a",
132
+ :b => "b",
133
+ :c => "c",
134
+ :d => "d",
135
+ :e => "e",
136
+ :f => "f",
137
+ :g => "g",
138
+ :h => "h",
139
+ :i => "i",
140
+ :j => "j",
141
+ :k => "k",
142
+ :l => "l",
143
+ :m => "m",
144
+ :n => "n",
145
+ :o => "o",
146
+ :p => "p",
147
+ :q => "q",
148
+ :r => "r",
149
+ :s => "s",
150
+ :t => "t",
151
+ :u => "u",
152
+ :v => "v",
153
+ :w => "w",
154
+ :x => "x",
155
+ :y => "y",
156
+ :z => "z",
157
+ :A => "A",
158
+ :B => "B",
159
+ :C => "C",
160
+ :D => "D",
161
+ :E => "E",
162
+ :F => "F",
163
+ :G => "G",
164
+ :H => "H",
165
+ :I => "I",
166
+ :J => "J",
167
+ :K => "K",
168
+ :L => "L",
169
+ :M => "M",
170
+ :N => "N",
171
+ :O => "O",
172
+ :P => "P",
173
+ :Q => "Q",
174
+ :R => "R",
175
+ :S => "S",
176
+ :T => "T",
177
+ :U => "U",
178
+ :V => "V",
179
+ :W => "W",
180
+ :X => "X",
181
+ :Y => "Y",
182
+ :Z => "Z",
183
+ :locking_capslock => nil,
184
+ :locking_numlock => nil,
185
+ :locking_scrolllock => nil,
186
+ :mail => nil,
187
+ :media_select => nil,
188
+ :mem_add => nil,
189
+ :mem_clear => nil,
190
+ :mem_divide => nil,
191
+ :mem_multiply => nil,
192
+ :mem_recall => nil,
193
+ :mem_store => nil,
194
+ :mem_subtract => nil,
195
+ :menu => nil,
196
+ :minus => "-",
197
+ :mode => nil,
198
+ :multiply => "*",
199
+ :mute => nil,
200
+ :non_us_backslash => nil,
201
+ :non_us_hash => nil,
202
+ :"0" => "0",
203
+ :"00" => "00",
204
+ :"000" => "000",
205
+ :"1" => "1",
206
+ :"2" => "2",
207
+ :"3" => "3",
208
+ :"4" => "4",
209
+ :"5" => "5",
210
+ :"6" => "6",
211
+ :"7" => "7",
212
+ :"8" => "8",
213
+ :"9" => "9",
214
+ :numlock_clear => nil,
215
+ :numpad_0 => "0",
216
+ :numpad_1 => "1",
217
+ :numpad_2 => "2",
218
+ :numpad_3 => "3",
219
+ :numpad_4 => "4",
220
+ :numpad_5 => "5",
221
+ :numpad_6 => "6",
222
+ :numpad_7 => "7",
223
+ :numpad_8 => "8",
224
+ :numpad_9 => "9",
225
+ :numpad_equals => "=",
226
+ :numpad_slash => "/",
227
+ :numpad_asterisk => "*",
228
+ :numpad_minus => "-",
229
+ :numpad_plus => "+",
230
+ :numpad_enter => nil,
231
+ :numpad_period => ".",
232
+ :octal => nil,
233
+ :oper => nil,
234
+ :out => nil,
235
+ :page_down => nil,
236
+ :page_up => nil,
237
+ :paste => nil,
238
+ :pause => nil,
239
+ :percent => "%",
240
+ :period => ".",
241
+ :plus => "+",
242
+ :plus_minus => nil,
243
+ :power => nil,
244
+ :print_screen => nil,
245
+ :prior => nil,
246
+ :question => "?",
247
+ :quote => '\'',
248
+ :return => nil,
249
+ :right => nil,
250
+ :right_alt => nil,
251
+ :right_brace => "}",
252
+ :right_bracket => "]",
253
+ :right_control => nil,
254
+ :right_ctrl => nil,
255
+ :right_gui => nil,
256
+ :right_parenthesis => ")",
257
+ :right_shift => nil,
258
+ :scrolllock => nil,
259
+ :select => nil,
260
+ :semicolon => ";",
261
+ :separator => nil,
262
+ :slash => "/",
263
+ :sleep => nil,
264
+ :space => nil,
265
+ :stop => nil,
266
+ :sysreq => nil,
267
+ :tab => nil,
268
+ :thousands_separator => nil,
269
+ :tilde => "~",
270
+ :underscore => "_",
271
+ :undo => nil,
272
+ :unknown => nil,
273
+ :up => nil,
274
+ :vertical_bar => "|",
275
+ :volume_down => nil,
276
+ :volume_up => nil,
277
+ :www => nil,
278
+ :xor => nil
279
+ }
280
+
281
+ class << self
282
+
283
+ # Check if the given name is valid.
284
+ #
285
+ # @param [#to_sym] value
286
+ # @return [Boolean]
287
+ def valid_name?(value)
288
+ NAMES.key?(value.to_sym)
289
+ end
290
+
291
+ # Check if the given name is printable.
292
+ #
293
+ # @param [#to_sym] value
294
+ # @return [Boolean]
295
+ def name_is_printable?(value)
296
+ !NAMES[value.to_sym].nil?
297
+ end
298
+
299
+ def name_from_character(value)
300
+ value = value.to_s[0]
301
+
302
+ NAMES.key(value)
303
+ end
304
+
305
+ def character_from_name(value)
306
+ NAMES[value.to_sym]
307
+ end
308
+
309
+ end
310
+
311
+ end
312
+
313
+ end