Page 1 sur 1

[Résolu] Scintilla : plier/déplier

Publié : mar. 18/mars/2014 11:16
par blendman
salut

J'essaye d'ajouter la fonction plier/déplier tout (équivalent du Ctrl+F4 de l'ide de purebasic) à un petit éditeur que je réalise avec scintilla, mais je ne trouve pas la commande qui permet de faire ça.
Sur le site Scintilla, il parle de SCI_FOLDALL(), mais par de bol on n'a pas de #SCI_FOLDALL comme constante avec ScintillaSendMessage() ^^.

Quelqu'un saurait-il comment on fait ça ?

Merci.

Re: Scintilla : plier/déplier

Publié : mar. 18/mars/2014 12:14
par Backup
en principe :

Code : Tout sélectionner

For i=0 To ScintillaSendMessage(1, #SCI_GETLINECOUNT)-1 ; pour toute les lignes de l'editeur
	If ScintillaSendMessage(1, #SCI_GETFOLDLEVEL, i) = #SC_FOLDLEVELBASE|#SC_FOLDLEVELHEADERFLAG ; verifie si une ligne est pliable
		ScintillaSendMessage(1, #SCI_TOGGLEFOLD, i) ; alors on la plie
	EndIf
Next
comme j'utilise #SCI_TOGGLEFOLD un coup ça plie , un coup ça deplie ... ideal pour un raccourci clavier de pliage/depliage
de l'ensemble du code


le probleme n'est pas tant de "folder" le code, comme tu le vois c'est assez simple
mais .... de definir quel mote clef sert a folder ou unfolder le code ...

là c'est une autre histoire ....


pour info dans Goscintilla , ça se passe ici :

Code : Tout sélectionner

 If *this\state & (#GOSCI_LEXERSTATE_ENABLECODEFOLDING|#GOSCI_LEXERSTATE_ENABLECLICKANYWHERECODEFOLDING)
        t1 = 0
        If *this\blnLineCodeFoldOption >= 1 ;Open fold.
          t1 = #SC_FOLDLEVELHEADERFLAG
        EndIf
        ScintillaSendMessage(id, #SCI_SETFOLDLEVEL, i, t1|*this\foldLevel)
        *this\foldLevel + *this\blnLineCodeFoldOption
        If *this\foldLevel < #SC_FOLDLEVELBASE
          *this\foldLevel = #SC_FOLDLEVELBASE
        EndIf
      Else
        ScintillaSendMessage(id, #SCI_SETFOLDLEVEL, i, 0)
      EndIf
grosso modo , il regarde si un mot dans la liste "This" est foldable (donc il utilise un flag pour savoir si un mot est foldable ou pas ...
si le flag dit que c'est un mot d'ouverture de fold (comme "Procedure(" par ex ) il met T1= a #SC_FOLDLEVELHEADERFLAG
et donne l'ordre a Scintilla d'afficher le symbole de folding avec
ScintillaSendMessage(id, #SCI_SETFOLDLEVEL, i, t1|*this\foldLevel)
sinon il utilise ScintillaSendMessage(id, #SCI_SETFOLDLEVEL, i, 0) pour la fin de Folding ....
#SCI_SETFOLDLEVEL permet de faire de la hierarchie des Folders dans des Folders ....
c'est ce qu'il fait dans sa structure en gardant le niveau de profondeur avec "*this\foldLevel"
donc il te faut tenir un compteur de profondeur pour pouvoir a la fin revenir a 0 et ainsi afficher le symbole de fin de folding ...


comme tu vois c'est simple :mrgreen:


sinon en utilisant Go_scintilla c'est quand meme plus simple a mettre en place puisque :

Code : Tout sélectionner

GOSCI_AddKeywords(onglet, com2$, #STYLES_COMMANDS, #GOSCI_OPENFOLDKEYWORD|#GOSCI_ADDTOCODECOMPLETION,-1)
te permet de faire afficher le sympbole de folding open a chaque mot clef contenue dans "Com2$" séparé par des Espaces
com2$="Procedure If For" par exemple

et un

Code : Tout sélectionner

GOSCI_AddKeywords(onglet, com2$, #STYLES_COMMANDS, #GOSCI_CLOSEFOLDKEYWORD|#GOSCI_ADDTOCODECOMPLETION,-1)
avec le meme principe pour avoir le Symbole de Fermeture
avec comme mot clef pour l'exemple "EndProcedure Endif Next" :)

Re: Scintilla : plier/déplier

Publié : mar. 18/mars/2014 13:29
par blendman
Merci beaucoup pour ton explication, ça marche nickel ;). J'avais vu dans la doc #SCI_TOGGLEFOLD, mais je ne savais pas comment l'utiliser.

J'utilise effectivement Goscintilla car c'est plus simple (pour le moment) pour certaines choses (et ça m'évite de réinventer la roue ^^).

Par contre, j'ai testé d'autres choses , mais certains codes ne marchent pas directement.
Je pense notamment à ce code :

Code : Tout sélectionner

  
ScintillaSendMessage(id, #SCI_SETPROPERTY, @"fold", @"1")
  ScintillaSendMessage(id, #SCI_SETPROPERTY, @"fold.compact", @"0")
  ScintillaSendMessage(id, #SCI_SETPROPERTY, @"fold.comment", @"1") 
  ScintillaSendMessage(id, #SCI_SETPROPERTY, @"fold.preprocessor", @"1") 
Pour permettre le pliage des commentaires (ligne 3). J'imagine qu'il faut modifier le code en conséquence, car je n'ai pas trouvé de #SCI_SETPROPERTY dans les fichiers Goscintilla. Je me demande si ça ne peut pas s'utiliser uniquement avec un "lexer" disponible par la version complète de scintilla (celle qu'on trouve sur le site officiel). Faudra que je creuse ça à l'occasion ^^.

Encore merci pour les explications ;)

Re: Scintilla : plier/déplier

Publié : mer. 19/mars/2014 9:01
par blendman
j'ai remarqué que le code :

Code : Tout sélectionner

For i=0 To ScintillaSendMessage(1, #SCI_GETLINECOUNT)-1 ; pour toute les lignes de l'editeur
   If ScintillaSendMessage(1, #SCI_GETFOLDLEVEL, i) = #SC_FOLDLEVELBASE|#SC_FOLDLEVELHEADERFLAG ; verifie si une ligne est pliable
      ScintillaSendMessage(1, #SCI_TOGGLEFOLD, i) ; alors on la plie
   EndIf
Next
plie si une ligne est dépliée et déplie si elle est pliée.
Il y a moyen de toutes les plier/déplier, peu importe qu'elles soient déjà pliées ou non, comme l'IDE avec Ctrl+F4 ?

Re: Scintilla : plier/déplier

Publié : mer. 19/mars/2014 11:27
par Backup
tu as :
SCI_FOLDLINE(int line, int action)
SCI_FOLDCHILDREN(int line, int action)
SCI_FOLDALL(int action)
donc :

Code : Tout sélectionner

Action = 0 Contract. 
Action = #SC_FOLDACTION_EXPAND=1 Expand. 
Action = #SC_FOLDACTION_TOGGLE=2 Toggle between contracted and expanded. 



ScintillaSendMessage(1, #SCI_FOLDLINE, numero de ligne, Action ) ;


ça devrai le faire ...

Re: Scintilla : plier/déplier

Publié : mer. 19/mars/2014 11:46
par blendman
hélas #SCI_FOLDLINE n'est pas une constante purebasic et je n'ai pas trouvé d'équivalent :(

Je crois que la version de scintilla de Purebasic est la 3.2.2, et ces fonctions-là sont visiblement disponibles dans la version 3.3.1. 'faudrait que Fred mette à jour Scintilla :).

Re: Scintilla : plier/déplier

Publié : mer. 19/mars/2014 12:07
par Backup
essaye ça

Code : Tout sélectionner

; pour plier les lignes depliees
 For i=0 To ScintillaSendMessage(1, #SCI_GETLINECOUNT)-1 ; pour toute les lignes de l'editeur
   If ScintillaSendMessage(1, #SCI_GETFOLDLEVEL, i) = #SC_FOLDLEVELBASE|#SC_FOLDLEVELHEADERFLAG  and ScintillaSendMessage(1, #SCI_GETFOLDEXPANDED, i)<>0
      ScintillaSendMessage(1, #SCI_TOGGLEFOLD, i) ; alors on la plie
   EndIf
Next i

; pour Deplier les lignes pliees
 For i=0 To ScintillaSendMessage(1, #SCI_GETLINECOUNT)-1 ; pour toute les lignes de l'editeur
   If ScintillaSendMessage(1, #SCI_GETFOLDLEVEL, i) = #SC_FOLDLEVELBASE|#SC_FOLDLEVELHEADERFLAG  and ScintillaSendMessage(1, #SCI_GETFOLDEXPANDED, i)=0
      ScintillaSendMessage(1, #SCI_TOGGLEFOLD, i) ; alors on la plie
   EndIf
Next i
le but est d'utiliser ToggleFold seulement sur les lignes Dépliées...
donc, faut regarder si la ligne en cours d'observation est pliée ou pas ...

et normalement ScintillaSendMessage(1, #SCI_GETFOLDEXPANDED, Numero de ligne) devrai etre capable de te renseigner sur ce fait ....

il faut utiliser ça pour savoir si tu inverses le pliage ou pas ....

sans avoir de code, je ne peux pas t'aider mieux ....

Re: Scintilla : plier/déplier

Publié : mer. 19/mars/2014 12:22
par blendman
Merci beaucoup, ça marche nickel ;)

J'ai ajouter une petite variable pour mon interface pour savoir si on est déjà plié ou déplié et hop, ça roule :

Code : Tout sélectionner

Fold = 1 - Fold

If Fold
  ; pour plier les lignes depliees
  For i=0 To ScintillaSendMessage(1, #SCI_GETLINECOUNT)-1 ; pour toute les lignes de l'editeur
    If ScintillaSendMessage(1, #SCI_GETFOLDLEVEL, i) = #SC_FOLDLEVELBASE|#SC_FOLDLEVELHEADERFLAG  And ScintillaSendMessage(1, #SCI_GETFOLDEXPANDED, i)<>0
      ScintillaSendMessage(1, #SCI_TOGGLEFOLD, i) ; alors on la plie
    EndIf
  Next i
Else
  ; pour Deplier les lignes pliees
  For i=0 To ScintillaSendMessage(1, #SCI_GETLINECOUNT)-1 ; pour toute les lignes de l'editeur
    If ScintillaSendMessage(1, #SCI_GETFOLDLEVEL, i) = #SC_FOLDLEVELBASE|#SC_FOLDLEVELHEADERFLAG  And ScintillaSendMessage(1, #SCI_GETFOLDEXPANDED, i)=0
      ScintillaSendMessage(1, #SCI_TOGGLEFOLD, i) ; alors on la plie
    EndIf
  Next i
EndIf
Encore merci ;).