Class: Canopus::Workspace::View
- Inherits:
-
Zaniah::Element
- Object
- Zaniah::Element
- Canopus::Workspace::View
- Includes:
- TerminalPresentable
- Defined in:
- lib/canopus/workspace/view.rb,
sig/controller.rbs
Overview
A viewport is one element; only visible document rows become draw commands.
Defined Under Namespace
Modules: TerminalPresentable
Constant Summary
Constants included from TerminalPresentable
TerminalPresentable::ANSI_COLORS
Instance Attribute Summary collapse
-
#accessibility ⇒ Array[{role: Symbol, label: String, bounds: Zaniah::Bounds}]
readonly
Returns the value of attribute accessibility.
-
#editor_bounds ⇒ Hash[Editor, Zaniah::Bounds]
readonly
Returns the value of attribute editor_bounds.
-
#keymap ⇒ Zaniah::Input::Keymap?
Returns the value of attribute keymap.
-
#minimap_bounds ⇒ Hash[Editor, Hash[Symbol, untyped]]
readonly
Returns the value of attribute minimap_bounds.
-
#regions ⇒ Array[[Zaniah::Bounds, action]]
readonly
Returns the value of attribute regions.
-
#row_layouts ⇒ Hash[[Editor, Integer], Zaniah::TextSystem::LineLayout]
readonly
Returns the value of attribute row_layouts.
Attributes included from TerminalPresentable
#terminal_bounds, #terminal_selection
Instance Method Summary collapse
- #cursor_visible? ⇒ Boolean
- #hit(point) ⇒ action?
-
#initialize(workspace) ⇒ View
constructor
A new instance of View.
- #minimap_scroll(editor, point) ⇒ Boolean
- #offset_at(editor, point) ⇒ Integer
- #paint(bounds, _state, _prepaint, cx) ⇒ void
- #project_scroll(delta) ⇒ Numeric
- #reset_blink(now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ void
- #tick(now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ Boolean
Methods included from TerminalPresentable
#focus_terminal, #terminal_color, #terminal_command, #terminal_command_jump, #terminal_link_at, #terminal_open_link, #terminal_point, #terminal_scroll, #terminal_select, #terminal_selected_text, #terminal_toggle_command
Constructor Details
#initialize(workspace) ⇒ View
Returns a new instance of View.
8 9 10 11 12 13 14 15 |
# File 'lib/canopus/workspace/view.rb', line 8 def initialize(workspace) super() @workspace = workspace @editor_bounds, @minimap_bounds, @row_layouts, @regions, @accessibility = {}, {}, {}, [], [] @project_scroll = 0 reset_blink @revealed_cursors, @line_widths, @code_caches = {}, {}, {} end |
Instance Attribute Details
#accessibility ⇒ Array[{role: Symbol, label: String, bounds: Zaniah::Bounds}] (readonly)
Returns the value of attribute accessibility.
6 7 8 |
# File 'lib/canopus/workspace/view.rb', line 6 def accessibility @accessibility end |
#editor_bounds ⇒ Hash[Editor, Zaniah::Bounds] (readonly)
Returns the value of attribute editor_bounds.
6 7 8 |
# File 'lib/canopus/workspace/view.rb', line 6 def editor_bounds @editor_bounds end |
#keymap ⇒ Zaniah::Input::Keymap?
Returns the value of attribute keymap.
7 8 9 |
# File 'lib/canopus/workspace/view.rb', line 7 def keymap @keymap end |
#minimap_bounds ⇒ Hash[Editor, Hash[Symbol, untyped]] (readonly)
Returns the value of attribute minimap_bounds.
6 7 8 |
# File 'lib/canopus/workspace/view.rb', line 6 def minimap_bounds @minimap_bounds end |
#regions ⇒ Array[[Zaniah::Bounds, action]] (readonly)
Returns the value of attribute regions.
6 7 8 |
# File 'lib/canopus/workspace/view.rb', line 6 def regions @regions end |
#row_layouts ⇒ Hash[[Editor, Integer], Zaniah::TextSystem::LineLayout] (readonly)
Returns the value of attribute row_layouts.
6 7 8 |
# File 'lib/canopus/workspace/view.rb', line 6 def row_layouts @row_layouts end |
Instance Method Details
#cursor_visible? ⇒ Boolean
19 |
# File 'lib/canopus/workspace/view.rb', line 19 def cursor_visible? = @cursor_visible |
#hit(point) ⇒ action?
94 95 96 97 98 |
# File 'lib/canopus/workspace/view.rb', line 94 def hit(point) return unless @painted_palette.equal?(@workspace.palette) @regions.reverse_each { |bounds, action| return action if bounds.contains?(point) } nil end |
#minimap_scroll(editor, point) ⇒ Boolean
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/canopus/workspace/view.rb', line 112 def minimap_scroll(editor, point) entry = @minimap_bounds[editor] return false unless entry && @workspace.panes.include?(entry[:pane]) && entry[:pane].active.equal?(editor) bounds = entry[:bounds] fraction = ((point.y - bounds.y).to_f / [bounds.height, 1].max).clamp(0, 1) source_row = (fraction * editor.buffer.line_count).floor.clamp(0, editor.buffer.line_count - 1) display_row = editor.display_map.to_display(editor.buffer.rope.line_start(source_row)).row target = (display_row - editor. / 2.0).clamp(0, [editor.display_map.row_count - editor., 0].max) editor.scroll(dy: target - editor.scroll_y) true end |
#offset_at(editor, point) ⇒ Integer
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/canopus/workspace/view.rb', line 99 def offset_at(editor, point) bounds = @editor_bounds.fetch(editor) row = (((point.y - bounds.y) / @line_height) + editor.scroll_y).floor.clamp(0, editor.display_map.row_count - 1) value = editor.display_map.row(row).text layout = @row_layouts[[editor, row]] || @cx.text_system&.layout_line(value, size: @font_size) x = point.x - bounds.x - gutter(editor) + editor.scroll_x byte = layout ? layout.index_for_x(x) : (x / (@font_size * 0.6)).round.clamp(0, value.length) column = layout ? value.byteslice(0, byte).length : byte editor.display_map.to_buffer(DisplayPoint.new(row, column)) end |
#paint(bounds, _state, _prepaint, cx) ⇒ void
This method returns an undefined value.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/canopus/workspace/view.rb', line 27 def paint(bounds, _state, _prepaint, cx) @cx, @theme, @scene = cx, @workspace.theme, cx.scene @children.clear @viewport_bounds = bounds @painted_palette = @workspace.palette @font_size = @workspace.settings["font_size"] @line_height = (@font_size * 1.55).ceil @line_height = 20 if @cx.window.is_a?(Zaniah::Platform::TUI::Window) @frame_id = @frame_id.to_i + 1 @workspace.minimap.begin_frame(@frame_id, text_system: @cx.text_system, font_size: @font_size, font_family: @workspace.settings["font_family"], scale_factor: @cx.window.scale_factor) @regions.clear @row_layouts.clear @overlay_rows = [] @editor_bounds.clear @minimap_bounds.clear @accessibility.clear visible_editors = @workspace.panes.map(&:active) @revealed_cursors.delete_if { |editor, _| !visible_editors.include?(editor) } @line_widths.delete_if { |editor, _| !visible_editors.include?(editor) } @code_caches.delete_if { |editor, _| !visible_editors.include?(editor) } fill(bounds, :background) left_panels = drawable_panels(:left) bottom_panels = drawable_panels(:bottom) bottom_visible = @workspace.docks[:bottom][:visible] && (@workspace.task_output_visible || @workspace.terminal_visible || !bottom_panels.empty?) bottom = bottom_visible ? [bounds.height * 0.7, @workspace.docks[:bottom][:size]].min : 0 left_visible = @workspace.docks[:left][:visible] && (@workspace.show_project || !left_panels.empty?) = left_visible && bounds.width >= 620 ? [@workspace.docks[:left][:size], bounds.width * 0.4].min : 0 right = @workspace.docks[:right][:visible] && !drawable_panels(:right).empty? && bounds.width >= 620 ? [@workspace.docks[:right][:size], bounds.width * 0.4].min : 0 body = Zaniah::Bounds.new(, 0, bounds.width - - right, [bounds.height - 26 - bottom, 0].max) if .positive? project_height = if @workspace.show_project left_panels.empty? ? bounds.height - 26 : (bounds.height - 26) * 0.6 else 0 end paint_project(Zaniah::Bounds.new(0, 0, , project_height)) if project_height.positive? paint_panels(:left, Zaniah::Bounds.new(0, project_height, , bounds.height - 26 - project_height)) unless left_panels.empty? end paint_layout(@workspace.layout, body) if bottom.positive? area = Zaniah::Bounds.new(, body.height, body.width, bottom) if @workspace.task_output_visible paint_task_output(area) elsif @workspace.terminal_visible paint_terminal(area) else paint_panels(:bottom, area) end end paint_panels(:right, Zaniah::Bounds.new(bounds.width - right, 0, right, bounds.height - 26)) if right.positive? region(Zaniah::Bounds.new( - 3, 0, 6, body.height), role: :separator, label: "Resize left dock", action: [:dock_resize, :left, bounds]) if .positive? region(Zaniah::Bounds.new(bounds.width - right - 3, 0, 6, body.height), role: :separator, label: "Resize right dock", action: [:dock_resize, :right, bounds]) if right.positive? region(Zaniah::Bounds.new(body.x, body.bottom - 3, body.width, 6), role: :separator, label: "Resize bottom dock", action: [:dock_resize, :bottom, bounds]) if bottom.positive? paint_status(Zaniah::Bounds.new(0, bounds.height - 26, bounds.width, 26)) paint_hover(bounds) if @workspace.hover_card && !@workspace.hover_card.empty? paint_palette(bounds) if @workspace.palette paint_notifications(bounds) unless @workspace.notifications.empty? if @workspace.performance stats = @workspace.performance.statistics label = "#{stats[:last_frame_ms]&.round(2) || 'n/a'} ms | #{stats[:last_allocations] || 'n/a'} objects | #{stats[:last_draw_calls] || 'n/a'} draws" @scene.layer(2_000_000) do area = Zaniah::Bounds.new([bounds.right - 360, 0].max, 3, [bounds.width, 356].min, 24) fill(area, :panel) text(label, area.x + 8, area.y + 4, color: :accent, size: 11) end end end |
#project_scroll(delta) ⇒ Numeric
109 110 111 |
# File 'lib/canopus/workspace/view.rb', line 109 def project_scroll(delta) @project_scroll = [@project_scroll + delta, 0].max end |
#reset_blink(now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ void
This method returns an undefined value.
16 17 18 |
# File 'lib/canopus/workspace/view.rb', line 16 def reset_blink(now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) @blink_started, @cursor_visible = now, true end |
#tick(now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ Boolean
20 21 22 23 24 25 26 |
# File 'lib/canopus/workspace/view.rb', line 20 def tick(now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) expired = @workspace.expire_notifications(now) visible = ((now - @blink_started) / 0.5).floor.even? return expired if visible == @cursor_visible @cursor_visible = visible true end |