Page 1 of 1

Multi slider trackbar

Posted: Fri Mar 02, 2007 4:16 pm
by localmotion34
someone posted the question of how to create a multi trackbar, and here is my example. its not very optimized, and is a tiny bit buggy, but maybe if some more experienced people could help out and streamline the code, we can all use a really cool gadget. i basically emulated a slider control from Video Avatar, and all the drawing is done to an image on a static control. no flickering, even on a very slow machine. this eliminates the need of constant #wm_paint messages and processing.

Code: Select all

#pb_settrack1=8000
#pb_settrack2=8001
#pb_getselrange=8002
#WM_MOUSEHOVER = $2A1
#WM_MOUSELEAVE = $2A3
#TME_HOVER = 1
#TME_LEAVE = 2

Global ticktomove.l , mousedownx.l,deltaX.l 
Structure trackbar
  width.l
  height.l
  pbID.l
  tick1pos.l
  tick2pos.l
  range.l
  rangestep.l
  pbimage.l
  tick1.RECT
  tick2.RECT
  
EndStructure

Procedure.w LOWORD(Value.l) ;windef.h macro
  ProcedureReturn (Value & $FFFF)
EndProcedure

Procedure.w HIWORD(Value.l) ;windef.h macro
  ProcedureReturn ((Value >> 16) & $FFFF)
EndProcedure 

