Page 1 of 1

SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 1:39 am
by eddy
v2 For PB 4.41+
-SetSplitterDashed : enable dashed mode
  • you can specify the grip size(disable If ZERO)
  • you can specify the bar thickness
  • you can customize the grip images
-SetSplitterSnapping : specify the border snapping distances(disable If ZERO)
-SetSplitterDoubleClick : enable auto snapping by double-click(disable If #False)
-SwapSplitter : Swap gadgets Or/And other options
-LockSplitter : lock splitter bar(unlock If #False)
-SplitterLocked : returns #True If the splitter is locked
-SplitterSnapped : returns 1 Or 2 If splitter snapped border 1 Or 2 is snapped (Not snapped If ZERO)
-event type: #PB_EventType_LeftDoubleClick
-event type: #PB_EventType_Change
Image

Code: Select all

EnableExplicit
CompilerIf Defined(PB_Gadget_SendGadgetCommand, #PB_Procedure)=#False
   Import ""
      ;send custom gadget event type
      PB_Gadget_SendGadgetCommand(hwnd, EventType)
   EndImport
CompilerEndIf
Prototype SGP_CreateImage(ID, Width, Height, Vertical, Focused)
Structure SGP_PARAMS
   *CB            ;stored original splittergadget Callback
   ID.i           ;stored original splittergadget ID
   x.i            ;Splitter Pos (for bar position calculation)
   y.i            ;Splitter Pos (for bar position calculation)
   Thickness.i    ;Bar Thickness
   Flags.i        ;stored original splittergadget flags
   Parent.i       ;gadget list
   Vertical.b     ;is vertical bar
   Dashed.b       ;is dashed bar
   Locked.b       ;is locked bar
   UnsnapPos.i    ;Unsnap position
   Pos.i          ;Bar position
   *LineCB        ;line Callback
   Line.i         ;line ID
   LinePos.Rect   ;line position
   LineVisible.i  ;line Visible
   Limit.Rect     ;Line Scroll limit
   Snap.Rect      ;Line Snap border
   SnapFirst.i    ;Snap distance (first gadget)
   SnapSecond.i   ;Snap distance (second gadget)
   SnapDblClick.b ;Snap to fixed gadget border
   Grip.i         ;Grip ID
   GripImg1.i     ;Grip Image ID1
   GripImg2.i     ;Grip Image ID2
   GripWidth.i    ;Grip width
   GripFocus.b    ;Grip focus
   
   ;Grip drawing function
   *GripImage.SGP_CreateImage
EndStructure
Global *SGP_PARAMS_LINE.SGP_PARAMS
Global SGP_Line
Global SGP_Cursor_Arrow=LoadCursor_(0, #IDC_ARROW)
Global SGP_Cursor_V=LoadCursor_(0, #IDC_SIZENS)
Global SGP_Cursor_H=LoadCursor_(0, #IDC_SIZEWE)
Enumeration
   ;custom windows message
   #SGP_WM_FIXUP=#WM_USER
   #SGP_WM_SENDEVENT
   #SGP_WM_SAVEUNSNAPPOS
   #SGP_WM_SHOWCURSOR
   #SGP_WM_SHOWLINE
   #SGP_WM_HIDELINE
   #SGP_WM_SHOWGRIP
   #SGP_WM_GRIPCHECKING
   ;custom constants
   #SGP_Action_Snap=1
   #SGP_Action_Unsnap
EndEnumeration
ProcedureDLL SGP_LineCB(Window, Message, wParam, lParam)
   If *SGP_PARAMS_LINE And IsGadget(*SGP_PARAMS_LINE\ID)
      Protected *SGP_PARAMS.SGP_PARAMS=*SGP_PARAMS_LINE
      Protected ID=*SGP_PARAMS\ID
      Select Message
         Case #SGP_WM_SHOWCURSOR
            ;{/// SHOW CURSOR
            If *SGP_PARAMS\Vertical
               SetCursor_(SGP_Cursor_H)
            Else
               SetCursor_(SGP_Cursor_V)
            EndIf
            ;}
            
         Case #SGP_WM_SHOWLINE
            ;{/// SHOW DASHED LINE
            *SGP_PARAMS\LineVisible=1
            SetLayeredWindowAttributes_(WindowID(*SGP_PARAMS\Line), 0, 60, #LWA_ALPHA)
            If *SGP_PARAMS\Vertical
               ResizeWindow(*SGP_PARAMS\Line, #PB_Ignore, #PB_Ignore, *SGP_PARAMS\Thickness, GadgetHeight(ID))
            Else
               ResizeWindow(*SGP_PARAMS\Line, #PB_Ignore, #PB_Ignore, GadgetWidth(ID), *SGP_PARAMS\Thickness)
            EndIf
            ;}
            
         Case #SGP_WM_HIDELINE
            ;{/// SHOW DASHED LINE
            *SGP_PARAMS\LineVisible=0
            SetLayeredWindowAttributes_(WindowID(*SGP_PARAMS\Line), 0, 0, #LWA_ALPHA)
            ResizeWindow(*SGP_PARAMS\Line, #PB_Ignore, #PB_Ignore, 0, 0)
            ;}
            
         Case #WM_MOUSEMOVE
            ;{/// MOVE DASHED LINE
            Protected x=(GetGadgetState(ID))+(DesktopMouseX()-*SGP_PARAMS\x)
            Protected y=(GetGadgetState(ID))+(DesktopMouseY()-*SGP_PARAMS\y)
            
            ;snap auto
            If y<*SGP_PARAMS\Snap\Top : y=*SGP_PARAMS\Limit\Top : EndIf
            If x<*SGP_PARAMS\Snap\Left : x=*SGP_PARAMS\Limit\Left : EndIf
            If x>*SGP_PARAMS\Snap\Right : x=*SGP_PARAMS\Limit\Right : EndIf
            If y>*SGP_PARAMS\Snap\Bottom : y=*SGP_PARAMS\Limit\Bottom : EndIf
            
            ;move limits
            If y<*SGP_PARAMS\Limit\Top : y=*SGP_PARAMS\Limit\Top : EndIf
            If x<*SGP_PARAMS\Limit\Left : x=*SGP_PARAMS\Limit\Left : EndIf
            If x>*SGP_PARAMS\Limit\Right : x=*SGP_PARAMS\Limit\Right : EndIf
            If y>*SGP_PARAMS\Limit\Bottom : y=*SGP_PARAMS\Limit\Bottom : EndIf
            
            If *SGP_PARAMS\Vertical
               ResizeWindow(*SGP_PARAMS\Line, *SGP_PARAMS\LinePos\left+x, #PB_Ignore, #PB_Ignore, #PB_Ignore)
            Else
               ResizeWindow(*SGP_PARAMS\Line, #PB_Ignore, *SGP_PARAMS\LinePos\top+y, #PB_Ignore, #PB_Ignore)
            EndIf
            
            ;show cursor
            PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_SHOWCURSOR, 0, 0)
            ;}
            
         Case #WM_LBUTTONUP
            ;{/// RELEASE DASHED LINE
            If *SGP_PARAMS\LineVisible
               Protected LinePos
               If *SGP_PARAMS\Vertical
                  LinePos=WindowX(*SGP_PARAMS\Line)-*SGP_PARAMS\LinePos\left
               Else
                  LinePos=WindowY(*SGP_PARAMS\Line)-*SGP_PARAMS\LinePos\top
               EndIf
               
               PostMessage_(GadgetID(ID), #SGP_WM_SAVEUNSNAPPOS, 0, LinePos)
               PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_HIDELINE, 0, 0)
               SetGadgetState(ID, LinePos)
               ;send PB event
               PostMessage_(GadgetID(ID), #SGP_WM_SENDEVENT, 0, #PB_EventType_Change)
            EndIf
            ;release captured line
            ReleaseCapture_()
            ;}
            
      EndSelect
   EndIf
   
   ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
ProcedureDLL SGP_LineImages(colorRGBA=$1E000000)
   Protected c=RGB(Red(colorRGBA), Green(colorRGBA), Blue(colorRGBA))
   Protected alpha=Alpha(colorRGBA)
   
   ;create transparent windows
   Protected style=#PB_Window_NoGadgets | #PB_Window_Invisible | #PB_Window_BorderLess
   Protected parent=OpenWindow(#PB_Any, 0, 0, 0, 0, "", style)
   SGP_Line=OpenWindow(#PB_Any, 0, 0, 0, 0, "", style, WindowID(parent))
   SetWindowColor(SGP_Line, c)
   DisableWindow(SGP_Line, 1)
   StickyWindow(SGP_Line, 1)
   ShowWindow_(WindowID(SGP_Line), #SW_SHOWNA)
   ;set transparent fx
   Protected winLine=WindowID(SGP_Line)
   Protected winstyle=GetWindowLongPtr_(winLine, #GWL_EXSTYLE) | #WS_EX_LAYERED
   SetWindowLongPtr_(winLine, #GWL_EXSTYLE, winstyle)
   SetLayeredWindowAttributes_(winLine, 0, alpha, #LWA_ALPHA)
   ;set callback
   SetWindowCallback(@SGP_LineCB(), SGP_Line)
EndProcedure
ProcedureDLL SGP_GripImages(ID, Width, Height, Vertical, Focused)
   ; ====================
   ; Draw the default grip images
   ; ====================
   Protected Img=CreateImage(#PB_Any, Width, Height, 32)
   StartDrawing(ImageOutput(Img))
      Protected dot
      Protected f1=RGB(189, 204, 254)
      Protected f2=GetSysColor_(#COLOR_BTNFACE)
      Protected c1=GetSysColor_(#COLOR_BTNSHADOW)
      Protected c2=GetSysColor_(#COLOR_BTNHILIGHT)
      
      ;background rectangle
      If Focused
         Box(0, 0, Width, Height, f1)
      Else
         Box(0, 0, Width, Height, f2)
      EndIf
      
      If Vertical
         ;borders
         Line(0, 0, Width, 1, c1)
         Line(0, 1, Width, 1, c2)
         Line(0, Height-2, Width, 1, c1)
         Line(0, Height-1, Width, 1, c2)
         
         ;dots
         For dot=10 To Height-10 Step 3
            Line(Width/2-1, dot, 2, 1, c1)
         Next
      Else
         ;borders
         Line(0, 0, 1, Height, c1)
         Line(1, 0, 1, Height, c2)
         Line(Width-2, 0, 1, Height, c1)
         Line(Width-1, 0, 1, Height, c2)
         
         ;dots
         For dot=10 To Width-10 Step 3
            Line(dot, Height/2-1, 1, 2, c1)
            Line(dot, Height/2+1, 1, 1, c2)
         Next
      EndIf
   StopDrawing()
   ProcedureReturn Img
EndProcedure
ProcedureDLL SGP_CB(Window, Message, wParam, lParam)
   Protected ID=GetProp_(Window, "SplitterGadgetPlus")
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   
   ;{/// BAR LOCKED
   Select Message
      Case #WM_LBUTTONDOWN, #WM_LBUTTONUP, #WM_MOUSEMOVE, #WM_LBUTTONDBLCLK
         If *SGP_PARAMS\Locked
            SetCursor_(SGP_Cursor_Arrow)
            ;disable normal behaviour...
            ProcedureReturn 1
         EndIf
   EndSelect
   ;}
   
   Select Message
      Case #WM_DESTROY
         ;{/// FREE GADGET
         Protected CB=*SGP_PARAMS\CB
         If *SGP_PARAMS_LINE=*SGP_PARAMS : *SGP_PARAMS_LINE=0 : EndIf
         If IsGadget(*SGP_PARAMS\Grip) : FreeGadget(*SGP_PARAMS\Grip) : EndIf
         If IsImage(*SGP_PARAMS\GripImg1) : FreeImage(*SGP_PARAMS\GripImg1) : EndIf
         SetWindowLong_(GadgetID(ID), #GWL_WNDPROC, CB)
         SetGadgetData(ID, 0)
         FreeMemory(*SGP_PARAMS)
         ProcedureReturn CallWindowProc_(CB, Window, Message, wParam, lParam)
         ;}
         
      Case #WM_LBUTTONDOWN
         ;{/// CAPTURE LINE
         ;show cursor
         SendMessage_(GadgetID(ID), #SGP_WM_SHOWCURSOR, 0, 0)
         
         *SGP_PARAMS_LINE=*SGP_PARAMS
         
         ;line position
         *SGP_PARAMS\Pos=GetGadgetState(ID)
         
         ;line limits
         *SGP_PARAMS\Limit\Left=GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)
         *SGP_PARAMS\Limit\Top=GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)
         *SGP_PARAMS\Limit\Right=GadgetWidth(ID)-*SGP_PARAMS\Thickness-GetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize)
         *SGP_PARAMS\Limit\Bottom=GadgetHeight(ID)-*SGP_PARAMS\Thickness-GetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize)
         
         *SGP_PARAMS\Snap=*SGP_PARAMS\Limit
         *SGP_PARAMS\Snap\Left+*SGP_PARAMS\SnapFirst
         *SGP_PARAMS\Snap\Top+*SGP_PARAMS\SnapFirst
         *SGP_PARAMS\Snap\Right-*SGP_PARAMS\SnapSecond
         *SGP_PARAMS\Snap\Bottom-*SGP_PARAMS\SnapSecond
         
         ;line layout
         If *SGP_PARAMS\Dashed=0 Or (*SGP_PARAMS\GripWidth=0 Or *SGP_PARAMS\GripFocus=1)
            GetWindowRect_(GadgetID(ID), @*SGP_PARAMS\LinePos)
            If *SGP_PARAMS\Vertical
               *SGP_PARAMS\x=DesktopMouseX()
               ResizeWindow(*SGP_PARAMS\Line, *SGP_PARAMS\LinePos\left+GetGadgetState(ID), *SGP_PARAMS\LinePos\top, *SGP_PARAMS\Thickness, GadgetHeight(ID))
            Else
               *SGP_PARAMS\y=DesktopMouseY()
               ResizeWindow(*SGP_PARAMS\Line, *SGP_PARAMS\LinePos\left, *SGP_PARAMS\LinePos\top+GetGadgetState(ID), GadgetWidth(ID), *SGP_PARAMS\Thickness)
            EndIf
         EndIf
         
         ;line display
         If *SGP_PARAMS\Dashed
            If *SGP_PARAMS\LineVisible=0 And (*SGP_PARAMS\GripWidth=0 Or *SGP_PARAMS\GripFocus=1)
               PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_SHOWLINE, 0, 0)
               SetCapture_(WindowID(*SGP_PARAMS\Line))
            EndIf
            ProcedureReturn 1
         Else
            If *SGP_PARAMS\LineVisible=0
               PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_SHOWLINE, 0, 0)
            EndIf
         EndIf
         ;}
         
      Case #WM_LBUTTONUP
         ;{/// RELEASE LINE
         ;show cursor
         SendMessage_(GadgetID(ID), #SGP_WM_SHOWCURSOR, 0, 0)
         
         If *SGP_PARAMS\Dashed=0 And GetCapture_()=GadgetID(ID)
            If *SGP_PARAMS\LineVisible
               PostMessage_(WindowID(*SGP_PARAMS\Line), #WM_LBUTTONUP, 0, 0)
            Else
               PostMessage_(GadgetID(ID), #SGP_WM_SAVEUNSNAPPOS, 0, GetGadgetState(ID))
               ;send PB event
               PostMessage_(GadgetID(ID), #SGP_WM_SENDEVENT, 0, #PB_EventType_Change)
            EndIf
         EndIf
         ;}
         
      Case #WM_LBUTTONDBLCLK
         ;{/// DOUBLE-CLICK SNAP / UNSNAP
         ;show cursor
         SendMessage_(GadgetID(ID), #SGP_WM_SHOWCURSOR, 0, 0)
         
         Protected Pos=*SGP_PARAMS\Pos
         Protected SnapAction
         Protected Snap1, Snap2
         
         If *SGP_PARAMS\Vertical
            Snap1=*SGP_PARAMS\Limit\Left
            Snap2=*SGP_PARAMS\Limit\Right
         Else
            Snap1=*SGP_PARAMS\Limit\Top
            Snap2=*SGP_PARAMS\Limit\Bottom
         EndIf
         
         ;fix pixel slide
         If *SGP_PARAMS\Dashed=0 And Abs(Pos-Snap1)<2 : Pos=Snap1 : EndIf
         If *SGP_PARAMS\Dashed=0 And Abs(Pos-Snap2)<2 : Pos=Snap2 : EndIf
         
         ;determine snap action
         If (*SGP_PARAMS\GripWidth And *SGP_PARAMS\GripFocus=0)
            SnapAction=0
         ElseIf (Pos=Snap1 Or Pos=Snap2)
            SnapAction=#SGP_Action_Unsnap
         Else
            SnapAction=#SGP_Action_Snap
         EndIf
         
         Select SnapAction
            Case #SGP_Action_Snap
               Select *SGP_PARAMS\SnapDblClick
                  Case 1
                     SetGadgetState(ID, Snap1)
                     *SGP_PARAMS\GripFocus=0
                     *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
                  Case 2
                     SetGadgetState(ID, Snap2)
                     *SGP_PARAMS\GripFocus=0
                     *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
                  Default
               EndSelect
            Case #SGP_Action_Unsnap
               PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_HIDELINE, 0, 0)
               SetGadgetState(ID, *SGP_PARAMS\UnsnapPos)
               *SGP_PARAMS\GripFocus=0
               *SGP_PARAMS\UnsnapPos=#PB_Ignore
         EndSelect
         
         ;send PB event
         PostMessage_(GadgetID(ID), #SGP_WM_SENDEVENT, 0, #PB_EventType_LeftDoubleClick)
         PostMessage_(GadgetID(ID), #SGP_WM_SENDEVENT, 0, #PB_EventType_Change)
         ;}
         
      Case #WM_MOUSEMOVE
         ;{/// MOVE LINE
         ;show cursor
         SendMessage_(GadgetID(ID), #SGP_WM_SHOWCURSOR, 0, 0)
         
         If GetCapture_()=GadgetID(ID)
            Protected Hide.b=1
            
            ;snap auto
            If *SGP_PARAMS\Vertical
               Protected x=GetGadgetState(ID)+GadgetX(ID)
               If x<*SGP_PARAMS\Snap\Left : x=*SGP_PARAMS\Limit\Left : Hide=0 : EndIf
               If x>*SGP_PARAMS\Snap\Right : x=*SGP_PARAMS\Limit\Right : Hide=0 : EndIf
               ResizeWindow(*SGP_PARAMS\Line, *SGP_PARAMS\LinePos\Left+x, #PB_Ignore, #PB_Ignore, #PB_Ignore)
            Else
               Protected y=GetGadgetState(ID)+GadgetY(ID)
               If y<*SGP_PARAMS\Snap\Top : y=*SGP_PARAMS\Limit\Top : Hide=0 : EndIf
               If y>*SGP_PARAMS\Snap\Bottom : y=*SGP_PARAMS\Limit\Bottom : Hide=0 : EndIf
               ResizeWindow(*SGP_PARAMS\Line, #PB_Ignore, *SGP_PARAMS\LinePos\Top+y, #PB_Ignore, #PB_Ignore)
            EndIf
            
            ;snap position preview
            If Hide
               If *SGP_PARAMS\LineVisible
                  PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_HIDELINE, 0, 0)
               EndIf
            Else
               If *SGP_PARAMS\LineVisible=0
                  PostMessage_(WindowID(*SGP_PARAMS\Line), #SGP_WM_SHOWLINE, 0, 0)
               EndIf
            EndIf
         EndIf
         
         ;start grip checking
         PostMessage_(GadgetID(ID), #SGP_WM_GRIPCHECKING, 0, 0)
         ;}
         
      Case #WM_PAINT;, #WM_ERASEBKGND
         ;{/// REDRAW SPLITTER
         PostMessage_(GadgetID(ID), #SGP_WM_FIXUP, 0, 0)
         PostMessage_(GadgetID(ID), #SGP_WM_SHOWGRIP, 0, 0)
         ;}
         
      Case #SGP_WM_GRIPCHECKING, #WM_TIMER
         ;{/// GRIP CHECKING
         If *SGP_PARAMS\Dashed And *SGP_PARAMS\GripWidth
            Protected GripRect.RECT
            GetWindowRect_(GadgetID(*SGP_PARAMS\Grip), @GripRect)
            If DesktopMouseX()>=GripRect\Left And DesktopMouseX()<=GripRect\right And DesktopMouseY()>=GripRect\top And DesktopMouseY()<=GripRect\bottom
               If *SGP_PARAMS\GripFocus=0
                  *SGP_PARAMS\GripFocus=1
                  ;use timer to check grip automaticly
                  SetTimer_(GadgetID(ID), 2000, 100, 0)
                  PostMessage_(GadgetID(ID), #SGP_WM_SHOWGRIP, 0, 0)
               EndIf
            Else
               If *SGP_PARAMS\GripFocus=1
                  *SGP_PARAMS\GripFocus=0
                  ;stop grip checking (because mouse pointer is out of area)
                  KillTimer_(GadgetID(ID), 2000)
                  PostMessage_(GadgetID(ID), #SGP_WM_SHOWGRIP, 0, 0)
               EndIf
            EndIf
         EndIf
         ;}
         
      Case #SGP_WM_SHOWCURSOR
         ;{/// SHOW CURSOR
         If *SGP_PARAMS\GripWidth And *SGP_PARAMS\GripFocus=0
            ;if out of grip area...
            SetCursor_(SGP_Cursor_Arrow)
         ElseIf *SGP_PARAMS\Vertical
            SetCursor_(SGP_Cursor_H)
         Else
            SetCursor_(SGP_Cursor_V)
         EndIf
         ;}
         
      Case #SGP_WM_SHOWGRIP
         ;{/// SHOW GRIP
         If *SGP_PARAMS\Dashed And *SGP_PARAMS\GripWidth
            If *SGP_PARAMS\GripFocus
               If GetGadgetState(*SGP_PARAMS\Grip)<>ImageID(*SGP_PARAMS\GripImg2)
                  SetGadgetState(*SGP_PARAMS\Grip, ImageID(*SGP_PARAMS\GripImg2))
               EndIf
            Else
               If GetGadgetState(*SGP_PARAMS\Grip)<>ImageID(*SGP_PARAMS\GripImg1)
                  SetGadgetState(*SGP_PARAMS\Grip, ImageID(*SGP_PARAMS\GripImg1))
               EndIf
            EndIf
         EndIf
         ;}
         
      Case #SGP_WM_FIXUP
         ;{/// FIX BAR THICKNESS
         Protected ModifiedThickness
         ModifiedThickness+(#True And *SGP_PARAMS\Thickness=4 And (*SGP_PARAMS\Flags & #PB_Splitter_Separator)=0)
         ModifiedThickness+(#True And *SGP_PARAMS\Thickness=7 And (*SGP_PARAMS\Flags & #PB_Splitter_Separator))
         
         ;fix bar thickness
         If Not ModifiedThickness
            Protected ID1=GetGadgetAttribute(ID, #PB_Splitter_FirstGadget)
            Protected ID2=GetGadgetAttribute(ID, #PB_Splitter_SecondGadget)
            
            If *SGP_PARAMS\Vertical
               x=GadgetWidth(ID1)+*SGP_PARAMS\Thickness
               Protected w=GadgetWidth(ID)-x
               ResizeGadget(ID2, x, #PB_Ignore, w, #PB_Ignore)
            Else
               y=GadgetHeight(ID1)+*SGP_PARAMS\Thickness
               Protected h=GadgetHeight(ID)-y
               ResizeGadget(ID2, #PB_Ignore, y, #PB_Ignore, h)
            EndIf
         EndIf
         ;}
         
         ;{/// FIX GRIP SIZE AND IMAGES
         If GetGadgetState(*SGP_PARAMS\Grip)
            If *SGP_PARAMS\Vertical
               ;fix grip position
               ResizeGadget(*SGP_PARAMS\Grip, GetGadgetState(ID), (GadgetHeight(ID)-*SGP_PARAMS\gripWidth)/2, #PB_Ignore, #PB_Ignore)
               
               ;fix grip images
               If ImageWidth(*SGP_PARAMS\GripImg1)<>*SGP_PARAMS\Thickness Or ImageHeight(*SGP_PARAMS\GripImg1)<>*SGP_PARAMS\GripWidth
                  FreeImage(*SGP_PARAMS\GripImg1) : *SGP_PARAMS\GripImg1=*SGP_PARAMS\GripImage(ID, *SGP_PARAMS\Thickness, *SGP_PARAMS\GripWidth, *SGP_PARAMS\Vertical, #False)
                  FreeImage(*SGP_PARAMS\GripImg2) : *SGP_PARAMS\GripImg2=*SGP_PARAMS\GripImage(ID, *SGP_PARAMS\Thickness, *SGP_PARAMS\GripWidth, *SGP_PARAMS\Vertical, #True)
                  SetGadgetState(*SGP_PARAMS\Grip, ImageID(*SGP_PARAMS\GripImg1))
               EndIf
            Else
               ;fix grip position
               ResizeGadget(*SGP_PARAMS\Grip, (GadgetWidth(ID)-*SGP_PARAMS\gripWidth)/2, GetGadgetState(ID), #PB_Ignore, #PB_Ignore)
               
               ;fix grip images
               If ImageWidth(*SGP_PARAMS\GripImg1)<>*SGP_PARAMS\GripWidth Or ImageHeight(*SGP_PARAMS\GripImg1)<>*SGP_PARAMS\Thickness
                  FreeImage(*SGP_PARAMS\GripImg1) : *SGP_PARAMS\GripImg1=*SGP_PARAMS\GripImage(ID, *SGP_PARAMS\GripWidth, *SGP_PARAMS\Thickness, *SGP_PARAMS\Vertical, #False)
                  FreeImage(*SGP_PARAMS\GripImg2) : *SGP_PARAMS\GripImg2=*SGP_PARAMS\GripImage(ID, *SGP_PARAMS\GripWidth, *SGP_PARAMS\Thickness, *SGP_PARAMS\Vertical, #True)
                  SetGadgetState(*SGP_PARAMS\Grip, ImageID(*SGP_PARAMS\GripImg1))
               EndIf
            EndIf
         EndIf
         ;}
         
      Case #SGP_WM_SENDEVENT
         ;{/// SEND PB EVENT
         Protected EvenType=lparam
         Select EvenType
            Case #PB_EventType_Change
               If GetGadgetState(ID)<>*SGP_PARAMS\Pos
                  PB_Gadget_SendGadgetCommand(GadgetID(ID), EvenType)
               EndIf
            Default
               PB_Gadget_SendGadgetCommand(GadgetID(ID), EvenType)
         EndSelect
         ;}
         
      Case #SGP_WM_SAVEUNSNAPPOS
         ;{/// SAVE UNSNAP POS
         Protected LinePos=lParam
         If *SGP_PARAMS\Vertical
            If (LinePos=*SGP_PARAMS\Limit\Right Or LinePos=*SGP_PARAMS\Limit\Left)
               If LinePos<>*SGP_PARAMS\Pos
                  *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
               EndIf
            Else
               *SGP_PARAMS\UnsnapPos=#PB_Ignore
            EndIf
         Else
            If (LinePos=*SGP_PARAMS\Limit\top Or LinePos=*SGP_PARAMS\Limit\right)
               If LinePos<>*SGP_PARAMS\Pos
                  *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
               EndIf
            Else
               *SGP_PARAMS\UnsnapPos=#PB_Ignore
            EndIf
         EndIf
         ;}
         
   EndSelect
   
   ProcedureReturn CallWindowProc_(*SGP_PARAMS\CB, Window, Message, wParam, lParam)
EndProcedure
ProcedureDLL SGP_SplitterGadget(ID, x, y, Width, Height, Gadget1, Gadget2, Flags=0)
   ;create line images (transparent or dashed)
   SGP_LineImages()
   
   ;gadget
   Protected result=SplitterGadget(ID, x, y, Width, Height, Gadget1, Gadget2, Flags)
   If result=0 : ProcedureReturn 0 : EndIf
   If ID=#PB_Any : ID=result : EndIf
   
   ;set style (enable double-click)
   SetClassLong_(GadgetID(ID), #GCL_STYLE, GetClassLong_(GadgetID(ID), #GCL_STYLE) | #CS_DBLCLKS)
   
   ;set parameters
   Protected *SGP_PARAMS.SGP_PARAMS=AllocateMemory(SizeOf(SGP_PARAMS))
   *SGP_PARAMS\ID=ID
   *SGP_PARAMS\Dashed=0
   *SGP_PARAMS\Flags=Flags
   *SGP_PARAMS\Vertical=Flags & #PB_Splitter_Vertical
   *SGP_PARAMS\SnapFirst=0
   *SGP_PARAMS\SnapSecond=0
   *SGP_PARAMS\UnsnapPos=150;#PB_Ignore
   *SGP_PARAMS\GripImg1=CreateImage(#PB_Any, 2, 2, 32)
   *SGP_PARAMS\GripImg2=CreateImage(#PB_Any, 2, 2, 32)
   *SGP_PARAMS\Line=SGP_Line
   *SGP_PARAMS\Parent=UseGadgetList(GadgetID(ID))
   If *SGP_PARAMS\Parent
      ;hidden gadgets for drawing line and grip
      If *SGP_PARAMS\Vertical
         *SGP_PARAMS\Thickness=(GadgetX(Gadget2)-GadgetWidth(Gadget1))
         *SGP_PARAMS\Grip=ImageGadget(#PB_Any, GadgetX(ID)+GetGadgetState(ID), GadgetY(ID), 0, 0, 0)
      Else
         *SGP_PARAMS\Thickness=(GadgetY(Gadget2)-GadgetHeight(Gadget1))
         *SGP_PARAMS\Grip=ImageGadget(#PB_Any, GadgetX(ID), GadgetY(ID)+GetGadgetState(ID), 0, 0, 0)
      EndIf
      HideGadget(*SGP_PARAMS\Grip, 1)
      DisableGadget(*SGP_PARAMS\Grip, 1)
   EndIf
   UseGadgetList(*SGP_PARAMS\Parent)
   SetGadgetData(ID, *SGP_PARAMS)
   SetTimer_(GadgetID(ID), 100, 500, 0)
   SetProp_(GadgetID(ID), "SplitterGadgetPlus", ID)
   
   ;set callbacks
   *SGP_PARAMS\CB=SetWindowLong_(GadgetID(ID), #GWL_WNDPROC, @SGP_CB())
   
   ProcedureReturn result
EndProcedure

Macro SplitterGadget
   SGP_SplitterGadget
EndMacro
Procedure SetSplitterSnapping(ID, SnapFirst, SnapSecond) ; change snap-to-border distance (disable if ZERO)
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   
   *SGP_PARAMS\SnapFirst=SnapFirst
   *SGP_PARAMS\SnapSecond=SnapSecond
EndProcedure
Procedure SetSplitterDoubleClick(ID, DblClickToSnap=#True) ; snap-to-border via double-click (disable if #FALSE)
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   
   *SGP_PARAMS\SnapDblClick=0
   If DblClickToSnap
      If *SGP_PARAMS\Flags & #PB_Splitter_FirstFixed
         *SGP_PARAMS\SnapDblClick=1
      EndIf
      If *SGP_PARAMS\Flags & #PB_Splitter_SecondFixed
         *SGP_PARAMS\SnapDblClick=2
      EndIf
   EndIf
EndProcedure
Procedure SetSplitterDashed(ID, Thickness=0, GripWidth=0, *GripDrawingFunction=#Null) ; change bar thickness (between 4 - 16), grip size (disable if ZERO)
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   
   ;enable dashed bar
   *SGP_PARAMS\Dashed=1
   
   ;update bar thickness
   If Thickness>16 : Thickness=16 : EndIf
   If Thickness<4 : Thickness=4 : EndIf
   If *SGP_PARAMS\Thickness<>Thickness
      *SGP_PARAMS\Thickness=Thickness
      PostMessage_(GadgetID(ID), #SGP_WM_FIXUP, 0, 0)
   EndIf
   
   ;update grip button ( optional custom grip painter )
   If gripWidth<1
      *SGP_PARAMS\GripWidth=0
      *SGP_PARAMS\GripImage=#Null
      SetGadgetState(*SGP_PARAMS\Grip, 0)
      HideGadget(*SGP_PARAMS\Grip, 1)
   Else
      *SGP_PARAMS\GripWidth=GripWidth
      If *GripDrawingFunction
         *SGP_PARAMS\GripImage=*GripDrawingFunction
      Else
         *SGP_PARAMS\GripImage=@SGP_GripImages()
      EndIf
      SetGadgetState(*SGP_PARAMS\Grip, ImageID(*SGP_PARAMS\GripImg1))
      HideGadget(*SGP_PARAMS\Grip, 0)
      PostMessage_(GadgetID(ID), #SGP_WM_FIXUP, 0, 0)
   EndIf
EndProcedure
Procedure LockSplitter(ID, Locked=#True) ; lock splitter bar (unlock if #FALSE)
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   
   *SGP_PARAMS\Locked=Locked
EndProcedure
Procedure SwapSplitter(ID, SwapBarPosition=#True, SwapSnapping=#True, SwapMinimumSize=#True, SwapFixedGadget=#True, SwapGadgets=#True) ; swap gadgets and other options
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   Protected SGP_PARAMS.SGP_PARAMS
   CopyMemory(*SGP_PARAMS, @SGP_PARAMS, SizeOf(SGP_PARAMS))
   
   If SwapFixedGadget
      If SGP_PARAMS\Flags & #PB_Splitter_SecondFixed
         SGP_PARAMS\Flags | #PB_Splitter_FirstFixed & ~#PB_Splitter_SecondFixed
      ElseIf SGP_PARAMS\Flags & #PB_Splitter_FirstFixed
         SGP_PARAMS\Flags | #PB_Splitter_SecondFixed & ~#PB_Splitter_FirstFixed
      EndIf
   EndIf
   
   If SwapSnapping
      Swap SGP_PARAMS\SnapFirst, SGP_PARAMS\SnapSecond
   EndIf
   
   Protected Pos=GetGadgetState(ID)
   If SwapBarPosition
      If *SGP_PARAMS\Vertical
         Pos+(GadgetWidth(ID)-2*Pos-*SGP_PARAMS\Thickness)
      Else
         Pos+(GadgetHeight(ID)-2*Pos-*SGP_PARAMS\Thickness)
      EndIf
   EndIf
   
   Protected Min1=GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)
   Protected Min2=GetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize)
   If SwapMinimumSize
      Swap Min1, Min2
   EndIf
   
   Protected Gadget1=GetGadgetAttribute(ID, #PB_Splitter_FirstGadget)
   Protected Gadget2=GetGadgetAttribute(ID, #PB_Splitter_SecondGadget)
   If SwapGadgets
      Swap Gadget1, Gadget2
   EndIf
   
   Protected CurrentGadgetList=UseGadgetList(*SGP_PARAMS\Parent)
   If CurrentGadgetList
      ;preserver gadget children
      Protected dummy=TextGadget(#PB_Any, 0, 0, 0, 0, "")
      SetGadgetAttribute(ID, #PB_Splitter_FirstGadget, dummy)
      SetGadgetAttribute(ID, #PB_Splitter_SecondGadget, dummy)
      ;recreate gadget
      SplitterGadget(ID, GadgetX(ID), GadgetY(ID), GadgetWidth(ID), GadgetHeight(ID), Gadget1, Gadget2, SGP_PARAMS\Flags)
      SetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize, Min1)
      SetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize, Min2)
      SetGadgetState(ID, Pos)
      If SGP_PARAMS\Dashed
         SetSplitterDashed(ID, SGP_PARAMS\Thickness, SGP_PARAMS\GripWidth, SGP_PARAMS\GripImage)
      EndIf
      SetSplitterSnapping(ID, SGP_PARAMS\SnapFirst, SGP_PARAMS\SnapSecond)
      SetSplitterDoubleClick(ID, SGP_PARAMS\SnapDblClick)
      UseGadgetList(CurrentGadgetList)
   EndIf
EndProcedure
Procedure.b SplitterLocked(ID) ;Returns #True if splitter is locked
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   If *SGP_PARAMS\Locked
      ProcedureReturn #True
   EndIf
EndProcedure
Procedure.b SplitterSnapped(ID) ;Returns 1 or 2 if splitter snapped border 1 or 2  is snapped (not snapped if ZERO)
   Protected *SGP_PARAMS.SGP_PARAMS=GetGadgetData(ID)
   Protected snapPos1=GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)
   Protected snapPos2
   If *SGP_PARAMS\Vertical
      snapPos2=GadgetWidth(ID)-GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)-*SGP_PARAMS\Thickness
   Else
      snapPos2=GadgetHeight(ID)-GetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize)-*SGP_PARAMS\Thickness
   EndIf
   If *SGP_PARAMS\SnapFirst And GetGadgetState(ID)=snapPos1
      ProcedureReturn 1
   ElseIf *SGP_PARAMS\SnapSecond And GetGadgetState(ID)=snapPos2
      ProcedureReturn 2
   EndIf
EndProcedure

; ********************
; EXAMPLE @ eddy
; ********************
Enumeration
   #FirstWindow
   #SecondWindow
   #Splitter1
   #Splitter2
   #w=800
   #h=600
EndEnumeration
If OpenWindow(#FirstWindow, 0, 0, 410, 440, "Dashed SplitterGadget And Auto Snap-To-Border", #PB_Window_SizeGadget | #PB_Window_SystemMenu)
   WindowBounds(#FirstWindow, 300, 200, #PB_Ignore, #PB_Ignore)
   SmartWindowRefresh(#FirstWindow, 1)
   ButtonGadget(300, 5, 5, 80, 20, "SWAP")
   
   PanelGadget(10, 0, 0, 0, 0)
   AddGadgetItem(10, -1, "Tab 1")
   ButtonGadget(22, 0, 0, 80, 30, "CLICK!")
   CloseGadgetList()
   ButtonGadget(11, 0, 0, 0, 0, "BIG CLICK!")
   SplitterGadget(#Splitter1, 5, 30, 0, 0, 10, 11, #PB_Splitter_FirstFixed)
   
   SetGadgetAttribute(#Splitter1, #PB_Splitter_FirstMinimumSize, 20)
   SetGadgetAttribute(#Splitter1, #PB_Splitter_SecondMinimumSize, 10)
   SetSplitterDoubleClick(#Splitter1, #True)
   SetSplitterSnapping(#Splitter1, 50, 100)
   SetSplitterDashed(#Splitter1, 8, 100)
   ;SetSplitterDashed(#Splitter1, 8, 100, @MyGripDrawingFunction())
EndIf

If OpenWindow(#SecondWindow, 220, 220, 410, 440, "SplitterGadget : enable / disable options", #PB_Window_SizeGadget | #PB_Window_SystemMenu)
   WindowBounds(#SecondWindow, 300, 200, #PB_Ignore, #PB_Ignore)
   SmartWindowRefresh(#SecondWindow, 1)
   CheckBoxGadget(100, 5, 5, 80, 20, "LOCKED")
   CheckBoxGadget(101, 100, 5, 130, 20, "DOUBLE-CLICK SNAP")
   CheckBoxGadget(102, 250, 5, 120, 20, "SNAP-TO-BORDER")
   SetGadgetState(101, #True)
   SetGadgetState(102, #True)
   
   ContainerGadget(800, 0, 0, 0, 0, #PB_Container_Double) : CloseGadgetList()
   ContainerGadget(900, 0, 0, 0, 0, #PB_Container_Double) : CloseGadgetList()
   SetGadgetItemColor(800, 0, #PB_Gadget_BackColor, $F0F0F0)
   SetGadgetColor(900, #PB_Gadget_BackColor, $ACACAC)
   SplitterGadget(#Splitter2, 5, 30, 0, 0, 800, 900, #PB_Splitter_Vertical | #PB_Splitter_FirstFixed | #PB_Splitter_Separator)
   SetSplitterSnapping(#Splitter2, 90, 30)
   SetSplitterDoubleClick(#Splitter2, #True)
EndIf

Repeat
   Define e=WaitWindowEvent()
   Define g=EventGadget()
   Define t=EventType()
   Define w=EventWindow()
   
   Select e
      Case #PB_Event_CloseWindow
         End
      Case #PB_Event_SizeWindow
         Select w
            Case #FirstWindow
               ResizeGadget(#Splitter1, #PB_Ignore, #PB_Ignore, WindowWidth(w)-10, WindowHeight(w)-40)
            Case #SecondWindow
               ResizeGadget(#Splitter2, #PB_Ignore, #PB_Ignore, WindowWidth(w)-10, WindowHeight(w)-40)
         EndSelect
      Case #PB_Event_Gadget
         Select g
            Case #Splitter1
               If t=#PB_EventType_LeftDoubleClick
                  Debug "Double-Click : #Splitter1"
               ElseIf t=#PB_EventType_Change
                  Debug "Splitter1 : pos="+Str(GetGadgetState(g))
               EndIf
            Case #Splitter2
               If t=#PB_EventType_LeftDoubleClick
                  Debug "Double-Click : #Splitter2"
               ElseIf t=#PB_EventType_Change
                  Debug "Splitter2 : pos="+Str(GetGadgetState(g))
               EndIf
            Case 300
               SwapSplitter(#Splitter1)
            Case 100
               LockSplitter(#Splitter2, GetGadgetState(100))
            Case 101
               SetSplitterDoubleClick(#Splitter2, GetGadgetState(101))
            Case 102
               SetSplitterSnapping(#Splitter2, 90*GetGadgetState(102), 30*GetGadgetState(102))
         EndSelect
      Default
   EndSelect
ForEver

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 1:51 am
by Demivec
When I run the program without changing any settings and modify the position of the vertical splitter by dragging it to a new position in the window. I noticed that double-clicking cause it to snap to a border, but only single clicking it at the border caused it to be restored. It that the intended behavoir?

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 1:54 am
by eddy
Demivec wrote:When I run the program without changing any settings and modify the position of the vertical splitter by dragging it to a new position in the window. I noticed that double-clicking cause it to snap to a border, but only single clicking it at the border caused it to be restored. It that the intended behavoir?
Yes

Why ? Is it weird ?

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 2:02 am
by Demivec
eddy wrote:
Demivec wrote:When I run the program without changing any settings and modify the position of the vertical splitter by dragging it to a new position in the window. I noticed that double-clicking cause it to snap to a border, but only single clicking it at the border caused it to be restored. It that the intended behavoir?
Yes

Why ? Is it weird ?
IMHO it seemed to make more sense that if a Double-click was required to snap it to the border that a Double-click should be required to restore it. I noticed when I manually drug the splitter to the border. When I tried to manually drag it from the border it always jumped to where it had previously been position (the middle). I had to chase it around a little so that I could reposition it. :)

Nice code. Thanks for sharing it.

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 2:23 am
by eddy
Ok I'll fix it

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 5:16 am
by eddy
I fixed the snapping.
Now you have to double-click to snap or unsnap the splitter bar.

[updated] improved snapping precision

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 7:03 am
by Demivec
When Double-Clip-Snap, Snap-to-border, and Locked are each unchecked and the vertical splitter has been drug all the way to the left border it will ignore subsequent double-clicks. However if it is drug to the right border than a double-clicked at the right border will cause it to revert to its last position.

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 12:50 pm
by srod
Interesting.... looks good.

I take it that you must always use container gadgets inside the splitter? I ask because there are some redrawing issues when using a dashed splitter when I switch the containers for panels and buttons etc. (Especially panel gadgets!) When I put the panels and buttons inside the containers then everything works much better, although the dashed separator does have a habit of disappearing whilst being dragged!

I had the same kinds of problems with my splitter when I attempted to use an image-gadget as the basis for the separator, problems which I could not reliably fix. I ended up using a top-level window instead of the image gadgets which worked much better and which did not corrupt any of the child controls whilst being dragged.

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Sun Feb 14, 2010 3:06 pm
by eddy
srod wrote:Interesting.... looks good.

I take it that you must always use container gadgets inside the splitter? I ask because there are some redrawing issues when using a dashed splitter when I switch the containers for panels and buttons etc. (Especially panel gadgets!) When I put the panels and buttons inside the containers then everything works much better, although the dashed separator does have a habit of disappearing whilst being dragged!

I had the same kinds of problems with my splitter when I attempted to use an image-gadget as the basis for the separator, problems which I could not reliably fix. I ended up using a top-level window instead of the image gadgets which worked much better and which did not corrupt any of the child controls whilst being dragged.
You're right. In fact, I didn't test it with buttonGadget or anything else.
My previous version used top-level window too.

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Mon Feb 15, 2010 10:01 pm
by eddy
- fixed dashed splitter (now it's a top-most transparent window)
- fixed unsnap functionality

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Mon Feb 15, 2010 11:26 pm
by srod
Looks much better Eddy - very nice. 8)

Have found a problem though when using a panel gadget and a button ...

Code: Select all

If OpenWindow(#FirstWindow, 0, 0, 410, 440, "Dashed SplitterGadget And Auto Snap-To-Border", #PB_Window_SizeGadget | #PB_Window_SystemMenu)
   WindowBounds(#FirstWindow, 300, 200, #PB_Ignore, #PB_Ignore)
   SmartWindowRefresh(#FirstWindow, 1)
   ButtonGadget(300, 5, 5, 80, 20, "SWAP")
   
   PanelGadget(10, 0, 0, 0, 0)
    AddGadgetItem(10, -1, "Tab 1")
      ButtonGadget(100, 0, 0, 80, 30, "CLICK!")
   CloseGadgetList()
   ButtonGadget(11, 0, 0, 0, 0, "CLICK!")
   SetGadgetColor(10, #PB_Gadget_BackColor, $F0F0F0)
   SetGadgetColor(11, #PB_Gadget_BackColor, $ACACAC)
   SplitterGadget(#Splitter1, 5, 30, 0, 0, 10, 11, #PB_Splitter_FirstFixed)
   
   SetGadgetAttribute(#Splitter1, #PB_Splitter_FirstMinimumSize, 20)
   SetGadgetAttribute(#Splitter1, #PB_Splitter_SecondMinimumSize, 10)
   SetSplitterDoubleClick(#Splitter1, #True)
   SetSplitterSnapping(#Splitter1, 50, 100)
   SetSplitterDashed(#Splitter1, 8, 100)
   ;SetSplitterDashed(#Splitter1, 8, 100, @MyGripDrawingFunction())
EndIf
The panel doesn't show and there are some redrawing problems.

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Tue Feb 16, 2010 12:06 am
by eddy
Fixed
I removed the EraseBackground windows message. :arrow: reduce flickering (good thing!)

Re: SplitterGadget+ dashed bar, border snap, thickness,grip,swap

Posted: Tue Feb 16, 2010 11:14 am
by srod
Very nice - a great splitter control, better than mine. :wink:

Thanks Eddy.