metro 0.2.5 → 0.2.6

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 (35) hide show
  1. data/changelog.md +11 -0
  2. data/lib/assets/menu-movement.wav +0 -0
  3. data/lib/assets/menu-selection.wav +0 -0
  4. data/lib/metro.rb +1 -0
  5. data/lib/metro/asset_path.rb +27 -9
  6. data/lib/metro/events/event_dictionary.rb +1 -2
  7. data/lib/metro/font.rb +66 -0
  8. data/lib/metro/image.rb +4 -3
  9. data/lib/metro/models/draws.rb +8 -7
  10. data/lib/metro/models/model.rb +8 -5
  11. data/lib/metro/models/model_factory.rb +4 -6
  12. data/lib/metro/models/properties/animation_property.rb +1 -1
  13. data/lib/metro/models/properties/array_property.rb +24 -0
  14. data/lib/metro/models/properties/boolean_property.rb +27 -0
  15. data/lib/metro/models/properties/font_property.rb +5 -29
  16. data/lib/metro/models/properties/options_property/no_option.rb +29 -0
  17. data/lib/metro/models/properties/options_property/options.rb +94 -0
  18. data/lib/metro/models/properties/options_property/options_property.rb +125 -0
  19. data/lib/metro/models/properties/property.rb +14 -5
  20. data/lib/metro/models/properties/property_owner.rb +1 -0
  21. data/lib/metro/models/ui/generic.rb +22 -5
  22. data/lib/metro/models/ui/grid_drawer.rb +25 -15
  23. data/lib/metro/models/ui/image.rb +7 -3
  24. data/lib/metro/models/ui/label.rb +25 -15
  25. data/lib/metro/models/ui/menu.rb +106 -95
  26. data/lib/metro/models/ui/rectangle.rb +21 -8
  27. data/lib/metro/version.rb +1 -1
  28. data/spec/metro/models/properties/array_property_spec.rb +60 -0
  29. data/spec/metro/models/properties/{color_spec.rb → color_property_spec.rb} +0 -0
  30. data/spec/metro/models/properties/{font_spec.rb → font_property_spec.rb} +16 -18
  31. data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
  32. data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
  33. data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
  34. data/spec/metro/models/ui/label_spec.rb +56 -15
  35. metadata +29 -11
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metro::Model::OptionsProperty::NoOption do
4
+
5
+ context "when attempting to an attribute like color of the no option" do
6
+
7
+ let(:log) { mock('log') }
8
+
9
+ it "should generate a warning message" do
10
+ log.should_receive(:warn).with(subject.warning_message)
11
+ subject.stub(:log) { log }
12
+ subject.color = :unknown
13
+ end
14
+ end
15
+
16
+ context "when queried for its action" do
17
+
18
+ let(:expected_action) { :missing_menu_action }
19
+
20
+ it "should return 'missing_menu_action'" do
21
+ subject.properties[:action].should eq expected_action
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metro::Model::OptionsProperty do
4
+
5
+ subject { described_class.new model }
6
+ let(:model) { mock("model", create: 'builds models for a living') }
7
+
8
+ describe "#get" do
9
+ context "when the value is nil" do
10
+ context "when no menu has been specified" do
11
+ it "should return empty options" do
12
+ subject.get(nil).count.should eq 0
13
+ end
14
+ end
15
+ end
16
+
17
+
18
+ context "when the value is an array of options names" do
19
+ before do
20
+ model.stub(:create) { |model_type,options| mock(model_type,options) }
21
+ end
22
+
23
+ let(:names) { [ 'Start Game', 'Options', 'Exit Game' ] }
24
+ let(:actions) { [ :start_game, :options, :exit_game ] }
25
+
26
+ let(:options) { subject.get(names) }
27
+
28
+ it "should return an option for each name" do
29
+ options.count.should eq names.count
30
+ end
31
+
32
+ it "should create labels with text with each name" do
33
+ options.map { |option| option.text }.should eq names
34
+ end
35
+
36
+ it "should create actions based on each name" do
37
+ options.map { |option| option.action }.should eq actions
38
+ end
39
+
40
+ it "should set the default selected as the first item" do
41
+ options.selected.should eq options.first
42
+ end
43
+ end
44
+
45
+
46
+ context "when the value is a hash which is a set of option names and the selected index" do
47
+ before do
48
+ model.stub(:create) { |model_type,options| mock(model_type,options) }
49
+ end
50
+
51
+ let(:names_and_selected_index) do
52
+ { 'selected' => selected_index, 'items' => names }
53
+ end
54
+
55
+ let(:names) { [ 'Start Game', 'Options', 'Exit Game' ] }
56
+ let(:actions) { [ :start_game, :options, :exit_game ] }
57
+ let(:selected_index) { 1 }
58
+
59
+ let(:label_model_class) { 'metro::ui::label' }
60
+
61
+
62
+ let(:options) { subject.get(names_and_selected_index) }
63
+
64
+ it "should return an option for each name" do
65
+ options.count.should eq names.count
66
+ end
67
+
68
+ it "should create labels for each name" do
69
+ options.each { |option| option.model.should eq label_model_class }
70
+ end
71
+
72
+ it "should create labels with text with each name" do
73
+ options.map { |option| option.text }.should eq names
74
+ end
75
+
76
+ it "should create actions based on each name" do
77
+ options.map { |option| option.action }.should eq actions
78
+ end
79
+
80
+ it "should set the default selected as the first item" do
81
+ options.selected.should eq options[selected_index]
82
+ end
83
+ end
84
+
85
+
86
+ context "when the value is hash that contains a set of options (with specific ui details) and the seelcted index" do
87
+ before do
88
+ model.stub(:create) { |model_type,options| mock(model_type,options) }
89
+ end
90
+
91
+ let(:names_and_selected_index) do
92
+ { 'selected' => selected_index, 'items' => details }
93
+ end
94
+
95
+ let(:details) do
96
+ [ { model: 'metro::ui::label', text: 'Start Game!', action: 'start_game' },
97
+ { model: 'metro::ui::image', text: 'Settings', action: 'open_settings' },
98
+ { model: 'metro::ui::label', text: 'Exit' } ]
99
+ end
100
+
101
+
102
+ let(:names) { [ 'Start Game!', 'Settings', 'Exit' ] }
103
+ let(:actions) { [ :start_game, :open_settings, :exit ] }
104
+ let(:models) { [ 'metro::ui::label', 'metro::ui::image', 'metro::ui::label' ] }
105
+
106
+ let(:selected_index) { 1 }
107
+
108
+ let(:options) { subject.get(names_and_selected_index) }
109
+
110
+ it "should return an option for each name" do
111
+ options.count.should eq names.count
112
+ end
113
+
114
+ it "should create labels for each name" do
115
+ options.map { |option| option.model }.should eq models
116
+ end
117
+
118
+ it "should create labels with text with each name" do
119
+ options.map { |option| option.text }.should eq names
120
+ end
121
+
122
+ it "should create actions based on each name" do
123
+ options.map { |option| option.action }.should eq actions
124
+ end
125
+
126
+ it "should set the default selected as the first item" do
127
+ options.selected.should eq options[selected_index]
128
+ end
129
+ end
130
+
131
+ end
132
+
133
+ end
@@ -0,0 +1,125 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metro::Model::OptionsProperty::Options do
4
+
5
+ describe "ClassMethods" do
6
+ describe "#empty" do
7
+ it "should generate an empty set of options" do
8
+ described_class.empty.should be_kind_of described_class
9
+ end
10
+ end
11
+ end
12
+
13
+ subject { described_class.new [ :a, :b ] }
14
+
15
+ describe "#current_selected_index" do
16
+ it "should by default be 0" do
17
+ subject.current_selected_index.should eq 0
18
+ end
19
+
20
+ context "when the value is set to negative value" do
21
+ let(:expected_index) { subject.count - 1 }
22
+
23
+ it "should set the current_selected_index to the last item" do
24
+ subject.current_selected_index = -1
25
+ subject.current_selected_index.should eq expected_index
26
+ end
27
+ end
28
+
29
+ context "when the value is set to a value greater than the count" do
30
+ let(:expected_index) { 0 }
31
+
32
+ it "should set the current_selected_index to the first item" do
33
+ subject.current_selected_index = 4
34
+ subject.current_selected_index.should eq expected_index
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "#next!" do
40
+ before do
41
+ subject.current_selected_index = 0
42
+ end
43
+
44
+ let(:expected_index) { 1 }
45
+
46
+ it "should move the index to the next item" do
47
+ subject.next!
48
+ subject.current_selected_index.should eq expected_index
49
+ end
50
+
51
+ context "when next will pass the last item" do
52
+ before do
53
+ subject.current_selected_index = (subject.count - 1)
54
+ end
55
+
56
+ let(:expected_index) { 0 }
57
+
58
+ it "should return to the first item" do
59
+ subject.next!
60
+ subject.current_selected_index.should eq expected_index
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "#previous!" do
66
+ before do
67
+ subject.current_selected_index = 1
68
+ end
69
+
70
+ let(:expected_index) { 0 }
71
+
72
+ it "should move to the item previous of the current one" do
73
+ subject.previous!
74
+ subject.current_selected_index.should eq expected_index
75
+ end
76
+
77
+ context "when previous! will move before the first item" do
78
+ let(:expected_index) { subject.count - 1 }
79
+
80
+ it "should return to the last item" do
81
+ subject.previous!
82
+ subject.previous!
83
+ subject.current_selected_index.should eq expected_index
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "#selected" do
89
+ context "when their are options defined" do
90
+ let(:expected_selected) { subject[subject.current_selected_index] }
91
+
92
+ it "should return the item at the current_selected index" do
93
+ subject.selected.should eq expected_selected
94
+ end
95
+ end
96
+
97
+ context "when there are no options defined" do
98
+ subject { described_class.new [] }
99
+
100
+ it "should return a NoOption" do
101
+ subject.selected.should be_kind_of Metro::Model::OptionsProperty::NoOption
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "#selected_action" do
107
+ context "when there are options defined" do
108
+ subject { described_class.new [ mock('first-option',properties: { action: expected_action }), mock('second-option') ] }
109
+ let(:expected_action) { :execute_this_action }
110
+
111
+ it "should return the action defined on the current selected item" do
112
+ subject.selected_action.should eq expected_action
113
+ end
114
+ end
115
+
116
+ context "when there are no options defined" do
117
+ subject { described_class.new [] }
118
+
119
+ it "should return the action on the NoOption" do
120
+ subject.selected_action.should eq :missing_menu_action
121
+ end
122
+ end
123
+ end
124
+
125
+ end
@@ -76,7 +76,7 @@ describe Metro::UI::Label do
76
76
 
