It is currently Fri May 24, 2013 1:57 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: Track Selection Gadget - Revised June 26 2011
PostPosted: Sun May 01, 2011 3:04 am 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
I wanted to give the new CanvasGadget a run through its paces and I got this idea from a question in the coding questions forum. It's a selection tool that allows you to set an upper and lower selection point in a large set of <whatever>, say, movie frames for example. I obviously haven't tapped into every feature of the canvas gadget in this project but it's being put to a pretty reasonable test imho. So far it performs exactly as advertised with no disappointments. Beta 2, 1 really as this wasn't improved for 2 and the performance is rock-solid. Really impressive for something this far from its release date. Probably a few bugs in it, it's early. But here's the Canvas Gadget implemented as a TrackSelection tool:

Image

June 26 2011:
Code is updated to use CustomRegions.pbi (available in this forum) and is now nearly crossplatform. The only thing OS-specific in it is the GetSysColor_() command and if some kind Linux/MacOS coder posts or pms the equivalents I can modify this to be fully crossplatform.

Also fixed a small bug in the drawing where the selection box was one pixel too wide. This can be seen in the posted graphic, which I haven't changed.

Code:
;=============================================================
; Library:            TrackSelectionGadget
; Author:             Lloyd Gallant (netmaestro)
; Date:               April 30, 2011
; Target compiler:    Purebasic 4.60 and later
; Target OS:          Microsoft Windows all
; License:            Free, unrestricted, no warranty
;=============================================================
;
;  How to use the gadget:

;  - Leftclick and drag the lower pointer to set the selection endpoint
;  - Leftclick and drag the upper pointer to set the selection startpoint
;  - Fine-tune the selections with the mousewheel while the mousepointer is over the appropriate pointer
;  - Move the selection endpoint one increment higher/lower with the Right/Left tArrow keys
;  - Move the selection startpoint one increment higher/lower with the Shift/Right and Shift/left arrow keys
;  - Leftclicks outside the thumbs affect the startpoint if the mousepointer is in the top half of the gadget,
;    and the endpoint if the mousepointer is in the bottom half.
;
;  - Note: keyboard control of fine-tuning is scrapped in favor of the mousewheel only.
;

XIncludeFile "CustomRegions.pbi"

Structure TrackData
  p_region1.l
  p_region2.l
  baseimage.l
  baseimagetop.l
  baseimageleft.l
  bclientwidth.l
  baseimagewidth.l
  pointer1.l
  pointer2.l
  selection_start.l
  selection_end.l
  selection_max.l
  tickmin.l
  tickmax.l
  tickleftx.l
  tickrightx.l
  pointer1top.l
  pointer2top.l
  pointer1x.l
  pointer2x.l
  pointermin.l
  pointermax.l
  startchanged.l
  endchanged.l
  displayfont.l
EndStructure

