diff --git a/fcore/app-update.sml b/fcore/app-update.sml index c8f42ae..48df52e 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -11,8 +11,9 @@ struct val {buffer, windowWidth, windowHeight, startLine} = app val newBuffer = LineGap.goToLine (startLine, buffer) - val textVec = - TextBuilder.build (startLine, newBuffer, newWidth, newHeight) + val cursorIdx = 0 (* TEMP *) + val textVec = TextBuilder.build + (startLine, cursorIdx, newBuffer, newWidth, newHeight) val newApp = AppWith.bufferAndSize (app, newBuffer, newWidth, newHeight) val msg = REDRAW_TEXT textVec diff --git a/fcore/text-builder.sml b/fcore/text-builder.sml index b9e1462..45c1677 100644 --- a/fcore/text-builder.sml +++ b/fcore/text-builder.sml @@ -1,7 +1,7 @@ signature TEXT_BUILDER = sig (* Prerequisite: LineGap is moved to requested line first. *) - val build: int * LineGap.t * int * int + val build: int * int * LineGap.t * int * int -> Real32.real vector end @@ -144,11 +144,214 @@ struct ) | [] => acc + (* same as buildTextStringAfterCursor, except this keeps track of absolute + * index and cursor pos too *) + fun buildTextStringBeforeCursor + ( pos, str, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx, cursorPos + ) = + if pos < String.size str then + case String.sub (str, pos) of + #" " => + buildTextStringBeforeCursor + ( pos + 1, str, acc, posX + xSpace, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + | #"\t" => + buildTextStringBeforeCursor + ( pos + 1, str, acc, posX + xSpace3, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + | #"\n" => + if posY + ySpace < windowHeight then + buildTextStringBeforeCursor + ( pos + 1, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + else + acc + | #"\r" => + if posY + ySpace < windowHeight then + if + pos < String.size str - 1 + andalso String.sub (str, pos + 1) = #"\n" + then + buildTextStringBeforeCursor + ( pos + 2, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + else + buildTextStringBeforeCursor + ( pos + 1, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + else + acc + | chr => + let + val chrFun = Vector.sub (CozetteAscii.asciiTable, Char.ord chr) + in + if posX + xSpace < windowWidth then + let + val chrVec = chrFun + (posX, posY, fontSize, fontSize, fWindowWidth, fWindowHeight, r, g, b) + val acc = chrVec :: acc + in + buildTextStringBeforeCursor + ( pos + 1, str, acc, posX + xSpace, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + end + else if posY + ySpace < windowHeight then + let + val chrVec = chrFun + ( startX, posY + ySpace, fontSize, fontSize + , fWindowWidth, fWindowHeight + , r, g, b + ) + val acc = chrVec :: acc + in + buildTextStringBeforeCursor + ( pos + 1, str, acc, startX + xSpace, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + end + else + acc + end + else + continueBuildTextLineGapBeforeCursor + ( tl, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, absIdx, cursorPos + ) + + and buildTextStringWithinCursor + ( pos, str, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx, cursorPos + ) = + if pos < String.size str then + case String.sub (str, pos) of + #" " => + buildTextStringWithinCursor + ( pos + 1, str, acc, posX + xSpace, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + | #"\t" => + buildTextStringWithinCursor + ( pos + 1, str, acc, posX + xSpace3, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + | #"\n" => + if posY + ySpace < windowHeight then + buildTextStringWithinCursor + ( pos + 1, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + else + acc + | #"\r" => + if posY + ySpace < windowHeight then + if + pos < String.size str - 1 + andalso String.sub (str, pos + 1) = #"\n" + then + buildTextStringWithinCursor + ( pos + 2, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + else + buildTextStringWithinCursor + ( pos + 1, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + else + acc + | chr => + let + val chrFun = Vector.sub (CozetteAscii.asciiTable, Char.ord chr) + in + if posX + xSpace < windowWidth then + let + val chrVec = chrFun + (posX, posY, fontSize, fontSize, fWindowWidth, fWindowHeight, r, g, b) + val acc = chrVec :: acc + in + buildTextStringWithinCursor + ( pos + 1, str, acc, posX + xSpace, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + end + else if posY + ySpace < windowHeight then + let + val chrVec = chrFun + ( startX, posY + ySpace, fontSize, fontSize + , fWindowWidth, fWindowHeight + , r, g, b + ) + val acc = chrVec :: acc + in + buildTextStringWithinCursor + ( pos + 1, str, acc, startX + xSpace, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos + ) + end + else + acc + end + else + (* we have built cursor now, so can call after-cursor function + * to build rest of text *) + continueBuildTextLineGapAfterCursor + ( tl, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b + ) + + and continueBuildTextLineGapBeforeCursor + ( strList, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, absIdx, cursorPos + ) = + case strList of + hd :: tl => + if cursorPos >= absIdx + cursorPos then + (* if end of string is before cursor *) + buildTextStringBeforeCursor + ( 0, hd, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx, cursorPos + ) + else + (* if within cursor *) + buildTextStringWithinCursor + ( 0, hd, acc, posX, posY, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx, cursorPos + ) + | [] => acc + fun build - (startLine, lineGap: LineGap.t, windowWidth, windowHeight) = + (startLine, cursorPos, lineGap: LineGap.t, windowWidth, windowHeight) = let val lineGap = LineGap.goToLine (startLine, lineGap) - val {rightStrings, rightLines, line = curLine, ...} = lineGap + val {rightStrings, rightLines, line = curLine, idx = curIdx, ...} = lineGap val acc = case (rightStrings, rightLines) of @@ -172,14 +375,24 @@ struct end else 0 + + val absIdx = curIdx + startIdx + + val f = + if cursorPos < curIdx + String.size rStrHd then + (* if cursor is within string *) + buildTextStringWithinCursor + else + (* if cursor is after string *) + buildTextStringBeforeCursor in - buildTextStringAfterCursor + f ( startIdx, rStrHd, [] , 5, 5, 5 , windowWidth, windowHeight , Real32.fromInt windowWidth, Real32.fromInt windowHeight , 0.67, 0.51, 0.83 - , rStrTl + , rStrTl, absIdx, cursorPos ) end | (_, _) => diff --git a/shf b/shf index a341148..aa5e930 100755 Binary files a/shf and b/shf differ