77
77
  describe "font" do
78
78
  before do
79
- Metro::Model::FontProperty.stub(:create_font).and_return(font)
79
+ Metro::Font.stub(:find_or_create).and_return(font)
80
80
  end
81
81
 
82
82
  let(:font) { mock('font', name: expected_font_name, size: expected_font_size) }
@@ -128,21 +128,16 @@ describe Metro::UI::Label do
128
128
  let(:scale_x) { 1.0 }
129
129
  let(:scale_y) { 1.0 }
130
130
 
131
+ let(:font) { mock('font') }
131
132
 
132
- let(:font_height) { 20 }
133
+ let(:line_height) { 20 }
133
134
 
134
135
  before do
135
136
  subject.text = given_text
136
137
  subject.position = Point.at(x_position,y_position,z_order)
137
138
  subject.scale = Scale.to(scale_x,scale_y)
138
139
  subject.stub(:font).and_return(font)
139
- end
140
-
141
- let(:font) do
142
- font = mock('font')
143
- font.stub(:text_width) { 12 }
144
- font.stub(:height) { font_height }
145
- font
140
+ subject.stub(:line_height) { line_height }
146
141
  end
147
142
 
148
143
  it "should have the font draw each of the lines" do
@@ -150,6 +145,52 @@ describe Metro::UI::Label do
150
145
  subject.draw
