Page 1 of 1

Color one line in a scintilla gadget

Posted: Thu Apr 13, 2023 7:40 pm
by jacdelad
Hello,
I'm totally new to Scintilla. I need it for an editor field that shows me where an error is within a text file (which I cannot autocorrect). How do I color a single line in another color? I'm reading through the online documentation, but it's a lot of stuff and I don't know which is the right way: using a style or, which I suspect, using an indicator?

Code: Select all

If OpenWindow(0, 0, 0, 330, 90, "ScintillaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If InitScintilla()
    ScintillaGadget(0, 10, 10, 320, 70, 0)
    *Text = UTF8("This is a simple ScintillaGadget with text..."+#LF$+"More text"+#LF$+"Even more text!")
    ScintillaSendMessage(0, #SCI_SETTEXT, 0, *Text)
    FreeMemory(*Text)
  EndIf
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Slightly modified source from the help. Help with coloring or somehow highlighting the second line would be appreciated (finally I need to highlight several lines, but I guess I will understand it from doing it with one).

Re: Color one line in a scintilla gadget

Posted: Thu Apr 13, 2023 9:22 pm
by spikey
Every character position in a scintilla gadget 'points' to two values, the first is the two byte UTF character code as you might expect. The second is a single byte style code which defines the position in a table of visual styles to apply to the character. The table contains the details of the style in terms of font, size, colour. So the first thing to do is define a style table for all the styles you wish to use and the second is to apply the style bytes to the characters in the ranges you wish to show in a specific style. When you load a file/first set the text in the gadget everything gets the default style 0.

This example loads a sample source and styles all the comments with a different colour (the cyan from the IDE's default scheme). It shows all the processes above and how to search too. I don't have an example for using indicators to hand at the moment.

Code: Select all

#File = 0
#Window = 0
#Gadget = 0

#StyleBody = 0
#StyleComment = 1

; Initialize the Scintilla library.
If InitScintilla() = 0
  Debug "Couldn't initialize the Scintilla library."
EndIf

Define OriginalFile.s = #PB_Compiler_Home + "Examples\Sources\Window.pb"
Define TextSize.l, Size.l, CharPosition.l, EndPosition.l, LineNum.l

Size = FileSize(OriginalFile)

If OpenWindow(#Window, 20, 20, 800, 600, "ScintillaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ScintillaGadget(#Gadget, 10, 10, 780, 580, #Null)
  
  ; Define two style colors, one for the body text and one for comment lines.
  ScintillaSendMessage(#Gadget, #SCI_STYLESETFORE, #StyleBody, #Black)
  ScintillaSendMessage(#Gadget, #SCI_STYLESETFORE, #StyleComment, 11184640)
  
  ; Read the source file.
  *Buffer = AllocateMemory(Size + 2)
  ReadFile(#File, OriginalFile)
  ReadData(#File, *Buffer, Size)
  ScintillaSendMessage(#Gadget, #SCI_SETTEXT, #Null, *Buffer)
  FreeMemory(*Buffer) 
  
  ; Prepare for a search.
  *Buffer = UTF8(";")
  TextSize = ScintillaSendMessage(#Gadget, #SCI_GETLENGTH)
  ScintillaSendMessage(#Gadget, #SCI_SETTARGETSTART, 0)
  ScintillaSendMessage(#Gadget, #SCI_SETTARGETEND, TextSize)
  
  ; Repeat until ; is not found.
  Repeat 
    CharPosition = ScintillaSendMessage(#Gadget, #SCI_SEARCHINTARGET, 1, *Buffer)
    If CharPosition <> #INVALID_POSITION
      ; Determine the position of the end of line, and the length to style.
      LineNum = ScintillaSendMessage(#Gadget, #SCI_LINEFROMPOSITION, CharPosition)
      EndPosition = ScintillaSendMessage(#Gadget, #SCI_GETLINEENDPOSITION, LineNum)
      Size = EndPosition - CharPosition
      ; Change the style.
      ScintillaSendMessage(#Gadget, #SCI_STARTSTYLING, CharPosition)
      ScintillaSendMessage(#Gadget, #SCI_SETSTYLING, Size, #StyleComment)
      ; Update the search start position.
      ScintillaSendMessage(#Gadget, #SCI_SETTARGETSTART, EndPosition)
      ScintillaSendMessage(#Gadget, #SCI_SETTARGETEND, TextSize)
    EndIf
    
  Until CharPosition = #INVALID_POSITION
  FreeMemory(*Buffer) 
  
EndIf

Repeat  
Until WaitWindowEvent(500) = #PB_Event_CloseWindow

Re: Color one line in a scintilla gadget

Posted: Fri Apr 14, 2023 12:07 pm
by AZJIO

Code: Select all

#num_indicator = 1

If OpenWindow(0, 0, 0, 330, 90, "ScintillaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	If InitScintilla()
		ScintillaGadget(0, 10, 10, 320, 70, 0)
		*Text = UTF8("This is a simple ScintillaGadget with text..." + #LF$ + "More text" + #LF$ + "Even more text!")
		ScintillaSendMessage(0, #SCI_SETTEXT, 0, *Text)
		FreeMemory(*Text)

		ScintillaSendMessage(0, #SCI_INDICSETSTYLE, #num_indicator, #INDIC_STRAIGHTBOX) ; first indicator style 8 (0-19)
		ScintillaSendMessage(0, #SCI_INDICSETFORE, #num_indicator, #Red)    ; first indicator color red
		ScintillaSendMessage(0, #SCI_SETINDICATORCURRENT, #num_indicator, #INDIC_STRAIGHTBOX) ; makes the indicator current
		ScintillaSendMessage(0, #SCI_INDICSETUNDER, #num_indicator, 1) ; indicator below the text, does not obscure it
		ScintillaSendMessage(0, #SCI_INDICSETALPHA, #num_indicator, 127) ; Transparency
; 		ScintillaSendMessage(0, #SCI_INDICGETOUTLINEALPHA, #num_indicator, 255) ; Transparency
		
		nLine = 1 ; line number starts from 0
		start = ScintillaSendMessage(0, #SCI_POSITIONFROMLINE, nLine, 0)
		length = ScintillaSendMessage(0, #SCI_GETLINEENDPOSITION, nLine, 0) - start
		ScintillaSendMessage(0, #SCI_INDICATORFILLRANGE, start, length) ; start and length
; 		ScintillaSendMessage(0, #SCI_INDICATORFILLRANGE, 46, 9)   ; start and length
	EndIf
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Color one line in a scintilla gadget

Posted: Fri Apr 14, 2023 12:38 pm
by jacdelad
Ah, thank you both. This is a great start for me. There are still many open questions, but I'll try to figure this out on myself first.