metro-ld26 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +14 -0
- data/Guardfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +177 -0
- data/Rakefile +18 -0
- data/bin/metro +16 -0
- data/changelog.md +153 -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 +144 -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 +342 -0
- data/lib/metro/events/event_state_manager.rb +70 -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 +75 -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 +246 -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 +98 -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 +132 -0
- data/lib/metro/models/ui/tmx/isometric_position.rb +43 -0
- data/lib/metro/models/ui/tmx/orthogonal_position.rb +15 -0
- data/lib/metro/models/ui/tmx/tile_layer.rb +78 -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 +478 -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 +148 -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 +95 -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 +43 -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/tmx_ext/object.rb +26 -0
- data/lib/tmx_ext/tile_set.rb +41 -0
- data/metro.gemspec +57 -0
- data/metro.png +0 -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/image_spec.rb +33 -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/units/rectangle_bounds_spec.rb +56 -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
- data/spec/tmx_ext/object_spec.rb +96 -0
- data/spec/tmx_ext/tile_set_spec.rb +24 -0
- metadata +379 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
class FPS < Model
|
5
|
+
|
6
|
+
property :placement, type: :text, default: 'top'
|
7
|
+
property :color, default: "rgba(255,255,255,1.0)"
|
8
|
+
|
9
|
+
property :label, type: :model do
|
10
|
+
create "metro::ui::label", text: "FPS: 0", color: color
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_placements
|
14
|
+
@valid_placements ||= begin
|
15
|
+
{
|
16
|
+
top_left: { position: Game.bounds.top_left, align: 'left', vertical_align: 'top' },
|
17
|
+
top: { position: Point.at(Game.center.x, Game.bounds.top), align: 'center', vertical_align: 'top' },
|
18
|
+
top_right: { position: Game.bounds.top_right, align: 'right', vertical_align: 'top' },
|
19
|
+
right: { position: Point.at(Game.bounds.right, Game.center.y), align: 'right', vertical_align: 'center' },
|
20
|
+
bottom_right: { position: Game.bounds.bottom_right, align: 'right', vertical_align: 'bottom' },
|
21
|
+
bottom: { position: Point.at(Game.center.x, Game.bounds.bottom), align: 'right', vertical_align: 'bottom' },
|
22
|
+
bottom_left: { position: Game.bounds.bottom_right, align: 'left', vertical_align: 'bottom' },
|
23
|
+
left: { position: Point.at(Game.bounds.left, Game.center.y), align: 'left', vertical_align: 'center' }
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
@valid_placements.default = :top
|
28
|
+
@valid_placements
|
29
|
+
end
|
30
|
+
|
31
|
+
def show
|
32
|
+
place_label
|
33
|
+
end
|
34
|
+
|
35
|
+
def place_label
|
36
|
+
placement_hash = valid_placements[placement.to_sym]
|
37
|
+
|
38
|
+
label.align = placement_hash[:align]
|
39
|
+
label.vertical_align = placement_hash[:vertical_align]
|
40
|
+
label.position = placement_hash[:position]
|
41
|
+
end
|
42
|
+
|
43
|
+
def update
|
44
|
+
label.text = "FPS: #{Gosu.fps}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def draw
|
48
|
+
label.draw
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
#
|
5
|
+
# Generic model is used when no model can be found.
|
6
|
+
#
|
7
|
+
# @example Defining an actor in a scene without the model
|
8
|
+
#
|
9
|
+
# class IntroScene < GameScene
|
10
|
+
#
|
11
|
+
# draw :game_title, text: "Super Game Title", position: Game.center
|
12
|
+
# color: "rgba(255,255,255,1.0)"
|
13
|
+
#
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# The above `game_title` actor was likely suppose to be a `metro::ui::label`, but
|
17
|
+
# the model was not specified. So this warning would be generated.
|
18
|
+
#
|
19
|
+
class Generic < Model
|
20
|
+
|
21
|
+
# @attribute
|
22
|
+
# Sets whether the generic model has warned the user in the logs about it
|
23
|
+
# being a generic model.
|
24
|
+
property :warned, type: :boolean, default: false
|
25
|
+
|
26
|
+
def show
|
27
|
+
self.saveable_to_view = false
|
28
|
+
end
|
29
|
+
|
30
|
+
def draw
|
31
|
+
log.warn cannot_draw_message unless warned
|
32
|
+
self.warned = true
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def cannot_draw_message
|
38
|
+
%{Unable to draw #{name} in #{scene}
|
39
|
+
|
40
|
+
The actor named '#{name}' does not specify a suitable model so it could not be drawn in the scene.
|
41
|
+
|
42
|
+
#{properties}
|
43
|
+
|
44
|
+
Did you mean to use one of the following models:
|
45
|
+
|
46
|
+
Models defined in #{Game.name}:
|
47
|
+
|
48
|
+
#{user_defined_models.join(', ')}
|
49
|
+
|
50
|
+
Models defined in Metro:
|
51
|
+
|
52
|
+
#{metro_models.join(', ')}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def metro_models
|
57
|
+
Models.list.find_all {|m| m =~ /metro(::|\/).+(::|\/).+/i }
|
58
|
+
end
|
59
|
+
|
60
|
+
def user_defined_models
|
61
|
+
Models.list - metro_models
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
#
|
5
|
+
# The grid drawer will draw a grid from the specified position out to the specified
|
6
|
+
# dimensions at the spacing interval provided. This is currently used when the edit
|
7
|
+
# mode is enabled.
|
8
|
+
#
|
9
|
+
# @example Drawing a white, translucent, 100 by 100 grid starting at (20,20).
|
10
|
+
#
|
11
|
+
# class BuildScene < GameScene
|
12
|
+
# draw :grid, model: "metro::ui::grid_drawer", position: "20,20",
|
13
|
+
# color: "rgba(255,255,255,0.5)", spacing: 20, dimensions: "100,100"
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
class GridDrawer < Model
|
17
|
+
|
18
|
+
# @attribute
|
19
|
+
# The position to start drawing the grid
|
20
|
+
property :position, default: Point.at(0,0,100)
|
21
|
+
|
22
|
+
# @attribute
|
23
|
+
# The color of the grid lines
|
24
|
+
property :color, default: "rgba(255,255,255,0.1)"
|
25
|
+
|
26
|
+
# @attribute
|
27
|
+
# The interval which to draw the lines
|
28
|
+
property :spacing, type: :numeric, default: 10
|
29
|
+
|
30
|
+
# @attribute
|
31
|
+
# The dimension of the grid
|
32
|
+
property :dimensions do
|
33
|
+
Dimensions.of Game.width, Game.height
|
34
|
+
end
|
35
|
+
|
36
|
+
# @attribute
|
37
|
+
# This controls whether the grid should be drawn. By default
|
38
|
+
# the grid will be drawn.
|
39
|
+
property :enabled, type: :boolean, default: true
|
40
|
+
|
41
|
+
def show
|
42
|
+
self.saveable_to_view = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def draw
|
46
|
+
return unless enabled
|
47
|
+
draw_horizontal_lines
|
48
|
+
draw_vertical_lines
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def draw_vertical_lines
|
54
|
+
xs = (width / spacing + 1).to_i.times.map {|segment| segment * spacing }
|
55
|
+
xs.each do |x|
|
56
|
+
draw_line(x,1,x,height)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def draw_horizontal_lines
|
61
|
+
ys = (height / spacing + 1).to_i.times.map {|segment| segment * spacing }
|
62
|
+
ys.each do |y|
|
63
|
+
draw_line(1,y,width,y)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def draw_line(start_x,start_y,finish_x,finish_y)
|
68
|
+
window.draw_line(position.x + start_x, position.y + start_y, color,
|
69
|
+
position.x + finish_x, position.y + finish_y, color, 0, :additive)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
#
|
5
|
+
# The image will draw an image with the specifie path, color, rotation, and scale.
|
6
|
+
#
|
7
|
+
# @example Drawing the 'player.png' image at (320,240)
|
8
|
+
#
|
9
|
+
# class MainScene < GameScene
|
10
|
+
# draw :player, model: "metro::ui::image", position: "320,240",
|
11
|
+
# image: "player.png"
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
class Image < Model
|
15
|
+
|
16
|
+
# @attribute
|
17
|
+
# The position of the image
|
18
|
+
property :position
|
19
|
+
|
20
|
+
# @attribute
|
21
|
+
# The scale of the image
|
22
|
+
property :scale, default: Scale.one
|
23
|
+
|
24
|
+
# @attribute
|
25
|
+
# The color of the image, by default this is white to display the image
|
26
|
+
# as normal, but this can be used to augment the look of the image. Mostly
|
27
|
+
# color is use for the sub-property :alpha which allows an image to be
|
28
|
+
# faded-in and faded-out
|
29
|
+
property :color
|
30
|
+
|
31
|
+
# @attribute
|
32
|
+
# The angle at which to draw the image
|
33
|
+
property :angle, type: :numeric, default: 0
|
34
|
+
|
35
|
+
# @attribute
|
36
|
+
# The center x position of the image as expressed in a scale of from left
|
37
|
+
# to right (0.0 to 1.0).
|
38
|
+
property :center_x, type: :numeric, default: 0.5
|
39
|
+
|
40
|
+
# @attribute
|
41
|
+
# The center y position of the image as expressed in a scale of from top
|
42
|
+
# to bottom (0.0 to 1.0).
|
43
|
+
property :center_y, type: :numeric, default: 0.5
|
44
|
+
|
45
|
+
# @attribute
|
46
|
+
# The image asset to draw.
|
47
|
+
property :image
|
48
|
+
|
49
|
+
# @attribute
|
50
|
+
# The dimensions of the image.
|
51
|
+
property :dimensions do
|
52
|
+
image.dimensions
|
53
|
+
end
|
54
|
+
|
55
|
+
def bounds
|
56
|
+
Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
|
57
|
+
end
|
58
|
+
|
59
|
+
def draw
|
60
|
+
image.draw_rot x, y, z_order,
|
61
|
+
angle.to_f,
|
62
|
+
center_x, center_y,
|
63
|
+
x_factor, y_factor,
|
64
|
+
color
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def left_x
|
70
|
+
x - (width * center_x)
|
71
|
+
end
|
72
|
+
|
73
|
+
def right_x
|
74
|
+
left_x + width
|
75
|
+
end
|
76
|
+
|
77
|
+
def top_y
|
78
|
+
y - (height * center_y)
|
79
|
+
end
|
80
|
+
|
81
|
+
def bottom_y
|
82
|
+
top_y + height
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
#
|
5
|
+
# The label will draw the specified text with the font, position, color,
|
6
|
+
# and alignment provided.
|
7
|
+
#
|
8
|
+
# @example Drawing a label
|
9
|
+
#
|
10
|
+
# class TitleScene < GameScene
|
11
|
+
# draw :game_title, model: "metro::ui::label", position: "320,240",
|
12
|
+
# vertical_align: "center", align: "center", color: "rgba(255,255,255,1.0)",
|
13
|
+
# text: "Super Awesome Game\n2"
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
class Label < Model
|
17
|
+
|
18
|
+
# @attribute
|
19
|
+
# The position of the label
|
20
|
+
property :position
|
21
|
+
|
22
|
+
# @attribute
|
23
|
+
# The scale of the text
|
24
|
+
property :scale, default: Scale.one
|
25
|
+
|
26
|
+
# @attribute
|
27
|
+
# The text color
|
28
|
+
property :color, default: "rgba(255,255,255,1.0)"
|
29
|
+
|
30
|
+
# @attribute
|
31
|
+
# The font to use for the label text
|
32
|
+
property :font, default: { size: 20 }
|
33
|
+
|
34
|
+
# @attribute
|
35
|
+
# The text to appear on the label
|
36
|
+
property :text
|
37
|
+
|
38
|
+
# @attribute
|
39
|
+
# The alignment for the label. This influences where the text draws in
|
40
|
+
# relation to the specified position. Your choices are 'left', 'center',
|
41
|
+
# and 'right'. The default is 'left'.
|
42
|
+
property :align, type: :text, default: "left"
|
43
|
+
|
44
|
+
# @attribute
|
45
|
+
# The vertical alignment for the label. This influences where the text
|
46
|
+
# draws in relation to the specified position. Your choices are 'top',
|
47
|
+
# 'center', and 'bottom'. This default is 'top'
|
48
|
+
property :vertical_align, type: :text, default: "top"
|
49
|
+
|
50
|
+
# @attribute
|
51
|
+
# When calculating the dimensions of the label, this is the minimum
|
52
|
+
# dimensions. This is necessary in cases when the text is blank. This
|
53
|
+
# allows for the label to have size when in the edit mode.
|
54
|
+
property :minimum_dimensions, type: :dimensions, default: "16,16"
|
55
|
+
|
56
|
+
# @attribute
|
57
|
+
# The dimensions of label. If the label text is blank, then the dimensions
|
58
|
+
# of the label will return a minimum dimension.
|
59
|
+
property :dimensions do
|
60
|
+
calculated = Dimensions.of (longest_line * x_factor), (line_height * line_count * y_factor)
|
61
|
+
[ calculated, minimum_dimensions ].max
|
62
|
+
end
|
63
|
+
|
64
|
+
def bounds
|
65
|
+
Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
|
66
|
+
end
|
67
|
+
|
68
|
+
def draw
|
69
|
+
parsed_text.each_with_index do |line,index|
|
70
|
+
font.draw line, x_position(index), y_position(index), z_order, x_factor, y_factor, color
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def left_x
|
77
|
+
line_count.times.map { |index| x_position(index) }.min
|
78
|
+
end
|
79
|
+
|
80
|
+
def right_x
|
81
|
+
left_x + width
|
82
|
+
end
|
83
|
+
|
84
|
+
def top_y
|
85
|
+
y_position(0)
|
86
|
+
end
|
87
|
+
|
88
|
+
def bottom_y
|
89
|
+
top_y + height
|
90
|
+
end
|
91
|
+
|
92
|
+
def line_height
|
93
|
+
font.height
|
94
|
+
end
|
95
|
+
|
96
|
+
def line_width(line)
|
97
|
+
font.text_width(line)
|
98
|
+
end
|
99
|
+
|
100
|
+
def half_line_height
|
101
|
+
line_height / 2
|
102
|
+
end
|
103
|
+
|
104
|
+
def longest_line
|
105
|
+
parsed_text.map { |line| line_width(line) }.max || 0
|
106
|
+
end
|
107
|
+
|
108
|
+
def line_count
|
109
|
+
parsed_text.count
|
110
|
+
end
|
111
|
+
|
112
|
+
def parsed_text
|
113
|
+
text.split("\n")
|
114
|
+
end
|
115
|
+
|
116
|
+
def x_left_alignment(index)
|
117
|
+
x
|
118
|
+
end
|
119
|
+
|
120
|
+
def x_center_alignment(index)
|
121
|
+
x - line_width(parsed_text[index]) / 2
|
122
|
+
end
|
123
|
+
|
124
|
+
def x_right_alignment(index)
|
125
|
+
x - line_width(parsed_text[index])
|
126
|
+
end
|
127
|
+
|
128
|
+
def horizontal_alignments
|
129
|
+
{ left: :x_left_alignment,
|
130
|
+
center: :x_center_alignment,
|
131
|
+
right: :x_right_alignment }
|
132
|
+
end
|
133
|
+
|
134
|
+
def x_position(index)
|
135
|
+
alignment = horizontal_alignments[align.to_sym]
|
136
|
+
send(alignment,index)
|
137
|
+
end
|
138
|
+
|
139
|
+
def y_top_alignment(index)
|
140
|
+
y + (index * line_height)
|
141
|
+
end
|
142
|
+
|
143
|
+
def y_bottom_alignment(index)
|
144
|
+
y - line_height * (line_count - index)
|
145
|
+
end
|
146
|
+
|
147
|
+
def y_center_alignment(index)
|
148
|
+
if line_count.even?
|
149
|
+
full_height = (line_count / 2 - index) * line_height
|
150
|
+
else
|
151
|
+
offset = (line_count / 2 - index)
|
152
|
+
if offset < 0
|
153
|
+
full_height = (offset + 1) * line_height - half_line_height
|
154
|
+
else
|
155
|
+
full_height = offset * line_height + half_line_height
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
y - full_height
|
160
|
+
end
|
161
|
+
|
162
|
+
def vertical_alignments
|
163
|
+
{ top: :y_top_alignment,
|
164
|
+
center: :y_center_alignment,
|
165
|
+
bottom: :y_bottom_alignment }
|
166
|
+
end
|
167
|
+
|
168
|
+
def y_position(index)
|
169
|
+
alignment = vertical_alignments[vertical_align.to_sym]
|
170
|
+
send(alignment,index)
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|