[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Using TeminalScreen.class to move cursor


Why would you not just use the absolute position escape sequence after calculating the needed position from your text buffer?

'\e[vpos;hposH'

or move n pos left or right

'\e[nspacesD'  '\e24D' or '\e[nspacesC' '\e2C'

Maybe I don't understand, But it seems correct to not be moving the cursor around bit by bit, but just put it where you want.

Select Case iCode
      Case Key.Up
        sText = If(.AppCursorKey, "\eOA", subst("\e[&1A",len))
      Case Key.Down
        sText = If(.AppCursorKey, "\eOB", subst("\e[&1B",len))
      Case Key.Right
        sText = If(.AppCursorKey, "\eOC", subst("\e[&1C",len))
      Case Key.Left
        sText = If(.AppCursorKey, "\eOD", subst("\e[&1D",len))
    End Select

'sText = String(Len, sText)

On 4/5/24 17:52, Bruce Steers wrote:
Finally got something working...
This CtrlMove function is called with Key.Code as argument if Ctrl key + Arrow key is hit.
Left and right moves to previous/next white space
Up and Down moves cursor up or down lines.

The CtrlMove function is dirty and my code probably sucks but at least the MoveCursor function now works, the terminalview updates it's cursor position okay this way.

Please feel free to suggest/implement a better method :)


Public Sub MoveCursor(iCode As Integer, Optional Len As Integer = 1)

  Dim sText As String

  Select Case iCode
    Case Key.Up
      sText = String(TerminalView1.ScreenWidth, "\e[D")
    Case Key.Down
      sText = String(TerminalView1.ScreenWidth, "\e[C")
    Case Key.Right
      sText = "\e[C"
    Case Key.Left
      sText = "\e[D"
  End Select

  sText = String(Len, sText)

  Dim hProcess As Stream = TerminalView1.GetOutputStream()
  If TerminalView1._OutputTimer().Enabled Then TerminalView1._OutputTimer().Trigger

  Wait

  If hProcess Then
    Print #hProcess, sText;
  Endif

  TerminalView1.ResetStart()

End


Public Sub CtrlMove(KeyCode As Integer)

  If KeyCode = Key.Up Or If KeyCode = Key.Down Then
    MoveCursor(KeyCode)
    Return
  Endif

  Dim iDist As Integer
  Dim iFind As Integer
  Dim sLine As String = GetCommand()  ' get current command line string
  Dim iAbove As Integer = TerminalView1.Count - 1 - TerminalView1.Line  ' how many lines above the EOL is the cursor

  ' get command line text position relevant to cursor pos
  Dim iPos As Integer = TerminalView1.Column - Me.PromtLen + ((sLine.Len \ TerminalView1.ScreenWidth) * TerminalView1.ScreenWidth)
  iPos -= (iAbove * TerminalView1.ScreenWidth)
  iPos = Max(0, Min(sLine.Len, iPos))

  If KeyCode = Key.Left Then
    iFind = RInStr(sLine, " ", Max(1, iPos - 1))
    If iPos > 0 And If iFind > 0 Then
      iDist = iPos - iFind + 1
    Else
      iDist = iPos
    Endif
  Else
    iFind = InStr(sLine, " ", iPos + 2)
    If iFind > 0 Then
      iDist = iFind - iPos - 1
    Else
      iDist = Max(0, sLine.Len - iPos)
    Endif
  Endif

  MoveCursor(KeyCode, iDist)

End

Pretty odd that the terminalview cannot realize position change when just using TerminalView.Print() though. Also this way if the cursor is on Column 0 moving left will go up to the end of the previous line (just like pressing left key), when using TerminalView.Print() the left escape would only go left and not go up to previous line.
Respects
BruceS


On Sat, 30 Mar 2024 at 23:26, Bruce Steers <bsteers4@xxxxxxxxx> wrote:



    On Sat, 30 Mar 2024 at 09:31, Benoît Minisini
    <benoit.minisini@xxxxxxxxxxxxxxxx> wrote:

        Le 30/03/2024 à 02:40, Bruce Steers a écrit :
        > If i move the cursor by using TerminalScreen what am i
        missing to update
        > the view?
        >
        > For example this code...
        >
        > Public Sub btnMoveLeft_Click()
        >
        >    TerminalView1._GetCurrentScreen().CursorLeft()
        >
        > End
        >
        > That moves the cursor left , if the cursor was initially at
        eol then if
        > i use the keyboard to go right the terminal thinks i am at
        eol still and
        > blinks and does not move.
        >
        > So either i need a way to move the cursor that updates the
        terminal
        > properly/correctly
        > or i need to update it manually after the position move.
        >
        > Can't figure out what i'm missing in how the terminalview works.
        >
        > (yes i know i'm tinkering with a hidden function of the
        internal API ,
        > but i couldn't find any other way, so how must I do it
        properly?)
        >
        > Cheers for any info/solutions
        > BruceS
        >

        You must use the 'TerminalView.Print()' method and send VT-100
        escape
        codes if you want to move the cursor.

        Regards,

