metro-ld25 0.3.3
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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +12 -0
- data/Guardfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +189 -0
- data/Rakefile +18 -0
- data/bin/metro +16 -0
- data/changelog.md +157 -0
- data/lib/assets/menu-movement.wav +0 -0
- data/lib/assets/menu-selection.wav +0 -0
- data/lib/assets/missing.ogg +0 -0
- data/lib/assets/missing.png +0 -0
- data/lib/assets/missing.wav +0 -0
- data/lib/assets/missing_animation.png +0 -0
- data/lib/commands/generate_game.rb +13 -0
- data/lib/commands/generate_model.rb +25 -0
- data/lib/commands/generate_scene.rb +36 -0
- data/lib/commands/generate_view.rb +21 -0
- data/lib/commands/thor.rb +83 -0
- data/lib/core_ext/class.rb +14 -0
- data/lib/core_ext/numeric.rb +59 -0
- data/lib/gosu_ext/color.rb +62 -0
- data/lib/gosu_ext/gosu_constants.rb +53 -0
- data/lib/locale/en.yml +35 -0
- data/lib/locale/locale.rb +1 -0
- data/lib/metro.rb +140 -0
- data/lib/metro/animation.rb +135 -0
- data/lib/metro/animation/after_interval_factory.rb +12 -0
- data/lib/metro/animation/animation_factory.rb +15 -0
- data/lib/metro/animation/easing/ease_in.rb +15 -0
- data/lib/metro/animation/easing/easing.rb +51 -0
- data/lib/metro/animation/easing/linear.rb +15 -0
- data/lib/metro/animation/has_animations.rb +70 -0
- data/lib/metro/animation/implicit_animation.rb +100 -0
- data/lib/metro/animation/on_update_operation.rb +96 -0
- data/lib/metro/animation/scene_animation.rb +16 -0
- data/lib/metro/asset_path.rb +97 -0
- data/lib/metro/events/control_definition.rb +11 -0
- data/lib/metro/events/controls.rb +42 -0
- data/lib/metro/events/event_data.rb +60 -0
- data/lib/metro/events/event_dictionary.rb +52 -0
- data/lib/metro/events/event_factory.rb +17 -0
- data/lib/metro/events/event_relay.rb +300 -0
- data/lib/metro/events/event_state_manager.rb +63 -0
- data/lib/metro/events/events.rb +3 -0
- data/lib/metro/events/has_events.rb +108 -0
- data/lib/metro/events/hit_list.rb +75 -0
- data/lib/metro/events/unknown_sender.rb +5 -0
- data/lib/metro/font.rb +69 -0
- data/lib/metro/game.rb +102 -0
- data/lib/metro/game/dsl.rb +68 -0
- data/lib/metro/image.rb +68 -0
- data/lib/metro/logging.rb +33 -0
- data/lib/metro/missing_scene.rb +21 -0
- data/lib/metro/models/audio/song.rb +33 -0
- data/lib/metro/models/draws.rb +86 -0
- data/lib/metro/models/key_value_coding.rb +38 -0
- data/lib/metro/models/model.rb +236 -0
- data/lib/metro/models/model_factory.rb +32 -0
- data/lib/metro/models/models.rb +62 -0
- data/lib/metro/models/properties/animation_property.rb +115 -0
- data/lib/metro/models/properties/array_property.rb +24 -0
- data/lib/metro/models/properties/boolean_property.rb +27 -0
- data/lib/metro/models/properties/color_property.rb +116 -0
- data/lib/metro/models/properties/dimensions_property.rb +84 -0
- data/lib/metro/models/properties/font_property.rb +130 -0
- data/lib/metro/models/properties/image_property.rb +96 -0
- data/lib/metro/models/properties/model_property.rb +84 -0
- data/lib/metro/models/properties/numeric_property.rb +29 -0
- data/lib/metro/models/properties/options_property/no_option.rb +29 -0
- data/lib/metro/models/properties/options_property/options.rb +94 -0
- data/lib/metro/models/properties/options_property/options_property.rb +125 -0
- data/lib/metro/models/properties/position_property.rb +90 -0
- data/lib/metro/models/properties/property.rb +221 -0
- data/lib/metro/models/properties/property_owner.rb +137 -0
- data/lib/metro/models/properties/sample_property.rb +84 -0
- data/lib/metro/models/properties/scale_property.rb +80 -0
- data/lib/metro/models/properties/song_property.rb +89 -0
- data/lib/metro/models/properties/text_property.rb +75 -0
- data/lib/metro/models/ui/animated_sprite.rb +85 -0
- data/lib/metro/models/ui/border.rb +95 -0
- data/lib/metro/models/ui/fps.rb +54 -0
- data/lib/metro/models/ui/generic.rb +66 -0
- data/lib/metro/models/ui/grid_drawer.rb +74 -0
- data/lib/metro/models/ui/image.rb +87 -0
- data/lib/metro/models/ui/label.rb +175 -0
- data/lib/metro/models/ui/menu.rb +214 -0
- data/lib/metro/models/ui/model_label.rb +65 -0
- data/lib/metro/models/ui/model_labeler.rb +79 -0
- data/lib/metro/models/ui/rectangle.rb +59 -0
- data/lib/metro/models/ui/sprite.rb +79 -0
- data/lib/metro/models/ui/tile_map.rb +162 -0
- data/lib/metro/models/ui/ui.rb +13 -0
- data/lib/metro/parameters/command_line_args_parser.rb +68 -0
- data/lib/metro/parameters/options.rb +25 -0
- data/lib/metro/parameters/parameters.rb +2 -0
- data/lib/metro/sample.rb +40 -0
- data/lib/metro/scene.rb +477 -0
- data/lib/metro/scenes.rb +154 -0
- data/lib/metro/song.rb +56 -0
- data/lib/metro/template_message.rb +60 -0
- data/lib/metro/transitions/edit_transition_scene.rb +100 -0
- data/lib/metro/transitions/fade_transition_scene.rb +66 -0
- data/lib/metro/transitions/scene_transitions.rb +44 -0
- data/lib/metro/transitions/transition_scene.rb +19 -0
- data/lib/metro/units/bounds.rb +8 -0
- data/lib/metro/units/calculation_validations.rb +74 -0
- data/lib/metro/units/dimensions.rb +60 -0
- data/lib/metro/units/point.rb +51 -0
- data/lib/metro/units/rectangle_bounds.rb +85 -0
- data/lib/metro/units/scale.rb +46 -0
- data/lib/metro/units/units.rb +6 -0
- data/lib/metro/version.rb +32 -0
- data/lib/metro/views/json_view.rb +60 -0
- data/lib/metro/views/no_view.rb +34 -0
- data/lib/metro/views/parsers.rb +42 -0
- data/lib/metro/views/scene_view.rb +107 -0
- data/lib/metro/views/view.rb +133 -0
- data/lib/metro/views/writers.rb +43 -0
- data/lib/metro/views/yaml_view.rb +94 -0
- data/lib/metro/window.rb +94 -0
- data/lib/setup_handlers/exit_if_dry_run.rb +26 -0
- data/lib/setup_handlers/game_execution.rb +65 -0
- data/lib/setup_handlers/load_game_configuration.rb +65 -0
- data/lib/setup_handlers/load_game_files.rb +101 -0
- data/lib/setup_handlers/move_to_game_directory.rb +25 -0
- data/lib/setup_handlers/reload_game_on_game_file_changes.rb +79 -0
- data/lib/templates/game/README.md.tt +52 -0
- data/lib/templates/game/assets/brand.jpg +0 -0
- data/lib/templates/game/assets/hero.png +0 -0
- data/lib/templates/game/lib/custom_easing.rb +32 -0
- data/lib/templates/game/metro.tt +63 -0
- data/lib/templates/game/models/hero.rb +62 -0
- data/lib/templates/game/scenes/brand_scene.rb +19 -0
- data/lib/templates/game/scenes/brand_to_title_scene.rb +13 -0
- data/lib/templates/game/scenes/first_scene.rb +28 -0
- data/lib/templates/game/scenes/game_scene.rb +43 -0
- data/lib/templates/game/scenes/title_scene.rb +15 -0
- data/lib/templates/game/views/brand.yaml +4 -0
- data/lib/templates/game/views/brand_to_title.yaml +8 -0
- data/lib/templates/game/views/first.yaml +26 -0
- data/lib/templates/game/views/title.yaml +11 -0
- data/lib/templates/message.erb +23 -0
- data/lib/templates/model.rb.tt +111 -0
- data/lib/templates/scene.rb.tt +140 -0
- data/lib/templates/view.yaml.tt +11 -0
- data/lib/tmxed_ext/tile_set.rb +34 -0
- data/metro.gemspec +56 -0
- data/spec/core_ext/numeric_spec.rb +78 -0
- data/spec/core_ext/string_spec.rb +33 -0
- data/spec/gosu_ext/color_spec.rb +80 -0
- data/spec/metro/events/event_state_manager_spec.rb +5 -0
- data/spec/metro/models/key_value_coding_spec.rb +61 -0
- data/spec/metro/models/properties/array_property_spec.rb +60 -0
- data/spec/metro/models/properties/color_property_spec.rb +85 -0
- data/spec/metro/models/properties/dimensions_spec.rb +29 -0
- data/spec/metro/models/properties/font_property_spec.rb +127 -0
- data/spec/metro/models/properties/numeric_property_spec.rb +46 -0
- data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
- data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
- data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
- data/spec/metro/models/properties/position_property_spec.rb +90 -0
- data/spec/metro/models/ui/label_spec.rb +259 -0
- data/spec/metro/parameters/command_line_args_parser_spec.rb +42 -0
- data/spec/metro/scene_spec.rb +15 -0
- data/spec/metro/scene_views/json_view_spec.rb +27 -0
- data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
- data/spec/metro/scenes_spec.rb +77 -0
- data/spec/metro/units/point_spec.rb +132 -0
- data/spec/metro/views/view_spec.rb +53 -0
- data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
- data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
- data/spec/spec_helper.rb +20 -0
- metadata +374 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
module Metro
|
|
2
|
+
class Model
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# A font property maintains a Gosu::Font.
|
|
6
|
+
#
|
|
7
|
+
# A font property also defines a `font_size` property and a `font_name` property which allows a
|
|
8
|
+
# more direct interface. Changing these values will update the font the next time that it is drawn.
|
|
9
|
+
#
|
|
10
|
+
# A font is stored in the properties as a hash representation and is converted into
|
|
11
|
+
# a Gosu::Font when it is retrieved within the system. When retrieving a font the Font
|
|
12
|
+
# Property will attempt to use a font that already exists that meets that criteria.
|
|
13
|
+
#
|
|
14
|
+
# The fonts are cached within the font property to help performance by reducing the unncessary
|
|
15
|
+
# creation of similar fonts.
|
|
16
|
+
#
|
|
17
|
+
# @example Defining a font property
|
|
18
|
+
#
|
|
19
|
+
# class Scoreboard < Metro::Model
|
|
20
|
+
# property :font
|
|
21
|
+
#
|
|
22
|
+
# def draw
|
|
23
|
+
# font.draw text, x, y, z_order, x_factor, y_factor, color
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# @example Defining a font property providing a default
|
|
29
|
+
#
|
|
30
|
+
# class Hero < Metro::Model
|
|
31
|
+
# property :font, default: { name: 'Comic Sans', size: 80 }
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# @example Using the `font_size` and `font_name` properties
|
|
35
|
+
#
|
|
36
|
+
# class Hero < Metro::Model
|
|
37
|
+
# property :font, default: { name: 'Comic Sans', size: 80 }
|
|
38
|
+
# property :color, default: "rgba(255,0,0,1.0)"
|
|
39
|
+
#
|
|
40
|
+
# def dignified
|
|
41
|
+
# self.font_size = 45
|
|
42
|
+
# self.font_name = 'Helvetica'
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# @example Using a font property with a different property name
|
|
47
|
+
#
|
|
48
|
+
# class Hero < Metro::Model
|
|
49
|
+
# property :alt_font, type: :font, default: { name: 'Helvetica', size: 80 }
|
|
50
|
+
#
|
|
51
|
+
# def draw
|
|
52
|
+
# puts "Font: #{alt_font_name}:#{alt_font_size}"
|
|
53
|
+
# alt_font.draw text, x, y, z_order, x_factor, y_factor, color
|
|
54
|
+
# end
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
class FontProperty < Property
|
|
58
|
+
|
|
59
|
+
# Define a paired property which allows the setting of the font size
|
|
60
|
+
define_property :size, prefix: true
|
|
61
|
+
# Define a paired property which allows the setting of the font name
|
|
62
|
+
define_property :name, type: :text, prefix: true
|
|
63
|
+
|
|
64
|
+
# Return the default font when the value is not supported.
|
|
65
|
+
get do
|
|
66
|
+
default_font
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Create a font from the specified hash of data.
|
|
70
|
+
#
|
|
71
|
+
# @example Format of Hash
|
|
72
|
+
#
|
|
73
|
+
# { name: 'Times New Roman', size: 33 }
|
|
74
|
+
#
|
|
75
|
+
get Hash do |value|
|
|
76
|
+
self.class.font_for value.merge(window: model.window)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Save a hash of the default font when the value is not supported.
|
|
80
|
+
set do
|
|
81
|
+
{ name: default_font_name, size: default_font_size }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Save a hash representation of the font when given a font
|
|
85
|
+
set Metro::Font do |font|
|
|
86
|
+
{ name: font.name, size: font.height }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Save the hash provided. It is assumed to contain the correct font data.
|
|
90
|
+
set Hash, HashWithIndifferentAccess do |hash|
|
|
91
|
+
hash.to_hash
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# @return the default font to use when a value has not been provided.
|
|
96
|
+
#
|
|
97
|
+
def default_font
|
|
98
|
+
self.class.font_for name: default_font_name,
|
|
99
|
+
size: default_font_size,
|
|
100
|
+
window: model.window
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
#
|
|
104
|
+
# Use the specified default font size or fall back to 40.
|
|
105
|
+
#
|
|
106
|
+
def default_font_size
|
|
107
|
+
(options[:default] and options[:default][:size]) ? options[:default][:size] : 40
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Use the specified default font name or fall back to Gosu's default font name.
|
|
112
|
+
#
|
|
113
|
+
def default_font_name
|
|
114
|
+
(options[:default] and options[:default][:name]) ? options[:default][:name] : Gosu::default_font_name
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# Return a font that matches the specified criteria. Usig the name, size, and window a font will be
|
|
119
|
+
# generated or retrieved from the cache.
|
|
120
|
+
#
|
|
121
|
+
# @param [Hash] value the hash that contains the `name`, `size` and `window` that describe the font.
|
|
122
|
+
#
|
|
123
|
+
def self.font_for(value)
|
|
124
|
+
Font.find_or_create(value)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Metro
|
|
2
|
+
class Model
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# A image property maintains a Gosu::Image.
|
|
6
|
+
#
|
|
7
|
+
# An image is stored in the properties as a string to the specified image path and is converted into
|
|
8
|
+
# a Gosu::Image when it is retrieved within the system. When retrieving an image the Image
|
|
9
|
+
# Property will attempt to use a image at that path that already meets that criteria if it has been
|
|
10
|
+
# loaded.
|
|
11
|
+
#
|
|
12
|
+
# @example Defining a image property
|
|
13
|
+
#
|
|
14
|
+
# class Player < Metro::Model
|
|
15
|
+
# property :image
|
|
16
|
+
#
|
|
17
|
+
# def draw
|
|
18
|
+
# image.draw x, y, z_order, x_factor, y_factor, color, :add)
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# @example Defining an image property providing a path
|
|
24
|
+
#
|
|
25
|
+
# class Player < Metro::Model
|
|
26
|
+
# property :image, path: "player.png"
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# @example Using an image property with a different property name
|
|
30
|
+
#
|
|
31
|
+
# class Player < Metro::Model
|
|
32
|
+
# property :disconnected_image, type: :image, path: "disconnected_player.png"
|
|
33
|
+
#
|
|
34
|
+
# def draw
|
|
35
|
+
# disconnected_image.draw x, y, z_order, x_factor, y_factor, color, :add)
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
class ImageProperty < Property
|
|
40
|
+
|
|
41
|
+
# By default, getting will use the the default image.
|
|
42
|
+
get do
|
|
43
|
+
default_image
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Return the image at the specified path.
|
|
47
|
+
get String do |path|
|
|
48
|
+
self.class.image_for path: path, window: model.window
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# By default, setting will use the path of the default image.
|
|
52
|
+
set do
|
|
53
|
+
default_image.path
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Set the image with the specified path.
|
|
57
|
+
set String do |path|
|
|
58
|
+
path
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Set the image with the given image. A Gosu::Image does not normally
|
|
62
|
+
# store it's path, however, this functionality has been monkey-patched.
|
|
63
|
+
set Metro::Image do |image|
|
|
64
|
+
image.path
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# @return the default image based on the default image path specified.
|
|
69
|
+
#
|
|
70
|
+
def default_image
|
|
71
|
+
self.class.image_for path: default_image_path, window: model.window
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# @return the path provided as the default or if one has not been specified
|
|
76
|
+
# the default "missing.png"
|
|
77
|
+
#
|
|
78
|
+
def default_image_path
|
|
79
|
+
options[:path] or "missing.png"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# Return an image for the specified path. On first request it will be loaded from
|
|
84
|
+
# the file-system. On subsequent requests it will be pulled from the cache.
|
|
85
|
+
#
|
|
86
|
+
# @param [Hash] options the relative `path` to the image and the window for which it
|
|
87
|
+
# will be displayed.
|
|
88
|
+
#
|
|
89
|
+
def self.image_for(options)
|
|
90
|
+
Metro::Image.find_or_create(options)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Metro
|
|
2
|
+
class Model
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# A model property maintains a reference to another model. This property
|
|
6
|
+
# allows for an existing model to be more easily composed with other models.
|
|
7
|
+
#
|
|
8
|
+
# The model is stored as a hash which describes the model.
|
|
9
|
+
#
|
|
10
|
+
# @example Defining a model property with a block
|
|
11
|
+
#
|
|
12
|
+
# class ScoreBoard < Metro::Model
|
|
13
|
+
# property :position
|
|
14
|
+
# property :score
|
|
15
|
+
# property :label, type: :model do
|
|
16
|
+
# create "metro::ui::label", text: "", position: position
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# @example Defining a model property with a hash
|
|
21
|
+
#
|
|
22
|
+
# class ScoreBoard < Metro::Model
|
|
23
|
+
# property :position
|
|
24
|
+
# property :score
|
|
25
|
+
# property :label, type: :model, default: { model: "metro::ui::label",
|
|
26
|
+
# text: "", position: position }
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
class ModelProperty < Property
|
|
31
|
+
|
|
32
|
+
# When retrieving a model and the type is unsupported generate the
|
|
33
|
+
# model instance from the default.
|
|
34
|
+
get do
|
|
35
|
+
default_model
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# When retrieving a hash representation of the model, convert it into
|
|
39
|
+
# a Metro::Model instance.
|
|
40
|
+
get Hash do |params|
|
|
41
|
+
create_model params
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# When setting the property with an unsupported type, simply save an
|
|
45
|
+
# empty hash. Which later, if retrieved, it will generate a generic
|
|
46
|
+
# model.
|
|
47
|
+
set do
|
|
48
|
+
{}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# When setting the property with a hash, assume that the hash is a
|
|
52
|
+
# valid description of a Metro::Model.
|
|
53
|
+
set Hash, HashWithIndifferentAccess do |hash|
|
|
54
|
+
hash
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# When setting the property with a Metro::Model, convert the model into
|
|
58
|
+
# a hash.
|
|
59
|
+
set Metro::Model do |model|
|
|
60
|
+
model.to_hash
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# Allow for a model property to be defined with a block initialization or
|
|
65
|
+
# a default hash.
|
|
66
|
+
#
|
|
67
|
+
def default_model
|
|
68
|
+
if block
|
|
69
|
+
model.instance_eval(&block)
|
|
70
|
+
else
|
|
71
|
+
create_model options[:default]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @return [Metro::Model] return a model created by the current model that
|
|
76
|
+
# owns the property.
|
|
77
|
+
def create_model
|
|
78
|
+
model.create params[:model], params.except(:model)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Metro
|
|
2
|
+
class Model
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# The numeric property will simply convert any input into a floating
|
|
6
|
+
# point value. This is the same both on getting and setting.
|
|
7
|
+
#
|
|
8
|
+
class NumericProperty < Property
|
|
9
|
+
|
|
10
|
+
# For all cases the value is converted to floating point when it can
|
|
11
|
+
# otherwise the default number is used.
|
|
12
|
+
get_or_set do |value|
|
|
13
|
+
if value.is_a?(NilClass)
|
|
14
|
+
default_number
|
|
15
|
+
elsif value.respond_to?(:to_f)
|
|
16
|
+
value.to_f
|
|
17
|
+
else
|
|
18
|
+
default_number
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def default_number
|
|
23
|
+
options[:default].to_f
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Metro
|
|
2
|
+
class Model
|
|
3
|
+
class OptionsProperty
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# When the options cannot find a selected menu option then this no option
|
|
7
|
+
# is returned instead of a nil value. This allows for a warning to be generated
|
|
8
|
+
# if any methods target this item.
|
|
9
|
+
#
|
|
10
|
+
# Also if the option will send a 'missing_menu_action' if the options were to
|
|
11
|
+
# ask for the selected action.
|
|
12
|
+
#
|
|
13
|
+
class NoOption
|
|
14
|
+
def method_missing(name,*args,&block)
|
|
15
|
+
log.warn warning_message
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def warning_message
|
|
19
|
+
"No valid options were found in the menu"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def properties
|
|
23
|
+
{ action: :missing_menu_action }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Metro
|
|
2
|
+
class Model
|
|
3
|
+
class OptionsProperty
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# Options maintains the list of menu options that would be displayed in a menu.
|
|
7
|
+
# Each option is a component that can be rendered during the draw phase.
|
|
8
|
+
#
|
|
9
|
+
# Also, options maintains the currently selected item and has the ability to manage
|
|
10
|
+
# the changes from the previous.
|
|
11
|
+
#
|
|
12
|
+
class Options < SimpleDelegator
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Generate an empty set of options.
|
|
16
|
+
#
|
|
17
|
+
def self.empty
|
|
18
|
+
new []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Create options with the provided array of options.
|
|
23
|
+
#
|
|
24
|
+
# @param [Array] options the array of options that this object will maintain
|
|
25
|
+
# as it's list of options.
|
|
26
|
+
#
|
|
27
|
+
def initialize(options)
|
|
28
|
+
super(options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# @return [Fixnum] the index of the current selected option.
|
|
33
|
+
#
|
|
34
|
+
def current_selected_index
|
|
35
|
+
@current_selected_index ||= 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Set the index of the currently selected item. Values that exceed the possible
|
|
40
|
+
# count of options will reset to the beginning of the list of options.
|
|
41
|
+
# Values that proceed the start of of the list of options will fallback to the last option.
|
|
42
|
+
#
|
|
43
|
+
def current_selected_index=(value)
|
|
44
|
+
@current_selected_index = value || 0
|
|
45
|
+
@current_selected_index = 0 if @current_selected_index >= count
|
|
46
|
+
@current_selected_index = count - 1 if @current_selected_index <= -1
|
|
47
|
+
@current_selected_index
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# @return [Array] a list of all the options that are currently not selected.
|
|
52
|
+
#
|
|
53
|
+
def unselected
|
|
54
|
+
self - [ selected ]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# @return [Object] the currently selected option.
|
|
59
|
+
#
|
|
60
|
+
def selected
|
|
61
|
+
at(current_selected_index) || NoOption.new
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# @return [Symbol] the action name of the currently selected option. If no
|
|
66
|
+
# option is currently selected then the NoOption 'missing_menu_action' will be
|
|
67
|
+
# returned.
|
|
68
|
+
#
|
|
69
|
+
def selected_action
|
|
70
|
+
if selected.respond_to?(:properties) && selected.properties[:action]
|
|
71
|
+
selected.properties[:action]
|
|
72
|
+
else
|
|
73
|
+
selected.to_sym
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Move the current selected item to the next item
|
|
79
|
+
#
|
|
80
|
+
def next!
|
|
81
|
+
self.current_selected_index += 1
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Move the current selected item to the previous item
|
|
86
|
+
#
|
|
87
|
+
def previous!
|
|
88
|
+
self.current_selected_index -= 1
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|