Un photoshop Like !

Programmation d'applications complexes
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Un photoshop Like !

Message par Backup »

pour rappel on peut utiliser

Resultat = OpenWindowedScreen(FenetreID, x, y, Largeur, Hauteur, RedimensionnementAuto, OffsetDroit, OffsetBas)


qui permet l'utilisation des gadgets + de l'ecran graphique !
a mon sens , c'est la meilleur soluce !! :)

de plus l'ecran graphique est une représentation de l'image sur lequel on travail , il permet d'avoir une réduction de l'image affiché
mais rien n'empêche d'avoir un systeme d'écran taille réel
je pencherai plus pour un menu flottant sur un ecran graphique que l'utilisation des fenetre windows, qui ne sont pas vraiment faite pour ça non ?

:) des idées en l'air...
Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Un photoshop Like !

Message par venom »

Il est vrai qu'il faudrais voir pour l'interface graphique. Si ont souhaite faire comme photoshop ou autres, eux il utilisent le système de fenêtre mère et fille (désoler je ne suis pas sur mon ordinateur je n'est plus la fonction en tête).
Ou alors carrément un autre système révolutionnaire :D

fin il faut prendre son temps et voir tous les points avant de commencer quel que chose je pense non ?







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

Le problème de openwindowscreen() c'est que si tu ouvres plusieurs images dans différente fenêtre, c'est pas evident a gérer !
Il faut fermer et réouvrir l'openwindowscreen() et il y a des reactions pas tres jolies ...

J'ai pensé a faire carrement un openscreen() mais il faut developper un screenGUI et là c'est sur que ça peut vite devenir un énorme boulot pour avoir les gadgets dont on a besoin ... mais ça laisse plus de liberté ! surtout que CPT BAtor et quelques personnes sur le forum anglais on posté des debut de ScreenGUI tres sympa ! Et puis ça permet de faire des gadgets sur mesure ...
l'avantage d'un openscreen() c'est aussi qu'on peu utiliser le GPU (avec certaine limitation) pour l'affichage !

Je vais essayer de vous pondre un premier code de test ... j'ai essayer avec et sans openscreen et pour l'instant je trouve plus facile sans ... :? Je vais essayer de vous poster ça dans la journée ....ça sera plus facile d'avoir un code de base pour tester !
venom a écrit : Ou alors carrément un autre système révolutionnaire :D
une idée en tête ?
Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Un photoshop Like !

Message par venom »

Oui c'est sur qu'un photoshop tout en screen sa permet de dessinées ces gadget.

Mais le problème d'un screen, c'est qu'ont est limiter dans la taille de l'écran moi par exemple je suis en 1600x1200 et tout les ordinateurs ne font pas tourner a grande résolution qu'en pensez vous ???

Mais bon a voir






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

venom a écrit :Oui c'est sur qu'un photoshop tout en screen sa permet de dessinées ces gadget.

Mais le problème d'un screen, c'est qu'ont est limiter dans la taille de l'écran moi par exemple je suis en 1600x1200 et tout les ordinateurs ne font pas tourner a grande résolution qu'en pensez vous ???

Mais bon a voir

@++
On peut tres bien ouvrir un ecran dans une fenêtre il ne devrait pas y avoir de problème de resolution.Le problème c'est plus si on veut utiliser les sprite3D car certain carte graphique ne supporte que les sprites carré et certain dimension.Mais on peut toujours utilisé la lib image comme on fait avec une fenêtre classique
Le problème c'est que l'openscreen et les fenêtre classique sont totalement complementaire là ou ça marche bien d'un côté, ça fonctionne pas de l'autre et vis versa ....

Voici un début de code ! Dite moi ce que vous en pensez ... Pas d'openscreen pour l'instant, mais on vas peut devoir y arriver
Je pense déjà a un autre problème, comment détecter si une touche est appuyer ou non sans utiliser l'openscreen. Est ce que ExamineKeyboard() fonctionne sans l'openscreen !? Sous photoshop on utilise souvent la touche Shift ou alt en plus du clic de la souris !

Voici le code que j'ai essayé de commenter au maximum !Et j'ai mis les procédures a la fin spécialement pour Dobro
Avec la souris vous pouvez dessiné sur les images.... C'est très basique ! c'est histoire d'avoir un code pour faire des choix au niveau de l'interface.

Code : Tout sélectionner

EnableExplicit

InitSprite()
InitMouse()

;-Structure des données

Structure Layer
  Active.b          ; #True ou #False si ce calque est affiché ou pas
  Image.l           ; Image originale
  
  Opacity.l         ; Transparence global de l'image : ConstAlpha de la function DrawAlphaImage()
  BlendingMode.l    ; Je sais pas si c'est gérable il y a un exemple d'utilisation sur le forum Anglais
  FusionMaskImage.l ; Image comportant le Mask de fusion si il y a !
  ;http://www.purebasic.fr/english/viewtopic.php?f=13&t=36311
EndStructure

#Max_Layer=255
Structure Document
  FileName.s        ;Nom de l'image
  Window.i          ;Fenêtre contenant l'image
  GdtImage.i        ;N° du Gadget contenant l'image
  GdtScrollBarV.i   ;N° du Gadget pour le Scrolling de l'image Verticalement
  GdtScrollBarH.i   ;N°du Gadget pour le Scrolling de l'image Horizontalement
  RenderImage.l     ;Image de rendu des layers
  Zoom.f            ;Zoom de l'image
  WorkImage.l       ; Image redimensionné et affiché !
  Depth.b           ;Profondeur de l'image (peut être n'en a t'on pas besoin ImageDepth() suffit
  ImageSelection.l  ;Image comportant le Masque de Selection
  Layer.l           ;Numero du layer selectionné
  NbLayer.l         ;Nombre de Layer
  Layers.Layer[#Max_Layer] ;Les informations sur les layers mais je ne sais pas si c'est la bonne façon de faire
EndStructure

Global NewList Workbench.Document()

;Variable général aux outils (a voir si ces infos devraient pas être propre a chaque outil)
Structure ToolsInfo
  FrontColor.l      ;Couleur de premier plan
  BackgroundColor.l ;Couleur d'arrière plan
  ToolRenderMode.l  ;Mode de rendu des outils voir enumeration si dessous Couleur/Gradiant/Pattern
EndStructure

Global ToolsInfo.ToolsInfo

Structure InterfaceInfo
  WinMain.i         ;N° de la fenêtre principal
  WinTools.i
EndStructure

Global InterfaceInfo.InterfaceInfo

;Mode de rendu d'un outil
Enumeration
  #ModeCouleur    ;On utilise les couleur de premier et arrière plan
  #ModeGradiant   ;On utilise un dégradé
  #ModePattern    ;On utilise un motif
EndEnumeration

;-Déclaration des procedures
Declare WindowMouseButton(Wnd, ButtonNr)
Declare AddLayer(Image.i=0)
Declare RenderLayers()
Declare WriteLayerPixel(x.l,y.l,Color.l)
Declare RefreshWindow()
Declare NewDocument(Name.s="")

;Creation des fenêtres de l'application part defaut
;fenêtre des menu et de quelques options des outils
InterfaceInfo\WinMain=OpenWindow(#PB_Any, 0, 0, 640, 50, "PhotoPb",#PB_Window_SystemMenu)
;fenêtre des outils
InterfaceInfo\WinTools=OpenWindow(#PB_Any, 0, WindowX(InterfaceInfo\WinMain)+WindowHeight(InterfaceInfo\WinMain), 100, 250, "Tools",#PB_Window_Tool,WindowID(InterfaceInfo\WinMain))
;Creation d'un menu fictif pour que ça ressemble a quelques chose
If CreateMenu(0, WindowID(InterfaceInfo\WinMain))
    MenuTitle("File")
      MenuItem( 1, "&New...")
      MenuItem( 2, "Open")
      MenuItem( 3, "Save")
      MenuBar()
EndIf

Define Event.l,LastWindow.i,FoundWindow.b,inscreen.b,x.l,y.l,Quit.b=#False
NewDocument() ;Ouverture d'un document
NewDocument() ;Ouverture d'un deuxième document pour montrer qu'on peut travailler sur plusieur document en même temps

;-Boucle Principal
Repeat
  Event = WaitWindowEvent()
  
  ;Si on change de fenêtre On trouve le document sur le quel on va travailler 
  If LastWindow<>GetActiveWindow()
    ForEach Workbench()
      If Workbench()\Window=GetActiveWindow() ;Hop on l'a trouvé
        SetActiveWindow(GetActiveWindow());Pas obligatoire ce truc ...:P
        Break;
      EndIf
    Next
    LastWindow=GetActiveWindow();Je mémorise la fenêtre histoire de ne pas faire la recherche a chaque boucle
  EndIf  
    
  ;Pseudo Outil histoire de dire ...
  If WindowMouseButton(WindowID(Workbench()\Window), 0)
    x=WindowMouseX(Workbench()\Window)
    y=WindowMouseY(Workbench()\Window)
    WriteLayerPixel(x,y,#Black)
  EndIf
  
  ;La c'est un peu burtal je rafraichis la fenêtre a chauqe fois ....de toute façon ça sera a améliorer  
  RefreshWindow()
  If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
    Quit = #True
  EndIf

Until Quit = #True



;-Les procedures a la fin pour faire plaisir a Dobro

Procedure WindowMouseButton(Wnd, ButtonNr)
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ;Linux Version

  Protected gdkWnd.l, x.l, y.l, mask.l

  If Wnd
    *Window.GTKWindow = Wnd
    gdkWnd = *Window\bin\child\window
    gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
   
    Select ButtonNr
      Case 0
        If (mask & #GDK_BUTTON1_MASK)
          ProcedureReturn 1
        EndIf
      Case 1
        If (mask & #GDK_BUTTON3_MASK)
          ProcedureReturn 1
        EndIf
      Case 2
        If (mask & #GDK_BUTTON2_MASK)
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf

  CompilerElse
  ;Windows Version

  If Wnd And GetForegroundWindow_() = Wnd
    Select ButtonNr
      Case 0
        If GetAsyncKeyState_(#VK_LBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 1
        If GetAsyncKeyState_(#VK_RBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 2
        If GetAsyncKeyState_(#VK_MBUTTON) > 0
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf

  CompilerEndIf

  ProcedureReturn 0
EndProcedure


;Ajouter un Layer a un document
Procedure AddLayer(Image.i=0)
  ;si on a pas de n° d'image dans les paramètres alors on créer l'image en fonction de l'image de rendu
  If Image=0
    Image=CreateImage(#PB_Any,ImageWidth(Workbench()\RenderImage),ImageHeight(Workbench()\RenderImage),ImageDepth(Workbench()\RenderImage))
  EndIf
  Workbench()\NbLayer+1 ;On ajoute un calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Active=#True  ;On l'active
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Image=Image   ;l'image du calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Opacity=255   ;L'opacité du calque
  Workbench()\Layer=Workbench()\NbLayer ; Et part defaut on selectionne le calque qu'on vient d'ajouter
EndProcedure

;Rendu des calques
Procedure RenderLayers()
  Protected z.l
  ;Le rendu des calques se fait sur l'image de rendu
  StartDrawing(ImageOutput(Workbench()\RenderImage))
  For z=1 To Workbench()\NbLayer ; je dessine chaque calque
    ;Si le calque est bien visible(activé)
    DrawingMode(#PB_2DDrawing_AlphaClip)
    If Workbench()\Layers.Layer[z]\Active=#True
      DrawAlphaImage(ImageID(Workbench()\Layers.Layer[z]\Image),0,0,Workbench()\Layers.Layer[z]\Opacity)
    EndIf
  Next
  StopDrawing()
 EndProcedure


;Pour écrire sur le calque selectionné 
Procedure WriteLayerPixel(x.l,y.l,Color.l)
  Select ToolsInfo\ToolRenderMode
  
    ;Si l'outil doit écrire avec une couleur
    Case #ModeCouleur
       Protected Image.i=Workbench()\Layers.Layer[Workbench()\Layer]\Image
        x=x/Workbench()\Zoom
        y=y/Workbench()\Zoom
        StartDrawing(ImageOutput(Image))
          If x>0 And x<ImageWidth(Image) And y>0 And y<ImageHeight(Image)
            Plot(x,y,Color)
          EndIf
        StopDrawing()
    
    ;Si l'outil doit écrire avec un dégradé
    Case #ModeGradiant
    
    ;Si l'outil doit écrire avec un motif  
    Case #ModePattern
    
  EndSelect
EndProcedure

Procedure RefreshWindow()
  Protected Max.l,DeltaX.l,DeltaY.l
  ;Je modifie le nom de la fenêtre car elle contient des informations sur le nom le zoom et la profondeur de l'image
  SetWindowTitle(Workbench()\Window, GetFilePart(Workbench()\FileName)+" @ "+Str(Abs(Workbench()\Zoom*100))+"%"+" (Layer"+Str(Workbench()\Layer)+",???/"+Str(ImageDepth(Workbench()\RenderImage))+")") 
  
  ;Dans le cas d'un redimensionnement de la fenêtre je redimenssione les ScrollBar
  ResizeGadget(Workbench()\GdtScrollBarV,WindowWidth(Workbench()\Window)-20, 0, 20, WindowHeight(Workbench()\Window))
  Max=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom-WindowHeight(Workbench()\Window)-20
  If Max<0:Max=0:EndIf
  SetGadgetAttribute(Workbench()\GdtScrollBarV,#PB_ScrollBar_Maximum,Max)
  
  ResizeGadget(Workbench()\GdtScrollBarH,100, WindowHeight(Workbench()\Window)-20, WindowWidth(Workbench()\Window)-120, 20)
  Max=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom-WindowWidth(Workbench()\Window)-20
  If Max<0:Max=0:EndIf
  SetGadgetAttribute(Workbench()\GdtScrollBarH,#PB_ScrollBar_Maximum,Max)
  
  RenderLayers();Je fait un rendu complet
 
 ;Une fois le rendu finit je créer l'image qui sera affiché dans la fenêtre
  If IsImage(Workbench()\WorkImage)
    FreeImage(Workbench()\WorkImage)
  EndIf
  
  ;Position des ScrollsBar
  DeltaX=GetGadgetState(Workbench()\GdtScrollBarH)
  DeltaY=GetGadgetState(Workbench()\GdtScrollBarV)
  
  ;Calcul de la taille de l'image affiché dans la fenêtre
  Protected Width.l,Height.l
  Width=WindowWidth(Workbench()\Window)-20
  If Width>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
    Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  
  Height=WindowHeight(Workbench()\Window)-20
  If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
    Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  
  Workbench()\WorkImage=CreateImage(#PB_Any,Width,Height,ImageDepth(Workbench()\RenderImage)) ; je créer l'image
  ;On affiche la partie de l'image qui est visible
  StartDrawing(ImageOutput(Workbench()\WorkImage))
    DrawImage(ImageID(Workbench()\RenderImage),-DeltaX,-DeltaY,ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom,ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom)
  StopDrawing()
 
 ;On affiche le resultat sur la fenêtre
  StartDrawing(WindowOutput(Workbench()\Window))
    DrawImage(ImageID(Workbench()\WorkImage),0,0)
  StopDrawing()
EndProcedure

;Ouverdure d'une image ou creation d'un nouveau document
Procedure NewDocument(Name.s="")
  Protected Image.i
  AddElement(Workbench())
  If Name=""
    Name.s="Untitled "+Str(ListSize(Workbench()))
  EndIf
  Workbench()\FileName=Name
  
    If FileSize(Workbench()\FileName)>0
      Image=LoadImage(#PB_Any,Workbench()\FileName)
    Else
      Image=CreateImage(#PB_Any,320,200,32);Il faudra ici mettre des variables pour la taille part defaut (peut être prendre la taille de l'image si dans le presse papier)
      StartDrawing(ImageOutput(Image))
        Box(0,0,320,200,#Red)
        Circle(50,50,25,#Blue)
      StopDrawing()
    EndIf
    
    ;Ouverture de la fenêtre contenant l'image
    Workbench()\Window=OpenWindow(#PB_Any, WindowWidth(InterfaceInfo\WinTools)+ListIndex(Workbench())*16, WindowHeight(InterfaceInfo\WinMain)+ListIndex(Workbench())*16, 640, 480, "",#PB_Window_Tool|#PB_Window_TitleBar|#PB_Window_SizeGadget|#PB_Window_SystemMenu,WindowID(InterfaceInfo\WinMain))
    ;Creation des gadgets 
    Workbench()\GdtScrollBarV=ScrollBarGadget(#PB_Any, WindowWidth(Workbench()\Window)-20, 0, 20, WindowHeight(Workbench()\Window),0,0,10,#PB_ScrollBar_Vertical) 
    Workbench()\GdtScrollBarH=ScrollBarGadget(#PB_Any, 100, WindowHeight(Workbench()\Window)-20, WindowWidth(Workbench()\Window)-120, 20,0,0,10) 
    ;On definit une Image pour le rendu final des calques
    Workbench()\RenderImage=CreateImage(#PB_Any,ImageWidth(Image),ImageHeight(Image),ImageDepth(Image))
    ;On definit le Zoom en fonction de la taille de l'image et de la fenêtre
    Workbench()\Zoom=WindowWidth(Workbench()\Window)/ImageWidth(Image)
    AddLayer(Image);On créer le premier calque du document
    RefreshWindow();On rafraichissement 
    SmartWindowRefresh(Workbench()\Window,1)
EndProcedure


Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

Voilà une version avec un OpenWindowScreen
Il y a des tucs currieus lorsqu'on change de fenêtre pour travailler ! Normalement je ferme l'écran pour le réouvrir sur l'autre fenêtre et je profite pour dessiner avec startdrawing(windowoutout()) sur la fenêtre non active l'image... mais apparement comme il y a un screen a cet endroit ça ne marche pas ...

Je commence a me dire que l'idéal ça serait vraiment de se faire sa propre ScreenGUI ! mais c'est un projet complet lollllll ! Si quelqu'un est interessé : :P

Mais pour revenir a mon test avec OpenWIndowScreen voilà ce que ça donne
vous pouvez zoomer avec la molette de la souris !et dessiné avec le clic droit !
J'attends vos retour entre le code d'avant WIndow Only et celui si OpenWindowSceen
D'ailleur si quelqu'un a une idée de mon problème décrit si dessus ....

Code : Tout sélectionner

EnableExplicit

InitSprite()
InitMouse()

;-Structure des données

Structure Layer
  Active.b          ; #True ou #False si ce calque est affiché ou pas
  Image.l           ; Image originale
  
  Opacity.l         ; Transparence global de l'image : ConstAlpha de la function DrawAlphaImage()
  BlendingMode.l    ; Je sais pas si c'est gérable il y a un exemple d'utilisation sur le forum Anglais
  FusionMaskImage.l ; Image comportant le Mask de fusion si il y a !
  ;http://www.purebasic.fr/english/viewtopic.php?f=13&t=36311
EndStructure

#Max_Layer=255
Structure Document
  FileName.s        ;Nom de l'image
  Window.i          ;Fenêtre contenant l'image
  GdtImage.i        ;N° du Gadget contenant l'image
  GdtScrollBarV.i   ;N° du Gadget pour le Scrolling de l'image Verticalement
  GdtScrollBarH.i   ;N°du Gadget pour le Scrolling de l'image Horizontalement
  RenderImage.l     ;Image de rendu des layers
  Zoom.f            ;Zoom de l'image
  WorkImage.l       ; Image redimensionné et affiché !
  Depth.b           ;Profondeur de l'image (peut être n'en a t'on pas besoin ImageDepth() suffit
  ImageSelection.l  ;Image comportant le Masque de Selection
  Layer.l           ;Numero du layer selectionné
  NbLayer.l         ;Nombre de Layer
  Layers.Layer[#Max_Layer] ;Les informations sur les layers mais je ne sais pas si c'est la bonne façon de faire
EndStructure

Global NewList Workbench.Document()

;Variable général aux outils (a voir si ces infos devraient pas être propre a chaque outil)
Structure ToolsInfo
  FrontColor.l      ;Couleur de premier plan
  BackgroundColor.l ;Couleur d'arrière plan
  ToolRenderMode.l  ;Mode de rendu des outils voir enumeration si dessous Couleur/Gradiant/Pattern
EndStructure

Global ToolsInfo.ToolsInfo

Structure InterfaceInfo
  WinMain.i         ;N° de la fenêtre principal
  WinTools.i
EndStructure

Global InterfaceInfo.InterfaceInfo

;Mode de rendu d'un outil
Enumeration
  #ModeCouleur    ;On utilise les couleur de premier et arrière plan
  #ModeGradiant   ;On utilise un dégradé
  #ModePattern    ;On utilise un motif
EndEnumeration

;-Déclaration des procedures
Declare WindowMouseButton(Wnd, ButtonNr)
Declare AddLayer(Image.i=0)
Declare RenderLayers()
Declare WriteLayerPixel(x.l,y.l,Color.l)
Declare RefreshWindow()
Declare NewDocument(Name.s="")

;Creation des fenêtres de l'application part defaut
;fenêtre des menu et de quelques options des outils
InterfaceInfo\WinMain=OpenWindow(#PB_Any, 0, 0, 640, 50, "PhotoPb",#PB_Window_SystemMenu)
;fenêtre des outils
InterfaceInfo\WinTools=OpenWindow(#PB_Any, 0, WindowX(InterfaceInfo\WinMain)+WindowHeight(InterfaceInfo\WinMain), 100, 250, "Tools",#PB_Window_Tool,WindowID(InterfaceInfo\WinMain))
;Creation d'un menu fictif pour que ça ressemble a quelques chose
If CreateMenu(0, WindowID(InterfaceInfo\WinMain))
    MenuTitle("File")
      MenuItem( 1, "&New...")
      MenuItem( 2, "Open")
      MenuItem( 3, "Save")
      MenuBar()
EndIf

Define Event.l,LastWindow.i,FoundWindow.b,inscreen.b,x.l,y.l,Quit.b=#False,Resize.b
NewDocument() ;Ouverture d'un document
NewDocument() ;Ouverture d'un deuxième document pour montrer qu'on peut travailler sur plusieur document en même temps
Define Width.l,Height.l,mx.l,my.l
;-Boucle Principal
Repeat
  Event = WaitWindowEvent()
  
  ;-SwapWindows
  ;Si on change de fenêtre On trouve le document sur le quel on va travailler 
  If LastWindow<>GetActiveWindow()
    If LastWindow>0
    SetWindowTitle(LastWindow,"coucou")
    StartDrawing(WindowOutput(LastWindow))
      Box(0,0,600,600,#Blue)
      DrawImage(ImageID(Workbench()\WorkImage),0,0)
    StopDrawing()
    EndIf
  
    ForEach Workbench() ;On cherche a retrouver le document propre a la fenêtre   active
      If Workbench()\Window=GetActiveWindow() ;Hop on l'a trouvé
         Width=WindowWidth(Workbench()\Window)-20
        If Width>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
          Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
        EndIf
  
        Height=WindowHeight(Workbench()\Window)-20
        If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
          Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
        EndIf
        
        OpenWindowedScreen(WindowID(Workbench()\Window), 0, 0, Width, Height, 0, 0, 0)
        SetActiveWindow(GetActiveWindow());Pas obligatoire ce truc ...:P
        Break;
      EndIf
    Next
    
    LastWindow=GetActiveWindow();Je mémorise la fenêtre histoire de ne pas faire la recherche a chaque boucle
  EndIf  
    

  ;La c'est un peu burtal je rafraichis la fenêtre a chauqe fois ....de toute façon ça sera a améliorer  
  RefreshWindow()
  If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
    Quit = #True
  EndIf

 If inscreen
    If MouseX()>WindowWidth(Workbench()\Window)-22 Or MouseY()>WindowHeight(Workbench()\Window)-22 Or MouseX()<1 Or MouseY()<1
      ReleaseMouse(1)
      inscreen = #False
    EndIf
  Else
    ;
    ;************************************
    ;    Handle #PB_Event_Gadget Here
    ;************************************
    
    If Event=#PB_Event_SizeWindow
      Resize=#True
    Else
      If Resize=#True

      Width=WindowWidth(Workbench()\Window)-20
        If Width>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
          Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
        EndIf
  
        Height=WindowHeight(Workbench()\Window)-20
        If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
          Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
        EndIf
        CloseScreen()
        OpenWindowedScreen(WindowID(Workbench()\Window), 0, 0, Width, Height, 0, 0, 0)
        Resize=#False
      EndIf  
    EndIf
    
    If Event = #PB_Event_Gadget
    
    
      If EventGadget() = 1
        MessageRequester("","You pressed the button!")
      EndIf
    EndIf
    ;
    ;On verifie si on est dans l'ecran
    mx = WindowMouseX(Workbench()\Window):my = WindowMouseY(Workbench()\Window)
    If mx < WindowWidth(Workbench()\Window)-22 And mx > 0 And my > 0 And my < WindowHeight(Workbench()\Window)-22
      ReleaseMouse(0)
      MouseLocate(mx,my)
      inscreen = #True
    EndIf
  EndIf

  ClearScreen(RGB(0,0,0))

 ;Display your screen stuff
  StartDrawing(ScreenOutput())
    DrawImage(ImageID(Workbench()\WorkImage),0,0)
    Circle(MouseX(),MouseY(),5,#Black) 
    
  StopDrawing()
  ;
  If inscreen  ; manage mouse events only if mouse is inside screen
    WindowEvent()
    ExamineMouse()
    If MouseButton(#PB_MouseButton_Left)
      WriteLayerPixel(MouseX(),MouseY(),#Black)
    EndIf

  If MouseWheel()
      Workbench()\Zoom+MouseWheel()*0.1
  EndIf

  EndIf
  FlipBuffers()

Until Quit = #True



;-Les procedures a la fin pour faire plaisir a Dobro

Procedure WindowMouseButton(Wnd, ButtonNr)
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ;Linux Version

  Protected gdkWnd.l, x.l, y.l, mask.l

  If Wnd
    *Window.GTKWindow = Wnd
    gdkWnd = *Window\bin\child\window
    gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
   
    Select ButtonNr
      Case 0
        If (mask & #GDK_BUTTON1_MASK)
          ProcedureReturn 1
        EndIf
      Case 1
        If (mask & #GDK_BUTTON3_MASK)
          ProcedureReturn 1
        EndIf
      Case 2
        If (mask & #GDK_BUTTON2_MASK)
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf

  CompilerElse
  ;Windows Version

  If Wnd And GetForegroundWindow_() = Wnd
    Select ButtonNr
      Case 0
        If GetAsyncKeyState_(#VK_LBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 1
        If GetAsyncKeyState_(#VK_RBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 2
        If GetAsyncKeyState_(#VK_MBUTTON) > 0
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf

  CompilerEndIf

  ProcedureReturn 0
EndProcedure


;Ajouter un Layer a un document
Procedure AddLayer(Image.i=0)
  ;si on a pas de n° d'image dans les paramètres alors on créer l'image en fonction de l'image de rendu
  If Image=0
    Image=CreateImage(#PB_Any,ImageWidth(Workbench()\RenderImage),ImageHeight(Workbench()\RenderImage),ImageDepth(Workbench()\RenderImage))
  EndIf
  Workbench()\NbLayer+1 ;On ajoute un calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Active=#True  ;On l'active
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Image=Image   ;l'image du calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Opacity=255   ;L'opacité du calque
  Workbench()\Layer=Workbench()\NbLayer ; Et part defaut on selectionne le calque qu'on vient d'ajouter
EndProcedure

;Rendu des calques
Procedure RenderLayers()
  Protected z.l
  ;Le rendu des calques se fait sur l'image de rendu
  StartDrawing(ImageOutput(Workbench()\RenderImage))
  For z=1 To Workbench()\NbLayer ; je dessine chaque calque
    ;Si le calque est bien visible(activé)
    DrawingMode(#PB_2DDrawing_AlphaClip)
    If Workbench()\Layers.Layer[z]\Active=#True
      DrawAlphaImage(ImageID(Workbench()\Layers.Layer[z]\Image),0,0,Workbench()\Layers.Layer[z]\Opacity)
    EndIf
  Next
  StopDrawing()
 EndProcedure


;Pour écrire sur le calque selectionné 
Procedure WriteLayerPixel(x.l,y.l,Color.l)
  Select ToolsInfo\ToolRenderMode
  
    ;Si l'outil doit écrire avec une couleur
    Case #ModeCouleur
       Protected Image.i=Workbench()\Layers.Layer[Workbench()\Layer]\Image
        x=x/Workbench()\Zoom
        y=y/Workbench()\Zoom
        StartDrawing(ImageOutput(Image))
          If x>0 And x<ImageWidth(Image) And y>0 And y<ImageHeight(Image)
            Plot(x,y,Color)
          EndIf
        StopDrawing()
    
    ;Si l'outil doit écrire avec un dégradé
    Case #ModeGradiant
    
    ;Si l'outil doit écrire avec un motif  
    Case #ModePattern
    
  EndSelect
EndProcedure

Procedure RefreshWindow()
  Protected Max.l,DeltaX.l,DeltaY.l
  ;Je modifie le nom de la fenêtre car elle contient des informations sur le nom le zoom et la profondeur de l'image
  SetWindowTitle(Workbench()\Window, GetFilePart(Workbench()\FileName)+" @ "+Str(Abs(Workbench()\Zoom*100))+"%"+" (Layer"+Str(Workbench()\Layer)+",???/"+Str(ImageDepth(Workbench()\RenderImage))+")") 
  
  ;Dans le cas d'un redimensionnement de la fenêtre je redimenssione les ScrollBar
  ResizeGadget(Workbench()\GdtScrollBarV,WindowWidth(Workbench()\Window)-20, 0, 20, WindowHeight(Workbench()\Window))
  Max=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom-WindowHeight(Workbench()\Window)-20
  If Max<0:Max=0:EndIf
  SetGadgetAttribute(Workbench()\GdtScrollBarV,#PB_ScrollBar_Maximum,Max)
  
  ResizeGadget(Workbench()\GdtScrollBarH,100, WindowHeight(Workbench()\Window)-20, WindowWidth(Workbench()\Window)-120, 20)
  Max=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom-WindowWidth(Workbench()\Window)-20
  If Max<0:Max=0:EndIf
  SetGadgetAttribute(Workbench()\GdtScrollBarH,#PB_ScrollBar_Maximum,Max)
  
  RenderLayers();Je fait un rendu complet
 
 ;Une fois le rendu finit je créer l'image qui sera affiché dans la fenêtre
  If IsImage(Workbench()\WorkImage)
    FreeImage(Workbench()\WorkImage)
  EndIf
  
  ;Position des ScrollsBar
  DeltaX=GetGadgetState(Workbench()\GdtScrollBarH)
  DeltaY=GetGadgetState(Workbench()\GdtScrollBarV)
  
  ;Calcul de la taille de l'image affiché dans la fenêtre
  Protected Width.l,Height.l
  Width=WindowWidth(Workbench()\Window)-20
  If Width>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
    Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  
  Height=WindowHeight(Workbench()\Window)-20
  If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
    Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  
  Workbench()\WorkImage=CreateImage(#PB_Any,Width,Height,ImageDepth(Workbench()\RenderImage)) ; je créer l'image
  ;On affiche la partie de l'image qui est visible
  StartDrawing(ImageOutput(Workbench()\WorkImage))
    DrawImage(ImageID(Workbench()\RenderImage),-DeltaX,-DeltaY,ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom,ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom)
  StopDrawing()
 
 ;On affiche le resultat sur la fenêtre
EndProcedure

;Ouverdure d'une image ou creation d'un nouveau document
Procedure NewDocument(Name.s="")
  Protected Image.i
  AddElement(Workbench())
  If Name=""
    Name.s="Untitled "+Str(ListSize(Workbench()))
  EndIf
  Workbench()\FileName=Name
  
    If FileSize(Workbench()\FileName)>0
      Image=LoadImage(#PB_Any,Workbench()\FileName)
    Else
      Image=CreateImage(#PB_Any,320,200,32);Il faudra ici mettre des variables pour la taille part defaut (peut être prendre la taille de l'image si dans le presse papier)
      StartDrawing(ImageOutput(Image))
        Box(0,0,320,200,#Red)
        Circle(50,50,25,#Blue)
      StopDrawing()
    EndIf
    
    ;Ouverture de la fenêtre contenant l'image
    Workbench()\Window=OpenWindow(#PB_Any, WindowWidth(InterfaceInfo\WinTools)+ListIndex(Workbench())*16, WindowHeight(InterfaceInfo\WinMain)+ListIndex(Workbench())*16, 640, 480, "",#PB_Window_Tool|#PB_Window_TitleBar|#PB_Window_SizeGadget|#PB_Window_SystemMenu,WindowID(InterfaceInfo\WinMain))
    ;Creation des gadgets 
    Workbench()\GdtScrollBarV=ScrollBarGadget(#PB_Any, WindowWidth(Workbench()\Window)-20, 0, 20, WindowHeight(Workbench()\Window),0,0,10,#PB_ScrollBar_Vertical) 
    Workbench()\GdtScrollBarH=ScrollBarGadget(#PB_Any, 100, WindowHeight(Workbench()\Window)-20, WindowWidth(Workbench()\Window)-120, 20,0,0,10) 
    ;On definit une Image pour le rendu final des calques
    Workbench()\RenderImage=CreateImage(#PB_Any,ImageWidth(Image),ImageHeight(Image),ImageDepth(Image))
    ;On definit le Zoom en fonction de la taille de l'image et de la fenêtre
    Workbench()\Zoom=WindowWidth(Workbench()\Window)/ImageWidth(Image)
    AddLayer(Image);On créer le premier calque du document
    RefreshWindow();On rafraichissement 
    SmartWindowRefresh(Workbench()\Window,1)
EndProcedure


Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Un photoshop Like !

Message par venom »

J'ai compiler les 2 codes chez moi,

le 1er fonctionne bien ( avec ma tablette graphique )
par contre le deuxième, avec ma tablette graphique le curseur fait nimp il bouge dans tous les sens 8O etonnant.








@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

venom a écrit :J'ai compiler les 2 codes chez moi,
le 1er fonctionne bien ( avec ma tablette graphique )
par contre le deuxième, avec ma tablette graphique le curseur fait nimp il bouge dans tous les sens 8O etonnant.

@++
Très curieux ... alors une question est ce que par hasard le pointeur déconne lorsque tu arrives sur les bords de l'image ?
Car pour passer du mode Examinemouse() qui capture le pointeur dans le Screen, au mode normal lorsque le pointeur en sort, je suis obligé de passer part une astuce de NetMaestro ou je repositionne le pointeur lorsqu'on se raproche du bord de l'Screen
et peut être que ça, ça ne marche pas avec les tablettes graphique ...

D'autre on essayé ? des impressions ?
Il faut donc faire un choix
  • Une application FullWindows ?
  • Un application Windows + Screen ?
  • Une application FullScreen ?
Moi pour l'instant je serais tenté part un FullWindows en premier choix
et en deuxième choix FullScreen.
Pourquoi ?
et bien FullWindows pour l'instant c'est le meilleur compromis résultat temps de travaille !
le Windows + Screen c'est vraiment pas evident a mettre en place !
et le FullScreen ça serait génial, mais tres tres tres gros boulot pour faire un ScreenGUI !
d'ou mon choix !
lollllll C'est pas gagné tout ça !!!
Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Un photoshop Like !

Message par venom »

Non des que je pose mon stylo sur ma tablette au milieu de la feuille de dessin, le pointeur fait des petits mouvement dans tous les sens.

Par contre a la souris cela fonctionne.

Le 1er code lui va avec la souris et ma tablette.







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

venom a écrit :Non des que je pose mon stylo sur ma tablette au milieu de la feuille de dessin, le pointeur fait des petits mouvement dans tous les sens.

Par contre a la souris cela fonctionne.

Le 1er code lui va avec la souris et ma tablette.
@++
vraiment currieux !

Voici une nouvelle version concentré sur une application FullWindow
tant que vous n'utilisez pas le zoom ...c'est clean !! vous pouvez dessiner et redimensionné la fenêtre ça marche pas trop mal ... Et cela sans clignotement de l'image

parcontre si on modifie le zoom ça marche, mais il y a des bugs de rafraichissement !

Dite moi ce que vous en pensez !

Code : Tout sélectionner

EnableExplicit

InitSprite()
InitMouse()

;-Structure des données

Structure Layer
  Active.b          ; #True ou #False si ce calque est affiché ou pas
  Image.l           ; Image originale
 
  Opacity.l         ; Transparence global de l'image : ConstAlpha de la function DrawAlphaImage()
  BlendingMode.l    ; Je sais pas si c'est gérable il y a un exemple d'utilisation sur le forum Anglais
  FusionMaskImage.l ; Image comportant le Mask de fusion si il y a !
  ;http://www.purebasic.fr/english/viewtopic.php?f=13&t=36311
EndStructure

#Max_Layer=255
Structure Document
  FileName.s        ;Nom de l'image
  
  ;Tout ce qui concerne la fenêtre qui contient le document
  Window.i          ;Fenêtre contenant l'image
  GdtImage.i        ;N° du Gadget contenant l'image
  GdtScrollBarV.i   ;N° du Gadget pour le Scrolling de l'image Verticalement
  GdtScrollBarH.i   ;N°du Gadget pour le Scrolling de l'image Horizontalement
  GdtZoom.i         ;N°Du gadget pour zoomer
  GdtImageX.l       ;Coordonée X de l'image dans la fenêtre
  GdtImageY.l       ;Coordonée Y de l'image dans la fenêtre
  GdtImageWidth.l   ;Largeur de l'image afficher dans la fenêtre
  GdtImageHeight.l  ;Largeur de l'image afficher dans la fenêtre
  
  ;Strucutre même du document
  RenderImage.l     ;Image de rendu des layers
  Zoom.f            ;Zoom de l'image
  WorkImage.l       ; Image redimensionné et affiché !
  Depth.b           ;Profondeur de l'image (peut être n'en a t'on pas besoin ImageDepth() suffit
  ImageSelection.l  ;Image comportant le Masque de Selection
  Layer.l           ;Numero du layer selectionné
  NbLayer.l         ;Nombre de Layer
  Layers.Layer[#Max_Layer] ;Les informations sur les layers mais je ne sais pas si c'est la bonne façon de faire
EndStructure

Global NewList Workbench.Document()

;Variable général aux outils (a voir si ces infos devraient pas être propre a chaque outil)
Structure ToolsInfo
  FrontColor.l      ;Couleur de premier plan
  BackgroundColor.l ;Couleur d'arrière plan
  ToolRenderMode.l  ;Mode de rendu des outils voir enumeration si dessous Couleur/Gradiant/Pattern
EndStructure

Global ToolsInfo.ToolsInfo

Structure InterfaceInfo
  WinMain.i         ;N° de la fenêtre principal
  WinTools.i
EndStructure

Global InterfaceInfo.InterfaceInfo

;Mode de rendu d'un outil
Enumeration
  #ModeCouleur    ;On utilise les couleur de premier et arrière plan
  #ModeGradiant   ;On utilise un dégradé
  #ModePattern    ;On utilise un motif
EndEnumeration

;-Déclaration des procedures
Declare WindowMouseButton(Wnd, ButtonNr)
Declare AddLayer(Image.i=0)
Declare RenderLayers()
Declare WriteLayerPixel(x.l,y.l,Color.l)
Declare RefreshWindow()
Declare NewDocument(Name.s="")
Declare RefreshImage()

;Creation des fenêtres de l'application part defaut
;fenêtre des menu et de quelques options des outils
InterfaceInfo\WinMain=OpenWindow(#PB_Any, 0, 0, 640, 50, "PhotoPb",#PB_Window_SystemMenu)
;fenêtre des outils
InterfaceInfo\WinTools=OpenWindow(#PB_Any, 0, WindowX(InterfaceInfo\WinMain)+WindowHeight(InterfaceInfo\WinMain), 100, 250, "Tools",#PB_Window_Tool,WindowID(InterfaceInfo\WinMain))
;Creation d'un menu fictif pour que ça ressemble a quelques chose
If CreateMenu(0, WindowID(InterfaceInfo\WinMain))
    MenuTitle("File")
      MenuItem( 1, "&New...")
      MenuItem( 2, "Open")
      MenuItem( 3, "Save")
      MenuBar()
EndIf

;*---------------------------------------*
;-                Tools                  -
;*---------------------------------------*
;reflexions sur l'ajout d'un outil ...
Structure Tools
  GdtTool.i
EndStructure

Global NewList Tools.Tools()
CreateImage(0,40,40)
#GadgetToolWidth=40
Procedure AddTools()
  Protected x.l,y.l,ToolWidth.l,ToolHeight.l
  AddElement(Tools())
  
  ToolWidth=WindowWidth(InterfaceInfo\WinTools)/#GadgetToolWidth
  ToolHeight=WindowHeight(InterfaceInfo\WinTools)/#GadgetToolWidth
  y=(ListSize(Tools())-1)/ToolWidth
  x=(ListSize(Tools())-1-ToolWidth*y)
  
  x=x*#GadgetToolWidth
  y=y*#GadgetToolWidth
  Debug x
  Debug y
  Debug"__"
  Tools()\GdtTool=ButtonImageGadget(#PB_Any,x,y,#GadgetToolWidth,#GadgetToolWidth,ImageID(0),#PB_Button_Toggle)
EndProcedure

AddTools()
AddTools()
AddTools()
AddTools()
AddTools()
;*---------------------------------------*

Define Event.l,LastWindow.i,FoundWindow.b,inscreen.b,x.l,y.l,Quit.b=#False
NewDocument() ;Ouverture d'un document
NewDocument() ;Ouverture d'un deuxième document pour montrer qu'on peut travailler sur plusieur document en même temps


;-Boucle Principal
Repeat
  Event = WaitWindowEvent()
  
  ;Si on change de fenêtre On trouve le document sur le quel on va travailler
  If LastWindow<>GetActiveWindow()
    ForEach Workbench()
      If Workbench()\Window=GetActiveWindow() ;Hop on l'a trouvé
        SetActiveWindow(GetActiveWindow());Pas obligatoire ce truc ...:P
        Break;
      EndIf
    Next
    LastWindow=GetActiveWindow();Je mémorise la fenêtre histoire de ne pas faire la recherche a chaque boucle
  EndIf 
  
  Select Event
    Case #PB_Event_SizeWindow; La fenêtre est redimensioné
      RefreshWindow()
      ;RefreshImage()
    Case #PB_Event_Gadget
      
      Select EventGadget()
        Case Workbench()\GdtZoom
           Workbench()\Zoom=GetGadgetState(Workbench()\GdtZoom)/100 
           RefreshWindow()
      EndSelect
  EndSelect

  ;Pseudo Outil histoire de dire ...
  If WindowMouseButton(WindowID(Workbench()\Window), 0) And WindowMouseX(Workbench()\Window)>Workbench()\GdtImageX And WindowMouseX(Workbench()\Window)<Workbench()\GdtImageX+Workbench()\GdtImageWidth
  
    x=WindowMouseX(Workbench()\Window)
    y=WindowMouseY(Workbench()\Window)
    WriteLayerPixel(x,y,#Black)
    RefreshImage()
  EndIf
 
  If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
    Quit = #True
  EndIf

Until Quit = #True


;*---------------------------------------*
;-              Function                 -
;*---------------------------------------*
Procedure WindowMouseButton(Wnd, ButtonNr)
  ;From DarkDragon
  ;http://www.purebasic.fr/english/viewtopic.php?f=12&t=17998&hilit=WindowMouseButton
  CompilerSelect #PB_Compiler_OS
    
    ;Linux Version
    CompilerCase #PB_OS_Linux
      Protected gdkWnd.l, x.l, y.l, mask.l
      If Wnd
        *Window.GTKWindow = Wnd
        gdkWnd = *Window\bin\child\window
        gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
       
        Select ButtonNr
          Case 0
            If (mask & #GDK_BUTTON1_MASK)
              ProcedureReturn 1
            EndIf
          Case 1
            If (mask & #GDK_BUTTON3_MASK)
              ProcedureReturn 1
            EndIf
          Case 2
            If (mask & #GDK_BUTTON2_MASK)
              ProcedureReturn 1
            EndIf
        EndSelect
      EndIf

    ;Windows Version
    CompilerCase #PB_OS_Windows
      If Wnd And GetForegroundWindow_() = Wnd
        Select ButtonNr
          Case 0
            If GetAsyncKeyState_(#VK_LBUTTON) > 0
              ProcedureReturn 1
            EndIf
          Case 1
            If GetAsyncKeyState_(#VK_RBUTTON) > 0
              ProcedureReturn 1
            EndIf
          Case 2
            If GetAsyncKeyState_(#VK_MBUTTON) > 0
              ProcedureReturn 1
            EndIf
        EndSelect
      EndIf
  
    ;Macintosh Version
    CompilerCase #PB_OS_MacOS
  
  CompilerEndSelect
  ProcedureReturn 0
EndProcedure


Procedure IsAltPressed()
  ;From DoubleDutch
  ;http://www.purebasic.fr/english/viewtopic.php?f=12&t=17998&hilit=WindowMouseButton
  CompilerSelect #PB_Compiler_OS

    ;Windows Version
    CompilerCase #PB_OS_Windows
      ProcedureReturn GetAsyncKeyState_(#VK_MENU)&$8000

    ;Linux Version
    CompilerCase #PB_OS_Linux   

    ;Macintosh Version
    CompilerCase #PB_OS_MacOS 
  CompilerEndSelect
EndProcedure

Procedure IsShiftPressed()
  ;From DoubleDutch
  ;http://www.purebasic.fr/english/viewtopic.php?f=12&t=17998&hilit=WindowMouseButton
  CompilerSelect #PB_Compiler_OS

    ;Windows Version
    CompilerCase #PB_OS_Windows
      ProcedureReturn GetAsyncKeyState_(#VK_SHIFT)&$8000

    ;Linux Version
    CompilerCase #PB_OS_Linux   

    ;Macintosh Version
    CompilerCase #PB_OS_MacOS 
  CompilerEndSelect

   
EndProcedure

Procedure IsCtrlPressed()
  ;From DoubleDutch
  ;http://www.purebasic.fr/english/viewtopic.php?f=12&t=17998&hilit=WindowMouseButton
  CompilerSelect #PB_Compiler_OS

    ;Windows Version
    CompilerCase #PB_OS_Windows
      ProcedureReturn GetAsyncKeyState_(#VK_CONTROL)&$8000

    ;Linux Version
    CompilerCase #PB_OS_Linux   

    ;Macintosh Version
    CompilerCase #PB_OS_MacOS 
  CompilerEndSelect
   
EndProcedure

Enumeration
  #CURSOR_CROSSHAIR
  #CURSOR_NORMAL
  #CURSOR_WAIT
  #CURSOR_IBEAM
  #CURSOR_HAND
  #CURSOR_HELP
  #CURSOR_MOVE
  #CURSOR_UPARROW
EndEnumeration

Procedure LoadCursor(Type)
  Protected Cursor.l
    CompilerIf #PB_Compiler_OS=#PB_OS_Linux
    Select Type
      Case #CURSOR_HELP:Cursor=#GDK_QUESTION_ARROW
      Case #CURSOR_HAND:Cursor=#GDK_HAND2
      Case #CURSOR_IBEAM:Cursor=#GDK_XTERM
      Case #CURSOR_NORMAL:Cursor=#GDK_ARROW
      Case #CURSOR_CROSSHAIR:Cursor=#GDK_CROSSHAIR
      Case #CURSOR_WAIT:Cursor=#GDK_WATCH
      Case #CURSOR_MOVE:Cursor=#GDK_FLEUR   
      Case #CURSOR_UPARROW:Cursor=#GDK_CENTER_PTR
    EndSelect
    ProcedureReturn gdk_cursor_new_(Cursor)
    CompilerElse
    Select Type
      Case #CURSOR_HELP:Cursor=#IDC_HELP
      Case #CURSOR_HAND:Cursor=#IDC_HAND
      Case #CURSOR_IBEAM:Cursor=#IDC_IBEAM
      Case #CURSOR_NORMAL:Cursor=#IDC_ARROW
      Case #CURSOR_CROSSHAIR:Cursor=#IDC_CROSS
      Case #CURSOR_WAIT:Cursor=#IDC_WAIT   
      Case #CURSOR_MOVE:Cursor=#IDC_SIZEALL
      Case #CURSOR_UPARROW:Cursor=#IDC_UPARROW     
    EndSelect
    ProcedureReturn LoadCursor_(0,Cursor)
    CompilerEndIf
EndProcedure

ProcedureDLL SetCursor(Handle,Cursor)
  CompilerIf #PB_Compiler_OS=#PB_OS_Linux
    *widget.gtkwidget=Handle
    gdk_window_set_cursor_(*widget\window, Cursor)
  CompilerElse
    SetWindowLong_(Handle,#GCL_HCURSOR,Cursor)
    ;Should set a property instead and handle the #WM_SETCURSOR event in window procedure
  CompilerEndIf
EndProcedure
;*---------------------------------------*
;-                Layer                  -
;*---------------------------------------*

;Ajouter un Layer a un document
Procedure AddLayer(Image.i=0)
  ;si on a pas de n° d'image dans les paramètres alors on créer l'image en fonction de l'image de rendu
  If Image=0
    Image=CreateImage(#PB_Any,ImageWidth(Workbench()\RenderImage),ImageHeight(Workbench()\RenderImage),ImageDepth(Workbench()\RenderImage))
  EndIf
  Workbench()\NbLayer+1 ;On ajoute un calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Active=#True  ;On l'active
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Image=Image   ;l'image du calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Opacity=255   ;L'opacité du calque
  Workbench()\Layer=Workbench()\NbLayer ; Et part defaut on selectionne le calque qu'on vient d'ajouter
EndProcedure

;Rendu des calques
Procedure RenderLayers()
  Protected z.l
  ;Le rendu des calques se fait sur l'image de rendu
  StartDrawing(ImageOutput(Workbench()\RenderImage))
  For z=1 To Workbench()\NbLayer ; je dessine chaque calque
    ;Si le calque est bien visible(activé)
    DrawingMode(#PB_2DDrawing_AlphaClip)
    If Workbench()\Layers.Layer[z]\Active=#True
      DrawAlphaImage(ImageID(Workbench()\Layers.Layer[z]\Image),0,0,Workbench()\Layers.Layer[z]\Opacity)
    EndIf
  Next
  StopDrawing()
EndProcedure

;Calcul de la largeur de l'image affiché dans la fenêtre
Procedure ImageWidthInWindow()
  Protected Width.l
  If WindowWidth(Workbench()\Window)-20>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
    Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
  Else
    Width=WindowWidth(Workbench()\Window)-21
  EndIf
  ProcedureReturn Width 
EndProcedure

;Calcul de la hauteur de l'image affiché dans la fenêtre
Procedure ImageHeightInWindow()
  Protected Height.l
   Height=WindowHeight(Workbench()\Window)-21
  If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
    Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  ProcedureReturn Height
EndProcedure

;Transforme une coordonée X sur la fenêtre en coordonée X sur le layer
Procedure MouseX2LayerCoord(x)
  ProcedureReturn x=(x+GetGadgetState(Workbench()\GdtScrollBarH)-Workbench()\GdtImageX)/Workbench()\Zoom
EndProcedure

;Transforme une coordonée Y sur la fenêtre en coordonée Y sur le layer
Procedure MouseY2LayerCoord(y)
  ProcedureReturn y=(y+GetGadgetState(Workbench()\GdtScrollBarV)-Workbench()\GdtImageY)/Workbench()\Zoom
EndProcedure


;Pour écrire sur le calque selectionné
Procedure WriteLayerPixel(x.l,y.l,Color.l)
  Select ToolsInfo\ToolRenderMode
 
    ;Si l'outil doit écrire avec une couleur
    Case #ModeCouleur
       Protected Image.i=Workbench()\Layers.Layer[Workbench()\Layer]\Image
        x=MouseX2LayerCoord(x)
        y=MouseY2LayerCoord(y)
        StartDrawing(ImageOutput(Image))
          If x>0 And x<ImageWidth(Image) And y>0 And y<ImageHeight(Image)
            Plot(x,y,Color)
            ;Plot(x+GetGadgetState(Workbench()\GdtScrollBarH),y,#Green)
          EndIf
        StopDrawing()
   
    ;Si l'outil doit écrire avec un dégradé
    Case #ModeGradiant
   
    ;Si l'outil doit écrire avec un motif 
    Case #ModePattern
   
  EndSelect
EndProcedure

Procedure RefreshImage()
  RenderLayers()
    ;On affiche la partie de l'image qui est visible
  StartDrawing(ImageOutput(Workbench()\WorkImage))
    DrawImage(ImageID(Workbench()\RenderImage),-GetGadgetState(Workbench()\GdtScrollBarH),-GetGadgetState(Workbench()\GdtScrollBarV),ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom,ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom)
  StopDrawing()
SetGadgetState(Workbench()\GdtImage,ImageID(Workbench()\WorkImage))
EndProcedure

Procedure RefreshWindow()
  Protected Max.l,DeltaX.l,DeltaY.l,Width.l,Height.l
  ;Je modifie le nom de la fenêtre car elle contient des informations sur le nom le zoom et la profondeur de l'image
  SetWindowTitle(Workbench()\Window, GetFilePart(Workbench()\FileName)+" @ "+Str(Abs(Workbench()\Zoom*100))+"%"+" (Layer"+Str(Workbench()\Layer)+",???/"+Str(ImageDepth(Workbench()\RenderImage))+")")
  
  Workbench()\GdtImageWidth=ImageWidthInWindow()
  Workbench()\GdtImageHeight=ImageHeightInWindow()
  
  ;On ne recréé l'image que si la taille de l'image a changé
  If IsImage(Workbench()\WorkImage) And (Workbench()\GdtImageWidth<>ImageWidth(Workbench()\WorkImage) Or Workbench()\GdtImageHeight<>ImageHeight(Workbench()\WorkImage))
    FreeImage(Workbench()\WorkImage)
    Workbench()\WorkImage=CreateImage(#PB_Any,Workbench()\GdtImageWidth,Workbench()\GdtImageHeight,ImageDepth(Workbench()\RenderImage)) ; je créer l'image
  EndIf

  ;On rafraichit l'image dans le gadget  

  
  Workbench()\GdtImageWidth=ImageWidth(Workbench()\WorkImage)
  Workbench()\GdtImageHeight=ImageHeight(Workbench()\WorkImage)
  
  ;Dans le cas d'un redimensionnement de la fenêtre je redimenssione les ScrollBar
  ResizeGadget(Workbench()\GdtScrollBarV,WindowWidth(Workbench()\Window)-21, 0, 20, WindowHeight(Workbench()\Window))
  Max=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom-WindowHeight(Workbench()\Window)-21
  If Max<0:Max=0:EndIf
  SetGadgetAttribute(Workbench()\GdtScrollBarV,#PB_ScrollBar_Maximum,Workbench()\GdtImageHeight)
  SetGadgetAttribute(Workbench()\GdtScrollBarV,#PB_ScrollBar_PageLength,Workbench()\GdtImageHeight-Max)
 
  ResizeGadget(Workbench()\GdtScrollBarH,100, WindowHeight(Workbench()\Window)-21, WindowWidth(Workbench()\Window)-120, 20)
  Max=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom-WindowWidth(Workbench()\Window)-21
  If Max<0:Max=0:EndIf
  SetGadgetAttribute(Workbench()\GdtScrollBarH,#PB_ScrollBar_Maximum,Workbench()\GdtImageWidth)
  SetGadgetAttribute(Workbench()\GdtScrollBarH,#PB_ScrollBar_PageLength,Workbench()\GdtImageWidth-Max)

  ResizeGadget(Workbench()\GdtZoom,0,WindowHeight(Workbench()\Window)-21,#PB_Ignore,#PB_Ignore)
  ;redimensionement de la fenêtre

  Workbench()\GdtImageX=(WindowWidth(Workbench()\Window)-21-Workbench()\GdtImageWidth)/2
  Workbench()\GdtImageY=(WindowHeight(Workbench()\Window)-21-Workbench()\GdtImageHeight)/2
  
  ResizeGadget(Workbench()\GdtImage,Workbench()\GdtImageX,Workbench()\GdtImageY,Workbench()\GdtImageWidth,Workbench()\GdtImageHeight)
  
  ;On rafraichit l'image dans le gadget 
  StartDrawing(ImageOutput(Workbench()\WorkImage))
    DrawImage(ImageID(Workbench()\RenderImage),-GetGadgetState(Workbench()\GdtScrollBarH),-GetGadgetState(Workbench()\GdtScrollBarV),ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom,ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom)
  StopDrawing()
  SetGadgetState(Workbench()\GdtImage,ImageID(Workbench()\WorkImage))

EndProcedure

;Ouverdure d'une image ou creation d'un nouveau document
Procedure NewDocument(Name.s="")
  Protected Image.i
  AddElement(Workbench())
  If Name=""
    Name.s="Untitled "+Str(ListSize(Workbench()))
  EndIf
  Workbench()\FileName=Name
 
    If FileSize(Workbench()\FileName)>0
      Image=LoadImage(#PB_Any,Workbench()\FileName)
    Else
      Image=CreateImage(#PB_Any,320,200,32);Il faudra ici mettre des variables pour la taille part defaut (peut être prendre la taille de l'image si dans le presse papier)
      StartDrawing(ImageOutput(Image))
        Box(0,0,320,200,#Red)
        Circle(50,50,25,#Blue)
      StopDrawing()
    EndIf
   
   ;On definit une Image pour le rendu final des calques
   Workbench()\RenderImage=CreateImage(#PB_Any,ImageWidth(Image),ImageHeight(Image),ImageDepth(Image))
   
   ;Ouverture de la fenêtre contenant l'image
   Workbench()\Window=OpenWindow(#PB_Any, WindowWidth(InterfaceInfo\WinTools)+ListIndex(Workbench())*16, WindowHeight(InterfaceInfo\WinMain)+ListIndex(Workbench())*16, 640, 480, "",#PB_Window_Tool|#PB_Window_TitleBar|#PB_Window_SizeGadget|#PB_Window_SystemMenu,WindowID(InterfaceInfo\WinMain))
   Workbench()\GdtScrollBarV=ScrollBarGadget(#PB_Any, WindowWidth(Workbench()\Window)-20, 0, 20, WindowHeight(Workbench()\Window),0,0,10,#PB_ScrollBar_Vertical)
   Workbench()\GdtScrollBarH=ScrollBarGadget(#PB_Any, 100, WindowHeight(Workbench()\Window)-20, WindowWidth(Workbench()\Window)-120, 20,0,0,10)
   ;On definit le Zoom en fonction de la taille de l'image et de la fenêtre
    Workbench()\Zoom=WindowWidth(Workbench()\Window)/ImageWidth(Image)
   Workbench()\GdtZoom=TrackBarGadget(#PB_Any,0,WindowHeight(Workbench()\Window)-20, 100, 20, 1, 1000)
  SetGadgetState(Workbench()\GdtZoom,Workbench()\Zoom*100)
   ;On definit l'image afficher dans le fenêtre
   Workbench()\WorkImage=CreateImage(#PB_Any,ImageWidthInWindow(),ImageHeightInWindow(),ImageDepth(Workbench()\RenderImage))
      
   ;Creation des gadgets
   Workbench()\GdtImage=ImageGadget(#PB_Any,0,0,WindowWidth(Workbench()\Window)-20,WindowHeight(Workbench()\Window)-20,ImageID(Workbench()\WorkImage),#PB_Image_Border)
    
    AddLayer(Image);On créer le premier calque du document
    RefreshWindow();On rafraichissement
    RefreshImage()
    SmartWindowRefresh(Workbench()\Window,1); Franchement ça change rien cette fonction
EndProcedure



Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Un photoshop Like !

Message par venom »

Chez moi ça fonctionne bien, c'est vrai qu'au niveau du zoom c'est pas top :D a suivre.







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Re: Un photoshop Like !

Message par Frenchy Pilou »

Encore un et celui-là que pour FireFox ;)
Gratoche of course :mrgreen:

Hop on grabe l'image par un clic droit dessus et hop on la bidouille dans son navigateur fétiche ! :D

ça peut donner des idées ;)

Image

Fractal non? :mrgreen:
Image
Est beau ce qui plaît sans concept :)
Speedy Galerie
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Un photoshop Like !

Message par Ar-S »

Whouaou frenchy, celui ci est impressionnant ! il reconnais même les raccourcis claviers de photoshop..
Les styles de calques sont pas encore tous présent et certaines options bug (genre ctrl+t pour redimensionner le calque le fait aller tout en haut à gauche de l'écran) mais en tout cas, ce programme flash gère grave !

@Thyphoon
J'ai essayé ton dernier code, ça fonctionne chez moi (mais j'ai pas de palettes graphique par contre).
Coté zoom, je mettrais cette barre juste sous la barre d'option, pas la peine de la répéter pour chaque fenêtre selon moi.
Il faut cependant que le zoom s'applique à la dernière fenêtre/image qui a eu le focus.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

Je vous rassure je n'ai pas laissé tombé ! Mais il y a un truc qui sérieusement me gonfle dans purebasic !
A chaque fois que je commence un gros projet je suis bloqué part un bug qui traine .....
Il y a le problème de rafraichissement de ButtonImageGadget(), il ya le bug de freexml(), Et il y a ce dernier bug de comportement currieux de l'alphablending en openscreen...
D'ailleur je n'ai eu aucune reponse pour ce dernier problème je ne sais toujours pas si c'est moi ou si c'est purebasic. Alors si vous avez 20 sec a m'accorder !
Aller testé mon bug => http://www.purebasic.fr/french/viewtopi ... 85#p106485
Et dite moi pourquoi ça scintille en plein ecran et pas windowscreen
ça m'aidera pour mon projet ExtremBrainQuiz et Le photoshop Like!
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Un photoshop Like !

Message par Thyphoon »

Voici mon dernier essais Avec une GUI faite maison (ce n'est que le début, et il faut avouer que je me suis inspiré de pas mal de code trouvé sur les forums)
;-Je ne suis pas encore certain de la façon de faire pour les Gadgets

Sinon vous pouvez dessiner avec la souris et zoomer avec la molette (une grille apparaitra si votre zoom >300%)

Si quelqu'un a des idées pour les Gadgets ou si quelqu'un veut me donner un coup de main pour faire des Gadgets n'hésitez pas .. :mrgreen: (je dis ça sans grand espoirs, vous avez déjà tous des projets qui vous occupe bien)

Code : Tout sélectionner

UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
InitSprite() : InitKeyboard() : InitMouse()

;-WorkBench
Structure Layer
  Active.b          ; #True ou #False si ce calque est affiché ou pas
  Image.l           ; Image originale

  Opacity.l         ; Transparence global de l'image : ConstAlpha de la function DrawAlphaImage()
  BlendingMode.l    ; Je sais pas si c'est gérable il y a un exemple d'utilisation sur le forum Anglais
  FusionMaskImage.l ; Image comportant le Mask de fusion si il y a !
  ;http://www.purebasic.fr/english/viewtopic.php?f=13&t=36311
EndStructure

#Max_Layer=255
Structure Document
  FileName.s        ;Nom de l'image
  Window.i          ;Fenêtre contenant l'image
  GdtImage.i        ;N° du Gadget contenant l'image
  GdtScrollBarV.i   ;N° du Gadget pour le Scrolling de l'image Verticalement
  GdtScrollBarH.i   ;N°du Gadget pour le Scrolling de l'image Horizontalement
  RenderImage.l     ;Image de rendu des layers
  Zoom.f            ;Zoom de l'image
  WorkImage.l       ; Image redimensionné et affiché !
  Depth.b           ;Profondeur de l'image (peut être n'en a t'on pas besoin ImageDepth() suffit
  ImageSelection.l  ;Image comportant le Masque de Selection
  Layer.l           ;Numero du layer selectionné
  NbLayer.l         ;Nombre de Layer
  Layers.Layer[#Max_Layer] ;Les informations sur les layers mais je ne sais pas si c'est la bonne façon de faire
EndStructure

Global NewList Workbench.Document()

;Variable général aux outils (a voir si ces infos devraient pas être propre a chaque outil)
Structure ToolsInfo
  FrontColor.l      ;Couleur de premier plan
  BackgroundColor.l ;Couleur d'arrière plan
  ToolRenderMode.l  ;Mode de rendu des outils voir enumeration si dessous Couleur/Gradiant/Pattern
EndStructure

Global ToolsInfo.ToolsInfo

Structure InterfaceInfo
  WinMain.i         ;N° de la fenêtre principal
  WinTools.i
EndStructure

Global InterfaceInfo.InterfaceInfo

;Mode de rendu d'un outil
Enumeration
  #ModeCouleur    ;On utilise les couleur de premier et arrière plan
  #ModeGradiant   ;On utilise un dégradé
  #ModePattern    ;On utilise un motif
EndEnumeration

;-EX GUI

Structure Ex
  CLRFACE.l
  CLRHILIGHT.l
  CLRLIGHT.l
  CLRSHADOW.l
  CLRDKSHADOW.l
 
  WINDRAG.b
  WINZONE.l
EndStructure

Global Ex.Ex
Ex\CLRFACE = RGB(113,113,113);32
Ex\CLRHILIGHT = RGB(145,145,145);42
Ex\CLRLIGHT = RGB(113,113,113);32
Ex\CLRSHADOW = RGB(88,88,88);25
Ex\CLRDKSHADOW = RGB(71,71,71);20

;-ExWindows
Structure ExWindow
  Sprite.i
  X.l
  Y.l
  Width.l
  Height.l
  Title.s
EndStructure

Global NewList ExWindow.ExWindow()

Procedure ExDrawRect(X,Y,Width,Height,Mode)
  Select Mode
    Case 0
      Box(X,Y,Width,Height,Ex\CLRDKSHADOW)
      Box(X + 1,Y + 1,Width - 2,Height - 2,Ex\CLRSHADOW)
      Box(X + 2,Y + 2,Width - 4,Height - 4,Ex\CLRFACE)     
    Case 1
      Box(X,Y,Width,Height,Ex\CLRDKSHADOW)
      Box(X,Y,Width - 1,Height - 1,Ex\CLRLIGHT)
      Box(X + 1,Y + 1,Width - 2,Height - 2,Ex\CLRSHADOW)
      Box(X + 1,Y + 1,Width - 3,Height - 3,Ex\CLRHILIGHT)
      Box(X + 2,Y + 2,Width - 4,Height - 4,Ex\CLRFACE)
    Case 2
      Box(X,Y,Width,Height,Ex\CLRDKSHADOW)
  EndSelect 
EndProcedure

Declare RenderExGadget()

Procedure RenderExWindow()
  StartDrawing(SpriteOutput(ExWindow()\Sprite))
    DrawingMode(#PB_2DDrawing_Transparent)
     
   Box(0,0,ExWindow()\Width,ExWindow()\Height,Ex\CLRDKSHADOW)   
   Box(0,0,ExWindow()\Width - 1,ExWindow()\Height - 1,Ex\CLRLIGHT)
   Box(1,1,ExWindow()\Width - 2,25,Ex\CLRSHADOW)
   Box(1,1,ExWindow()\Width - 3,24,Ex\CLRHILIGHT)
   Box(2,2,ExWindow()\Width - 4,23,Ex\CLRLIGHT)
   Box(1,26,ExWindow()\Width - 2,ExWindow()\Height - 27,Ex\CLRSHADOW)
   Box(1,26,ExWindow()\Width - 3,ExWindow()\Height - 28,Ex\CLRHILIGHT)
   Box(2,27,ExWindow()\Width - 4,ExWindow()\Height - 29,Ex\CLRFACE)
   
   ;GUI_DrawGradient(2,2,Width - 4,23,GUI_CLRSHADOW,GUI_CLRFACE)
   ;GUI_DrawGradient(2,27,Width - 4,Height - 29,GUI_CLRFACE,GUI_CLRSHADOW)
   
   ;DrawingFont(FontID(#GUI_Font_Icon))
   ;GUI_DrawRect(Width - 23,6,17,16)   
   ;DrawText(Width - 20,9,"r",RGB(230,200,180))
   
   ;DrawingFont(FontID(#GUI_Font_Caption))
   DrawText(12,8,ExWindow()\Title,RGB(60,0,0))
   DrawText(10,6,ExWindow()\Title,#White)
   RenderExGadget()
  StopDrawing()
EndProcedure




Procedure OpenExWindow(X,Y,Width,Height,Title.s,Option.l=0)
  AddElement(ExWindow())
  ExWindow()\Sprite = CreateSprite(#PB_Any,Width,Height,#PB_Sprite_Memory) 
  ExWindow()\X=X
  ExWindow()\Y=Y
  ExWindow()\Width=Width
  ExWindow()\Height=Height
  ExWindow()\Title=Title
  RenderExWindow()
  ProcedureReturn ExWindow()
EndProcedure

Procedure ExResizeWindow(Handle,Width,Height)
  If Handle<>0
    ChangeCurrentElement(ExWindow(),Handle)   
  EndIf
  If Width<10:Width=10:EndIf
  If Height<25:Height=25:EndIf
   
  ExWindow()\Width=Width
  ExWindow()\Height=Height
  FreeSprite(ExWindow()\Sprite)
  ExWindow()\Sprite=CreateSprite(#PB_Any,Width,Height,#PB_Sprite_Memory)
  UseBuffer(Sprite)
  RenderExWindow()
EndProcedure

Procedure SetExWindowTitle(Handle,Title.s)
  If Handle<>0
    ChangeCurrentElement(ExWindow(),Handle)   
  EndIf
  ExWindow()\Title=Title
  RenderExWindow()
EndProcedure

Procedure ExWindowX(Handle=0)
  If Handle<>0
    ChangeCurrentElement(ExWindow(),Handle)   
  EndIf
  ProcedureReturn ExWindow()\X
EndProcedure

Procedure ExWindowY(Handle=0)
  If Handle<>0
    ChangeCurrentElement(ExWindow(),Handle)   
  EndIf
  ProcedureReturn ExWindow()\Y
EndProcedure

Procedure ExWindowWidth(Handle=0)
  If Handle<>0
    ChangeCurrentElement(ExWindow(),Handle)   
  EndIf
  ProcedureReturn ExWindow()\Width
EndProcedure

Procedure ExWindowHeight(Handle=0)
  If Handle<>0
    ChangeCurrentElement(ExWindow(),Handle)   
  EndIf
  ProcedureReturn ExWindow()\Height
EndProcedure

Procedure GetActiveExWindow()
   LastElement(ExWindow())
   ProcedureReturn ExWindow()
EndProcedure

Procedure ExamineExGUI()
Static MouseX.l,MouseY.l

StartDrawing(ScreenOutput())
  ForEach ExWindow()
    DisplaySprite(ExWindow()\Sprite,ExWindow()\X,ExWindow()\Y)
  Next
StopDrawing()

If Ex\WINZONE=0 And MouseButton(#PB_MouseButton_Left)
  LastElement(ExWindow())
  Repeat
    If MouseX()>ExWindow()\X And MouseX()<ExWindow()\X+ExWindow()\Width And MouseY()>ExWindow()\Y And MouseY()<ExWindow()\Y+ExWindow()\Height
      If MouseY()>ExWindow()\Y And MouseY()<ExWindow()\Y+25:Ex\WINZONE=1:EndIf
      If MouseX()>ExWindow()\X+ExWindow()\Width-25 And MouseY()>ExWindow()\Y+ExWindow()\Height-25:Ex\WINZONE=2:EndIf
      *FirstElement = ExWindow()
      LastElement(ExWindow())
      *LastElement = ExWindow()
      If *FirstElement=*LastElement
        Break;
      Else
        SwapElements(ExWindow(),*FirstElement,*LastElement)
        Break;
      EndIf
    EndIf
  Until PreviousElement(ExWindow())=0
  LastElement(ExWindow())
EndIf

If MouseButton(#PB_MouseButton_Left)
  If Ex\WINZONE=1 And Ex\WINDRAG=#True
    ExWindow()\X=ExWindow()\X+MouseX()-MouseX
    ExWindow()\Y=ExWindow()\Y+MouseY()-MouseY
  ElseIf Ex\WINZONE=2 And Ex\WINDRAG=#True
    ExResizeWindow(0,ExWindow()\Width+MouseX()-MouseX,ExWindow()\Height+MouseY()-MouseY)
  EndIf

  MouseX=MouseX()
  MouseY=MouseY()
  Ex\WINDRAG=#True
Else
  Ex\WINDRAG=#False
  Ex\WINZONE=0
EndIf
EndProcedure
;-ExMenu
Procedure RenderExMenu()
  StartDrawing(ScreenOutput())
   Box(0,0,WindowWidth(0),25,Ex\CLRDKSHADOW)   
   Box(0,0,WindowWidth(0) - 1,24,Ex\CLRLIGHT)
   Box(1,1,WindowWidth(0) - 2,25,Ex\CLRSHADOW)
   Box(1,1,WindowWidth(0) - 3,24,Ex\CLRHILIGHT)
   Box(2,2,WindowWidth(0) - 4,23,Ex\CLRLIGHT)
  StopDrawing()
EndProcedure

;-ExGadget
Structure ExGadget
  WinHandle.i
  Type.l
  X.l
  Y.l
  Width.l
  Height.l
 
  Name.s
  ValueA.f
  ValueB.f
  ValueC.f
  ValueD.f
  Option.l
EndStructure
Global NewList ExGadget.ExGadget()

Procedure ScrollBarExGadget(x.l, y.l, Width.l, Height.l, Min.l, Max.l, Len.l , Options=0)
  AddElement(ExGadget())
  ExGadget()\WinHandle=ExWindow()
  ExGadget()\X=x
  ExGadget()\Y=y
  ExGadget()\Width=width
  ExGadget()\Height=height
  ExGadget()\ValueA=Min
  ExGadget()\ValueB=Max
  ExGadget()\ValueC=Len
EndProcedure

Procedure ResizeExGadget(Handle.l,x.l, y.l, Width.l, Height.l)
  If Handle<>0
    ChangeCurrentElement(ExGadget(),Handle)   
  EndIf
  If x<>#PB_Ignore:ExGadget()\X=x:EndIf
  If y<>#PB_Ignore:ExGadget()\X=y:EndIf
  If Width<>#PB_Ignore:ExGadget()\X=Width:EndIf
  If Height<>#PB_Ignore:ExGadget()\X=Height:EndIf
EndProcedure

Procedure RenderExGadget()
  ForEach ExGadget()
    If ExGadget()\WinHandle=ExWindow()
      Select ExGadget()\Type
        Case 0
          If Option=0
          ExDrawRect(ExGadget()\X,ExGadget()\Y,ExGadget()\Height,ExGadget()\Height,0)
          ExDrawRect(ExGadget()\X+ExGadget()\Width-ExGadget()\Height,ExGadget()\Y,ExGadget()\Height,ExGadget()\Height,0)
          ExDrawRect(ExGadget()\X+ExGadget()\Height,ExGadget()\Y,ExGadget()\Width-ExGadget()\Height*2,ExGadget()\Height,2)
          bwidth=(ExGadget()\Width-ExGadget()\Height*2)-(ExGadget()\ValueB-ExGadget()\ValueA)
         
          ExDrawRect(ExGadget()\X+ExGadget()\Height,ExGadget()\Y+2,bwidth,ExGadget()\Height-4,1)
         
          EndIf
      EndSelect
    EndIf
  Next
EndProcedure




;-WorkBench Procedure
Procedure AddLayer(Image.i=0)
  ;si on a pas de n° d'image dans les paramètres alors on créer l'image en fonction de l'image de rendu
  If Image=0
    Image=CreateImage(#PB_Any,ImageWidth(Workbench()\RenderImage),ImageHeight(Workbench()\RenderImage),ImageDepth(Workbench()\RenderImage))
  EndIf
  Workbench()\NbLayer+1 ;On ajoute un calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Active=#True  ;On l'active
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Image=Image   ;l'image du calque
  Workbench()\Layers.Layer[Workbench()\NbLayer]\Opacity=255   ;L'opacité du calque
  Workbench()\Layer=Workbench()\NbLayer ; Et part defaut on selectionne le calque qu'on vient d'ajouter
EndProcedure

;Rendu des calques
Procedure RenderLayers()
  Protected z.l
  ;Le rendu des calques se fait sur l'image de rendu
  StartDrawing(ImageOutput(Workbench()\RenderImage))
  For z=1 To Workbench()\NbLayer ; je dessine chaque calque
    ;Si le calque est bien visible(activé)
    DrawingMode(#PB_2DDrawing_AlphaClip)
    If Workbench()\Layers.Layer[z]\Active=#True
      DrawAlphaImage(ImageID(Workbench()\Layers.Layer[z]\Image),0,0,Workbench()\Layers.Layer[z]\Opacity)
    EndIf
  Next
  StopDrawing()
EndProcedure


;Pour écrire sur le calque selectionné
Procedure WriteLayerPixel(x.l,y.l,Color.l)
  Select ToolsInfo\ToolRenderMode

    ;Si l'outil doit écrire avec une couleur
    Case #ModeCouleur
       Protected Image.i=Workbench()\Layers.Layer[Workbench()\Layer]\Image
         Protected Width.l,Height.l
  Width=ExWindowWidth(Workbench()\Window)-20
  If Width>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
    Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  If Width<1
    Width=1
  EndIf

  Height=ExWindowHeight(Workbench()\Window)-20
  If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
    Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  If Height<1
    Height=1
  EndIf
       Dx=(ExWindowWidth(Workbench()\Window)-Width)/2
       Dy=26+(ExWindowHeight(Workbench()\Window)-Height-26)/2
        x=(x-ExWindowX(Workbench()\Window)-Dx)/Workbench()\Zoom
        y=(y-ExWindowY(Workbench()\Window)-Dy)/Workbench()\Zoom
        StartDrawing(ImageOutput(Image))
          If x>0 And x<ImageWidth(Image) And y>0 And y<ImageHeight(Image)
            Plot(x,y,Color)
          EndIf
        StopDrawing()
   
    ;Si l'outil doit écrire avec un dégradé
    Case #ModeGradiant
   
    ;Si l'outil doit écrire avec un motif
    Case #ModePattern
   
  EndSelect
EndProcedure

Procedure RefreshWindow()
  Protected Max.l,DeltaX.l,DeltaY.l
  ;Je modifie le nom de la fenêtre car elle contient des informations sur le nom le zoom et la profondeur de l'image

  SetExWindowTitle(Workbench()\Window, GetFilePart(Workbench()\FileName)+" @ "+Str(Abs(Workbench()\Zoom*100))+"%"+" (Layer"+Str(Workbench()\Layer)+",???/"+Str(ImageDepth(Workbench()\RenderImage))+")")

  ;Dans le cas d'un redimensionnement de la fenêtre je redimenssione les ScrollBar
  ResizeExGadget(Workbench()\GdtScrollBarV,ExWindowWidth(Workbench()\Window)-20, 0, 20, ExWindowHeight(Workbench()\Window))
  Max=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom-ExWindowHeight(Workbench()\Window)-20
  If Max<0:Max=0:EndIf
  ;SetGadgetAttribute(Workbench()\GdtScrollBarV,#PB_ScrollBar_Maximum,Max)

  ResizeExGadget(Workbench()\GdtScrollBarH,100, ExWindowHeight(Workbench()\Window)-20, ExWindowWidth(Workbench()\Window)-120, 20)
  Max=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom-ExWindowWidth(Workbench()\Window)-20
  If Max<0:Max=0:EndIf
  ;SetGadgetAttribute(Workbench()\GdtScrollBarH,#PB_ScrollBar_Maximum,Max)

  RenderLayers();Je fait un rendu complet

;Une fois le rendu finit je créer l'image qui sera affiché dans la fenêtre
  If IsImage(Workbench()\WorkImage)
    FreeImage(Workbench()\WorkImage)
  EndIf

  ;Position des ScrollsBar
  DeltaX=0;GetGadgetState(Workbench()\GdtScrollBarH)
  DeltaY=0;GetGadgetState(Workbench()\GdtScrollBarV)

  ;Calcul de la taille de l'image affiché dans la fenêtre
  Protected Width.l,Height.l
  Width=ExWindowWidth(Workbench()\Window)-20
  If Width>ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
    Width=ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  If Width<1
    Width=1
  EndIf

  Height=ExWindowHeight(Workbench()\Window)-20
  If Height>ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
    Height=ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom
  EndIf
  If Height<1
    Height=1
  EndIf

  tmp=CopyImage(Workbench()\RenderImage,#PB_Any)
  ClipI
  ResizeImage(tmp,ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom,ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom,#PB_Image_Raw)
  Workbench()\WorkImage=CreateImage(#PB_Any,Width,Height,ImageDepth(Workbench()\RenderImage)) ; je créer l'image
  ;On affiche la partie de l'image qui est visible
  StartDrawing(ImageOutput(Workbench()\WorkImage))
    DrawImage(ImageID(tmp),-DeltaX,-DeltaY,ImageWidth(Workbench()\RenderImage)*Workbench()\Zoom,ImageHeight(Workbench()\RenderImage)*Workbench()\Zoom)
  StopDrawing()
  FreeImage(tmp)
  ;
   StartDrawing(SpriteOutput(ExWindow()\Sprite))
    XImage=(ExWindowWidth(Workbench()\Window)-Width)/2
    YImage=26+(ExWindowHeight(Workbench()\Window)-Height-26)/2
    Box(XImage-1,YImage-1,Width+2,Height+2,#Black)
    DrawImage(ImageID(Workbench()\WorkImage),XImage,YImage,Width,Height)
   
    ;Grille
    If Workbench()\Zoom>3
      z.f=0
      Repeat
        z=z+Workbench()\Zoom
        Line(XImage+z,YImage,1,Height,#Black)
      Until z>=Width
      z=0
      Repeat
        z=z+Workbench()\Zoom
        Line(XImage,YImage+z,Width,1,#Black)
      Until z>=Height
    EndIf
  StopDrawing()

EndProcedure

;Ouverdure d'une image ou creation d'un nouveau document
Procedure NewDocument(Name.s="")
  Protected Image.i
  AddElement(Workbench())
  If Name=""
    Name.s="Untitled "+Str(ListSize(Workbench()))
  EndIf
  Workbench()\FileName=Name

    If FileSize(Workbench()\FileName)>0
      Image=LoadImage(#PB_Any,Workbench()\FileName)
    Else
      Image=CreateImage(#PB_Any,320,200,32);Il faudra ici mettre des variables pour la taille part defaut (peut être prendre la taille de l'image si dans le presse papier)
      StartDrawing(ImageOutput(Image))
        Box(0,0,320,200,#Red)
        Circle(50,50,25,#Blue)
      StopDrawing()
    EndIf
   
    ;Ouverture de la fenêtre contenant l'image
    Workbench()\Window=OpenExWindow(ExWindowWidth(InterfaceInfo\WinTools)+ListIndex(Workbench())*16, 25+ListIndex(Workbench())*16, 640, 480, "",#PB_Window_Tool|#PB_Window_TitleBar|#PB_Window_SizeGadget|#PB_Window_SystemMenu)
    ;Creation des gadgets
    ;Workbench()\GdtScrollBarV=ScrollBarExGadget(ExWindowWidth(Workbench()\Window)-20, 0, 20, ExWindowHeight(Workbench()\Window),0,0,10,#PB_ScrollBar_Vertical)
    Workbench()\GdtScrollBarH=ScrollBarExGadget(100, ExWindowHeight(Workbench()\Window)-20, ExWindowWidth(Workbench()\Window)-120, 20,0,0,10)
    ;On definit une Image pour le rendu final des calques
    Workbench()\RenderImage=CreateImage(#PB_Any,ImageWidth(Image),ImageHeight(Image),ImageDepth(Image))
    ;On definit le Zoom en fonction de la taille de l'image et de la fenêtre
    Workbench()\Zoom=ExWindowWidth(Workbench()\Window)/ImageWidth(Image)
    AddLayer(Image);On créer le premier calque du document
    RefreshWindow();On rafraichissement


    *FirstElement = ExWindow()
    LastElement(ExWindow())
    *LastElement = ExWindow()
    SwapElements(ExWindow(),*FirstElement,*LastElement)

EndProcedure


; Open Screen
OpenWindow(0,0,0,1024,768,"PBPhoto",#PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_SizeGadget)
OpenWindowedScreen(WindowID(0),0,0,1024,768,0,0,0)

InterfaceInfo\WinTools=OpenExWindow(0,25,100,250,"Tools")

EnableWindowDrop(0,#PB_Drop_Files,#PB_Drag_Copy)

NewDocument("1-avatar.jpg")
;NewDocument()
;NewDocument()
; Mouse Pointer
lpBuffer = AllocateMemory(630)
UnpackMemory(?Cursor,lpBuffer)
CatchSprite(0,lpBuffer)
TransparentSpriteColor(0,RGB(0,128,128))
FreeMemory(lpBuffer)

Repeat
  Event = WindowEvent()   
   
  If inscreen
    If MouseX()>WindowWidth(0)-2 Or MouseY()>WindowHeight(0)-2 Or MouseX()<1 Or MouseY()<1
      ReleaseMouse(1)
      inscreen = #False
    EndIf
  Else
    ;
    ;************************************
    ;    Handle #PB_Event_Gadget Here
    ;************************************
    If Event= #PB_Event_SizeWindow
      ;OpenWindowedScreen(WindowID(0),0,0,WindowWidth(0)+10,WindowHeight(0)+10,0,0,0)
    EndIf
    
    If Event = #PB_Event_WindowDrop 
      Debug "Coucou"
       Debug EventDropFiles()
    EndIf
    
    If Event = #PB_Event_Gadget
      If EventGadget() = 1
        MessageRequester("","You pressed the button!")
      EndIf
    EndIf
   
    ;On verifie si on est dans l'ecran
    mx = WindowMouseX(0):my = WindowMouseY(0)
    If mx < WindowWidth(0)-2 And mx > 0 And my > 0 And my < WindowHeight(0)-2
      ReleaseMouse(0)
      MouseLocate(mx,my)
      inscreen = #True
    EndIf
  EndIf
 
  ;On Se positionne sur le bon Document
  If LastWindow<>GetActiveExWindow()
    ForEach Workbench() ;On cherche a retrouver le document propre a la fenêtre   active
      If Workbench()\Window=GetActiveExWindow() ;Hop on l'a trouvé
         Break;
      EndIf
    Next
   LastWindow=GetActiveExWindow();Je mémorise la fenêtre histoire de ne pas faire la recherche a chaque boucle
  EndIf 
   
   
  ClearScreen(Ex\CLRHILIGHT)
  ExamineKeyboard()
  ExamineExGUI():RenderExMenu()
   
  If inscreen  ; manage mouse events only if mouse is inside screen
    Event=WindowEvent()
    
    If Event = #PB_Event_WindowDrop 
      Debug "Coucou"
      Debug EventDropFiles()
      NewDocument(EventDropFiles())
    EndIf
    
    ExamineMouse()

    If MouseButton(#PB_MouseButton_Left) And Ex\WINZONE=0
      RefreshWindow()
      WriteLayerPixel(MouseX(),MouseY(),#Red)
    EndIf

    If MouseWheel()
      If Workbench()\Zoom+MouseWheel()*0.1>0
      Workbench()\Zoom+MouseWheel()*0.1
      
      EndIf
      RefreshWindow()
    EndIf
  DisplayTransparentSprite(0,MouseX(),MouseY())
  EndIf
 
  LastElement(ExWindow())
  
  FlipBuffers()

Until KeyboardPushed(1) Or Event = #PB_Event_CloseWindow
   
   
   
   ;   ExamineKeyboard() : ExamineMouse() :ExamineExGUI():RenderExMenu()
  ;

; -------------------------------------------------------------------
; DATA SECTION
; -------------------------------------------------------------------

DataSection
   Cursor:
   Data.l $0276434A,$4A720000,$A9B7AACC,$146320D0,$284A6811,$01232023,$9188409D,$F3000461,$20492601,$0A0401E0
   Data.l $E00081C0,$FFC0E015,$09302024,$409C3C04,$66013801,$FE4D02B6,$91FB77FB,$B7C236B7,$BDF63086,$BFEC1EC1
   Data.l $C0F36107,$0F625EF7,$008A083D,$87FFF581,$C4592A11,$4287C926,$3EC90540,$69F6974F,$21E5E328,$DDDE6107
   Data.l $50B353C6,$0FB86C06,$0000D893
   Data.b $90,$48
EndDataSection
Dernière modification par Thyphoon le sam. 12/déc./2009 19:35, modifié 1 fois.
Répondre