-- Benoît Minisini.


    That was the first method i tried. (i studied VT100 class InputTo
    to get the escape chars I used)
    But I get the same result. using TerminalView1.Print("\e[D")

    This is my code...
    It is used to move the cursor and stop at a space if I'm holding
    Ctrl key when hitting an arrow key.
    the cursor goes left just fine but then i cannot move it right
    unless i use Ctrl key again and Key.Right to run my code
    If i press right key with no Ctrl then it flashes like i'm still
    at end of line.

    I need to tell the terminalview of the position change (i just
    can't figure out the workaround)
    Or a better way to trigger a left/right move

    Respects
    BruceS

    Public Sub TerminalView1_KeyPress()

      If Key.Control Then
        If Key.Code = Key.Left Then
          GotoSpace(True)
        Else If Key.Code = Key.Right Then
          GotoSpace
        Endif
      Endif

    End

    Public Sub IsWordChar(C As String) As Boolean

      If Len(C) = 1 Then
        If IsLetter(C) Or If IsDigit(C) Then Return True
        If InStr(":./_", C) Then Return True  ' don't stop at these chars
      Else
        Return
      Endif

    End

    Public Sub MoveCursor(iCode As Integer, Optional Len As Integer = 1)

      Dim sText As String

      With TerminalView1._GetCurrentScreen()

        Select Case iCode
          Case Key.Up
            sText = If(.AppCursorKey, "\eOA", "\e[A")
          Case Key.Down
            sText = If(.AppCursorKey, "\eOB", "\e[B")
          Case Key.Right
            sText = If(.AppCursorKey, "\eOC", "\e[C")
          Case Key.Left
            sText = If(.AppCursorKey, "\eOD", "\e[D")
        End Select
      End With

      sText = String(Len, sText)
      If sText Then TerminalView1.Print(sText)

    End

    Public Sub GotoSpace(Optional GoLeft As Boolean)

      Dim iPrompt As Integer = FindPromptLine()
      Dim sChar As String
      Dim bWordChar As Boolean
      Dim bStartIsWordChar As Boolean = IsWordChar(TerminalView1.CharAt())

      Do
        If GoLeft Then
          If TerminalView1.Line = iPrompt And If TerminalView1.Column
    = Me.PromtLen Then Return
          If TerminalView1.Column = 0 Then
            MoveCursor(Key.Up)
            MoveCursor(Key.Right, TerminalView1.ScreenWidth)
          Endif
          MoveCursor(Key.Left)
        Else
          If TerminalView1.Line = TerminalView1.Count - 1 And If
    TerminalView1.Column = TerminalView1.GetLineLength() Then Return
          If TerminalView1.Column = TerminalView1.ScreenWidth - 1 Then
            MoveCursor(Key.Left, TerminalView1.ScreenWidth)
            MoveCursor(Key.Down)
          Endif
          MoveCursor(Key.Right)
        Endif

        sChar =
    TerminalView1._GetCurrentScreen().Lines[TerminalView1.Line].Text[TerminalView1.Column]
        bWordChar = IsWordChar(sChar)

        If Not bStartIsWordChar And If bWordChar Then
          bStartIsWordChar = True
          Continue
        Else If bStartIsWordChar And If Not bWordChar Then
          Break
        Endif

        If TerminalView1.Line < iPrompt Then Break
        If TerminalView1.Line = iPrompt And If TerminalView1.Column =
    Me.PromtLen Then Break
        If TerminalView1.Line >= TerminalView1.Count - 1 And If
    TerminalView1.Column >= TerminalView1.GetLineLength() - 1 Then Break
      Loop

      TerminalView1.Refresh

    End

--
~~~~ Brian

Attachment: OpenPGP_0x78BFB26402F48419.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature


Follow-Ups:
Re: Using TeminalScreen.class to move cursorBruce Steers <bsteers4@xxxxxxxxx>
References:
Re: Using TeminalScreen.class to move cursorBruce Steers <bsteers4@xxxxxxxxx>