Color one line in a scintilla gadget

Just starting out? Need help? Post your questions and find answers here.
User avatar
jacdelad
Addict
Addict
Posts: 2030
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Color one line in a scintilla gadget

Post 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).
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
User avatar
spikey
Enthusiast
Enthusiast
Posts: 778
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Color one line in a scintilla gadget

Post 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
AZJIO
Addict
Addict
Posts: 2223
Joined: Sun May 14, 2017 1:48 am

Re: Color one line in a scintilla gadget

Post 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
User avatar
jacdelad
Addict
Addict
Posts: 2030
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Color one line in a scintilla gadget

Post 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.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Post Reply