cyberarm_engine 0.19.0 → 0.19.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/LICENSE.txt +21 -21
  7. data/README.md +74 -74
  8. data/Rakefile +10 -10
  9. data/bin/console +14 -14
  10. data/bin/setup +8 -8
  11. data/cyberarm_engine.gemspec +39 -39
  12. data/lib/cyberarm_engine/animator.rb +219 -219
  13. data/lib/cyberarm_engine/background.rb +179 -179
  14. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  15. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  16. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  17. data/lib/cyberarm_engine/cache/download_manager.rb +121 -121
  18. data/lib/cyberarm_engine/cache.rb +4 -4
  19. data/lib/cyberarm_engine/common.rb +113 -113
  20. data/lib/cyberarm_engine/config_file.rb +46 -46
  21. data/lib/cyberarm_engine/console/command.rb +157 -157
  22. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  23. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  24. data/lib/cyberarm_engine/console.rb +248 -248
  25. data/lib/cyberarm_engine/game_object.rb +248 -248
  26. data/lib/cyberarm_engine/game_state.rb +97 -97
  27. data/lib/cyberarm_engine/model/material.rb +21 -21
  28. data/lib/cyberarm_engine/model/model_object.rb +131 -131
  29. data/lib/cyberarm_engine/model/parser.rb +74 -74
  30. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  31. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  32. data/lib/cyberarm_engine/model.rb +212 -212
  33. data/lib/cyberarm_engine/model_cache.rb +31 -31
  34. data/lib/cyberarm_engine/opengl/light.rb +50 -50
  35. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  36. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -38
  37. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  38. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -164
  39. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +298 -298
  40. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -22
  41. data/lib/cyberarm_engine/opengl/shader.rb +406 -406
  42. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  43. data/lib/cyberarm_engine/opengl.rb +28 -28
  44. data/lib/cyberarm_engine/ray.rb +56 -56
  45. data/lib/cyberarm_engine/stats.rb +21 -21
  46. data/lib/cyberarm_engine/text.rb +197 -197
  47. data/lib/cyberarm_engine/timer.rb +23 -23
  48. data/lib/cyberarm_engine/transform.rb +296 -296
  49. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  50. data/lib/cyberarm_engine/ui/dsl.rb +139 -139
  51. data/lib/cyberarm_engine/ui/element.rb +488 -488
  52. data/lib/cyberarm_engine/ui/elements/button.rb +97 -97
  53. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  54. data/lib/cyberarm_engine/ui/elements/container.rb +256 -256
  55. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  56. data/lib/cyberarm_engine/ui/elements/edit_line.rb +263 -263
  57. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  58. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  59. data/lib/cyberarm_engine/ui/elements/list_box.rb +88 -82
  60. data/lib/cyberarm_engine/ui/elements/progress.rb +51 -51
  61. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  62. data/lib/cyberarm_engine/ui/elements/slider.rb +104 -104
  63. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  64. data/lib/cyberarm_engine/ui/elements/text_block.rb +162 -162
  65. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +65 -65
  66. data/lib/cyberarm_engine/ui/event.rb +54 -54
  67. data/lib/cyberarm_engine/ui/gui_state.rb +256 -256
  68. data/lib/cyberarm_engine/ui/style.rb +49 -49
  69. data/lib/cyberarm_engine/ui/theme.rb +207 -207
  70. data/lib/cyberarm_engine/vector.rb +293 -293
  71. data/lib/cyberarm_engine/version.rb +4 -4
  72. data/lib/cyberarm_engine/window.rb +120 -120
  73. data/lib/cyberarm_engine.rb +71 -71
  74. metadata +3 -3
