Skip to content

Commit

Permalink
editor refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Yatao Li committed Nov 2, 2020
1 parent d039d9a commit 4d1717a
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 110 deletions.
200 changes: 92 additions & 108 deletions ViewModels/EditorViewModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,53 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
let markAllDirty () =
m_griddirty <- true

let cursorConfig() =
if theme.mode_defs.Length = 0 || m_cursor_vm.modeidx < 0 then ()
elif m_gridbuffer.GetLength(0) <= m_cursor_vm.row || m_gridbuffer.GetLength(1) <= m_cursor_vm.col then ()
else
let mode = theme.mode_defs.[m_cursor_vm.modeidx]
let hlid = m_gridbuffer.[m_cursor_vm.row, m_cursor_vm.col].hlid
let hlid = Option.defaultValue hlid mode.attr_id
let fg, bg, sp, attrs = theme.GetDrawAttrs hlid
let origin : Point = this.GetPoint m_cursor_vm.row m_cursor_vm.col
let text = m_gridbuffer.[m_cursor_vm.row, m_cursor_vm.col].text
let text_type = wswidth text
let width = float(max <| 1 <| CharTypeWidth text_type) * m_glyphsize.Width

let on, off, wait =
match mode with
| { blinkon = Some on; blinkoff = Some off; blinkwait = Some wait }
when on > 0 && off > 0 && wait > 0 -> on, off, wait
| _ -> 0,0,0

// do not use the default colors for cursor
let colorf = if hlid = 0 then GetReverseColor else id
let fg, bg, sp = colorf fg, colorf bg, colorf sp
let chksum = m_cursor_vm.VisualChecksum()
m_cursor_vm.typeface <- theme.guifont
m_cursor_vm.wtypeface <- theme.guifontwide
m_cursor_vm.fontSize <- m_fontsize
m_cursor_vm.text <- text
m_cursor_vm.fg <- fg
m_cursor_vm.bg <- bg
m_cursor_vm.sp <- sp
m_cursor_vm.underline <- attrs.underline
m_cursor_vm.undercurl <- attrs.undercurl
m_cursor_vm.bold <- attrs.bold
m_cursor_vm.italic <- attrs.italic
m_cursor_vm.cellPercentage <- Option.defaultValue 100 mode.cell_percentage
m_cursor_vm.blinkon <- on
m_cursor_vm.blinkoff <- off
m_cursor_vm.blinkwait <- wait
m_cursor_vm.shape <- Option.defaultValue CursorShape.Block mode.cursor_shape
m_cursor_vm.X <- origin.X
m_cursor_vm.Y <- origin.Y
m_cursor_vm.Width <- width
m_cursor_vm.Height <- m_glyphsize.Height
if chksum <> m_cursor_vm.VisualChecksum() then
m_cursor_vm.RenderTick <- m_cursor_vm.RenderTick + 1
trace _gridid "set cursor info, color = %A %A %A" fg bg sp

let clearBuffer preserveContent =
let oldgrid = m_gridbuffer
m_gridbuffer <- Array2D.create m_gridsize.rows m_gridsize.cols GridBufferCell.empty
Expand All @@ -83,6 +130,13 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
this.RaisePropertyChanged("BufferHeight")
this.RaisePropertyChanged("BufferWidth")

let initBuffer nrow ncol preserveContent =
let new_gridsize = { rows = nrow; cols = ncol }
if m_gridsize <> new_gridsize then
m_gridsize <- new_gridsize
trace _gridid "buffer resize = %A" m_gridsize
clearBuffer preserveContent

let putBuffer (line: GridLine) =
let row = line.row
let mutable col = line.col_start
Expand All @@ -98,7 +152,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
let dirty = { row = row; col = line.col_start; height = 1; width = col - line.col_start }
// if the buffer under cursor is updated, also notify the cursor view model
if row = m_cursor_vm.row && line.col_start <= m_cursor_vm.col && m_cursor_vm.col < col
then this.cursorConfig()
then cursorConfig()
// trace _gridid "putBuffer: writing to %A" dirty
// italic font artifacts I: remainders after scrolling and redrawing the dirty part
// workaround: extend the dirty region one cell further towards the end
Expand Down Expand Up @@ -135,16 +189,20 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
if id = _gridid then
m_cursor_vm.row <- row
m_cursor_vm.col <- col
this.cursorConfig()
cursorConfig()

let changeMode (name: string) (index: int) =
m_cursor_vm.modeidx <- index
this.cursorConfig()
cursorConfig()

let setCursorEnabled v =
m_cursor_vm.enabled <- v
m_cursor_vm.RenderTick <- m_cursor_vm.RenderTick + 1

let setBusy (v: bool) =
trace _gridid "neovim: busy: %A" v
m_busy <- v
this.setCursorEnabled <| not v
setCursorEnabled <| not v
//if v then this.Cursor <- Cursor(StandardCursorType.Wait)
//else this.Cursor <- Cursor(StandardCursorType.Arrow)

Expand Down Expand Up @@ -200,7 +258,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
&& left <= m_cursor_vm.col
&& m_cursor_vm.col <= right
then
this.cursorConfig()
cursorConfig()

m_drawops.Add(Scroll(top, bot, left, right, rows, cols))

Expand All @@ -217,7 +275,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
(* manually resize and position the child grid as per neovim docs *)
let origin: Point = parent.GetPoint startrow startcol
trace _gridid "setWinPos: update parameters: c = %d r = %d X = %f Y = %f" c r origin.X origin.Y
this.initBuffer r c true
initBuffer r c true
this.X <- origin.X
this.Y <- origin.Y

Expand Down Expand Up @@ -265,7 +323,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
let redraw(cmd: RedrawCommand) =
//trace "%A" cmd
match cmd with
| GridResize(_, c, r) -> this.initBuffer r c true
| GridResize(_, c, r) -> initBuffer r c true
| GridClear _ -> clearBuffer false
| GridLine lines -> putBufferM lines
| GridCursorGoto(id, row, col) -> cursorGoto id row col
Expand All @@ -290,7 +348,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
trace _gridid "fontConfig: glyphsize=%A, measured font size=%A" m_glyphsize m_fontsize

// sync font to cursor vm
this.cursorConfig()
cursorConfig()
// sync font to popupmenu vm
m_popupmenu_vm.SetFont(theme.guifont, theme.fontsize)
markAllDirty()
Expand Down Expand Up @@ -329,7 +387,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
do
trace _gridid "%s" "ctor"
fontConfig()
this.setCursorEnabled theme.cursor_enabled
setCursorEnabled theme.cursor_enabled
clearBuffer false

this.Watch [
Expand All @@ -349,34 +407,12 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
theme.cursoren_ev.Publish
|> Observable.subscribe (fun en ->
if m_cursor_vm.ingrid then
this.setCursorEnabled en)
setCursorEnabled en)

States.Register.Watch "font" fontConfig

]

member __.Item with get(row, col) = m_gridbuffer.[row, col]

member __.Cols with get() = m_gridsize.cols

member __.Rows with get() = m_gridsize.rows

member __.Dirty with get() = m_griddirty

member __.DrawOps with get() = m_drawops

member __.MarkAllDirty() = markAllDirty()

member __.GetFontAttrs() =
theme.guifont, theme.guifontwide, m_fontsize

member private __.initBuffer nrow ncol preserveContent =
let new_gridsize = { rows = nrow; cols = ncol }
if m_gridsize <> new_gridsize then
m_gridsize <- new_gridsize
trace _gridid "buffer resize = %A" m_gridsize
clearBuffer preserveContent

interface IGridUI with
member __.Id = _gridid
member __.GridHeight = int( this.Height / m_glyphsize.Height )
Expand All @@ -398,101 +434,49 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
| None -> ()
| Some p -> (p:>IGridUI).RemoveChild this

member __.markClean () =
member __.MarkClean () =
m_griddirty <- false
m_drawops.Clear()

member __.MarkAllDirty = markAllDirty

// converts grid position to UI Point
member __.GetPoint row col =
Point(double(col) * m_glyphsize.Width, double(row) * m_glyphsize.Height)

member __.cursorConfig() =
if theme.mode_defs.Length = 0 || m_cursor_vm.modeidx < 0 then ()
elif m_gridbuffer.GetLength(0) <= m_cursor_vm.row || m_gridbuffer.GetLength(1) <= m_cursor_vm.col then ()
else
let mode = theme.mode_defs.[m_cursor_vm.modeidx]
let hlid = m_gridbuffer.[m_cursor_vm.row, m_cursor_vm.col].hlid
let hlid = Option.defaultValue hlid mode.attr_id
let fg, bg, sp, attrs = theme.GetDrawAttrs hlid
let origin = this.GetPoint m_cursor_vm.row m_cursor_vm.col
let text = m_gridbuffer.[m_cursor_vm.row, m_cursor_vm.col].text
let text_type = wswidth text
let width = float(max <| 1 <| CharTypeWidth text_type) * m_glyphsize.Width

let on, off, wait =
match mode with
| { blinkon = Some on; blinkoff = Some off; blinkwait = Some wait }
when on > 0 && off > 0 && wait > 0 -> on, off, wait
| _ -> 0,0,0

