Posted: Sat Mar 15, 2008 4:36 pm
Frankly, I agree. I don't know what I wanted to achieve.walker wrote:@Demivec: didn't understand what you want to achieve with the line state%segments ,,,,

On to other things.
1. I think it would be better to avoid redrawing all of the states each time you are only advancing by one. Here is my change: set only a single state, unless the value of state is negative. If state<0 then set the range of states from 1 to +state.
2. Changed state drawing calculations. Made calculations more precise and did away with nudging. The number of Segments is now only limited by resolution instead of wether it was divisible by 4 (or any other #). The smallest working (Size,Segments) combo is 12 with 8 Segments!:shock: If you want to read the text the smallest Size would be 26, if you've got good eyes.

Here's the code with changes included:
Code: Select all
;- ProgressCircle
; 2008 by walker
; modifications by ebs
; modifications by Demivec
; modifications by walker
;--------------------------------------------
;-free for everyone and any purposes
;-enhancements made by others
;-must be published and posted in the same PB-Forum ;-)
;-cross plattform ability must be achieved
;--------------------------------------------
EnableExplicit
Procedure ProgressCircle(gadgetNumber.l,x.l,y.l,Size.l,segments.l,fg.l,bg.l)
Protected radius.l,n.l,X2.l,Y2.l,img.l, beta_in_rad.d
img = CreateImage(#PB_Any,Size,Size)
StartDrawing(ImageOutput(img))
Box(0,0,Size,Size,bg)
radius = Size/2
Circle(radius,radius,radius,fg)
Circle(radius,radius,2*radius/3,bg)
; draw radial lines
For n = 0 To segments-1
beta_in_rad = (2*#PI*n)/segments - #PI/2 ; [Demivec] updated formula makes nudging unnecessary in SetProgressCircleState
X2.l = radius *(1 + Cos(beta_in_rad))
Y2.l = radius *(1 + Sin(beta_in_rad))
LineXY(radius,radius,X2,Y2,bg)
Next
StopDrawing()
ImageGadget(gadgetNumber,x,y,Size,Size,ImageID(img))
SetGadgetData(gadgetNumber, img) ;store #image with gadget
EndProcedure
Procedure SetProgressCircleState(progressbar.l,segments.l, state.l, Text.s , COLOR.l, backgroundcolor.l, textcolor.l=0)
Static progCirc_font.l
Protected IW2.l,TW2.l,TH2.l,x.l,y.l
Protected img.l = GetGadgetData(progressbar) ;retrieve stored #image
Protected beta_in_rad.d
Protected m.l,rangeStart.l ; [Demivec]
IW2.l = ImageWidth(img)/2
If progCirc_font = 0 ;avoid loading font if it is already loaded
progCirc_font = LoadFont(#PB_Any,"sans",IW2/3-1,#PB_Font_Bold)
EndIf
StartDrawing(ImageOutput(img))
If Text
; use circle color for text
DrawingFont(FontID(progCirc_font));
TH2 = TextHeight(Text)/2
TW2 = TextWidth(Text)/2
Circle(IW2,IW2,2*IW2/3,backgroundcolor) ;
DrawText(IW2-TW2,IW2-TH2,Text,textcolor,backgroundcolor)
EndIf
;check if setting a range or only a single state [Demivec]
; a range will be set (of from 1 to state) if state is negative,
; only the single state will be set if state>0
If state<0
rangeStart = 1
state * -1
Else
rangeStart = state
EndIf
; adjust angle so first segment is at top of circle
state -1
For m= rangeStart - 1 To state ; To clear the circle (set color to initial color and text to 1 space, and state=-segments) [Demivec] changed explanation
beta_in_rad.d = #PI*((2*m+1)/segments - 1/2) ; [Demivec] updated formula makes nudging unnecessary
; calculate point on radius
x = IW2 + (IW2 - 2)*Cos(beta_in_rad) ; [Demivec] adjusted to find a point at a set distance from largest radius
y = IW2 + (IW2 - 2)*Sin(beta_in_rad) ; to avoid segment lines
FillArea(x,y,backgroundcolor,COLOR)
Next
StopDrawing()
SetGadgetState(progressbar,ImageID(img))
While WindowEvent():Wend; update the gadget
ProcedureReturn 1
EndProcedure
;---- DEMO -----<
Define.l bg,fg,stp,Size,r,g,b,count,m
Define.l Event
bg=$D2D8C3; backgroundcolor
fg=$AAB68F; initial color of the circle
stp=33 ;Any value allowed, working values are usually less than Size (i.e. stp<Size), [Demivec]
;for max segments for lower sizes these work (stp,size) (32,30) (16,20) (12,16) (8,12), (100,120) (1 to 44,50)
Size=50 ;12 is minimum; maximum... your screen ;-)
OpenWindow(0,0,0,310,310,"ProgressCircle DEMO",#PB_Window_SystemMenu | #PB_Window_SizeGadget)
CreateGadgetList(WindowID(0))
ProgressCircle(0,70,70,Size,stp,fg,bg)
r=10
g=150
b=10
count=0
Repeat
For m= 1 To stp
SetProgressCircleState(0,stp,m,Str(1+100/stp*m)+ "%",RGB(r, g, b),bg, RGB(236, 200-(m*5), 19)) ; [Demivec] adjusted % calculation
Delay(300)
Event = WindowEvent()
While Event ;improved event catcher for demo
If Event = #PB_Event_CloseWindow
Break 2
EndIf
Event=WindowEvent()
Wend
Next
count+1
r+20
g+20
b+10
If r >240 Or g>240 Or b>240
r=Random(255)
g=Random(255)
b=Random(255)
EndIf
Until Event =#PB_Event_CloseWindow Or count=3
SetProgressCircleState(0,stp,-stp," ",fg,bg); clear the ProgressCircle.... [Demivec] using new parameter method
Delay(3000)
End