hackin on the layout and window management

This commit is contained in:
cqc
2024-07-19 14:42:31 -05:00
parent d3dc3d091b
commit 686d868a94
2 changed files with 113 additions and 67 deletions

172
ogui.ml
View File

@ -3,6 +3,14 @@ module Gv = Graphv_gles2_native
module F = Fmt module F = Fmt
module Str = Re.Str module Str = Re.Str
let pp_box2 ppf b =
F.(
pf ppf "[%a %a]"
(pair ~sep:(any " ") float float)
Gg.(Box2.min b |> V2.to_tuple)
(pair ~sep:(any " ") float float)
Gg.(Box2.max b |> V2.to_tuple))
let pair a b = (a, b) let pair a b = (a, b)
module Lwd = struct module Lwd = struct
@ -129,13 +137,14 @@ module Margin = struct
let sum t : size2 = Size2.v (t.left +. t.right) (t.top +. t.bottom) let sum t : size2 = Size2.v (t.left +. t.right) (t.top +. t.bottom)
let inner t b : box2 = let inner t b : box2 =
Box2.of_pts Box2.(
(V2.v (Box2.minx b +. t.left) (Box2.miny b +. t.top)) of_pts
(V2.v (Box2.maxx b -. t.right) (Box2.maxy b -. t.bottom)) (V2.v (minx b +. t.left) (miny b +. t.top))
(V2.v (maxx b -. t.right) (maxy b -. t.bottom)))
let outer t b = let outer t b =
Box2.( Box2.(
v of_pts
(V2.v (minx b -. t.left) (miny b -. t.top)) (V2.v (minx b -. t.left) (miny b -. t.top))
(V2.v (maxx b +. t.right) (maxy b +. t.bottom))) (V2.v (maxx b +. t.right) (maxy b +. t.bottom)))
@ -1222,8 +1231,8 @@ module Layout = struct
and t = and t =
[ `Join of dir * (frame * frame) [ `Join of dir * (frame * frame)
| `String of string | `String of string * TextLayout.format
| `Buffer of TextBuffer.t | `Buffer of TextBuffer.t * TextLayout.format
| `TextEdit of TextEdit.t * TextLayout.layout | `TextEdit of TextEdit.t * TextLayout.layout
| `None ] | `None ]
@ -1239,7 +1248,7 @@ module Layout = struct
{ t; size; style } { t; size; style }
let none = frame `None let none = frame `None
let join d ?style a b = frame ?style (`Join (d, (a, b))) let join ?size ?style d a b = frame ?size ?style (`Join (d, (a, b)))
(* let hbox, vbox, zbox = (box `X, box `Y, box `Z) *) (* let hbox, vbox, zbox = (box `X, box `Y, box `Z) *)
let pack ?style d = (none, join d ?style) let pack ?style d = (none, join d ?style)
@ -1261,6 +1270,8 @@ module Layout = struct
margin = Margin.symmetric 10. 10.; margin = Margin.symmetric 10. 10.;
} }
let string ?size ?style s = frame ?size ?style (`String s)
let textedit_s ?size ?(style = textedit_style) let textedit_s ?size ?(style = textedit_style)
(t : TextEdit.t Lwd.t) : frame Lwd.t Lwt.t = (t : TextEdit.t Lwd.t) : frame Lwd.t Lwt.t =
let open TextLayout in let open TextLayout in
@ -1298,7 +1309,7 @@ module Layout = struct
| `Join (d, _) -> F.str "`Join %a" pp_dir d | `Join (d, _) -> F.str "`Join %a" pp_dir d
| `Buffer _ -> "`Buffer" | `Buffer _ -> "`Buffer"
| `TextEdit _ -> "`TextEdit" | `TextEdit _ -> "`TextEdit"
| `String s -> F.str "`String %s" s | `String (s, _) -> F.str "`String %s" s
| `None -> "`None") | `None -> "`None")
let pp_dim ppf = function let pp_dim ppf = function
@ -1326,7 +1337,7 @@ module Layout = struct
p p
| `Buffer _ -> pf ppf "`Buffer" | `Buffer _ -> pf ppf "`Buffer"
| `TextEdit _ -> pf ppf "`TextEdit" | `TextEdit _ -> pf ppf "`TextEdit"
| `String s -> pf ppf "`String @[<h 1>%s@]" s | `String (s, _) -> pf ppf "`String @[<h 1>%s@]" s
| `None -> pf ppf "`None" | `None -> pf ppf "`None"
and pp_frame_rec ppf t = and pp_frame_rec ppf t =
@ -1342,56 +1353,70 @@ module Layout = struct
end end
module WindowManager = struct module WindowManager = struct
type dir = Layout.dir open Layout
type t = type t =
[ `T of dir * t list [ `T of dir * (t * dim) list
| `TextEdit of TextEdit.t * Layout.dim | `TextEdit of TextEdit.t
| `Frame of Layout.frame ] | `Frame of frame ]
let rec length : t -> int = function let rec length : t -> int = function
| `T (_, tl) -> List.fold_left (fun a t' -> a + length t') 0 tl | `T (_, tl) ->
List.fold_left (fun a (t', _) -> a + length t') 0 tl
| _ -> 1 | _ -> 1
let rec fold_left ?(dir = `X) let rec fold_left ?(dir = `X)
~(f : ~(f :
dir -> dir ->
'a -> 'a ->
[ `Frame of Layout.frame | `TextEdit of TextEdit.t ] -> [ `Frame of frame | `TextEdit of TextEdit.t ] ->
'a) acc = function 'a) acc = function
| `T (dir, tl) -> | `T (dir, tl) ->
List.fold_left (fun a' t' -> fold_left ~f ~dir a' t') acc tl List.fold_left (fun a' t' -> fold_left ~f ~dir a' t') acc tl
| (`Frame _ as tt) | (`TextEdit _ as tt) -> f dir acc tt | (`Frame _ as tt) | (`TextEdit _ as tt) -> f dir acc tt
let frame_of_window (ui : Ui.t) (n : int) cursor style let color_gray c = Gv.Color.rgbf ~r:c ~g:c ~b:c
(content : Layout.frame Lwd.t) : Layout.frame Lwd.t Lwt.t =
let open Layout in let status_style sel : Style.t =
textedit let open Ui.Style in
~size:(`Ratio 1.0, `Pixels 30.) {
~style stroke =
(TextEdit.multiline ui Some (3.0, if sel then color_gray 0.6 else color_gray 0.4);
(TextBuffer.of_string fill = (if sel then color_gray 0.8 else color_gray 0.2);
~path:[ F.str "window/%d/status" n ] margin = Margin.symmetric 2. 2.;
(F.str "window/%d" n))) }
>>= fun status ->
Lwd.map2 (Lwd.map2 content status ~f:pair) (Lwd.get cursor) let status_format sel : TextLayout.format =
~f:(fun (tt', status) cursor -> {
join `Y TextLayout.format_default with
font_id = FontId ("mono", 18.0);
line_height = Some 19.;
color = (if sel then color_gray 0.1 else color_gray 0.9);
background = Gv.Color.transparent;
}
let frame_of_window (n : int) cursor style (size : dim * dim)
(content : frame Lwd.t) : frame Lwd.t =
Lwd.map2 content (Lwd.get cursor) ~f:(fun content cursor ->
join ~size
~style: ~style:
{ {
tt'.style with style with
stroke = stroke =
Option.map Option.map
(fun (s, c) -> (fun (s, c) ->
( s, ( s,
if n != cursor then Gv.Color.(transf c 0.3) if n != cursor then Gv.Color.(transf c 0.3)
else c )) else c ))
tt'.style.stroke; content.style.stroke;
} }
tt' status) `Y content
|> Lwt.return (string
~style:(status_style (n == cursor))
~size:(`Ratio 1.0, `Pixels 30.)
(F.str "window/%d" n, status_format (n == cursor))))
let make ui ?(style = Layout.textedit_style) let make ui ?(style = textedit_style)
?(_mode : [ `Tiling | `FullScreen | `Floating ] = `Tiling) ?(_mode : [ `Tiling | `FullScreen | `Floating ] = `Tiling)
(telist : t Lwd.var) = (telist : t Lwd.var) =
let cursor = Lwd.var 0 in let cursor = Lwd.var 0 in
@ -1411,7 +1436,7 @@ module WindowManager = struct
else 0); else 0);
(*TextEdit.default_bindings (*TextEdit.default_bindings
(List.nth (Lwd.peek telist) (Lwd.peek cursor)) (List.nth (Lwd.peek telist) (Lwd.peek cursor))
ui;*) ui; *)
Lwt.return_unit ); Lwt.return_unit );
] ]
|> Event.adds |> Event.adds
@ -1431,26 +1456,33 @@ module WindowManager = struct
]); ]);
Lwd.map_s (Lwd.get telist) ~f:(fun (tl : t) -> Lwd.map_s (Lwd.get telist) ~f:(fun (tl : t) ->
let rec fold dir : t -> Layout.frame Lwd.t Lwt.t = function let rec fold dir dim : t -> Layout.frame Lwd.t Lwt.t =
| `T (dir', tl) -> let size =
Lwt_list.fold_left_s match dir with
(fun f t ->
fold dir' t >>= fun newf ->
Lwd.map2 f newf ~f:(Layout.join dir') |> Lwt.return)
(Lwd.pure Layout.none) tl
| `Frame f' ->
frame_of_window ui 314 cursor style (Lwd.return f')
| `TextEdit (t', dim) ->
Layout.textedit
~size:
(match dir with
| `X -> (dim, `Ratio 1.) | `X -> (dim, `Ratio 1.)
| `Y -> (`Ratio 1., dim) | `Y -> (`Ratio 1., dim)
| `Z -> (dim, dim)) | `Z -> (dim, dim)
~style t'
>>= fun tt -> frame_of_window ui 314 cursor style tt
in in
fold `X tl) function
| `T ((dir', (t0, dim0) :: trest) as tl) ->
fold dir' dim0 t0 >>= fun fst ->
Lwt_list.fold_left_s
(fun f (t, dim) ->
fold dir' dim t >>= fun newf ->
Lwd.map2 f newf ~f:(join ~size dir') |> Lwt.return)
fst trest
| `T (_, []) -> Layout.none |> Lwd.return |> Lwt.return
| `Frame f' ->
frame_of_window 314 cursor style size (Lwd.return f')
|> Lwt.return
| `TextEdit t' ->
Layout.textedit
~size:(`Ratio 1.0, `Fun (fun b -> Gg.Box2.h b -. 30.))
t'
>>= fun tt ->
frame_of_window 314 cursor style size tt |> Lwt.return
in
fold `X (`Ratio 1.) tl)
>>= fun d -> Lwd.join d |> Lwt.return >>= fun d -> Lwd.join d |> Lwt.return
end end
@ -1482,10 +1514,22 @@ module Painter = struct
let open Gv in let open Gv in
Text.set_font_face t ~name:font_name; Text.set_font_face t ~name:font_name;
Text.set_size t ~size:font_size; Text.set_size t ~size:font_size;
Text.set_align t ~align:Align.(left lor top) Text.set_align t ~align:Align.(left lor top);
set_fill_color t ~color:format.color
let string (t : Gv.t) (rect : box2) str : box2 Lwt.t = let string ?(style = Style.default) (t : Gv.t) (rect : box2)
Lwt.return Gg.Box2.zero ((contents, format) : string * TextLayout.format) : box2 Lwt.t =
(* draw_box t ~box:rect ~style; *)
F.epr "string";
set_text_format t format;
let rect' = Margin.inner style.margin rect in
V2.v
(Gv.Text.text_w t ~x:(Box2.minx rect') ~y:(Box2.miny rect')
contents)
(Gv.Text.metrics t).line_height
|> Box2.v (Box2.o rect')
|> Margin.outer style.margin
|> Lwt.return
let text_layout (t : Gv.t) (rect : box2) let text_layout (t : Gv.t) (rect : box2)
((te, layout) : TextEdit.t * TextLayout.layout) : box2 Lwt.t = ((te, layout) : TextEdit.t * TextLayout.layout) : box2 Lwt.t =
@ -1560,7 +1604,7 @@ module Painter = struct
({ t; style; size = sx, sy } : frame) : box2 Lwt.t = ({ t; style; size = sx, sy } : frame) : box2 Lwt.t =
let box = let box =
Box2.v (Box2.o box) Box2.v (Box2.o box)
(V2.v (Size2.v
(match sx with (match sx with
| `Ratio r -> Box2.w box *. r | `Ratio r -> Box2.w box *. r
| `Pixels p -> p | `Pixels p -> p
@ -1571,32 +1615,36 @@ module Painter = struct
| `Fun f -> f box)) | `Fun f -> f box))
in in
let box' = Margin.inner style.margin box in let box' = Margin.inner style.margin box in
F.epr "@[<hv 3>%a " pp_box2 box;
draw_box ui.gv ~box ~style;
(match t with (match t with
| `Join (dir, (a, b)) -> | `Join (dir, (a, b)) ->
F.epr "`Join %a (@,@[<hv>" pp_dir dir; F.epr "`Join %a @,(@[<hv>" pp_dir dir;
layout box' ui a >>= fun ra -> layout box' ui a >>= fun ra ->
F.epr ",@ ";
let c' = let c' =
Box2.( Box2.(
match dir with match dir with
| `X -> of_pts (V2.v (maxx ra) (miny box')) (max box') | `X -> of_pts (V2.v (maxx ra) (miny box')) (max box')
| `Y -> of_pts (V2.v (minx box') (maxy ra)) (max box') | `Y -> of_pts (V2.v (minx box') (maxy ra)) (max box')
| `Z -> box) | `Z -> box')
in in
layout c' ui b >>= fun rb -> layout c' ui b >>= fun rb ->
F.epr "@])@."; F.epr "@])";
Gg.Box2.union ra rb |> Lwt.return Gg.Box2.union ra rb |> Lwt.return
| `TextEdit tt -> | `TextEdit tt ->
F.epr "`TextEdit"; F.epr "`TextEdit";
text_layout ui.gv box' tt text_layout ui.gv box' tt
| `None -> | `None ->
F.epr "`None"; F.epr "`None";
Lwt.return Gg.Box2.zero Lwt.return Gg.Box2.(v (o box') Gg.V2.zero)
| `String s -> string ui.gv box' s | `String s -> string ui.gv box' s
| _ -> | _ ->
F.epr "Layout not implemented!!@."; F.epr "_ !!Unimplemented!!";
Lwt.return Gg.Box2.zero) Lwt.return Gg.Box2.zero)
>>= fun r -> >>= fun r ->
draw_box ui.gv ~box:r ~style; F.epr "@]";
let r' = let r' =
(*Box2.add_pt r (*Box2.add_pt r
V2.(Box2.max r + v style.margin.right style.margin.bottom) V2.(Box2.max r + v style.margin.right style.margin.bottom)

View File

@ -126,7 +126,7 @@ let main =
(String.concat "/" initial_path)) (String.concat "/" initial_path))
|> Lwt.return |> Lwt.return
>>= fun to_init -> >>= fun to_init ->
let out_ppf = let _out_ppf =
let insert s = let insert s =
Lwt.async (fun () -> Lwt.async (fun () ->
TextBuffer.length to_init >>= fun len -> TextBuffer.length to_init >>= fun len ->
@ -174,15 +174,13 @@ let main =
])); ]));
WindowManager.make ui WindowManager.make ui
~style:
Layout.Style.
{ default with margin = Margin.symmetric 10.0 10.0 }
(Lwd.var (Lwd.var
(`T (`T
( `Y, ( `Y,
[ [
`TextEdit (TextEdit.multiline ui tb_init, `Ratio 1.0); (`TextEdit (TextEdit.multiline ui to_init), `Ratio 0.333);
`TextEdit (TextEdit.multiline ui to_init, `Ratio 0.5); (`TextEdit (TextEdit.multiline ui tb_init), `Ratio 0.5);
(`TextEdit (TextEdit.multiline ui to_init), `Ratio 1.0);
] ))) ] )))
>>= fun page -> >>= fun page ->
let page_root = Lwd.observe page in let page_root = Lwd.observe page in