J'ai retrouvé un ancien fichier que j'ai essayé de modifier pour l'optimiser un peu.
Il s'agit d'un système de "dalles" pour du painting2D (pour un soft comme photoshop, gimp, ou autre).
Voici une première version du code, non optimisée et non terminée.
N'hésitez pas à poster si vous changez des choses dessus, apporté des améliorations, etc
PB : 5.20beta 14
Code : Tout sélectionner
;{ infos
; test de dalle (pour painting 2D ou autre)
; dev :blendman 08/2011 - revu en 08/2013
; pb : 5.20 beta14
;}
;{ constantes
;window
Enumeration
#Win_0
EndEnumeration
; menu
Enumeration
#menu_Sortie
EndEnumeration
; gadget
Enumeration
#SA_surfaceDessin
#canvas
; Brush
#TB_BrushSize
#TB_BrushAlpha
#Button_BrushColor
EndEnumeration
; Image
Enumeration
#image_dessinfinal
#imageDessin
EndEnumeration
;}
;{ Structures
Structure s_dalle
id.a
position.point
image.w
width.w
height.w
touched.a
EndStructure
Global NewMap dalle.s_dalle()
Structure Brush
Size.i
Alpha.a
Color.i
EndStructure
Global Brush.Brush
brush\Size = 10
brush\Alpha = 150
brush\color = RGBA(0,0,0,brush\Alpha)
;}
;{ variables
Global doc_H.w = 2000, doc_W.w = 2000, draw.b, xx.w, yy.w, globalID.a, winW.w,winH.w
Global Size.w = 128, Arx.w, ArY.w, ScrollH.w,ScrollW.w
;}
;{ Procedure
Procedure DrawBG(mode=0, x1=0,y1=0)
Shared first
key$ =Str((x1-1)/Size)+"/"+Str((y1-1)/Size)
Select mode
Case 0 ; classique
If StartDrawing(ImageOutput(#image_dessinfinal))
If first = 0
Box(0,0,ScrollW,ScrollH,RGBA(255,255,255,0))
first =1
EndIf
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(0,0,ScrollW,ScrollH,RGBA(125,255,255,0))
DrawAlphaImage(ImageID(dalle(key$)\image),dalle(key$)\position\x - ArX,dalle(key$)\position\y - ArY)
StopDrawing()
EndIf
Case 1; quand on déplace l'area
If StartDrawing(ImageOutput(#image_dessinfinal))
Box(0,0,ScrollW,ScrollH,RGBA(255,255,255,0))
DrawingMode(#PB_2DDrawing_AlphaChannel); d'abord pour effacer
Box(0,0,ScrollW,ScrollH,RGBA(125,255,255,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
ForEach dalle()
DrawAlphaImage(ImageID(dalle()\image), dalle()\position\x - ArX, dalle()\position\y - ArY)
dalle()\touched = 0
Next
StopDrawing()
EndIf
If StartDrawing(CanvasOutput(#canvas))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawImage(ImageID(#image_dessinfinal),ArX,ArY)
StopDrawing()
EndIf
Case 2
EndSelect
EndProcedure
Procedure update_drawing(xx=0,yy=0,mode = 0)
key$ =Str((xx-1)/Size)+"/"+Str((yy-1)/Size)
If mode = 1
DrawBG(1,xx,yy)
Else
If StartDrawing(CanvasOutput(#canvas))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,ScrollW,ScrollH,RGBA(255,255,255,255))
DrawImage(ImageID(#image_dessinfinal),ArX,ArY)
DrawAlphaImage(ImageID(dalle(key$)\image),dalle(key$)\position\x,dalle(key$)\position\y)
StopDrawing()
EndIf
EndIf
EndProcedure
;}
;{ openwindow
ExamineDesktops()
winW = DesktopWidth(0)
winH = DesktopHeight(0)
ScrollW = winW-150-150
ScrollH = winH-120
If OpenWindow(#Win_0, 0,0,winW,winH,"Animatoon-test dalle", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_WindowCentered|#PB_Window_Maximize|#PB_Window_Minimize)
;{ Menus
MenuBar=CreateMenu(#PB_Any,WindowID(#Win_0))
MenuTitle("Fichier")
MenuItem(#menu_Sortie,"Quitter")
;}
;{ Status barre
StatusBar=CreateStatusBar(#PB_Any,WindowID(#Win_0))
AddStatusBarField(400)
AddStatusBarField(200)
;}
;{ Gadget & images
; creation des dalles (256*256), en fonction de la taille du document
nb_dalle_w = Round(doc_w/Size,0)
nb_dalle_h = Round(doc_h/Size,0)
; on crée le système de dalle, à revoir sans doute. Mais on comprend l'idée/
; on pourrait créé un canvas par dalle sans doute.
For i = 0 To nb_dalle_w ; on commence les images à 1000, ça laisse de la marge au cas où on aurait besoin de 1000 images pour le logiciel
For j = 0 To nb_dalle_h
; creation of the image for the dalle
If CreateImage(#imageDessin+a, Size,Size,32)
If StartDrawing(ImageOutput(#imageDessin+a))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,Size,Size,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(0,0,Size,Size,RGBA(155-Random(50),155-Random(50),155-Random(50),255))
StopDrawing()
EndIf
EndIf
; add the dalle on the list dalle()
AddMapElement(dalle(),Str(i)+"/"+Str(j))
dalle()\id = a
dalle()\position\y = j * Size
dalle()\position\x = i * Size
dalle()\width = Size
dalle()\height = Size
dalle()\image = #imageDessin+a
a + 1
Next j
Next i
; creation de l'image (support) pour le dessin
CreateImage(#image_dessinfinal,ScrollW,ScrollH,32, #PB_Image_Transparent)
DrawBG()
; brush tools
TrackBarGadget(#TB_BrushSize,5,10,100,20,1,500)
GadgetToolTip(#TB_BrushSize,"Régler la taille de la brosse")
SetGadgetState(#TB_BrushSize,brush\Size)
TrackBarGadget(#TB_BrushAlpha,5,40,100,20,0,255)
GadgetToolTip(#TB_BrushAlpha,"Régler l'opacité de la brosse")
SetGadgetState(#TB_BrushAlpha,brush\Alpha)
ButtonGadget(#Button_BrushColor, 5,70,20,20,"")
GadgetToolTip(#Button_BrushColor,"Choisir la couleur de la brosse")
; scrollareagadget & canvas // surface de dessin
ScrollAreaGadget(#SA_surfaceDessin,150,10,ScrollW,ScrollH,doc_W,doc_H,10,#PB_ScrollArea_Flat)
CanvasGadget(#canvas,0,0,doc_W,doc_H, #PB_Canvas_ClipMouse); ou créer plein de petits canvas, ce serait plus rapide ?
CloseGadgetList()
update_drawing()
;}
EndIf
;}
;{ Boucle
Repeat
EventID = WaitWindowEvent()
MenuID = EventMenu()
GadgetID = EventGadget()
WindowID = EventWindow()
;{ general
XX = (WindowMouseX(#Win_0)-150 + ArX)
YY = (WindowMouseY(#Win_0) -10 + ArY)
;}
Select EventID
Case #PB_Event_Menu
Select MenuID
Case #menu_Sortie
quit.b=1
EndSelect
Case #PB_Event_Gadget
Select GadgetID
Case #SA_surfaceDessin
ArX = GetGadgetAttribute(#SA_surfaceDessin,#PB_ScrollArea_X)
ArY = GetGadgetAttribute(#SA_surfaceDessin,#PB_ScrollArea_Y)
update_drawing(xx,yy, 1)
Case #canvas
Select EventType()
Case #PB_EventType_MouseMove
StatusBarText(StatusBar,0,"Coords : "+Str(XX)+","+Str(YY) + " / Dalle : "+Str(Dx)+"/"+Str(Dy))
If draw = 1
Dx = (xx-1)/Size
Dy = (yy-1)/Size
If D2x <> Dx Or D2y <> Dy
D2x = Dx
D2y = Dy
DrawBG(0,XX1,YY1)
EndIf
key$ =Str((xx-1)/Size)+"/"+Str((yy-1)/Size)
dalle(key$)\touched =1
If StartDrawing(ImageOutput(dalle(key$)\image))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Circle(XX-dalle(key$)\position\x ,YY-dalle(key$)\position\y ,brush\Size,brush\Color)
StopDrawing()
EndIf
D2x =Dx
D2y =Dy
XX1 = XX
YY1 = YY
update_drawing(xx,yy)
EndIf
Case #PB_EventType_LeftButtonDown
draw = 1
Case #PB_EventType_LeftButtonUp
draw = 0
EndSelect
Case #TB_BrushSize
Brush\Size= GetGadgetState(#TB_BrushSize)
Case #TB_BrushAlpha
Brush\Alpha= GetGadgetState(#TB_BrushAlpha)
Brush\Color = RGBA(Red(Color),Green(Color),Blue(color),Brush\Alpha)
Case #Button_BrushColor
Color = ColorRequester(Brush\Color)
Brush\Color = RGBA(Red(Color),Green(Color),Blue(color),Brush\Alpha)
EndSelect
Case #PB_Event_CloseWindow
If WindowID=#win_0
quit.b=1
EndIf
EndSelect
Until quit
;}
[edit]
Optimisation :
- ne faire un update que les dalles touchées par la souris (ou proche)
[/edit]
Autres optimisations :
- ne faire un update que une image (imagefinale) de la taille de la surface de dessin visible et non du document, en fonction d'un zoom éventuel
Si vous avez des idées d'optimisation possibles, vous pouvez aussi les poster bien sûr.