Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Word Processor Using Single String
#1
Most of the WP stuff I made decades ago required a lot of emphasis on saving memory, so a gigantic doc, as a single string, was not in the cards back then. At one point I made a single string version, but rather than dig through the last 8 years of crap quality work, I decided to have some fun and start a new build.

So this is the fundamentals without text highlighting. It has _Resize to squish or expand the page width. If you REM out the included test string, you can run it with whatever you have stored to your clipboard.

Right now, it is in bruit force mode, meaning it does a rewrap for every key press. I'll modify it to only wrap when needed, place it into subs, and switch over to UDTs at some point.

Use the Insert key to switch from insert to overwrite mode. All other WP keys to control the cursor, page keys, home end, Ctrl+Home, Ctrl+End, etc. are included. Enter key for paragraph.

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
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
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

Mardi Gras was fun, but it's good to be back home again. Hey, guess who I bumped into? https://qb64phoenix.com/forum/showthread.php?tid=4491

Pete
Reply
#2
Hi Pete, testing your WP I noticed when the text exceeds the box at bottom and automatically shifts the newest word down, the cursor moves to the left edge of the box NOT to the expected end of the new text line. Not a bad editor for LOC amount it might work in Multi-Line Textbox for GUI.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#3
Hi Mark,

That was working until I changed something else, which threw it off. WP routines can get a lot like herding cats. Anyway, I had to change out a routine to get both conditions working.

I need to figure out a scroll method for the times Ctrl + arrow left/right crosses multiple spaces. I have a concept ready for that one, but I don't want it to create another cat stampede! When that gets finalized, I think this phase 1 part is done. I simply edited the previous code and will continue to do so until phase 1 is completed.

Thanks and +1

Pete
Shoot first and shoot people who ask questions, later.
Reply
#4
Okay, on to Phase II...

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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  b+ String Math Update bplus 31 5,174 04-11-2025, 11:56 AM
Last Post: bplus
  I'm adding SQR to my new faster string math routines... Pete 17 3,309 04-01-2025, 04:56 PM
Last Post: Pete
  word wrap + action words! SMcNeill 3 971 03-04-2024, 11:35 PM
Last Post: bplus
  Word Game Assistant PhilOfPerth 2 753 11-18-2023, 04:11 PM
Last Post: TerryRitchie
  Font from a string pattern - help needed grymmjack 22 4,948 08-27-2023, 07:26 PM
Last Post: grymmjack

Forum Jump:


Users browsing this thread: