Richtext Cursor position

Post

Posted
Rating:
#1 (In Topic #859)
Regular
seany is in the usergroup ‘Regular’
I am using a qt5 TextEdit in Gambas3 for rich text.

Please consider the code:

Code (gambas)

  1. Dim cursorpos As Integer
  2.  
  3.   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
  4.    
  5.     cursorpos = TextEdit1.Pos ' just pick the position
  6.     Print cursorpos
  7.    
  8.   Else
  9.     cursorpos = TextEdit1.Pos
  10.     Print cursorpos
  11.     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
  12.     Print "setting : ", cursorpos ' prints the correct value
  13.     TextEdit1.Pos = cursorpos ' does not work
  14.     Print "got : ", TextEdit1.Pos ' jumps to the end of the string
  15.  
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.
Online now: No Back to the top

Post

Posted
Rating:
#2
Guru
BruceSteers is in the usergroup ‘Guru’
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…

Code (gambas)

  1.  
  2. Public Sub TextEdit1_KeyPress()
  3.  
  4.   Dim cursorpos As Integer
  5.  
  6.   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
  7.      
  8.     cursorpos = TextEdit1.Pos ' just pick the position
  9.     Print cursorpos
  10.      
  11.   Else
  12.   If Not Key.Text Then Return    ' if key was not a text key then do nothing.
  13.  
  14.    cursorpos = TextEdit1.Pos + 1 ' Record cursor pos and advance it as text will be interted.
  15.     Print cursorpos
  16.  
  17.     TextEdit1.Insert(Key.Text) ' insert manually the key text now.
  18.  
  19.     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
  20.     Print "setting : "; cursorpos ' prints the correct value
  21.  
  22.     TextEdit1.Index = cursorpos ' Recall pos using .Index not .Pos does work
  23.     Print "got : "; TextEdit1.Pos ' jumps to the end of the string
  24.  
  25.     Stop Event ' IMPORTANT use Stop Event to stop the Key character going in again
  26.  
  27.  
  28.  


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.
Online now: No Back to the top

Post

Posted
Rating:
#3
Guru
BruceSteers is in the usergroup ‘Guru’
 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
Online now: No Back to the top

Post

Posted
Rating:
#4
Guru
BruceSteers is in the usergroup ‘Guru’
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…

Code (gambas)

  1.  
  2. Private $bRemoving As Boolean
  3.  
  4. Public Sub TextEdit1_KeyPress()
  5.  
  6.   If Key.Code = key.Delete Or If Key.Code = Key.Backspace Then
  7.     $bRemoving = True
  8.  
  9.   Else If Key.Text Then
  10.     If $bRemoving Then
  11.       $bRemoving = False
  12.       TextEdit1.Selection.RichText = "<font color=red>" & Key.Text & "</font>"
  13.       Stop Event
  14.     Endif
  15.  
  16.  

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.
Online now: No Back to the top

Post

Posted
Rating:
#5
Guru
BruceSteers is in the usergroup ‘Guru’
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.

Code (gambas)

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

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…

Code (gambas)

  1. Debug TextEdit1.Text
  2. Debug TextEdit1.RichText
  3. Debug TextEdit1.Pos;; TextEdit1.Index
  4.  

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

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#6
Regular
seany is in the usergroup ‘Regular’
Hello
This si absolutely fantastic. Thank you
 :D  :D
Online now: No Back to the top
1 guest and 0 members have just viewed this.