[Logiciel 2D] Animatoon

Programmation d'applications complexes
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

[Logiciel 2D] Animatoon

Message par blendman »

salut

En ce moment, j'essaie de comprendre les gadgets, car par la suite, je voudrais refaire mon éditeur de map pour mon jeu 3Arks.
Pour comprendre les gadgets, j'essaye de créer le même logiciel 2D (peinture) que celui que j'avais réalisé avec GameMaker : animatoon.
En plus, ça me sera utile si j'y parviens :)

Merci à Kernadec, et Kwanjeen, ainsi que Le Soldat inconnu et G-rom et tous ceux qui m'aident ;).

Description
Animatoon est un logiciel de dessin et de peinture numérique, ainsi que d'animation traditionnelle 2D.
Les buts du logiciel :
- offrir des outils de peinture simulant les outils traditionnels (encre, aquarelle, crayon, feutre, pinceau...), en plus de quelques fonctions de retouches.
- offrir des outils d'animation de type traditionnelle (image par image), avec gestion de couches/calques d'animation anormal, camera, light, objet, particule, son..), des keyframe, onion skinning...

Version Actuelle : 0.58x (03.2021)

Download

Dernière version (open-source et complète) :
https://github.com/blendman/animatoon




Ancienne version :
https://github.com/blendman/Purebasic/t ... /animatoon
Version 0.156 :
http://blendman.free.fr/dev/pb/animatoo ... _0.156.zip


Screenshots

Version 0.2982 :
Image

version 0.151 :
http://blendman.free.fr/dev/pb/animatoo ... n0.151.jpg

Fonctions spéciales :
Viscosité(la peinture reste sur le pinceau et se mélange moins rapidement) :
Image

