package miaou-core
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Miaou core/widgets (no drivers, no SDL)
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.5.2.tar.gz
md5=60a3b9f181f24572a06a9492532bfdda
sha512=fcc35a275066be2900e6201782faf47503076fa4640f08cf78067835a6f447b74613009e55b2ac799adb7ca46f1bffa261fc5971753f2cc3c6bef327511c7ef6
doc/src/miaou_widgets_layout/pane.ml.html
Source file pane.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164(*****************************************************************************) (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2025 Nomadic Labs <contact@nomadic-labs.com> *) (* Copyright (c) 2026 Mathias Bourgoin <mathias.bourgoin@atacama.tech> *) (* *) (*****************************************************************************) (* Pane splitting helpers for Miaou widgets *) [@@@warning "-32-34-37-69"] (* reuse visible/ansi helpers and glyphs from display widgets/helpers *) module Helpers = Miaou_helpers.Helpers let visible_chars_count = Miaou_helpers.Helpers.visible_chars_count let visible_byte_index_of_pos = Miaou_helpers.Helpers.visible_byte_index_of_pos let insert_before_reset = Miaou_helpers.Helpers.insert_before_reset let has_trailing_reset = Miaou_helpers.Helpers.has_trailing_reset let repeat s n = let buf = Buffer.create (max 0 n * String.length s) in for _ = 1 to max 0 n do Buffer.add_string buf s done ; Buffer.contents buf let ansi = Miaou_widgets_display.Widgets.ansi (* Canonical glyphs and unicode-border flag come from display Widgets so behavior is consistent across all widgets. Keep local short names for convenience. *) let use_ascii_borders = Miaou_widgets_display.Widgets.use_ascii_borders let glyph_corner_tl = Miaou_widgets_display.Widgets.glyph_corner_tl let glyph_corner_tr = Miaou_widgets_display.Widgets.glyph_corner_tr let glyph_corner_bl = Miaou_widgets_display.Widgets.glyph_corner_bl let glyph_corner_br = Miaou_widgets_display.Widgets.glyph_corner_br let glyph_hline = Miaou_widgets_display.Widgets.glyph_hline let glyph_vline = Miaou_widgets_display.Widgets.glyph_vline let pad_right s n = let v = visible_chars_count s in if v >= n then s else Miaou_helpers.Helpers.pad_to_width s n ' ' let trunc_visible n s = let v = visible_chars_count s in if v <= n then s else let byte_idx = visible_byte_index_of_pos s (max 0 (n - 1)) in let prefix = String.sub s 0 byte_idx in prefix ^ "…" let split_lines s = String.split_on_char '\n' s let normalize_lines width wrap lines = let rec wrap_line w acc line = if line = "" then List.rev ("" :: acc) else let v = visible_chars_count line in if v <= w then List.rev (line :: acc) else if wrap then let byte_idx = visible_byte_index_of_pos line w in let part = String.sub line 0 byte_idx in let rest = String.sub line byte_idx (String.length line - byte_idx) in wrap_line w (part :: acc) rest else List.rev (trunc_visible w line :: acc) in let rec go acc = function | [] -> List.rev acc | x :: xs -> let parts = wrap_line width [] x in go (List.rev_append parts acc) xs in go [] lines let make_rows ~lines ~height = let rec go acc i = if i >= height then List.rev acc else let row = if i < List.length lines then List.nth lines i else "" in go (row :: acc) (i + 1) in go [] 0 let split_vertical_with_left_width ~width ~left_pad ~right_pad ~border ~wrap ~sep ~left ~right ~left_width = let total_w = width in let inner_w = if border then total_w - 4 else total_w in let left_w = max 0 (min inner_w left_width) in let right_w = inner_w - left_w in (* reserve left_pad/right_pad columns as padding inside each pane *) let left_content_w = max 0 (left_w - left_pad) in let right_content_w = max 0 (right_w - right_pad) in let left_lines_raw = normalize_lines left_content_w wrap (split_lines left) in let right_lines_raw = normalize_lines right_content_w wrap (split_lines right) in let left_lines = List.map (fun l -> String.make left_pad ' ' ^ l) left_lines_raw in let right_lines = List.map (fun l -> l ^ String.make right_pad ' ') right_lines_raw in let height = max (List.length left_lines) (List.length right_lines) in let left_rows = make_rows ~lines:left_lines ~height in let right_rows = make_rows ~lines:right_lines ~height in let rows = List.mapi (fun i l -> pad_right l left_w ^ sep ^ pad_right (List.nth right_rows i) right_w) left_rows in let body = Helpers.concat_lines rows in if border then let top = glyph_corner_tl ^ repeat glyph_hline (total_w - 2) ^ glyph_corner_tr in let bot = glyph_corner_bl ^ repeat glyph_hline (total_w - 2) ^ glyph_corner_br in top ^ "\n" ^ body ^ "\n" ^ bot else body (* Backwards-compatible wrapper: choose half/half split when left width not specified. *) let split_vertical ~width ~left_pad ~right_pad ~border ~wrap ~sep ~left ~right = let inner_w = if border then width - 4 else width in let left_w = inner_w / 2 in split_vertical_with_left_width ~width ~left_pad ~right_pad ~border ~wrap ~sep ~left ~right ~left_width:left_w let split_horizontal ~height ~top_pad ~bottom_pad ~border ~wrap ~sep ~top ~bottom = let top_lines = split_lines top in let bottom_lines = split_lines bottom in (* apply vertical padding lines *) let top_padded = List.init top_pad (fun _ -> "") @ top_lines in let bottom_padded = bottom_lines @ List.init bottom_pad (fun _ -> "") in let top_s = Helpers.concat_lines top_padded in let bottom_s = Helpers.concat_lines bottom_padded in let frame_width = max 10 height in let _ = wrap in if border then let top_frame = glyph_corner_tl ^ repeat glyph_hline (frame_width - 2) ^ glyph_corner_tr in top_frame ^ "\n" ^ top_s ^ "\n" ^ sep ^ "\n" ^ bottom_s else top_s ^ "\n" ^ sep ^ "\n" ^ bottom_s [@@@enforce_exempt] (* non-widget module *)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>