ScintillaGadget() pas à pas

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

ScintillaGadget() pas à pas

Message par falsam »

Scintilla pas à pas

Qu'est ce que Scintilla.
C'est un éditeur de texte survitaminé inclus dans PureBasic avec le gadget ScintillaGadget()

:arrow: https://www.purebasic.com/french/docume ... adget.html

ScintillaSendMessage() permet de prendre le contrôle de l'édition du texte avec par exemple la coloration syntaxique en définissant les différentes couleurs, styles et couleurs d'arrière-plans du texte, les numéros de lignes dans la marge. D'autres composants peuvent être utilisés tels que l'indentation, l’auto complétion et le pliage de texte (ou code) qui permet à l'utilisateur de révéler ou cacher des blocs de texte.

:arrow: https://www.purebasic.com/french/docume ... ssage.html


Téléchargement.
L'ensemble des codes peut être téléchargé depuis la plateforme collaborative GitHub
:arrow: https://github.com/pbcodex/ScintillaGad ... master.zip


Au travail.
Une série de cinq exercices pour mieux appréhender le gadget Scintilla de la mise en place de GadgetScintilla() à la coloration syntaxique pour n'importe quel langage ou mots que vous souhaitez colorer.

Sauf exception comme les bonus, chaque code est structuré en Unités de Traitement (U.T.)

- U.T. Fenêtres, Menu, Gadgets
- U.T. Utilitaires
- U.T. Scintilla
- U.T. Coloration syntaxique

Cliquez sur le tutoriel qui vous intéresse.

Tuto 00 - Mise en place.pb Mise en place du gadget Scintilla.
Tuto 01 - Préliminaire.pb Comment activer la touche TAB et neutraliser les caractères spéciaux.
Tuto 02 - Indentation.pb Indenter le texte par rapport à la position de la ligne précédente.
Tuto 03 - Customisation minimum.pb Couleur du gadget Scintilla et affichage de la numérotation des lignes.
Tuto 04 - Autocompletion.pb Compléter automatiquement le mot que l'utilisateur est en train décrire.
Tuto 05 - Pliage et coloration syntaxique.pb Pliage de code et colorer automatiquement des mots faisant parties d'une liste

Bonus
ScintillaGadget() et le SDK Syntax Highlighting Pourquoi pas un IDE PureBasic sur mesure.


Image


Remerciement.
Merci à cha0s et Eddy (Forum anglophone) pour leurs codes qui m'ont aidés à terminer le tuto 4 et 5.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Tuto 00 - Mise en place.pb

Avec ce code vous allez mettre le gadget Scintilla.

Vous allez pouvoir tapez du texte et zoomer sur le texte avec la combinaison de touche Ctrl + Molette de la souris tout comme dans l'IDE de PureBasic.
Vous allez aussi vous apercevoir que la touche Tab ne fonctionne pas. De même il est possible d'insérer des caractére spéciaux pas forcément désirable comme par exemple Ctrl + G.

Code : Tout sélectionner

;Mise en place du Gadget Scintilla

EnableExplicit

Enumeration Form
  #Mainform
  #StatusBar
EndEnumeration

Enumeration Menu
  #MainMenu  
  #Quit
EndEnumeration

Enumeration Gadget  
  #Editor
EndEnumeration

;-Déclaration variable et procédures 
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

;-Plan de l'application
Declare Start()

Declare MainFormShow() 
Declare MainFormResize()
Declare MainFormClose()

Declare SciCallBack(Gadget, *scinotify.SCNotification)

Start()