Macro DrawTick(xPos)
  Box(xPos-4,4,8,12,#White);tick 1
  Box(xPos-3,5,8,13,#Black)
  Box(xPos-3,5,7,12,GetSysColor_(#COLOR_BTNFACE)) 
EndMacro 



Procedure TrackbarProc(hwnd,msg,wParam,lParam)
  *track.trackbar=GetWindowLong_(hwnd,#GWL_USERDATA)
  Select msg
    
    Case #WM_PAINT 
      
    Case #WM_LBUTTONDOWN
      
      xPos = LOWORD(lParam)
      yPos = HIWORD(lParam)
      tick1.RECT
      tick1\left=*track\tick1pos-4
      tick1\right=*track\tick1pos+4
      tick1\top=4
      tick1\bottom=16
      tick2.RECT
      tick2\left=*track\tick2pos-4
      tick2\right=*track\tick2pos+4
      tick2\top=4
      tick2\bottom=16
      If ptinrect_(tick1.RECT,xPos,yPos)
        SetCapture_(hwnd)
        ticktomove=1
        mousedownx=xPos
      ElseIf ptinrect_(tick2.RECT,xPos,yPos)
        SetCapture_(hwnd)
        ticktomove=2
        mousedownx=xPos
      EndIf 
      ProcedureReturn 0
    Case #WM_LBUTTONUP
      Select ticktomove
        Case 1
          *track\tick1pos=*track\tick1pos+deltaX
          SetWindowLong_(hwnd,#GWL_USERDATA,*track)
        Case 2
          *track\tick2pos=*track\tick2pos+deltaX
          SetWindowLong_(hwnd,#GWL_USERDATA,*track)
      EndSelect
      
      ReleaseCapture_()
    Case #WM_RBUTTONDOWN
      
    Case #WM_RBUTTONUP
      
    Case #WM_MOUSEMOVE
      deltaX=0
        Structure myTRACKMOUSEEVENT
          cbSize.l
          dwFlags.l
          hwndTrack.l  
          dwHoverTime.l
        EndStructure
        mte.myTRACKMOUSEEVENT
        mte\cbSize = SizeOf(myTRACKMOUSEEVENT)
        mte\dwFlags = #TME_LEAVE
        mte\hwndTrack = hwnd
        TrackMouseEvent_(mte)
        If getcapture_()=hwnd
          xPos = LOWORD(lParam)
          yPos = HIWORD(lParam)
          deltaX.l=xPos-mousedownx
          Select ticktomove
            Case 1
              If xPos <= 3 Or xPos>= *track\tick2pos-4
              Else
                hdc=StartDrawing(ImageOutput(*track\pbimage))
              Box(0,0,*track\width,*track\height,GetSysColor_(#COLOR_BTNFACE))
              Box(1,10,*track\width,2,#Black) ; center black line
              Box(0,20,*track\width,20,$0000B91C) ; slider range
              Box(*track\tick1pos+deltaX,20,*track\tick2pos-(*track\tick1pos+deltaX),20,$00FE6A02) ;highlight region
              DrawTick(*track\tick1pos+deltaX)
              DrawTick(*track\tick2pos)
              StopDrawing()
              SetGadgetState(*track\pbID,ImageID(*track\pbimage))
              
              ProcedureReturn 0
            EndIf 
            Case 2
              If xPos > *track\width-6 Or xPos<= *track\tick1pos+4
                Else
              hdc=StartDrawing(ImageOutput(*track\pbimage))
              Box(0,0,*track\width,*track\height,GetSysColor_(#COLOR_BTNFACE))
              Box(1,10,*track\width,2,#Black) ; center black line
              Box(0,20,*track\width,20,$0000B91C) ; slider range
              Box(*track\tick1pos,20,(*track\tick2pos+deltaX)-(*track\tick1pos),20,$00FE6A02) ;highlight region
              DrawTick(*track\tick2pos+deltaX)
              DrawTick(*track\tick1pos)
              StopDrawing()
              SetGadgetState(*track\pbID,ImageID(*track\pbimage))
              ProcedureReturn 0
            EndIf 
          EndSelect 
      EndIf 
    Case #WM_MOUSEHOVER 
      
    Case #WM_MOUSELEAVE
      
    Case #pb_settrack1
      
    Case #pb_settrack2
    
      
  EndSelect 
  ProcedureReturn CallWindowProc_(GetProp_(hwnd,"oldproc"),hwnd,msg,wParam,lParam)
EndProcedure 

Procedure MultiTrackbar(id.l,x,Y,width,height,TrackRange, Trackstep)
  *track.trackbar=AllocateMemory(SizeOf(trackbar))
  image.l=CreateImage(#PB_Any,width,height)
  hdc=StartDrawing(ImageOutput(image))
  Box(0,0,width,height,GetSysColor_(#COLOR_BTNFACE))
  Box(1,10,width,2,#Black) ; center black line
  
  Box(0,20,width,20,$0000B91C) ; slider range
  xdiv=Round(width/3,0)
  Box(xdiv,20,xdiv,20,$00FE6A02) ;highlight region
  
  DrawTick(xdiv) ; tick 1
 *track\tick1pos=xdiv
  
  nextdiv.f=xdiv*2
  DrawTick(nextdiv);tick 2
  *track\tick2pos=nextdiv
  StopDrawing()
  imagegad.l=ImageGadget(id,x,Y,width,height,ImageID(image))
  
  If id=#PB_Any
    *track\pbID=imagegad
    hwndreturn=imagegad
    hwnd=GadgetID(imagegad)
  Else
    *track\pbID=id
    hwndreturn=imagegad
    hwnd=imagegad
  EndIf 
  
  With *track
    \width=width
    \height=height
    \pbimage=image
    \range=TrackRange
    \rangestep=Trackstep
  EndWith 
  SetProp_(hwnd,"oldproc",SetWindowLong_(hwnd,#GWL_WNDPROC,@TrackbarProc()))
  SetWindowLong_(hwnd,#GWL_USERDATA,*track)
  
  ProcedureReturn hwndreturn
EndProcedure 

If OpenWindow(0, 259, 217, 605, 388, "MultiTrackbar",  #PB_Window_SystemMenu |  #PB_Window_TitleBar | #PB_Window_ScreenCentered )
  
  
  If CreateGadgetList(WindowID(0))
    MultiTrackbar(10,30,100,400,60,1000,50)
  EndIf
EndIf


;-Event Loop 
Repeat 
  Select WaitWindowEvent()
    Case #PB_Event_Gadget
      Select EventGadget()
        
        
        
      EndSelect
    Case #PB_Event_Menu
      Select EventMenu()
        
      EndSelect 
    Case #PB_Event_CloseWindow
      Quit=1
  EndSelect
Until Quit=1 

Posted: Sat Mar 03, 2007 7:18 pm
by Konne
There is a bug if both of the control touch you can move them anymore or stuff like that.