Multiple Knobs

Share your advanced PureBasic knowledge/code with the community.
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Multiple Knobs

Post by einander »

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
Cheers!
Last edited by einander on Thu Oct 24, 2013 1:33 am, edited 1 time in total.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Multiple Knobs

Post by idle »

nice thanks!
Windows 11, Manjaro, Raspberry Pi OS
Image
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Multiple Knobs

Post by davido »

Excellent. Thank you for sharing. :D
DE AA EB
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Multiple Knobs

Post by IdeasVacuum »

top knobs! 8)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Multiple Knobs

Post by rsts »

Wow, another beauty from einander.

Thanks for sharing. :D
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Multiple Knobs

Post by Kwai chang caine »

Very nice, thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
SoS
User
User
Posts: 13
Joined: Sat Feb 18, 2006 4:46 am

Re: Multiple Knobs

Post by SoS »

A never ending Repeat/Until Story.
Image
User avatar
NicknameFJ
User
User
Posts: 90
Joined: Tue Mar 17, 2009 6:36 pm
Location: Germany

Re: Multiple Knobs

Post by NicknameFJ »

Very nice.

Thank you einander for sharing.

NicknameFJ
PS: Sorry for my weird english, but english is not my native language.



Image
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Re: Multiple Knobs

Post by zxtunes.com »

Thx!

But have bug.

if you click the mouse when the cursor is outside of the circle and put it in a circle without letting go of the button, then release the button when the knob continues to think that I retain it.
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Re: Multiple Knobs

Post by einander »

Thanks! :D
Updated.
Now the knobs can be started only clicking the mouse inside them.
Post Reply