Procedure CreatePointers()
  Protected ptr, i, j
  ptr = CreateImage(#PB_Any, 11,30,32|#PB_Image_Transparent)                 
 
  Protected Dim pcolors(4)
  pcolors(0) = RGBA(0,0,0,0)
  pcolors(1) = GetSysColor_(#COLOR_3DDKSHADOW) |$FFFFFFFFFF000000
  pcolors(2) = GetSysColor_(#COLOR_3DSHADOW)   |$FFFFFFFFFF000000
  pcolors(3) = GetSysColor_(#COLOR_3DFACE)     |$FFFFFFFFFF000000
  pcolors(4) = GetSysColor_(#COLOR_3DHIGHLIGHT)|$FFFFFFFFFF000000               
 
  StartDrawing(ImageOutput(ptr))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Restore base   : For i=0 To 10  : Read.i index  : Plot(i,0,pcolors(index)) : Next
    For j=1 To 9   : Restore body   : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next
    Restore pdn    : For j=10 To 14 : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next
    Restore pup    : For j=15 To 19 : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next   
    For j=20 To 28 : Restore body   : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next   
    Restore base   : For i=0 To 10  : Read.i index  : Plot(i,29,pcolors(index)) : Next
  StopDrawing()
 
  ProcedureReturn ptr
 
  DataSection
    base: Data.i 4,4,4,4,4,4,4,4,4,4,1
    body: Data.i 4,3,3,3,3,3,3,3,3,2,1
    pdn:  Data.i 0,4,3,3,3,3,3,3,2,1,0,0,0,4,3,3,3,3,2,1,0,0,0,0,0,4,3,3
          Data.i 2,1,0,0,0,0,0,0,0,4,2,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
    pup:  Data.i 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,4,2,1,0,0,0,0,0,0,0,4,3,3
          Data.i 2,1,0,0,0,0,0,4,3,3,3,3,2,1,0,0,0,4,3,3,3,3,3,3,2,1,0
  EndDataSection
 
EndProcedure

Procedure RedrawTrackSelectionGadget(gadget)
  *p.TrackData = GetGadgetData(gadget)
  StartDrawing(CanvasOutput(Gadget))
    Box(0,0,GadgetWidth(Gadget),GadgetHeight(Gadget),GetSysColor_(#COLOR_3DFACE))
    DrawImage(ImageID(*p\baseimage),*p\baseimageleft,*p\baseimagetop)
    Box(*p\tickleftx,*p\baseimagetop+2,*p\tickrightx-*p\tickleftx,11,GetSysColor_(#COLOR_MENUHILIGHT))
    DrawAlphaImage(ImageID(*p\pointer1),*p\pointer1x,*p\pointer1top)   
    DrawAlphaImage(ImageID(*p\pointer2),*p\pointer2x,*p\pointer2top)
   
    Box(*p\tickmin-17,*p\pointer1top-11,35,10, GetSysColor_(#COLOR_INFOBK))
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(*p\tickmin-17,*p\pointer1top-11,35,10,GetSysColor_(#COLOR_3DDKSHADOW))
    DrawingFont(*p\displayfont)
    DrawingMode(#PB_2DDrawing_Transparent)
    txt$ = Str(*p\selection_start)
    w = TextWidth(txt$)/2
    DrawText(*p\tickmin-w,*p\pointer1top-11,txt$,GetSysColor_(#COLOR_INFOTEXT))
   
    DrawingMode(#PB_2DDrawing_Default)
    Box(*p\tickmin-17,*p\pointer2top+16,35,10,GetSysColor_(#COLOR_INFOBK))
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(*p\tickmin-17,*p\pointer2top+16,35,10,GetSysColor_(#COLOR_3DDKSHADOW))
    DrawingFont(*p\displayfont)
    DrawingMode(#PB_2DDrawing_Transparent)
    txt$ = Str(*p\selection_end)
    w = TextWidth(txt$)/2
    DrawText(*p\tickmin-w,*p\pointer2top+16,txt$,GetSysColor_(#COLOR_INFOTEXT))   
   
  StopDrawing()
EndProcedure

ProcedureDLL TrackSelectGadget(gadgetnumber, x, y, width, min=0, max=100, drawfocus=0)
  tmp = CreatePointers()
  pointer1 = GrabImage(tmp, #PB_Any,0,0,11,15)
  pointer2 = GrabImage(tmp, #PB_Any,0,15,11,15)
  FreeImage(tmp)
 
  If drawfocus
    flags = #PB_Canvas_Keyboard|#PB_Canvas_GrabMouse|#PB_Canvas_DrawFocus
  Else
    flags = #PB_Canvas_Keyboard|#PB_Canvas_GrabMouse
  EndIf
 
  Protected height = 60
  If gadgetnumber = #PB_Any
    result = CanvasGadget(#PB_Any, x, y, width, height, flags)
    gadgetnumber = result
  Else
    result = CanvasGadget(gadgetnumber, x, y, width, height, flags)
  EndIf
 
  h1 = CreateBitmapRegion(pointer1)
  h2 = CreateBitmapRegion(pointer2)
 
  *gadgetdata.TrackData = AllocateMemory(SizeOf(TrackData))
  With *gadgetdata
    \p_region1       = h1
    \p_region2       = h2
    \baseimage       = baseimage
    \baseimagetop    = 23
    \baseimageleft   = 20
    \baseimagewidth  = width-36
    \bclientwidth    = \baseimagewidth-5
    \pointer1        = pointer1
    \pointer2        = pointer2
    \selection_start = 0
    \selection_end   = 0
    \selection_max   = max
    \tickmin         = 22
    \tickmax         = width-19
    \pointer1top     = 15
    \pointer2top     = 30
    \tickleftx       = 22
    \tickrightx      = 22
    \pointer1x       = 17
    \pointer2x       = 17
    \pointermin      = 17
    \pointermax      = width-24
    \displayfont     = LoadFont(0,"verdana", 6)
  EndWith
 
  SetGadgetData(gadgetnumber, *gadgetdata)
  *gadgetdata\baseimage = CreateImage(#PB_Any, *gadgetdata\baseimagewidth,15)
 
  StartDrawing(ImageOutput(*gadgetdata\baseimage))
    Box(0,0,*gadgetdata\baseimagewidth,15,GetSysColor_(#COLOR_3DFACE))
    Box(0,0,*gadgetdata\baseimagewidth-1,1,GetSysColor_(#COLOR_3DSHADOW))
    Box(0,0,1,14,GetSysColor_(#COLOR_3DSHADOW))
    Box(1,1,1,12,GetSysColor_(#COLOR_3DDKSHADOW))
    Box(1,1,*gadgetdata\baseimagewidth-3,1,GetSysColor_(#COLOR_3DDKSHADOW))
    Box(2,2,*gadgetdata\baseimagewidth-5,11,GetSysColor_(#COLOR_3DHIGHLIGHT))
    Box(1,13,*gadgetdata\baseimagewidth-4,1,GetSysColor_(#COLOR_3DFACE))
    Box(0,14,*gadgetdata\baseimagewidth-2,1,GetSysColor_(#COLOR_3DHIGHLIGHT))
    Box(*gadgetdata\baseimagewidth-3,1,1,13,GetSysColor_(#COLOR_3DFACE))
    Box(*gadgetdata\baseimagewidth-2,0,1,15,GetSysColor_(#COLOR_3DHIGHLIGHT))
  StopDrawing()
 
  RedrawTrackSelectionGadget(gadgetnumber)
  ProcedureReturn result
EndProcedure

ProcedureDLL GetTrackSelectionStart(gadget)
  *p.TrackData = GetGadgetData(gadget)
  ProcedureReturn *p\selection_start
EndProcedure

ProcedureDLL GetTrackSelectionEnd(gadget)
  *p.TrackData = GetGadgetData(gadget)
  ProcedureReturn *p\selection_end
EndProcedure

ProcedureDLL CheckSelectionStartChanged(gadget)
  *p.TrackData = GetGadgetData(gadget)
  If *p\startchanged
    *p\startchanged=0
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

ProcedureDLL CheckSelectionEndChanged(gadget)
  *p.TrackData = GetGadgetData(gadget)
  If *p\endchanged
    *p\endchanged=0
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

ProcedureDLL HandleTrackEvents(EventGadget,EventType)
  Static hot1, hot2, xoffset
  *p.TrackData = GetGadgetData(EventGadget)
  mx = GetGadgetAttribute(EventGadget,#PB_Canvas_MouseX)
  my = GetGadgetAttribute(EventGadget,#PB_Canvas_MouseY)
 
  Select EventType
      ;       
    Case #PB_EventType_KeyDown
      key = GetGadgetAttribute(EventGadget, #PB_Canvas_Key)
      mods = GetGadgetAttribute(EventGadget, #PB_Canvas_Modifiers)
      Select key
        Case #PB_Shortcut_Right
          If mods & #PB_Canvas_Shift
            *p\pointer1x = *p\tickleftx-5
            If *P\tickleftx < *p\tickmax
              *p\tickleftx+1
              *p\pointer1x+1
              If *p\tickrightx < *p\tickleftx
                *p\tickrightx = *p\tickleftx
                *p\pointer2x = *p\tickrightx-5
              EndIf
            EndIf
            s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
            *p\selection_start = Int(s)
            *P\startchanged = 1
            If *p\selection_start > *p\selection_end
              *p\selection_end = *p\selection_start
              *p\endchanged = 1
            EndIf                 
            RedrawTrackSelectionGadget(EventGadget)
          Else
            *p\pointer2x = *p\tickrightx-5
            If *p\tickrightx < *p\tickmax
              *p\tickrightx+1
              *p\pointer2x+1
            EndIf
            e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
            *p\selection_end = Int(e)
            *p\endchanged = 1
            RedrawTrackSelectionGadget(EventGadget)
          EndIf
         
        Case #PB_Shortcut_Left
          If mods & #PB_Canvas_Shift
            *p\pointer1x = *p\tickleftx-5
            If *p\tickleftx > *p\tickmin
              *p\tickleftx-1
              *p\pointer1x-1
            EndIf
            s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
            *p\selection_start = Int(s)
            *P\startchanged = 1
            RedrawTrackSelectionGadget(EventGadget)
          Else
            *p\pointer2x = *p\tickrightx-5
            If *p\tickrightx > *p\tickmin
              *p\tickrightx-1
              *p\pointer2x-1
              If *p\tickleftx > *p\tickrightx
                *p\tickleftx = *p\tickrightx
                *p\pointer1x = *p\tickleftx-5
              EndIf
            EndIf
            e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
            *p\selection_end = Int(e)
            *p\endchanged = 1
            If *p\selection_end < *p\selection_start
              *p\selection_start = *p\selection_end
              *p\startchanged = 1
            EndIf                 
            RedrawTrackSelectionGadget(EventGadget)
          EndIf
         
      EndSelect
     
    Case #PB_EventType_LeftButtonDown
     
      If mx <= *p\tickrightx And mx >= *p\tickmin And (my <= 26)
        *p\pointer1x = mx-5
        If *p\pointer1x < *p\pointermin
          *p\pointer1x = *p\pointermin
        EndIf
        *p\tickleftx = *p\pointer1x+5
        s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
        *p\selection_start = Int(s)
        *P\startchanged = 1
        hot1 = #True : #hot2 = #False
        RedrawTrackSelectionGadget(EventGadget)
      ElseIf mx >= *p\tickleftx And mx <=*p\tickmax And (my >= 28)
        *p\pointer2x = mx-5
        If *p\pointer2x > *p\pointermax
          *p\pointer2x = *p\pointermax
        EndIf
        *p\tickrightx = *p\pointer2x+5
        e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
        *p\selection_end = Int(e)
        *p\endchanged = 1
        hot2 = #True : hot1 = #False
        RedrawTrackSelectionGadget(EventGadget)
      EndIf
     
    Case #PB_EventType_MouseWheel
      delta = GetGadgetAttribute(EventGadget, #PB_Canvas_WheelDelta)
      If PtinRegion(*p\p_region2, mx-*p\pointer2x, my-*p\pointer2top)
        If delta>0
          thisone = *p\selection_end
          e.d = Round(((*p\tickrightx+1-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
          nextone = Int(e)
          testone = thisone+1
          *p\pointer2x = *p\tickrightx-5
          If testone<nextone
            If *p\selection_end < nextone And *p\selection_end < *p\selection_max
              *p\selection_end+1
              *p\endchanged = 1
              RedrawTrackSelectionGadget(EventGadget)
            EndIf
          EndIf
        ElseIf delta < 0
          If *p\pointer2x = *p\tickrightx-5
            thisone = *p\selection_end
            e.d = Round(((*p\tickrightx-1-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
            nextone = Int(e)
            testone = thisone-1
            *p\pointer2x = *p\tickrightx-5
            If testone>nextone
              If *p\selection_end > nextone And *p\selection_end > *p\selection_start
                *p\selection_end-1
                *p\endchanged = 1
                RedrawTrackSelectionGadget(EventGadget)
              EndIf
            EndIf
          EndIf
        EndIf
      ElseIf PtinRegion(*p\p_region1, mx-*p\pointer1x, my-*p\pointer1top)
        If delta > 0
          thisone = *p\selection_start
          s.d = Round(((*p\tickleftx+1-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
          nextone = Int(s)
          testone = thisone+1
          *p\pointer1x = *p\tickleftx-5
          If testone>0
            If testone<nextone
              If *p\selection_start < nextone And *p\selection_start < *p\selection_end
                *p\selection_start+1
                *P\startchanged = 1
                RedrawTrackSelectionGadget(EventGadget)
              EndIf
            EndIf
          EndIf
        ElseIf delta < 0
          thisone = *p\selection_start
          s.d = Round(((*p\tickleftx-1-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
          nextone = Int(s)
          testone = thisone-1
          *p\pointer1x = *p\tickleftx-5
          If testone>=0
            If testone>nextone
              If *p\selection_start > nextone And *p\selection_start > 0
                *p\selection_start-1
                *P\startchanged = 1
                RedrawTrackSelectionGadget(EventGadget)
              EndIf
            EndIf
          EndIf
        EndIf         
      EndIf
     
    Case #PB_EventType_LeftButtonUp
      hot1 = #False
      hot2 = #False
     
    Case #PB_EventType_MouseMove
      buttonstate = GetGadgetAttribute(EventGadget, #PB_Canvas_Buttons)
      lbutton = buttonstate & #PB_Canvas_LeftButton
      If lbutton
        If hot1
          *p\pointer1x = mx-xoffset
          If *p\pointer1x < *p\pointermin
            *p\pointer1x = *p\pointermin
          ElseIf *p\pointer1x > *p\pointermax
            *p\pointer1x = *p\pointermax
          EndIf
          *p\tickleftx = *p\pointer1x+5
          If *p\tickrightx < *p\tickleftx
            *p\tickrightx = *p\tickleftx
            *p\pointer2x = *p\tickrightx-5
          EndIf
          s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
          *p\selection_start = Int(s)
          *P\startchanged = 1
          If *p\selection_start > *p\selection_end
            *p\selection_end = *p\selection_start
            *p\endchanged = 1
          EndIf
          RedrawTrackSelectionGadget(EventGadget)
         
        ElseIf hot2
          *p\pointer2x = mx-xoffset
          If *p\pointer2x < *p\pointermin
            *p\pointer2x = *p\pointermin
          ElseIf *p\pointer2x > *p\pointermax
            *p\pointer2x = *p\pointermax
          EndIf         
          *p\tickrightx = *p\pointer2x+5
          If *p\tickleftx > *p\tickrightx
            *p\tickleftx = *p\tickrightx
            *p\pointer1x = *p\tickleftx-5
          EndIf
          e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
          *p\selection_end   = Int(e)
          *p\endchanged = 1
          If *p\selection_end < *p\selection_start
            *p\selection_start = *p\selection_end
            *p\startchanged = 1
          EndIf
        EndIf
        RedrawTrackSelectionGadget(EventGadget)
      Else
        If PtinRegion(*p\p_region1, mx-*p\pointer1x, my-*p\pointer1top)
          SetGadgetAttribute(EventGadget, #PB_Canvas_Cursor,#PB_Cursor_Hand)
          hot1 = #True : hot2 = #False
          xoffset = mx-*p\pointer1x
        ElseIf PtinRegion(*p\p_region2, mx-*p\pointer2x, my-*p\pointer2top)
          SetGadgetAttribute(EventGadget, #PB_Canvas_Cursor,#PB_Cursor_Hand)
          hot2 = #True : hot1 = #False
          xoffset = mx-*p\pointer2x
        Else
          hot1=#False : hot2 = #False
          SetGadgetAttribute(EventGadget, #PB_Canvas_Cursor,#PB_Cursor_Default)
        EndIf
      EndIf
     
  EndSelect
 
EndProcedure

;========================================================
;                    End of Library Code
;========================================================

; Test program

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(0,20,20,100,20,"Button")
TrackSelectGadget(1,20,360,600,0,20129,1)

Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          HandleTrackEvents(EventGadget(), EventType())
      EndSelect
  EndSelect
 
Until ev = #PB_Event_CloseWindow

_________________
Veni, vidi, vici.


Last edited by netmaestro on Sun Jun 26, 2011 5:30 pm, edited 9 times in total.

Top
 Profile  
 
 Post subject: Re: Track Selection Gadget
PostPosted: Sun May 01, 2011 6:46 am 
Offline
Addict
Addict
User avatar

Joined: Tue Dec 23, 2003 3:54 am
Posts: 932
Location: New York
Brilliant :shock:

I don't have an immediate use for this, but it's a very nice gadget to have handy!
(Looks just like a native gadget, as well - clever.)

A cool variation would be: the pointer only appears when the mouse is over the control, and automatically jumps to whichever end you're hovering closest to. You could then drag the start and end points with just left-clicks, no right-clicks needed. (Although it could be tricky to use when the endpoints are too close and overlap.) Normally I'd try to implement this myself, but it's 2 AM here, I'm exhausted :)

Nice work!


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget
PostPosted: Sun May 01, 2011 10:42 am 
Offline
Always Here
Always Here
User avatar

Joined: Mon Sep 22, 2003 6:45 pm
Posts: 7304
Location: Norway
It looks very good, but it doesn't seem to act naturally. I just don't feel that I'm in control of the control (pun!).

Consider:
- The lower bound starts at 0, but once you set it to anything else, sometimes it won't go back to 0, only 1.
- Dragging the lower bound past the upper bound moves the upper bound, but left clicking past the upper bound does nothing (I'd expect it to behave like dragging the lower bound there).
- And vice versa for the upper bound.
- When clicking on the band outside the thumb to set the bound (instead of dragging the thumb) I'd find it natural if it started a drag operation.
- Why is there only one thumb? Wouldn't it be natural to have two thumbs, both operated by the left mouse button?

_________________
Woa, I set up a web server.


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget
PostPosted: Sun May 01, 2011 4:11 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
I agree, I don't like it either. It isn't intuitive and it takes too long to learn to use it without making a lot of mistakes. I took the single-thumb idea from the posted picture in Coding Questions, it just had the one thumb. What do you think of this idea?

Image

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 1/11
PostPosted: Sun May 01, 2011 10:33 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
Quote:
Consider:
- The lower bound starts at 0, but once you set it to anything else, sometimes it won't go back to 0, only 1.

I can't reproduce that no matter how hard I try
Quote:
- Dragging the lower bound past the upper bound moves the upper bound, but left clicking past the upper bound does nothing (I'd expect it to behave like dragging the lower bound there).

Agreed, done.
Quote:
- And vice versa for the upper bound.

Agreed, done.
Quote:
- When clicking on the band outside the thumb to set the bound (instead of dragging the thumb) I'd find it natural if it started a drag operation.

Agreed, done.
Quote:
- Why is there only one thumb? Wouldn't it be natural to have two thumbs, both operated by the left mouse button?

Agreed, done.

Thanks for your comments, they resulted in a much more intuitive control.

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 1/11
PostPosted: Sun May 08, 2011 8:47 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
Gadget is modified to always show the start/end selection points on the gadget itself, so no need to use statusbartext or textgadgets etc. Code in first post is updated.

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 8/11
PostPosted: Sun May 08, 2011 9:07 pm 
Offline
Addict
Addict

Joined: Thu Nov 01, 2007 5:37 pm
Posts: 1566
Location: Germany
Well, now it would be cool if the "value preview" would (optionally) move with the slider (and hide when cursor isn't over the gadget?) - similar to the #TBS_TOOLTIPS style. And you could use #COLOR_INFOBK (Tooltip background), #COLOR_INFOTEXT (Tooltip text) for it. ;)


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 8/11
PostPosted: Sun May 08, 2011 9:52 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
Quote:
And you could use #COLOR_INFOBK (Tooltip background), #COLOR_INFOTEXT (Tooltip text) for it.

Yes, good idea. On the moving info displays though there is a problem with the lower one. You can't see it under the cursor. You can move the cursor down out of the way while dragging because of #PB_Canvas_GrabMouse but for mousewheel finetuning it has to be in the way. Also, I thought it best that you can always read the settings whether the gadget is in focus or not.

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 8/11
PostPosted: Wed Jun 22, 2011 3:27 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Wed Sep 03, 2008 9:29 am
Posts: 270
Thanks for share this code :)


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 8/11
PostPosted: Thu Jun 23, 2011 4:12 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Fri Apr 04, 2008 6:20 pm
Posts: 124
Location: Belgium
Hi !, Tank for this code...
I speak French, and in gratitude, here's my contribution ...
Code:
; I wanted To give the new CanvasGadget a run through its paces And I got this idea from a question
; in the coding questions forum. It's a selection tool that allows you to set an upper and lower selection
; point in a large set of <whatever>, say, movie frames For example. I obviously haven't tapped into every
; feature of the canvas gadget in this project but it's being put To a pretty reasonable test imho.
; So far it performs exactly As advertised With no disappointments. Beta 2, 1 really As this wasn't
; improved For 2 And the performance is rock-solid. Really impressive For something this far from its
; release date. Probably a few bugs in it, it's early. But here's the Canvas Gadget implemented As a
; TrackSelection tool.
; ---------------------------
; Je voulais donner au CanvasGadget une nouvelle forme d'usage et j'ai eu cette idée suite à une
; question sur le forum. C'est un outil de sélection qui vous permet de définir un Point de sélection
; supérieure et inférieure dans un grand ensemble, disons, une image vidéo par exemple ou page editeur de texte.
; Je n'ai évidemment pas exploité toutes les fonctionnalités du Gadget "Canvas" dans ce projet mais il est
; mis soumis à un test raisonnable dans cet exemple. Jusqu'à présent, il se comporte exactement comme annoncé
; sans déceptions. Cela da,s les version Bêta 2, 1 vraiment et comme cela n'a pas été améliorée pour la Beta 3
; et la performance semble très stable. Vraiment impressionnant pour une version aussi loin de sa date de
; libération. Il y a/aura probablement quelques bugs dedans ? Il est tôt pour le dire. mais voici le Gadget
; "CanvasGadget" mis en œuvre comme un outil de "TrackSelection".
;
;  How to use the gadget:

;  - Leftclick and drag the lower pointer to set the selection endpoint
;  - Leftclick and drag the upper pointer to set the selection startpoint
;  - Fine-tune the selections with the mousewheel while the mousepointer is over the appropriate pointer
;  - Move the selection endpoint one increment higher/lower with the Right/Left tArrow keys
;  - Move the selection startpoint one increment higher/lower with the Shift/Right and Shift/left arrow keys
;  - Leftclicks outside the thumbs affect the startpoint if the mousepointer is in the top half of the gadget,
;    and the endpoint if the mousepointer is in the bottom half.
;
;  - Note: keyboard control of fine-tuning is scrapped in favor of the mousewheel only.
; -------------------------------------------------------------------------------------------
; Comment utiliser le Gadget !
;
; - Click Gauche : et faites glisser le curseur du bas pour regler la fin de zone
; - Click Gauche : et faites glisser le curseur du dessus pour régler le début de la zone
; - Ajustez finement le pointage des curseurs en plaçant la souris sur le curseur approprié
;   et actionner la molette de la souris...
; - Déplacer le curseur de début d'un point avec la Maj+ Flèches Gauche/droite
; - Déplacer le curseur de fin de zone d'un point avec la Ctrl + Flèches Gauche/droite
; - Leftclicks dans la zone sans les curseurs déplace l'un ou l'autre curseurs vers l'endroit
;   ou se trouve le pointeur de la souris
;

Bye :wink:

_________________
Sorry for my english !


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 8/11
PostPosted: Thu Jun 23, 2011 5:08 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Aug 07, 2003 7:01 pm
Posts: 2853
Location: United Kingdom
Great stuff. :)

_________________
http://www.SinisterSoft.com <- My Business website
http://www.ReportComplete.com and http://www.ReportPlus.co.uk <- School end of term reports system


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised May 8/11
PostPosted: Sun Jun 26, 2011 5:30 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
Updated today to move close to crossplatform (see first post). Also fixed a minor drawing bug.

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised June 26 2011
PostPosted: Sun Jun 26, 2011 6:58 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Aug 07, 2003 7:01 pm
Posts: 2853
Location: United Kingdom
Quote:
GetSysColor_()


If there is something like this for Linux/OSX then it would be great if Fred/Freak could add it as a built-in command...

_________________
http://www.SinisterSoft.com <- My Business website
http://www.ReportComplete.com and http://www.ReportPlus.co.uk <- School end of term reports system


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised June 26 2011
PostPosted: Wed Jun 29, 2011 1:35 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Mar 06, 2006 3:53 pm
Posts: 529
Location: Austria
Quote:
If there is something like this for Linux/OSX then it would be great if Fred/Freak could add it as a built-in command...

Yes, there are such commands.
http://developer.gnome.org/gtk/2.24/GtkWidget.html
http://developer.gnome.org/gtk/2.24/GtkStyle.html
http://developer.gnome.org/gtk/2.24/Gtk ... -style-get

You can "ask" a widget for it's colorset or ask for a complete style, but normally you would just parse the .gtkrc file which is a flat text file that holds the user's (or the system's) theme (and other information).
http://www.gtk.org/api/2.6/gtk/gtk-Resource-Files.html

_________________
Image


Top
 Profile  
 
 Post subject: Re: Track Selection Gadget - Revised June 26 2011
PostPosted: Thu Jun 30, 2011 4:55 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Aug 04, 2008 10:56 pm
Posts: 849
Location: Seattle, USA
The Track Selection Gadget works great! I wanted to see if the code would run on a Mac and the only obstacle with the code was the windows API colors. I replaced the window color themes with my guess of RGBA colors to match. The shortcoming to using RGBA colors is that each platform has theme colors and those should be the colors that are used. On-the-other-hand, if you define the colors you can get creative. This is my offering to the Mac users (and I hope it runs on Linux too) of one method to be able to use netmaestro's gadget.

Code:
;=============================================================
; Library:            TrackSelectionGadget
; Author:             Lloyd Gallant (netmaestro)
; Date:               April 30, 2011
; Target compiler:    Purebasic 4.60 and later
; Target OS:          Microsoft Windows all
; License:            Free, unrestricted, no warranty
;=============================================================
;
;  How to use the gadget:

;  - Leftclick and drag the lower pointer to set the selection endpoint
;  - Leftclick and drag the upper pointer to set the selection startpoint
;  - Fine-tune the selections with the mousewheel while the mousepointer is over the appropriate pointer
;  - Move the selection endpoint one increment higher/lower with the Right/Left tArrow keys
;  - Move the selection startpoint one increment higher/lower with the Shift/Right and Shift/left arrow keys
;  - Leftclicks outside the thumbs affect the startpoint if the mousepointer is in the top half of the gadget,
;    and the endpoint if the mousepointer is in the bottom half.
;
;  - Note: keyboard control of fine-tuning is scrapped in favor of the mousewheel only.
;

XIncludeFile "CustomRegions.pbi"

Structure TrackData
  p_region1.l
  p_region2.l
  baseimage.l
  baseimagetop.l
  baseimageleft.l
  bclientwidth.l
  baseimagewidth.l
  pointer1.l
  pointer2.l
  selection_start.l
  selection_end.l
  selection_max.l
  tickmin.l
  tickmax.l
  tickleftx.l
  tickrightx.l
  pointer1top.l
  pointer2top.l
  pointer1x.l
  pointer2x.l
  pointermin.l
  pointermax.l
  startchanged.l
  endchanged.l
  displayfont.l
  c_transparent.l
  c_textshadow.l
  c_boxshadow.l
  c_background.l
  c_barbckgrnd.l
  c_textbckgrnd.l
  c_menuhighlight.l
  c_textcolor.l
EndStructure

Procedure CreatePointers()
  Protected ptr, i, j
  ptr = CreateImage(#PB_Any, 11,30,32); |#PB_Image_Transparent)
 
  Protected Dim pcolors(4)
  pcolors(0) = RGBA(0,0,0,0) ; \c_transparent
  pcolors(1) = RGBA(0,0,0,255) ; \c_textshadow ; GetSysColor_(#COLOR_3DDKSHADOW) |$FFFFFFFFFF000000
  pcolors(2) = RGBA(0,0,0,255) ; \c_boxshadow ; GetSysColor_(#COLOR_3DSHADOW)   |$FFFFFFFFFF000000
  pcolors(3) = RGBA(203,198,186,255) ; \c_background ; GetSysColor_(#COLOR_3DFACE)     |$FFFFFFFFFF000000
  pcolors(4) = RGBA(255,255,255,255) ; \c_barbckgrnd ; GetSysColor_(#COLOR_3DHIGHLIGHT)|$FFFFFFFFFF000000

  StartDrawing(ImageOutput(ptr))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Restore base   : For i=0 To 10  : Read.i index  : Plot(i,0,pcolors(index)) : Next
    For j=1 To 9   : Restore body   : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next
    Restore pdn    : For j=10 To 14 : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next
    Restore pup    : For j=15 To 19 : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next   
    For j=20 To 28 : Restore body   : For i=0 To 10 : Read.i index : Plot(i,j,pcolors(index)) : Next : Next   
    Restore base   : For i=0 To 10  : Read.i index  : Plot(i,29,pcolors(index)) : Next
  StopDrawing()
 
  ProcedureReturn ptr
 
  DataSection
    base: Data.i 4,4,4,4,4,4,4,4,4,4,1
    body: Data.i 4,3,3,3,3,3,3,3,3,2,1
    pdn:  Data.i 0,4,3,3,3,3,3,3,2,1,0,0,0,4,3,3,3,3,2,1,0,0,0,0,0,4,3,3
          Data.i 2,1,0,0,0,0,0,0,0,4,2,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
    pup:  Data.i 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,4,2,1,0,0,0,0,0,0,0,4,3,3
          Data.i 2,1,0,0,0,0,0,4,3,3,3,3,2,1,0,0,0,4,3,3,3,3,3,3,2,1,0
  EndDataSection
 
EndProcedure

Procedure RedrawTrackSelectionGadget(gadget)
  *p.TrackData = GetGadgetData(gadget)
  StartDrawing(CanvasOutput(Gadget))
    Box(0,0,GadgetWidth(Gadget),GadgetHeight(Gadget),*p\c_background)
    DrawImage(ImageID(*p\baseimage),*p\baseimageleft,*p\baseimagetop)
    Box(*p\tickleftx,*p\baseimagetop+2,*p\tickrightx-*p\tickleftx,11,*p\c_menuhighlight) ; GetSysColor_(#COLOR_MENUHILIGHT))
    DrawAlphaImage(ImageID(*p\pointer1),*p\pointer1x,*p\pointer1top)   
    DrawAlphaImage(ImageID(*p\pointer2),*p\pointer2x,*p\pointer2top)
   
    Box(*p\tickmin-17,*p\pointer1top-11,35,10,*p\c_textbckgrnd) ; GetSysColor_(#COLOR_INFOBK))
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(*p\tickmin-17,*p\pointer1top-11,35,10,*p\c_textshadow) ; GetSysColor_(#COLOR_3DDKSHADOW))
    DrawingFont(*p\displayfont)
    DrawingMode(#PB_2DDrawing_Transparent)
    txt$ = Str(*p\selection_start)
    w = TextWidth(txt$)/2
    DrawText(*p\tickmin-w,*p\pointer1top-11,txt$,*p\c_textcolor) ; GetSysColor_(#COLOR_INFOTEXT))
   
    DrawingMode(#PB_2DDrawing_Default)
    Box(*p\tickmin-17,*p\pointer2top+16,35,10,*p\c_textbckgrnd) ; GetSysColor_(#COLOR_INFOBK))
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(*p\tickmin-17,*p\pointer2top+16,35,10,*p\c_textshadow) ; GetSysColor_(#COLOR_3DDKSHADOW))
    DrawingFont(*p\displayfont)
    DrawingMode(#PB_2DDrawing_Transparent)
    txt$ = Str(*p\selection_end)
    w = TextWidth(txt$)/2
    DrawText(*p\tickmin-w,*p\pointer2top+16,txt$,*p\c_textcolor) ; GetSysColor_(#COLOR_INFOTEXT))   
   
  StopDrawing()
EndProcedure

ProcedureDLL TrackSelectGadget(gadgetnumber, x, y, width, min=0, max=100, drawfocus=0)
  tmp = CreatePointers()
  pointer1 = GrabImage(tmp, #PB_Any,0,0,11,15)
  pointer2 = GrabImage(tmp, #PB_Any,0,15,11,15)
  FreeImage(tmp)
 
  If drawfocus
    flags = #PB_Canvas_Keyboard|#PB_Canvas_GrabMouse|#PB_Canvas_DrawFocus
  Else
    flags = #PB_Canvas_Keyboard|#PB_Canvas_GrabMouse
  EndIf
 
  Protected height = 60
  If gadgetnumber = #PB_Any
    result = CanvasGadget(#PB_Any, x, y, width, height, flags)
    gadgetnumber = result
  Else
    result = CanvasGadget(gadgetnumber, x, y, width, height, flags)
  EndIf
 
  h1 = CreateBitmapRegion(pointer1)
  h2 = CreateBitmapRegion(pointer2)
 
  *gadgetdata.TrackData = AllocateMemory(SizeOf(TrackData))
  With *gadgetdata
    \p_region1       = h1
    \p_region2       = h2
    \baseimage       = baseimage
    \baseimagetop    = 23
    \baseimageleft   = 20
    \baseimagewidth  = width-36
    \bclientwidth    = \baseimagewidth-5
    \pointer1        = pointer1
    \pointer2        = pointer2
    \selection_start = 0
    \selection_end   = 0
    \selection_max   = max
    \tickmin         = 22
    \tickmax         = width-19
    \pointer1top     = 15
    \pointer2top     = 30
    \tickleftx       = 22
    \tickrightx      = 22
    \pointer1x       = 17
    \pointer2x       = 17
    \pointermin      = 17
    \pointermax      = width-24
    If LoadFont(0,"verdana", 6)
        \displayfont = FontID(0)
    ElseIf LoadFont(0,"Arial",9) ; for Mac platform
        \displayfont=FontID(0)
    Else
        MessageRequester("Loading font..","Font not found")
    EndIf
    *gadgetdata\c_transparent = RGBA(0,0,0,0) ; transparent
    *gadgetdata\c_textshadow = RGBA(0,0,0,255) ; shadow color of text box - GetSysColor_(#COLOR_3DDKSHADOW) |$FFFFFFFFFF000000
    *gadgetdata\c_boxshadow = RGBA(0,0,0,255) ; right shadow color of bar box & pointers - GetSysColor_(#COLOR_3DSHADOW)   |$FFFFFFFFFF000000
    *gadgetdata\c_background = RGBA(203,198,186,255) ; gadget background -  GetSysColor_(#COLOR_3DFACE)     |$FFFFFFFFFF000000
    *gadgetdata\c_barbckgrnd = RGBA(255,255,255,255) ; bar background - GetSysColor_(#COLOR_3DHIGHLIGHT)|$FFFFFFFFFF000000
    *gadgetdata\c_textbckgrnd = RGBA(255,255,255,255) ; text background - GetSysColor_(#COLOR_INFOBK))
    *gadgetdata\c_menuhighlight = RGBA(6,21,93,255) ; unkn - GetSysColor_(#COLOR_MENUHILIGHT))
    *gadgetdata\c_textcolor = RGBA(0,0,0,255) ; text color -  = GetSysColor_(#COLOR_INFOTEXT))
       
  EndWith
 
  SetGadgetData(gadgetnumber, *gadgetdata)
  *gadgetdata\baseimage = CreateImage(#PB_Any, *gadgetdata\baseimagewidth,15)
 
  StartDrawing(ImageOutput(*gadgetdata\baseimage))
    Box(0,0,*gadgetdata\baseimagewidth,15,*gadgetdata\c_background) ; GetSysColor_(#COLOR_3DFACE))
    Box(0,0,*gadgetdata\baseimagewidth-1,1,*gadgetdata\c_boxshadow) ; GetSysColor_(#COLOR_3DSHADOW))
    Box(0,0,1,14,*gadgetdata\c_boxshadow) ; GetSysColor_(#COLOR_3DSHADOW))
    Box(1,1,1,12,*gadgetdata\c_textshadow) ; GetSysColor_(#COLOR_3DDKSHADOW))
    Box(1,1,*gadgetdata\baseimagewidth-3,1,*gadgetdata\c_textshadow) ; GetSysColor_(#COLOR_3DDKSHADOW))
    Box(2,2,*gadgetdata\baseimagewidth-5,11,*gadgetdata\c_barbckgrnd) ; GetSysColor_(#COLOR_3DHIGHLIGHT))
    Box(1,13,*gadgetdata\baseimagewidth-4,1,*gadgetdata\c_background) ; GetSysColor_(#COLOR_3DFACE))
    Box(0,14,*gadgetdata\baseimagewidth-2,1,*gadgetdata\c_barbckgrnd) ; GetSysColor_(#COLOR_3DHIGHLIGHT))
    Box(*gadgetdata\baseimagewidth-3,1,1,13,*gadgetdata\c_background) ; GetSysColor_(#COLOR_3DFACE))
    Box(*gadgetdata\baseimagewidth-2,0,1,15,*gadgetdata\c_barbckgrnd) ;GetSysColor_(#COLOR_3DHIGHLIGHT))
  StopDrawing()
 
  RedrawTrackSelectionGadget(gadgetnumber)
  ProcedureReturn result
EndProcedure

ProcedureDLL GetTrackSelectionStart(gadget)
  *p.TrackData = GetGadgetData(gadget)
  ProcedureReturn *p\selection_start
EndProcedure

ProcedureDLL GetTrackSelectionEnd(gadget)
  *p.TrackData = GetGadgetData(gadget)
  ProcedureReturn *p\selection_end
EndProcedure

ProcedureDLL CheckSelectionStartChanged(gadget)
  *p.TrackData = GetGadgetData(gadget)
  If *p\startchanged
    *p\startchanged=0
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

ProcedureDLL CheckSelectionEndChanged(gadget)
  *p.TrackData = GetGadgetData(gadget)
  If *p\endchanged
    *p\endchanged=0
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

ProcedureDLL HandleTrackEvents(EventGadget,EventType)
  Static hot1, hot2, xoffset
  *p.TrackData = GetGadgetData(EventGadget)
  mx = GetGadgetAttribute(EventGadget,#PB_Canvas_MouseX)
  my = GetGadgetAttribute(EventGadget,#PB_Canvas_MouseY)
 
  Select EventType
      ;       
    Case #PB_EventType_KeyDown
      key = GetGadgetAttribute(EventGadget, #PB_Canvas_Key)
      mods = GetGadgetAttribute(EventGadget, #PB_Canvas_Modifiers)
      Select key
        Case #PB_Shortcut_Right
          If mods & #PB_Canvas_Shift
            *p\pointer1x = *p\tickleftx-5
            If *P\tickleftx < *p\tickmax
              *p\tickleftx+1
              *p\pointer1x+1
              If *p\tickrightx < *p\tickleftx
                *p\tickrightx = *p\tickleftx
                *p\pointer2x = *p\tickrightx-5
              EndIf
            EndIf
            s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
            *p\selection_start = Int(s)
            *P\startchanged = 1
            If *p\selection_start > *p\selection_end
              *p\selection_end = *p\selection_start
              *p\endchanged = 1
            EndIf                 
            RedrawTrackSelectionGadget(EventGadget)
          Else
            *p\pointer2x = *p\tickrightx-5
            If *p\tickrightx < *p\tickmax
              *p\tickrightx+1
              *p\pointer2x+1
            EndIf
            e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
            *p\selection_end = Int(e)
            *p\endchanged = 1
            RedrawTrackSelectionGadget(EventGadget)
          EndIf
         
        Case #PB_Shortcut_Left
          If mods & #PB_Canvas_Shift
            *p\pointer1x = *p\tickleftx-5
            If *p\tickleftx > *p\tickmin
              *p\tickleftx-1
              *p\pointer1x-1
            EndIf
            s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
            *p\selection_start = Int(s)
            *P\startchanged = 1
            RedrawTrackSelectionGadget(EventGadget)
          Else
            *p\pointer2x = *p\tickrightx-5
            If *p\tickrightx > *p\tickmin
              *p\tickrightx-1
              *p\pointer2x-1
              If *p\tickleftx > *p\tickrightx
                *p\tickleftx = *p\tickrightx
                *p\pointer1x = *p\tickleftx-5
              EndIf
            EndIf
            e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
            *p\selection_end = Int(e)
            *p\endchanged = 1
            If *p\selection_end < *p\selection_start
              *p\selection_start = *p\selection_end
              *p\startchanged = 1
            EndIf                 
            RedrawTrackSelectionGadget(EventGadget)
          EndIf
         
      EndSelect
     
    Case #PB_EventType_LeftButtonDown
     
      If mx <= *p\tickrightx And mx >= *p\tickmin And (my <= 26)
        *p\pointer1x = mx-5
        If *p\pointer1x < *p\pointermin
          *p\pointer1x = *p\pointermin
        EndIf
        *p\tickleftx = *p\pointer1x+5
        s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
        *p\selection_start = Int(s)
        *P\startchanged = 1
        hot1 = #True : #hot2 = #False
        RedrawTrackSelectionGadget(EventGadget)
      ElseIf mx >= *p\tickleftx And mx <=*p\tickmax And (my >= 28)
        *p\pointer2x = mx-5
        If *p\pointer2x > *p\pointermax
          *p\pointer2x = *p\pointermax
        EndIf
        *p\tickrightx = *p\pointer2x+5
        e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
        *p\selection_end = Int(e)
        *p\endchanged = 1
        hot2 = #True : hot1 = #False
        RedrawTrackSelectionGadget(EventGadget)
      EndIf
     
    Case #PB_EventType_MouseWheel
      delta = GetGadgetAttribute(EventGadget, #PB_Canvas_WheelDelta)
      If PtinRegion(*p\p_region2, mx-*p\pointer2x, my-*p\pointer2top)
        If delta>0
          thisone = *p\selection_end
          e.d = Round(((*p\tickrightx+1-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
          nextone = Int(e)
          testone = thisone+1
          *p\pointer2x = *p\tickrightx-5
          If testone<nextone
            If *p\selection_end < nextone And *p\selection_end < *p\selection_max
              *p\selection_end+1
              *p\endchanged = 1
              RedrawTrackSelectionGadget(EventGadget)
            EndIf
          EndIf
        ElseIf delta < 0
          If *p\pointer2x = *p\tickrightx-5
            thisone = *p\selection_end
            e.d = Round(((*p\tickrightx-1-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
            nextone = Int(e)
            testone = thisone-1
            *p\pointer2x = *p\tickrightx-5
            If testone>nextone
              If *p\selection_end > nextone And *p\selection_end > *p\selection_start
                *p\selection_end-1
                *p\endchanged = 1
                RedrawTrackSelectionGadget(EventGadget)
              EndIf
            EndIf
          EndIf
        EndIf
      ElseIf PtinRegion(*p\p_region1, mx-*p\pointer1x, my-*p\pointer1top)
        If delta > 0
          thisone = *p\selection_start
          s.d = Round(((*p\tickleftx+1-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
          nextone = Int(s)
          testone = thisone+1
          *p\pointer1x = *p\tickleftx-5
          If testone>0
            If testone<nextone
              If *p\selection_start < nextone And *p\selection_start < *p\selection_end
                *p\selection_start+1
                *P\startchanged = 1
                RedrawTrackSelectionGadget(EventGadget)
              EndIf
            EndIf
          EndIf
        ElseIf delta < 0
          thisone = *p\selection_start
          s.d = Round(((*p\tickleftx-1-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
          nextone = Int(s)
          testone = thisone-1
          *p\pointer1x = *p\tickleftx-5
          If testone>=0
            If testone>nextone
              If *p\selection_start > nextone And *p\selection_start > 0
                *p\selection_start-1
                *P\startchanged = 1
                RedrawTrackSelectionGadget(EventGadget)
              EndIf
            EndIf
          EndIf
        EndIf         
      EndIf
     
    Case #PB_EventType_LeftButtonUp
      hot1 = #False
      hot2 = #False
     
    Case #PB_EventType_MouseMove
      buttonstate = GetGadgetAttribute(EventGadget, #PB_Canvas_Buttons)
      lbutton = buttonstate & #PB_Canvas_LeftButton
      If lbutton
        If hot1
          *p\pointer1x = mx-xoffset
          If *p\pointer1x < *p\pointermin
            *p\pointer1x = *p\pointermin
          ElseIf *p\pointer1x > *p\pointermax
            *p\pointer1x = *p\pointermax
          EndIf
          *p\tickleftx = *p\pointer1x+5
          If *p\tickrightx < *p\tickleftx
            *p\tickrightx = *p\tickleftx
            *p\pointer2x = *p\tickrightx-5
          EndIf
          s.d = Round(((*p\tickleftx-*p\tickmin)/*p\bclientwidth)  * *p\selection_max, #PB_Round_Nearest)
          *p\selection_start = Int(s)
          *P\startchanged = 1
          If *p\selection_start > *p\selection_end
            *p\selection_end = *p\selection_start
            *p\endchanged = 1
          EndIf
          RedrawTrackSelectionGadget(EventGadget)
         
        ElseIf hot2
          *p\pointer2x = mx-xoffset
          If *p\pointer2x < *p\pointermin
            *p\pointer2x = *p\pointermin
          ElseIf *p\pointer2x > *p\pointermax
            *p\pointer2x = *p\pointermax
          EndIf         
          *p\tickrightx = *p\pointer2x+5
          If *p\tickleftx > *p\tickrightx
            *p\tickleftx = *p\tickrightx
            *p\pointer1x = *p\tickleftx-5
          EndIf
          e.d = Round(((*p\tickrightx-*p\tickmin)/*p\bclientwidth) * *p\selection_max, #PB_Round_Nearest)
          *p\selection_end   = Int(e)
          *p\endchanged = 1
          If *p\selection_end < *p\selection_start
            *p\selection_start = *p\selection_end
            *p\startchanged = 1
          EndIf
        EndIf
        RedrawTrackSelectionGadget(EventGadget)
      Else
        If PtinRegion(*p\p_region1, mx-*p\pointer1x, my-*p\pointer1top)
          SetGadgetAttribute(EventGadget, #PB_Canvas_Cursor,#PB_Cursor_Hand)
          hot1 = #True : hot2 = #False
          xoffset = mx-*p\pointer1x
        ElseIf PtinRegion(*p\p_region2, mx-*p\pointer2x, my-*p\pointer2top)
          SetGadgetAttribute(EventGadget, #PB_Canvas_Cursor,#PB_Cursor_Hand)
          hot2 = #True : hot1 = #False
          xoffset = mx-*p\pointer2x
        Else
          hot1=#False : hot2 = #False
          SetGadgetAttribute(EventGadget, #PB_Canvas_Cursor,#PB_Cursor_Default)
        EndIf
      EndIf
     
  EndSelect
 
EndProcedure

;========================================================
;                    End of Library Code
;========================================================

; Test program

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(0,20,20,100,20,"Button")
TrackSelectGadget(1,20,360,600,0,20129,1)

Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          HandleTrackEvents(EventGadget(), EventType())
      EndSelect
  EndSelect
 
Until ev = #PB_Event_CloseWindow

_________________
MacBook Pro/Retina, OSX 10.8.3 Mountain Lion, PB-5.11x64


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye