create a separate directory for different text builders

This commit is contained in:
2025-09-12 08:57:17 +01:00
parent 9ec74380c4
commit b6de188f7d
4 changed files with 329 additions and 316 deletions

View File

@@ -1,320 +1,7 @@
structure TextBuilder =
struct
structure TC = TextConstants
type env_data =
{ charR: Real32.real
, charG: Real32.real
, charB: Real32.real
(* different colours for char when cursor is on char *)
, cursorOnCharR: Real32.real
, cursorOnCharG: Real32.real
, cursorOnCharB: Real32.real
, cursorR: Real32.real
, cursorG: Real32.real
, cursorB: Real32.real
, highlightR: Real32.real
, highlightG: Real32.real
, highlightB: Real32.real
, charZ: Real32.real
, cursorZ: Real32.real
, highlightZ: Real32.real
, startX: int
, startY: int
, scrollColumnStart: int
, scrollColumnEnd: int
, lastLineNumber: int
(* fw/fh = float window width and float window height *)
, fw: Real32.real
, fh: Real32.real
, msgs: MailboxType.t list
, searchList: int vector
, searchLen: int
}
(* different functions to make vectors of different things we want to draw. *)
fun makeCursor (posX, posY, env: env_data) =
Rect.lerp
( Real32.fromInt (posX - 1)
, Real32.fromInt posY
, #cursorZ env
, TC.scale
, #fw env
, #fh env
, #cursorR env
, #cursorG env
, #cursorB env
)
fun makeHighlight (posX, posY, env: env_data) =
Rect.lerp
( Real32.fromInt (posX - 1)
, Real32.fromInt posY
, #highlightZ env
, TC.scale
, #fw env
, #fh env
, #highlightR env
, #highlightG env
, #highlightB env
)
fun makeChr (chr, posX, posY, env: env_data) =
CozetteAscii.make
( chr
, Real32.fromInt posX
, Real32.fromInt posY
, #charZ env
, TC.scale
, #fw env
, #fh env
, #charR env
, #charG env
, #charB env
)
fun makeCursorOnChr (chr, posX, posY, env: env_data) =
CozetteAscii.make
( chr
, Real32.fromInt posX
, Real32.fromInt posY
, #charZ env
, TC.scale
, #fw env
, #fh env
, #cursorOnCharR env
, #cursorOnCharG env
, #cursorOnCharB env
)
structure TextWithCursor =
struct
fun goToFirstLineAfter
(stl, ltl, posY, lineNumber, absIdx, cursorIdx, env, acc) =
case (stl, ltl) of
(shd :: stl, lhd :: ltl) =>
if Vector.length lhd > 0 then
let
val lineOffset = Vector.sub (lhd, 0)
val strPos = lineOffset + 1
val absIdx = absIdx + strPos
val posY = posY + TC.ySpace
val lineNumber = lineNumber + 1
in
build
( strPos
, shd
, stl
, lhd
, ltl
, #startX env
, posY
, 0
, lineNumber
, absIdx
, cursorIdx
, env : env_data
, acc
)
end
else
(* keep looping until we find a linebreak *)
goToFirstLineAfter
( stl
, ltl
, posY
, lineNumber
, absIdx + String.size shd
, cursorIdx
, env
, acc
)
| (_, _) => acc
and skipToColumnStart
(pos, str, stl, line, ltl, posY, lineNumber, absIdx, cursorIdx, env, acc) =
if Vector.length line = 0 then
let
(* get index of buffer after this string *)
val absIdx = absIdx - pos
val absIdx = absIdx + String.size str
in
goToFirstLineAfter
(stl, ltl, posY, lineNumber, absIdx, cursorIdx, env, acc)
end
else
(* bin search lines *)
let
val searchPos = BinSearch.equalOrMore (pos + 1, #searchList env)
in
if searchPos = Vector.length line then
(* next line is not in this node *)
let
val absIdx = absIdx - pos
val absIdx = absIdx + String.size str
in
goToFirstLineAfter
(stl, ltl, posY, lineNumber, absIdx, cursorIdx, env, acc)
end
else
let
val lineOffset = Vector.sub (line, searchPos)
val newStrPos = lineOffset + 1
val absIdx = absIdx - pos + newStrPos
val posY = posY + TC.ySpace
val lineNumber = lineNumber + 1
in
build
( newStrPos
, str
, stl
, line
, ltl
, #startX env
, posY
, 0
, lineNumber
, absIdx
, cursorIdx
, env
, acc
)
end
end
and build
( pos
, str
, stl
, line
, ltl
, posX
, posY
, column
, lineNumber
, absIdx
, cursorIdx
, env: env_data
, acc
) =
if pos = String.size str then
case (stl, ltl) of
(str :: stl, line :: ltl) =>
build
( 0
, str
, stl
, line
, ltl
, posX
, posY
, column
, lineNumber
, absIdx
, cursorIdx
, env
, acc
)
| (_, _) => acc
else if column < #scrollColumnStart env then
skipToColumnStart
( pos
, str
, stl
, line
, ltl
, posY
, lineNumber
, absIdx
, cursorIdx
, env
, acc
)
else
case String.sub (str, pos) of
#" " =>
let
val acc =
if absIdx = cursorIdx then makeCursor (posX, posY, env) :: acc
else acc
in
build
( pos + 1
, str
, stl
, line
, ltl
, posX + TC.xSpace
, posY
, column + 1
, lineNumber
, absIdx + 1
, cursorIdx
, env
, acc
)
end
| #"\n" =>
let
val acc =
if absIdx = cursorIdx then makeCursor (posX, posY, env) :: acc
else acc
val nextLineNumber = lineNumber + 1
in
if nextLineNumber > #lastLineNumber env then
acc
else
build
( pos + 1
, str
, stl
, line
, ltl
, #startX env
, posY + TC.ySpace
, 0
, lineNumber + 1
, absIdx + 1
, cursorIdx
, env
, acc
)
end
| chr =>
let
val acc =
if absIdx = cursorIdx then
let val acc = makeCursor (posX, posY, env) :: acc
in makeCursorOnChr (chr, posX, posY, env) :: acc
end
else
makeCursor (posX, posY, env) :: acc
in
build
( pos + 1
, str
, stl
, line
, ltl
, posX + TC.xSpace
, posY
, column + 1
, lineNumber
, absIdx + 1
, cursorIdx
, env
, acc
)
end
end
structure Utils = TextBuilderUtils
fun buildTextString
( pos
@@ -327,7 +14,7 @@ struct
, cursorPos
, cursorAcc
, bgAcc
, env: env_data
, env: Utils.env_data
) =
if pos < String.size str then
case String.sub (str, pos) of
@@ -615,7 +302,7 @@ struct
, cursorPos
, cursorAcc
, bgAcc
, env: env_data
, env: Utils.env_data
, searchPos
) =
if searchPos = Vector.length (#searchList env) then