il y a quelques mois je commençais ce programme pour me faire mon propre éditeur de texte multi-taille (par opposition au monofont).
Depuis, le temps a manqué, avec la concentration nécessaire. Alors, au lieu de l'expédier dans la case des oublis, ou celle des << demain peut-être >>, je prends le risque de vous le poster et que plusieurs se posent la question de l'utilité d'un tel code.
La réponse est simple et sera toujours celle-là : parce que les esprits suffisamment éprouvés y verront d'eux-mêmes le côté utile.
Le programme en lui-même ne fait vraiment pas grand chose. Ce sont 64 bandes horizontales qui miment des lignes de texte de hauteur différente chacune.
Donc, il n'y a donc que 3 touches : haut bas et échap.
* flèches haut/bas : monte ou descend le curseur pour mimer un déplacement dans un texte
* Echap = quitte
Et la molette souris pour défiler aussi vers le haut comme vers le bas.
Ce qui m'a cassé dans ce projet c'est que je souhaitais rendre dynamique le nombre total de lignes qui s'élève ici à 64 (de 0 à 63) pour permettre d'augmenter le nombre en cas de zoom arrière, ou de libérer la mémoire en cas de zoom avant. Le problème c'est qu'il faut en plus de traiter les x types de mesures de hauteur (en pixels, en lignes de texte, ainsi qu'en coefficients visible/invisible en cours et en coefficients invisible en cours/invisible total : bref, c'est de la virtualisation de 3D iso sans rotation pour ne perdre ni en ressource CPU ni en mémoire) traiter la qualité des images qui doit être nécessairement amoindrie en cas de zoom arrière (sinon ça bouffe en mémoire).
Ça peut sembler bizarre de buter sur des broutilles, mais le but était (et est) d'être sans limite sur les y et sur les z. J'ai déjà fait un programme sur opengl qui fonctionnait bien mais il était monofont. Et la virtualisation c'était opengl qui la gèrait complètement. Là, j'avais préféré m'en occuper.
Donc voici cette "poubelle". Voyez-là comme une oeuvre d'art insignifiante dont le but est juste de voir une simple mécanique de défilement bien fonctionner, pour quiconque a l'envie de fabriquer son propre éditeur de texte, il y a deux ou trois "engrenages" dedans qui peuvent vraiment inspirer. Chaque ligne (ou case) est une image. Aucune mise à jour de ces images n'est traitée pour "sortir" de ce ruban qui a donc ici, fin et début liés.
Tout est dans la seule structure "gbl" (GloBaL) et les noms des champs dont les termes sont réduits à 3 lettres, c'est une astuce que j'ai empruntée dans mes habitudes de prog sur smartphone car j'ai programmé un éditeur monofont fonctionnel sur Smartphone dans un autre langage. Et le smartphone, pour programmer dessus, il vaut mieux faire court avec les noms de variables vu la petite taille de l'écran... Etrangement, 3 lettres ça me rappelle direct les extensions de fichier et donc ma mémoire s'en familiarise. Et pour l'absence de français, désolé, je ne me fais pas à une langue française sans accents donc je reste à l'anglaise.
Une fois qu'on a ce genre de petit outil, on a un peu une sorte de fourre-tout graphique : éditeur de texte, console, explorateur de fichier. Et ainsi, on n'est plus à la merci de délires d'interface qui font perdre un temps fou, et de systèmes qui changent constamment.
Personnellement, le temps informatique va s'annuler pour moi sans prévision de durée.
Donc, à vos molettes de souris (et vos touches haut et bas), bon défilement !
Code : Tout sélectionner
;- Enumerations
Enumeration
#docEsc = 1 ; document : menu item code for escape
#docLastLine ; document : menu item code for last line move
#docNextLine ; document : menu item code for next line move
EndEnumeration
;- Structures
Structure gbl
;- gbl doc ('§' <=> default value)
docHei .D ; document : height (double)
docVisX .D ; document : visible X position (double § = 0.0)
docVisY .D ; document : visible Y position (double § = 0.0)
docVisWid .D ; document : visible width (double § = 800.0)
docVisHei .D ; document : visible height (double § = 600.0)
docNam .S{80} ; document : name (char*80 § = 'UNTITLED')
docWinHnd .I ; document : window handle (integer)
docWinFlg .I ; document : window flags (integer § = BORDERLESS | SCREENCENTERED)
docCanHnd .I ; document : canvas handle (integer)
docCanWhl .I ; document : canvas wheel delta (integer)
docMosX .D ; document : mouse X position (integer)
docMosY .D ; document : mouse Y position (integer)
docMosOldX .D ; document : mouse old X position (integer)
docMosOldY .D ; document : mouse old Y position (integer)
docEvt .I ; document : real-time event (integer)
docEvtTyp .I ; document : real-time event type (integer)
docEvtGdt .I ; document : real-time event gadget (integer)
docEvtMnu .I ; document : real-time event menu (integer)
;- gbl dli
dliMinHei .D ; document line : minimum height (double § = 24.0)
dliImgHnd .I[64] ; document line : image handle (integer*64)
dliImgWid .D[64] ; document line : image width (double*64)
dliImgHei .D[64] ; document line : image height (double*64)
dliGdtHnd .I[64] ; document line : gadget handle (integer*64)
dliGdtX .D[64] ; document line : gadget X position (double*64)
dliGdtY .D[64] ; document line : gadget Y position (double*64)
;- gbl crs
crsWinHnd .I ; cursor window handle (integer)
crsWinFlg .I ; cursor window flags (integer)
crsWid .D ; cursor width (double § = 2.0)
crsHei .D ; cursor height (double)
crsVisDli .I ; on which visible doc line it is (integer § = -1)
crsVisDliChg .I ; to which visible doc line it goes (integer § = 1)
EndStructure
;- Procedures
Procedure gblCreate()
Define *this.gbl
With *this
*this = AllocateMemory(SizeOf(gbl) )
\docVisX = 0.0
\docVisY = 0.0
\docVisWid = 800.0
\docVisHei = 600.0
\crsWid = 2.0
ProcedureReturn *this
EndWith
EndProcedure
;-
Procedure gblScrollUp(*this.gbl, delta.D)
Define x.D
Define y.D
Define i.I
With *this
Delay(14)
For i = 0 To 63
x = \dliGdtX[i]
y = \dliGdtY[i] - delta ; \dliMinHei
If y + \dliImgHei[i] < 0
y + \docHei
EndIf
ResizeGadget(\dliGdtHnd[i], x, y, #PB_Ignore, #PB_Ignore)
\dliGdtY[i] = y
Next
EndWith
EndProcedure
;-
Procedure gblScrollDown(*this.gbl, delta.D)
Define x.D
Define y.D
Define i.I
Define j.I
With *this
Delay(14)
For i = 0 To 63
x = \dliGdtX[i]
y = \dliGdtY[i] + delta ; \dliMinHei
If y + \dliImgHei[i] > \docHei
y - \docHei
EndIf
ResizeGadget(\dliGdtHnd[i], x, y, #PB_Ignore, #PB_Ignore)
\dliGdtY[i] = y
Next
EndWith
EndProcedure
;-
Procedure gblSyncCursor(*this.gbl)
Define delta.D ; /!\ 2 uses !
Define x.D
Define y.D
Define w.D
Define h.D
Define *this.gbl
With *this
If \crsVisDliChg
\crsVisDli + \crsVisDliChg
\crsVisDli & 63
x = WindowX(\docWinHnd) + 64
y = WindowY(\docWinHnd) + 4 + \dliGdtY[\crsVisDli]
w = \crsWid
h = \dliImgHei[\crsVisDli] - 8
If \crsVisDliChg > 0
delta = \dliGdtY[\crsVisDli] + \dliImgHei[\crsVisDli] - \docVisHei
If delta > 0
gblScrollUp(*this, delta)
y - delta
EndIf
EndIf
If \crsVisDliChg < 0
delta = \dliGdtY[\crsVisDli]
If delta < 0
gblScrollDown(*this, - delta)
y - delta
EndIf
If delta + \dliImgHei[\crsVisDli] > \docVisHei
gblScrollDown(*this, \dliImgHei[\crsVisDli] )
y - delta
EndIf
EndIf
ResizeWindow(\crsWinHnd, x, y, w, h)
\crsVisDliChg = 0
EndIf
EndWith
EndProcedure
;-
Procedure gblNewDoc(*this.gbl)
Define i.I
Define x.D
Define y.D
Define w.D
Define h.D
With *this
\dliMinHei = 24.0
x = \docVisX
y = \docVisY
For i = 0 To 63
\dliImgWid[i] = \docVisWid
coef = (1 + Random(3) )
\dliImgHei[i] = \dliMinHei * coef
; \dliImgHei[i] = (4 + Random(91) )
\dliImgHnd[i] = CreateImage(#PB_Any, \dliImgWid[i], \dliImgHei[i], 32, RGBA(0, 0, 0, 0) )
If 1
StartDrawing(ImageOutput(\dliImgHnd[i] ) )
w = OutputWidth()
h = OutputHeight()
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, w, h, RGBA(0, 0, 0, 255) )
Box(1, 1, w - 2, h - 2, RGBA(255, 255, 255, 255) )
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(0, 0, Str(i) + " " + Str(coef), RGB(0, 0, 0) )
StopDrawing()
EndIf
\dliGdtX[i] = x
\dliGdtY[i] = y
\dliGdtHnd[i] = ImageGadget(#PB_Any, x, y, \dliImgWid[i], \dliImgHei[i], ImageID(\dliImgHnd[i] ) )
y + \dliImgHei[i]
Next
\docHei = y
\crsWinFlg = #PB_Window_BorderLess | #PB_Window_NoActivate
\crsWinHnd = OpenWindow(#PB_Any, 0, 0, 1, 1, "", \crsWinFlg, WindowID(\docWinHnd) )
SetWindowColor(\crsWinHnd, #Red)
\crsVisDli = -1
\crsVisDliChg = 1
gblSyncCursor(*this)
EndWith
EndProcedure
;-
Procedure main()
Define *this.gbl = gblCreate()
With *this
\docNam = "Untitled"
\docWinFlg = #PB_Window_BorderLess | #PB_Window_ScreenCentered
\docWinHnd = OpenWindow(#PB_Any, 0, 0, \docVisWid, \docVisHei, \docNam, \docWinFlg)
SetWindowData(\docWinHnd, *this)
\docCanHnd = CanvasGadget(#PB_Any, 0, 0, 1, 1, #PB_Canvas_Keyboard)
gblNewDoc(*this)
AddKeyboardShortcut(\docWinHnd, #PB_Shortcut_Escape, #docEsc)
AddKeyboardShortcut(\docWinHnd, #PB_Shortcut_Up, #docLastLine)
AddKeyboardShortcut(\docWinHnd, #PB_Shortcut_Down, #docNextLine)
SetActiveGadget(\docCanHnd)
Repeat
\docMosOldX = \docMosX
\docMosOldY = \docMosY
\docMosX = WindowMouseX(\docWinHnd)
\docMosY = WindowMouseY(\docWinHnd)
If \docMosX <> \docMosOldX Or \docMosY <> \docMosOldY
ResizeGadget(\docCanHnd, \docMosX, \docMosY, #PB_Ignore, #PB_Ignore)
EndIf
\docEvt = WaitWindowEvent()
\docEvtTyp = EventType()
Select \docEvt
Case #PB_Event_Menu: \docEvtMnu = EventMenu()
Select \docEvtMnu
Case #docLastLine
\crsVisDliChg = - 1
gblSyncCursor(*this)
Case #docNextLine
\crsVisDliChg = 1
gblSyncCursor(*this)
EndSelect
Case #PB_Event_ActivateWindow
;Debug "YES !"
Case #PB_Event_Gadget: \docEvtGdt = EventGadget()
If \docEvtGdt = \docCanHnd
If \docEvtTyp = #PB_EventType_MouseWheel
\docCanWhl = GetGadgetAttribute(\docCanHnd, #PB_Canvas_WheelDelta)
If \docCanWhl
For i = 1 To Abs(\docCanWhl)
\crsVisDliChg = - Sign(\docCanWhl)
gblSyncCursor(*this)
Next
EndIf
EndIf
EndIf
EndSelect
Until \docEvtMnu = #docEsc
EndWith
EndProcedure
;- *** Start ***
main()