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

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

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

Post by eddy »

v1.2 for PB 4.20 & PB 4.30
- SplitterGadgetPlus
- SwapSplitter : swap gadgets or/and other options
- DashedSplitterMode : dashed bar mode ( disable if #FALSE )
- DashedSplitterGrip : change grip size for dashed mode (disable if ZERO)
- DashedSplitterThickness : change bar thickness for dashed mode
- SnapSplitterDistance : change snap-to-border distance (disable if ZERO)
- SnapSplitterDoubleClick : snap-to-border via double-click ( disable if #FALSE )
- LockSplitter : lock splitter bar ( unlock if #FALSE )
- SplitterLocked
- SplitterDashed
- * Double-Click event
- * Custom Grip Painter

Code: Select all

Structure SGP_PARAMS
   ID.i           ;stored original splittergadget ID
   CB.i           ;stored original splittergadget callback
   Flags.i        ;stored original splittergadget flags
   Dashed.b       ;enable dashedbar
   Line.i         ;current dashed line ID
   x.i            ;Splitter Pos (for bar position calculation)
   y.i            ;Splitter Pos (for bar position calculation)
   Thickness.i    ;Bar Thickness (can't changed)
   Parent.i       ;Parent  (not used)
   SnapFirst.i    ;Snap for first gadget
   SnapSecond.i   ;Snap for second gadget
   SnapDblClick.b ;Snap to fixed gadget border
   UnsnapPos.i    ;Unsnap position
   Pos.i          ;Bar position
   Locked.b       ;Bar locked
   GripWidth.i    ;Grip width
   GripFocus.b    ;Grip focus
   *GripPaint     ;Grip painter
EndStructure
Procedure SGP_LinesCB(Window, Message, wParam, lParam)
   Shared SGP_LineH
   Shared SGP_LineV
   Shared SGP_Owner
   Shared Limit.RECT
   Shared Snap.RECT
   
   Protected ID
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   If *SGP_PARAMS : ID=*SGP_PARAMS\ID : EndIf
   
   Select Message
      Case #WM_MOUSEMOVE
         ;{/// MOVE LINES ( DASHED )
         Protected mx=PeekW(@lparam)
         Protected my=PeekW(@lparam+2)
         
         Static offx=#PB_Ignore
         Static offy=#PB_Ignore
         If offx=#PB_Ignore : offx=-mx : EndIf
         If offy=#PB_Ignore : offy=-my : EndIf
         
         Protected x=WindowX(SGP_LineV)+mx+offx-*SGP_PARAMS\x
         Protected y=WindowY(SGP_LineH)+my+offy-*SGP_PARAMS\y
         
         ;snap automaticly
         If y<Snap\Top : y=Limit\Top : EndIf
         If x<Snap\Left : x=Limit\Left : EndIf
         If x>Snap\Right : x=Limit\Right : EndIf
         If y>Snap\Bottom : y=Limit\Bottom : EndIf
         
         ;move limits
         If y<Limit\Top : y=Limit\Top : EndIf
         If x<Limit\Left : x=Limit\Left : EndIf
         If x>Limit\Right : x=Limit\Right : EndIf
         If y>Limit\Bottom : y=Limit\Bottom : EndIf
         
         ResizeWindow(SGP_LineH, #PB_Ignore, y+*SGP_PARAMS\y, #PB_Ignore, #PB_Ignore)
         ResizeWindow(SGP_LineV, x+*SGP_PARAMS\x, #PB_Ignore, #PB_Ignore, #PB_Ignore)
         ;}
         
         ;{/// GRIP CURSOR ( DASHED )
         Structure SGP_Cursor
            arrow.l
            vert.l
            horz.l
         EndStructure
         Shared SGP_Cursor.SGP_Cursor
         If *SGP_PARAMS\Line=SGP_LineH
            SetCursor_(SGP_Cursor\vert)
         Else
            SetCursor_(SGP_Cursor\horz)
         EndIf
         ;}
         
      Case #WM_LBUTTONUP
         Protected Pos=GetGadgetState(ID)
         Protected LineY=WindowY(SGP_LineH)-*SGP_PARAMS\y
         Protected LineX=WindowX(SGP_LineV)-*SGP_PARAMS\x
         
         ;{/// UNSNAP ( DASHED )
         If *SGP_PARAMS\UnsnapPos<>#PB_Ignore
            If *SGP_PARAMS\Line=SGP_LineH
               ;fix pixel slide
               If *SGP_PARAMS\Dashed=0 And Abs(Pos-Limit\Top)<2 : Pos=Limit\Top : EndIf
               If *SGP_PARAMS\Dashed=0 And Abs(Pos-Limit\Bottom)<2 : Pos=Limit\Bottom : EndIf
               
               If (Pos=Limit\Top Or Pos=Limit\Bottom) And Pos=LineY
                  HideWindow(SGP_LineH, 1)
                  SetGadgetState(ID, *SGP_PARAMS\UnsnapPos)
                  *SGP_PARAMS\GripFocus=0
                  *SGP_PARAMS\UnsnapPos=#PB_Ignore
               EndIf
            Else
               ;fix pixel slide
               If *SGP_PARAMS\Dashed=0 And Abs(Pos-Limit\Right)<2 : Pos=Limit\Right : EndIf
               If *SGP_PARAMS\Dashed=0 And Abs(Pos-Limit\Left)<2 : Pos=Limit\Left : EndIf
               
               If (Pos=Limit\Right Or Pos=Limit\Left) And Pos=LineX
                  HideWindow(SGP_LineV, 1)
                  SetGadgetState(ID, *SGP_PARAMS\UnsnapPos)
                  *SGP_PARAMS\GripFocus=0
                  *SGP_PARAMS\UnsnapPos=#PB_Ignore
               EndIf
            EndIf
         EndIf
         ;}
         
         ;{/// HIDE LINES ( DASHED )
         If IsWindowVisible_(WindowID(*SGP_PARAMS\Line))
            If *SGP_PARAMS\Line=SGP_LineH
               If (LineY=Limit\Top Or LineY=Limit\Bottom)
                  If LineY<>*SGP_PARAMS\Pos
                     *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
                  EndIf
               Else
                  *SGP_PARAMS\UnsnapPos=#PB_Ignore
               EndIf
               SetGadgetState(ID, LineY)
               HideWindow(SGP_LineH, 1)
            Else
               If (LineX=Limit\Right Or LineX=Limit\Left)
                  If LineX<>*SGP_PARAMS\Pos
                     *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
                  EndIf
               Else
                  *SGP_PARAMS\UnsnapPos=#PB_Ignore
               EndIf
               SetGadgetState(ID, LineX)
               HideWindow(SGP_LineV, 1)
            EndIf
         EndIf
         ;}
         
         ReleaseCapture_()
         offx=#PB_Ignore
         offy=#PB_Ignore
   EndSelect
   
   ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure SGP_Lines()
   Shared SGP_LineH
   Shared SGP_LineV
   Shared SGP_Owner
   
   If SGP_LineH And SGP_LineV : ProcedureReturn 0 : EndIf
   
   ExamineDesktops()
   Protected w=DesktopWidth(0)
   Protected h=DesktopHeight(0)
   Protected a=16
   Protected b=15
   Protected rg0=CreateRectRgn_(0, 0, a, a)
   Protected rgH=CreateRectRgn_(0, 0, w, a)
   Protected rgV=CreateRectRgn_(0, 0, a, h)
   Protected pt=CreateRectRgn_(0, 0, 1, 1)
   
   ;{//// DASHED SQUARE
   For y=0 To b Step 2
      For x=0 To b Step 2
         CombineRgn_(rg0, rg0, pt, #RGN_XOR)
         OffsetRgn_(pt, 1, 1)
         CombineRgn_(rg0, rg0, pt, #RGN_XOR)
         OffsetRgn_(pt, 1, -1)
      Next
      OffsetRgn_(pt, -a, 2)
   Next
   ;}
   
   ;{//// DASHED HORIZONTAL
   While OffsetRgn<w+1
      CombineRgn_(rgH, rgH, rg0, #RGN_XOR)
      OffsetRgn_(rg0, a, 0)
      OffsetRgn+a
   Wend
   OffsetRgn_(rg0, -OffsetRgn, 0)
   ;}
   
   ;{//// DASHED VERTICAL
   While OffsetRgn<h+1
      CombineRgn_(rgV, rgV, rg0, #RGN_XOR)
      OffsetRgn_(rg0, 0, a)
      OffsetRgn+a
   Wend
   ;}
   
   ;{//// CREATE LINES
   Protected GadgetListButtonID=ButtonGadget(#PB_Any, 0, 0, 0, 0, "Hidden")  ;// Update for PB 4.30b1
   Protected GadgetList=GetParent_(GadgetID(GadgetListButtonID))        ;// Update for PB 4.30b1
   
   SGP_Owner=OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_Invisible)
   If SGP_Owner
      SGP_LineH=OpenWindow(#PB_Any, 0, 0, w, a, "", #PB_Window_BorderLess | #PB_Window_Invisible, WindowID(SGP_Owner))
      SGP_LineV=OpenWindow(#PB_Any, 9, 9, a, h, "", #PB_Window_BorderLess | #PB_Window_Invisible, WindowID(SGP_Owner))
      
      ;set dashed mode
      SetWindowRgn_(WindowID(SGP_LineH), rgH, 1)
      SetWindowRgn_(WindowID(SGP_LineV), rgV, 1)
      
      ;set color
      SetWindowColor(SGP_LineH, GetSysColor_(#COLOR_3DSHADOW))
      SetWindowColor(SGP_LineV, GetSysColor_(#COLOR_3DSHADOW))
      
      ;set callback
      SetWindowCallback(@SGP_LinesCB(), SGP_LineH)
      SetWindowCallback(@SGP_LinesCB(), SGP_LineV)
      
      Protected result=1
   EndIf
   
   FreeGadget(GadgetListButtonID);// Update for PB 4.30b1
   UseGadgetList(GadgetList) ;// Update for PB 4.30b1
   ;}
   
   DeleteObject_(rg0)
   DeleteObject_(rgH)
   DeleteObject_(rgV)
   DeleteObject_(pt)
   
   Shared SGP_Cursor.SGP_Cursor
   SGP_Cursor\arrow=LoadCursor_(0, #IDC_ARROW)
   SGP_Cursor\vert=LoadCursor_(0, #IDC_SIZENS)
   SGP_Cursor\horz=LoadCursor_(0, #IDC_SIZEWE)
   
   ProcedureReturn result
EndProcedure
Procedure SGP_CB(Window, Message, wParam, lParam)
   Shared SGP_LineH
   Shared SGP_LineV
   Shared SGP_Owner
   Shared Limit.RECT
   Shared Snap.RECT
   
   Protected vertical
   Protected focus
   Protected bx, by, bw, bh, dx, dy
   Protected Pos, x, y, w, h
   
   Protected ID
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   If *SGP_PARAMS : ID=*SGP_PARAMS\ID : EndIf
   
   Select Message
      Case #WM_DESTROY
         ;{/// FREE GADGET
         Protected CB=*SGP_PARAMS\CB
         SetWindowLong_(GadgetID(ID), #GWL_WNDPROC, CB)
         SetWindowLong_(GadgetID(ID), #GWL_USERDATA, 0)
         FreeMemory(*SGP_PARAMS)
         ProcedureReturn CallWindowProc_(CB, Window, Message, wParam, lParam)
         ;}
         
      Case #WM_LBUTTONDOWN
         ;{/// SHOW LINES
         ;check if locked
         If *SGP_PARAMS\Locked : ProcedureReturn 1 : EndIf
         
         ;line linked to gadget
         SetWindowLong_(WindowID(*SGP_PARAMS\Line), #GWL_USERDATA, *SGP_PARAMS)
         
         ;line position
         *SGP_PARAMS\Pos=GetGadgetState(ID)
         
         ;line limits
         GetClientRect_(GadgetID(ID), @Limit)
         GetClientRect_(GadgetID(ID), @Snap)
         
         Limit\Left+GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)
         Limit\Top+GetGadgetAttribute(ID, #PB_Splitter_FirstMinimumSize)
         Limit\Right-*SGP_PARAMS\Thickness-GetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize)
         Limit\Bottom-*SGP_PARAMS\Thickness-GetGadgetAttribute(ID, #PB_Splitter_SecondMinimumSize)
         
         Snap\Left+*SGP_PARAMS\SnapFirst
         Snap\Top+*SGP_PARAMS\SnapFirst
         Snap\Right-*SGP_PARAMS\SnapSecond
         Snap\Bottom-*SGP_PARAMS\SnapSecond
         
         ;line layout
         Protected rc.RECT
         GetWindowRect_(GadgetID(ID), rc.RECT)
         *SGP_PARAMS\x=rc\Left
         *SGP_PARAMS\y=rc\Top
         ResizeWindow(SGP_LineH, *SGP_PARAMS\x, *SGP_PARAMS\y+GetGadgetState(ID), GadgetWidth(ID), *SGP_PARAMS\Thickness)
         ResizeWindow(SGP_LineV, *SGP_PARAMS\x+GetGadgetState(ID), *SGP_PARAMS\y, *SGP_PARAMS\Thickness, GadgetHeight(ID))
         
         ;line display
         If *SGP_PARAMS\Dashed
            If *SGP_PARAMS\GripWidth=0 Or *SGP_PARAMS\GripFocus=1
               ShowWindow_(WindowID(*SGP_PARAMS\Line), #SW_SHOWNA)
               SetCapture_(WindowID(*SGP_PARAMS\Line))
            EndIf
            ProcedureReturn 1
         EndIf
         ;}
         
      Case #WM_LBUTTONUP
         ;{/// HIDE LINES
         If *SGP_PARAMS\Dashed=0 And GetCapture_()=GadgetID(ID) And IsWindowVisible_(WindowID(*SGP_PARAMS\Line))
            PostMessage_(WindowID(*SGP_PARAMS\Line), #WM_LBUTTONUP, 0, 0)
         EndIf
         ;}
         
      Case #WM_MOUSEMOVE
         ;{/// MOVE LINES
         Pos=GetGadgetState(ID)
         x=Pos
         y=Pos
         
         If GetCapture_()=GadgetID(ID)
            Protected Hide.b=1
            
            ;snap automaticly
            If *SGP_PARAMS\Line=SGP_LineH
               If y<Snap\Top : y=Limit\Top : Hide=0 : EndIf
               If y>Snap\Bottom : y=Limit\Bottom : Hide=0 : EndIf
            Else
               If x<Snap\Left : x=Limit\Left : Hide=0 : EndIf
               If x>Snap\Right : x=Limit\Right : Hide=0 : EndIf
            EndIf
            
            ;snap position preview
            x+*SGP_PARAMS\x
            y+*SGP_PARAMS\y
            ResizeWindow(SGP_LineV, x, #PB_Ignore, #PB_Ignore, #PB_Ignore)
            ResizeWindow(SGP_LineH, #PB_Ignore, y, #PB_Ignore, #PB_Ignore)
            HideWindow(*SGP_PARAMS\Line, Hide)
         EndIf
         ;}
         
         ;{/// GRIP CHECKING
         SGP_CB(GadgetID(ID), #WM_TIMER, 2000, 0)
         ;}
         
         ;{/// GRIP CURSOR
         If *SGP_PARAMS\Dashed And *SGP_PARAMS\GripWidth
            Shared SGP_Cursor.SGP_Cursor
            If Not *SGP_PARAMS\GripFocus
               SetCursor_(SGP_Cursor\arrow)
            ElseIf *SGP_PARAMS\Line=SGP_LineH
               SetCursor_(SGP_Cursor\vert)
            Else
               SetCursor_(SGP_Cursor\horz)
            EndIf
         EndIf
         ;}
         
      Case #WM_MOUSELEAVE, #WM_MOUSEHOVER
         ;{/// GRIP CURSOR
         If *SGP_PARAMS\Dashed And *SGP_PARAMS\GripWidth
            Shared SGP_Cursor.SGP_Cursor
            SetCursor_(SGP_Cursor\arrow)
         EndIf
         ;}
         
      Case #WM_PAINT, #WM_ERASEBKGND
         ;{/// GRIP PAINT
         
         If Message=#WM_ERASEBKGND ;And IsWindowVisible_(*SGP_PARAMS\Line)=0
            ; Paint Gadget
            ; -> Post message to paint grip
            ; -> Paint Grip
            PostMessage_(GadgetID(ID), #WM_UPDATEUISTATE, 1, 1)
            PostMessage_(GadgetID(ID), #WM_PAINT, 1, 1)
         ElseIf wParam=0 Or lParam=0
            ; Paint Gadget
            ; -> Post message to paint grip
            ; -> Paint Grip
            PostMessage_(GadgetID(ID), #WM_UPDATEUISTATE, 1, 1)
            PostMessage_(GadgetID(ID), #WM_PAINT, 1, 1)
         ElseIf wParam=1 And lParam=1
            If *SGP_PARAMS\Dashed And *SGP_PARAMS\GripWidth
               
               vertical=(#True And *SGP_PARAMS\Line=SGP_LineV)
               focus=*SGP_PARAMS\GripFocus
               If vertical
                  bw=*SGP_PARAMS\Thickness
                  bh=*SGP_PARAMS\GripWidth
                  bx=GetGadgetState(ID)
                  by=(GadgetHeight(ID)-bh)/2
               Else
                  bw=*SGP_PARAMS\GripWidth
                  bh=*SGP_PARAMS\Thickness
                  bx=(GadgetWidth(ID)-bw)/2
                  by=GetGadgetState(ID)
               EndIf
               
               Protected *GadgetOutput=AllocateMemory(4*SizeOf(Long))
               PokeL(*GadgetOutput+0*SizeOf(Long), 1)             ;Type.l
               PokeL(*GadgetOutput+1*SizeOf(Long), GadgetID(ID))  ;Windows.l
               PokeL(*GadgetOutput+2*SizeOf(Long), 0)             ;DC.l
               PokeL(*GadgetOutput+3*SizeOf(Long), 0)             ;ReleaseProc.l
               
               StartDrawing(*GadgetOutput)
                  If *SGP_PARAMS\GripPaint
                     ;{/// USE CUSTOM PAINTER
                     CallFunctionFast(*SGP_PARAMS\GripPaint, bx, by, bw, bh, vertical, focus)
                     ;}
                  Else
                     ;{/// USE DEFAULT PAINTER
                     Protected foreColor
                     Protected backColor
                     foreColor+(#True And focus=0)*GetSysColor_(#COLOR_3DFACE)
                     foreColor+(#True And focus>0)*GetSysColor_(#COLOR_SCROLLBAR)
                     
                     ;background rectangle
                     Box(bx, by, bw, bh, foreColor)
                     
                     If vertical
                        ;borders
                        Line(bx, by+0, bw, 0, GetSysColor_(#COLOR_BTNSHADOW))
                        Line(bx, by+1, bw, 0, GetSysColor_(#COLOR_BTNHILIGHT))
                        Line(bx, by+bh-2, bw, 0, GetSysColor_(#COLOR_BTNSHADOW))
                        Line(bx, by+bh-1, bw, 0, GetSysColor_(#COLOR_BTNHILIGHT))
                        
                        ;dots
                        For dy=10 To bh-10 Step 3
                           Line(bx+bw/2-1, by+dy, 2, 0, GetSysColor_(#COLOR_BTNSHADOW))
                        Next
                     Else
                        ;borders
                        Line(bx+0, by, 0, bh, GetSysColor_(#COLOR_BTNSHADOW))
                        Line(bx+1, by, 0, bh, GetSysColor_(#COLOR_BTNHILIGHT))
                        Line(bx+bw-2, by, 0, bh, GetSysColor_(#COLOR_BTNSHADOW))
                        Line(bx+bw-1, by, 0, bh, GetSysColor_(#COLOR_BTNHILIGHT))
                        
                        ;dots
                        For dx=10 To bw-10 Step 3
                           Line(bx+dx, by+bh/2-1, 0, 2, GetSysColor_(#COLOR_BTNSHADOW))
                        Next
                     EndIf
                     ;}
                  EndIf
               StopDrawing()
               
               FreeMemory(*GadgetOutput)
            EndIf
         EndIf
         ;}
         
      Case #WM_TIMER
         ;{/// GRIP CHECKING
         If wParam=2000 And *SGP_PARAMS\Dashed And *SGP_PARAMS\GripWidth
            vertical=(#True And *SGP_PARAMS\Line=SGP_LineV)
            focus=*SGP_PARAMS\GripFocus
            
            If vertical
               bw=*SGP_PARAMS\Thickness
               bh=*SGP_PARAMS\GripWidth
               bx=GetGadgetState(ID)
               by=(GadgetHeight(ID)-bh)/2
            Else
               bw=*SGP_PARAMS\GripWidth
               bh=*SGP_PARAMS\Thickness
               bx=(GadgetWidth(ID)-bw)/2
               by=GetGadgetState(ID)
            EndIf
            
            GetCursorPos_(@mouse.POINT)
            ScreenToClient_(GadgetID(ID), @mouse.POINT)
            If mouse\x>=bx And mouse\x<=bx+bw And mouse\y>=by And mouse\y<=by+bh
               If *SGP_PARAMS\GripFocus=0
                  *SGP_PARAMS\GripFocus=1
                  SetTimer_(GadgetID(ID), 2000, 100, 0)
                  SGP_CB(GadgetID(ID), #WM_PAINT, 1, 1)
               EndIf
            Else
               If *SGP_PARAMS\GripFocus=1
                  *SGP_PARAMS\GripFocus=0
                  KillTimer_(GadgetID(ID), 2000)
                  SGP_CB(GadgetID(ID), #WM_PAINT, 1, 1)
               EndIf
            EndIf
         EndIf
         ;}
         
      Case #WM_UPDATEUISTATE
         ;{/// BAR THICKNESS
         If (wParam=1 And lParam=1)
            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))
            
            If Not ModifiedThickness
               Protected ID1=GetGadgetAttribute(ID, #PB_Splitter_FirstGadget)
               Protected ID2=GetGadgetAttribute(ID, #PB_Splitter_SecondGadget)
               
               vertical=(#True And *SGP_PARAMS\Line=SGP_LineV)
               If vertical
                  x=GadgetX(ID1)+GadgetWidth(ID1)+*SGP_PARAMS\Thickness
                  w=GadgetWidth(ID)-x
                  ResizeGadget(ID2, x, #PB_Ignore, w, #PB_Ignore)
               Else
                  y=GadgetY(ID1)+GadgetHeight(ID1)+*SGP_PARAMS\Thickness
                  h=GadgetHeight(ID)-y
                  ResizeGadget(ID2, #PB_Ignore, y, #PB_Ignore, h)
               EndIf
            EndIf
         EndIf
         ;}
         
      Case #WM_LBUTTONDBLCLK
         ;{/// DOUBLE-CLICK EVENT
         Protected wp
         Protected lp
         PokeW(@wp+0, ID)
         PokeW(@wp+2, #PB_EventType_LeftDoubleClick)
         lp=GadgetID(ID)
         PostMessage_(*SGP_PARAMS\Parent, #WM_COMMAND, wp, lp)
         ;}
         
         ;{/// DOUBLE-CLICK SNAP
         Select *SGP_PARAMS\SnapDblClick
            Case 1
               *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
               *SGP_PARAMS\GripFocus=0
               SetGadgetState(ID, 0)
            Case 2
               *SGP_PARAMS\UnsnapPos=*SGP_PARAMS\Pos
               *SGP_PARAMS\GripFocus=0
               SetGadgetState(ID, GadgetWidth(ID)+GadgetHeight(ID))
            Default
         EndSelect
         ;}
         
      Case #WM_WINDOWPOSCHANGED
         
      Default
   EndSelect
   
   ProcedureReturn CallWindowProc_(*SGP_PARAMS\CB, Window, Message, wParam, lParam)
EndProcedure

ProcedureDLL SplitterGadgetPlus(ID, x, y, w, h, Gadget1, Gadget2, Flags=0, Dashed.b=#True, SnapFirst=0, SnapSecond=0)
   Shared SGP_LineH
   Shared SGP_LineV
   Shared SGP_Owner
   
   SGP_Lines()
   
   ;gadget
   If IsGadget(ID) : FreeGadget(ID) : EndIf
   Protected result=SplitterGadget(ID, x, y, w, h, Gadget1, Gadget2, Flags)
   If result=0 : ProcedureReturn 0 : EndIf
   If ID=#PB_Any : ID=result : EndIf
   
   ;gadget parent
   Protected Parent=GadgetID(ID)
   While GetParent_(Parent) : Parent=GetParent_(Parent) : Wend
   
   ;set style
   Protected style=GetClassLong_(GadgetID(ID), #GCL_STYLE) | #CS_DBLCLKS
   SetClassLong_(GadgetID(ID), #GCL_STYLE, style)
   
   ;set callback
   Protected CB=SetWindowLong_(GadgetID(ID), #GWL_WNDPROC, @SGP_CB())
   
   ;set parameters
   Protected *SGP_PARAMS.SGP_PARAMS=AllocateMemory(SizeOf(SGP_PARAMS))
   *SGP_PARAMS\ID=ID
   *SGP_PARAMS\CB=CB
   *SGP_PARAMS\Dashed=Dashed
   *SGP_PARAMS\Flags=Flags
   *SGP_PARAMS\Thickness+4*(#True And (Flags & #PB_Splitter_Separator)=0)
   *SGP_PARAMS\Thickness+7*(#True And (Flags & #PB_Splitter_Separator))
   *SGP_PARAMS\Line+SGP_LineH*(#True And (Flags & #PB_Splitter_Vertical)=0)
   *SGP_PARAMS\Line+SGP_LineV*(#True And (Flags & #PB_Splitter_Vertical))
   *SGP_PARAMS\Parent=Parent
   *SGP_PARAMS\SnapFirst=SnapFirst
   *SGP_PARAMS\SnapSecond=SnapSecond
   *SGP_PARAMS\UnsnapPos=#PB_Ignore
   SetWindowLong_(GadgetID(ID), #GWL_USERDATA, *SGP_PARAMS)
   SetTimer_(GadgetID(ID), 100, 500, 0)
   ProcedureReturn result
EndProcedure
ProcedureDLL SnapSplitterDistance(ID, SnapFirst, SnapSecond) ; change snap-to-border distance (disable if ZERO)
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   *SGP_PARAMS\SnapFirst=SnapFirst
   *SGP_PARAMS\SnapSecond=SnapSecond
EndProcedure
ProcedureDLL SnapSplitterDoubleClick(ID, DblClickToSnap.b=1) ; snap-to-border via double-click (disable if #FALSE)
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   *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
ProcedureDLL DashedSplitterThickness(ID, Thickness) ; change bar thickness for dashed mode
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   ;check if out of range
   If Thickness>16 : Thickness=16 : EndIf
   If Thickness<4 : Thickness=4 : EndIf
   
   ;dashed mode with modified bar thickness
   *SGP_PARAMS\Dashed=1
   *SGP_PARAMS\Thickness=Thickness
   PostMessage_(GadgetID(ID), #WM_UPDATEUISTATE, 1, 1)
EndProcedure
ProcedureDLL DashedSplitterGrip(ID, gripWidth, gripPaintProc=0) ; change grip size for dashed mode (disable if ZERO)
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   ;dashed mode with grip button ( optional custom grip painter )
   *SGP_PARAMS\Dashed=1
   *SGP_PARAMS\GripWidth=gripWidth
   *SGP_PARAMS\GripPaint=gripPaintProc
EndProcedure
ProcedureDLL DashedSplitterMode(ID, Dashed.b=1) ; enable dashed mode (disable if #FALSE)
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   *SGP_PARAMS\Dashed=Dashed
EndProcedure
ProcedureDLL SwapSplitter(ID, SwapBarPosition.b=1, SwapBorderSnap.b=1, SwapMinimumSize.b=1, SwapFixedGadget.b=1, SwapGadgets.b=1) ; swap gadgets and other options
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(GadgetID(ID), #GWL_USERDATA)
   Protected Thickness=*SGP_PARAMS\Thickness
   Protected Dashed=*SGP_PARAMS\Dashed
   Protected GripWidth=*SGP_PARAMS\GripWidth
   Protected GripPaint=*SGP_PARAMS\GripPaint
   
   If SwapFixedGadget
      If *SGP_PARAMS\Flags & #PB_Splitter_FirstFixed
         *SGP_PARAMS\Flags | #PB_Splitter_SecondFixed & ~#PB_Splitter_FirstFixed
      ElseIf *SGP_PARAMS\Flags & #PB_Splitter_SecondFixed
         *SGP_PARAMS\Flags | #PB_Splitter_FirstFixed & ~#PB_Splitter_SecondFixed
      EndIf
   EndIf
   
   Protected SnapDblClick=*SGP_PARAMS\SnapDblClick
   Protected SnapFirst=*SGP_PARAMS\SnapFirst
   Protected SnapSecond=*SGP_PARAMS\SnapSecond
   If SwapBorderSnap
      Swap SnapFirst, SnapSecond
   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 Pos=GetGadgetState(ID)
   If SwapBarPosition
      Shared SGP_LineH
      Shared SGP_LineV
      Shared SGP_Owner
      Pos+(GadgetHeight(ID)-2*Pos-Thickness)*(#True And *SGP_PARAMS\Line=SGP_LineH)
      Pos+(GadgetWidth(ID)-2*Pos-Thickness)*(#True And *SGP_PARAMS\Line=SGP_LineV)
   EndIf
   
   UseGadgetList(GetParent_(GadgetID(ID)));fix multi-windows
   Protected Gadget0=ButtonGadget(#PB_Any, 0, 0, 0, 0, "HiddenGadget")
   SetGadgetAttribute(ID, #PB_Splitter_FirstGadget, Gadget0)
   SetGadgetAttribute(ID, #PB_Splitter_SecondGadget, Gadget0)
   
   SplitterGadgetPlus(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)
   SnapSplitterDistance(ID, SnapFirst, SnapSecond)
   SnapSplitterDoubleClick(ID, SnapDblClick)
   DashedSplitterGrip(ID, GripWidth, GripPaint)
   DashedSplitterThickness(ID, Thickness)
   DashedSplitterMode(ID, Dashed)
   SetGadgetState(ID, Pos)
EndProcedure
ProcedureDLL LockSplitter(ID, Locked.b=1) ; lock splitter bar (unlock if #FALSE)
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   *SGP_PARAMS\Locked=Locked
EndProcedure
ProcedureDLL.b SplitterLocked(ID) ;Returns #True if splitter is locked
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   ProcedureReturn *SGP_PARAMS\Locked
EndProcedure
ProcedureDLL.b SplitterDashed(ID) ;Returns #True if splitter is dashed
   Protected Window=GadgetID(ID)
   Protected *SGP_PARAMS.SGP_PARAMS=GetWindowLong_(Window, #GWL_USERDATA)
   
   ProcedureReturn *SGP_PARAMS\Dashed
EndProcedure

; ********************
; EXAMPLE @ eddy
; ********************

Procedure CustomGripPaint(bx, by, bw, bh, vertical, focus)
   Protected foreColor
   Protected backColor
   foreColor+(#True And focus=0)*#White
   foreColor+(#True And focus>0)*#Red
   
   ;background rectangle
   Box(bx, by, bw, bh, foreColor)
   
   If vertical
      ;borders
      Line(bx, by+0, bw, 0, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx, by+1, bw, 0, GetSysColor_(#COLOR_BTNHILIGHT))
      Line(bx, by+bh-2, bw, 0, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx, by+bh-1, bw, 0, GetSysColor_(#COLOR_BTNHILIGHT))
      
      ;dots
      For dy=10 To bh-10 Step 3
         Line(bx+bw/2-1, by+dy, 2, 0, GetSysColor_(#COLOR_BTNSHADOW))
      Next
   Else
      ;borders
      Line(bx+0, by, 0, bh, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx+1, by, 0, bh, GetSysColor_(#COLOR_BTNHILIGHT))
      Line(bx+bw-2, by, 0, bh, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx+bw-1, by, 0, bh, GetSysColor_(#COLOR_BTNHILIGHT))
      
      ;dots
      For dx=10 To bw-10 Step 3
         Line(bx+dx, by+bh/2-1, 0, 2, GetSysColor_(#COLOR_BTNSHADOW))
      Next
   EndIf
EndProcedure

If OpenWindow(0, 0, 0, 410, 440, "Dashed SplitterGadget And Auto Snap-To-Border", #PB_Window_SizeGadget | #PB_Window_SystemMenu)
   CompilerIf #PB_Compiler_Version<430
      CreateGadgetList(WindowID(0))
   CompilerEndIf
   ButtonGadget(300, 5, 5, 80, 20, "SWAP")
   
   ContainerGadget(800, 0, 0, 0, 0, #PB_Container_Double) : CloseGadgetList()
   ContainerGadget(801, 0, 0, 0, 0, #PB_Container_Double) : CloseGadgetList()
   SplitterGadgetPlus(3, 5, 30, 0, 0, 800, 801, #PB_Splitter_FirstFixed)
   SetGadgetAttribute(3, #PB_Splitter_FirstMinimumSize, 10)
   SetGadgetAttribute(3, #PB_Splitter_SecondMinimumSize, 10)
   DashedSplitterGrip(3, 200);(3, 200, @CustomGripPaint())
   DashedSplitterThickness(3, 8)
   SnapSplitterDistance(3, 50, 100)
   SnapSplitterDoubleClick(3, #True)
EndIf

If OpenWindow(1, 220, 220, 410, 440, "SplitterGadget : enable / disable options", #PB_Window_SizeGadget | #PB_Window_SystemMenu)
   CompilerIf #PB_Compiler_Version<430
      CreateGadgetList(WindowID(1))
   CompilerEndIf
   CheckBoxGadget(100, 5, 5, 80, 20, "LOCKED")
   CheckBoxGadget(101, 100, 5, 80, 20, "DASHED")
   CheckBoxGadget(102, 200, 5, 120, 20, "SNAP-TO-BORDER")
   SetGadgetState(100, #False)
   SetGadgetState(101, #True)
   SetGadgetState(102, #True)
   
   ContainerGadget(700, 0, 0, 0, 0, #PB_Container_Double) : CloseGadgetList()
   ContainerGadget(701, 0, 0, 0, 0, #PB_Container_Double) : CloseGadgetList()
   SplitterGadgetPlus(6, 5, 30, 0, 0, 700, 701, #PB_Splitter_Vertical | #PB_Splitter_Separator | #PB_Splitter_FirstFixed, #True)
   SnapSplitterDistance(6, 90, 90)
EndIf

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         End
      Case #PB_Event_SizeWindow
         Select EventWindow()
            Case 0
               ResizeGadget(3, #PB_Ignore, #PB_Ignore, WindowWidth(0)-10, WindowHeight(0)-40)
            Case 1
               ResizeGadget(6, #PB_Ignore, #PB_Ignore, WindowWidth(1)-10, WindowHeight(1)-40)
         EndSelect
      Case #PB_Event_Gadget
         Select EventType()
            Case #PB_EventType_LeftDoubleClick
               If EventGadget()=3
                  Debug "Double-Click"
               EndIf
            Case #PB_EventType_LeftClick
               Select EventGadget()
                  Case 300
                     SwapSplitter(3)
                  Case 100
                     LockSplitter(6, GetGadgetState(100))
                  Case 101
                     DashedSplitterMode(6, GetGadgetState(101))
                  Case 102
                     SnapSplitterDistance(6, 90*GetGadgetState(102), 90*GetGadgetState(102))
               EndSelect
         EndSelect
   EndSelect
ForEver
Last edited by eddy on Thu Nov 13, 2008 9:52 pm, edited 38 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

- ADDED : dashed option
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

This works great! Thanks. :D
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

DoubleDutch wrote:This works great! Thanks. :D
:D

Updated :
- SwapSplitterGadgetPlus can swap fixed gadget attribute ( #PB_Splitter_FirstFixed <-> #PB_Splitter_SecondFixed )
Added :
- SnapSplitterGadgetPlus
- DashedSplitterGadgetPlus
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Added :
- Double-Click Event #PB_EventType_LeftDoubleClick
- AutoSnapSplitterGadgetPlus ( double-click to snap to fixed gadget's border )

Code: Select all

SplitterGadgetPlus(3, 5, 30, 400, 400, 1, 2, #PB_Splitter_FirstFixed)
AutoSnapSplitterGadgetPlus(3, #True); ---> double-click to snap the first gadget's border 
Last edited by eddy on Mon Aug 04, 2008 11:12 pm, edited 7 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Great stuff! :D
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Fixed
- SwapSplitterGadgetPlus : AutoSnap support
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Added
- Unsnap ( restore collapsed panel by mouse-click )

Fixed
- fix pixel slide for unsnap
- fix swapSplitterGadgetPlus for multi-windows application
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Added
- grip button
- grip painter


Here is a custom painter :

Code: Select all

Procedure GripPaint(bx, by, bw, bh, vertical, focus)
   Protected foreColor
   Protected backColor
   foreColor+(#True And focus=0)*#White 
   foreColor+(#True And focus>0)*#Red
   
   ;background rectangle
   Box(bx, by, bw, bh, foreColor)
   
   If vertical
      ;borders
      Line(bx, by+0, bw, 0, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx, by+1, bw, 0, GetSysColor_(#COLOR_BTNHILIGHT))
      Line(bx, by+bh-2, bw, 0, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx, by+bh-1, bw, 0, GetSysColor_(#COLOR_BTNHILIGHT))
      
      ;dots
      For dy=10 To bh-10 Step 3
         Line(bx+bw/2-1, by+dy, 2, 0, GetSysColor_(#COLOR_BTNSHADOW))
      Next
   Else
      ;borders
      Line(bx+0, by, 0, bh, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx+1, by, 0, bh, GetSysColor_(#COLOR_BTNHILIGHT))
      Line(bx+bw-2, by, 0, bh, GetSysColor_(#COLOR_BTNSHADOW))
      Line(bx+bw-1, by, 0, bh, GetSysColor_(#COLOR_BTNHILIGHT))
      
      ;dots
      For dx=10 To bw-10 Step 3
         Line(bx+dx, by+bh/2-1, 0, 2, GetSysColor_(#COLOR_BTNSHADOW))
      Next
   EndIf
EndProcedure

Code: Select all

DashedSplitterGrip(3, 100,@GripPaint())
Last edited by eddy on Sat Aug 16, 2008 4:55 pm, edited 1 time in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Added
- cursor shape changes if grip button is detected

Fixed
- restore grip color after click
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Whole source code (my old dirty codes 8) ) from PB3.94 has been rewritten in PB4.20

released v1.0
- changed : function names
- added : bar thickness option
- fixed : SwapSplitter ( grip & thickness support )
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

The GadgetOutput variable has a conlict with another libraray, this would fix it:

Code: Select all

               Dim dsGadgetOutput(4)
               dsGadgetOutput(0)=1             ;Type.l
               dsGadgetOutput(1)=GadgetID(ID)  ;Win.l
               dsGadgetOutput(2)=0             ;DC.l
               dsGadgetOutput(3)=0             ;ReleaseProc.l
               
               StartDrawing(dsGadgetOutput())
Otherwise, great stuff! :D
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

v1.1 updated code for PB 4.30b1
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

v1.2 updated
- LockSplitter : lock splitter bar ( unlock if #FALSE )
- SplitterLocked : returns #TRUE if locked
- SplitterDashed : returns #TRUE if dashed

purrfect :twisted:
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
dige
Addict
Addict
Posts: 1405
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Post by dige »

Since PB4.40 all the GadgetOutput () functions does not working
any more.
Post Reply