// do not use the default colors for cursor
let colorf = if hlid = 0 then GetReverseColor else id
let fg, bg, sp = colorf fg, colorf bg, colorf sp
let chksum = m_cursor_vm.VisualChecksum()
m_cursor_vm.typeface <- theme.guifont
m_cursor_vm.wtypeface <- theme.guifontwide
m_cursor_vm.fontSize <- m_fontsize
m_cursor_vm.text <- text
m_cursor_vm.fg <- fg
m_cursor_vm.bg <- bg
m_cursor_vm.sp <- sp
m_cursor_vm.underline <- attrs.underline
m_cursor_vm.undercurl <- attrs.undercurl
m_cursor_vm.bold <- attrs.bold
m_cursor_vm.italic <- attrs.italic
m_cursor_vm.cellPercentage <- Option.defaultValue 100 mode.cell_percentage
m_cursor_vm.blinkon <- on
m_cursor_vm.blinkoff <- off
m_cursor_vm.blinkwait <- wait
m_cursor_vm.shape <- Option.defaultValue CursorShape.Block mode.cursor_shape
m_cursor_vm.X <- origin.X
m_cursor_vm.Y <- origin.Y
m_cursor_vm.Width <- width
m_cursor_vm.Height <- m_glyphsize.Height
if chksum <> m_cursor_vm.VisualChecksum() then
m_cursor_vm.RenderTick <- m_cursor_vm.RenderTick + 1
trace _gridid "set cursor info, color = %A %A %A" fg bg sp

member this.setCursorEnabled v =
m_cursor_vm.enabled <- v
m_cursor_vm.RenderTick <- m_cursor_vm.RenderTick + 1
member this.SetMeasuredSize (v: Size) =
trace _gridid "set measured size: %A" v
let gridui = this :> IGridUI
let gw, gh = gridui.GridWidth, gridui.GridHeight
this.Width <- v.Width
this.Height <- v.Height
let gw', gh' = gridui.GridWidth, gridui.GridHeight
if gw <> gw' || gh <> gh' then
if this.IsTopLevel then
m_resize_ev.Trigger(this)

(******************* Exposed properties ***********************)

member this.CursorInfo
with get() : CursorViewModel = m_cursor_vm

member this.PopupMenu
with get(): PopupMenuViewModel = m_popupmenu_vm

member __.Item with get(row, col) = m_gridbuffer.[row, col]
member __.Cols with get() = m_gridsize.cols
member __.Rows with get() = m_gridsize.rows
member __.Dirty with get() = m_griddirty
member __.DrawOps with get() = m_drawops
member __.CursorInfo with get() : CursorViewModel = m_cursor_vm
member __.PopupMenu with get(): PopupMenuViewModel = m_popupmenu_vm
member __.RenderScale
with get() : float = m_gridscale
and set(v) =
m_gridscale <- v

and set(v) = m_gridscale <- v
member __.FontAttrs with get() = theme.guifont, theme.guifontwide, m_fontsize
member __.BackgroundColor with get(): Color = theme.default_bg
member __.BufferHeight with get(): float = m_fb_h
member __.BufferWidth with get(): float = m_fb_w
member __.GlyphHeight with get(): float = m_glyphsize.Height
member __.GlyphWidth with get(): float = m_glyphsize.Width
member __.TopLevel with get(): bool = parent.IsNone

member __.GridId
with get() = _gridid

member __.IsTopLevel with get(): bool = parent.IsNone
member __.GridId with get() = _gridid
member __.ChildGrids = m_child_grids

member this.SetMeasuredSize (v: Size) =
trace _gridid "set measured size: %A" v
let gridui = this :> IGridUI
let gw, gh = gridui.GridWidth, gridui.GridHeight
this.Width <- v.Width
this.Height <- v.Height
let gw', gh' = gridui.GridWidth, gridui.GridHeight
if gw <> gw' || gh <> gh' then
if this.TopLevel then
m_resize_ev.Trigger(this)

(******************* Events ***********************)

member __.OnKey (e: KeyEventArgs) =
Expand Down
4 changes: 2 additions & 2 deletions Views/Editor.xaml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ type Editor() as this =

if col = colend then () else

let font, fontwide, fontsize = grid_vm.GetFontAttrs()
let font, fontwide, fontsize = grid_vm.FontAttrs
let fg, bg, sp, attrs = theme.GetDrawAttrs hlid
let typeface = GetTypeface(grid_vm.[row, col].text, attrs.italic, attrs.bold, font, fontwide)

Expand Down Expand Up @@ -368,7 +368,7 @@ type Editor() as this =
doWithDataContext(fun vm ->
vm.RenderScale <- (this :> IVisual).GetVisualRoot().RenderScaling
let sz =
if vm.TopLevel then
if vm.IsTopLevel then
size
// multigrid: size is top-down managed, which means that
// the measurement of the view should be consistent with
Expand Down

0 comments on commit 4d1717a

Please sign in to comment.