Page 1 of 1

Elliptic Progressbars

Posted: Sun Jan 30, 2005 4:07 am
by Mischa
Code updated for 5.20+

Code: Select all

#maxroundprogresses=10

Structure rprogress
  gadgetid.i
  imageid.i
  imagecolor.i
  backcolor.i
  frontcolor.i
  textcolor.i
  font.i
  max.i
  state.i
  extension.s
EndStructure

Global Dim RoundProgresses.rprogress(#maxroundprogresses)

Procedure SetRoundProgressState(id,state)
  If state<>RoundProgresses(id)\state
    w=ImageWidth(RoundProgresses(id)\imageid) : h=ImageHeight(RoundProgresses(id)\imageid)
    dc=StartDrawing(ImageOutput(RoundProgresses(id)\imageid))
      Box(0,0,w,h,RoundProgresses(id)\imagecolor)
      pen=CreatePen_(#PS_SOLID,1,RoundProgresses(id)\backcolor)
      brush=CreateSolidBrush_(RoundProgresses(id)\backcolor)
      SelectObject_(dc,brush) : SelectObject_(dc,pen)
      Ellipse_(dc,0,0,w,h)
      DeleteObject_(brush) : DeleteObject_(pen)
      pen=CreatePen_(#PS_SOLID,1,0)
      If RoundProgresses(id)\frontcolor=-1
        cstate=state * 448 / RoundProgresses(id)\max
        If cstate<256
          color=RGB(255,cstate,0)
        Else
          cstate-256
          color=RGB(255-cstate,255,0)
        EndIf
        brush=CreateSolidBrush_(color)
      Else  
        brush=CreateSolidBrush_(RoundProgresses(id)\frontcolor)
      EndIf
      SelectObject_(dc,brush) : SelectObject_(dc,pen)
      angle.f=state * 360 / RoundProgresses(id)\max
      If angle>0
        If angle>358
          Ellipse_(dc,0,0,w,h)
        Else
          mx=w/2 : my=h/2
          rx.f = 0 - (0 - my) * Sin(6.28318531*angle/360) + mx 
          ry.f = (0 - my) * Cos(6.28318531*angle/360) + my
          x2 = rx : y2 = ry
          Pie_(dc,0,0,w,h,x2,y2,w/2,0) 
        EndIf
      EndIf
      DeleteObject_(brush) : DeleteObject_(pen)
      SelectObject_(dc,RoundProgresses(id)\font)
      SetBkMode_(dc,#TRANSPARENT)
      SetTextColor_(dc,RoundProgresses(id)\textcolor)
      text.s = Str(state)+RoundProgresses(id)\extension
      DrawText_(dc,text,-1,rect.RECT,#DT_CALCRECT)
      diffx=(w-rect\right)/2 : diffy=(h-rect\bottom)/2
      DrawText(diffx, diffy, text)
    StopDrawing()
    RoundProgresses(id)\state = state
  EndIf
  SetGadgetState(RoundProgresses(id)\gadgetid,ImageID(RoundProgresses(id)\imageid))
EndProcedure

Procedure RoundProgress(id,x,y,w,h,ic,bc,fc,tc,font,max,state,ext.s)
  RoundProgresses(id)\gadgetid   = ImageGadget(#PB_Any,x,y,w,h,0)
  RoundProgresses(id)\imageid    = CreateImage(#PB_Any,w,h)
  RoundProgresses(id)\imagecolor = ic
  RoundProgresses(id)\backcolor  = bc
  RoundProgresses(id)\frontcolor = fc
  RoundProgresses(id)\textcolor  = tc
  RoundProgresses(id)\font       = font
  RoundProgresses(id)\max        = max
  RoundProgresses(id)\state      = -1
  RoundProgresses(id)\extension  = ext
  SetRoundProgressState(id,state)
EndProcedure

Procedure RemoveRoundProgress(id)
  FreeImage(RoundProgresses(id)\imageid)
  FreeGadget(RoundProgresses(id)\gadgetid)
EndProcedure  

OpenWindow(0,50,50,450,230,"Test",#PB_Window_SystemMenu)
font1=LoadFont(#PB_Any,"Arial",14,#PB_Font_Bold)
font2=LoadFont(#PB_Any,"Times New Roman",24,#PB_Font_Bold)
font3=LoadFont(#PB_Any,"System",10)

RoundProgress(0,10,10,100,100,GetSysColor_(#COLOR_BTNFACE),RGB(160,160,160),RGB(230,128,230),RGB(255,230,255),FontID(font1),100,0,"%")
RoundProgress(1,120,10,100,100,GetSysColor_(#COLOR_BTNFACE),RGB(160,160,160),RGB(230,230,128),RGB(255,255,230),FontID(font1),100,0,"%")
RoundProgress(2,230,10,210,210,GetSysColor_(#COLOR_BTNFACE),RGB(160,160,160),-1,RGB(0,0,0),FontID(font2),100,0,"%")
RoundProgress(3,10,120,100,100,GetSysColor_(#COLOR_BTNFACE),RGB(160,160,160),RGB(128,230,230),RGB(0,0,0),FontID(font1),1000,0," Units")
RoundProgress(4,120,120,100,45,GetSysColor_(#COLOR_BTNFACE),RGB(120,120,120),RGB(64,160,160),RGB(0,0,0),FontID(font3),100,0,"%")
RoundProgress(5,120,175,100,45,GetSysColor_(#COLOR_BTNFACE),RGB(80,80,32),RGB(160,160,64),RGB(255,255,128),FontID(font3),100,100,"%")

time=timeGetTime_()
Repeat
  Event=WindowEvent()
  If timeGetTime_()-time>80
    state1+1
    If state1>100
      state1=0
    EndIf
    state2+2
    If state2>100
      state2=0
    EndIf
    state3+4
    If state3>100
      state3=0
    EndIf
    state4+5
    If state4>1000
      state4=0
    EndIf
    state5+3
    If state5>100
      state5=0
    EndIf
    state6-2
    If state6<0
      state6=100
    EndIf
    SetRoundProgressState(5,state6)
    SetRoundProgressState(4,state5)
    SetRoundProgressState(3,state4)
    SetRoundProgressState(2,state1)
    SetRoundProgressState(1,state2)
    SetRoundProgressState(0,state3)
    time=timeGetTime_()
  EndIf  
  Delay(5)
Until Event=#PB_Event_CloseWindow
Regards,
Mischa

Posted: Sun Jan 30, 2005 1:35 pm
by Fred
Very nice code :)

The Delay(5) should be put only when no event occurs else the event queue will be slow to flush (try to move the mouse over the window, the refresh is stopping partially)

So just replace Delay(5) with

Code: Select all

If Event
  ; Do your normal event check here and don't wait to check if another event is following
Else
  Delay(5)
EndIf
and all the refresh is now perfect.

Posted: Sun Jan 30, 2005 1:48 pm
by DarkDragon
Fred wrote:Very nice code :)

The Delay(5) should be put only when no event occurs else the event queue will be slow to flush (try to move the mouse over the window, the refresh is stopping partially)

So just replace Delay(5) with

Code: Select all

If Event
  ; Do your normal event check here and don't wait to check if another event is following
Else
  Delay(5)
EndIf
and all the refresh is now perfect.
I make it better:

Code: Select all

Select Event
  Case #PB_Event_Repaint
  Case ...
  Default
    Delay(5)
EndSelect
I like that more.

Posted: Sun Jan 30, 2005 3:07 pm
by Fred
Tastes and colors.. ;)

Posted: Sun Jan 30, 2005 3:23 pm
by Le Soldat Inconnu
I do the same in 3D 1 years ago :wink:

Sorry, comments are in french

Code: Select all

; Auteur : Le Soldat Inconnu
; Version de PB : 3.92
;
; Explication du programme :
; Dessiner un camembert en 3D

#Pi.f = 3.14159265

Procedure Pie3D(HDC.l, x.l, y.l, Rayon.l, Orientation.f, Hauteur.l, AngleDepart.f, AngleFin.f, Couleur.l)
  ; HDC : Handle du dessin
  ; X, Y : centre du camembert
  ; Rayon : Rayon du camembert
  ; Orientation : Orientation du camembert qui donne l'effet 3D. cette valeur doit être comprise entre 0 et 1
  ; Hauteur : Hauteur ou épaisseur du camembert
  ; AngleDepart : Angle de départ en radian
  ; AngleFin : Angle de fin en radian
  ; Couleur : Couleur du camenbert
  
  Protected R.l, G.l, b.l, n.l, AX1.l, AY1.l, AX2.l, AY2.l, Rayon2.l
  
  Rayon2 = Rayon * Orientation ; calul du rayon sur l'axe Y du camembert
  
  y = y - Hauteur / 2 ; on recentre le camemenbert en fonction de l'épaisseur
  
  R = Red(Couleur) : G = Green(Couleur) : b = Blue(Couleur) ; On décompose la couleur en RGB
  
  AX2 = Int(x + 100 * Cos(AngleDepart)) ; calcul du point d'arriver
  AY2 = Int(y + 100 * Sin(AngleDepart) * Orientation)
  
  AX1 = Int(x + 100 * Cos(AngleFin)) ; calcul du point de départ
  AY1 = Int(y + 100 * Sin(AngleFin) * Orientation)
  
  For n = Hauteur To 1 Step -1 ; On dessine l'épaisseur du camembert
    FrontColor(R * (0.8 - 0.08 * n / Hauteur), G * (0.8 - 0.08 * n / Hauteur), b * (0.8 - 0.08 * n / Hauteur)) ; Choix de la couleur du bord du camembert
    Pie_(HDC, x - Rayon, y - Rayon2 + n, x + Rayon, y + Rayon2 + n, AX1, AY1 + n, AX2, AY2 + n)
  Next
  
  ; On dessine le dessus du camembert
  FrontColor(R, G, b)
  Pie_(HDC, x - Rayon, y - Rayon2, x + Rayon, y + Rayon2, AX1, AY1, AX2, AY2) ; on dessine le dessus du camembert
  
EndProcedure

Procedure DoublePie3D(HDC.l, x.l, y.l, Rayon.l, Orientation.f, Hauteur.l, Decalage.l, Angle.f, Couleur1.l, Couleur2.l)
  ; HDC : Handle du dessin
  ; X, Y : centre du camembert
  ; Rayon : Rayon du camembert
  ; Orientation : Orientation du camembert qui donne l'effet 3D. cette valeur doit être comprise entre 0 et 1
  ; Hauteur : Hauteur ou épaisseur du camembert
  ; Decalage : Pour mettre un espace entre les 2 zone du camenbert
  ; Angle : Angle correspondant à la zone 1 du camembert
  ; Couleur1 : Couleur de la zone 1 du camenbert
  ; Couleur2 : Couleur de la zone 2 du camenbert
  
  DecalageX = Decalage * Cos(Angle / 2)
  DecalageY = Decalage * Sin(Angle / 2)
  
  If Angle = 0
    Pie3D(HDC, x, y, Rayon, Orientation, Hauteur, 0, 2 * #Pi, Couleur1)
  ElseIf Angle <= #Pi / 2
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, #Pi + Angle, 0, Couleur1)
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, #Pi, #Pi + Angle, Couleur2)
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, 0, #Pi, Couleur1)
  ElseIf Angle <= 3 * #Pi / 2
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, #Pi, #Pi + Angle, Couleur2)
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, #Pi + Angle, #Pi, Couleur1)
  Else
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, #Pi, 0, Couleur2)
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, #Pi + Angle, #Pi, Couleur1)
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, 0, #Pi + Angle, Couleur2)
  EndIf
EndProcedure



; Création de la fenêtre et dela GadgetList
If OpenWindow(0, 0, 0, 600, 600, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

CreateImage(0, 600, 600)
ImageGadget(0, 0, 0, 0, 0, UseImage(0))

SetTimer_(WindowID(), 0, 50, 0)

Repeat
  Event = WaitWindowEvent()
  
  If Event = #WM_TIMER
    
    Angle.f + 0.02
    If Angle > 2 * #Pi
      Angle = 0
    EndIf
    
    HDC = StartDrawing(ImageOutput())
      Box(0, 0, 600, 600, 0)
      
      ; Camenbert normal (1 seule part)
      Pie3D(HDC, 150, 150, 120, 0.45, 20, Angle, 0, RGB(100, 200, 200))
      
      ; Camenbert normal (1 seule part)
      Pie3D(HDC, 150, 450, 120, 0.8, 20, #Pi, #Pi + Angle, RGB(100, 200, 200))
      
      ; Camenbert avec 2 parts
      DoublePie3D(HDC, 450, 150, 140, 0.6, 10, 0, Angle, RGB(100, 200, 200), RGB(0, 150, 150))
      
      ; Camenbert avec 2 parts et avec un espace entre les parts
      DoublePie3D(HDC, 450, 450, 100, 0.5, 15, 5, Angle, RGB(100, 200, 200), RGB(0, 150, 150))
      
      
    StopDrawing()
    SetGadgetState(0, UseImage(0))
    
  EndIf
  
Until Event = #PB_EventCloseWindow

KillTimer_(WindowID(), 0)

End

Posted: Thu Feb 17, 2005 11:30 pm
by kawasaki
Very nice example of progresspies :P

Posted: Tue Apr 12, 2005 10:03 am
by akee
nice pies...

Posted: Wed Apr 13, 2005 4:50 pm
by dell_jockey
nice indeed, Mischa!

and now for a fully anti-aliased version....

Relax, just kidding!

Posted: Wed Apr 13, 2005 10:18 pm
by Le Soldat Inconnu
Anti-aliazed version ?
very simple

just draw your pie with a big size

and resize your image

the result is the pie Anti-aliazed.

It's low but it's a very simple way

Posted: Wed Apr 13, 2005 10:22 pm
by GeoTrail
What does

Code: Select all

SetTimer_(WindowID(), 0, 50, 0)
do?

Posted: Thu Apr 14, 2005 2:56 am
by akee
GeoTrail wrote:What does

Code: Select all

SetTimer_(WindowID(), 0, 50, 0)
do?
It is to enable the timer so that a WM_TIMER event is trigered every specified time slice.

Posted: Thu Apr 14, 2005 9:07 am
by GeoTrail
Aaa I see, thanx :)