Richtext Cursor position

New to Gambas? Post your questions here. No question is too silly or too simple.
Post Reply
seany
Posts: 32
Joined: Friday 6th December 2019 3:09pm

Richtext Cursor position

Post by seany »

I am using a qt5 TextEdit in Gambas3 for rich text.

Please consider the code:
Dim cursorpos As Integer

  If Key.Code = Key.Left Or Key.Code = Key.Up Or Key.code = Key.Right Or Key.Code = Key.Down Or Key.Code = Key.Delete Or Key.Code = Key.Backspace Then
    
    cursorpos = TextEdit1.Pos ' just pick the position
    Print cursorpos
    
  Else 
    cursorpos = TextEdit1.Pos
    Print cursorpos
    TextEdit1.RichText = "<font color = \"#224444\">" & Replace(TextEdit1.Text, gb.NewLine, "<br>") & "</font>" ' this updates the HTML color of the newly added character, preserves the newlines, and replaces them with a <br> for the rich text
    Print "setting : ", cursorpos ' prints the correct value
    TextEdit1.Pos = cursorpos ' does not work
    Print "got : ", TextEdit1.Pos ' jumps to the end of the string
  Endif
Now, I write :
This si a line
this is a second line
I have a typo on the first line. I use my arrow key to get there. I hit backspace twice, and remove the word
si
. All good. Now I expect to type in the character i, and the cursor should stay just after the character i. But as soon as the i is typed in the correct position, the cursor jumps to the end of the text.

Please help. How can I keep the cursor position in the correct place? Thank you.
User avatar
BruceSteers
Posts: 1521
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Richtext Cursor position

Post by BruceSteers »

Okay, oddly it works as expected when you save the TextEdit.Pos but recall it as TextEdit.Index

also you must note the following...

You are doing the processing in the KeyPress event handler, this is an intercept to the controls own Keypress event that inputs characters, the TextEdit1_Keypress you enter happens "BEFORE" the code is inserted.

so all your functions happen then after that the key you pressed is inserted.

Consider the following changes, in this event handler I manually input the key text then use Stop Event to stop the TextEdit control doing it after...

Public Sub TextEdit1_KeyPress()

  Dim cursorpos As Integer
 
  If Key.Code = Key.Left Or Key.Code = Key.Up Or Key.code = Key.Right Or Key.Code = Key.Down Or Key.Code = Key.Delete Or Key.Code = Key.Backspace Then
     
    cursorpos = TextEdit1.Pos ' just pick the position
    Print cursorpos
     
  Else 
  If Not Key.Text Then Return    ' if key was not a text key then do nothing.

   cursorpos = TextEdit1.Pos + 1 ' Record cursor pos and advance it as text will be interted.
    Print cursorpos

    TextEdit1.Insert(Key.Text) ' insert manually the key text now.

    TextEdit1.RichText = "<font color = \"#FF4444\">" & Replace(TextEdit1.Text, gb.NewLine, "<br>") & "</font>" ' this updates the HTML color of the newly added character, preserves the newlines, and replaces them with a <br> for the rich text
    Print "setting : "; cursorpos ' prints the correct value

    TextEdit1.Index = cursorpos ' Recall pos using .Index not .Pos does work
    Print "got : "; TextEdit1.Pos ' jumps to the end of the string

    Stop Event ' IMPORTANT use Stop Event to stop the Key character going in again
  Endif

End


I don't understand the control fully but having a Pos and an Index probably is to do with how there is hidden html code so the visible position in colored text will not be the same as the actual position.

Hope that helps.
If at first you don't succeed , try doing something differently.
BruceS
User avatar
BruceSteers
Posts: 1521
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Richtext Cursor position

Post by BruceSteers »

PS. you have a bit more coding to do if you only want the newly inputted characters to be a different colour.

you TextEdit.RichText line starts with the colour setting so ALL text will be that color
If at first you don't succeed , try doing something differently.
BruceS
User avatar
BruceSteers
Posts: 1521
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Richtext Cursor position

Post by BruceSteers »

I did some investigating.

Seems the magic property is TextEdit1.Selection.RichText

Note that TextEdit.Text has NO html formatting so any time you use
TextEdit.RichText = Replace(TextEdit.Text,"\n", "<br>") you remove all other html code.

Setting TextEdit.Selection.RichText property works like a .InsertRichText()

Consider this Keypress event...

Private $bRemoving As Boolean

Public Sub TextEdit1_KeyPress()

  If Key.Code = key.Delete Or If Key.Code = Key.Backspace Then 
    $bRemoving = True

  Else If Key.Text Then
    If $bRemoving Then
      $bRemoving = False
      TextEdit1.Selection.RichText = "<font color=red>" & Key.Text & "</font>"
      Stop Event
    Endif
  Endif

End
How that works...
If delete or backspace is pressed it sets a global variable $bRemoving boolean to true
then when a Text key is pressed if the $bRemoving boolean is true it inserts the font color code and the key (using TextEdit.Selection.RichText) and sets $bRemoving to false again.
This puts the text you are typing inside the <font> declaration so all text typed there will be red.

Hope that helps.
If at first you don't succeed , try doing something differently.
BruceS
User avatar
BruceSteers
Posts: 1521
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Richtext Cursor position

Post by BruceSteers »

I've attached your source modified with the above keypress event

I also set the forms Arrangement property to Arrange.Vertical and .TextEdit1.Expand removed the need for your manual arrangement in the Resize event (Like Cogier said you should experiment with form layouts Panel.Arrangement properties/.Expand/.Margin/.Spacing)

I also added a color button that will change the color of the selected text to show you how to use some features like how to convert a gambas integer color value into R,G,B hex strings for html.

  Dim R, G, B As String
  R = Hex(Lsr(Last.Value, 16) And &HFF, 2)
  G = Hex(Lsr(Last.Value, 8) And &HFF, 2)
  B = Hex(Last.Value And &HFF, 2)
  ' setting Selection will overwrite current selection so no need to clear it.
  TextEdit1.Selection.RichText = Subst("<font color=#&1&2&3>&4</font>", R, G, B, TextEdit1.Selection.Text)



PS.
I'm pretty sure i was wrong about .Pos and .Index relating to the Text/RichText stuff.

If you use the following code somewhere...
Debug TextEdit1.Text
Debug TextEdit1.RichText
Debug TextEdit1.Pos;; TextEdit1.Index


You will see that Text and RichText properties are very different and the Pos .Index etc don't have much to do with the RichText.

PPS. I found setting .Background property worked just fine. (the app sets it to white on Form_Open() )

Hopefully this will help you :)
Attachments
src-1.0.2.tar.gz
(12.49 KiB) Downloaded 115 times
If at first you don't succeed , try doing something differently.
BruceS
seany
Posts: 32
Joined: Friday 6th December 2019 3:09pm

Re: Richtext Cursor position

Post by seany »

Hello
This si absolutely fantastic. Thank you
:D :D
Post Reply