PureWaitingCircle

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
coder
Beiträge: 204
Registriert: 25.09.2005 17:53
Computerausstattung: Intel Core2Quad Q8200 @ 2.33GHz
ASUS P5Q3, 2GB DDR3-1066 RAM, ATi Raedeon HD 4850
Wohnort: Deutschland
Kontaktdaten:

PureWaitingCircle

Beitrag von coder »

Moin,

ich hab mal aus langerweile ein kleinen Codes geschrieben, welcher die das darstellen von Warteanimationen erlaubt!

Wäre dankbar für 'ne bisschen Feedback! :allright:

Code: Alles auswählen

; gPreferences[460-5-1-1-794-154-0-252-111]
;
;PureWaitingCircle - Engine
;
;geschrieben in PureBasic 4.10
;   (C) 2008 by Martin 'coder' Peters
;   einfach.martin [at] t-online [dot] de
;
;-OS:
;   Windows          (X)
;   Linux            (?)
;   MacOS            (?)
;
;
;-HAVE:
;   PB only          (X)
;   Without Userlibs (X)
;   Without any DLLs (X)
;   EnableExplicit   (X)
;   Unicode          (X)
;   
;   
;-NEED:
;   ThreadSafe       (X)
;   Unicode          ( )
;   UserMode         (?)
;   AdminMode        ( )
;   InlineASM        ( )
;   PBOSL            ( )
;   DLLs             ( )


EnableExplicit    ;->>>EnableExplicit<<<

;-______________________________
;-DECLARATION

#PWC_CMax = 8

Structure PWC
  w.l   ;width
  h.l   ;height
  Gadget.l    ;ImageGadget
  Image.l   ;ImageID welche genutzt werden kann
  
  Play.b    ;Soll die Animation abgespielt werden?
  Wait.l    ;Zeit die minimal ein Bild zu sehen sein soll (in ms)
  Thread.l    ;ThreadID
  Pos.l   ;Position von dem hervorgehobenen Segment
  
  CSize.l   ;Durchmesser der Kreise
  
  BackColor.l   ;Hintergrundfarbe
  Color.l   ;Standardfarbe
  Color1.l    ;1 Farbe
  Color2.l    ;2 Farbe
  Color3.l    ;3 Farbe
EndStructure

Structure Punkt2D 
  X.d 
  Y.d 
EndStructure 

;-______________________________
;-HELP PROCS

Procedure EllipseAnglePoint(X, Y, RadiusX, RadiusY, EllipseAngle.d, PositionAngle.d, *Point.Punkt2D) 
;RadiusX = Vertikaler Radius
;RadiusY = Horizontaler Radius
;EllipseAngle = Neigung der Ellipse in Grad
;PositionAngle = benötigter Punkt in Grad
;*Point.Punkt2D = Structurierte Variable welche später die Koordinaten des Punktes enthält
Protected dx.d, dy.d
 EllipseAngle = EllipseAngle * #PI/180 
 PositionAngle = PositionAngle * #PI/180
 
 dx = Cos(PositionAngle)*RadiusX - Sin(PositionAngle)*RadiusX 
 dy = Sin(PositionAngle)*RadiusY + Cos(PositionAngle)*RadiusY 
 *Point\X = X + Cos(EllipseAngle)*dx - Sin(EllipseAngle)*dy 
 *Point\Y = Y + Sin(EllipseAngle)*dx + Cos(EllipseAngle)*dy 
EndProcedure

Procedure myAbs(Zahl, Min, Max)
  If Zahl > Min And Zahl < Max
    ProcedureReturn Zahl
  EndIf
  If Zahl > Max
    Repeat
      Zahl = Zahl - Max
    Until Zahl <= Max
  EndIf
  If Zahl < Min
    Repeat
      Zahl = Zahl + Max
    Until Zahl >= Min
  EndIf
  ProcedureReturn Zahl
EndProcedure

;-______________________________
;-PROCS

