Class: Charming::Presentation::Components::Viewport
- Inherits:
-
Charming::Presentation::Component
- Object
- View
- Charming::Presentation::Component
- Charming::Presentation::Components::Viewport
- Includes:
- KeyboardHandler
- Defined in:
- lib/charming/presentation/components/viewport.rb
Overview
Viewport is a scrollable region over multi-line content. Supports keyboard scrolling (up/down/left/right, page up/down, home/end) and mouse interactions (scroll wheel and click-to-position). Lines are clipped with ANSI awareness via ‘UI::ANSISlicer` so styled text is preserved across horizontal scrolls. When `wrap:` is true, long lines are wrapped to the configured width before scrolling.
Constant Summary collapse
- ANSI_PATTERN =
Matches an ANSI SGR escape sequence (e.g., “e[31m” for red foreground).
/\e\[[0-9;]*m/- KEY_ACTIONS =
Maps scroll keys to the instance methods that perform them via KeyboardHandler.
{ up: :scroll_up, down: :scroll_down, page_up: :page_up, page_down: :page_down, home: :scroll_home, end: :scroll_end, left: :scroll_left, right: :scroll_right }.freeze
Constants included from KeyboardHandler
Instance Attribute Summary collapse
-
#column ⇒ Object
readonly
The current top-visible row and left-visible column, respectively.
-
#offset ⇒ Object
readonly
The current top-visible row and left-visible column, respectively.
Instance Method Summary collapse
-
#handle_mouse(event) ⇒ Object
Handles mouse events: scroll wheel adjusts the row offset, click moves the top visible row to the clicked position.
-
#initialize(content:, width: nil, height: nil, offset: 0, column: 0, wrap: false, keymap: :vim) ⇒ Viewport
constructor
content may be a string, an array of lines, or any object responding to ‘render`.
-
#render ⇒ Object
Renders the visible window of content as a multi-line string.
Methods included from KeyboardHandler
Methods inherited from View
Constructor Details
#initialize(content:, width: nil, height: nil, offset: 0, column: 0, wrap: false, keymap: :vim) ⇒ Viewport
content may be a string, an array of lines, or any object responding to ‘render`. width and height constrain the visible window; offset is the top-visible row and column is the left-visible column. wrap enables soft-wrapping of long lines.
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/charming/presentation/components/viewport.rb', line 37 def initialize(content:, width: nil, height: nil, offset: 0, column: 0, wrap: false, keymap: :vim) super() @content = content @width = width @height = height @offset = offset @column = column @wrap = wrap @keymap = keymap clamp_position end |
Instance Attribute Details
#column ⇒ Object (readonly)
The current top-visible row and left-visible column, respectively.
32 33 34 |
# File 'lib/charming/presentation/components/viewport.rb', line 32 def column @column end |
#offset ⇒ Object (readonly)
The current top-visible row and left-visible column, respectively.
32 33 34 |
# File 'lib/charming/presentation/components/viewport.rb', line 32 def offset @offset end |
Instance Method Details
#handle_mouse(event) ⇒ Object
Handles mouse events: scroll wheel adjusts the row offset, click moves the top visible row to the clicked position. Returns :handled on success.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/charming/presentation/components/viewport.rb', line 56 def handle_mouse(event) return nil unless height if event.scroll? scroll_delta = (event. == :scroll_up) ? -1 : 1 @offset += scroll_delta clamp_position return :handled end return nil unless event.click? clicked_row = event.y return nil if clicked_row < offset || clicked_row >= offset + @offset = clicked_row clamp_position :handled end |
#render ⇒ Object
Renders the visible window of content as a multi-line string.
50 51 52 |
# File 'lib/charming/presentation/components/viewport.rb', line 50 def render visible_lines.map { |line| render_line(line) }.join("\n") end |