02-28-2026, 12:07 AM
Okay, on to Phase II...
So now we need to teach our code to recognize when a word wrap event will take place. This avoids re-indexing our document every time a key is pressed.
This start of Phase II onlly includes non-paragraph documents. I'll work on how paragraphs are handled next, and update this post when that part is completed. For now, any non-paragraph document should produce a beep sound when it wraps. If it wraps without a sound, it means another condition needs to be addressed.
Pete
Code: (Select All)
$Resize:On
Width 60, 35: _Font 16
t.mt = 3: t.ml = 4: t.mr = t.ml + 19: t.mb = t.mt + 4
t.pw = t.mr - t.ml + 1: total = Len(new$): DisplayHeight = t.mb - t.mt + 1
If Len(_Clipboard$) Then new$ = _Clipboard$
ReDim track(0), eol(0)
GoSub skin
CurStyle = 7
Do
ReDim map(DisplayHeight) As String: For i = 1 To DisplayHeight: map(i) = String$(t.ml - 1 + t.pw, Chr$(0)): Next
If Not scroll Then ReDim track(0), eol(0): index = 0: TextLines = 0: a = 1: DisplayOnScreen = 0: total = Len(new$) Else index = t.scr
CurShow = 0: Locate , , CurShow
Do
index = index + 1
If Not scroll Then
If TextLines >= t.scr And DisplayOnScreen = 0 Then DisplayOnScreen = -1
If InStr(Mid$(new$, a, t.pw + 1), Chr$(13)) Then
q = 2: c = a: para$ = Chr$(20)
x1$ = Mid$(new$, a, InStr(Mid$(new$, a, t.pw + 1), Chr$(13)) - 1)
Else
If Right$(Mid$(new$, a, t.pw + 1), 1) = " " And t.pw > 1 Then q = 1 Else q = 0
x1$ = Mid$(new$, a, t.pw): c = a
End If
If q Or a + t.pw > total Then
If a + Len(x1$) + q > total Then q = -1: Else a = a + Len(x1$) + q
Else
If _InStrRev(x1$, " ") Then x1$ = Mid$(x1$, 1, _InStrRev(x1$, " "))
a = a + Len(x1$)
End If
TextLines = TextLines + 1
ReDim _Preserve track(TextLines + 1), eol(TextLines + 1)
track(TextLines) = c: eol(TextLines) = Len(x1$)
Else
If UBound(track) < t.scr + 1 + cnt Then ReDim _Preserve track(t.scr + 1 + cnt + 1), eol(t.scr + 1 + cnt + 1)
x1$ = Mid$(new$, track(t.scr + 1 + cnt), eol(t.scr + 1 + cnt))
If Mid$(new$, track(t.scr + 1 + cnt) + eol(t.scr + 1 + cnt), 1) = Chr$(13) Then para$ = Chr$(20)
DisplayOnScreen = -1
End If
s$ = String$(t.pw, 0): Mid$(s$, 1) = x1$
If CurReplaceArray Then
If Len(para$) Then k = 1 Else k = 0
If track(index) - 1 + eol(index) + k >= CurReplaceArray Or q = -1 And DisplayOnScreen < 0 Then ' q = -1 handles deleting from the end of the text.
If cnt = 0 And DisplayOnScreen = 0 Then DisplayOnScreen = -1: t.scr = index - DisplayHeight
If DisplayOnScreen < 0 Then
yy = t.mt - 1 + cnt + 1: xx = t.ml + CurReplaceArray - track(index): CurReplaceArray = 0
If ParaRemoved And xx = t.ml And Mid$(new$, track(row - 1), 1) = Chr$(13) Then autokey$ = Chr$(0) + "H|" + Chr$(0) + "O"
End If
End If
End If
If DisplayOnScreen < 0 Then
cnt = cnt + 1
Mid$(map(cnt), 1) = x1$ + para$ ' Map may be 1 column longer if it ends in a paragraph.
Locate t.mt - 1 + cnt, t.ml, CurShow, 7, CurStyle: Print s$;
If cnt = DisplayHeight Or scroll And cnt = TextLines Then
DisplayOnScreen = 1: If scroll Then q = -1
End If
End If
para$ = ""
Loop Until q = -1
If DisplayOnScreen <> 1 Then For i = 0 To t.mb - t.mt - cnt: Locate t.mt + cnt + i, t.ml, CurShow, 7, CurStyle: Print Space$(t.pw);: Next: DisplayOnScreen = 1
track(TextLines + 1) = Len(new$) + 1: eol(TextLines + 1) = 0
j = 0: q = 0: x1$ = "": cnt = 0: scroll = 0: hh = 0: para$ = "": ParaRemoved = 0
CurShow = 1: j = 0: GoSub Place_Cursor
Do
If _Resize Then
If initiate Then
If _ResizeWidth \ _FontWidth > _Width And _Width < 150 Then t.mr = t.mr + 1: t.pw = t.mr - t.ml + 1: Width _Width + 1, _Height: _Font 16: GoSub skin: Exit Do
If _ResizeWidth \ _FontWidth < _Width Then
If t.mr - t.ml > 0 Then
t.mr = t.mr - 1: t.pw = t.mr - t.ml + 1: Width _Width - 1, _Height: _Font 16: GoSub skin: Exit Do
End If
End If
End If
initiate = 1
End If
_Limit 60
GoSub keyboard
If Len(b$) Then Exit Do
Loop
yy = CsrLin: xx = Pos(0)
Loop
keyboard:
While _MouseInput: m.mw = m.mw + _MouseWheel: Wend
m.x = _MouseX
m.y = _MouseY
m.lb = _MouseButton(1)
m.rb = _MouseButton(2)
If m.mw Then
If m.mw > 0 Then b$ = Chr$(0) + "P" Else b$ = Chr$(0) + "H"
m.mw = 0
Else
If Len(autokey$) Then
If InStr(autokey$, "|") Then b$ = Mid$(autokey$, 1, InStr(autokey$, "|") - 1): autokey$ = Mid$(autokey$, InStr(autokey$, "|") + 1) Else b$ = autokey$: autokey$ = ""
Else
b$ = InKey$
End If
End If
If Len(b$) Then
up$ = Mid$(new$, track(row - 1), eol(row - 1))
down$ = Mid$(new$, track(row + 1), eol(row + 1)): If row + 1 = TextLines And Len(down$) And Right$(down$, 1) <> " " Then down$ = down$ + " "
j = 0: row = yy + t.scr - (t.mt - 1): xxEOL = t.ml - 1 + eol(row)
Select Case b$
Case Chr$(27): System
Case Chr$(13) ' Paragraph.
t = track(yy - (t.mt - 1) + t.scr): t = t + xx - (t.ml - 1) - 1
new$ = Mid$(new$, 1, t - 1) + Chr$(13) + Chr$(10) + Mid$(new$, t)
TextLines = TextLines + 1: ReDim _Preserve track(TextLines + 1), eol(TextLines + 1)
autokey$ = Chr$(0) + "P" + "|" + Chr$(0) + "G"
Case Chr$(32) To Chr$(126)
t = track(row) + xx - (t.ml - 1) - 1
If t > total Or ovw = 0 Or ovw And Mid$(new$, t, 1) = Chr$(13) Then
new$ = Mid$(new$, 1, t - 1) + b$ + Mid$(new$, t)
Else ' Overwrite within text.
Mid$(new$, t, 1) = b$
End If
If xx > t.mr And yy = t.mb Then t.scr = t.scr + 1 ' Forces scroll down to next line.
If yy = t.mt And t.scr > 0 And DisplayHeight > 2 Then t.scr = t.scr - 1
If yy = t.mb And t.scr + DisplayHeight < TextLines And DisplayHeight > 1 Then t.scr = t.scr + 1
GoSub Cursor_Relocate: autokey$ = Chr$(0) + "M"
Case Chr$(8)
If row > 1 Or row = 1 And xx > t.ml Then autokey$ = Chr$(0) + "K|" + Chr$(0) + "S"
Case Chr$(0) + "S" ' Delete.
GoSub Cursor_Relocate
If Mid$(new$, CurReplaceArray, 1) = Chr$(13) Then k = 1 Else k = 0
new$ = Mid$(new$, 1, CurReplaceArray - 1) + Mid$(new$, CurReplaceArray + k + 1)
If yy = t.mt And t.scr > 0 And DisplayHeight > 2 Then t.scr = t.scr - 1
If yy = t.mb And t.scr + DisplayHeight < TextLines And DisplayHeight > 1 Then t.scr = t.scr + 1
If k Then ParaRemoved = -1: k = 0
Case Chr$(0) + "I" ' PgUp.
t.scr = t.scr - (DisplayHeight - 1): If t.scr < 0 Then t.scr = 0
If xx - (t.ml - 1) > eol(row) Then autokey$ = Chr$(0) + "O"
Case Chr$(0) + "Q" ' PgDn.
t.scr = t.scr + (DisplayHeight - 1): If t.scr + DisplayHeight > TextLines Then t.scr = TextLines - DisplayHeight
If xx - (t.ml - 1) > eol(row) Then autokey$ = Chr$(0) + "O"
Case Chr$(0) + "s" ' Ctrl + Arrow Lt.
k = track(row) - 1 + xx - (t.ml - 1) - 1: i = 0
If Mid$(new$, k, 1) = Chr$(10) Then
autokey$ = Chr$(0) + "K"
Else
Do Until k = 0
t$ = Mid$(new$, k, 1): If i = 0 And t$ > Chr$(32) Then i = 1
If i Then
If t$ = " " Then k = k + 1: Exit Do
If t$ = Chr$(13) Then k = k + 2: Exit Do
End If
k = k - 1
Loop
If k Then
CurReplaceArray = k
Do
If CurReplaceArray >= track(t.scr + 1) Then Exit Do Else t.scr = t.scr - 1
Loop
Else
autokey$ = Chr$(0) + "w"
End If
End If
k = 0: h = 0: i = 0: t$ = ""
Case Chr$(0) + "t" ' Ctrl + Arrow Rt.
k = track(row) - 1 + xx - (t.ml - 1): h = 0
If k < total Then
Do
t$ = Mid$(new$, k, 1): If t$ = " " Or t$ = Chr$(13) Then h = Asc(t$)
If t$ <> " " And h Then Exit Do Else k = k + 1
Loop Until k = total
If h = 13 And k = track(row) - 1 + xx - (t.ml - 1) Then
autokey$ = Chr$(0) + "M" ' Move off a paragraph. Do not use k + 2 here as it will jump a paragraph with terminal paragraph/paragraph/paragraph format.
Else
If k = total Then
autokey$ = Chr$(0) + "u"
Else
CurReplaceArray = k
If DisplayHeight >= TextLines Then k = TextLines Else k = t.scr + DisplayHeight
Do
If t.scr < TextLines - DisplayHeight And CurReplaceArray >= track(k) + eol(k) Then t.scr = t.scr + 1: k = k + 1 Else Exit Do
Loop
End If
End If
k = 0: h = 0: t$ = ""
Else
autokey$ = Chr$(0) + "O"
End If
Case Chr$(0) + "w" ' Ctrl + Home.
yy = t.mt: xx = t.ml: j = 0: GoSub Place_Cursor: t.scr = 0
Case Chr$(0) + "u" ' Ctrl + End.
If t.scr + DisplayHeight < TextLines Then
t.scr = TextLines - DisplayHeight: autokey$ = Chr$(0) + "u"
Else
yy = TextLines - t.scr + (t.mt - 1): xx = t.mr + 1: j = -1: GoSub Place_Cursor
autokey$ = Chr$(0) + "P" ' Check for terminal paragraph and ignore if not present.
End If
Case Chr$(0) + "G"
xx = t.ml: GoSub Place_Cursor
Case Chr$(0) + "O"
j = -1: xx = t.mr + 1: GoSub Place_Cursor
Case Chr$(0) + "K"
If xx > t.ml Then
xx = xx - 1: j = 0: GoSub Place_Cursor
Else
If row > 1 Then
tmp$ = Mid$(new$, track(row - 1) + eol(row - 1), 1)
If tmp$ = Chr$(13) Or tmp$ = Chr$(32) And eol(row - 1) = t.pw Then tmp$ = "" Else tmp$ = "|" + Chr$(0) + "K"
If autokey$ = "" Then
autokey$ = Chr$(0) + "H|" + Chr$(0) + "O" + tmp$
Else
autokey$ = Chr$(0) + "H|" + Chr$(0) + "O" + tmp$ + "|" + autokey$ ' Adds Backspace if present.
End If
tmp$ = ""
End If
End If
Case Chr$(0) + "M"
If xx < xxEOL Or xx = xxEOL And row = TextLines Or xx = xxEOL And Mid$(new$, track(row) + t.pw, 1) = " " Or xx = xxEOL And Mid$(new$, track(row) + eol(row), 1) = Chr$(13) Then
If row <= TextLines Then xx = xx + 1: j = 0: GoSub Place_Cursor
Else
If row < TextLines Or row = TextLines And xx > t.mr And Mid$(new$, track(row) + t.pw, 1) = " " Or Mid$(new$, track(row) + eol(row), 1) = Chr$(13) Then ' > occurs when a marginal space is present.
autokey$ = Chr$(0) + "P" + "|" + Chr$(0) + "G"
End If
End If
Case Chr$(0) + "H"
If yy = t.mt Then
If t.scr > 0 Then t.scr = t.scr - 1 Else b$ = ""
Else
yy = yy - 1: j = -1: GoSub Place_Cursor
End If
Case Chr$(0) + "P"
Select Case row
Case Is = TextLines ' Last line only cursors down if text line is full.
If eol(row) = t.pw And Mid$(new$, track(row) + t.pw, 1) = " " Or Mid$(new$, track(row) + eol(row), 1) = Chr$(13) Then
If yy = t.mb Then t.scr = t.scr + 1 Else yy = yy + 1: xx = t.ml
TextLines = TextLines + 1: ReDim _Preserve track(TextLines + 1), eol(TextLines + 1)
track(TextLines) = Len(new$) + 1: eol(TextLines) = 0
j = -1: GoSub Place_Cursor ' Cursor will be placed in home line position.
Else
b$ = "" ' Can't cursor down.
End If
Case Is < TextLines
If yy = t.mb Then t.scr = t.scr + 1 Else yy = yy + 1: j = -1: GoSub Place_Cursor
End Select
Case Chr$(0) + "R"
ovw = Not ovw
If ovw Then CurStyle = 1 Else CurStyle = 7
Case Else: b$ = ""
End Select
If Len(b$) = 2 Then If InStr("KMHPIQGOtsuw", Right$(b$, 1)) Then scroll = -1
Else
If m.y And oldmy <> m.y Or m.x And m.x <> oldmx Or m.lb = -1 Or m.rb = -1 Then
If m.y >= t.mt And m.x <= t.mr + 1 And m.y <= t.mb And m.x >= t.ml Then inside = _TRUE Else inside = _FALSE
If inside = _TRUE Then
If m.lb = -1 Then
y1 = m.y - (t.mt - 1): x1 = m.x - (t.ml - 1)
Rem t = track(y1 + t.scr): t = t + x1 - 1
If Asc(Mid$(map(y1), x1, 1)) Then
yy = m.y: xx = m.x: j = 0: GoSub Place_Cursor
Else
If Asc(Left$(map(y1), 1)) > 0 Then ' Click inside page but beyond text.
yy = m.y: xx = t.mr + 1: j = -1: GoSub Place_Cursor
Else
If t.scr + y1 = TextLines Then ' Last line after a new paragraph was started.
yy = m.y: xx = t.mr + 1: j = -1: GoSub Place_Cursor
End If
End If
End If
End If
End If
End If
End If
oldmy = m.y: oldmx = m.x
change = 0
If b$ >= Chr$(32) And b$ <= Chr$(126) Then
If ovw = 0 Or ovw And xx > xxEOL Or b$ = " " Then change = 1
ElseIf b$ = Chr$(0) + "S" Then change = -1
End If
If change Then
n$ = Mid$(new$, track(row), eol(row) + change)
If Len(n$) > t.pw And Right$(n$, 1) = " " Then TSpace = 1 Else TSpace = 0
If InStr(Mid$(n$, 1, t.pw), Chr$(13)) Then para = 1 Else para = 0
If row = 1 Or InStr(up$, Chr$(13)) Then WrapUp = 0 Else WrapUp = t.pw - Len(up$)
WrapLine = Len(n$)
WrapLead = InStr(n$ + " ", " ") - 1: If WrapLead < 0 Then WrapLead = 0
If para = 0 Then WrapTrail = t.pw - Len(n$) Else WrapTrail = 0
If TextLines > 1 Then WrapDn = InStr(down$, " ") - 1 Else WrapDn = 0
wrap = 0
If WrapLine > t.pw And TSpace = 0 Or TSpace And WrapLine > t.pw + 1 Then
wrap = -1
ElseIf WrapUp And WrapLead > 0 And WrapLead <= WrapUp Then
wrap = -2
ElseIf WrapDn > 0 And WrapDn <= WrapTrail Then
wrap = -3
End If
If wrap Then Sound 1000, .3
s1 = CsrLin: s2 = Pos(0): Locate 20, 1: Print "WrapUp ="; WrapUp, "WrapLead ="; WrapLead; " ";: Locate s2, s2
End If
Return
Place_Cursor:
row = yy + t.scr - (t.mt - 1): xxEOL = t.ml - 1 + eol(row)
If j And xx > xxEOL Then xx = xxEOL + 1
Locate yy, xx, CurShow, 7, CurStyle
j = 0
Return
Cursor_Relocate:
CurReplaceArray = track(row) + xx - (t.ml - 1) - 1
Return
skin:
Locate t.mt - 1, t.ml - 1, 0: Print Chr$(218) + String$(t.mr - t.ml + 1, Chr$(196)) + Chr$(191)
For i = t.mt To t.mb: Locate i, t.ml - 1: Print Chr$(179);: Locate , t.mr + 1: Print Chr$(179);: Next
Locate t.mb + 1, t.ml - 1: Print Chr$(192) + String$(t.mr - t.ml + 1, Chr$(196)) + Chr$(217);
Locate t.mt, t.ml, CurShow, 7, CurStyle: yy = CsrLin: xx = Pos(0)
Return
So now we need to teach our code to recognize when a word wrap event will take place. This avoids re-indexing our document every time a key is pressed.
This start of Phase II onlly includes non-paragraph documents. I'll work on how paragraphs are handled next, and update this post when that part is completed. For now, any non-paragraph document should produce a beep sound when it wraps. If it wraps without a sound, it means another condition needs to be addressed.
Pete