@@ -1,256 +1,256 @@
1
- module CyberarmEngine
2
- class GuiState < GameState
3
- include Common
4
- include DSL
5
-
6
- def initialize(options = {})
7
- @options = options
8
- @game_objects = []
9
- @global_pause = false
10
-
11
- @down_keys = {}
12
-
13
- @root_container = Element::Stack.new(gui_state: self)
14
- @game_objects << @root_container
15
- $__current_container__ = @root_container
16
-
17
- @active_width = window.width
18
- @active_height = window.height
19
-
20
- @menu = nil
21
- @focus = nil
22
- @mouse_over = nil
23
- @mouse_down_on = {}
24
- @mouse_down_position = {}
25
- @last_mouse_pos = nil
26
- @dragging_element = nil
27
- @pending_recalculate_request = false
28
-
29
- @menu = nil
30
- @min_drag_distance = 0
31
- @mouse_pos = Vector.new
32
- end
33
-
34
- def post_setup
35
- @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY, theme: current_theme)
36
- end
37
-
38
- # throws :blur event to focused element and sets GuiState focused element
39
- # Does NOT throw :focus event at element or set element as focused
40
- def focus=(element)
41
- @focus.publish(:blur) if @focus && element && @focus != element
42
- @focus = element
43
- end
44
-
45
- def focused
46
- @focus
47
- end
48
-
49
- def draw
50
- super
51
-
52
- if @menu
53
- Gosu.flush
54
- @menu.draw
55
- end
56
-
57
- if @tip.value.length.positive?
58
- Gosu.flush
59
- @tip.draw
60
- end
61
-
62
- if defined?(GUI_DEBUG)
63
- Gosu.flush
64
-
65
- @root_container.debug_draw
66
- end
67
- end
68
-
69
- def update
70
- if @pending_recalculate_request
71
- @root_container.recalculate
72
- @root_container.recalculate
73
- @root_container.recalculate
74
-
75
- @pending_recalculate_request = false
76
- end
77
-
78
- if @pending_focus_request
79
- @pending_focus_request = false
80
-
81
- self.focus = @pending_focus_element
82
- @pending_focus_element.publish(:focus)
83
- end
84
-
85
- @menu&.update
86
- super
87
-
88
- new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
89
- new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
90
-
91
- if new_mouse_over
92
- new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over
93
- new_mouse_over.publish(:hover)
94
- # puts "#{new_mouse_over.class}[#{new_mouse_over.value}]: #{new_mouse_over.x}:#{new_mouse_over.y} #{new_mouse_over.width}:#{new_mouse_over.height}" if new_mouse_over != @mouse_over
95
- end
96
- @mouse_over.publish(:leave) if @mouse_over && new_mouse_over != @mouse_over
97
- @mouse_over = new_mouse_over
98
-
99
- redirect_holding_mouse_button(:left) if @mouse_over && Gosu.button_down?(Gosu::MsLeft)
100
- redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MsMiddle)
101
- redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MsRight)
102
-
103
- if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
104
- if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
105
- @tip.value = @mouse_over.tip if @mouse_over
106
- @tip.x = window.mouse_x
107
- @tip.x = 0 if @tip.x < 0
108
- @tip.x = window.width - @tip.width if @tip.x + @tip.width > window.width
109
- @tip.y = window.mouse_y - (@tip.height + 5)
110
- @tip.y = 0 if @tip.y < 0
111
- @tip.y = window.height - @tip.height if @tip.y + @tip.height > window.height
112
- @tip.update
113
- @tip.recalculate
114
- else
115
- @tip.value = ""
116
- end
117
- else
118
- @mouse_moved_at = Gosu.milliseconds
119
- end
120
-
121
- @last_mouse_pos = Vector.new(window.mouse_x, window.mouse_y)
122
- @mouse_pos = @last_mouse_pos.clone
123
-
124
- if @active_width != window.width || @active_height != window.height
125
- request_recalculate
126
- @root_container.publish(:window_size_changed)
127
- end
128
-
129
- @active_width = window.width
130
- @active_height = window.height
131
- end
132
-
133
- def tool_tip_delay
134
- 250 # ms
135
- end
136
-
137
- def button_down(id)
138
- super
139
-
140
- case id
141
- when Gosu::MsLeft
142
- redirect_mouse_button(:left)
143
- when Gosu::MsMiddle
144
- redirect_mouse_button(:middle)
145
- when Gosu::MsRight
146
- redirect_mouse_button(:right)
147
- when Gosu::KbF5
148
- request_recalculate
149
- end
150
-
151
- @focus.button_down(id) if @focus.respond_to?(:button_down)
152
- end
153
-
154
- def button_up(id)
155
- super
156
-
157
- case id
158
- when Gosu::MsLeft
159
- redirect_released_mouse_button(:left)
160
- when Gosu::MsMiddle
161
- redirect_released_mouse_button(:middle)
162
- when Gosu::MsRight
163
- redirect_released_mouse_button(:right)
164
- when Gosu::MsWheelUp
165
- redirect_mouse_wheel(:up)
166
- when Gosu::MsWheelDown
167
- redirect_mouse_wheel(:down)
168
- end
169
-
170
- @focus.button_up(id) if @focus.respond_to?(:button_up)
171
- end
172
-
173
- def redirect_mouse_button(button)
174
- hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
175
-
176
- if @focus && @mouse_over != @focus
177
- @focus.publish(:blur)
178
- @focus = nil
179
- end
180
-
181
- if @mouse_over
182
- @mouse_down_position[button] = Vector.new(window.mouse_x, window.mouse_y)
183
- @mouse_down_on[button] = @mouse_over
184
-
185
- @mouse_over.publish(:"#{button}_mouse_button", window.mouse_x, window.mouse_y)
186
- else
187
- @mouse_down_position[button] = nil
188
- @mouse_down_on[button] = nil
189
- end
190
- end
191
-
192
- def redirect_released_mouse_button(button)
193
- hide_menu if @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
194
-
195
- if @mouse_over
196
- @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y)
197
- if @mouse_over == @mouse_down_on[button]
198
- @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x,
199
- window.mouse_y)
200
- end
201
- end
202
-
203
- if @dragging_element
204
- @dragging_element.publish(:end_drag, window.mouse_x, window.mouse_y, button)
205
- @dragging_element = nil
206
- end
207
-
208
- @mouse_down_position[button] = nil
209
- @mouse_down_on[button] = nil
210
- end
211
-
212
- def redirect_holding_mouse_button(button)
213
- if !@dragging_element && @mouse_down_on[button] && @mouse_down_on[button].draggable?(button) && @mouse_pos.distance(@mouse_down_position[button]) > @min_drag_distance
214
- @dragging_element = @mouse_down_on[button]
215
- @dragging_element.publish(:begin_drag, window.mouse_x, window.mouse_y, button)
216
- end
217
-
218
- if @dragging_element
219
- @dragging_element.publish(:drag_update, window.mouse_x, window.mouse_y, button) if @dragging_element
220
- elsif @mouse_over
221
- @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y)
222
- end
223
- end
224
-
225
- def redirect_mouse_wheel(button)
226
- @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if @mouse_over
227
- end
228
-
229
- # Schedule a full GUI recalculation on next update
230
- def request_recalculate
231
- @pending_recalculate_request = true
232
- end
233
-
234
- def request_focus(element)
235
- @pending_focus_request = true
236
- @pending_focus_element = element
237
- end
238
-
239
- def show_menu(list_box)
240
- @menu = list_box
241
- end
242
-
243
- def hide_menu
244
- @menu = nil
245
- end
246
-
247
- def to_s
248
- # "#{self.class} children=#{@children.map { |c| c.to_s }}"
249
- @root_container.to_s
250
- end
251
-
252
- def inspect
253
- to_s
254
- end
255
- end
256
- end
1
+ module CyberarmEngine
2
+ class GuiState < GameState
3
+ include Common
4
+ include DSL
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ @game_objects = []
9
+ @global_pause = false
10
+
11
+ @down_keys = {}
12
+
13
+ @root_container = Element::Stack.new(gui_state: self)
14
+ @game_objects << @root_container
15
+ $__current_container__ = @root_container
16
+
17
+ @active_width = window.width
18
+ @active_height = window.height
19
+
20
+ @menu = nil
21
+ @focus = nil
22
+ @mouse_over = nil
23
+ @mouse_down_on = {}
24
+ @mouse_down_position = {}
25
+ @last_mouse_pos = nil
26
+ @dragging_element = nil
27
+ @pending_recalculate_request = false
28
+
29
+ @menu = nil
30
+ @min_drag_distance = 0
31
+ @mouse_pos = Vector.new
32
+ end
33
+
34
+ def post_setup
35
+ @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY, theme: current_theme)
36
+ end
37
+
38
+ # throws :blur event to focused element and sets GuiState focused element
39
+ # Does NOT throw :focus event at element or set element as focused
40
+ def focus=(element)
41
+ @focus.publish(:blur) if @focus && element && @focus != element
42
+ @focus = element
43
+ end
44
+
45
+ def focused
46
+ @focus
47
+ end
48
+
49
+ def draw
50
+ super
51
+
52
+ if @menu
53
+ Gosu.flush
54
+ @menu.draw
55
+ end
56
+
57
+ if @tip.value.length.positive?
58
+ Gosu.flush
59
+ @tip.draw
60
+ end
61
+
62
+ if defined?(GUI_DEBUG)
63
+ Gosu.flush
64
+
65
+ @root_container.debug_draw
66
+ end
67
+ end
68
+
69
+ def update
70
+ if @pending_recalculate_request
71
+ @root_container.recalculate
72
+ @root_container.recalculate
73
+ @root_container.recalculate
74
+
75
+ @pending_recalculate_request = false
76
+ end
77
+
78
+ if @pending_focus_request
79
+ @pending_focus_request = false
80
+
81
+ self.focus = @pending_focus_element
82
+ @pending_focus_element.publish(:focus)
83
+ end
84
+
85
+ @menu&.update
86
+ super
87
+
88
+ new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
89
+ new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
90
+
91
+ if new_mouse_over
92
+ new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over
93
+ new_mouse_over.publish(:hover)
94
+ # puts "#{new_mouse_over.class}[#{new_mouse_over.value}]: #{new_mouse_over.x}:#{new_mouse_over.y} #{new_mouse_over.width}:#{new_mouse_over.height}" if new_mouse_over != @mouse_over
95
+ end
96
+ @mouse_over.publish(:leave) if @mouse_over && new_mouse_over != @mouse_over
97
+ @mouse_over = new_mouse_over
98
+
99
+ redirect_holding_mouse_button(:left) if @mouse_over && Gosu.button_down?(Gosu::MsLeft)
100
+ redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MsMiddle)
101
+ redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MsRight)
102
+
103
+ if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
104
+ if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
105
+ @tip.value = @mouse_over.tip if @mouse_over
106
+ @tip.x = window.mouse_x
107
+ @tip.x = 0 if @tip.x < 0
108
+ @tip.x = window.width - @tip.width if @tip.x + @tip.width > window.width
109
+ @tip.y = window.mouse_y - (@tip.height + 5)
110
+ @tip.y = 0 if @tip.y < 0
111
+ @tip.y = window.height - @tip.height if @tip.y + @tip.height > window.height
112
+ @tip.update
113
+ @tip.recalculate
114
+ else
115
+ @tip.value = ""
116
+ end
117
+ else
118
+ @mouse_moved_at = Gosu.milliseconds
119
+ end
120
+
121
+ @last_mouse_pos = Vector.new(window.mouse_x, window.mouse_y)
122
+ @mouse_pos = @last_mouse_pos.clone
123
+
124
+ if @active_width != window.width || @active_height != window.height
125
+ request_recalculate
126
+ @root_container.publish(:window_size_changed)
127
+ end
128
+
129
+ @active_width = window.width
130
+ @active_height = window.height
131
+ end
132
+
133
+ def tool_tip_delay
134
+ 250 # ms
135
+ end
136
+
137
+ def button_down(id)
138
+ super
139
+
140
+ case id
141
+ when Gosu::MsLeft
142
+ redirect_mouse_button(:left)
143
+ when Gosu::MsMiddle
144
+ redirect_mouse_button(:middle)
145
+ when Gosu::MsRight
146
+ redirect_mouse_button(:right)
147
+ when Gosu::KbF5
148
+ request_recalculate
149
+ end
150
+
151
+ @focus.button_down(id) if @focus.respond_to?(:button_down)
152
+ end
153
+
154
+ def button_up(id)
155
+ super
156
+
157
+ case id
158
+ when Gosu::MsLeft
159
+ redirect_released_mouse_button(:left)
160
+ when Gosu::MsMiddle
161
+ redirect_released_mouse_button(:middle)
162
+ when Gosu::MsRight
163
+ redirect_released_mouse_button(:right)
164
+ when Gosu::MsWheelUp
165
+ redirect_mouse_wheel(:up)
166
+ when Gosu::MsWheelDown
167
+ redirect_mouse_wheel(:down)
168
+ end
169
+
170
+ @focus.button_up(id) if @focus.respond_to?(:button_up)
171
+ end
172
+
173
+ def redirect_mouse_button(button)
174
+ hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
175
+
176
+ if @focus && @mouse_over != @focus
177
+ @focus.publish(:blur)
178
+ @focus = nil
179
+ end
180
+
181
+ if @mouse_over
182
+ @mouse_down_position[button] = Vector.new(window.mouse_x, window.mouse_y)
183
+ @mouse_down_on[button] = @mouse_over
184
+
185
+ @mouse_over.publish(:"#{button}_mouse_button", window.mouse_x, window.mouse_y)
186
+ else
187
+ @mouse_down_position[button] = nil
188
+ @mouse_down_on[button] = nil
189
+ end
190
+ end
191
+
192
+ def redirect_released_mouse_button(button)
193
+ hide_menu if @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
194
+
195
+ if @mouse_over
196
+ @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y)
197
+ if @mouse_over == @mouse_down_on[button]
198
+ @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x,
199
+ window.mouse_y)
200
+ end
201
+ end
202
+
203
+ if @dragging_element
204
+ @dragging_element.publish(:end_drag, window.mouse_x, window.mouse_y, button)
205
+ @dragging_element = nil
206
+ end
207
+
208
+ @mouse_down_position[button] = nil
209
+ @mouse_down_on[button] = nil
210
+ end
211
+
212
+ def redirect_holding_mouse_button(button)
213
+ if !@dragging_element && @mouse_down_on[button] && @mouse_down_on[button].draggable?(button) && @mouse_pos.distance(@mouse_down_position[button]) > @min_drag_distance
214
+ @dragging_element = @mouse_down_on[button]
215
+ @dragging_element.publish(:begin_drag, window.mouse_x, window.mouse_y, button)
216
+ end
217
+
218
+ if @dragging_element
219
+ @dragging_element.publish(:drag_update, window.mouse_x, window.mouse_y, button) if @dragging_element
220
+ elsif @mouse_over
221
+ @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y)
222
+ end
223
+ end
224
+
225
+ def redirect_mouse_wheel(button)
226
+ @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if @mouse_over
227
+ end
228
+
229
+ # Schedule a full GUI recalculation on next update
230
+ def request_recalculate
231
+ @pending_recalculate_request = true
232
+ end
233
+
234
+ def request_focus(element)
235
+ @pending_focus_request = true
236
+ @pending_focus_element = element
237
+ end
238
+
239
+ def show_menu(list_box)
240
+ @menu = list_box
241
+ end
242
+
243
+ def hide_menu
244
+ @menu = nil
245
+ end
246
+
247
+ def to_s
248
+ # "#{self.class} children=#{@children.map { |c| c.to_s }}"
249
+ @root_container.to_s
250
+ end
251
+
252
+ def inspect
253
+ to_s
254
+ end
255
+ end
256
+ end
@@ -1,49 +1,49 @@
1
- module Gosu
2
- class Color
3
- def _dump(_level)
4
- [
5
- "%02X" % alpha,
6
- "%02X" % red,
7
- "%02X" % green,
8
- "%02X" % blue
9
- ].join
10
- end
11
-
12
- def self._load(hex)
13
- argb(hex.to_i(16))
14
- end
15
- end
16
- end
17
-
18
- module CyberarmEngine
19
- class Style
20
- attr_reader :hash
21
-
22
- def initialize(hash = {})
23
- h = Marshal.load(Marshal.dump(hash))
24
-
25
- h[:default] = {}
26
-
27
- h.each do |key, value|
28
- next if value.is_a?(Hash)
29
-
30
- h[:default][key] = value
31
- end
32
-
33
- @hash = h
34
- end
35
-
36
- def method_missing(method, *args)
37
- if method.to_s.end_with?("=")
38
- raise "Did not expect more than 1 argument" if args.size > 1
39
-
40
- @hash[method.to_s.sub("=", "").to_sym] = args.first
41
-
42
- elsif args.empty?
43
- @hash[method]
44
- else
45
- raise ArgumentError, "Did not expect arguments"
46
- end
47
- end
48
- end
49
- end
1
+ module Gosu
2
+ class Color
3
+ def _dump(_level)
4
+ [
5
+ "%02X" % alpha,
6
+ "%02X" % red,
7
+ "%02X" % green,
8
+ "%02X" % blue
9
+ ].join
10
+ end
11
+
12
+ def self._load(hex)
13
+ argb(hex.to_i(16))
14
+ end
15
+ end
16
+ end
17
+
18
+ module CyberarmEngine
19
+ class Style
20
+ attr_reader :hash
21
+
22
+ def initialize(hash = {})
23
+ h = Marshal.load(Marshal.dump(hash))
24
+
25
+ h[:default] = {}
26
+
27
+ h.each do |key, value|
28
+ next if value.is_a?(Hash)
29
+
30
+ h[:default][key] = value
31
+ end
32
+
33
+ @hash = h
34
+ end
35
+
36
+ def method_missing(method, *args)
37
+ if method.to_s.end_with?("=")
38
+ raise "Did not expect more than 1 argument" if args.size > 1
39
+
40
+ @hash[method.to_s.sub("=", "").to_sym] = args.first
41
+
42
+ elsif args.empty?
43
+ @hash[method]
44
+ else
45
+ raise ArgumentError, "Did not expect arguments"
46
+ end
47
+ end
48
+ end
49
+ end