Mode aquarelle (les couleurs se mélangent entre elles, en fonction d'un pourcentage) :
Image


Fonctionnalités
Tout n'est pas encore disponible :)

1. Interfaces
commencées mais pas du tout terminées :
- menu > commencé : ouvrir/sauver un document animatoon. OK : importer une image sur un calque (jpg, png), exporter en jpg, png,bmp, tga, tiff
- onglets avec splitter : à compléter> brush éditor, nuanciers, options, calques, canaux (si j'y arrive), brush presets, couleurs
- canvas et area gadgets (à corriger) / ajouter le zoom sur le canvas, et le "pan" à la main
- sélecteur de couleur

2. Outils
Commencés :
- outils de peinture ( aquarelle, gouache, encre, crayon, fusain, stylo, feutre, pinceau encre de chine...)
- pipette : on prend la couleur soit sur le roughboard, soit directement sur le canvas (clic gauche +ctrl)
- gomme
- pot de peinture
- déplacer un calque

Commencés, mais à corriger :
- dessin : ligne, rectangle, cercle
- dégradé : plein, transparent

Non commencé :
- pattern
- sélection : rectangle, cercle, lasso (?)


Prévu, mais non commencés :
- motifs (patterns)
- "spay" et pen
- "shapes "(formes type rond, carré, etc..)
- ajout d'eau, goutte d'eau


3. Paramètres des outils
Commencés :
- changer la taille, la rotation, la transparence, la taille en X et Y, le taux de mélange
- ajouter de l'aléatoire (scatter, taille, rotation)
- fall-off : la couleur s'estompe avec le temps
- changer l'espace du brush, brush avec ligne liées

non commencés :
- random vs pression, random_vs_time (la "peinture s'estompe petit à petit)
- mode aquarelle
- dual brush
- brush animé, brush multiple, texture
- smooth, hard, smudge, sharpen/dodge

4. Calques :
- création et suppression de calque
- option (opacité, vue, bloqué..)

Disponibles, mais à revoir :
- mode de fusion

Prévu, mais non disponibles :
- filtres simples (flou, noise)
- calque de réglage : niveau, couleur, contraste, saturation, luminosité

5. Edition (fonctions simples d'éditions) :
Disponible :
- Coller depuis le
- effacer le canvas
- redimensionner une image, la surface de travail, un calque

Non disponible
- copier/coller
- undo/redo


Infos

Un grand merci à Kernadec, Kwanjeen, G-rom, Le Soldat Inconnu, Djes, Falsam, Dobro, Attomo, et tous ceux qui directement ou indirectement ont contribué ou contribuent, et à tous ceux qui contribuent ou contribueront directement ou indirectement :).

Je n'ai pas testé sous linux et mac, si quelqu'un veut bien tester cela serait super :).


Si vous avez des remarques, des questions ou si vous souhaitez participer, surtout n'hésitez pas ;).

Merci encore
Dernière modification par blendman le mer. 17/mars/2021 17:04, modifié 20 fois.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: [Logiciel 2D] Animatoon

Message par Kwai chang caine »

Bonjour BLENDMAN

Erreur ligne 455 :(

Code : Tout sélectionner

  DEC x2
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [Logiciel 2D] Animatoon

Message par blendman »

Kwai chang caine a écrit :Bonjour BLENDMAN

Erreur ligne 455 :(

Code : Tout sélectionner

  DEC x2
coucou KCC

Ah oui, j'ai oublié de préciser qu'il fallait cocher la case :
"activer l'assembleur en ligne" dans les options du compilateur ;)

Je le rajoute au premier message, merci :).

EDIT :

Nouvelle version. Ajout :
- Panneau layer, nuancier, options, etc.. à droite (inactif pour l'instant)
- menu fichier/ouvrir : ouvre une fenêtre (inactive pour l'instant)
- les sélecteurs de couleurs sont cliquables
- je charge et j'enregistre maintenant des préférences à l'ouverture/fermeture.
- on peut peindre sur toute la surface de l'image (il reste quelques bugs à régler, mais ça commence à être sympa :))

Le code (version 0.12) :

Code : Tout sélectionner

;{ infos
; PureBasic Visual Designer v3.95 build 1485 (PB4Code) et pureform aussi, hein
; blendman juin 2011
; animatoon  version 0.12
; ce code est libre, vous pouvez l'utiliser, le changer, l'améliorer, etc.. si vous le modifier, dites le moi histoire que j'ajoute des choses dans animatoon ;)
; merci à Kernadec et Kwandjeen, ainsi que Le Soldat Inconnu, Djes, G-rom, Dobro...
; thanks to : Syntax Error, for this First help (canvas test example)
;}

;{ enumeration, constante
Enumeration ; image
  #brush = 1
  #pbrush = 5
  #previewbrush = 21
  #previewcoloBG = 22
  #previewcoloFG = 23
  #saveimage = 500
  #IMAGE_LoadSave  =501
EndEnumeration

;- MenuBar Constants
Enumeration
  #MenuBar_0
EndEnumeration

Enumeration
  #menu1
  #menu2
  #menu3
  #menu4
  #menu5
  #menu6
  #menu7
  #menu8
  #menu9
  #MENU_3
  #MENU_4
  #MENU_5
EndEnumeration

;- Gadget Constants
Enumeration
  #canvas   
  #container0
  #cont_layer
  #cont_swatch  
  #Panel_0
  #Panel_r
  #panel_r2
  #panel_r3
  #panel_r4     
  #imagegadget
  #imagegadget2
  #imagegadget3
  #imagegadget4
  #preview_brush
  #previewcoloBG_img
  #previewcoloFG_img  
  #scroll
  #ScrollBar_0
  #ScrollBar_1  
  #splitter_0
  #splitter_1 
  #splitter_2
  #splitter_3  
  #Combo_0
  #Combo_1  
  #TrackBar_0
  #TrackBar_1
  #TrackBar_2
  #TrackBar_3
  #TrackBar_4
  #TrackBar_5
  #TrackBar_6
  #TrackBar_7
  #tb_layer_op  
  #Radio_0
  #CheckBox_0
  #CheckBox_1
  #CheckBox_2
  #CheckBox_3
  #Cb_layer_op
  #textgadget_0
  #textgadget_1
  #textgadget_2
  #textgadget_3    
EndEnumeration
;}

;{ declare
;pref
Declare openAppli() : Declare CloseAppli()
; UI
Declare create_menu() : Declare panel_param()  
;update
Declare update_color()  : Declare update_preview() 
; brush
Declare DrawBrush(can,xpos,ypos)  : Declare Clear_Canvas(can,r,g,b) : Declare random_resize()  : Declare.l RotateImageEx2(ImageID, Angle.f, Mode.l=2)
;event
Declare event_paint() : Declare event_()
;}

;{ variable

;{ GENERAL 
; general UI
Global  quit.b, clscolor, preview_size.b=50, cursor, nbdial, open_menu.b = -1, pipette.b=0
; general
Global lang$, version${5}="0.12", clic_gauche.b, menu.a = 9, key.u, resize.b=1
;infos
Global zoom.u=100, info$="Pas d'outil sélectionné"
; document
Global doc_w.w=2000, doc_h.w=2000, docname${25}="Untitled"
;}
;{ UI
; canvas 
Global canvas,canvas_w = 1200,canvas_x.w = 140, canvas_y.w = 30, canvas_h = 800
; mouse
Global mouseincanvas,x,y,igad,clscolor,xx,yy, drawmode.b, event.i
; position souris, donc pinceau, etc..
Global x=-50, y=-50, DepartX=-50, DepartY=-50, rx, ry, finX, finY
; color, tool
Global color_R.a, color_G.a, color_B.a, color.i, color_BG.i, tool.a=9, defautcolor_BG.i =0, defautcolor_FG.i
defautcolor_FG=RGB(255,255,255)
;}
;{ Brush
; brush parameters
Global size.u = 300, random_size.b, transparence.a=255, brushid.w = 4, brush_dir$="blendman", brush_nb=58 ; <<<<---- note : Brush_nb is temporary ;)
; aléatoire du brush
Global random_size.b, random_rotation.b, random_scatter.b, radiusX.u=5, radiusY.u=5, scatter.u=20
;}
; event
Global event.i, WindowID, GadgetID, EventType, menuID
; preferences
openAppli()
CloseAppli()
;}

;{ init
If UseJPEGImageDecoder() = 0 Or UsePNGImageDecoder() = 0 Or UseJPEGImageEncoder() = 0 Or UsePNGImageEncoder()=0 Or UseTGAImageDecoder()=0 Or UseTIFFImageDecoder() =0
  MessageRequester("Erreur", "Erreur de chargement des decoder images") :   End : EndIf
;}

;{ images
;{ Motif canvas (checker)
LoadImage(3,"bg\bg1.jpg")
repetx =Round(canvas_w/64,1)
repety =Round(canvas_h/64,1)
;}
;{ canvas
canvas=CreateImage(#PB_Any,canvas_w,canvas_H,32)
StartDrawing(ImageOutput(canvas))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,preview_size,preview_size,RGBA(255,255,255,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For i=0 To repetx 
  For j = 0 To repety
    DrawAlphaImage(ImageID(3),i*64,j*64)
  Next j  
Next i
StopDrawing()
;}
;{ layer
CreateImage(100,canvas_w,canvas_h,32)
StartDrawing(ImageOutput(100))
Box(0,0,canvas_w,canvas_h,RGBA(255,255,255,0))
StopDrawing()
;}
;{ brush
LoadImage(1,"brush\"+brush_dir$+"\brush"+Str(brushId)+".png")
ResizeImage(1,preview_size,preview_size,#PB_Image_Smooth)
;}
;{ copy brush needed !
CreateImage(5,32,32,32); brush_copy avec lequel on peint - a brush copy to paint with
CopyImage(1,7)
;}
;{ preview Brush & Color
CreateImage(2,preview_size,preview_size,32)
; preview brush
StartDrawing(ImageOutput(2))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,preview_size,preview_size,RGBA(15,15,15,255))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,preview_size,preview_size,RGBA(125,125,125,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)    
DrawImage(ImageID(1),0,0)
StopDrawing()
; preview color selector
CreateImage(#previewcoloBG_img,30,30) ; color fg
CreateImage(#previewcoloFG_img,30,30); color bg  
; color select Front Ground color  (color_fg)   
StartDrawing(ImageOutput(#previewcoloBG_img))
Box(0,0,30,30,RGB(255,255,255))
Box(1,1,28,28,color)
StopDrawing()
; color select BackGround color (color_bg)
StartDrawing(ImageOutput(#previewcoloFG_img))
Box(0,0,30,30,RGB(255,255,255))
Box(1,1,28,28,color_BG)
StopDrawing()
;}
;}

;{ openwindow
If OpenWindow(0, 0,0,canvas_w+46+100, canvas_w+66,  "Animatoon",#PB_Window_SystemMenu | #PB_Window_ScreenCentered| #PB_Window_MinimizeGadget | #PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_Maximize) =0
  End :  EndIf
SetWindowTitle(0,"Animatoon "+version$+" - ["+docname$+"]")
SmartWindowRefresh(0,1)
If bg_color = 1 : SetWindowColor(0,#Gray) : EndIf ; pour plus tard (customisation de l'interface)
;{ menu
create_menu()
;}
;{ image gadget ("canvas")
If canvas_gadget = 0
  igad=ImageGadget(#PB_Any, canvas_x, canvas_y, canvas_w,canvas_h, ImageID(canvas))
EndIf  
;}
;{ toolbar  
    If CreateToolBar(0, WindowID(0))
      ToolBarStandardButton(0, #PB_ToolBarIcon_New)
      ToolBarToolTip(0, 0, "Nouveau")
      ToolBarStandardButton(1, #PB_ToolBarIcon_Open)
      ToolBarToolTip(0, 1, "Ouvrir")
      ToolBarStandardButton(2, #PB_ToolBarIcon_Save)
      ToolBarToolTip(0, 2, "Enregistrer")
      ToolBarSeparator()
      ToolBarStandardButton(10, #PB_ToolBarIcon_Delete)
      ToolBarSeparator()
      ToolBarStandardButton(11, #PB_ToolBarIcon_Undo)
      ToolBarStandardButton(12, #PB_ToolBarIcon_Redo)
      ToolBarSeparator()
    EndIf    
;}
;{ Panel tool 
panel_param()  
;}
;{ canvas & scrollarea
ScrollAreaGadget(#Scroll, canvas_x,canvas_y,WindowWidth(0)-140-150 ,WindowHeight(0)-76, doc_w+150, doc_h+50, 30)
SetGadgetColor(#Scroll,#PB_Gadget_BackColor,#Gray)
CanvasGadget(#canvas,0,0,doc_w,doc_h,#PB_Canvas_ClipMouse|#PB_Canvas_GrabMouse|#PB_Canvas_Keyboard)
CloseGadgetList()

SplitterGadget(#splitter_0,0,30,WindowWidth(0)-150,WindowHeight(0)-72,#container0,#scroll,#PB_Splitter_Vertical|#PB_Splitter_FirstFixed)
SetGadgetState(#Splitter_0, 150)
SetGadgetAttribute(#splitter_0,#PB_Splitter_FirstMinimumSize ,80)
SetGadgetAttribute(#splitter_0,#PB_Splitter_SecondMinimumSize ,300) 
;}
;{ panel layer, etc.
    
;Nuanciers
ContainerGadget(#cont_layer, 0,0,0,0,#PB_Container_Single) 
; nuanciers
PanelGadget(#Panel_r2, 0,30, WindowWidth(0)-156,120)      ;
AddGadgetItem(#Panel_r2, 0, "Nuanciers")       
AddGadgetItem(#Panel_r2, 1, "Options")     
CloseGadgetList()  

; brush
PanelGadget(#panel_r3, 0,150, WindowWidth(0)-156, 200) 
AddGadgetItem(#Panel_r3, 0, "Brush")
AddGadgetItem(#Panel_r3, 1, "Presets")
CloseGadgetList() 
; layers
PanelGadget(#Panel_r, 0,350, WindowWidth(0)-156, 600) 
AddGadgetItem(#Panel_r, 0, "Layers")
; opacité calque (opacity layer)
TrackBarGadget(#tb_layer_op, 0, 10, 110, 20, 0, 100)
;calque mode de fusion   (blendmode layers)   
ComboBoxGadget(#Combo_1, 0, 30, 90, 20,#PB_ComboBox_UpperCase)
AddGadgetItem(#Combo_1, -1,"Normal")
AddGadgetItem(#Combo_1, 1,"Multiply")
AddGadgetItem(#Combo_1, 2,"Color Burn")
AddGadgetItem(#Combo_1, 3,"Color Add")

AddGadgetItem(#Panel_r, 1, "Channels")

CloseGadgetList()
CloseGadgetList()


SplitterGadget(#splitter_1,0,30,WindowWidth(0),WindowHeight(0)-72,#splitter_0,#cont_layer,#PB_Splitter_Vertical|#PB_Splitter_FirstFixed)
SetGadgetState(#Splitter_1, WindowWidth(0)-150)
SetGadgetAttribute(#splitter_1,#PB_Splitter_FirstMinimumSize ,600)
SetGadgetAttribute(#splitter_1,#PB_Splitter_SecondMinimumSize ,50)


    
    ;}
;{ status bar
If CreateStatusBar(0, WindowID(0))      
  AddStatusBarField(120)
  AddStatusBarField(110)
  AddStatusBarField(250)
  AddStatusBarField(#PB_Ignore )      
  StatusBarText(0,1,"Zoom : "+Str(zoom)+"%",#PB_StatusBar_Center) 
  StatusBarText(0,2,"Taille du Document : "+Str(doc_w)+" / "+Str(doc_h),#PB_StatusBar_Raised)
  StatusBarText(0,3, info$)       
EndIf
;}
;{ shortcut keyboard  
AddKeyboardShortcut(0,#PB_Shortcut_Escape, 23) ; quit the program
AddKeyboardShortcut(0,#PB_Shortcut_X|#PB_Shortcut_Control, 44) ; erase the canvas
AddKeyboardShortcut(0,#PB_Shortcut_Shift|#PB_Shortcut_Control|#PB_Shortcut_H,50) ; Help Message


AddKeyboardShortcut(0,#PB_Shortcut_Control|#PB_Shortcut_N,20) ; ;new document
AddKeyboardShortcut(0,#PB_Shortcut_Control|#PB_Shortcut_O,21) ; ;open doc



AddKeyboardShortcut(0,#PB_Shortcut_D,100) ; random size
AddKeyboardShortcut(0,#PB_Shortcut_T,105) ; Transparence
AddKeyboardShortcut(0,#PB_Shortcut_R,106) ; color
AddKeyboardShortcut(0,#PB_Shortcut_S,107) ; change size
AddKeyboardShortcut(0,#PB_Shortcut_X,108) ; brush +
AddKeyboardShortcut(0,#PB_Shortcut_C,109) ; brush -
AddKeyboardShortcut(0,#PB_Shortcut_Alt,110) ; pipette
;}
;{ update the preview (brush & color)
rotation = RotateImageEx2(ImageID(5),r ) 
random_resize() 
; update
update_color()
update_preview() 
;}
 ;}
   
;{ la boucle - the loop
  open_menu = 0
  Repeat
    event_()
    event_paint()
  Until quit=1
  
  closeappli()
  End
  ;}
  
  
  ;########################################################################################################################

  ;- THE PROCEDURES
  
 ; save et load preferences
Procedure openAppli()
   OpenPreferences("options.ini")
  PreferenceGroup("general")  
  lang$ = ReadPreferenceString("lang","fr") 
  color = ReadPreferenceInteger("Color_FG",0)  
  color_BG = ReadPreferenceInteger("Color_BG",RGB(255,255,255))  
  color_R = Red(color)
  color_G = Green(color)
  color_B = Blue(color)
  
  PreferenceGroup("brush")
  ; read the preferences
  brush_nb = ReadPreferenceInteger("brush_nb",59)
  brush_dir$ = ReadPreferenceString("brush_directory","blendman")
  brushId = ReadPreferenceInteger("brush",1)
  space = ReadPreferenceInteger("space",1)
  size = ReadPreferenceInteger("size",1)
  transparence = ReadPreferenceInteger("transparence",255)
  tool = ReadPreferenceInteger("Tool",9)
  Debug tool
  ClosePreferences()
  menu = tool
  
  ;LoadImage(#brush,"data\"+brush_dir$+"\brush"+Str(brushId)+".png")
EndProcedure
Procedure closeAppli()
  CreatePreferences("options.ini")
  PreferenceGroup("general")
  WritePreferenceString("lang",lang$)
  WritePreferenceString("version",version$)
  WritePreferenceInteger("Color_FG",color)
  WritePreferenceInteger("Color_BG",color_BG)
  
  PreferenceGroup("brush")  
  WritePreferenceInteger("brush_nb",brush_nb)
  WritePreferenceString("brush_directory",brush_dir$)
  WritePreferenceInteger("brush",brushId)
  WritePreferenceInteger("space",space)
  WritePreferenceInteger("size",size)
  WritePreferenceInteger("transparence",transparence)
  WritePreferenceInteger("Tool",tool)
  Debug tool
  ClosePreferences()
EndProcedure
     
  ; UI, interface
Procedure Create_Menu()
    
 
    If CreateMenu(0, WindowID(0))      
      ; menu Fichier  20 à 39
      MenuTitle("Fichier")
      MenuItem(20,"Nouveau"+Chr(9)+"Ctrl+N")
      MenuItem(21,"Ouvrir"+Chr(9)+"Ctrl+O") 
      MenuBar()
      OpenSubMenu("Récent")
      MenuItem(31,"")
      CloseSubMenu()
      MenuBar()
      OpenSubMenu("Importer")
      MenuItem(24,"Importer une image sur le calque"+Chr(9)+"Ctrl+Shift+I")
      MenuItem(27,"Ouvrir une image en tant que document"+Chr(9)+"Ctrl+Shift+O")
      MenuItem(28,"Importer un preset de brush"+Chr(9)+"Ctrl+Shift+P")
      MenuItem(29,"Importer un Nuancier"+Chr(9)+"Ctrl+Shift+N")      
      CloseSubMenu()
      MenuBar()
      OpenSubMenu("Exporter")
      MenuItem(25,"Exporter L'image en jpg"+Chr(9)+"Ctrl+Shift+s")
      MenuItem(26,"Exporter L'image en png"+Chr(9)+"Ctrl+Alt+S")
      CloseSubMenu()
      MenuItem(22,"Enregistrer"+Chr(9)+"Ctrl+S") 
      MenuItem(30,"Enregistrer sous"+Chr(9)+"Ctrl+shift+alt+S") 
      MenuBar()
      MenuItem(23,"Quitter"+Chr(9)+"Esc")
      
      ; menu Edition    40 à 59 
      MenuTitle("Edition")
      MenuItem(40,"Annuler"+Chr(9)+"Ctrl+Z")
      MenuItem(41,"Refaire"+Chr(9)+"Ctrl+Y")
      MenuBar()      
      MenuItem(42,"Copier"+Chr(9)+"Ctrl+C")
      MenuItem(43,"Coller"+Chr(9)+"Ctrl+V")
      MenuItem(44,"Effacer"+Chr(9)+"Ctrl+X")
      MenuBar()
      
      ; menu vue    60 à 79
      MenuTitle("Vue")
      MenuItem(60, "Réinitialiser la vue"+Chr(9)+"(0)")
      MenuItem(61, "Centrer la vue"+Chr(9)+"(9)")
      MenuBar() 
      MenuItem(62, "Zoom Avant"+Chr(9)+"(+)")
      MenuItem(63, "Zoom Arrière"+Chr(9)+"(-)")
      MenuBar() 
      MenuItem(64, "Zoom 50%")
      MenuItem(65, "Zoom 100%")
      MenuItem(66, "Zoom 200%")
      MenuItem(67, "Zoom 400%")
      MenuItem(68, "Zoom 800%")
      MenuItem(69, "Zoom 1600%")
      MenuBar()
      MenuItem(70, "Grille"+Chr(9)+"Ctrl+G")
      MenuItem(71, "Repères"+Chr(9)+"Alt+R")
      MenuItem(72, "Régles"+Chr(9)+"Ctrl+R")
      
      ; menu image 80 à 99
      MenuTitle("Images")
      OpenSubMenu("Mode")
      MenuItem(80,"Mode RGB")      
      CloseSubMenu()
      MenuItem(81,"Taille de l'image")
      MenuItem(82,"Taille de la zone de travail")
      
      ; Menu Calques 180 à 199
      MenuTitle("Calques")
      MenuItem(180, "Créer un Nouveau Calque")
      MenuItem(181, "Supprimer la calque actif")
      MenuBar()
      OpenSubMenu("Calque de réglages")
      MenuItem(182,"Niveau")      
      CloseSubMenu()
      
      ; Menu outils 0 à 19
      MenuTitle("Outils")
      MenuItem(1, "Ligne")
      MenuItem(2, "Ligne Epaisse")
      MenuBar()
      MenuItem(3, "Cercle")
      MenuItem(4, "Cercle vide")
      MenuItem(5, "Box")
      MenuItem(10,"Box vide")
      MenuItem(11,"Roundbox")
      MenuBar()
      MenuItem(12, "Brosse Ronde")
      MenuItem(9, "Pinceau")
      MenuItem(13, "Pinceau lié")
      MenuBar()
      MenuItem(14, "SpeedLine (radial)")
      
      ; Menu paramètres 100 à 119
      MenuTitle("Paramètres")
      MenuItem(100,"Taille Aléatoire"+Chr(9)+"D")
      SetMenuItemState(0,100,random_size)
      MenuItem(101,"Rotation Aléatoire")
      SetMenuItemState(0,101,random_rotation)
      MenuItem(102,"Diffusion Aléatoire")
      SetMenuItemState(0,101,random_scatter)
      MenuBar()
      MenuItem(103,"Diffusion") 
      MenuItem(104,"Brush Space") 
      MenuItem(105, "Transparence"+Chr(9)+"T")
      MenuItem(106, "Couleur"+Chr(9)+"R")
      MenuItem(107, "Taille"+Chr(9)+"S")     
      MenuItem(108,"Next Brush"+Chr(9)+"C")
      MenuItem(109,"Previous Brush"+Chr(9)+"X")    
      
      ; menu Interface 120 à 139
      MenuTitle("Interface")  
      MenuItem(120,"Masquer/afficher tout"+Chr(9)+"Tab")        
      MenuBar()
      MenuItem(121,"Afficher les Nuanciers") 
      MenuItem(122,"Afficher les Options")        
      MenuBar()
      MenuItem(123,"Afficher les Brushes")
      MenuItem(124,"Afficher les Presets de Brushes")
      MenuBar()
      MenuItem(125,"Afficher les Calques")
      MenuItem(126,"Afficher les Canaux")  
      
      ; menu fenêtre 140 à 159
      MenuTitle("Fenêtre") 
      MenuItem(140,"") 
      OpenSubMenu("Préférences")
      MenuItem(146,"Langues")
      MenuItem(147,"Couleurs Interface")
      CloseSubMenu()
      
      ; Menu Aides 160 à 179
      MenuTitle("Aides")
      MenuItem(160,"A propos")
      MenuItem(161,"Mise à jour")
      MenuBar()
      MenuItem(162,"Aide (html)") 
      MenuItem(163,"Aide (txt)") 
      MenuBar()
      

    EndIf
  
EndProcedure
Procedure panel_param()     
    If ContainerGadget(#container0,0,30,130,WindowHeight(0)-72-60)
      PanelGadget(#Panel_0, 0, 0, WindowWidth(0)-600, WindowHeight(0)-72-30-60)
      SetGadgetColor(#panel_0,#PB_Gadget_BackColor,#Gray)
      AddGadgetItem(#Panel_0, 0, "Gen")
      ;ImageGadget(#imagegadget,  10, 10, 50, 50, ImageID(1),#PB_Image_Border|#PB_Image_Smooth) 
      
      TextGadget    (#textgadget_0, 10, 88, 120, 20,"Taille", #PB_Text_Center)
      TrackBarGadget(#TrackBar_0, 8, 108, 110, 20, 0, 500)
      
      TextGadget    (#textgadget_1, 10, 128, 120, 20,"Opacité", #PB_Text_Center)
      TrackBarGadget(#TrackBar_1, 8, 148, 110, 20, 0, 255)
      
      TextGadget    (#textgadget_2, 10, 168, 120, 20,"Diffusion", #PB_Text_Center)
      TrackBarGadget(#TrackBar_2, 8, 188, 110, 20, 0, 100)
      
      ;OptionGadget(#Radio_0, 8, 198, 20, 30, "")
      CheckBoxGadget(#CheckBox_0, 8, 258, 200, 20, "Taille")
      CheckBoxGadget(#CheckBox_1, 8, 278, 200, 20, "Rotation")
      CheckBoxGadget(#CheckBox_2, 8, 298, 200, 20, "Diffusion")
      CheckBoxGadget(#CheckBox_3, 8, 318, 200, 20, "Couleur")
      AddGadgetItem(#Panel_0, 1, "Dyn")
      ComboBoxGadget(#Combo_0, 10, 30, 90, 20)
      For a = 1 To 5
          AddGadgetItem(#Combo_0, -1,"Elément de liste déroulante " + Str(a))
        Next
      AddGadgetItem(#Panel_0, 2, "Coul")
      TrackBarGadget(#TrackBar_5, 8, 68, 110, 20, 0, 10)
      TrackBarGadget(#TrackBar_6, 8, 88, 110, 20, 0, 10)
      TrackBarGadget(#TrackBar_7, 8, 108, 110, 20, 0, 10)
      CloseGadgetList()
      ; preview panel
      ImageGadget(#preview_brush,10, WindowHeight(0)-150, 50, 50, ImageID(2),#PB_Image_Border|#PB_Image_Smooth) 
      ; couleurs
      ImageGadget(#previewcoloBG, 100, WindowHeight(0)-130, 30, 30, ImageID(#previewcoloBG_img),#PB_Image_Border) 
      ImageGadget(#previewcoloFG,80, WindowHeight(0)-150, 30, 30, ImageID(#previewcoloFG_img),#PB_Image_Border) 
      
      CloseGadgetList()         
    EndIf   
EndProcedure
Procedure coloriz(couleur)
  color_R=Red(couleur)
  color_G=Green(couleur)
  color_B=Blue(couleur)
  EndProcedure

; brush
Procedure paint_brush()  
  
  CopyImage(1,7) ; on copie le brush pour travailler sans modifier l'origine
  ResizeImage(7,size,size) ;on modifie la taille du brush  
  brush_w = ImageWidth(7)
  brush_h = ImageHeight(7)
  StartDrawing(ImageOutput(7))
  For y=0 To ImageHeight(7)-1
    For x=0 To ImageWidth(7)-1  
      DrawingMode(#PB_2DDrawing_AlphaChannel)
      alpha_point = Alpha(Point(x,y))-(255-transparence) ;on récupère l'alpha du brush (pixel par pixel) qu'on modifie par la valeur transparence
      If alpha_point<0
        alpha_point = 0
      EndIf
      DrawingMode(#PB_2DDrawing_AllChannels)
      Plot(x,y,RGBA(color_R, color_G,color_B,alpha_point)) ;on redessine chaque point par la nouvelle couleur et l'alpha modifiée
    Next x
  Next y 
  StopDrawing()
EndProcedure

; transform - brush
Procedure.l RotateImageEx2(ImageID, Angle.f, Mode.l=2) ; Rotation d'une image d'un angle en °
   Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.l, NewImageID, Mem, n, nn, bm.BITMAP
   
   Angle = Angle * #PI / 180 ; On convertit en radian
   
   Cos.f = Cos(Angle)
   Sin.f = Sin(Angle)
   
   CouleurFond = 0
   
   GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
   
   bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
   bmi\bmiHeader\biWidth = bm\bmWidth
   bmi\bmiHeader\biHeight = bm\bmHeight
   bmi\bmiHeader\biPlanes = 1
   bmi\bmiHeader\biBitCount = 32
   
   bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
;    Select Mode
;       Case 1
;          bmi2\bmiHeader\biWidth = bm\bmWidth
;          bmi2\bmiHeader\biHeight = bm\bmHeight
;       Case 2
         bmi2\bmiHeader\biWidth = Round(Sqr(bm\bmWidth * bm\bmWidth + bm\bmHeight * bm\bmHeight), 1)
         bmi2\bmiHeader\biHeight = bmi2\bmiHeader\biWidth
;       Default
;          bmi2\bmiHeader\biWidth = Round(bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin), 1)
;          bmi2\bmiHeader\biHeight = Round(bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin), 1)
;    EndSelect
   bmi2\bmiHeader\biPlanes = 1
   bmi2\bmiHeader\biBitCount = 32
   
   Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
   If Mem
      Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
      If Mem2
         
         hdc = CreateCompatibleDC_(GetDC_(ImageID))
         If hdc
            GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
            DeleteDC_(hdc)
         EndIf
         
         CX1 = bm\bmWidth - 1
         CY1 = bm\bmHeight - 1
         CX2 = bmi2\bmiHeader\biWidth - 1
         CY2 = bmi2\bmiHeader\biHeight - 1
         
         Mem01 = Mem + bm\bmWidth * 4
         Mem10 = Mem + 4
         Mem11 = Mem01 + 4
         
         Mem2Temp = Mem2
         
         For nn = 0 To CY2
            y1b.l = nn * 2 - CY2
            Temp1.f = CX1 - y1b * Sin
            Temp2.f = CY1 + y1b * Cos
            For n = 0 To CX2
               x1b.l = n * 2 - CX2
               
               x1.f = (Temp1 + x1b * Cos) / 2
               y1.f = (Temp2 + x1b * Sin) / 2
               
               x2.l = x1
               y2.l = y1
               
               If x1 < x2
                  DEC x2
               EndIf
               If y1 < y2
                  DEC y2
               EndIf
               
               x2b = x2 + 1
               y2b = y2 + 1
               
               If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est completement en dehors de l'image
                  
                  fx.f = x1 - x2
                  fy.f = y1 - y2
                  f00.f = (1 - fx) * (1 - fy)
                  f01.f = (1 - fx) * fy
                  f10.f = fx * (1 - fy)
                  f11.f = fx * fy
                  
                  MemTemp = (x2 + y2 * bm\bmWidth) * 4
                  
                  If x2 >= 0 And x2 <= CX1
                     If y2 >= 0 And y2 <= CY1
                        c00 = PeekL(Mem + MemTemp)
                     Else
                        c00 = 0
                     EndIf
                     If y2b >= 0 And y2b <= CY1
                        c01 = PeekL(Mem01 + MemTemp)
                     Else
                        c01 = 0
                     EndIf
                  Else
                     c00 = 0
                     c01 = 0
                  EndIf
                  If x2b >= 0 And x2b <= CX1
                     If y2 >= 0 And y2 <= CY1
                        c10 = PeekL(Mem10 + MemTemp)
                     Else
                        c10 = 0
                     EndIf
                     If y2b >= 0 And y2b <= CY1
                        c11 = PeekL(Mem11 + MemTemp)
                     Else
                        c11 = 0
                     EndIf
                  Else
                     c10 = 0
                     c11 = 0
                  EndIf
                  
                  Channel00 = c00 >> 24 & $FF
                  Channel01 = c01 >> 24 & $FF
                  Channel10 = c10 >> 24 & $FF
                  Channel11 = c11 >> 24 & $FF
                  Alpha = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
                  
                  Channel00 = c00 >> 16 & $FF
                  Channel01 = c01 >> 16 & $FF
                  Channel10 = c10 >> 16 & $FF
                  Channel11 = c11 >> 16 & $FF
                  Bleu = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
                  
                  Channel00 = c00 >> 8 & $FF
                  Channel01 = c01 >> 8 & $FF
                  Channel10 = c10 >> 8 & $FF
                  Channel11 = c11 >> 8 & $FF
                  Vert = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
                  
                  Channel00 = c00 & $FF
                  Channel01 = c01 & $FF
                  Channel10 = c10 & $FF
                  Channel11 = c11 & $FF
                  Rouge  = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
                  
                  PokeL(Mem2Temp, Rouge | Vert << 8 | Bleu  << 16 | Alpha << 24)
                  
               Else
                  PokeL(Mem2Temp, 0)
               EndIf
               
               Mem2Temp + 4
               
            Next
         Next
         
         ; On crée la nouvelle image
         NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight, 32)
         hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
         If hdc
            SetDIBits_(hdc, ImageID(NewImageID), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
            DeleteDC_(hdc)
         EndIf
         
         FreeMemory(Mem2)
      EndIf
      FreeMemory(Mem)
   EndIf
   
   ProcedureReturn NewImageID
EndProcedure
Procedure random_resize() 
  siz =20+Random(size-20)*(1-random_size) + random_size*80
  CopyImage(7,5)
  ResizeImage(5,siz,siz,0)
EndProcedure

; update 
Procedure update_canvas(can)
  StartDrawing(CanvasOutput(0)) 
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(can),0,0)
    StopDrawing()
  EndProcedure
Procedure update_color()

; color select Front Ground color  (color_fg)   
StartDrawing(ImageOutput(#previewcolofG_img))
Box(0,0,30,30,RGB(255,255,255))
Box(1,1,28,28,color)
StopDrawing()

; color select BackGround color (color_bg)
StartDrawing(ImageOutput(#previewcolobG_img))
Box(0,0,30,30,RGB(255,255,255))
Box(1,1,28,28,color_BG)
StopDrawing()

SetGadgetState(#previewcoloBG,ImageID(#previewcoloBG_img))
SetGadgetState(#previewcoloFG,ImageID(#previewcoloFG_img))
paint_brush()  
EndProcedure
Procedure update_preview()  
  CopyImage(1,2)
  CopyImage(1,23)
  ResizeImage(2,preview_size,preview_size) 
  ResizeImage(23,preview_size,preview_size) 
  StartDrawing(ImageOutput(2))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  Box(0,0,preview_size,preview_size,RGBA(15,15,15,255))
  DrawingMode(#PB_2DDrawing_Default)   
  Box(0,0,preview_size,preview_size,RGBA(125,125,125,0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)    
  DrawImage(ImageID(23),0,0)
  StopDrawing()  
  SetGadgetState(#preview_brush,ImageID(2))  
EndProcedure


; brush - drawing
Procedure DrawBrush(can,xpos,ypos)
  If mouseincanvas=1    
    random_resize()  
    If rotation = 0
      r=Round(Random(360),0)
      rotation = RotateImageEx2(ImageID(5),r)
      x1 = ImageWidth(rotation)/2
      y1 = ImageHeight(rotation)/2   
    Else 
      x1 = ImageWidth(5)/2
      y1 = ImageWidth(5)/2
    EndIf
    StartDrawing(CanvasOutput(0));ImageOutput(can)) 
    DrawingMode(#PB_2DDrawing_AlphaBlend)
   
    DrawAlphaImage(ImageID(rotation),xpos-x1,ypos-y1,transparence)
    ;DrawAlphaImage(ImageID(5),xpos-x1,ypos-y1,transparence)
    StopDrawing()
    FreeImage(rotation)
  EndIf
EndProcedure
Procedure EraseBrush(can,xpos,ypos)
  If mouseincanvas=1    
    random_resize()         
    r=Round(Random(360),0)
    rotation = RotateImageEx2(ImageID(5),r)
    x1 = ImageWidth(rotation)/2
    y1 = ImageHeight(rotation)/2 
    
    StartDrawing(ImageOutput(100)) 
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    DrawAlphaImage(ImageID(rotation),xpos-x1,ypos-y1,transparence)
    StopDrawing()
    
    SetGadgetState(igad,ImageID(can))
    update_canvas(can)   
    FreeImage(rotation)
  EndIf
EndProcedure
Procedure Clear_Canvas(can,r,g,b)
  Static bkgcolor
  bkgcolor=RGB(r,g,b)
  
  StartDrawing(CanvasOutput(0));ImageOutput(100))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  Box(0,0,doc_w+5,doc_h+5,RGBA(0,0,0,0))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0,0,doc_w+5,doc_h+5,bkgcolor) 
  StopDrawing()
  
;   StartDrawing(ImageOutput(can))
;   DrawImage(ImageID(100),0,0)
;   StopDrawing()
;   
  
  ;SetGadgetState(igad,ImageID(can))
  ;update_canvas(can)
EndProcedure 

; menu
Procedure Doc_new(number, nom$="")
  flag = #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_WindowCentered
    w = 400
    h = 300
    If OpenWindow(number, x,y, w, h, nom$, flag)
      pixel_x = 640
      pixel_y = 480
      reso = 72
      TextGadget(114,10,10,50,50, "Nom :")
      StringGadget(125, 40, 10, 200, 20, "")
      
      Frame3DGadget(110, 10, 30, 300, 130, "Image")
      
      TextGadget(111,0,60,80,20,"Largeur : ", #PB_Text_Right) 
      StringGadget(116, 100,  60, 55, 20, Str(pixel_x), #PB_String_Numeric)
      TextGadget(112,0,80,80,20,"Hauteur : ", #PB_Text_Right) 
      StringGadget(117, 100,  80, 55, 20, Str(pixel_y), #PB_String_Numeric)
      TextGadget(113,0,100,80,20,"Résolution : ", #PB_Text_Right) 
      StringGadget(118, 100,  100, 55, 20, Str(reso), #PB_String_Numeric)      
 
      poids = pixel_x*pixel_y*3
      oct$ = "Ko"
      If poids <1000
        poids = 1
      ElseIf poids > 1000 And poids<1000000
        poids =Round(poids /1000,1)
      ElseIf poids >1000000
        poids = Round(poids/100000,1)
        oct$="Mo"
      EndIf
      
      TextGadget(115,0,120,80,20,"Taille : ", #PB_Text_Right)
      TextGadget(119,105,120,100,20,Str(poids)+" "+oct$)
      TextGadget(126,0,140,80,20,"Mode : ", #PB_Text_Right) 
            
      Frame3DGadget(120, 10, 180, 300, 110, "Remplir avec :")
      OptionGadget(121, 20,200,150,20,"Blanc")
      OptionGadget(127, 20,220,150,20,"Couleur d'arrière-plan")
      OptionGadget(123, 20,240,150,20,"Couleur d'avant-plan")
      OptionGadget(124, 20,260,150,20,"Transparent")
      
      ButtonGadget(108,320,20,70,25,"Ok")
      ButtonGadget(109,320,50,70,25,"Annuler")
      StickyWindow(number,1) 
    EndIf
    
  
  EndProcedure

; event
Procedure event_paint()   
 ;{ x , y position of the mouse  
  xx = WindowMouseX(0)-canvas_x+GetGadgetAttribute(#Scroll,#PB_ScrollArea_X)  :  yy =WindowMouseY(0)-canvas_y+GetGadgetAttribute(#Scroll,#PB_ScrollArea_Y)
 ; x=WindowMouseX(0)-120-5 : y=WindowMouseY(0)-20-24
  key = GetGadgetAttribute(#canvas,#PB_Canvas_Key)
  
  If (xx>=-5 And xx<doc_w) And (yy>=-5 And yy<doc_h);(x>=-15 And x<canvas_w+150) And (y>=-150 And y<canvas_h+120)
    mouseincanvas=1
    StatusBarText(sb, 0, "Coords: "+Str(xx)+","+Str(yy))
;     If cursor = 0
;       Debug cursor
;       SetMouseCursor(#PB_Cursor_Busy)
;       cursor = 1
;     EndIf      
  Else
    mouseincanvas=0
    StatusBarText(sb, 0, "Coords: xxx,xxx")
;     If cursor = 1
;       SetMouseCursor(#PB_Cursor_Default)
;       cursor = 0
;     EndIf    
  EndIf
  ;}
        
  Select event
      ;{ event menu   
    Case #PB_Event_Menu 
      menuID = EventMenu()
      Select menuID
          
          
        Case 20 ; new doc
          open_menu = 1
          Doc_new(6,"Nouveau Document")
          
        Case 21 ; open doc          
                  
        Case 23 ; escape
          quit = 1
          
        Case 44 ;ctrl+X
          Clear_Canvas(canvas,255,255,255)
                    
        Case 50
          MessageRequester("Help", "Middle clic To Erase the canvas in black")
          
        Case 100 ; key D          
          random_size = 1-random_size  
          
        Case 105 ; T
          transparence = Val(InputRequester("transparence","transparence of the brush",Str(transparence)))
          If transparence <=0
            transparence = 1
          ElseIf transparence > 255
            transparence=255            
          EndIf
          
        Case 106 ;R - color
          col = ColorRequester(color)
          coloriz(col)
          color= col
          paint_brush()
          update_color() 
          
        Case 107 ; key S
          size = Val(InputRequester("Size","Size of the brush",Str(size)))
          If size <=0
            size = 1
          ElseIf size >1000
            size =1000
          EndIf  
          paint_brush()
          
        Case 108 ; key X
          If brushid >1
            brushId - 1         
          Else 
            brushId = brush_nb
          EndIf
          Debug brushId
          LoadImage(1,"brush\"+brush_dir$+"\brush"+Str(brushId)+".png")
          paint_brush()
          update_preview()
          
        Case 109  ; key C   
          If brushid <brush_nb
            brushId + 1         
          Else 
            brushId = 1
          EndIf
          Debug brushId
          LoadImage(1,"brush\"+brush_dir$+"\brush"+Str(brushId)+".png")          
          paint_brush()
          update_preview()
          
        Case 110 ; alt
          If pipette = 0
            pipette = 1
            Debug pipette
          EndIf
        
          
          
        
       
          
        
      EndSelect 
      ;} 
      ;{ gadget event
    Case #PB_Event_Gadget      
      If EventGadget()  
        Select EventType()
          Case #PB_EventType_LeftClick
            If open_menu =0 And mouseincanvas
              If pipette = 0
                drawmode=1 :DrawBrush(canvas,xx,yy) 
              ElseIf pipette = 1                
                color_R=Red(Point(xx,yy))
                color_G=Green(Point(xx,yy))
                color_B=Blue(Point(xx,yy))
                color= RGB(color_R, color_G,color_B)
                paint_brush()
                update_color()
                Debug pipette
              EndIf            
            EndIf        
          Case #PB_EventType_RightClick
            If open_menu =0 And mouseincanvas
              drawmode=2 : eraseBrush(canvas,xx,yy)  ; Attention : bug
            EndIf  
        EndSelect  
      EndIf
            
    Case 513 ; LMB pressed
      If mouseincanvas
        ;drawmode=1 : DrawBrush(canvas,xx,yy)
      EndIf
      
    Case #WM_LBUTTONUP;514
      drawmode=0 ; LMB released
      
    Case #WM_RBUTTONUP
      drawmode=0 ; RMB released
      
    Case 512 ; mouse moving
      If mouseincanvas
        If drawmode=1 And open_menu = 0
          DrawBrush(canvas,xx,yy)
        ElseIf drawmode=2 And open_menu = 0
          EraseBrush(canvas,xx,yy)
        EndIf
      EndIf
      
    Case #WM_RBUTTONUP ;516 ; RMB;
      If mouseincanvas
        drawmode = 0
      EndIf
    
    Case #WM_MBUTTONDOWN;
      If mouseincanvas
        If open_menu = 0
          Clear_Canvas(canvas,0,0,0)
        EndIf
      EndIf
      
    Case #WM_KEYUP
      If pipette = 1
        pipette = 0 : Debug pipette        
      EndIf
      
    Case #VK_LMENU
      Debug "pipette"
      If pipette = 0
        pipette = 1 : Debug pipette        
      EndIf
      
    Case #PB_Event_CloseWindow 
      If GetActiveWindow() = 0
        quit = 1
      Else 
        CloseWindow(GetActiveWindow())
        open_menu = 0
      EndIf
  EndSelect
  ;}
EndProcedure
Procedure event_()
  Event = WaitWindowEvent() ; This line waits until an event is received from Windows  
  WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures  
  GadgetID = EventGadget() ; Is it a gadget event?  
  EventType = EventType() ; The event type

  Select Event 
    Case #PB_EventType_KeyDown 
    ;{ menu
    Case #PB_Event_Menu    
      MenuID = EventMenu()    
      Select MenuID 
        Case 0 ; 
          
        Case 1
          
        Case 2          
          
        Case 20
          
        Case 23 ; escape
          quit = 1
        Case 30          
          
      EndSelect      
      ;}
      ;{ gadget
    Case #PB_Event_Gadget    
      Select GadgetID 
        Case #Panel_0 
          
        Case #ScrollBar_0      
        Case #ScrollBar_1 
          
        Case #TrackBar_0
        Case #TrackBar_1 
          
        Case #Radio_0      
        Case #CheckBox_0    
        Case #CheckBox_1 
        Case #CheckBox_2 
          
        Case #previewcoloFG ; couleur FG
          If EventType() = #PB_EventType_LeftClick       
            color =ColorRequester(color)         
            coloriz(color)
            update_color()            
          EndIf
          
        Case #previewcoloBG ; couleur BG
          If EventType() = #PB_EventType_LeftClick       
            color_BG =ColorRequester(color_BG) 
            coloriz(color)
            update_color()            
          EndIf
      EndSelect 
      ;}
  EndSelect   
EndProcedure
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: [Logiciel 2D] Animatoon

Message par Anonyme2 »

Même erreur que KCC, soit il manque une macro/procedure soit c'est de l'assembleur pour décrémenter x2 et y2, dans ce cas l'asm n'apporte rien car x2 -1 produit un très bon code asm. Il manque une procedure je pense.

Sinon j'ai une remarque sur le code en général, c'est pas une critique, c'est à prendre ou à laisser.
Si tu souhaites un code stable, il faut tout tester, la création des fenêtres, gadget, chargement d'images, allocation mémoire etc et prévoir du code en cas d'erreur,
Et surtout pas de

Code : Tout sélectionner

Procedure update_canvas(can)
    StartDrawing(CanvasOutput(0)) 
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(can),0,0)
    StopDrawing()
EndProcedure
mais plus un truc du genre (tester aussi CanvasOutput(0))

Code : Tout sélectionner

Procedure update_canvas(can)
    If IsImage(can) = 0
        ;// c'est une erreur, on retourne
        ProcedureReturn xx
    EndIf
    
    If StartDrawing(CanvasOutput(0)) = 0
        ;// c'est une erreur, on retourne
        ProcedureReturn xx
    EndIf

    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(can),0,0)
    StopDrawing()
EndProcedure
Il me semble que ton projet sera assez conséquent, alors utilises toujours le debugger et le purifier lorsque tu développes, c'est fait pour ça.
Avec le debugger et le purifieur, j'ai une erreur ligne 98, l'image n'est pas initialisée.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [Logiciel 2D] Animatoon

Message par blendman »

Salut Denis, merci pour tes remarques, je vais en tenir compte pour les prochains codes ;).
Denis a écrit :Même erreur que KCC, soit il manque une macro/procedure soit c'est de l'assembleur pour décrémenter x2 et y2, dans ce cas l'asm n'apporte rien car x2 -1 produit un très bon code asm. Il manque une procedure je pense.
c'est dans la procédure Procedure.l RotateImageEx2(ImageID, Angle.f, Mode.l=2).

C'est une procédure du Soldat Inconnu, j'ai ajouté son nom dans la procédure d'ailleurs (en plus de le mettre dans les infos), car il faut rendre à Régis ce qui est à Régis ;).

J'ai modifié en x2-1 et y2-1, et effectivement ça marche aussi.
Donc, plus besoin de compiler avec l'option asm en ligne.
Sinon j'ai une remarque sur le code en général, c'est pas une critique, c'est à prendre ou à laisser.
Si tu souhaites un code stable, il faut tout tester, la création des fenêtres, gadget, chargement d'images, allocation mémoire etc et prévoir du code en cas d'erreur,
Et surtout pas de

Code : Tout sélectionner

Procedure update_canvas(can)
    StartDrawing(CanvasOutput(0)) 
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(can),0,0)
    StopDrawing()
EndProcedure
mais plus un truc du genre (tester aussi CanvasOutput(0))

Code : Tout sélectionner

Procedure update_canvas(can)
    If IsImage(can) = 0
        ;// c'est une erreur, on retourne
        ProcedureReturn xx
    EndIf
    
    If StartDrawing(CanvasOutput(0)) = 0
        ;// c'est une erreur, on retourne
        ProcedureReturn xx
    EndIf

    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(can),0,0)
    StopDrawing()
EndProcedure
Effectivement, pour l'instant, je n'ai pas encore tout testé, mais je vais le faire, ce sera plus stable, c'est bien vrai.
Merci de cette remarque;

Lors des tests, je dois mettre quoi à la place de :
ProcedureReturn xx

Je laisse tel quel ou je mets un message par exemple ou un break ?
Il me semble que ton projet sera assez conséquent, alors utilises toujours le debugger et le purifier lorsque tu développes, c'est fait pour ça.
Je ne sais pas s'il sera très conséquent, car pour le moment, ça va assez vite et je ne compte pas non plus bosser des mois dessus (c'est pas comme mon jeu, où j'en suis à plus de 10 000 lignes, et c'est loin d'être terminé :)).
Ce sera un "petit" logiciel de peinture numérique, mais sans l'attirail de photoshop, juste des outils de peintures, des calques, etc.. Pour faire mes couleurs de BD notamment.

Sinon, j'utilise toujours le debugger, mais je ne sais pas trop comment fonctionne le purifier en fait, je vais regarder ça.
Avec le debugger et le purifieur, j'ai une erreur ligne 98, l'image n'est pas initialisée.
ah c'est étrange.
Tu as bien dézipper le zip fourni, car cette image s'y trouve (dans bg\bg1.jpg).


Encore merci pour tes remarques, je vais en tenir compte, comme c'est souvent le cas lorsque l'on me fait des remarques.
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: [Logiciel 2D] Animatoon

Message par G-Rom »

tu peut oublier linux & mac :

Code : Tout sélectionner

GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
Tu as cloisonné le code avec des api win32
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [Logiciel 2D] Animatoon

Message par blendman »

G-Rom a écrit :tu peut oublier linux & mac :

Code : Tout sélectionner

GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
Tu as cloisonné le code avec des api win32
Comme je l'ai dit, cette procédure n'est pas de moi ;). Je cherchais un moyen de faire une rotation d'une image.
Je ne connais pas de méthode pour faire cela, si tu connais une méthode qui est disponible pour tous les systèmes, je suis preneur :).

car j'aimerai bien testé ce code sur mon Ubuntu :D.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: [Logiciel 2D] Animatoon

Message par Kwai chang caine »

Ca va mieux, ça démarre :D

Mais erreur ligne 827, quand je clique sur la scrollbar a droite :(

Code : Tout sélectionner

rotation = RotateImageEx2(ImageID(5),r)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [Logiciel 2D] Animatoon

Message par blendman »

Kwai chang caine a écrit :Ca va mieux, ça démarre :D
Mais erreur ligne 827, quand je clique sur la scrollbar a droite :(

Code : Tout sélectionner

rotation = RotateImageEx2(ImageID(5),r)
Ah, mince. comme ce n'est pas ma procédure, je ne sais pas trop quel est le problème. Il me faudrait un peu plus d'informations ;).
Tu étais en écran maximisé ?
C'est quoi ton système ?

Pour l'instant, je n'ai pas encore "bloqué" le dessin lorsque l'on clique sur les scrollbars, je pense que cela devrait résoudre le problème par la suite.
cela dit, je n'ai pas pu reproduire le problème, donc, difficile d'être sûr que ça résoudra ça.

EDIT :
bon, j'ai réussi à faire la fonction que je voulais faire depuis le début :
le mode aquarelle, autrement dit les couleurs qui se mélangent en peignant :D

Un petit screenshot pour illustrer ça :
Image

Avec l'interface complète :
http://blendman.free.fr/dev/pb/animatoo ... on0.14.jpg

Maintenant, il faut que je l'optimise car ça ne va pas très vite je trouve :).

Les nouveautés :
- ajout d'une option "mix" (touche Y ou menu paramètres), on règle le taux de mélange entre la couleur choisie et la couleur du calque (ou du dessin complet).
- preview des couleur RGB (panneau option)
- correction de quelques bugs (mais pas tous, hein, faut pas abuser :)).

le code :
http://blendman.free.fr/dev/pb/animatoo ... n_V0.14.pb
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [Logiciel 2D] Animatoon

Message par Backup »

blendman a écrit :Comme je l'ai dit, cette procédure n'est pas de moi ;). Je cherchais un moyen de faire une rotation d'une image.
tu l'a cherché .. mais pas demandé ;)

Code : Tout sélectionner

;Rotate image
; codé par Dobro
; en purebasic 4.00

Declare rotate_image(id,x,Y,degres)


UseJPEGImageDecoder ()
UsePNGImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
InitSprite ()

#dobro =1
#Police =1
#sprite =1
#image1 =1
#image2 =2

Structure image
      x.l
      Y.l
EndStructure
Global Dim image.image(1)


; ***********************************
FontID = LoadFont ( #Police , "arial" , 50, #PB_Font_Bold )
EcranX = GetSystemMetrics_ ( #SM_CXSCREEN ): ;=largeur de l'ecran
EcranY = GetSystemMetrics_ ( #SM_CYSCREEN ): ;=hauteur de l'ecran
      WindowID = OpenWindow (1, 0, 0, EcranX, EcranY, "hello" , #PB_Window_BorderLess |#PB_Window_ScreenCentered )
      
      WindowID = WindowID (1)
      Result = OpenWindowedScreen ( WindowID ,0,0, EcranX, EcranY, 1, 0,0)
      
      
      ; principe de rotation
      ;x1 = coordonée x du point rotationé
      ;Y1= coordonée y du point rotationé
      ; a = angle de rotation
      ; x1 = x * Cos(a) + Y * Sin(a);
      ; y1 = -x * Sin(a) + Y * Cos(a)
      
      ;NomFichier$ = OpenFileRequester("charge image (pas tros grosse !!)","*.jpg", "*.jpg",0)
      ; NomFichier$= "logo2.jpg"
      
      NomFichier$=OpenFileRequester("ouvrir_image","c:\","*.jpg",1)
      LoadImage ( #image1 , NomFichier$ ) 
      
      
      
      
      largeur = ImageWidth ( #image1 )
      hauteur = ImageHeight ( #image1 )
      CreateImage ( #image2 ,largeur,hauteur )
      Global Dim tabl1(largeur ,hauteur)
      
      ; ******* mise en tableau de l'image **********
      StartDrawing ( ImageOutput ( #image1 ) )
            For Y=1 To hauteur-1
                  For x=1 To largeur-1
                        tabl1(x,Y)= Point (x,Y)
                  Next x
            Next Y
      StopDrawing ()
      ;*****************************************************
      
      Resultat = InitMouse ()
      Repeat
            ExamineMouse ()
            Event= WindowEvent ()
            Delay (2)
            angle_degres=angle_degres+2 : If angle_degres>360:angle_degres=1: EndIf
            rotate_image( #image2 ,largeur, hauteur, angle_degres)
            
            ; ****** **on affiche l'image ********
            StartDrawing ( ScreenOutput ())
                  DrawImage ( ImageID ( #image2 ), 1, 1)
            StopDrawing ()
            ; *******************************
            FlipBuffers (): ; affiche l'ecran
            ClearScreen ( RGB (0, 0, 0)) : ;efface l'ecran
            Event= WindowEvent ()
            ;}
            
            If MouseButton (2) ; click droit fait quitter
                  
                  End
            EndIf
            
      Until Event= #PB_Event_CloseWindow
      
      
      Procedure rotate_image(id,x2,y2,degres)
            ; By Dobro
            ;id = id picture
            ;x2=Width
            ;y2=Height
            
            ;degres=rotation in degres
            ; *** Merci Comtois : D *********
            ;x' = x0 + (x-x0)*cos(A) + (y-y0)*sin(A)
            ;Y' = y0 - (x-x0)*sin(A) + (y-y0)*cos(A)
            x3=x2/2 ; le milieu x de l'image
            y3=y2/2 ; le milieu y de l'image
            StartDrawing ( ImageOutput ( id ) )
                  For Y=1 To y2-1
                        For x=1 To x2-1
                              ; ********* voici la formule de la rotation d'image *********
                              image(1)\x= x3+(x-x3) * Cos (degres* #PI /180) +( Y-y3)* Sin (degres* #PI /180)
                              image(1)\Y= y3-(x-x3) * Sin (degres* #PI /180) + (Y-y3)* Cos (degres* #PI /180)
                              ;*****************************************************
                              ; *** on evite que les coordonée sorte du tableau dim ****
                              If image(1) \Y <0 : image(1) \Y=0 : EndIf
                              If image(1)\Y>y2 : image(1) \Y =y2: EndIf
                              If image(1)\x>x2 : image(1)\x=x2: EndIf
                              If image(1)\x<0 : image(1)\x=0: EndIf
                              ; *****************************************
                              Plot (x,Y,tabl1( image(1)\x,image(1)\Y)) ; on dessine l'image rotaté a l'aide du tableau de points : D
                        Next x
                  Next Y
            StopDrawing ()
      EndProcedure 
la procedure c'est :
rotate_image(id,x2,y2,degres)

id=#image
X2,y2 = position de l'image
Degres = rotation en degres (34,54 ,279 ,45,30,20 ETc ...)
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: [Logiciel 2D] Animatoon

Message par G-Rom »

@Dobro , pourquoi utilise tu des commandes spécifique à un os alors qu'il y en a qui se casse le fion à codé des fonction portable ?
EcranX = GetSystemMetrics_ ( #SM_CXSCREEN ): ;=largeur de l'ecran
EcranY = GetSystemMetrics_ ( #SM_CYSCREEN ): ;=hauteur de l'ecran
ExamineDesktops()
EcranX = DesktopWidth(0)
EcranY = DesktopHeight(0)
c'est parcequ'il y a ExamineDesktops() en plus à écrire ? :mrgreen:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [Logiciel 2D] Animatoon

Message par Backup »

l'essentiel ici c'est la procedure rotate_image(id,x,Y,degres) ; qui elle l'est (multi_os) ;)


(Merci mon chien.... au passage)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [Logiciel 2D] Animatoon

Message par blendman »

Dobro a écrit :tu l'a cherché .. mais pas demandé ;)
Ah super, merci c'est cool ça ! :)

J'ai regardé, et j'ai remarqué 2 petites choses qu'il faudra que je regarde par la suite :
- lorsque j'ouvre une image avec canal alpha, je n'ai pas la transparence de l'image
- lorsque l'image tourne, elle ne tourne pas en entier dans le carré( elle est coupée)

Je regarderai ça un peu plus tard, un grand merci en tout cas !! :)
jbernard13
Messages : 1501
Inscription : dim. 18/avr./2004 15:04
Localisation : sud de la france

Re: [Logiciel 2D] Animatoon

Message par jbernard13 »

bonsoir
j'ai un message d'erreur à cette ligne
CanvasGadget(#canvas,0,0,doc_w,doc_h,#PB_Canvas_ClipMouse|#PB_Canvas_GrabMouse|#PB_Canvas_Keyboard)

quelle librairie il faut ?

merci
Jbernard13
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: [Logiciel 2D] Animatoon

Message par G-Rom »

(Merci mon chien.... au passage)
Tu dis ca pour moi ? :mrgreen:
je ne t'ai pas attendu pour pouvoir faire une rotation d'image. :mrgreen:
en plus tu ne gère même pas le filtrage bilinéaire... :mrgreen: :arrow: []
Répondre