151
146
  end
152
147
 
148
+ context "when the horizontal alignment is center" do
149
+
150
+ before do
151
+ subject.align = "center"
152
+ subject.vertical_align = "top"
153
+ subject.stub(:line_width).with(first_line) { 60 }
154
+ subject.stub(:line_width).with(last_line) { 42 }
155
+ end
156
+
157
+ let(:first_line_x_position) { x_position - 30 }
158
+ let(:second_line_x_position) { x_position - 21 }
159
+
160
+ let(:first_line_y_position) { y_position }
161
+ let(:second_line_y_position) { y_position + line_height }
162
+
163
+ it "should draw the lines correctly based on their on their respective widths" do
164
+ font.should_receive(:draw).with(first_line,first_line_x_position,first_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
165
+ font.should_receive(:draw).with(last_line,second_line_x_position,second_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
166
+ subject.draw
167
+ end
168
+
169
+ end
170
+
171
+ context "when the horizontal alignment is right" do
172
+
173
+ before do
174
+ subject.align = "right"
175
+ subject.vertical_align = "top"
176
+ subject.stub(:line_width).with(first_line) { 60 }
177
+ subject.stub(:line_width).with(last_line) { 42 }
178
+ end
179
+
180
+ let(:first_line_x_position) { x_position - 60 }
181
+ let(:second_line_x_position) { x_position - 42 }
182
+
183
+ let(:first_line_y_position) { y_position }
184
+ let(:second_line_y_position) { y_position + line_height }
185
+
186
+ it "should draw the lines correctly based on their on their respective widths" do
187
+ font.should_receive(:draw).with(first_line,first_line_x_position,first_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
188
+ font.should_receive(:draw).with(last_line,second_line_x_position,second_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
189
+ subject.draw
190
+ end
191
+
192
+ end
193
+
153
194
  context "when the vertical alignment is top" do
154
195
 
155
196
  before do
@@ -157,7 +198,7 @@ describe Metro::UI::Label do
157
198
  end
158
199
 
159
200
  let(:first_line_y_position) { y_position }
160
- let(:second_line_y_position) { y_position + font_height }
201
+ let(:second_line_y_position) { y_position + line_height }
161
202
 
162
203
  it "should draw the first line at the y position" do
163
204
  font.should_receive(:draw).with(first_line,x_position,first_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
@@ -182,9 +223,9 @@ describe Metro::UI::Label do
182
223
  let(:third_line) { text.split("\n")[2] }
183
224
 
184
225
 
185
- let(:first_line_y_position) { y_position - font_height - font_height / 2 }
186
- let(:second_line_y_position) { y_position - font_height / 2 }
187
- let(:third_line_y_position) { y_position + font_height / 2 }
226
+ let(:first_line_y_position) { y_position - line_height - line_height / 2 }
227
+ let(:second_line_y_position) { y_position - line_height / 2 }
228
+ let(:third_line_y_position) { y_position + line_height / 2 }
188
229
 
189
230
  it "should draw the first line at the y position" do
190
231
  font.should_receive(:draw).with(first_line,x_position,first_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
@@ -201,8 +242,8 @@ describe Metro::UI::Label do
201
242
  subject.vertical_align = "bottom"
202
243
  end
203
244
 
204
- let(:first_line_y_position) { y_position - font_height * 2 }
205
- let(:second_line_y_position) { y_position - font_height }
245
+ let(:first_line_y_position) { y_position - line_height * 2 }
246
+ let(:second_line_y_position) { y_position - line_height }
206
247
 
207
248
  it "should draw the first line at the y position" do
208
249
  font.should_receive(:draw).with(first_line,x_position,first_line_y_position,z_order,scale_x,scale_y,an_instance_of(Gosu::Color))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-18 00:00:00.000000000 Z
12
+ date: 2012-11-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gosu
@@ -110,6 +110,8 @@ files:
110
110
  - Rakefile
111
111
  - bin/metro
112
112
  - changelog.md
113
+ - lib/assets/menu-movement.wav
114
+ - lib/assets/menu-selection.wav
113
115
  - lib/assets/missing.ogg
114
116
  - lib/assets/missing.png
115
117
  - lib/assets/missing.wav
@@ -145,6 +147,7 @@ files:
145
147
  - lib/metro/events/has_events.rb
146
148
  - lib/metro/events/hit_list.rb
147
149
  - lib/metro/events/unknown_sender.rb
150
+ - lib/metro/font.rb
148
151
  - lib/metro/game.rb
149
152
  - lib/metro/game/dsl.rb
150
153
  - lib/metro/image.rb
@@ -156,11 +159,16 @@ files:
156
159
  - lib/metro/models/model.rb
157
160
  - lib/metro/models/model_factory.rb
158
161
  - lib/metro/models/properties/animation_property.rb
162
+ - lib/metro/models/properties/array_property.rb
163
+ - lib/metro/models/properties/boolean_property.rb
159
164
  - lib/metro/models/properties/color_property.rb
160
165
  - lib/metro/models/properties/dimensions_property.rb
161
166
  - lib/metro/models/properties/font_property.rb
162
167
  - lib/metro/models/properties/image_property.rb
163
168
  - lib/metro/models/properties/numeric_property.rb
169
+ - lib/metro/models/properties/options_property/no_option.rb
170
+ - lib/metro/models/properties/options_property/options.rb
171
+ - lib/metro/models/properties/options_property/options_property.rb
164
172
  - lib/metro/models/properties/position_property.rb
165
173
  - lib/metro/models/properties/property.rb
166
174
  - lib/metro/models/properties/property_owner.rb
@@ -221,10 +229,14 @@ files:
221
229
  - spec/core_ext/string_spec.rb
222
230
  - spec/gosu_ext/color_spec.rb
223
231
  - spec/metro/models/key_value_coding_spec.rb
224
- - spec/metro/models/properties/color_spec.rb
232
+ - spec/metro/models/properties/array_property_spec.rb
233
+ - spec/metro/models/properties/color_property_spec.rb
225
234
  - spec/metro/models/properties/dimensions_spec.rb
226
- - spec/metro/models/properties/font_spec.rb
235
+ - spec/metro/models/properties/font_property_spec.rb
227
236
  - spec/metro/models/properties/numeric_property_spec.rb
237
+ - spec/metro/models/properties/options_property/no_option_spec.rb
238
+ - spec/metro/models/properties/options_property/options_property_spec.rb
239
+ - spec/metro/models/properties/options_property/options_spec.rb
228
240
  - spec/metro/models/properties/position_property_spec.rb
229
241
  - spec/metro/models/ui/label_spec.rb
230
242
  - spec/metro/scene_spec.rb
@@ -238,11 +250,13 @@ licenses: []
238
250
  post_install_message: ! " ______ ___ _____\n ___ |/ /_____ __ /_______________\n
239
251
  \ __ /|_/ / _ _ \\_ __/__ ___/_ __ \\\n _ / / / / __// /_ _ / /
240
252
  /_/ /\n /_/ /_/ \\___/ \\__/ /_/ \\____/\n\n Thank you for installing
241
- metro 0.2.5 / 2012-11-18.\n ---------------------------------------------------------------------\n
242
- \ Changes:\n \n * FIX metro::ui::rectangle calculation\n * FIX remaining references
243
- to metro::models::* to metro::ui::*\n * FIX Models will use their setters over
244
- setting raw properties\n * Metro::UI::Label now supports horizontal alignment,
245
- vertical alignment, and multiple lines\n \n\n ---------------------------------------------------------------------\n"
253
+ metro 0.2.6 / 2012/11-20.\n ---------------------------------------------------------------------\n
254
+ \ Changes:\n \n * Menus now support vertical and horizontal layout\n * Menus
255
+ now support movement and selection noises\n * Menus can now have a default selection\n
256
+ \ * Menus can be enabled/disabled\n * Added Array Property, Boolean Property, and
257
+ Menu Options Property\n * FIX label horizontal center and right alignments\n *
258
+ Generic Models will now show a warning instead of raising an exception\n * Removed
259
+ event chain debug messaging\n \n\n ---------------------------------------------------------------------\n"
246
260
  rdoc_options: []
247
261
  require_paths:
248
262
  - lib
@@ -271,10 +285,14 @@ test_files:
271
285
  - spec/core_ext/string_spec.rb
272
286
  - spec/gosu_ext/color_spec.rb
273
287
  - spec/metro/models/key_value_coding_spec.rb
274
- - spec/metro/models/properties/color_spec.rb
288
+ - spec/metro/models/properties/array_property_spec.rb
289
+ - spec/metro/models/properties/color_property_spec.rb
275
290
  - spec/metro/models/properties/dimensions_spec.rb
276
- - spec/metro/models/properties/font_spec.rb
291
+ - spec/metro/models/properties/font_property_spec.rb
277
292
  - spec/metro/models/properties/numeric_property_spec.rb
293
+ - spec/metro/models/properties/options_property/no_option_spec.rb
294
+ - spec/metro/models/properties/options_property/options_property_spec.rb
295
+ - spec/metro/models/properties/options_property/options_spec.rb
278
296
  - spec/metro/models/properties/position_property_spec.rb
279
297
  - spec/metro/models/ui/label_spec.rb
280
298
  - spec/metro/scene_spec.rb