Code: Select all
;Multi KNOB by einander
;PB 5.20 LTS
EnableExplicit
;
Structure KNOB
Canv.I
Size.L
MinValue.L
MaxValue.L
Value.L
xCenter.L
yCenter.L
RGB1.L
RGB2.L
LightRGB.L
BkRGB.I
Ang.F
Info.L
EndStructure
;
Define Instances=9,Index,Ev,Catch,Offx
Global Dim _KNOB.KNOB(Instances),_BkRGB=$55
;
Structure Pointf
X.F : Y.F
EndStructure
;
Macro MMk
Abs(GetAsyncKeyState_(#VK_LBUTTON) +GetAsyncKeyState_(#VK_RBUTTON)*2+GetAsyncKeyState_(#VK_MBUTTON)*3)/$8000
EndMacro
;
Macro CMMx(Canv)
GetGadgetAttribute(Canv, #PB_Canvas_MouseX)
EndMacro
;
Macro CMMy(Canv)
GetGadgetAttribute(Canv, #PB_Canvas_MouseY)
EndMacro
;
Procedure Distance(X1, Y1, X2, Y2) ; Ret Int con LONGIT DE LA HIPOTEN DEL TRIANG RECTANG DADOS 2 LADOS
ProcedureReturn Sqr((X1-X2)*(X1-X2)+(Y1-Y2)*(Y1-Y2))
EndProcedure
;
Procedure DrawArc(X, Y, Ang1.F,Ang2.F, Radius.F, Color=#Red)
Ang1=Radian(Ang1):Ang2=Radian(Ang2)
Protected Stp.F = #PI /(Radius*4)
If Ang2<Ang1:Swap Ang1,Ang2:EndIf
Repeat
Box(X+Cos(Ang1) * Radius,Y+Sin(Ang1) * Radius, 2, 2, Color)
Ang1 + Stp
Until Ang1 > Ang2
;
EndProcedure
;
Procedure Lim(A,B,C)
If A<B :ProcedureReturn B
ElseIf A>C :ProcedureReturn C
EndIf
ProcedureReturn A
EndProcedure
;
Procedure AngLine(X.D,Y.D,Ang.D,LineSize.D,RGB=0) ;- AngLine(x,y,Ang,LineSize) - Draw Line with Len LineSize From x y with Angle Ang
LineXY(X,Y,X+Cos(Radian(Ang))*LineSize ,Y+Sin(Radian(Ang))*LineSize,RGB)
EndProcedure
;
Macro ConiCGradient(X,Y,RGB1,RGB2,Ang)
DrawingMode(#PB_2DDrawing_Gradient)
FrontColor(RGB1)
BackColor(RGB2)
ConicalGradient(X, Y,Ang)
EndMacro
;
Procedure AngleEndPoint(X.D,Y.D,Ang.D,LineSize.D,*P.PointF) ; Ret circular end PointF for Line, Angle, Size
*P\X= X+Cos(Radian(Ang))*LineSize
*P\Y= Y+Sin(Radian(Ang))*LineSize
EndProcedure
;
Procedure DrawPie(X,Y, Ang1,Ang2,Radius,RGB)
Protected Pf.Pointf
Angline(X,Y,Ang1,Radius,RGB)
Angline(X,Y,Ang2,Radius,RGB)
Drawarc(X,Y,Ang1,Ang2,Radius,RGB)
Angleendpoint(X,Y,(Ang1+Ang2)/2,Radius/2,@Pf)
FillArea(Pf\X,Pf\Y,-1,RGB)
EndProcedure
;
Procedure.F GetAngle(X1.F,Y1.F,X2,Y2) ; Ret Angle (Float)
Protected.F A = X2-X1 , B = Y2-Y1 , C = Sqr(A*A+B*B)
Protected Ang.F = Degree(ACos(A/C))
If Y1 > Y2 : ProcedureReturn 360-Ang : EndIf
ProcedureReturn Ang
EndProcedure
;
Procedure SpinKNOB(Index)
With _KNOB(Index)
Protected RGB,Radius=\Size/2-1
Protected J,P.Pointf,R=Radius*0.8
StartDrawing(CanvasOutput(\Canv))
Box(0,0,OutputWidth(),OutputHeight(),\BkRGB)
CONICGradient(\xCenter,\yCenter,$333333,$888888,90)
Circle(\xCenter,\yCenter,Radius)
DrawingMode(0)
For J=0 To 7
Angline(\xCenter,\yCenter,J*45,Radius*0.93,$Aaaaaa)
Next
RGB=Point(P\X,P\Y)
Angleendpoint(\xCenter,\yCenter,\Ang-90,Radius*0.84,P.Pointf)
Circle(\xCenter,\yCenter,Radius*0.85,$121212)
If \Value>\MinValue
Drawpie(\xCenter,\yCenter,-90,\Ang-90,Radius*0.85,#Green)
EndIf
LineXY(\xCenter,\yCenter,\xCenter,\yCenter-Radius,0)
LineXY(\xCenter,\yCenter,P\X,P\Y,0)
ConiCGradient(\xCenter,\yCenter,\RGB1,\RGB2,-\Ang+90)
Circle(\xCenter,\yCenter,Radius*0.75)
ConiCGradient(\xCenter,\yCenter,\RGB2,\RGB1,-\Ang+90)
Circle(\xCenter,\yCenter,Radius*0.70)
DrawingMode(#PB_2DDrawing_Outlined)
Circle(\xCenter,\yCenter,Radius*0.75,$676767)
StopDrawing()
EndWith
EndProcedure
;
Procedure.F RotaF(X.F ,Min.F ,Max.F )
Protected A.F
If X>=Min And X<=Max :ProcedureReturn X :EndIf
If X <-Min :A=-1 :EndIf
If X >=Min
ProcedureReturn Mod((X -Min -A), (1+Max -Min )) + A+Min
EndIf
ProcedureReturn Mod((1+X -Min -A), (1+Max -Min )) + A+Max
EndProcedure
;
Procedure Proportion(X.F, Min,Max,A.F,Z.F)
If X = Min : ProcedureReturn A: EndIf
If X = Max : ProcedureReturn Z: EndIf
Protected B.F=(Max-Min) / (X - Min)
ProcedureReturn Lim(A + (Z-A) / B,A,Z)
EndProcedure
;
Procedure KNOBSettings(Instances)
Protected Index,Offx,X=50,Y=100
For Index=0 To Instances
With _KNOB(Index)
\MinValue=0 ; ---------------- your settings here
\MaxValue=1000
\RGB1=$Bfbfbf
\RGB2=$454545
\LightRGB=$FfAa
\BkRGB=_BkRGB
; -----------------------------------
If Index<5 :\Size=140 ; test different sizes <<<<<<<<<
Else :\Size=100:Offx=40
EndIf
If Index And Index%5=0
X=50: Y+200
EndIf
\Canv=CanvasGadget(#PB_Any, X+Offx/2,Y,\Size,\Size,#PB_Canvas_Keyboard)
X+\Size+Offx+6
\xCenter=\Size/2.0
\yCenter=\Size/2.0
\Info=TextGadget(#PB_Any,GadgetX(\Canv)+\xCenter,GadgetY(\Canv)-35,100,30,"")
SetGadgetColor(\Info,#PB_Gadget_FrontColor,#White)
SetGadgetColor(\Info,#PB_Gadget_BackColor,\BkRGB)
SpinKNOB(Index)
SetGadgetText(\Info,Str(\Value))
EndWith
Next
EndProcedure
;
; Test it ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;
OpenWindow(0, 0, 0, 800, 600, "Multi KNOB", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowColor(0,_BkRGB)
KNOBSettings(Instances)
;
Repeat
Ev = WaitWindowEvent(1)
If EventType() = #PB_EventType_LeftButtonUp Or MMk=0 Or Index>Instances
Catch=0
EndIf
If Catch
With _KNOB(Index)
\Ang=RotaF(GetAngle(WindowMouseX(0),WindowMouseY(0),GadgetX(Catch)+\xCenter,GadgetY(Catch)+\yCenter)-90,0,360)
SpinKNOB(Index)
\Value= Proportion(\Ang,0,360,\MinValue,\MaxValue)
SetGadgetText(\Info,Str(\Value))
EndWith
Else
For Index=0 To Instances
With _Knob(Index)
If GetDlgCtrlID_(WindowFromPoint_(DesktopMouseX()|DesktopMouseY()<<32))=\Canv
If EventType()=#PB_EventType_LeftButtonDown And Distance(CMMx(\Canv),CMMy(\Canv),\xCenter,\yCenter)<\Size/2-1
Catch=\Canv
Break
EndIf
EndIf
EndWith
Next
EndIf
Until Ev = #PB_Event_CloseWindow
;
End