package quickterface
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Quick-to-program app interfaces in OCaml for terminal and web
Install
dune-project
Dependency
Authors
Maintainers
Sources
quickterface-0.1.0.tbz
sha256=8261e3819564fb5d05f1f313e62b73382152591d7a4349ae5b1b08a4fc2469f3
sha512=e739a971bb0e696ab716c168419c59a3d195922d2d1e4963106a845e3442ffa085b05106f36cceeec9b806bf7d6ef2c31e98db04911fbf73c5ac0ce626449d0f
doc/src/quickterface.terminal_app/progress_bar.ml.html
Source file progress_bar.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 88open! Core type t = { config : Progress_bar_config.t; current_value : int } [@@deriving sexp, fields] let maximum_value { config = { maximum_value; _ }; _ } = maximum_value let make ?(current_value = 0) ~config () = { config; current_value } let increment t = if current_value t < maximum_value t then { t with current_value = t.current_value + 1 } else raise_s [%message "Cannot increment loading bar beyond maximum value" (t : t)] let render ~render_info { config = { label; maximum_value }; current_value } = let open Notty.I in let margin = { Notty_utils.Sides.left = 1; right = 1; top = 1; bottom = 1 } in let title_img = Option.value_map label ~default:empty ~f:(fun label -> string Theme.loading_bar_title label) in let bar_img = let progress_text = (* E.g. "20/40 (50%)" *) sprintf "%d/%d (%.1f%%)" current_value maximum_value Float.(of_int 100 * of_int current_value / of_int maximum_value) in let progress_text_img = string Theme.loading_bar_text progress_text |> hpad 1 1 in let left_edge_img = char Theme.loading_bar_bar_edges '[' 1 1 in let right_edge_img = char Theme.loading_bar_bar_edges ']' 1 1 in let bar_img_width = render_info.Render_info.screen_width - width progress_text_img - width left_edge_img - width right_edge_img - margin.left - margin.right in if bar_img_width <= 0 then raise_s [%message "Not enough room to render progress bar" (render_info.Render_info.screen_width : int)]; let cell_progress_uchars = Notty_utils. [ Uchar.of_char ' '; uchar_left_block_one_eighth; uchar_left_block_one_quarter; uchar_left_block_three_eighths; uchar_left_block_half; uchar_left_block_five_eighths; uchar_left_block_three_quarters; uchar_left_block_seven_eighths; uchar_left_block_full; ] in let progress_cells_per_cell = List.length cell_progress_uchars in let total_progress_cells = bar_img_width * progress_cells_per_cell in let progress_cells_filled = Float.( of_int total_progress_cells * of_int current_value / of_int maximum_value) |> Float.round |> Int.of_float in let progress_cells_img = List.init bar_img_width ~f:(fun cell_index -> let start_progress_cell = cell_index * progress_cells_per_cell in let relative_progress_cell = progress_cells_filled - start_progress_cell in if relative_progress_cell < 0 then Uchar.of_char ' ' else if relative_progress_cell >= progress_cells_per_cell then List.last_exn cell_progress_uchars else List.nth_exn cell_progress_uchars relative_progress_cell) |> Array.of_list |> uchars Theme.loading_bar_bar_cells in left_edge_img <|> progress_cells_img <|> right_edge_img <|> progress_text_img in (Notty_utils.Sides.pad margin) (title_img <-> bar_img)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>