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.
Files changed (177) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +12 -0
  6. data/Guardfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +189 -0
  9. data/Rakefile +18 -0
  10. data/bin/metro +16 -0
  11. data/changelog.md +157 -0
  12. data/lib/assets/menu-movement.wav +0 -0
  13. data/lib/assets/menu-selection.wav +0 -0
  14. data/lib/assets/missing.ogg +0 -0
  15. data/lib/assets/missing.png +0 -0
  16. data/lib/assets/missing.wav +0 -0
  17. data/lib/assets/missing_animation.png +0 -0
  18. data/lib/commands/generate_game.rb +13 -0
  19. data/lib/commands/generate_model.rb +25 -0
  20. data/lib/commands/generate_scene.rb +36 -0
  21. data/lib/commands/generate_view.rb +21 -0
  22. data/lib/commands/thor.rb +83 -0
  23. data/lib/core_ext/class.rb +14 -0
  24. data/lib/core_ext/numeric.rb +59 -0
  25. data/lib/gosu_ext/color.rb +62 -0
  26. data/lib/gosu_ext/gosu_constants.rb +53 -0
  27. data/lib/locale/en.yml +35 -0
  28. data/lib/locale/locale.rb +1 -0
  29. data/lib/metro.rb +140 -0
  30. data/lib/metro/animation.rb +135 -0
  31. data/lib/metro/animation/after_interval_factory.rb +12 -0
  32. data/lib/metro/animation/animation_factory.rb +15 -0
  33. data/lib/metro/animation/easing/ease_in.rb +15 -0
  34. data/lib/metro/animation/easing/easing.rb +51 -0
  35. data/lib/metro/animation/easing/linear.rb +15 -0
  36. data/lib/metro/animation/has_animations.rb +70 -0
  37. data/lib/metro/animation/implicit_animation.rb +100 -0
  38. data/lib/metro/animation/on_update_operation.rb +96 -0
  39. data/lib/metro/animation/scene_animation.rb +16 -0
  40. data/lib/metro/asset_path.rb +97 -0
  41. data/lib/metro/events/control_definition.rb +11 -0
  42. data/lib/metro/events/controls.rb +42 -0
  43. data/lib/metro/events/event_data.rb +60 -0
  44. data/lib/metro/events/event_dictionary.rb +52 -0
  45. data/lib/metro/events/event_factory.rb +17 -0
  46. data/lib/metro/events/event_relay.rb +300 -0
  47. data/lib/metro/events/event_state_manager.rb +63 -0
  48. data/lib/metro/events/events.rb +3 -0
  49. data/lib/metro/events/has_events.rb +108 -0
  50. data/lib/metro/events/hit_list.rb +75 -0
  51. data/lib/metro/events/unknown_sender.rb +5 -0
  52. data/lib/metro/font.rb +69 -0
  53. data/lib/metro/game.rb +102 -0
  54. data/lib/metro/game/dsl.rb +68 -0
  55. data/lib/metro/image.rb +68 -0
  56. data/lib/metro/logging.rb +33 -0
  57. data/lib/metro/missing_scene.rb +21 -0
  58. data/lib/metro/models/audio/song.rb +33 -0
  59. data/lib/metro/models/draws.rb +86 -0
  60. data/lib/metro/models/key_value_coding.rb +38 -0
  61. data/lib/metro/models/model.rb +236 -0
  62. data/lib/metro/models/model_factory.rb +32 -0
  63. data/lib/metro/models/models.rb +62 -0
  64. data/lib/metro/models/properties/animation_property.rb +115 -0
  65. data/lib/metro/models/properties/array_property.rb +24 -0
  66. data/lib/metro/models/properties/boolean_property.rb +27 -0
  67. data/lib/metro/models/properties/color_property.rb +116 -0
  68. data/lib/metro/models/properties/dimensions_property.rb +84 -0
  69. data/lib/metro/models/properties/font_property.rb +130 -0
  70. data/lib/metro/models/properties/image_property.rb +96 -0
  71. data/lib/metro/models/properties/model_property.rb +84 -0
  72. data/lib/metro/models/properties/numeric_property.rb +29 -0
  73. data/lib/metro/models/properties/options_property/no_option.rb +29 -0
  74. data/lib/metro/models/properties/options_property/options.rb +94 -0
  75. data/lib/metro/models/properties/options_property/options_property.rb +125 -0
  76. data/lib/metro/models/properties/position_property.rb +90 -0
  77. data/lib/metro/models/properties/property.rb +221 -0
  78. data/lib/metro/models/properties/property_owner.rb +137 -0
  79. data/lib/metro/models/properties/sample_property.rb +84 -0
  80. data/lib/metro/models/properties/scale_property.rb +80 -0
  81. data/lib/metro/models/properties/song_property.rb +89 -0
  82. data/lib/metro/models/properties/text_property.rb +75 -0
  83. data/lib/metro/models/ui/animated_sprite.rb +85 -0
  84. data/lib/metro/models/ui/border.rb +95 -0
  85. data/lib/metro/models/ui/fps.rb +54 -0
  86. data/lib/metro/models/ui/generic.rb +66 -0
  87. data/lib/metro/models/ui/grid_drawer.rb +74 -0
  88. data/lib/metro/models/ui/image.rb +87 -0
  89. data/lib/metro/models/ui/label.rb +175 -0
  90. data/lib/metro/models/ui/menu.rb +214 -0
  91. data/lib/metro/models/ui/model_label.rb +65 -0
  92. data/lib/metro/models/ui/model_labeler.rb +79 -0
  93. data/lib/metro/models/ui/rectangle.rb +59 -0
  94. data/lib/metro/models/ui/sprite.rb +79 -0
  95. data/lib/metro/models/ui/tile_map.rb +162 -0
  96. data/lib/metro/models/ui/ui.rb +13 -0
  97. data/lib/metro/parameters/command_line_args_parser.rb +68 -0
  98. data/lib/metro/parameters/options.rb +25 -0
  99. data/lib/metro/parameters/parameters.rb +2 -0
  100. data/lib/metro/sample.rb +40 -0
  101. data/lib/metro/scene.rb +477 -0
  102. data/lib/metro/scenes.rb +154 -0
  103. data/lib/metro/song.rb +56 -0
  104. data/lib/metro/template_message.rb +60 -0
  105. data/lib/metro/transitions/edit_transition_scene.rb +100 -0
  106. data/lib/metro/transitions/fade_transition_scene.rb +66 -0
  107. data/lib/metro/transitions/scene_transitions.rb +44 -0
  108. data/lib/metro/transitions/transition_scene.rb +19 -0
  109. data/lib/metro/units/bounds.rb +8 -0
  110. data/lib/metro/units/calculation_validations.rb +74 -0
  111. data/lib/metro/units/dimensions.rb +60 -0
  112. data/lib/metro/units/point.rb +51 -0
  113. data/lib/metro/units/rectangle_bounds.rb +85 -0
  114. data/lib/metro/units/scale.rb +46 -0
  115. data/lib/metro/units/units.rb +6 -0
  116. data/lib/metro/version.rb +32 -0
  117. data/lib/metro/views/json_view.rb +60 -0
  118. data/lib/metro/views/no_view.rb +34 -0
  119. data/lib/metro/views/parsers.rb +42 -0
  120. data/lib/metro/views/scene_view.rb +107 -0
  121. data/lib/metro/views/view.rb +133 -0
  122. data/lib/metro/views/writers.rb +43 -0
  123. data/lib/metro/views/yaml_view.rb +94 -0
  124. data/lib/metro/window.rb +94 -0
  125. data/lib/setup_handlers/exit_if_dry_run.rb +26 -0
  126. data/lib/setup_handlers/game_execution.rb +65 -0
  127. data/lib/setup_handlers/load_game_configuration.rb +65 -0
  128. data/lib/setup_handlers/load_game_files.rb +101 -0
  129. data/lib/setup_handlers/move_to_game_directory.rb +25 -0
  130. data/lib/setup_handlers/reload_game_on_game_file_changes.rb +79 -0
  131. data/lib/templates/game/README.md.tt +52 -0
  132. data/lib/templates/game/assets/brand.jpg +0 -0
  133. data/lib/templates/game/assets/hero.png +0 -0
  134. data/lib/templates/game/lib/custom_easing.rb +32 -0
  135. data/lib/templates/game/metro.tt +63 -0
  136. data/lib/templates/game/models/hero.rb +62 -0
  137. data/lib/templates/game/scenes/brand_scene.rb +19 -0
  138. data/lib/templates/game/scenes/brand_to_title_scene.rb +13 -0
  139. data/lib/templates/game/scenes/first_scene.rb +28 -0
  140. data/lib/templates/game/scenes/game_scene.rb +43 -0
  141. data/lib/templates/game/scenes/title_scene.rb +15 -0
  142. data/lib/templates/game/views/brand.yaml +4 -0
  143. data/lib/templates/game/views/brand_to_title.yaml +8 -0
  144. data/lib/templates/game/views/first.yaml +26 -0
  145. data/lib/templates/game/views/title.yaml +11 -0
  146. data/lib/templates/message.erb +23 -0
  147. data/lib/templates/model.rb.tt +111 -0
  148. data/lib/templates/scene.rb.tt +140 -0
  149. data/lib/templates/view.yaml.tt +11 -0
  150. data/lib/tmxed_ext/tile_set.rb +34 -0
  151. data/metro.gemspec +56 -0
  152. data/spec/core_ext/numeric_spec.rb +78 -0
  153. data/spec/core_ext/string_spec.rb +33 -0
  154. data/spec/gosu_ext/color_spec.rb +80 -0
  155. data/spec/metro/events/event_state_manager_spec.rb +5 -0
  156. data/spec/metro/models/key_value_coding_spec.rb +61 -0
  157. data/spec/metro/models/properties/array_property_spec.rb +60 -0
  158. data/spec/metro/models/properties/color_property_spec.rb +85 -0
  159. data/spec/metro/models/properties/dimensions_spec.rb +29 -0
  160. data/spec/metro/models/properties/font_property_spec.rb +127 -0
  161. data/spec/metro/models/properties/numeric_property_spec.rb +46 -0
  162. data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
  163. data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
  164. data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
  165. data/spec/metro/models/properties/position_property_spec.rb +90 -0
  166. data/spec/metro/models/ui/label_spec.rb +259 -0
  167. data/spec/metro/parameters/command_line_args_parser_spec.rb +42 -0
  168. data/spec/metro/scene_spec.rb +15 -0
  169. data/spec/metro/scene_views/json_view_spec.rb +27 -0
  170. data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
  171. data/spec/metro/scenes_spec.rb +77 -0
  172. data/spec/metro/units/point_spec.rb +132 -0
  173. data/spec/metro/views/view_spec.rb +53 -0
  174. data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
  175. data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
  176. data/spec/spec_helper.rb +20 -0
  177. 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