;//
;// Name : Splitter Control
;// Desc : BlitzPlus extension,
;// A Splitter can simultaniously scale 2 controls,
;// By simply dragging the splitter back and forth.
;// It serves for resizing purposes, and can be applied for
;// Both horizontal and vertical resizing.
;// Author : Jim Teeuwen / Defiance
;// http://www.transmuter.nl :: blitz@transmuter.nl
;//
;// (c) 2002-2004, Jim Teeuwen. All rights reserved.
;//
Type Splitter
Field Gadget
Field FirstControl, SecondControl
Field Alignment
Field Group
Field Size
Field Canvas
End Type
Const SPLITTER_ALIGN_VERTICAL = 0
Const SPLITTER_ALIGN_HORIZONTAL = 1
Function CreateSplitter.Splitter(Group, PrimaryGadget, SecundaryGadget, Alignment = SPLITTER_ALIGN_VERTICAL, Size = 3)
spl.Splitter = New Splitter
splFirstControl = PrimaryGadget
splSecondControl = SecundaryGadget
splAlignment = Alignment
splGroup = Group
splSize = Size
splGadget = CreatePanel(0, 0, splSize, ClientHeight(Group), Group, 0)
If(splAlignment = SPLITTER_ALIGN_VERTICAL) Then
SetGadgetLayout(splgadget, 1, 1, 1, 1)
Else
SetGadgetLayout(splgadget, 1, 1, 0, 0)
End If
splCanvas = CreateCanvas(0, 0, GadgetWidth(splGadget), GadgetHeight(splGadget), splGadget)
SetGadgetLayout(splCanvas, 1, 1, 1, 1)
SetBuffer(CanvasBuffer(splCanvas))
Color(100, 100, 112)
Rect(0, 0, GadgetWidth(splGadget), GadgetHeight(splGadget))
UpdateSplitter(spl)
If(splSecondControl <> 0) Then
If(splAlignment = SPLITTER_ALIGN_VERTICAL) Then
SetGadgetShape(splSecondControl, GadgetX(splSecondControl) + splSize, GadgetY(splSecondControl), GadgetWidth(splSecondControl) - splSize, GadgetHeight(splSecondControl))
Else
SetGadgetShape(splSecondControl, GadgetX(splSecondControl), GadgetY(splSecondControl) + splSize, GadgetWidth(splSecondControl), GadgetHeight(splSecondControl) - splSize)
End If
End If
Return spl
End Function
Function UpdateSplitter(spl.Splitter)
If(splFirstControl = 0) Then
If(splAlignment = SPLITTER_ALIGN_VERTICAL) Then
SetGadgetShape(splGadget, 0, 0, splSize, ClientHeight(splGroup))
Else
SetGadgetShape(splGadget, 0, 0, ClientWidth(splGroup), 3)
End If
Else
If(splAlignment = SPLITTER_ALIGN_VERTICAL) Then
SetGadgetShape(splGadget, GadgetWidth(splFirstControl), GadgetY(splFirstControl), splSize, GadgetHeight(splFirstControl))
Else
SetGadgetShape(splGadget, GadgetX(splFirstControl), GadgetHeight(splFirstControl), GadgetWidth(splFirstControl), splSize)
End If
End If
End Function
Function SplitterEventLoop(spl.Splitter)
If(MouseDown(1)) Then
offsetX = EventX()
offsetY = EventY()
If(splAlignment = SPLITTER_ALIGN_VERTICAL) Then
If((GadgetWidth(splFirstControl) + offsetX) < (ClientWidth(splGroup) - splSize) And (GadgetWidth(splFirstControl) + offsetX) > 0) Then
SetGadgetShape(splFirstControl, GadgetX(splFirstControl), GadgetY(splFirstControl), (GadgetWidth(splFirstControl) + offsetX), GadgetHeight(splFirstControl))
SetGadgetShape(splGadget, GadgetWidth(splFirstControl), GadgetY(splFirstControl), splSize, GadgetHeight(splFirstControl))
SetGadgetShape(splSecondControl, GadgetX(splGadget) + splSize, GadgetY(splSecondControl), GadgetWidth(splSecondControl) - offsetX, GadgetHeight(splSecondControl))
End If
Else
If((GadgetHeight(splFirstControl) + offsetY) < (GadgetHeight(splGroup) - splSize) And (GadgetHeight(splFirstControl) + offsetY) > 0) Then
SetGadgetShape(splFirstControl, GadgetX(splFirstControl), GadgetY(splFirstControl), GadgetWidth(splFirstControl), (GadgetHeight(splFirstControl) + offsetX))
SetGadgetShape(splGadget, GadgetX(splFirstControl), GadgetHeight(splFirstControl), GadgetWidth(splFirstControl), splSize)
SetGadgetShape(splSecondControl, GadgetX(splSecondControl), (GadgetY(splGadget) + splSize), GadgetWidth(splSecondControl), GadgetHeight(splSecondControl) - offsetX)
End If
End If
End If
If(splAlignment = SPLITTER_ALIGN_VERTICAL) Then
SetCursor(LoadCursor(0, IDC_SIZEWE))
Else
SetCursor(LoadCursor(0, IDC_SIZENS))
End If
UpdateSplitter()
End Function
;// ### DEMO #####################################################################################
SplitterDemo()
Global mySplitter.Splitter
;/* Window Messages */
Const WM_MOUSEMOVE = $203
Const WM_RESIZE = $802
Const WM_CLOSE = $803
Const IDC_SIZENONE = 32641 ;// No Cursor
Const IDC_SIZENWSE = 32642 ;// Top left to bottom right
Const IDC_SIZENESW = 32643 ;// Top right to bottom left
Const IDC_SIZEWE = 32644 ;// Left to right
Const IDC_SIZENS = 32645 ;// Top to Bottom
Const IDC_SIZEMOVE = 32646 ;// Cross (4 directions)
Const IDC_SIZEDENIED = 32648 ;// Circle with diagonal Line
Const IDC_SIZEHAND = 32649 ;// Hand cursor
Const IDC_SIZEHOURGLASS = 32650 ;// Hourglass
Const IDC_SIZEHELP = 32651 ;// QuestionMark
Const IDC_SIZEMOVENS = 32652 ;// Move Top to Bottom
Const IDC_SIZEMOVEWE = 32653 ;// Move Left to right
Const IDC_SIZEMOVENSEW = 32654 ;// Move 4 directions
Const IDC_SIZEMOVEN = 32655 ;// Move Up
Const IDC_SIZEMOVES = 32656 ;// Move Down
Const IDC_SIZEMOVEW = 32657 ;// Move Left
Const IDC_SIZEMOVEE = 32658 ;// Move Right
Const IDC_SIZEMOVENW = 32659 ;// Move Top Left
Const IDC_SIZEMOVENE = 32660 ;// Move Top Right
Const IDC_SIZEMOVESW = 32661 ;// Move Bottom Left
Const IDC_SIZEMOVESE = 32662 ;// Move Bottom Right
Const IDC_SIZECD = 32663 ;// CD loading Icon
Function SplitterDemo()
;// Create a new form with some panels on it.
;// We will use the splitter control to be able to resize these panels
;// at runtime. The splitter will appear as a darkgray 3-pixel wide line between 2 panels
;// To use it., simply click on the splitter and drag it left/right(vertically aligned splitter)
;// or up/down (horizontally aligned Splitter)
;/* frmMain */
frmMain = CreateWindow("UI Test", 20, 20, ClientWidth(Desktop()) - 40, ClientHeight(Desktop()) - 40, 0)
SetMinWindowSize(frmMain, 320, 240)
SetGadgetText(frmMain, "Splitter Control Demo")
;/* Workspace */
pnlWorkSpace = CreatePanel(0, 0, ClientWidth(frmMain) - 193, ClientHeight(frmMain) , frmMain, 0)
SetGadgetLayout(pnlWorkSpace, 1, 1, 1, 1)
SetGadgetText(pnlWorkSpace, "WorkSpace")
SetPanelColor(pnlWorkSpace, 136, 147, 158)
;/* pnlProperties *.
pnlProperties = CreatePanel(GadgetWidth(frmMain) - 200, 0, 200, GadgetHeight(frmMain), frmMain, 0)
SetGadgetLayout(pnlProperties, 0, 1, 1, 1)
SetGadgetText(pnlProperties, "Properties")
trvProject = CreateTreeView(0, 0, GadgetWidth(pnlProperties) - 8, GadgetHeight(pnlProperties) / 3, pnlProperties)
SetGadgetLayout(trvProject, 1, 1, 1, 0)
;/* Splitter */
;// Here we create the splitter.
;// This splitter will 'split' the 2 panels 'pnlWorkSpace' and 'pnlProperties'
;// Normally we would add this splitter gadget after the first panel, but we need a valid
;// reference to the second Properties panel for this to work. Thus, we create the splitters
;// AFTER ALL THE PANELS ARE CREATED!
;// This splitter will be Vertically aligned
;// Calling the create method takes a few parameters:
;//
;// spl = CreateSplitter(group, firstControl, secondControl, alignment)
;//
;// group : This is the group to wich the splitter is added. works the same as
;// adding a normal gadget.
;// firstControl : This is the first gadget to wich the splitter will apply.
;// In our case this is 'pnlWorkSpace'
;// secondControl : Naturally, this is the second gadget to wich the splitter applies
;// You see now why we need to wait with splitter creation till ALL
;// the regular controls have been initialised.
;// Alignment : This is the splitter alignment. Can be either SPLITTER_ALIGN_VERTICAL (default),
;// or SPLITTER_ALIGN_HORIZONTAL. WIth the Vertical splitter, your 2 gadgets
;// to wich it applies should be left/right of eachother
;// With the Horizontal splitter, your 2 gadgets to wich the splitter applies
;// should be above/underneath eachother.
;//
;// You do not have to care about the positioning of the 2 gadgets, this will all be handled
;// by the Splitter code.
mySplitter.Splitter = CreateSplitter(frmMain, pnlWorkSpace, pnlProperties, SPLITTER_ALIGN_VERTICAL)
;// now we enter the main eventloop for the form and check for messages
;// The messages we want to handle for the splitter are:
;// WM_RESIZE and WM_MOUSEMOVE
Repeat
Select(WaitEvent())
Case WM_CLOSE ;// $803 Form close event
End
Case WM_RESIZE ;// $802
;// Update the splitter
UpdateSplitter(mySplitter)
Case WM_MOUSEMOVE ;// $203
;// Handle the movement
;// Note that only the Canvas gadget will detect MouseMove events, so I
;// added a special Canvas that streches the entire surface of the splitter
;// This will detect the Mouseevents for us. we have to determine here of the
;// mousemove event was fired by our splitter
Select(EventSource())
Case mySplitterCanvas
SplitterEventLoop(mySplitter)
End Select
End Select
Forever
;// Ready! Now start the app and notice the small darkgray line between the 2 panels
;// just click on it and drag the line Left/right while holding the mousebutton to see
;// the Splitter in action!
End Function