cyberarm_engine 0.24.3 → 0.24.5
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.
- checksums.yaml +4 -4
- data/.gitignore +8 -8
- data/.rubocop.yml +7 -7
- data/.travis.yml +5 -5
- data/Gemfile +6 -6
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +21 -21
- data/README.md +74 -74
- data/Rakefile +10 -10
- data/assets/shaders/fragment/g_buffer.glsl +30 -30
- data/assets/shaders/fragment/lighting.glsl +115 -69
- data/assets/shaders/include/light_struct.glsl +11 -11
- data/assets/shaders/include/material_struct.glsl +16 -16
- data/assets/shaders/vertex/g_buffer.glsl +28 -28
- data/assets/shaders/vertex/lighting.glsl +24 -24
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/cyberarm_engine.gemspec +36 -36
- data/lib/cyberarm_engine/animator.rb +219 -219
- data/lib/cyberarm_engine/background.rb +180 -179
- data/lib/cyberarm_engine/background_image.rb +93 -93
- data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
- data/lib/cyberarm_engine/bounding_box.rb +150 -150
- data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
- data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
- data/lib/cyberarm_engine/cache.rb +4 -4
- data/lib/cyberarm_engine/common.rb +128 -128
- data/lib/cyberarm_engine/config_file.rb +46 -46
- data/lib/cyberarm_engine/console/command.rb +157 -157
- data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
- data/lib/cyberarm_engine/console/subcommand.rb +99 -99
- data/lib/cyberarm_engine/console.rb +248 -248
- data/lib/cyberarm_engine/game_object.rb +244 -244
- data/lib/cyberarm_engine/game_state.rb +124 -124
- data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +97 -97
- data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
- data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
- data/lib/cyberarm_engine/model/material.rb +21 -21
- data/lib/cyberarm_engine/model/{model_object.rb → mesh.rb} +131 -131
- data/lib/cyberarm_engine/model/parser.rb +74 -74
- data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
- data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
- data/lib/cyberarm_engine/model.rb +216 -213
- data/lib/cyberarm_engine/model_cache.rb +31 -31
- data/lib/cyberarm_engine/notification.rb +82 -82
- data/lib/cyberarm_engine/notification_manager.rb +241 -241
- data/lib/cyberarm_engine/opengl/light.rb +52 -50
- data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
- data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -38
- data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
- data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -165
- data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -304
- data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
- data/lib/cyberarm_engine/opengl/shader.rb +408 -406
- data/lib/cyberarm_engine/opengl/texture.rb +69 -69
- data/lib/cyberarm_engine/opengl.rb +53 -40
- data/lib/cyberarm_engine/ray.rb +56 -56
- data/lib/cyberarm_engine/stats.rb +200 -200
- data/lib/cyberarm_engine/text.rb +260 -260
- data/lib/cyberarm_engine/timer.rb +23 -23
- data/lib/cyberarm_engine/transform.rb +296 -296
- data/lib/cyberarm_engine/trees/aabb_node.rb +126 -0
- data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -0
- data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -0
- data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
- data/lib/cyberarm_engine/ui/dsl.rb +142 -142
- data/lib/cyberarm_engine/ui/element.rb +662 -662
- data/lib/cyberarm_engine/ui/elements/button.rb +100 -100
- data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
- data/lib/cyberarm_engine/ui/elements/container.rb +404 -410
- data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
- data/lib/cyberarm_engine/ui/elements/edit_line.rb +297 -297
- data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
- data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
- data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
- data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
- data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
- data/lib/cyberarm_engine/ui/elements/progress.rb +93 -93
- data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
- data/lib/cyberarm_engine/ui/elements/slider.rb +107 -107
- data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
- data/lib/cyberarm_engine/ui/elements/text_block.rb +216 -216
- data/lib/cyberarm_engine/ui/elements/toggle_button.rb +67 -67
- data/lib/cyberarm_engine/ui/event.rb +54 -54
- data/lib/cyberarm_engine/ui/gui_state.rb +321 -321
- data/lib/cyberarm_engine/ui/style.rb +50 -50
- data/lib/cyberarm_engine/ui/theme.rb +225 -225
- data/lib/cyberarm_engine/vector.rb +312 -312
- data/lib/cyberarm_engine/version.rb +4 -4
- data/lib/cyberarm_engine/window.rb +195 -195
- data/lib/cyberarm_engine.rb +70 -78
- data/mrbgem.rake +29 -29
- metadata +8 -7
@@ -1,107 +1,107 @@
|
|
1
|
-
module CyberarmEngine
|
2
|
-
class Element
|
3
|
-
class Slider < Container
|
4
|
-
class Handle < Button
|
5
|
-
def initialize(*args)
|
6
|
-
super(*args)
|
7
|
-
|
8
|
-
event(:begin_drag)
|
9
|
-
event(:drag_update)
|
10
|
-
event(:end_drag)
|
11
|
-
|
12
|
-
subscribe :begin_drag do |_sender, x, y, _button|
|
13
|
-
@drag_start_pos = Vector.new(x, y)
|
14
|
-
|
15
|
-
:handled
|
16
|
-
end
|
17
|
-
|
18
|
-
subscribe :drag_update do |_sender, x, y, _button|
|
19
|
-
@parent.handle_dragged_to(x, y)
|
20
|
-
|
21
|
-
:handled
|
22
|
-
end
|
23
|
-
|
24
|
-
subscribe :end_drag do
|
25
|
-
@drag_start_pos = nil
|
26
|
-
|
27
|
-
:handled
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def draggable?(button)
|
32
|
-
button == :left
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
attr_reader :value
|
37
|
-
attr_accessor :range, :step_size
|
38
|
-
|
39
|
-
def initialize(options = {}, block = nil)
|
40
|
-
super(options, block)
|
41
|
-
|
42
|
-
@range = @options[:range] || (0.0..1.0)
|
43
|
-
@step_size = @options[:step] || 0.1
|
44
|
-
@value = @options[:value] || (@range.first + @range.last) / 2
|
45
|
-
|
46
|
-
@handle = Handle.new("", parent: self, theme: options[:theme], width: 8, height: 1.0) { close }
|
47
|
-
add(@handle)
|
48
|
-
end
|
49
|
-
|
50
|
-
def recalculate
|
51
|
-
_width = dimensional_size(@style.width, :width)
|
52
|
-
_height = dimensional_size(@style.height, :height)
|
53
|
-
|
54
|
-
@width = _width
|
55
|
-
@height = _height
|
56
|
-
|
57
|
-
position_handle
|
58
|
-
@handle.recalculate
|
59
|
-
@handle.update_background
|
60
|
-
|
61
|
-
update_background
|
62
|
-
end
|
63
|
-
|
64
|
-
def position_handle
|
65
|
-
@handle.x = @x + @handle.style.margin_left + @style.padding_left + @style.border_thickness_left +
|
66
|
-
((content_width - @handle.outer_width) * (@value - @range.min) / (@range.max - @range.min).to_f)
|
67
|
-
|
68
|
-
@handle.y = @y + @handle.style.margin_top + @style.border_thickness_top + @style.padding_top
|
69
|
-
end
|
70
|
-
|
71
|
-
def draw
|
72
|
-
super
|
73
|
-
|
74
|
-
@handle.draw
|
75
|
-
end
|
76
|
-
|
77
|
-
def update
|
78
|
-
super
|
79
|
-
|
80
|
-
@tip = format("%.2f", value.to_f)
|
81
|
-
@handle.tip = @tip
|
82
|
-
end
|
83
|
-
|
84
|
-
def holding_left_mouse_button(_sender, x, y)
|
85
|
-
handle_dragged_to(x, y)
|
86
|
-
|
87
|
-
:handled
|
88
|
-
end
|
89
|
-
|
90
|
-
def handle_dragged_to(x, _y)
|
91
|
-
@ratio = ((x - @handle.width / 2.0) - @x) / (content_width - @handle.outer_width.to_f)
|
92
|
-
|
93
|
-
self.value = @ratio.clamp(0.0, 1.0) * (@range.max - @range.min) + @range.min
|
94
|
-
end
|
95
|
-
|
96
|
-
def value=(n)
|
97
|
-
@value = n
|
98
|
-
position_handle
|
99
|
-
@handle.recalculate
|
100
|
-
|
101
|
-
root.gui_state.request_repaint
|
102
|
-
|
103
|
-
publish(:changed, @value)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
1
|
+
module CyberarmEngine
|
2
|
+
class Element
|
3
|
+
class Slider < Container
|
4
|
+
class Handle < Button
|
5
|
+
def initialize(*args)
|
6
|
+
super(*args)
|
7
|
+
|
8
|
+
event(:begin_drag)
|
9
|
+
event(:drag_update)
|
10
|
+
event(:end_drag)
|
11
|
+
|
12
|
+
subscribe :begin_drag do |_sender, x, y, _button|
|
13
|
+
@drag_start_pos = Vector.new(x, y)
|
14
|
+
|
15
|
+
:handled
|
16
|
+
end
|
17
|
+
|
18
|
+
subscribe :drag_update do |_sender, x, y, _button|
|
19
|
+
@parent.handle_dragged_to(x, y)
|
20
|
+
|
21
|
+
:handled
|
22
|
+
end
|
23
|
+
|
24
|
+
subscribe :end_drag do
|
25
|
+
@drag_start_pos = nil
|
26
|
+
|
27
|
+
:handled
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def draggable?(button)
|
32
|
+
button == :left
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :value
|
37
|
+
attr_accessor :range, :step_size
|
38
|
+
|
39
|
+
def initialize(options = {}, block = nil)
|
40
|
+
super(options, block)
|
41
|
+
|
42
|
+
@range = @options[:range] || (0.0..1.0)
|
43
|
+
@step_size = @options[:step] || 0.1
|
44
|
+
@value = @options[:value] || (@range.first + @range.last) / 2
|
45
|
+
|
46
|
+
@handle = Handle.new("", parent: self, theme: options[:theme], width: 8, height: 1.0) { close }
|
47
|
+
add(@handle)
|
48
|
+
end
|
49
|
+
|
50
|
+
def recalculate
|
51
|
+
_width = dimensional_size(@style.width, :width)
|
52
|
+
_height = dimensional_size(@style.height, :height)
|
53
|
+
|
54
|
+
@width = _width
|
55
|
+
@height = _height
|
56
|
+
|
57
|
+
position_handle
|
58
|
+
@handle.recalculate
|
59
|
+
@handle.update_background
|
60
|
+
|
61
|
+
update_background
|
62
|
+
end
|
63
|
+
|
64
|
+
def position_handle
|
65
|
+
@handle.x = @x + @handle.style.margin_left + @style.padding_left + @style.border_thickness_left +
|
66
|
+
((content_width - @handle.outer_width) * (@value - @range.min) / (@range.max - @range.min).to_f)
|
67
|
+
|
68
|
+
@handle.y = @y + @handle.style.margin_top + @style.border_thickness_top + @style.padding_top
|
69
|
+
end
|
70
|
+
|
71
|
+
def draw
|
72
|
+
super
|
73
|
+
|
74
|
+
@handle.draw
|
75
|
+
end
|
76
|
+
|
77
|
+
def update
|
78
|
+
super
|
79
|
+
|
80
|
+
@tip = format("%.2f", value.to_f)
|
81
|
+
@handle.tip = @tip
|
82
|
+
end
|
83
|
+
|
84
|
+
def holding_left_mouse_button(_sender, x, y)
|
85
|
+
handle_dragged_to(x, y)
|
86
|
+
|
87
|
+
:handled
|
88
|
+
end
|
89
|
+
|
90
|
+
def handle_dragged_to(x, _y)
|
91
|
+
@ratio = ((x - @handle.width / 2.0) - @x) / (content_width - @handle.outer_width.to_f)
|
92
|
+
|
93
|
+
self.value = @ratio.clamp(0.0, 1.0) * (@range.max - @range.min) + @range.min
|
94
|
+
end
|
95
|
+
|
96
|
+
def value=(n)
|
97
|
+
@value = n
|
98
|
+
position_handle
|
99
|
+
@handle.recalculate
|
100
|
+
|
101
|
+
root.gui_state.request_repaint
|
102
|
+
|
103
|
+
publish(:changed, @value)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
module CyberarmEngine
|
2
|
-
class Element
|
3
|
-
class Stack < Container
|
4
|
-
def layout
|
5
|
-
@children.each do |child|
|
6
|
-
move_to_next_line(child)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
1
|
+
module CyberarmEngine
|
2
|
+
class Element
|
3
|
+
class Stack < Container
|
4
|
+
def layout
|
5
|
+
@children.each do |child|
|
6
|
+
move_to_next_line(child)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -1,216 +1,216 @@
|
|
1
|
-
module CyberarmEngine
|
2
|
-
class Element
|
3
|
-
class TextBlock < Element
|
4
|
-
def initialize(text, options = {}, block = nil)
|
5
|
-
super(options, block)
|
6
|
-
|
7
|
-
@text = Text.new(
|
8
|
-
text, font: @options[:font], z: @z, color: @options[:color],
|
9
|
-
size: @options[:text_size], shadow: @options[:text_shadow],
|
10
|
-
static: @options[:text_static],
|
11
|
-
shadow_size: @options[:text_shadow_size],
|
12
|
-
shadow_color: @options[:text_shadow_color],
|
13
|
-
border: @options[:text_border],
|
14
|
-
border_size: @options[:text_border_size],
|
15
|
-
border_color: @options[:text_border_color]
|
16
|
-
)
|
17
|
-
|
18
|
-
@raw_text = text
|
19
|
-
end
|
20
|
-
|
21
|
-
def update
|
22
|
-
super
|
23
|
-
|
24
|
-
if @text.textobject.name != safe_style_fetch(:font)
|
25
|
-
set_font
|
26
|
-
root.gui_state.request_recalculate
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def render
|
31
|
-
# Gosu.clip_to is too expensive to always use so check if we actually need it.
|
32
|
-
if @text.width > width || @text.height > height
|
33
|
-
Gosu.clip_to(@x, @y, width, height) do
|
34
|
-
@text.draw
|
35
|
-
end
|
36
|
-
else
|
37
|
-
@text.draw
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def layout
|
42
|
-
unless @enabled
|
43
|
-
@text.color = @style.disabled[:color]
|
44
|
-
else
|
45
|
-
@text.color = @style.color
|
46
|
-
end
|
47
|
-
|
48
|
-
@width = 0
|
49
|
-
@height = 0
|
50
|
-
|
51
|
-
_width = dimensional_size(@style.width, :width)
|
52
|
-
_height = dimensional_size(@style.height, :height)
|
53
|
-
|
54
|
-
handle_text_wrapping(_width)
|
55
|
-
|
56
|
-
@width = _width || @text.width.floor
|
57
|
-
@height = _height || @text.height.floor
|
58
|
-
|
59
|
-
@text.y = @style.border_thickness_top + @style.padding_top + @y
|
60
|
-
@text.z = @z + 3
|
61
|
-
|
62
|
-
if (text_alignment = @options[:text_align] || @options[:text_h_align])
|
63
|
-
case text_alignment
|
64
|
-
when :left
|
65
|
-
@text.x = @style.border_thickness_left + @style.padding_left + @x
|
66
|
-
when :center
|
67
|
-
@text.x = if @text.width <= width
|
68
|
-
@x + width / 2 - @text.width / 2
|
69
|
-
else # Act as left aligned
|
70
|
-
@style.border_thickness_left + @style.padding_left + @x
|
71
|
-
end
|
72
|
-
when :right
|
73
|
-
@text.x = @x + outer_width - (@text.width + @style.border_thickness_right + @style.padding_right)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
if (vertical_alignment = @options[:text_v_align])
|
78
|
-
case vertical_alignment
|
79
|
-
when :center
|
80
|
-
@text.y = if @text.height <= height
|
81
|
-
@y + height / 2 - @text.height / 2
|
82
|
-
else
|
83
|
-
@style.border_thickness_top + @style.padding_top + @y
|
84
|
-
end
|
85
|
-
when :bottom
|
86
|
-
@text.y = @y + outer_height - (@text.height + @style.border_thickness_bottom + @style.padding_bottom)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
update_background
|
91
|
-
end
|
92
|
-
|
93
|
-
def handle_text_wrapping(max_width)
|
94
|
-
max_width ||= @parent&.content_width
|
95
|
-
max_width ||= @x - (window.width + noncontent_width)
|
96
|
-
wrap_behavior = style.text_wrap
|
97
|
-
copy = @raw_text.to_s.dup
|
98
|
-
|
99
|
-
# Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
|
100
|
-
if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
|
101
|
-
breaks = [] # list of indexes to insert a line break
|
102
|
-
line_start = 0
|
103
|
-
line_end = copy.length
|
104
|
-
|
105
|
-
stalled = false
|
106
|
-
stalled_interations = 0
|
107
|
-
max_stalled_iterations = 10
|
108
|
-
checked_copy_length = line_width(copy[line_start..line_end])
|
109
|
-
|
110
|
-
# find length of lines
|
111
|
-
while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
|
112
|
-
search_start = line_start
|
113
|
-
search_end = line_end
|
114
|
-
|
115
|
-
# Perform a binary search to find length of line
|
116
|
-
while search_start < search_end
|
117
|
-
midpoint = ((search_start.to_f + search_end) / 2.0).floor
|
118
|
-
|
119
|
-
if line_width(copy[line_start..midpoint]) > max_width
|
120
|
-
search_end = midpoint
|
121
|
-
else
|
122
|
-
search_start = midpoint + 1
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
if wrap_behavior == :word_wrap
|
127
|
-
word_search_end = search_end
|
128
|
-
failed = false
|
129
|
-
|
130
|
-
until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
|
131
|
-
word_search_end -= 1
|
132
|
-
|
133
|
-
if word_search_end <= 1 || word_search_end < line_start
|
134
|
-
failed = true
|
135
|
-
break
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
|
140
|
-
else
|
141
|
-
line_start = search_end
|
142
|
-
end
|
143
|
-
|
144
|
-
breaks << line_start
|
145
|
-
|
146
|
-
# Prevent locking up due to outer while loop text width < max_width check not being satisfied.
|
147
|
-
stalled = checked_copy_length == line_width(copy[line_start..line_end])
|
148
|
-
checked_copy_length = line_width(copy[line_start..line_end])
|
149
|
-
|
150
|
-
stalled_interations += 1 if stalled
|
151
|
-
stalled_interations = 0 unless stalled
|
152
|
-
end
|
153
|
-
|
154
|
-
breaks.each_with_index do |pos, index|
|
155
|
-
copy.insert(pos + index, "\n") if pos + index >= 0 && pos + index < copy.length
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
@text.text = copy
|
160
|
-
end
|
161
|
-
|
162
|
-
def line_width(text)
|
163
|
-
(@text.textobject.markup_width(text.to_s) + noncontent_width)
|
164
|
-
end
|
165
|
-
|
166
|
-
def value
|
167
|
-
@raw_text
|
168
|
-
end
|
169
|
-
|
170
|
-
def value=(value)
|
171
|
-
old_value = @raw_text
|
172
|
-
@raw_text = value.to_s.chomp
|
173
|
-
|
174
|
-
old_width = width
|
175
|
-
old_height = height
|
176
|
-
|
177
|
-
if old_width != width || old_height != height
|
178
|
-
root.gui_state.request_recalculate
|
179
|
-
else
|
180
|
-
recalculate
|
181
|
-
end
|
182
|
-
|
183
|
-
root.gui_state.request_repaint if old_value != @raw_text
|
184
|
-
|
185
|
-
publish(:changed, self.value)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
class Banner < TextBlock
|
190
|
-
end
|
191
|
-
|
192
|
-
class Title < TextBlock
|
193
|
-
end
|
194
|
-
|
195
|
-
class Subtitle < TextBlock
|
196
|
-
end
|
197
|
-
|
198
|
-
class Tagline < TextBlock
|
199
|
-
end
|
200
|
-
|
201
|
-
class Caption < TextBlock
|
202
|
-
end
|
203
|
-
|
204
|
-
class Para < TextBlock
|
205
|
-
end
|
206
|
-
|
207
|
-
class Inscription < TextBlock
|
208
|
-
end
|
209
|
-
|
210
|
-
class ToolTip < TextBlock
|
211
|
-
end
|
212
|
-
|
213
|
-
class Link < TextBlock
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
1
|
+
module CyberarmEngine
|
2
|
+
class Element
|
3
|
+
class TextBlock < Element
|
4
|
+
def initialize(text, options = {}, block = nil)
|
5
|
+
super(options, block)
|
6
|
+
|
7
|
+
@text = Text.new(
|
8
|
+
text, font: @options[:font], z: @z, color: @options[:color],
|
9
|
+
size: @options[:text_size], shadow: @options[:text_shadow],
|
10
|
+
static: @options[:text_static],
|
11
|
+
shadow_size: @options[:text_shadow_size],
|
12
|
+
shadow_color: @options[:text_shadow_color],
|
13
|
+
border: @options[:text_border],
|
14
|
+
border_size: @options[:text_border_size],
|
15
|
+
border_color: @options[:text_border_color]
|
16
|
+
)
|
17
|
+
|
18
|
+
@raw_text = text
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
super
|
23
|
+
|
24
|
+
if @text.textobject.name != safe_style_fetch(:font)
|
25
|
+
set_font
|
26
|
+
root.gui_state.request_recalculate
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def render
|
31
|
+
# Gosu.clip_to is too expensive to always use so check if we actually need it.
|
32
|
+
if @text.width > width || @text.height > height
|
33
|
+
Gosu.clip_to(@x, @y, width, height) do
|
34
|
+
@text.draw
|
35
|
+
end
|
36
|
+
else
|
37
|
+
@text.draw
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def layout
|
42
|
+
unless @enabled
|
43
|
+
@text.color = @style.disabled[:color]
|
44
|
+
else
|
45
|
+
@text.color = @style.color
|
46
|
+
end
|
47
|
+
|
48
|
+
@width = 0
|
49
|
+
@height = 0
|
50
|
+
|
51
|
+
_width = dimensional_size(@style.width, :width)
|
52
|
+
_height = dimensional_size(@style.height, :height)
|
53
|
+
|
54
|
+
handle_text_wrapping(_width)
|
55
|
+
|
56
|
+
@width = _width || @text.width.floor
|
57
|
+
@height = _height || @text.height.floor
|
58
|
+
|
59
|
+
@text.y = @style.border_thickness_top + @style.padding_top + @y
|
60
|
+
@text.z = @z + 3
|
61
|
+
|
62
|
+
if (text_alignment = @options[:text_align] || @options[:text_h_align])
|
63
|
+
case text_alignment
|
64
|
+
when :left
|
65
|
+
@text.x = @style.border_thickness_left + @style.padding_left + @x
|
66
|
+
when :center
|
67
|
+
@text.x = if @text.width <= width
|
68
|
+
@x + width / 2 - @text.width / 2
|
69
|
+
else # Act as left aligned
|
70
|
+
@style.border_thickness_left + @style.padding_left + @x
|
71
|
+
end
|
72
|
+
when :right
|
73
|
+
@text.x = @x + outer_width - (@text.width + @style.border_thickness_right + @style.padding_right)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if (vertical_alignment = @options[:text_v_align])
|
78
|
+
case vertical_alignment
|
79
|
+
when :center
|
80
|
+
@text.y = if @text.height <= height
|
81
|
+
@y + height / 2 - @text.height / 2
|
82
|
+
else
|
83
|
+
@style.border_thickness_top + @style.padding_top + @y
|
84
|
+
end
|
85
|
+
when :bottom
|
86
|
+
@text.y = @y + outer_height - (@text.height + @style.border_thickness_bottom + @style.padding_bottom)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
update_background
|
91
|
+
end
|
92
|
+
|
93
|
+
def handle_text_wrapping(max_width)
|
94
|
+
max_width ||= @parent&.content_width
|
95
|
+
max_width ||= @x - (window.width + noncontent_width)
|
96
|
+
wrap_behavior = style.text_wrap
|
97
|
+
copy = @raw_text.to_s.dup
|
98
|
+
|
99
|
+
# Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
|
100
|
+
if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
|
101
|
+
breaks = [] # list of indexes to insert a line break
|
102
|
+
line_start = 0
|
103
|
+
line_end = copy.length
|
104
|
+
|
105
|
+
stalled = false
|
106
|
+
stalled_interations = 0
|
107
|
+
max_stalled_iterations = 10
|
108
|
+
checked_copy_length = line_width(copy[line_start..line_end])
|
109
|
+
|
110
|
+
# find length of lines
|
111
|
+
while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
|
112
|
+
search_start = line_start
|
113
|
+
search_end = line_end
|
114
|
+
|
115
|
+
# Perform a binary search to find length of line
|
116
|
+
while search_start < search_end
|
117
|
+
midpoint = ((search_start.to_f + search_end) / 2.0).floor
|
118
|
+
|
119
|
+
if line_width(copy[line_start..midpoint]) > max_width
|
120
|
+
search_end = midpoint
|
121
|
+
else
|
122
|
+
search_start = midpoint + 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
if wrap_behavior == :word_wrap
|
127
|
+
word_search_end = search_end
|
128
|
+
failed = false
|
129
|
+
|
130
|
+
until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
|
131
|
+
word_search_end -= 1
|
132
|
+
|
133
|
+
if word_search_end <= 1 || word_search_end < line_start
|
134
|
+
failed = true
|
135
|
+
break
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
|
140
|
+
else
|
141
|
+
line_start = search_end
|
142
|
+
end
|
143
|
+
|
144
|
+
breaks << line_start
|
145
|
+
|
146
|
+
# Prevent locking up due to outer while loop text width < max_width check not being satisfied.
|
147
|
+
stalled = checked_copy_length == line_width(copy[line_start..line_end])
|
148
|
+
checked_copy_length = line_width(copy[line_start..line_end])
|
149
|
+
|
150
|
+
stalled_interations += 1 if stalled
|
151
|
+
stalled_interations = 0 unless stalled
|
152
|
+
end
|
153
|
+
|
154
|
+
breaks.each_with_index do |pos, index|
|
155
|
+
copy.insert(pos + index, "\n") if pos + index >= 0 && pos + index < copy.length
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
@text.text = copy
|
160
|
+
end
|
161
|
+
|
162
|
+
def line_width(text)
|
163
|
+
(@text.textobject.markup_width(text.to_s) + noncontent_width)
|
164
|
+
end
|
165
|
+
|
166
|
+
def value
|
167
|
+
@raw_text
|
168
|
+
end
|
169
|
+
|
170
|
+
def value=(value)
|
171
|
+
old_value = @raw_text
|
172
|
+
@raw_text = value.to_s.chomp
|
173
|
+
|
174
|
+
old_width = width
|
175
|
+
old_height = height
|
176
|
+
|
177
|
+
if old_width != width || old_height != height
|
178
|
+
root.gui_state.request_recalculate
|
179
|
+
else
|
180
|
+
recalculate
|
181
|
+
end
|
182
|
+
|
183
|
+
root.gui_state.request_repaint if old_value != @raw_text
|
184
|
+
|
185
|
+
publish(:changed, self.value)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class Banner < TextBlock
|
190
|
+
end
|
191
|
+
|
192
|
+
class Title < TextBlock
|
193
|
+
end
|
194
|
+
|
195
|
+
class Subtitle < TextBlock
|
196
|
+
end
|
197
|
+
|
198
|
+
class Tagline < TextBlock
|
199
|
+
end
|
200
|
+
|
201
|
+
class Caption < TextBlock
|
202
|
+
end
|
203
|
+
|
204
|
+
class Para < TextBlock
|
205
|
+
end
|
206
|
+
|
207
|
+
class Inscription < TextBlock
|
208
|
+
end
|
209
|
+
|
210
|
+
class ToolTip < TextBlock
|
211
|
+
end
|
212
|
+
|
213
|
+
class Link < TextBlock
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|