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

Re: Using TeminalScreen.class to move cursor


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
>

Follow-Ups:
Re: Using TeminalScreen.class to move cursorBrian G <brian@xxxxxxxxxxxxxxxx>