create text builder with highlight

This commit is contained in:
2025-09-12 10:42:13 +01:00
parent b6de188f7d
commit 9254fa9f5c
4 changed files with 317 additions and 234 deletions

View File

@@ -3,238 +3,6 @@ struct
structure TC = TextConstants
structure Utils = TextBuilderUtils
fun buildTextString
( pos
, str
, acc
, posX
, posY
, tl
, absIdx
, cursorPos
, cursorAcc
, bgAcc
, env: Utils.env_data
) =
if pos < String.size str then
case String.sub (str, pos) of
#" " =>
(* if inside cursor, then create cursorAcc;
* else, just skip as usual *)
if absIdx <> cursorPos then
(* not in cursur *)
buildTextString
( pos + 1
, str
, acc
, posX + xSpace
, posY
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
else
(* in cursor *)
let
val {r, g, b, fw, fh, ...} = env
val cursorAcc = makeRect (posX, posY, fw, fh, r, g, b)
in
buildTextString
( pos + 1
, str
, acc
, posX + xSpace
, posY
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
end
| #"\n" =>
if posY + ySpace < #h env then
if absIdx <> cursorPos then
(* not in cursor position, so iterate like normal *)
buildTextString
( pos + 1
, str
, acc
, #startX env
, posY + ySpace
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
else
(* in cursor position, so build cursorAcc *)
let
val {r, g, b, fw, fh, ...} = env
val cursorAcc = makeRect (posX, posY, fw, fh, r, g, b)
in
buildTextString
( pos + 1
, str
, acc
, #startX env
, posY + ySpace
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
end
else
accToDrawMsg (acc, cursorAcc, bgAcc, env)
| chr =>
let in
if absIdx <> cursorPos then
(* not equal to cursor *)
if posX + xSpace < #w env then
let
val {r, g, b, fw, fh, ...} = env
val chrVec = makeChr (chr, posX, posY, fw, fh, r, g, b)
val acc = chrVec :: acc
in
buildTextString
( pos + 1
, str
, acc
, posX + xSpace
, posY
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
end
else if posY + ySpace < #h env then
let
val {r, g, b, fw, fh, ...} = env
val chrVec = makeChr
(chr, #startX env, posY + ySpace, fw, fh, r, g, b)
val acc = chrVec :: acc
in
buildTextString
( pos + 1
, str
, acc
, #startX env + xSpace
, posY + ySpace
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
end
else
accToDrawMsg (acc, cursorAcc, bgAcc, env)
else
(* equal to cursor *)
let
val {fw, fh, r, g, b, hr, hg, hb, ...} = env
val cursorAcc = makeRect (posX, posY, fw, fh, r, g, b)
in
if posX + xSpace < #w env then
let
val chrVec = makeChr (chr, posX, posY, fw, fh, hr, hg, hb)
val acc = chrVec :: acc
in
(* can start building after cursor now,
* since cursor was built *)
buildTextString
( pos + 1
, str
, acc
, posX + xSpace
, posY
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
end
else if posY + ySpace < #h env then
let
val chrVec = makeChr
(chr, #startX env, posY + ySpace, fw, fh, hr, hg, hb)
val acc = chrVec :: acc
in
(* can start building after cursor now,
* since cursor was built *)
buildTextString
( pos + 1
, str
, acc
, #startX env + xSpace
, posY + ySpace
, tl
, absIdx + 1
, cursorPos
, cursorAcc
, bgAcc
, env
)
end
else
accToDrawMsg (acc, cursorAcc, bgAcc, env)
end
end
else
(* change to searching in string's tl *)
case tl of
hd :: tl =>
buildTextString
( 0
, hd
, acc
, posX
, posY
, tl
, absIdx
, cursorPos
, cursorAcc
, bgAcc
, env
)
| [] => accToDrawMsg (acc, cursorAcc, bgAcc, env)
fun isInSearchRange (absIdx, searchPos, searchList, searchLen) =
let val searchIdx = Vector.sub (searchList, searchPos)
in absIdx >= searchIdx andalso absIdx < searchIdx + searchLen
end
fun isAfterSearchRange (absIdx, searchPos, searchList, searchLen) =
let val searchIdx = Vector.sub (searchList, searchPos)
in absIdx >= searchIdx + searchLen
end
fun advanceSearchPos (absIdx, searchPos, searchList, searchLen) =
if isAfterSearchRange (absIdx, searchPos, searchList, searchLen) then
searchPos + 1
else
searchPos
local
fun loop
(pos, str, posX, posY, endX, acc, floatWindowWidth, floatWindowHeight) =
@@ -340,7 +108,6 @@ struct
, bgAcc
, env
)
else if pos < String.size str then
case String.sub (str, pos) of
#" " =>