Class: Fatty::Renderer
- Inherits:
-
Object
- Object
- Fatty::Renderer
- Defined in:
- lib/fatty/renderer.rb,
lib/fatty/renderer/curses.rb,
lib/fatty/renderer/truecolor.rb
Overview
The Renderer class implements drawing the elements of a Fatty terminal (output, input, alert, status, and popups) on the screen. There are two ways of doing so: (1) using normal curses operations with curses-defined pairs and (2) using ANSI codes to write with a Truecolor full-color palette. This class is the base class for those two rendering methods and provides methods common to them.
Defined Under Namespace
Constant Summary collapse
- FRAME_STYLES =
{ ascii: { h: "-", v: "|" }, single: { h: "─", v: "│" }, double: { h: "═", v: "║" }, }.freeze
- CORNER_STYLES =
{ square: { ascii: { tl: "+", tr: "+", bl: "+", br: "+" }, single: { tl: "┌", tr: "┐", bl: "└", br: "┘" }, double: { tl: "╔", tr: "╗", bl: "╚", br: "╝" }, }, rounded: { single: { tl: "╭", tr: "╮", bl: "╰", br: "╯" }, }, }.freeze
- POPUP_SELECTED_GUTTER =
"▶ "- POPUP_UNSELECTED_GUTTER =
" "
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#palette ⇒ Object
readonly
Returns the value of attribute palette.
-
#screen ⇒ Object
Returns the value of attribute screen.
Instance Method Summary collapse
- #apply_theme!(theme) ⇒ Object
- #flush_ansi_draws ⇒ Object
-
#initialize(screen:, palette:, context:) ⇒ Renderer
constructor
A new instance of Renderer.
- #invalidate! ⇒ Object
- #queue_ansi_line(row:, col:, width:, text:, role: nil) ⇒ Object
- #queue_ansi_popup_line(win:, inner_row:, inner_col: 0, width:, text:, role:) ⇒ Object
- #queue_ansi_rect(row:, col:, width:, height:, role:) ⇒ Object
- #queue_ansi_segments_line(row:, col:, width:, segments:, fill_role: :output) ⇒ Object
- #render_alert ⇒ Object
- #render_input_field ⇒ Object
- #render_output ⇒ Object
- #render_pager_field ⇒ Object
- #render_popup ⇒ Object
- #render_prompt_popup ⇒ Object
- #render_status ⇒ Object
-
#restore_output_cursor(field, row:) ⇒ Object
Restore cursor into the output window at a specific output-win row.
Constructor Details
#initialize(screen:, palette:, context:) ⇒ Renderer
Returns a new instance of Renderer.
42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/fatty/renderer.rb', line 42 def initialize(screen:, palette:, context:) @screen = screen @palette = palette @context = context @last_status_state = nil @last_alert_state = nil @last_output_state = nil @last_popup_state = nil @last_prompt_popup_state = nil @last_pager_field_state = nil end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
40 41 42 |
# File 'lib/fatty/renderer.rb', line 40 def context @context end |
#palette ⇒ Object (readonly)
Returns the value of attribute palette.
40 41 42 |
# File 'lib/fatty/renderer.rb', line 40 def palette @palette end |
#screen ⇒ Object
Returns the value of attribute screen.
40 41 42 |
# File 'lib/fatty/renderer.rb', line 40 def screen @screen end |
Instance Method Details
#apply_theme!(theme) ⇒ Object
56 57 58 59 60 61 62 63 64 |
# File 'lib/fatty/renderer.rb', line 56 def apply_theme!(theme) Fatty::Themes::Manager.set(theme) theme_spec = Fatty::Themes::Manager.roles(Fatty::Themes::Manager.current) || {} @palette = Fatty::Colors::Palette.compile(theme_spec, available_colors: available_colors) after_apply_theme! invalidate! sync_backgrounds! end |
#flush_ansi_draws ⇒ Object
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
# File 'lib/fatty/renderer/truecolor.rb', line 571 def flush_ansi_draws Fatty.debug("flush_ansi_draws pending_count=#{@pending_ansi_draws.length}", tag: :render) # Hide the cursor @ansi_renderer.write_ansi("\e[?25l") @pending_ansi_draws.each do |draw| case draw[:type] when :cursor @ansi_renderer.write_ansi("\e[#{draw[:row] + 1};#{draw[:col] + 1}H") when :segments_line @ansi_renderer.render_segments_line( row: draw[:row], col: draw[:col], width: draw[:width], segments: draw[:segments], palette: palette, fill_role: draw[:fill_role] || :output, ) else @ansi_renderer.render_line( row: draw[:row], col: draw[:col], width: draw[:width], text: draw[:text], role: draw[:role], palette: palette, ) end end @pending_ansi_draws.clear ensure # Unhide the cursor @ansi_renderer.write_ansi("\e[?25h") end |
#invalidate! ⇒ Object
94 95 96 97 98 99 100 101 |
# File 'lib/fatty/renderer.rb', line 94 def invalidate! @last_output_state = nil @last_input_state = nil @last_alert_state = nil @last_status_state = nil @last_pager_field_state = nil @last_popup_state = nil end |
#queue_ansi_line(row:, col:, width:, text:, role: nil) ⇒ Object
544 545 546 547 548 549 550 551 552 553 554 |
# File 'lib/fatty/renderer/truecolor.rb', line 544 def queue_ansi_line(row:, col:, width:, text:, role: nil) spec = palette[role] || {} @pending_ansi_draws << { row: row, col: col, width: width, text: text, role: role, spec: spec, } end |
#queue_ansi_popup_line(win:, inner_row:, inner_col: 0, width:, text:, role:) ⇒ Object
519 520 521 522 523 524 525 526 527 528 529 530 |
# File 'lib/fatty/renderer/truecolor.rb', line 519 def queue_ansi_popup_line(win:, inner_row:, inner_col: 0, width:, text:, role:) row, col = win.origin return unless row && col queue_ansi_line( row: row + 1 + inner_row, col: col + 1 + inner_col, width: width, text: text.to_s, role: role, ) end |
#queue_ansi_rect(row:, col:, width:, height:, role:) ⇒ Object
556 557 558 559 560 561 562 563 564 565 566 567 568 569 |
# File 'lib/fatty/renderer/truecolor.rb', line 556 def queue_ansi_rect(row:, col:, width:, height:, role:) return if height <= 0 || width <= 0 height.times do |i| queue_ansi_line( row: row + i, col: col, width: width, text: " " * width, role: role, ) end nil end |
#queue_ansi_segments_line(row:, col:, width:, segments:, fill_role: :output) ⇒ Object
532 533 534 535 536 537 538 539 540 541 542 |
# File 'lib/fatty/renderer/truecolor.rb', line 532 def queue_ansi_segments_line(row:, col:, width:, segments:, fill_role: :output) @pending_ansi_draws << { type: :segments_line, row: row, col: col, width: width, segments: segments, fill_role: fill_role, } nil end |
#render_alert ⇒ Object
90 91 92 |
# File 'lib/fatty/renderer.rb', line 90 def render_alert(...) raise NotImplementedError, "#{self.class} must implement #render_alert" end |
#render_input_field ⇒ Object
74 75 76 |
# File 'lib/fatty/renderer.rb', line 74 def render_input_field(...) raise NotImplementedError, "#{self.class} must implement #render_input_field" end |
#render_output ⇒ Object
66 67 68 |
# File 'lib/fatty/renderer.rb', line 66 def render_output(...) raise NotImplementedError, "#{self.class} must implement #render_output" end |
#render_pager_field ⇒ Object
78 79 80 |
# File 'lib/fatty/renderer.rb', line 78 def render_pager_field(...) raise NotImplementedError, "#{self.class} must implement #render_pager_field" end |
#render_popup ⇒ Object
82 83 84 |
# File 'lib/fatty/renderer.rb', line 82 def render_popup(...) raise NotImplementedError, "#{self.class} must implement #render_popup" end |
#render_prompt_popup ⇒ Object
86 87 88 |
# File 'lib/fatty/renderer.rb', line 86 def render_prompt_popup(...) raise NotImplementedError, "#{self.class} must implement #render_prompt_popup" end |
#render_status ⇒ Object
70 71 72 |
# File 'lib/fatty/renderer.rb', line 70 def render_status(...) raise NotImplementedError, "#{self.class} must implement #render_status" end |
#restore_output_cursor(field, row:) ⇒ Object
Restore cursor into the output window at a specific output-win row.
row: is 0..(screen.output_rect.rows-1), NOT an absolute screen row.
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# File 'lib/fatty/renderer/truecolor.rb', line 502 def restore_output_cursor(field, row:) cols = @screen.cols x = field.cursor_x.to_i x = x.clamp(0, [cols - 1, 0].max) row0 = @screen.output_rect.row col0 = @screen.output_rect.col cols = @screen.output_rect.cols @pending_ansi_draws << { type: :cursor, row: row0 + row, col: col0 + x.clamp(0, [cols - 1, 0].max), } end |