From a7761cb3334dc1a1155b12e7b46c1ed03279167f Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Mon, 6 May 2019 16:56:31 +0800 Subject: [PATCH] rpcnotify ok. fullscreen ok. --- Editor.xaml.fs | 22 +++++++++++++++++++++- FVimViewModel.fs | 34 +++++++++++++++++++++++++--------- MainWindow.xaml.fs | 1 + log.fs | 11 ++++++++++- neovim.rpc.fs | 16 ++++++++-------- ui.fs | 2 +- 6 files changed, 66 insertions(+), 20 deletions(-) diff --git a/Editor.xaml.fs b/Editor.xaml.fs index 65f3d4d..e3719ee 100644 --- a/Editor.xaml.fs +++ b/Editor.xaml.fs @@ -17,6 +17,7 @@ open Avalonia.Threading open Avalonia.Platform open System.Text open Avalonia.Utilities +open FSharp.Control.Reactive [] type private GridBufferCell = @@ -67,6 +68,7 @@ type Editor() as this = let mutable grid_size = { rows = 100; cols=50 } let mutable grid_scale = 1.0 let mutable grid_linespace = 0.0 + let mutable grid_fullscreen = false #if USE_FRAMEBUFFER let mutable grid_fb: RenderTargetBitmap = null let mutable grid_dc: IDrawingContextImpl = null @@ -476,6 +478,20 @@ type Editor() as this = | Mouse en -> setMouse en | _ -> () + let toggleFullScreen(gridid: int) = + if gridid = this.GridId then + let win = this.GetVisualRoot() :?> Window + if grid_fullscreen then + win.WindowState <- WindowState.Normal + win.HasSystemDecorations <- true + win.Topmost <- false + grid_fullscreen <- false + else + win.HasSystemDecorations <- false + win.WindowState <- WindowState.Maximized + win.Topmost <- true + grid_fullscreen <- true + do setFont font_family font_size AvaloniaXamlLoader.Load(this) @@ -484,7 +500,11 @@ type Editor() as this = member this.Id = this.GridId member this.GridHeight = int( measured_size.Height / glyph_size.Height ) member this.GridWidth = int( measured_size.Width / glyph_size.Width ) - member this.Connect cmds = cmds.Add (Array.iter redraw) + member this.Connect redraw_ev fullscreen_ev = + redraw_ev.Add (Array.iter redraw) + fullscreen_ev + |> Observable.observeOnContext (AvaloniaSynchronizationContext.Current) + |> Observable.add toggleFullScreen member this.Resized = resizeEvent.Publish member this.Input = inputEvent.Publish diff --git a/FVimViewModel.fs b/FVimViewModel.fs index b81754b..028d290 100644 --- a/FVimViewModel.fs +++ b/FVimViewModel.fs @@ -20,7 +20,8 @@ open FSharp.Control.Tasks.V2 type FVimViewModel(args: string[]) = inherit ViewModelBase() - let redraw = Event() + let redraw = Event() + let fullscreen = Event() let nvim = Process(args) let requestHandlers = Dictionary Response Async>() let notificationHandlers = Dictionary unit Async>() @@ -31,12 +32,18 @@ type FVimViewModel(args: string[]) = let msg_dispatch = function | Request(id, req, reply) -> - Async.Start(async { - let! rsp = requestHandlers.[req.method](req.parameters) - do! reply id rsp - }) + match requestHandlers.TryGetValue req.method with + | true, method -> + Async.Start(async { + let! rsp = method(req.parameters) + do! reply id rsp + }) + | _ -> error "rpc" "request handler [%s] not found" req.method + | Notification req -> - Async.Start(notificationHandlers.[req.method](req.parameters)) + match notificationHandlers.TryGetValue req.method with + | true, method -> Async.Start(method(req.parameters)) + | _ -> error "rpc" "notification handler [%s] not found" req.method | Redraw cmd -> redraw.Trigger cmd | Exit -> Avalonia.Application.Current.Exit() | _ -> () @@ -251,6 +258,15 @@ type FVimViewModel(args: string[]) = nvim.subscribe (AvaloniaSynchronizationContext.Current) (msg_dispatch) + trace "ViewModel" "registering rpc handlers" + notify "ToggleFullScreen" (fun ps -> async { + match ps with + | [| Integer32(gridid) |] -> + trace "ViewModel" "ToggleFullScreen: %A" gridid + fullscreen.Trigger gridid + | _ -> () + }) + trace "ViewModel" "commencing early initialization..." task { let! _ = nvim.set_var "fvim_loaded" 1 @@ -259,7 +275,7 @@ type FVimViewModel(args: string[]) = member this.OnGridReady(gridui: IGridUI) = // connect the redraw commands - gridui.Connect redraw.Publish + gridui.Connect redraw.Publish fullscreen.Publish gridui.Resized |> Observable.throttle (TimeSpan.FromMilliseconds 20.0) |> Observable.add onGridResize @@ -279,8 +295,8 @@ type FVimViewModel(args: string[]) = else failwithf "grid: unsupported: %A" gridui.Id - member val WindowWidth: int = 824 with get,set - member val WindowHeight: int = 721 with get,set + member val WindowWidth: int = 824 with get,set + member val WindowHeight: int = 721 with get,set member this.OnTerminated (args) = trace "ViewModel" "terminating nvim..." diff --git a/MainWindow.xaml.fs b/MainWindow.xaml.fs index 731db90..3384bbd 100644 --- a/MainWindow.xaml.fs +++ b/MainWindow.xaml.fs @@ -17,3 +17,4 @@ type MainWindow(datactx: FVimViewModel) as this = AvaloniaXamlLoader.Load this Avalonia.DevToolsExtensions.AttachDevTools(this); + diff --git a/log.fs b/log.fs index 0c35f47..5dd382d 100644 --- a/log.fs +++ b/log.fs @@ -3,10 +3,19 @@ open System.Diagnostics let trace cat fmt = + #if DEBUG + //Printf.kprintf (fun s -> printfn "%s: %s" cat s) fmt + //Printf.kprintf (fun s -> Trace.WriteLine(s, cat)) fmt + Printf.kprintf (fun s -> Trace.TraceInformation(sprintf "%s: %s" cat s)) fmt + #else + Printf.kprintf (fun s -> ()) fmt + #endif + +let error cat fmt = #if DEBUG //Printf.kprintf (fun s -> printfn "%s: %s" cat s) fmt //Printf.kprintf (fun s -> Trace.TraceInformation(sprintf "%s: %s" cat s)) fmt - Printf.kprintf (fun s -> Trace.WriteLine(s, cat)) fmt + Printf.kprintf (fun s -> Trace.TraceError(sprintf "%s: %s" cat s)) fmt #else Printf.kprintf (fun s -> ()) fmt #endif diff --git a/neovim.rpc.fs b/neovim.rpc.fs index 7b6add1..2a87991 100644 --- a/neovim.rpc.fs +++ b/neovim.rpc.fs @@ -31,24 +31,24 @@ let mkparams2 (t1: 'T1) (t2: 'T2) = [| box t1; box t2 |] let mkparams3 (t1: 'T1) (t2: 'T2) (t3: 'T3) = [| box t1; box t2; box t3 |] let mkparams4 (t1: 'T1) (t2: 'T2) (t3: 'T3) (t4: 'T4) = [| box t1; box t2; box t3; box t4|] -let private (|ObjArray|_|) (x:obj) = +let (|ObjArray|_|) (x:obj) = match x with | :? (obj[]) as x -> Some x | :? (obj list) as x -> Some(Array.ofList x) | :? (obj seq) as x -> Some(Array.ofSeq x) | _ -> None -let private (|Bool|_|) (x:obj) = +let (|Bool|_|) (x:obj) = match x with | :? bool as x -> Some x | _ -> None -let private (|String|_|) (x:obj) = +let (|String|_|) (x:obj) = match x with | :? string as x -> Some x | _ -> None -let private (|Integer32|_|) (x:obj) = +let (|Integer32|_|) (x:obj) = match x with | :? int32 as x -> Some(int32 x) | :? int16 as x -> Some(int32 x) @@ -58,7 +58,7 @@ let private (|Integer32|_|) (x:obj) = | :? uint8 as x -> Some(int32 x) | _ -> None -let private (|C|_|) (x:obj) = +let (|C|_|) (x:obj) = match x with | ObjArray x -> match x.[0] with @@ -66,19 +66,19 @@ let private (|C|_|) (x:obj) = | _ -> None | _ -> None -let private (|C1|_|) (x:obj) = +let (|C1|_|) (x:obj) = match x with | ObjArray [| (String cmd); ObjArray ps |] -> Some(cmd, ps) | _ -> None -let private (|P|_|) (parser: obj -> 'a option) (xs:obj) = +let (|P|_|) (parser: obj -> 'a option) (xs:obj) = match xs with | :? (obj seq) as xs -> let result = Seq.choose parser xs |> Array.ofSeq Some result | _ -> None -let private (|KV|_|) (k: string) (x: obj) = +let (|KV|_|) (k: string) (x: obj) = match x with | ObjArray [| (String key); x |] when key = k -> Some x | _ -> None diff --git a/ui.fs b/ui.fs index b74bf28..cba0519 100644 --- a/ui.fs +++ b/ui.fs @@ -27,7 +27,7 @@ type InputEvent = type IGridUI = abstract Id: int - abstract Connect: IEvent -> unit + abstract Connect: IEvent -> IEvent -> unit abstract GridHeight: int abstract GridWidth: int abstract Resized: IEvent