Module: RSpecTelemetry::Trace::Viewer::Layout

Defined in:
lib/rspec_telemetry/trace/viewer/layout.rb

Overview

Pure geometry shared by rendering and mouse hit-testing.

Defined Under Namespace

Classes: Regions

Constant Summary collapse

MIN_TWO_PANE =
60
GUTTER =
1
MIN_PANE_COLS =
12
MIN_SOURCE_ROWS =
3
MIN_BODY_ROWS =
4

Class Method Summary collapse

Class Method Details

.carve_source(body, source_rows) ⇒ Object



79
80
81
82
83
84
85
86
87
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 79

def self.carve_source(body, source_rows)
  return [nil, body, nil, nil] if body.rows < MIN_BODY_ROWS + MIN_SOURCE_ROWS + 1

  height = source_height(body, source_rows)
  return [nil, body, nil, nil] if height.nil?

  top, source = body.split_h(body.rows - height)
  [body, top, source, source.row]
end

.carve_time_bar(body) ⇒ Object



73
74
75
76
77
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 73

def self.carve_time_bar(body)
  return [nil, body] if body.rows < 2

  body.split_h(1)
end

.compute(size:, want_time_bar:, want_source:, split_ratio:, source_rows:) ⇒ Object

Regions are nil when the terminal is too small or a feature is hidden.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 29

def self.compute(size:, want_time_bar:, want_source:, split_ratio:, source_rows:)
  return single(whole(size)) if size.rows < 2

  body, status = whole(size).split_h(size.rows - 1)
  time, body = carve_time_bar(body) if want_time_bar
  content, body, source, source_top = carve_source(body, source_rows) if want_source
  list, detail, divider = split_panes(body, split_ratio)

  Regions.new(
    time: time,
    body: body,
    list: list,
    detail: detail,
    divider: divider,
    source: source,
    source_top: source_top,
    content: content,
    status: status
  )
end

.single(body) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 59

def self.single(body)
  Regions.new(
    time: nil,
    body: body,
    list: body,
    detail: nil,
    divider: nil,
    source: nil,
    source_top: nil,
    content: nil,
    status: nil
  )
end

.source_height(content, source_rows) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 50

def self.source_height(content, source_rows)
  # Keep both source and main body usable while dragging.
  lo = MIN_SOURCE_ROWS
  hi = content.rows - MIN_BODY_ROWS
  return nil if hi < lo

  source_rows.clamp(lo, hi)
end

.split_panes(body, ratio) ⇒ Object



89
90
91
92
93
94
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 89

def self.split_panes(body, ratio)
  return [body, nil, nil] if body.cols < MIN_TWO_PANE

  left, detail = body.split_ratio(ratio, min: MIN_PANE_COLS, gutter: GUTTER)
  [left, detail, left.col + left.cols]
end

.whole(size) ⇒ Object



96
# File 'lib/rspec_telemetry/trace/viewer/layout.rb', line 96

def self.whole(size) = TuiTui::Rect.new(row: 1, col: 1, rows: size.rows, cols: size.cols)