Procedure PWC_Thread(*Info.PWC)
  Protected P.Punkt2D
  Protected Color
  Protected Start
  Protected n
  Protected x, y
  Protected RadiusX, RadiusY
  
  If *Info\Image = #PB_Any
    *Info\Image = CreateImage(#PB_Any, *Info\w, *Info\h)
  Else
    CreateImage(*Info\Image, *Info\w, *Info\h)
  EndIf
  
  SetGadgetState(*Info\Gadget, 0)
  
  Repeat
    If *Info\Play = -1
      ProcedureReturn 0
    EndIf
    Delay(100)
  Until *Info\Play = #True
  
  x = *Info\w/2
  y = *Info\h/2
  RadiusX = *Info\w/4
  RadiusY = *Info\h/4
  
  Repeat
    
    Start = ElapsedMilliseconds()
    
    StartDrawing(ImageOutput(*Info\Image))
      Box(0, 0, *Info\w, *Info\h, *Info\BackColor)
      
      For n = 0 To #PWC_CMax
        If *Info\Pos = n
          Color = *Info\Color1
        ElseIf *Info\Pos = myAbs(n+1, 0, #PWC_CMax)
          Color = *Info\Color2
        ElseIf *Info\Pos = myAbs(n+2, 0, #PWC_CMax)
          Color = *Info\Color3
        Else
          Color = *Info\Color
        EndIf
        
        EllipseAnglePoint(x, y, RadiusX, RadiusY, 0, n*45, P)
        Circle(P\x, P\y, *Info\CSize, Color)
      Next
    StopDrawing()
    
    SetGadgetState(*Info\Gadget, ImageID(*Info\Image))
    
    Repeat
      Delay(10)
    Until ElapsedMilliseconds()-Start >= *Info\Wait
    
    If *Info\Play <> 1
      ;SetGadgetState(*Info\Gadget, 0)
      Repeat
        If *Info\Play = -1
          Break 2
        EndIf
        Delay(100)
      Until *Info\Play = #True
    EndIf
    
    *Info\Pos = myAbs(*Info\Pos+1, 0, #PWC_CMax)
    
  ForEver
  
  SetGadgetState(*Info\Gadget, 0)
          
EndProcedure

Procedure PWC_Create(Gadget, w, h, CSize, Image = #PB_Any, Wait = 100, Color = $dddddd, Color1 = $aaaaaa, Color2 = $bbbbbb, Color3 = $cccccc, BackColor = $eeeeee)  
  Protected *Sys.PWC
  Protected Thread
  
  *Sys = AllocateMemory(SizeOf(PWC))
  
  With *Sys
    \w = w   ;width
    \h = h   ;height
    \Gadget = Gadget    ;ImageGadget
    \Image = Image    ;ImageID welche genutzt werden kann
    
    \Play = 0    ;Soll die Animation abgespielt werden?
    \Wait = Wait    ;Zeit die minimal ein Bild zu sehen sein soll (in ms)
    \Thread = 0    ;ThreadID
    \Pos = 0   ;Position von dem hervorgehobenen Segment
    
    \CSize = CSize   ;Durchmesser der Kreise
    
    \BackColor = BackColor   ;Hintergrundfarbe
    \Color = Color   ;Standardfarbe
    \Color1 = Color1    ;1 Farbe
    \Color2 = Color2    ;2 Farbe
    \Color3 = Color3    ;3 Farbe
  EndWith
  
  Thread = CreateThread(@PWC_Thread(), *Sys.PWC)
  *Sys\Thread = Thread
  ProcedureReturn *Sys
EndProcedure

Procedure PWC_Play(*Sys.PWC)
  *Sys\Play = 1
EndProcedure

Procedure PWC_Stop(*Sys.PWC)
  *Sys\Play = 0
EndProcedure

Procedure PWC_Close(*Sys.PWC)
  Protected S
  *Sys\Play = -1
  
  S = 0
  While IsThread(*Sys\Thread)
    S + 1
    If S > 5
      KillThread(*Sys\Thread)
      ;Debug "Kill Thread"
      Break
    EndIf
    Delay(1)
  Wend
  
  FreeImage(*Sys\Image)
  SetGadgetState(*Sys\Gadget, 0)
  FreeMemory(*Sys)
EndProcedure

Procedure PWC_SetColor(*Sys.PWC, Color = $dddddd, Color1 = $aaaaaa, Color2 = $bbbbbb, Color3 = $cccccc, BackColor = $eeeeee)
  With *Sys
    \BackColor = BackColor   ;Hintergrundfarbe
    \Color = Color   ;Standardfarbe
    \Color1 = Color1    ;1 Farbe
    \Color2 = Color2    ;2 Farbe
    \Color3 = Color3    ;3 Farbe
  EndWith
EndProcedure

Procedure PWC_Hide(*Sys.PWC, State)
  If State
    PWC_Stop(*Sys)
    SetGadgetState(*Sys\Gadget, 0)
  Else
    PWC_Play(*Sys)
    SetGadgetState(*Sys\Gadget, *Sys\Image)
  EndIf
EndProcedure

DisableExplicit   ;->>>DisableExplicit<<<

;-______________________________
;-EXAMPLE

Define *a.PWC
Define *b.PWC
Define *c.PWC
Define *d.PWC

OpenWindow(0, 0, 0, 512, 256, "PureWaitingCircle Test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
If CreateGadgetList(WindowID(0))
  ImageGadget(0, 0, 0, 256, 256, 0)
  ImageGadget(1, 256, 0, 128, 128, 0)
  ImageGadget(2, 256, 128, 256, 128, 0)
  ButtonGadget(3, 385, 0, 128, 40, "Pause", #PB_Button_Toggle)
  ImageGadget(4, 385, 50, 64, 64, 0)
EndIf

*a = PWC_Create(0, 256, 256, 16, 0)
*b = PWC_Create(1, 128, 128, 16, 1, 50, $dd00dd, $aa00aa, $bb00bb, $cc00cc)
*c = PWC_Create(2, 256, 128, 16, 2, 75, $00dd00, $00aa00, $00bb00, $00cc00)
*d = PWC_Create(4, 64, 64, 5, 3, 100, $444444, $FFFFFF, $DDDDDD, $CCCCCC, 0)

PWC_Play(*a)
PWC_Play(*b)
PWC_Play(*c)
PWC_Play(*d)

Repeat
  Event = WaitWindowEvent(1)
  If Event = #PB_Event_CloseWindow
    Break
  ElseIf Event = #PB_Event_Gadget
    If EventGadget() = 3
      If GetGadgetState(3) = 0
        PWC_Play(*a)
        PWC_SetColor(*a, $444444, $FFFFFF, $DDDDDD, $CCCCCC, 0)
      Else
        PWC_Stop(*a)
      EndIf
    EndIf
  EndIf
ForEver

HideWindow(0, 1)
PWC_Close(*a)
PWC_Close(*b)
PWC_Close(*c)
PWC_Close(*d)
End
mfg coder
Windows 7 x64 | PureBasic 4.60 4.50 4.02
Ja verdammt, meine Eltern wohnen immer noch bei mir!
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Der Code ist sehr anfällig:
StopDrawing() must called before calling StartDrawing() again.
liegt vermutlich an den Threads die du verwendest.


EDIT: schon gut habe vergessen Thread-Sichere-Exe zu erstellen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Beitrag von marco2007 »

Sehr gut! :allright:

Ich bin schon am überlegen, ob ich´s bei meinem derzeitigen Programm verwenden soll/kann.

Danke!
Windows 11 - PB 6.03 x64
_________________________________
Benutzeravatar
coder
Beiträge: 204
Registriert: 25.09.2005 17:53
Computerausstattung: Intel Core2Quad Q8200 @ 2.33GHz
ASUS P5Q3, 2GB DDR3-1066 RAM, ATi Raedeon HD 4850
Wohnort: Deutschland
Kontaktdaten:

Beitrag von coder »

STARGÅTE hat geschrieben:Der Code ist sehr anfällig:
StopDrawing() must called before calling StartDrawing() again.
liegt vermutlich an den Threads die du verwendest.


EDIT: schon gut habe vergessen Thread-Sichere-Exe zu erstellen.
Wer lesen kann ist klar im Vorteil! :lol: is nicht ernst gemeint


@marco2006
Danke!
Windows 7 x64 | PureBasic 4.60 4.50 4.02
Ja verdammt, meine Eltern wohnen immer noch bei mir!
Antworten