;Début
Procedure Start()
  MainFormShow()
  
  BindEvent(#PB_Event_SizeWindow, @MainFormResize(), #MainForm)
  BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
  
  BindMenuEvent(#MainMenu, #Quit, @MainFormClose())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;-
;- U.T. Fenetres, Menu, Gadgets
Procedure MainFormShow()  
  OpenWindow(#MainForm,  0,  0, 1024, 768, "Pure Basic Editor : Mise en place du gadget Scintilla", WindowStyle)
  
  ;Barre de status
  If CreateStatusBar(#StatusBar,WindowID(#Mainform))
    AddStatusBarField(150)
    AddStatusBarField(450) 
  EndIf 
  
  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre 
  SmartWindowRefresh(#Mainform, #True)
  
  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#Quit,"Quitter")
  
  If InitScintilla()
    ;@ScintillaCallBack() est une procédure callback qui recevra  les évènements émis par ScintillaGadget
    ScintillaGadget(#Editor, 10, 40, 1004, 668, @SciCallBack())   
    SetActiveGadget(#Editor)
  EndIf
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-20, WindowHeight(#Mainform)-100)
EndProcedure

Procedure MainFormClose()
  End
EndProcedure

;-
;- U.T. Scintilla
Procedure SciCallBack(Gadget, *scinotify.SCNotification)
  ;Pour le moment rien mais ça va venir :)
EndProcedure
Le code est suffisamment documenter. A vous de vous entraîner :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Scintilla pas à pas

Message par microdevweb »

Merci Falsam,

Cela va m'être très utile pour speeDev.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Tuto 01 - Préliminaire.pb

Nous allons maintenant activer la touche Tab et neutraliser les caractères spéciaux à l'aide des fonctions classiques de PureBasic.

Code : Tout sélectionner

;Activer la touche TAB et neutraliser les caractères spéciaux

EnableExplicit

Enumeration Form
  #Mainform
  #StatusBar
EndEnumeration

Enumeration Menu
  #MainMenu
  #Quit
EndEnumeration

Enumeration Gadget  
  #Editor
EndEnumeration

;-Déclaration variable et procédures 
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

;-Plan de l'application
Declare Start()

Declare MainFormShow() 
Declare MainFormResize()
Declare MainFormClose()

Declare ScintillaCallBack(Gadget, *scinotify.SCNotification)

Start()

;Début
Procedure Start()
  MainFormShow()
  
  BindEvent(#PB_Event_SizeWindow, @MainFormResize(), #MainForm)
  BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
  
  BindMenuEvent(#MainMenu, #Quit, @MainFormClose())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;-
;- U.T. Fenetres, Menu, Gadgets
Procedure MainFormShow()  
  OpenWindow(#MainForm,  0,  0, 1024, 768, "Pure Basic Editor : Préliminaire", WindowStyle)
  
  ;Barre de status
  If CreateStatusBar(#StatusBar,WindowID(#Mainform))
    AddStatusBarField(150)
    AddStatusBarField(450)
  EndIf 
  
  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre 
  SmartWindowRefresh(#Mainform, #True)
  
  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#Quit,"Quitter")
  
  If InitScintilla()
    ;@ScintillaCallBack() est une procédure callback qui recevra  les évènements émis par ScintillaGadget 
    ScintillaGadget(#Editor, 10, 40, 1004, 668, @ScintillaCallBack())   
    SetActiveGadget(#Editor)
  EndIf
  
  ;-Préliminaires 
  
  ;-Neutraliser la touche TAB
  RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
  
  ;-Neutraliser les caractéres spéciaux
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_B, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_G, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_E, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_R, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_O, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_P, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_Q, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_S, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_F, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_H, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_K, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_W, 0)  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_N, 0)
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-20, WindowHeight(#Mainform)-100)
EndProcedure

Procedure MainFormClose()
  End
EndProcedure

;-
;- U.T. Scintilla
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
  ;Pour le moment rien mais ça va venir :)
EndProcedure
Rien de compliquer pour le moment. A vous d'essayer :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Tuto 02 - Indentation.pb

C'est maintenant qu'il va falloir mettre les mains dans la procédure callback qui recevra les événements émis par ScintillaGadget().

Pour cela nous allons nous servir de la commande native ScintillaSendMessage()

Les commandes lié à scintilla sont référencées sur le site officiel
:arrow: http://www.scintilla.org/ScintillaDoc.html

■ Examples.

.Déterminer la position du curseur dans la chaines contenu dans le gadget Scintilla
SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)
.Déterminer la ligne en cours
SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)
.Déterminer la colonne en cours
SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)
Voici le code de cet exercice. Vous allez pouvoir tester l'indentation.

Code : Tout sélectionner

;Indentation

EnableExplicit

Enumeration Form
  #Mainform
  #StatusBar
EndEnumeration
  
Enumeration Menu
  #MainMenu
  
  #Quit
EndEnumeration

Enumeration Gadget  
  #Editor
EndEnumeration

;-Déclaration variable et procédures 
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

;Scintilla 
Global SciPos.l, SciLine.l, SciCol.l, SciIndent.l

;-Plan de l'application
Declare Start()

Declare MainFormShow() 
Declare MainFormResize()
Declare MainFormClose()

Declare ScintillaCallBack(Gadget, *scinotify.SCNotification)

Start()

;Début
Procedure Start()
  MainFormShow()
  
  BindEvent(#PB_Event_SizeWindow, @MainFormResize(), #MainForm)
  BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
  
  BindMenuEvent(#MainMenu, #Quit, @MainFormClose())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;-
;- U.T. Fenetres, Menu, Gadgets
Procedure MainFormShow()  
  OpenWindow(#MainForm,  0,  0, 1024, 768, "ScintillaGadget : Indentation", WindowStyle)
  
  ;Barre de status
  If CreateStatusBar(#StatusBar,WindowID(#Mainform))
    AddStatusBarField(150)
    AddStatusBarField(450) 
  EndIf 
  
  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre 
  SmartWindowRefresh(#Mainform, #True)
  
  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#Quit,"Quitter")
  
  If InitScintilla()
    ;@ScintillaCallBack() est une procédure callback qui recevra  les évènements émis par ScintillaGadget
    ScintillaGadget(#Editor, 10, 40, 1004, 668, @ScintillaCallBack())   
    SetActiveGadget(#Editor)
  EndIf
    
  ;Neutraliser la touche TAB et les caractéres spéciaux
  RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_B, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_G, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_E, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_R, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_O, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_P, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_Q, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_S, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_F, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_H, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_K, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_W, 0)  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_N, 0)
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-20, WindowHeight(#Mainform)-100)
EndProcedure

Procedure MainFormClose()
  End
EndProcedure

;-
;- U.T. Scintilla
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
  
  Select *scinotify\nmhdr\code
    Case #SCN_CHARADDED
      
      ;Il y a t'il une indentation à faire aprés avoir presser la touche Entrée ?
		  If *scinotify\ch = 13
        ;Determination de l'indentation : SciIndent retourne le numéro de colonne  
        SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
        
        ;Mise en place dans la nouvelle ligne indenté : Passage à la ligne suivante et positionnement à la colonne précédente 
		    ScintillaSendMessage(Gadget, #SCI_SETLINEINDENTATION, SciLIne + 1, SciIndent)
    
        ;Vous avez pressé la touche entrée mais sans indentation : Le curseur ne passera pas à la ligne suivante.
        ;On va forcer le passage à la ligne en insérant la longueur de #CRLF
        If SciIndent=0 
          SciPos = SciPos + Len(#CRLF$)
        EndIf
    
        ;Positionnement du curseur 
        ScintillaSendMessage(Gadget, #SCI_GOTOPOS, SciPos+SciIndent)
      EndIf    
  EndSelect
  
  
  ;Determination de la position à l'intérieur de la chaine scintilla  
  SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)
  
  ;Determination de la ligne en cours 
  SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)
  
  ;Determination de la colonne en cours
  SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)
  
  ;Determination de l'indentation
  SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
  
  ;Affichage du numéro de ligne/colonne dans la barre de status
  StatusBarText(#StatusBar, 0, "Line : " +Str(SciLine+1)+ "  Col : "+Str(SciCol+1), #PB_StatusBar_Center)  
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Bernie
Messages : 282
Inscription : mar. 22/mars/2016 10:12
Localisation : En France

Re: Scintilla pas à pas

Message par Bernie »

Merci Falsam mais Scintilla c'est quoi exactement ?
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Bernie a écrit :Merci Falsam mais Scintilla c'est quoi exactement ?
En testant au moins le premier code tu aurais compris que c'était un éditeur de texte. Par contre ce n'est pas q'un simple éditeur de texte.

La définition est ajouté dans le premier message :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Scintilla pas à pas

Message par microdevweb »

@Bernie,

Pour te donner une idée plus précise, l'ide de PureBasic utilise scintilla ainsi que par exemple NotePad++
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Tuto 03 - Customisation minimum.pb

Il est temps de décorer ce gadget en lui ajoutant
- Une couleur de fond.
- Fixer la police de caractères.
- Une couleur pour la ligne en cours d'édition.
- La numérotation des lignes.

Code : Tout sélectionner

;Customisation minimum

EnableExplicit

Enumeration Form
  #Mainform
  #StatusBar
EndEnumeration
  
Enumeration Menu
  #MainMenu
  
  #Quit
EndEnumeration

Enumeration Gadget  
  #Editor
EndEnumeration

;-Déclaration variable et procédures 
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

;Scintilla 
Global SciPos.l, SciLine.l, SciCol.l, SciIndent.l, SciFile.s, SciText.s

;-Plan de l'application
Declare Start()

Declare MainFormShow() 
Declare MainFormResize()
Declare MainFormClose()

Declare ScintillaCallBack(Gadget, *scinotify.SCNotification)
Declare ScintillaProperties(Gadget)

Start()

;Début
Procedure Start()
  MainFormShow()
  
  BindEvent(#PB_Event_SizeWindow, @MainFormResize(), #MainForm)
  BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
  
  BindMenuEvent(#MainMenu, #Quit, @MainFormClose())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;-
;- U.T. Fenetres, Menu, Gadgets
Procedure MainFormShow()  
  OpenWindow(#MainForm,  0,  0, 1024, 768, "Pure Basic Editor", WindowStyle)
  
  ;Barre de status
  If CreateStatusBar(#StatusBar,WindowID(#Mainform))
    AddStatusBarField(150)
    AddStatusBarField(450) 
  EndIf 
  
  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre 
  SmartWindowRefresh(#Mainform, #True)
  
  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#Quit,"Quitter")
  
  If InitScintilla()
    ;@ScintillaCallBack() est une procédure callback qui recevra  les évènements émis par ScintillaGadget
    ScintillaGadget(#Editor, 10, 40, 1004, 668, @ScintillaCallBack())
    ScintillaProperties(#Editor) ;Customisation de l'éditeur
    SetActiveGadget(#Editor)
  EndIf
    
  ;Neutraliser la touche TAB et les caractéres spéciaux
  RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_B, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_G, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_E, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_R, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_O, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_P, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_Q, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_S, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_F, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_H, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_K, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_W, 0)  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_N, 0)
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-20, WindowHeight(#Mainform)-100)
EndProcedure

;Fin
Procedure MainFormClose()
  End
EndProcedure

;-
;- U.T. Scintilla
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
  
  Select *scinotify\nmhdr\code		  
    Case #SCN_CHARADDED
      
      ;Il y a t'il une indentation à faire aprés avoir presser la touche Entrée ?
		  If *scinotify\ch = 13
        ;Determination de l'indentation : SciIndent retourne le numéro de colonne  
        SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
        
        ;Mise en place dans la nouvelle ligne indenté : Passage à la ligne suivante et positionnement à la colonne précédente 
		    ScintillaSendMessage(Gadget, #SCI_SETLINEINDENTATION, SciLIne+1, SciIndent)
    
        ;Vous avez pressé la touche entrée mais sans indentation : Le curseur ne passera pas à la ligne suivante.
        ;On va forcer le passage à la ligne en insérant la longueur de #CRLF
        If SciIndent=0 
          SciPos = SciPos + Len(#CRLF$)
        EndIf
    
        ;Positionnement du curseur 
        ScintillaSendMessage(Gadget, #SCI_GOTOPOS, SciPos+SciIndent)
        
      EndIf    
  EndSelect
    
  ;Determination de la position à l'intérieur de la chaine scintilla  
  SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)
  
  ;Determination de la ligne en cours 
  SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)
  
  ;Determination de la colonne en cours
  SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)
  
  ;Determination de l'indentation
  SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
  
  ;Affichage du numéro de ligne/colonne dans la barre de status
  StatusBarText(#StatusBar, 1, "Line : " +Str(SciLine+1)+ "  Col : "+Str(SciCol+1), #PB_StatusBar_Center)  
EndProcedure

;Customisation de l'éditeur
Procedure ScintillaProperties(Gadget)
  Protected SciMarginSizeDefault = 40
  
  ;Style par defaut du gadget scintilla
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(0, 0, 0))       ;Couleur des caracteres du ScintillaGadget
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(250, 250, 210)) ;Couleur de fond du ScintillaGadget
  ScintillaSendMessage(Gadget, #SCI_STYLESETFONT,#STYLE_DEFAULT, @"Lucida Console") 
  ScintillaSendMessage(Gadget, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 10)
  ScintillaSendMessage(Gadget, #SCI_STYLECLEARALL)
  
  ;Activation et couleur de la ligne en cours d'édition
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEVISIBLE, #True)
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEBACK, RGB(255, 228, 181))
  
  ;Les tabulations sont remplacées par des espaces 
  ScintillaSendMessage(Gadget, #SCI_SETUSETABS, #False)
  
  ;Nombre d'espaces pour une tabulation
  ScintillaSendMessage(Gadget, #SCI_SETINDENT, 4)
  
  ;Affichage de la colone de numérotation des lignes
  ;0 est l'indice de la premiere colonne.
  ScintillaSendMessage(Gadget, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER) 
  ScintillaSendMessage(Gadget, #SCI_SETMARGINWIDTHN, 0, SciMarginSizeDefault)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(169, 169, 169))
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(250, 250, 210))
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Tuto 04 - Autocompletion.pb

Avec cette exercice, nous allons voir comment compléter automatiquement le mot que l'utilisateur est en train décrire.

Image

J'ai fait une toute petite liste de mots que vous connaissez avec le langage PureBasic. A vous de mettre ce que vous voulez.

Ces mots sont séparés par le caractère |.

Code : Tout sélectionner

KeyWord.s = "ButtonGadget|TextGadget|If|EndIf|Enumeration|EndEnumeration|Procedure|EndProcedure|Select|EndSelect|Case|Default"
Le code de cet exercice.

Code : Tout sélectionner

;Autocompletion

EnableExplicit

Enumeration Form
  #Mainform
  #StatusBar
EndEnumeration

Enumeration Menu
  #MainMenu
  
  #Quit
EndEnumeration

Enumeration Gadget  
  #Editor
EndEnumeration

;-Déclaration variable et procédures 
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

;Scintilla 
Global SciPos.l, SciLine.l, SciCol.l, SciIndent.l

;Liste des mots clé
Global KeyWord.s = "ButtonGadget|TextGadget|If|EndIf|Enumeration|EndEnumeration|Procedure|EndProcedure|Select|EndSelect|Case|Default"
Global KeyWordSep.s = "|"

;-Plan de l'application
Declare Start()

Declare MainFormShow() 
Declare MainFormResize()
Declare MainFormClose()

Declare ScintillaCallBack(Gadget, *scinotify.SCNotification)
Declare ScintillaProperties(Gadget)

Start()

;Début
Procedure Start()
  MainFormShow()
  
  BindEvent(#PB_Event_SizeWindow, @MainFormResize(), #MainForm)
  BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
  
  BindMenuEvent(#MainMenu, #Quit, @MainFormClose())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure


;-
;- U.T. Fenetres, Menu, Gadgets
Procedure MainFormShow()  
  OpenWindow(#MainForm,  0,  0, 1024, 768, "ScintillaGadget : Autocompletion", WindowStyle)
  
  ;Barre de status
  If CreateStatusBar(#StatusBar,WindowID(#Mainform))
    AddStatusBarField(150)
    AddStatusBarField(450) 
  EndIf 
  
  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre 
  SmartWindowRefresh(#Mainform, #True)
  
  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#Quit,"Quitter")
  
  If InitScintilla()
    ;@ScintillaCallBack() correspond à l'adresse de la procédure qui recevra les évènements émis par le contrôle.
    ScintillaGadget(#Editor, 10, 40, 1004, 668, @ScintillaCallBack())
    ScintillaProperties(#Editor) ;Customisation de l'éditeur
    SetActiveGadget(#Editor)
  EndIf
   
  ;Neutraliser la touche TAB et les caractéres spéciaux
  RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_B, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_G, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_E, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_R, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_O, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_P, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_Q, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_S, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_F, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_H, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_K, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_W, 0)  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_N, 0)
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-20, WindowHeight(#Mainform)-100)
EndProcedure

;Fin
Procedure MainFormClose()
  End
EndProcedure


;-
;- U.T. Utilitaire
Procedure MakeUTF8Text(Text.s)
  Static Buffer.s
  Buffer = Space(StringByteLength(Text, #PB_UTF8) + 1)
  PokeS(@buffer, text, -1, #PB_UTF8)
  ProcedureReturn @buffer
EndProcedure

;-
;- U.T. Scintilla
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
  Protected SciCurrentPos, SciWordStartPos
  
  Select *scinotify\nmhdr\code		  
    Case #SCN_CHARADDED
      
      ;- Indentation
      If *scinotify\ch = 13 ;Touche entrée
        ;Determination de l'indentation : SciIndent retourne le numéro de colonne  
        SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
        
        ;Mise en place dans la nouvelle ligne indenté : Passage à la ligne suivante et positionnement à la colonne précédente 
        ScintillaSendMessage(Gadget, #SCI_SETLINEINDENTATION, SciLIne+1, SciIndent)
        
        ;Vous avez pressé la touche entrée mais sans indentation : Le curseur ne passera pas à la ligne suivante.
        ;On va forcer le passage à la ligne en insérant la longueur de #CRLF
        If SciIndent=0 
          SciPos = SciPos + Len(#CRLF$)
        EndIf
        
        ;Positionnement du curseur 
        ScintillaSendMessage(Gadget, #SCI_GOTOPOS, SciPos+SciIndent)
      EndIf  
      
      ;- Autocomplétion
      Select *scinotify\ch
        Case 'a' To 'z'         
          ;Affichage du mot selectionné si autocomplétion
          SciCurrentPos = ScintillaSendMessage(0, #SCI_GETCURRENTPOS)
          SciWordStartPos = ScintillaSendMessage(0, #SCI_WORDSTARTPOSITION, SciCurrentPos, 1)
          ScintillaSendMessage(0, #SCI_AUTOCSHOW, SciCurrentPos - SciWordStartPos, MakeUTF8Text(KeyWord))   
      EndSelect
  EndSelect
  
  ;Determination de la position à l'intérieur de la chaine scintilla  
  SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)
  
  ;Determination de la ligne en cours 
  SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)
  
  ;Determination de la colonne en cours
  SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)
  
  ;Determination de l'indentation
  SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
  
  ;Affichage du numéro de ligne/colonne dans la barre de status
  StatusBarText(#StatusBar, 1, "Line : " +Str(SciLine+1)+ "  Col : "+Str(SciCol+1), #PB_StatusBar_Center)  
EndProcedure

;Customisation de l'éditeur
Procedure ScintillaProperties(Gadget)
  ;Style par defaut du gadget scintilla (Couleur de fond et de caractére, police .....)
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(0, 0, 0))           ;Couleur des caracteres du ScintillaGadget
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(250, 250, 210))     ;Couleur de fond du ScintillaGadget
  ScintillaSendMessage(Gadget, #SCI_STYLESETFONT,#STYLE_DEFAULT, @"Lucida Console")       ;Police à utiliser 
  ScintillaSendMessage(Gadget, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 10)                     ;Taille de la police
  ScintillaSendMessage(Gadget, #SCI_STYLECLEARALL)
  
  ;Activation et couleur de la ligne en cours d'édition
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEVISIBLE, #True)
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEBACK, RGB(255, 228, 181))
    
  ;Les tabulations sont remplacées par des espaces 
  ScintillaSendMessage(Gadget, #SCI_SETUSETABS, #False)
  
  ;Nombre d'espaces pour une tabulation
  ScintillaSendMessage(Gadget, #SCI_SETINDENT, 4)
  
  ;Affichage de la colone de numérotation des lignes
  ScintillaSendMessage(Gadget, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)                
  ScintillaSendMessage(Gadget, #SCI_SETMARGINWIDTHN, 0, 50)                               ;Largeur de la colonne
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(169, 169, 169))  ;Couleur de fond 
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(250, 250, 210))  ;Couleur des numéros
  
  ;Parametres de la liste d'autocomplétion des mots clés 
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETMAXHEIGHT, 40)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETMAXWIDTH, 150)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETAUTOHIDE, #True)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETCHOOSESINGLE, #True)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETIGNORECASE, #True)
  
  ;Caractére séparant chaque mot de la liste des mots clés
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETSEPARATOR, Asc(KeyWordSep)) 
  
  ;Caractére sélectionnant le mot de la liste d'autocomplétion
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETFILLUPS, 0, @" ")
  
  ;Tri de la liste d'autocomplétion
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETORDER, #SC_ORDER_PERFORMSORT) 
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Bernie
Messages : 282
Inscription : mar. 22/mars/2016 10:12
Localisation : En France

Re: Scintilla pas à pas

Message par Bernie »

Merci falsam mais je suis pas intéressé
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Scintilla pas à pas

Message par falsam »

Tuto 05 - Pliage et coloration syntaxique.pb

Pour la coloration syntaxique nous allons utiliser la fonction ScintillaSendMessage() de cette maniére.
ScintillaSendMessage(Gadget, #SCI_SETSTYLING, Len(MotCle), StyleID)
En tête de code on a énuméré une série de style. Par exemple : #Style_Keyword, #Style_Constant, #Style_Integer, etc ......

Arrêtons nous sur le dernier : #Style_Integer

1 - Nous allons définir les propriétés de ce style dans la procédure ScintillaProperties(Gadget) :

Code : Tout sélectionner

ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_Integer, RGB(255, 0, 0))
La couleur de chaque caractère numérique sera rouge. On aurait pu associer plusieurs propriété pour un style en définissant la couleur de fond ou/et la police.

2 - Nous avons ajouté la procédure Highlight(Gadget, EndPos) qui va se charger d'analyser tout ce que l'utilisateur frappe au clavier.
Si cette procédure détecte des caractères numériques alors cette portion de code sera exécutée.

Code : Tout sélectionner

Case '0' To '9'
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_Integer)
1 est la longueur à colorier.

Voici le code

Code : Tout sélectionner

;Coloration Syntaxique & Pliage de code

EnableExplicit

Enumeration Highlight
  #Style_Space
  #Style_Comment
  #Style_NonKeyword
  #Style_Keyword
  #Style_FoldKeyword
  #Style_Constant
  #Style_String
  #Style_Integer
  #Style_Operator
  
  #Style_FoldKeywordUp
  #Style_FoldKeywordDown
EndEnumeration

Enumeration Form
  #Mainform
  #StatusBar
EndEnumeration

Enumeration Menu
  #MainMenu
  #Quit
EndEnumeration

Enumeration Gadget  
  #Editor
EndEnumeration

;-Déclaration variable et procédures 
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

;Scintilla 
Global SciPos.l, SciLine.l, SciCol.l, SciIndent.l

;Liste des mots clés et définition du séparateur
Global KeyWord.s = "ButtonGadget|TextGadget|If|EndIf|Enumeration|EndEnumeration|Procedure|EndProcedure|Select|EndSelect|Case|Default"
Global KeyWordFoldingUp.s = "Procedure|Enumeration|If"
Global KeyWordfoldingDown.s = "EndProcedure|EndEnumeration|EndIf"
Global KeyWordSep.s = "|"

;-Plan de l'application
Declare Start()

Declare MainFormShow() 
Declare MainFormResize()
Declare MainFormClose()

Declare ScintillaCallBack(Gadget, *scinotify.SCNotification)
Declare ScintillaProperties(Gadget)
Declare ScintillaGetLineEndPosition(Gadget, Line)
Declare ScintillaLineFromPosition(Gadget, Pos)

Declare KeyWord(Key.s)
Declare Highlight(Gadget.l, EndPos.l)


Start()

;Début
Procedure Start()
  MainFormShow()
  
  BindEvent(#PB_Event_SizeWindow, @MainFormResize(), #MainForm)
  BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
  
  BindMenuEvent(#MainMenu, #Quit, @MainFormClose())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;-
;- U.T. Fenetres, Menu, Gadgets
Procedure MainFormShow()  
  OpenWindow(#MainForm,  0,  0, 1024, 768, "ScintillaGadget : Autocompletion", WindowStyle)
  
  ;Barre de status
  If CreateStatusBar(#StatusBar,WindowID(#Mainform))
    AddStatusBarField(150)
    AddStatusBarField(450) 
  EndIf 
  
  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre 
  SmartWindowRefresh(#Mainform, #True)
  
  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#Quit,"Quitter")
  
  If InitScintilla()
    ;@ScintillaCallBack() est une procédure callback qui recevra  les évènements émis par ScintillaGadget
    ScintillaGadget(#Editor, 10, 40, 1004, 668, @ScintillaCallBack())
    ScintillaProperties(#Editor)
    SetActiveGadget(#Editor)
  EndIf
  
  ;Neutraliser la touche TAB et les caractéres spéciaux
  RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_B, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_G, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_E, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_R, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_O, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_P, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_Q, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_S, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_F, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_H, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_K, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_W, 0)  
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_N, 0)
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-20, WindowHeight(#Mainform)-100)
EndProcedure

Procedure MainFormClose()
  End
EndProcedure

;-
;- U.T. Utilitaire
Procedure MakeUTF8Text(Text.s)
  Static Buffer.s
  Buffer = Space(StringByteLength(Text, #PB_UTF8) + 1)
  PokeS(@buffer, text, -1, #PB_UTF8)
  ProcedureReturn @buffer
EndProcedure

;-
;- U.T. Scintilla
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
  Protected SciCurrentPos, SciWordStartPos
  
  Select *scinotify\nmhdr\code		  
    Case #SCN_CHARADDED
      
      ;Indentation
      If *scinotify\ch = 13 ;Touche entrée
        ;Determination de l'indentation : SciIndent retourne le numéro de colonne  
        SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
        
        ;Mise en place dans la nouvelle ligne indenté : Passage à la ligne suivante et positionnement à la colonne précédente 
        ScintillaSendMessage(Gadget, #SCI_SETLINEINDENTATION, SciLIne+1, SciIndent)
        
        ;Vous avez pressé la touche entrée mais sans indentation : Le curseur ne passera pas à la ligne suivante.
        ;On va forcer le passage à la ligne en insérant la longueur de #CRLF
        If SciIndent=0 
          SciPos = SciPos + Len(#CRLF$)
        EndIf
        
        ;Positionnement du curseur 
        ScintillaSendMessage(Gadget, #SCI_GOTOPOS, SciPos+SciIndent)
      EndIf  
      
      ;Autocomplétion
      Select *scinotify\ch
        Case 'a' To 'z'         
          ;Affichage du mot selectionné si autocomplétion
          SciCurrentPos = ScintillaSendMessage(0, #SCI_GETCURRENTPOS)
          SciWordStartPos = ScintillaSendMessage(0, #SCI_WORDSTARTPOSITION, SciCurrentPos, 1)
          ScintillaSendMessage(0, #SCI_AUTOCSHOW, SciCurrentPos - SciWordStartPos, MakeUTF8Text(KeyWord))
          
      EndSelect
      
    Case #SCN_STYLENEEDED
      Highlight(Gadget, *scinotify\position)
      
    Case #SCN_MARGINCLICK
      ScintillaSendMessage(Gadget, #SCI_TOGGLEFOLD, ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, *scinotify\Position))
      
  EndSelect
  
  ;Determination de la position à l'intérieur de la chaine scintilla  
  SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)
  
  ;Determination de la ligne en cours 
  SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)
  
  ;Determination de la colonne en cours
  SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)
  
  ;Determination de l'indentation
  SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
  
  ;Affichage du numéro de ligne/colonne dans la barre de status
  StatusBarText(#StatusBar, 1, "Line : " +Str(SciLine+1)+ "  Col : "+Str(SciCol+1), #PB_StatusBar_Center)  
EndProcedure

;Customisation de l'éditeur
Procedure ScintillaProperties(Gadget)
  ;Style par defaut du gadget scintilla (Couleur de fond et de caractére, police .....)
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(0, 0, 0))           ;Couleur des caracteres du ScintillaGadget
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(250, 250, 210))     ;Couleur de fond du ScintillaGadget
  ScintillaSendMessage(Gadget, #SCI_STYLESETFONT,#STYLE_DEFAULT, @"Lucida Console")       ;Police à utiliser 
  ScintillaSendMessage(Gadget, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 10)                     ;Taille de la police
  ScintillaSendMessage(Gadget, #SCI_STYLECLEARALL)
  
  ;Activation et couleur de la ligne en cours d'édition
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEVISIBLE, #True)
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEBACK, RGB(255, 228, 181))
  
  ;Les tabulations sont remplacées par des espaces 
  ScintillaSendMessage(Gadget, #SCI_SETUSETABS, #False)
  
  ;Nombre d'espaces pour une tabulation
  ScintillaSendMessage(Gadget, #SCI_SETINDENT, 4)
  
  ;Affichage de la colone de numérotation des lignes
  ScintillaSendMessage(Gadget, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)                
  ScintillaSendMessage(Gadget, #SCI_SETMARGINWIDTHN, 0, 50)                               ;Largeur de la colonne
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(169, 169, 169))  ;Couleur de fond 
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(250, 250, 210))  ;Couleur des numéros
  
  ;Affichage de la colonne de pliages de code
  ScintillaSendMessage(Gadget, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
  ScintillaSendMessage(Gadget, #SCI_SETMARGINWIDTHN, 2, 20)
  ScintillaSendMessage(Gadget, #SCI_SETMARGINSENSITIVEN, 2, #True)
  
  ;Parametres de la liste d'autocomplétion des mots clés 
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETMAXHEIGHT, 40)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETMAXWIDTH, 150)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETAUTOHIDE, #True)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETCHOOSESINGLE, #True)
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETIGNORECASE, #True)
  
  ;Caractére séparant chaque mot de la liste des mots clés
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETSEPARATOR, Asc(KeyWordSep))
  
  ;Caractére sélectionnant le mot de la liste d'autocomplétion
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETFILLUPS, 0, @" ")
  
  ;Tri de la liste d'autocomplétion
  ScintillaSendMessage(Gadget, #SCI_AUTOCSETORDER, #SC_ORDER_PERFORMSORT) 
    
  ;Coloration syntaxique
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_Comment, RGB(0, 187, 0))
  ScintillaSendMessage(Gadget, #SCI_STYLESETITALIC, #Style_Comment, 1)
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_NonKeyword, RGB(0, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_Keyword, RGB(0, 102, 102))
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_Constant, RGB(169, 64, 147))
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_String, RGB(255, 139, 37))
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_Integer, RGB(255, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_Operator, RGB(205, 92, 92))
    
  ;Choix des icones de pliages du code 
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEROPEN, #SC_MARK_CIRCLEMINUS)
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDER, #SC_MARK_CIRCLEPLUS)
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERSUB, #SC_MARK_VLINE)
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERTAIL, #SC_MARK_LCORNERCURVE)
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEREND, #SC_MARK_CIRCLEPLUSCONNECTED)
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEROPENMID, #SC_MARK_CIRCLEMINUSCONNECTED)
  ScintillaSendMessage(Gadget, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERMIDTAIL, #SC_MARK_TCORNERCURVE)
  
  ;Couleur des icones de pliages de code
  ScintillaSendMessage(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDER, RGB(255, 255, 255))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDER, RGB(0, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDEROPEN, RGB(255, 255, 255))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDEROPEN, RGB(0, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDEROPENMID, RGB(0, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERSUB, RGB(0, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERTAIL, RGB(0, 0, 0))
  ScintillaSendMessage(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERMIDTAIL, RGB(0, 0, 0))
EndProcedure

Procedure ScintillaGetLineEndPosition(Gadget, Line)
  ProcedureReturn ScintillaSendMessage(Gadget, #SCI_GETLINEENDPOSITION, Line)
EndProcedure

Procedure ScintillaLineFromPosition(gadget, Pos)
  ProcedureReturn ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, Pos)
EndProcedure

;-
;- U.T. Coloration syntaxique
Procedure KeyWord(Key.s)
  Protected n
  
  If Key=""
    ProcedureReturn -1
  EndIf
  
  For n = 1 To CountString(KeyWordFoldingUp, KeyWordSep) + 1
    If LCase(StringField(KeyWordFoldingUp, n, KeyWordSep)) = LCase(Key)
      ProcedureReturn #Style_FoldKeywordUp
    EndIf
  Next
  
  For n=1 To CountString(KeyWordFoldingDown, KeyWordSep) + 1
    If LCase(StringField(KeyWordFoldingDown, n, KeyWordSep)) = LCase(Key)
      ProcedureReturn #Style_FoldKeywordDown
    EndIf
  Next
  
  For n=1 To CountString(KeyWord, KeyWordSep) + 1
    If LCase(StringField(KeyWord, n, KeyWordSep)) = LCase(Key)
      ProcedureReturn #Style_Keyword
    EndIf
  Next
  
  ProcedureReturn -1
EndProcedure


Procedure Highlight(Gadget.l, EndPos.l)
  Protected Level = #SC_FOLDLEVELBASE, Char.i, keyword.s, StyleID.i
  Protected ThisLevel.i = Level
  Protected NextLevel.i = Level
  Protected CurrentPos.i = 0, EndLinePos.i,  LineNumber.i, StartKeyword.i
  
  EndPos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, EndPos))
  ScintillaSendMessage(Gadget, #SCI_STARTSTYLING, CurrentPos, $1F | #INDICS_MASK)
  
  While CurrentPos <= EndPos
    Char = ScintillaSendMessage(Gadget, #SCI_GETCHARAT, CurrentPos)
    
    Select Char
      Case Asc(#LF$)
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_NonKeyword)
        ScintillaSendMessage(Gadget, #SCI_SETFOLDLEVEL, LineNumber , ThisLevel)
        ThisLevel = NextLevel
        LineNumber + 1
        
      Case '+', '-', '/', '*', '=', '>', '<'
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_Operator)
        
      Case '0' To '9'
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_Integer)
        
      Case 'a' To 'z', 'A' To 'Z', '{', '}'
        EndLinePos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, currentpos))
        keyword = Chr(char)
        
        While currentpos < EndLinePos
          currentpos + 1
          char = ScintillaSendMessage(Gadget, #SCI_GETCHARAT, currentpos)
          If Not ((char >= 'a' And char <= 'z') Or (char >= 'A' And char <= 'Z') Or char = '_'Or (char >= '0' And char <= '9'))
            currentpos-1
            Break
          EndIf
          keyword + Chr(char)
        Wend
        
        Select KeyWord(keyword)
          Case #Style_FoldKeywordUp
            StyleID = #Style_Keyword
            ThisLevel | #SC_FOLDLEVELHEADERFLAG
            NextLevel + 1
            
          Case #Style_FoldKeywordDown
            StyleID = #Style_Keyword
            NextLevel - 1
            If NextLevel < #SC_FOLDLEVELBASE
              NextLevel = #SC_FOLDLEVELBASE
            EndIf
            
          Case #Style_Keyword
            StyleID = #Style_Keyword
            
          Default
            StyleID = #Style_NonKeyword
            
        EndSelect
        
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, Len(keyword), StyleID)
        
      Case '"'
        EndLinePos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, currentpos))
        StartKeyword = 1
        While currentpos < EndLinePos
          currentpos + 1
          StartKeyword + 1
          If ScintillaSendMessage(Gadget, #SCI_GETCHARAT, currentpos) = '"'
            Break
          EndIf
        Wend
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, StartKeyword, #Style_String)
        
      Case ';'
        EndLinePos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, currentpos))
        StartKeyword = 1
        While currentpos < EndLinePos
          currentpos + 1
          StartKeyword + 1
        Wend
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, StartKeyword, #Style_Comment)
        
      Case 9, ' '
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_Space)
        
      Case '#'
        EndLinePos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, currentpos))
        StartKeyword = 1
        While currentpos < EndLinePos
          currentpos + 1
          char = ScintillaSendMessage(Gadget, #SCI_GETCHARAT, currentpos)
          If Not ((char >= 'a' And char <= 'z') Or (char >= 'A' And char <= 'Z') Or char = '_' Or (char >= '0' And char <= '9'))
            currentpos-1
            Break
          EndIf
          StartKeyword + 1
        Wend
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, StartKeyword, #Style_Constant)
        
      Default
        ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_NonKeyword)
        
    EndSelect
    currentpos+1
  Wend 
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Scintilla pas à pas

Message par Micoute »

Du bon et beau travail, comme d'habitude.

Merci de partager.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
digital
Messages : 25
Inscription : mar. 02/févr./2016 0:34

Re: ScintillaGadget() pas à pas

Message par digital »

Un très bon tutorial que j'apprécie beaucoup.
Shadow
Messages : 1373
Inscription : mer. 04/nov./2015 17:39

Re: ScintillaGadget() pas à pas

Message par Shadow »

Salut,

Ont peut pas dire le contraire, t'es sujet sont très utile !
Merci du partage, ça servira, c'est certain.
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Répondre