ruby_jard 0.1.0 → 0.3.0
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/.github/FUNDING.yml +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/documentation.yml +65 -0
- data/.github/workflows/rspec.yml +96 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +90 -2
- data/CHANGELOG.md +112 -0
- data/Gemfile +14 -4
- data/README.md +95 -3
- data/benchmark/path_filter_bench.rb +58 -0
- data/bin/console +1 -2
- data/lib/ruby_jard.rb +68 -32
- data/lib/ruby_jard/box_drawer.rb +175 -0
- data/lib/ruby_jard/color_scheme.rb +28 -0
- data/lib/ruby_jard/color_schemes.rb +54 -0
- data/lib/ruby_jard/color_schemes/256_color_scheme.rb +50 -0
- data/lib/ruby_jard/color_schemes/256_light_color_scheme.rb +50 -0
- data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +49 -0
- data/lib/ruby_jard/color_schemes/gruvbox_color_scheme.rb +48 -0
- data/lib/ruby_jard/color_schemes/one_half_dark_color_scheme.rb +47 -0
- data/lib/ruby_jard/color_schemes/one_half_light_color_scheme.rb +49 -0
- data/lib/ruby_jard/column.rb +26 -0
- data/lib/ruby_jard/commands/color_helpers.rb +32 -0
- data/lib/ruby_jard/commands/continue_command.rb +4 -9
- data/lib/ruby_jard/commands/down_command.rb +9 -8
- data/lib/ruby_jard/commands/exit_command.rb +27 -0
- data/lib/ruby_jard/commands/frame_command.rb +13 -11
- data/lib/ruby_jard/commands/jard/color_scheme_command.rb +74 -0
- data/lib/ruby_jard/commands/jard/filter_command.rb +136 -0
- data/lib/ruby_jard/commands/jard/hide_command.rb +40 -0
- data/lib/ruby_jard/commands/jard/output_command.rb +36 -0
- data/lib/ruby_jard/commands/jard/show_command.rb +41 -0
- data/lib/ruby_jard/commands/jard_command.rb +52 -0
- data/lib/ruby_jard/commands/list_command.rb +31 -0
- data/lib/ruby_jard/commands/next_command.rb +11 -8
- data/lib/ruby_jard/commands/step_command.rb +11 -8
- data/lib/ruby_jard/commands/step_out_command.rb +34 -0
- data/lib/ruby_jard/commands/up_command.rb +10 -8
- data/lib/ruby_jard/commands/validation_helpers.rb +50 -0
- data/lib/ruby_jard/config.rb +61 -0
- data/lib/ruby_jard/console.rb +158 -0
- data/lib/ruby_jard/control_flow.rb +73 -0
- data/lib/ruby_jard/decorators/array_decorator.rb +79 -0
- data/lib/ruby_jard/decorators/attributes_decorator.rb +172 -0
- data/lib/ruby_jard/decorators/color_decorator.rb +80 -0
- data/lib/ruby_jard/decorators/hash_decorator.rb +74 -0
- data/lib/ruby_jard/decorators/inspection_decorator.rb +109 -0
- data/lib/ruby_jard/decorators/loc_decorator.rb +108 -119
- data/lib/ruby_jard/decorators/object_decorator.rb +122 -0
- data/lib/ruby_jard/decorators/path_decorator.rb +56 -60
- data/lib/ruby_jard/decorators/rails_decorator.rb +194 -0
- data/lib/ruby_jard/decorators/source_decorator.rb +3 -1
- data/lib/ruby_jard/decorators/string_decorator.rb +41 -0
- data/lib/ruby_jard/decorators/struct_decorator.rb +79 -0
- data/lib/ruby_jard/frame.rb +68 -0
- data/lib/ruby_jard/key_binding.rb +14 -0
- data/lib/ruby_jard/key_bindings.rb +96 -0
- data/lib/ruby_jard/keys.rb +48 -0
- data/lib/ruby_jard/layout.rb +17 -88
- data/lib/ruby_jard/layout_calculator.rb +168 -0
- data/lib/ruby_jard/layout_picker.rb +34 -0
- data/lib/ruby_jard/layouts.rb +52 -0
- data/lib/ruby_jard/layouts/narrow_horizontal_layout.rb +32 -0
- data/lib/ruby_jard/layouts/narrow_vertical_layout.rb +32 -0
- data/lib/ruby_jard/layouts/tiny_layout.rb +29 -0
- data/lib/ruby_jard/layouts/wide_layout.rb +50 -0
- data/lib/ruby_jard/pager.rb +112 -0
- data/lib/ruby_jard/path_classifier.rb +133 -0
- data/lib/ruby_jard/path_filter.rb +125 -0
- data/lib/ruby_jard/reflection.rb +97 -0
- data/lib/ruby_jard/repl_processor.rb +151 -89
- data/lib/ruby_jard/repl_proxy.rb +337 -0
- data/lib/ruby_jard/row.rb +31 -0
- data/lib/ruby_jard/row_renderer.rb +119 -0
- data/lib/ruby_jard/screen.rb +14 -41
- data/lib/ruby_jard/screen_adjuster.rb +104 -0
- data/lib/ruby_jard/screen_drawer.rb +25 -0
- data/lib/ruby_jard/screen_manager.rb +167 -82
- data/lib/ruby_jard/screen_renderer.rb +152 -0
- data/lib/ruby_jard/screens.rb +31 -12
- data/lib/ruby_jard/screens/backtrace_screen.rb +118 -116
- data/lib/ruby_jard/screens/menu_screen.rb +73 -45
- data/lib/ruby_jard/screens/source_screen.rb +86 -106
- data/lib/ruby_jard/screens/threads_screen.rb +103 -78
- data/lib/ruby_jard/screens/variables_screen.rb +224 -142
- data/lib/ruby_jard/session.rb +151 -16
- data/lib/ruby_jard/span.rb +23 -0
- data/lib/ruby_jard/templates/layout_template.rb +35 -0
- data/lib/ruby_jard/templates/screen_template.rb +34 -0
- data/lib/ruby_jard/thread_info.rb +69 -0
- data/lib/ruby_jard/version.rb +1 -1
- data/ruby_jard.gemspec +7 -8
- metadata +84 -50
- data/.travis.yml +0 -6
- data/lib/ruby_jard/commands/finish_command.rb +0 -31
- data/lib/ruby_jard/decorators/text_decorator.rb +0 -61
- data/lib/ruby_jard/layout_template.rb +0 -101
- data/lib/ruby_jard/screens/breakpoints_screen.rb +0 -23
- data/lib/ruby_jard/screens/empty_screen.rb +0 -13
- data/lib/ruby_jard/screens/expressions_sreen.rb +0 -22
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyJard
|
4
|
+
##
|
5
|
+
# This class is a wrapper for Byebug::Frame. This class prevents direct
|
6
|
+
# access to Byebug's internal data structure, provides some more helpers
|
7
|
+
# and make Jard easier to test.
|
8
|
+
class Frame
|
9
|
+
attr_reader :real_pos
|
10
|
+
attr_writer :visible
|
11
|
+
attr_accessor :virtual_pos
|
12
|
+
|
13
|
+
def initialize(context, real_pos, virtual_pos: nil)
|
14
|
+
@context = context
|
15
|
+
@real_pos = real_pos
|
16
|
+
@virtual_pos = virtual_pos
|
17
|
+
|
18
|
+
@visible = true
|
19
|
+
end
|
20
|
+
|
21
|
+
def visible?
|
22
|
+
@visible == true
|
23
|
+
end
|
24
|
+
|
25
|
+
def hidden?
|
26
|
+
@visible == false
|
27
|
+
end
|
28
|
+
|
29
|
+
def frame_file
|
30
|
+
@context.frame_file(@real_pos)
|
31
|
+
end
|
32
|
+
|
33
|
+
def frame_line
|
34
|
+
@context.frame_line(@real_pos)
|
35
|
+
end
|
36
|
+
|
37
|
+
def frame_location
|
38
|
+
frame_backtrace = @context.backtrace[@real_pos]
|
39
|
+
return nil if frame_backtrace.nil?
|
40
|
+
|
41
|
+
frame_backtrace.first
|
42
|
+
end
|
43
|
+
|
44
|
+
def frame_self
|
45
|
+
@context.frame_self(@real_pos)
|
46
|
+
end
|
47
|
+
|
48
|
+
def frame_class
|
49
|
+
@context.frame_class(@real_pos)
|
50
|
+
end
|
51
|
+
|
52
|
+
def frame_binding
|
53
|
+
@context.frame_binding(@real_pos)
|
54
|
+
end
|
55
|
+
|
56
|
+
def frame_method
|
57
|
+
@context.frame_method(@real_pos)
|
58
|
+
end
|
59
|
+
|
60
|
+
def c_frame?
|
61
|
+
frame_binding.nil?
|
62
|
+
end
|
63
|
+
|
64
|
+
def thread
|
65
|
+
@context.thread
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyJard
|
4
|
+
##
|
5
|
+
# Register custom key bindings and corresponding action, try to
|
6
|
+
# match a key binding sequence from input.
|
7
|
+
# As this class is performant-sensitive, a lookup tree is built
|
8
|
+
# and updated whenever a new key is added.
|
9
|
+
class KeyBindings
|
10
|
+
attr_reader :indexes
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@key_bindings = []
|
14
|
+
@indexes = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_a
|
18
|
+
@key_bindings.dup
|
19
|
+
end
|
20
|
+
|
21
|
+
def push(sequence, action)
|
22
|
+
if sequence.is_a?(Array)
|
23
|
+
sequence.each { |s| push(s, action) }
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
raise RubyJard::Error if sequence.to_s.empty?
|
28
|
+
|
29
|
+
key_binding = RubyJard::KeyBinding.new(sequence, action)
|
30
|
+
reindex(key_binding)
|
31
|
+
@key_bindings << key_binding
|
32
|
+
end
|
33
|
+
|
34
|
+
def match(&read_key)
|
35
|
+
raise RubyJard::Error, 'This method requires a block' unless block_given?
|
36
|
+
|
37
|
+
buffer = ''
|
38
|
+
node = @indexes
|
39
|
+
loop do
|
40
|
+
keys = read_key.call
|
41
|
+
if keys.nil?
|
42
|
+
# No more key. Match the current node
|
43
|
+
if node[nil].nil?
|
44
|
+
return buffer
|
45
|
+
else
|
46
|
+
return node[nil]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
buffer += keys
|
51
|
+
keys.bytes.each do |byte|
|
52
|
+
if node[byte].is_a?(Hash)
|
53
|
+
# Not sure, continue to match
|
54
|
+
node = node[byte]
|
55
|
+
elsif node[byte].nil?
|
56
|
+
# It's sure that no more bindings to match
|
57
|
+
return buffer
|
58
|
+
elsif buffer == node[byte].sequence
|
59
|
+
# Exact match current key binding
|
60
|
+
return node[byte]
|
61
|
+
else
|
62
|
+
return buffer
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def reindex(key_binding)
|
71
|
+
parent = nil
|
72
|
+
node = @indexes
|
73
|
+
bytes = key_binding.sequence.bytes
|
74
|
+
bytes.each do |byte|
|
75
|
+
if node[byte].nil?
|
76
|
+
node[byte] = {}
|
77
|
+
elsif node[byte].is_a?(KeyBinding)
|
78
|
+
return if node[byte].sequence == key_binding.sequence
|
79
|
+
|
80
|
+
# Propagate the tree node
|
81
|
+
node[byte] = {
|
82
|
+
nil => node[byte]
|
83
|
+
}
|
84
|
+
end
|
85
|
+
parent = node
|
86
|
+
node = node[byte]
|
87
|
+
end
|
88
|
+
|
89
|
+
if node.empty?
|
90
|
+
parent[bytes.last] = key_binding
|
91
|
+
else
|
92
|
+
node[nil] = key_binding
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyJard
|
4
|
+
##
|
5
|
+
# A helper class to store pre-defined keys and key bindings
|
6
|
+
class Keys
|
7
|
+
# X-Term: https://invisible-island.net/xterm/xterm-function-keys.html
|
8
|
+
END_LINE = ["\n", "\r\n", "\r"].freeze
|
9
|
+
CTRL_C = "\u0003"
|
10
|
+
CTRL_D = "\u0004"
|
11
|
+
|
12
|
+
F1 = "\eOP"
|
13
|
+
F2 = "\eOQ"
|
14
|
+
F3 = "\eOR"
|
15
|
+
F4 = "\eOS"
|
16
|
+
F5 = "\e[15~"
|
17
|
+
F6 = "\e[17~"
|
18
|
+
F7 = "\e[18~"
|
19
|
+
F8 = "\e[19~"
|
20
|
+
F9 = "\e[20~"
|
21
|
+
F10 = "\e[21~"
|
22
|
+
F11 = "\e[23~"
|
23
|
+
F12 = "\e[24~"
|
24
|
+
|
25
|
+
SHIFT_F1 = "\e1;2P"
|
26
|
+
SHIFT_F2 = "\e1;2Q"
|
27
|
+
SHIFT_F3 = "\e1;2R"
|
28
|
+
SHIFT_F4 = "\e1;2S"
|
29
|
+
SHIFT_F5 = "\e[15;2~"
|
30
|
+
SHIFT_F6 = "\e[17;2~"
|
31
|
+
SHIFT_F7 = "\e[18;2~"
|
32
|
+
SHIFT_F8 = "\e[19;2~"
|
33
|
+
SHIFT_F9 = "\e[20;2~"
|
34
|
+
SHIFT_F10 = "\e[21;2~"
|
35
|
+
SHIFT_F11 = "\e[23;2~"
|
36
|
+
SHIFT_F12 = "\e[24;2~"
|
37
|
+
DEFAULT_KEY_BINDINGS = {
|
38
|
+
F2 => (ACTION_FILTER = :switch_filter),
|
39
|
+
F5 => (ACTION_LIST = :list),
|
40
|
+
F6 => (ACTION_UP = :up),
|
41
|
+
SHIFT_F6 => (ACTION_DOWN = :down),
|
42
|
+
F7 => (ACTION_STEP = :step),
|
43
|
+
SHIFT_F7 => (ACTION_STEP_OUT = :step_out),
|
44
|
+
F8 => (ACTION_NEXT = :next),
|
45
|
+
F9 => (ACTION_CONTINUE = :continue)
|
46
|
+
}.freeze
|
47
|
+
end
|
48
|
+
end
|
data/lib/ruby_jard/layout.rb
CHANGED
@@ -2,98 +2,27 @@
|
|
2
2
|
|
3
3
|
module RubyJard
|
4
4
|
##
|
5
|
-
#
|
6
|
-
# visibility, data size of each children screen.
|
7
|
-
# TODO: Right now, the sizes are fixed regardless of current screen data size.
|
5
|
+
# Data object to store calculated layout
|
8
6
|
class Layout
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
attr_accessor :template, :parent_template,
|
8
|
+
:box_width, :box_height, :box_x, :box_y,
|
9
|
+
:width, :height, :x, :y
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
template: nil, parent_template: nil,
|
13
|
+
width: 0, height: 0, x: 0, y: 0,
|
14
|
+
box_width: 0, box_height: 0, box_x: 0, box_y: 0
|
15
|
+
)
|
18
16
|
@template = template
|
17
|
+
@box_width = box_width
|
18
|
+
@box_height = box_height
|
19
|
+
@box_x = box_x
|
20
|
+
@box_y = box_y
|
19
21
|
@width = width
|
20
22
|
@height = height
|
21
|
-
@
|
22
|
-
@
|
23
|
-
|
24
|
-
|
25
|
-
def generate
|
26
|
-
if @template.screen.nil? && !@template.children.empty?
|
27
|
-
generate_childen
|
28
|
-
else
|
29
|
-
# Ignore children if a layout is a screen
|
30
|
-
@screen = @template.screen
|
31
|
-
end
|
32
|
-
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def generate_childen
|
39
|
-
total_height = 0
|
40
|
-
total_width = 0
|
41
|
-
|
42
|
-
@children = @template.children.map.with_index do |child_template, index|
|
43
|
-
child = RubyJard::Layout.new(
|
44
|
-
template: child_template,
|
45
|
-
height: calculate_child_height(child_template, index, total_height),
|
46
|
-
width: calculate_child_width(child_template, index, total_width)
|
47
|
-
)
|
48
|
-
child.generate
|
49
|
-
|
50
|
-
total_width += child.width
|
51
|
-
total_height += child.height
|
52
|
-
|
53
|
-
child
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def calculate_child_height(child_template, index, total_height)
|
58
|
-
height =
|
59
|
-
if !child_template.height.nil?
|
60
|
-
child_template.height
|
61
|
-
elsif child_template.height_ratio.nil?
|
62
|
-
@height
|
63
|
-
else
|
64
|
-
@height * child_template.height_ratio / 100
|
65
|
-
end
|
66
|
-
|
67
|
-
unless child_template.min_height.nil?
|
68
|
-
height = child_template.min_height if height < child_template.min_height
|
69
|
-
end
|
70
|
-
|
71
|
-
if @template.fill_height && index == @template.children.length - 1
|
72
|
-
height = @height - total_height if height < (@height - total_height)
|
73
|
-
end
|
74
|
-
|
75
|
-
height
|
76
|
-
end
|
77
|
-
|
78
|
-
def calculate_child_width(child_template, index, total_width)
|
79
|
-
width =
|
80
|
-
if !child_template.width.nil?
|
81
|
-
child_template.width
|
82
|
-
elsif child_template.width_ratio.nil?
|
83
|
-
@width
|
84
|
-
else
|
85
|
-
@width * child_template.width_ratio / 100
|
86
|
-
end
|
87
|
-
|
88
|
-
unless child_template.min_width.nil?
|
89
|
-
width = child_template.min_width if width < child_template.min_width
|
90
|
-
end
|
91
|
-
|
92
|
-
if @template.fill_width && index == @template.children.length - 1
|
93
|
-
width = @width - total_width if width < (@width - total_width)
|
94
|
-
end
|
95
|
-
|
96
|
-
width
|
23
|
+
@x = x
|
24
|
+
@y = y
|
25
|
+
@parent_template = parent_template
|
97
26
|
end
|
98
27
|
end
|
99
28
|
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/MethodLength
|
4
|
+
module RubyJard
|
5
|
+
##
|
6
|
+
# Layout calculator based on screen resolution to decide the height, width,
|
7
|
+
# visibility, data size of each children screen.
|
8
|
+
# TODO: Right now, the sizes are fixed regardless of current screen data size.
|
9
|
+
class LayoutCalculator
|
10
|
+
def self.calculate(**args)
|
11
|
+
new(**args).calculate
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(
|
15
|
+
layout_template:, width: 0, height: 0, x: 0, y: 0,
|
16
|
+
config: RubyJard.config
|
17
|
+
)
|
18
|
+
@layout_template = layout_template
|
19
|
+
@width = width
|
20
|
+
@height = height
|
21
|
+
@x = x
|
22
|
+
@y = y
|
23
|
+
@layouts = []
|
24
|
+
@config = config
|
25
|
+
end
|
26
|
+
|
27
|
+
def calculate
|
28
|
+
@layouts = []
|
29
|
+
calculate_layout(@layout_template, @width, @height, @x, @y, nil)
|
30
|
+
@layouts
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def calculate_layout(template, width, height, x, y, parent_template)
|
36
|
+
if template.is_a?(RubyJard::Templates::ScreenTemplate)
|
37
|
+
layout = RubyJard::Layout.new(
|
38
|
+
template: template, parent_template: parent_template,
|
39
|
+
width: width - 2, height: height - 2, x: x + 1, y: y + 1,
|
40
|
+
box_width: width, box_height: height, box_x: x, box_y: y
|
41
|
+
)
|
42
|
+
adjust_layout_overlap(layout)
|
43
|
+
@layouts << layout
|
44
|
+
else
|
45
|
+
overflow_width = 0
|
46
|
+
child_x = x
|
47
|
+
child_y = y
|
48
|
+
max_height = 0
|
49
|
+
|
50
|
+
lines = [[]]
|
51
|
+
visible_children(template).each do |child_template|
|
52
|
+
child_height = calculate_child_height(child_template, height)
|
53
|
+
child_width = calculate_child_width(child_template, width)
|
54
|
+
|
55
|
+
overflow_width += child_width
|
56
|
+
# Overflow. Break to next line
|
57
|
+
if overflow_width > width
|
58
|
+
child_y += max_height
|
59
|
+
child_x = x
|
60
|
+
overflow_width = 0
|
61
|
+
max_height = child_height
|
62
|
+
lines << []
|
63
|
+
elsif max_height < child_height
|
64
|
+
max_height = child_height
|
65
|
+
end
|
66
|
+
|
67
|
+
lines.last << [child_template, child_width, child_height, child_x, child_y]
|
68
|
+
child_x += child_width
|
69
|
+
end
|
70
|
+
|
71
|
+
stretch_children_layouts(template, width, height, lines)
|
72
|
+
lines.each do |line|
|
73
|
+
line.each do |child_template, child_width, child_height, xx, yy|
|
74
|
+
calculate_layout(child_template, child_width, child_height, xx, yy, template)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def visible_children(template)
|
81
|
+
template.children.select do |child|
|
82
|
+
visible?(child)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def visible?(template)
|
87
|
+
if template.is_a?(RubyJard::Templates::ScreenTemplate)
|
88
|
+
@config.enabled_screens.include?(template.screen.to_s.strip)
|
89
|
+
else
|
90
|
+
template.children.any? { |child| visible?(child) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def adjust_layout_overlap(layout)
|
95
|
+
if layout.box_x != 0
|
96
|
+
layout.width += 1
|
97
|
+
layout.x -= 1
|
98
|
+
layout.box_width += 1
|
99
|
+
layout.box_x -= 1
|
100
|
+
end
|
101
|
+
|
102
|
+
if layout.box_y != 0
|
103
|
+
layout.height += 1
|
104
|
+
layout.y -= 1
|
105
|
+
layout.box_height += 1
|
106
|
+
layout.box_y -= 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Stretch the children layouts to fill the gaps, remove redundant spaces inside the parent layout
|
111
|
+
def stretch_children_layouts(parent_template, parent_width, parent_height, lines)
|
112
|
+
total_height = 0
|
113
|
+
lines.each_with_index do |line, line_index|
|
114
|
+
desired_height =
|
115
|
+
if line_index == lines.length - 1
|
116
|
+
parent_height - total_height
|
117
|
+
else
|
118
|
+
line.map { |_child_template, _child_width, child_height, _x, _y| child_height }.max
|
119
|
+
end
|
120
|
+
|
121
|
+
total_width = 0
|
122
|
+
line.map!.with_index do |(child_template, child_width, child_height, x, y), index|
|
123
|
+
child_height = desired_height if parent_template.fill_height
|
124
|
+
child_width = parent_width - total_width if parent_template.fill_width && index == line.length - 1
|
125
|
+
total_width += child_width
|
126
|
+
[child_template, child_width, child_height, x, y]
|
127
|
+
end
|
128
|
+
total_height += desired_height
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def calculate_child_height(child_template, parent_height)
|
133
|
+
height =
|
134
|
+
if !child_template.height.nil?
|
135
|
+
child_template.height
|
136
|
+
elsif child_template.height_ratio.nil?
|
137
|
+
parent_height
|
138
|
+
else
|
139
|
+
parent_height * child_template.height_ratio / 100
|
140
|
+
end
|
141
|
+
|
142
|
+
unless child_template.min_height.nil?
|
143
|
+
height = child_template.min_height if height < child_template.min_height
|
144
|
+
end
|
145
|
+
|
146
|
+
height
|
147
|
+
end
|
148
|
+
|
149
|
+
def calculate_child_width(child_template, parent_width)
|
150
|
+
width =
|
151
|
+
if !child_template.width.nil?
|
152
|
+
child_template.width
|
153
|
+
elsif child_template.width_ratio.nil?
|
154
|
+
parent_width
|
155
|
+
else
|
156
|
+
parent_width * child_template.width_ratio / 100
|
157
|
+
end
|
158
|
+
|
159
|
+
unless child_template.min_width.nil?
|
160
|
+
width = child_template.min_width if width < child_template.min_width
|
161
|
+
end
|
162
|
+
|
163
|
+
width
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# rubocop:enable Metrics/MethodLength
|