Code archives/BlitzPlus Gui/Modified Splitter proxy gadget
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Changes: -Splitter handle is much narrower -Removed lines on splitter handle -Splitter will emit a window size event when resized. This is useful if any gadgets in the splitter panels need to be resized when the splitter changes. | |||||
SuperStrict Import MaxGUI.MaxGUI Private Function GadgetWindow:TGadget(gadget:TGadget) While gadget If gadgetclass(gadget)=GADGET_WINDOW Return gadget gadget=gadgetgroup(gadget) Wend EndFunction Public ' TSplitter Proxy Gadget ' Author: Seb Hollington Rem bbdoc: Creates a gadget consisting of two panels separated by a draggable divider. about: A splitter is made up of two panels: a main panel (identified using SPLITPANEL_MAIN) which acts as the main working area; and a side pane (identified using SPLITPANEL_SIDEPANE) which is typically used to display additional information. Both of these panels are contained within a parent panel that is represented by the @TSplitter instance. The two panels are separated by a split handle/divider, the behavior of which can be queried and altered using the #SplitterBehavior and #SetSplitterBehavior functions respectively. The size of the split handle is determined using the optional @pHandleSize parameter. The default size of 10 pixels should work well in most situations, and the minimum value that this can be is 4. After creating a splitter gadget, you can start adding gadgets to it by retrieving the appropriate panel with the #SplitterPanel command. The @TSplitter type instance can be used with most of the standard MaxGUI commands, allowing you to change the properties of the entire splitter gadget. There are, however, a few exceptions: #SetGadgetSensitivity and #GadgetSensitivity will have no effect on the splitter gadget. If you want to use active panels, create your own sub-panel within each splitter panel. #SetGadgetTooltip and #GadgetTooltip will set/retrieve a tooltip for when the user is hovering over the splitter handle/divider. #SetGadgetColor will modify the split handle/divider background color. See Also: #SplitterPanel, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. End Rem Function CreateSplitter:TSplitter( pX%, pY%, pW%, pH%, pParent:TGadget, pOrientation% = SPLIT_VERTICAL, pHandleSize% = 10 ) Return New TSplitter.Create( pX, pY, pW, pH, pParent, pOrientation, pHandleSize ) EndFunction Const SPLITPANEL_MAIN% = 0, SPLITPANEL_SIDEPANE% = 1, SPLITPANEL_HANDLE% = 2 Rem bbdoc: Retrieves either one of the two panels which make up a TSplitter gadget. about: This function is used to return a standard MaxGUI panel that you can add your gadgets to. The panels available are SPLITPANEL_MAIN and SPLITPANEL_SIDEPANE. See #CreateSplitter for more information about the differences between the two panels. See Also: #CreateSplitter, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. End Rem Function SplitterPanel:TGadget( splitter:TSplitter, panel% = SPLITPANEL_MAIN ) Return splitter.GetPanel(panel) EndFunction Rem bbdoc: Sets the position of the splitter (in pixels) from the edge of a TSplitter gadget. about: This function's most common use is to restore a split position previously returned by #SplitterPosition. The optional @save% parameter determines whether or not the position supplied is restored when the splitter returns from it's hidden state. In most circumstances, this should be left as #True. See Also: #CreateSplitter, #SplitterPanel, #SplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. End Rem Function SetSplitterPosition( splitter:TSplitter, position%, save% = True ) splitter.SetPanelSpace( position, save ) EndFunction Rem bbdoc: Returns the position of the splitter (in pixels) from the edge of a TSplitter gadget. about: This function's most common use is probably for saving the current splitter position to restore at a later time using #SetSplitterPosition. See Also: #CreateSplitter, #SplitterPanel, #SetSplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. End Rem Function SplitterPosition:Int( splitter:TSplitter ) Return splitter.GetPanelSpace( SPLITPANEL_SIDEPANE ) EndFunction Const SPLIT_HORIZONTAL% = 0, SPLIT_VERTICAL% = 1, SPLIT_FLIPPED% = 2 Rem bbdoc: Sets the splitter orientation. about: The two orientations available are (both of which can be combined with SPLIT_FLIPPED): [ @Orientation | @Description * -1 | Toggles the SPLIT_FLIPPED flag. * SPLIT_VERTICAL | The splitter consists of a main left panel with a side-pane along the right edge. * SPLIT_HORIZONTAL | The splitter consists of a main top panel with a side-pane along the bottom edge. * SPLIT_VERTICAL ~| SPLIT_FLIPPED | The splitter consists of a main right panel with a side-pane along the left edge. * SPLIT_HORIZONTAL ~| SPLIT_FLIPPED | The splitter consists of a main bottom with a side-pane along the top edge. ] See Also: #CreateSplitter, #SplitterPanel, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior and #SplitterOrientation. End Rem Function SetSplitterOrientation( splitter:TSplitter, orientation% = -1 ) splitter.ChangeOrientation( orientation ) EndFunction Rem bbdoc: Returns the orientation of the splitter. about: The two orientations available are (both of which can be combined with SPLIT_FLIPPED): [ @Orientation | @Description * SPLIT_VERTICAL | The splitter consists of a main left panel with a side-pane along the right edge. * SPLIT_HORIZONTAL | The splitter consists of a main top panel with a side-pane along the bottom edge. * SPLIT_VERTICAL ~| SPLIT_FLIPPED | The splitter consists of a main right panel with a side-pane along the left edge. * SPLIT_HORIZONTAL ~| SPLIT_FLIPPED | The splitter consists of a main bottom with a side-pane along the top edge. ] See Also: #CreateSplitter, #SplitterPanel, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior and #SetSplitterOrientation. End Rem Function SplitterOrientation:Int( splitter:TSplitter ) Return splitter.GetOrientation() EndFunction Const SPLIT_RESIZABLE% = %1, SPLIT_LIMITPANESIZE% = %10, SPLIT_CANFLIP% = %100, SPLIT_CANORIENTATE% = %1000, SPLIT_CLICKTOTOGGLE% = %100000, SPLIT_ALL% = -1 Rem bbdoc: Sets the behavior of a splitter. about: Any combination of the following are available: [ @{Behavior Flag} | @Description * 0 | The splitter does none of the actions listed below. * SPLIT_RESIZABLE | The splitter can be resized by dragging. * SPLIT_LIMITPANESIZE | The splitter side-pane is not allowed to take up more than half the splitted dimensions. * SPLIT_CANFLIP | The splitter can switch between opposite edges by dragging to the edge. * SPLIT_CANORIENTATE | The splitter can switch between vertical and horizontal modes by dragging to right/bottom edges. * SPLIT_CLICKTOTOGGLE | The splitter will hide/show when the drag-bar is clicked. * SPLIT_ALL | A shorthand flag for representing all of the above. ] The default behavior of a splitter is SPLIT_ALL&~~SPLIT_LIMITPANESIZE (i.e. everything but SPLIT_LIMITPANESIZE). See Also: #CreateSplitter, #SplitterPanel, #SplitterPosition, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. End Rem Function SetSplitterBehavior( splitter:TSplitter, flags%=SPLIT_ALL ) splitter.SetBehavior( flags ) EndFunction Rem bbdoc: Returns the value previously set using #SetSplitterBehavior. returns: An integer composed of a combination of bitwise flags that describe the behavior of the splitter. about: See #SetSplitterBehavior for more information. End Rem Function SplitterBehavior:Int( splitter:TSplitter ) Return splitter.GetBehavior() EndFunction Type TSplitter Extends TProxyGadget Const JUMP% = 200 ' SPLITPANEL_MAIN SPLITPANEL_SIDEPANE SPLITPANEL_HANDLE Global intOrientationLocks%[][][] = [[ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED] ], .. 'SPLIT_HORIZONTAL [ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED] ], .. 'SPLIT_VERTICAL [ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED] ], .. 'SPLIT_HORIZONTAL|SPLIT_FLIPPED [ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED] ]] 'SPLIT_VERTICAL|SPLIT_FLIPPED Field strToggleTooltip$ = "" Field intOrientation%, intMinPanelSpace% = 0, intSavePanelSpace% = 220, intBehavior% = 0, intGutterSize% Field intPanelSpace% = intMinPanelSpace, intMouseDown%[2], intHasMoved% = False, intShouldUpdate% = False Field pnlPanes:TGadget[] Field pnlSplitHandle:TGadget, divSplitHandle1:TGadget, divSplitHandle2:TGadget Field gadParent:TGadget Field pixHandle:TPixmap[] = [TPixmap(Null), TPixmap(Null)] Method Create:TSplitter( pX%, pY%, pW%, pH%, pParent:TGadget, pOrientation% = SPLIT_VERTICAL, pHandleSize% = 2 ) gadParent = CreatePanel(pX, pY, pW, pH, pParent);SetProxy( gadParent ) intGutterSize = 3'Max(pHandleSize, 4) DrawHandle();DrawPanes();ChangeOrientation(pOrientation) SetBehavior(SPLIT_ALL&~SPLIT_LIMITPANESIZE) AddHook EmitEventHook, eventHandler, Self, -1 Return Self EndMethod 'Interface Method GetOrientation:Int() Return intOrientation EndMethod Method SetOrientation(pOrientation%) ChangeOrientation(pOrientation) EndMethod Method SetBehavior( pBehavior% ) intBehavior = pBehavior If (intBehavior&SPLIT_CLICKTOTOGGLE) Then If strToggleTooltip Then SetGadgetToolTip(pnlSplitHandle,strToggleTooltip) Else If strToggleTooltip Then SetGadgetToolTip(pnlSplitHandle,"") EndIf EndMethod Method GetBehavior%() Return intBehavior EndMethod Method GetPanel:TGadget(pPane%) Return pnlPanes[pPane] EndMethod Method GetPanelSpace%(pPane%) Select pPane Case SPLITPANEL_SIDEPANE Return intPanelSpace Case SPLITPANEL_MAIN If intOrientation&SPLIT_VERTICAL Then Return (ClientWidth()-intPanelSpace-intGutterSize) Else Return (ClientHeight()-intPanelSpace-intGutterSize) EndIf EndSelect EndMethod Method SetPanelSpace( pPanelSpace%, flgSave% = True ) Local tmpOldPanelSpace% = intPanelSpace If (intBehavior & SPLIT_LIMITPANESIZE) Then pPanelSpace = Min(pPanelSpace, [ClientHeight(), ClientWidth()][intOrientation&SPLIT_VERTICAL] Shr 1) EndIf pPanelSpace = Max(pPanelSpace, intMinPanelSpace) intPanelSpace = pPanelSpace If GetPanelSpace(SPLITPANEL_MAIN) < intMinPanelSpace Then intPanelSpace = tmpOldPanelSpace If flgSave And intPanelSpace > Min(intGutterSize,intMinPanelSpace) Then intSavePanelSpace = intPanelSpace DrawHandle();DrawPanes() EndMethod 'Proxy Gadget Methods Method CleanUp() RemoveHook EmitEventHook, eventHandler, Self gadParent = Null Super.CleanUp() EndMethod Method SetTooltip%( pTooltip$ ) strToggleTooltip = "" divSplitHandle1.SetTooltip( pTooltip ) divSplitHandle2.SetTooltip( pTooltip ) Return pnlSplitHandle.SetTooltip( pTooltip ) EndMethod Method GetTooltip$() Return pnlSplitHandle.GetTooltip() EndMethod Method SetTextColor%( pRed%, pGreen%, pBlue%) pixHandle[0] = MakeColourHandlePixmap( pRed, pGreen, pBlue, intGutterSize ) If intOrientation & SPLIT_VERTICAL Then pixHandle[0] = RotatePixmap(pixHandle[0]) pixHandle[1] = BrightenPixmap(pixHandle[0]) HideGadget(divSplitHandle1);HideGadget(divSplitHandle2) 'SetPanelPixmap(pnlSplitHandle, pixHandle[0]) EndMethod Method SetColor%( pRed%, pGreen%, pBlue%) Return SetGadgetColor( pnlSplitHandle, pRed, pGreen, pBlue, True ) EndMethod Method SetSensitivity%(pSensitivity%) Return 0 EndMethod Method GetSensitivity%() Return 0 EndMethod 'Internal Methods Method ReapplyLocks() Local tmpLocks%[][] = intOrientationLocks[intOrientation] If pnlPanes And pnlPanes.length > 1 Then SetGadgetLayout( pnlPanes[SPLITPANEL_MAIN], tmpLocks[SPLITPANEL_MAIN][0], tmpLocks[SPLITPANEL_MAIN][1], tmpLocks[SPLITPANEL_MAIN][2], tmpLocks[SPLITPANEL_MAIN][3] ) SetGadgetLayout( pnlPanes[SPLITPANEL_SIDEPANE], tmpLocks[SPLITPANEL_SIDEPANE][0], tmpLocks[SPLITPANEL_SIDEPANE][1], tmpLocks[SPLITPANEL_SIDEPANE][2], tmpLocks[SPLITPANEL_SIDEPANE][3] ) EndIf If pnlSplitHandle Then SetGadgetLayout( pnlSplitHandle, tmpLocks[SPLITPANEL_HANDLE][0], tmpLocks[SPLITPANEL_HANDLE][1], tmpLocks[SPLITPANEL_HANDLE][2], tmpLocks[SPLITPANEL_HANDLE][3] ) EndMethod Const SPLITSIDE_LEFT% = 0, SPLITSIDE_RIGHT% = 1, SPLITSIDE_TOP% = 0, SPLITSIDE_BOTTOM% = 1 Global intSideToPanelMapping%[][] = [[ SPLITPANEL_MAIN, SPLITPANEL_SIDEPANE ], .. 'SPLIT_HORIZONTAL [ SPLITPANEL_MAIN, SPLITPANEL_SIDEPANE ], .. 'SPLIT_VERTICAL [ SPLITPANEL_SIDEPANE, SPLITPANEL_MAIN ], .. 'SPLIT_HORIZONTAL|SPLIT_FLIPPED [ SPLITPANEL_SIDEPANE, SPLITPANEL_MAIN ]] 'SPLIT_VERTICAL|SPLIT_FLIPPED Method GetSideSpace%( pSide% ) Return GetPanelSpace(intSideToPanelMapping[intOrientation][pSide]) EndMethod Method DrawHandle() Local tmpDimensions%[] '0: X, 1: Y, 2: W, 3: H Select intOrientation&SPLIT_VERTICAL Case SPLIT_HORIZONTAL;tmpDimensions = [0, GetSideSpace(SPLITSIDE_TOP), ClientWidth(), intGutterSize] Case SPLIT_VERTICAL;tmpDimensions = [GetSideSpace(SPLITSIDE_LEFT), 0, intGutterSize, ClientHeight()] EndSelect If pnlSplitHandle Then SetGadgetShape(pnlSplitHandle, tmpDimensions[0], tmpDimensions[1], tmpDimensions[2], tmpDimensions[3]) Select intOrientation&SPLIT_VERTICAL Case SPLIT_HORIZONTAL SetGadgetShape( divSplitHandle1,0,Ceil(tmpDimensions[3]/2.0)-2,tmpDimensions[2],2 ) SetGadgetShape( divSplitHandle2,0,Ceil(tmpDimensions[3]/2.0),tmpDimensions[2],2 ) Case SPLIT_VERTICAL SetGadgetShape( divSplitHandle1,Ceil(tmpDimensions[2]/2.0)-2,0,2,tmpDimensions[3] ) SetGadgetShape( divSplitHandle2,Ceil(tmpDimensions[2]/2.0),0,2,tmpDimensions[3] ) EndSelect If pixHandle[0] Then HideGadget(divSplitHandle1) HideGadget(divSplitHandle2) Else ShowGadget(divSplitHandle1) ShowGadget(divSplitHandle2) EndIf Else pnlSplitHandle = CreatePanel(tmpDimensions[0], tmpDimensions[1], tmpDimensions[2], tmpDimensions[3], gadParent, PANEL_ACTIVE) 'SetPanelPixmap( pnlSplitHandle, pixHandle[0]);SetGadgetToolTip(pnlSplitHandle,strToggleTooltip) Select intOrientation&SPLIT_VERTICAL Case SPLIT_HORIZONTAL divSplitHandle1 = CreateLabel("",0,Ceil(tmpDimensions[3]/2.0)-2,tmpDimensions[2],2,pnlSplitHandle)',LABEL_SEPARATOR) divSplitHandle2 = CreateLabel("",0,Ceil(tmpDimensions[3]/2.0),tmpDimensions[2],2,pnlSplitHandle)',LABEL_SEPARATOR) Case SPLIT_VERTICAL divSplitHandle1 = CreateLabel("",Ceil(tmpDimensions[2]/2.0)-2,0,2,tmpDimensions[3],pnlSplitHandle)',LABEL_SEPARATOR) divSplitHandle2 = CreateLabel("",Ceil(tmpDimensions[2]/2.0),0,2,tmpDimensions[3],pnlSplitHandle)',LABEL_SEPARATOR) EndSelect SetGadgetSensitivity(divSplitHandle1,SENSITIZE_MOUSE);SetGadgetSensitivity(divSplitHandle2,SENSITIZE_MOUSE) ?Win32 DisableGadget( divSplitHandle1 );DisableGadget( divSplitHandle2 ) ? SetGadgetToolTip( divSplitHandle1, strToggleTooltip );SetGadgetToolTip( divSplitHandle2, strToggleTooltip ) SetGadgetLayout( divSplitHandle1, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) SetGadgetLayout( divSplitHandle2, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) If pixHandle[0] Then HideGadget(divSplitHandle1);HideGadget(divSplitHandle2) EndIf EndMethod Method DrawPanes() Local tmpDimensions%[][] '0: X, 1: Y, 2: W, 3: H Select intOrientation&SPLIT_VERTICAL Case SPLIT_HORIZONTAL tmpDimensions = [[0, 0, ClientWidth(), GetSideSpace(SPLITSIDE_TOP)], [0, GetSideSpace(SPLITSIDE_TOP)+intGutterSize, ClientWidth(), GetSideSpace(SPLITSIDE_BOTTOM)]] Case SPLIT_VERTICAL tmpDimensions = [[0,0,GetSideSpace(SPLITSIDE_LEFT),ClientHeight()], [GetSideSpace(SPLITSIDE_LEFT)+intGutterSize,0,GetSideSpace(SPLITSIDE_RIGHT),ClientHeight()]] EndSelect If intOrientation & SPLIT_FLIPPED Then tmpDimensions = [tmpDimensions[1],tmpDimensions[0]] If pnlPanes.length <> 2 Then pnlPanes = [CreatePanel(0,0,1,1,gadParent,0), CreatePanel(0,0,1,1,gadParent,0)] ReapplyLocks() EndIf SetGadgetShape(pnlPanes[SPLITPANEL_MAIN], tmpDimensions[SPLITPANEL_MAIN][0], tmpDimensions[SPLITPANEL_MAIN][1], tmpDimensions[SPLITPANEL_MAIN][2], tmpDimensions[SPLITPANEL_MAIN][3]) SetGadgetShape(pnlPanes[SPLITPANEL_SIDEPANE], tmpDimensions[SPLITPANEL_SIDEPANE][0], tmpDimensions[SPLITPANEL_SIDEPANE][1], tmpDimensions[SPLITPANEL_SIDEPANE][2], tmpDimensions[SPLITPANEL_SIDEPANE][3]) EndMethod Method ChangeOrientation(pOrientation% = -1) If pOrientation = intOrientation Then Return If pOrientation < 0 Then intOrientation:~SPLIT_FLIPPED Else If pixHandle[0] And intOrientation&SPLIT_VERTICAL <> pOrientation&SPLIT_VERTICAL Then pixHandle[0] = RotatePixmap(pixHandle[0]);pixHandle[1] = RotatePixmap(pixHandle[1]) EndIf intOrientation = pOrientation EndIf 'SetPanelPixmap(pnlSplitHandle, pixHandle[0]) DrawHandle();DrawPanes();ReapplyLocks();RedrawGadget(gadParent) EndMethod Method Toggle() If intPanelSpace > intMinPanelSpace Then SetPanelSpace( intMinPanelSpace ) Else SetPanelSpace( intSavePanelSpace ) EndMethod Method eventHook:Object( pID%, pData:Object ) Local tmpEvent:TEvent = TEvent(pData) If (Not tmpEvent) Or (Not TGadget(tmpEvent.source)) Then Return pData Select tmpEvent.source Case pnlSplitHandle, divSplitHandle1, divSplitHandle2 If (tmpEvent.source = divSplitHandle1) Or (tmpEvent.source = divSplitHandle2) Then tmpEvent.x:+GadgetX(TGadget(tmpEvent.source)) tmpEvent.y:+GadgetY(TGadget(tmpEvent.source)) tmpEvent.source = pnlSplitHandle EndIf Select tmpEvent.id Case EVENT_MOUSEDOWN If (tmpEvent.data <> MOUSE_LEFT) Then Return Null intMouseDown = [tmpEvent.x, tmpEvent.y] intHasMoved = False Case EVENT_MOUSEMOVE intHasMoved = True If tmpEvent.data Then If intMouseDown Or (tmpEvent.data = MOUSE_LEFT And intShouldUpdate) Then EmitEvent CreateEvent(EVENT_WINDOWSIZE,GadgetWindow(Self)) 'Update our mouse pointer and re-set our drag-point (if needed). ShowDragPointer() If intShouldUpdate Or Not intMouseDown Then intMouseDown = [tmpEvent.x,tmpEvent.y] intShouldUpdate = False EndIf 'New values that are updated once everything has been checked Local tmpOrientation% = GetOrientation(), tmpPanelSpace% = -1, tmpPanelSave% = False 'New size of panel if resized with mouse cursor Local tmpDraggedSpace% = -[tmpEvent.y-intMouseDown[1],tmpEvent.x-intMouseDown[0]][intOrientation&SPLIT_VERTICAL] If tmpOrientation&SPLIT_FLIPPED Then tmpDraggedSpace:*-1 tmpDraggedSpace:+intPanelSpace 'Update intPanelSpace if we can drag as any calls to GetPanelSpace() need to return an accurate value If (intBehavior&SPLIT_RESIZABLE) And tmpDraggedSpace <> intPanelSpace Then 'Simulate a snap-closed action for the splitter If tmpDraggedSpace < intGutterSize Then tmpDraggedSpace = intMinPanelSpace tmpPanelSpace = tmpDraggedSpace intPanelSpace = tmpDraggedSpace EndIf 'Limit the pane-size to half the client-area if SPLIT_LIMITPANESIZE is set. If (intBehavior&SPLIT_LIMITPANESIZE) Then Local tmpDimensions%[] = [ClientHeight(),ClientWidth()] If GetPanelSpace(SPLITPANEL_SIDEPANE) > (tmpDimensions[(tmpOrientation&SPLIT_VERTICAL)])/2 Then If (intBehavior&SPLIT_CANFLIP) Then tmpOrientation:~SPLIT_FLIPPED tmpPanelSpace = GetPanelSpace(SPLITPANEL_MAIN) Else tmpPanelSpace = (tmpDimensions[(tmpOrientation&SPLIT_VERTICAL)])/2 EndIf tmpPanelSave = True EndIf EndIf 'Update the splitter's orientation if needed. If (intBehavior&(SPLIT_CANORIENTATE|SPLIT_CANFLIP)) Then 'Drag test conditions Local tmpLeftCond% = (GadgetX(pnlSplitHandle)+tmpEvent.x < 1) Local tmpRightCond% = (GadgetX(pnlSplitHandle)+tmpEvent.x > ClientWidth()-intGutterSize) Local tmpTopCond% = (GadgetY(pnlSplitHandle)+tmpEvent.y < 1) Local tmpBottomCond% = (GadgetY(pnlSplitHandle)+tmpEvent.y > ClientHeight()-intGutterSize) Select True Case (tmpRightCond And Not (tmpTopCond|tmpBottomCond)), (tmpLeftCond And Not (tmpTopCond|tmpBottomCond)), .. (tmpBottomCond And Not (tmpLeftCond|tmpRightCond)), (tmpTopCond And Not (tmpLeftCond|tmpRightCond)) If (intBehavior&SPLIT_CANFLIP) Or ((tmpLeftCond|tmpTopCond)=(tmpOrientation&SPLIT_FLIPPED)) Then If (intBehavior&SPLIT_CANORIENTATE) Then If (tmpLeftCond|tmpRightCond) Then tmpOrientation:|SPLIT_VERTICAL Else tmpOrientation:&~SPLIT_VERTICAL Else Select (tmpOrientation&SPLIT_VERTICAL) Case SPLIT_VERTICAL;tmpTopCond = 0;tmpBottomCond = 0 Case SPLIT_HORIZONTAL;tmpLeftCond = 0;tmpRightCond = 0 EndSelect EndIf 'Let's determine whether our side-panel should be flipped or not. If (tmpLeftCond|tmpTopCond) Then tmpOrientation:|SPLIT_FLIPPED ElseIf (tmpRightCond|tmpBottomCond) Then tmpOrientation:&~SPLIT_FLIPPED 'If we are resizable and the orientation has changed, let's reset the side-pane size. If (intBehavior&SPLIT_RESIZABLE) And (tmpOrientation <> intOrientation) Then tmpPanelSpace = intMinPanelSpace;tmpPanelSave = True EndIf EndSelect EndIf 'Apply our newly calculated values to the splitter. If (tmpOrientation <> GetOrientation()) Then If (tmpOrientation&SPLIT_VERTICAL <> GetOrientation()&SPLIT_VERTICAL) Then intMouseDown = Null intShouldUpdate = True EndIf ChangeOrientation( tmpOrientation ) ShowActivePointer() EndIf If tmpPanelSpace > -1 Then SetPanelSpace( tmpPanelSpace, tmpPanelSave ) EndIf Else intMouseDown = Null EndIf Case EVENT_MOUSEUP If (intMouseDown And tmpEvent.data = MOUSE_LEFT) Then If Not intHasMoved Then If (intBehavior&SPLIT_CLICKTOTOGGLE) Then Toggle() Else SetPanelSpace( intPanelSpace, True ) EndIf intMouseDown = Null ShowNormalPointer() EndIf Case EVENT_MOUSELEAVE If (intBehavior&(SPLIT_RESIZABLE|SPLIT_CLICKTOTOGGLE)) Then 'SetPanelPixmap(pnlSplitHandle, pixHandle[0]) EndIf ShowNormalPointer() Case EVENT_MOUSEENTER If (intBehavior&(SPLIT_RESIZABLE|SPLIT_CLICKTOTOGGLE)) Then 'SetPanelPixmap(pnlSplitHandle, pixHandle[1]) EndIf ShowActivePointer() EndSelect Case pnlPanes[SPLITPANEL_MAIN], pnlPanes[SPLITPANEL_SIDEPANE], gadParent 'Don't show these events to the other hooks! Default Select tmpEvent.id Case EVENT_WINDOWSIZE If (intBehavior&SPLIT_RESIZABLE) And TGadget(tmpEvent.source).HasDescendant(gadParent) Then Local tmpLimit% = [ClientHeight(),ClientWidth()][intOrientation&SPLIT_VERTICAL] If (intBehavior&SPLIT_LIMITPANESIZE) Then tmpLimit:Shr 1 Else tmpLimit:-intGutterSize If GetPanelSpace(SPLITPANEL_SIDEPANE) > tmpLimit Then SetPanelSpace( tmpLimit, True ) EndIf EndSelect Return pData EndSelect EndMethod 'Mouse Cursor Function ShowNormalPointer() SetPointer(POINTER_DEFAULT) EndFunction Method ShowActivePointer() If (intBehavior&SPLIT_RESIZABLE) Then Select intOrientation&SPLIT_VERTICAL Case SPLIT_HORIZONTAL;SetPointer(POINTER_SIZENS) Case SPLIT_VERTICAL;SetPointer(POINTER_SIZEWE) EndSelect ElseIf (intBehavior&SPLIT_CLICKTOTOGGLE) Then SetPointer(POINTER_HAND) Else SetPointer(POINTER_DEFAULT) EndIf EndMethod Method ShowDragPointer() If (intBehavior&SPLIT_RESIZABLE) Then Select intOrientation&SPLIT_VERTICAL Case SPLIT_HORIZONTAL;SetPointer(POINTER_SIZENS) Case SPLIT_VERTICAL;SetPointer(POINTER_SIZEWE) EndSelect ElseIf (intBehavior&(SPLIT_CANFLIP|SPLIT_CANORIENTATE)) SetPointer(POINTER_SIZEALL) Else SetPointer(POINTER_DEFAULT) EndIf EndMethod 'Helper Functions Function eventHandler:Object( pID%, pData:Object, pContext:Object) If TSplitter(pContext) Then Return TSplitter(pContext).eventHook( pID, pData ) Else Return pData EndFunction Function RotatePixmap:TPixmap( pSrcPixmap:TPixmap ) Local tmpDestPixmap:TPixmap = CreatePixmap(pSrcPixmap.height, pSrcPixmap.width, pSrcPixmap.format) For Local y% = 0 Until pSrcPixmap.height For Local x% = 0 Until pSrcPixmap.width WritePixel( tmpDestPixmap, y, x, ReadPixel(pSrcPixmap, x, y) ) Next Next Return tmpDestPixmap EndFunction Function BrightenPixmap:TPixmap( pSrcPixmap:TPixmap, pBrightness# = 1.05 ) Local tmpDestPixmap:TPixmap = CreatePixmap(pSrcPixmap.width, pSrcPixmap.height, pSrcPixmap.format) For Local y% = 0 Until pSrcPixmap.height For Local x% = 0 Until pSrcPixmap.width WritePixel( tmpDestPixmap, x, y, BrightenPixel(ReadPixel(pSrcPixmap, x, y), pBrightness) ) Next Next Return tmpDestPixmap EndFunction Function BrightenPixel%( pARGB%, pBrightness# = 1.05 ) Local tmpHSV:TColorHSV = New TColorHSV.fromARGB(pARGB) tmpHSV.v=Min(tmpHSV.v*pBrightness,1) Return tmpHSV.toARGB() EndFunction Function WhitenPixel%( pARGB%, pWhiteness# = 0.8 ) Local tmpHSV:TColorHSV = New TColorHSV.fromARGB(pARGB) tmpHSV.s=Min(tmpHSV.s*pWhiteness,1) Return tmpHSV.toARGB() EndFunction Function MakeColourHandlePixmap:TPixmap( pRed%, pGreen%, pBlue%, pWidth% ) Local tmpPixmap:TPixmap = CreatePixmap(1,pWidth,PF_RGB888) Local tmpPixel% = (pRed Shl 16)|(pGreen Shl 8)|pBlue For Local i% = 0 To pWidth/2 Local tmpCalculatedPixel% = BrightenPixel(tmpPixel,1.05^i) WritePixel(tmpPixmap,0,i,tmpCalculatedPixel) WritePixel(tmpPixmap,0,pWidth-1-i,tmpCalculatedPixel) Next Return tmpPixmap EndFunction EndType Private 'Some type declarations from fredborg's pub.color module 'http://www.blitzbasic.com/codearcs/codearcs.php?code=1749 Type TColor Method toARGB:Int() Abstract End Type Type TColorHSV Extends TColor Field h:Float,s:Float,v:Float,a:Float=1.0 Method toRGB:TColorRGB() Local temph:Float = Self.h Local temps:Float = Self.s Local tempv:Float = Self.v Local rgb:TColorRGB = New TColorRGB If temph=>360.0 Or temph<0.0 Then temph = 0.0 If temps = 0 Then rgb.r = v rgb.g = v rgb.b = v Else temph = temph / 60.0 Local i:Int = Floor(temph) Local f:Float = temph - i Local p:Float = tempv * (1 - temps) Local q:Float = tempv * (1 - temps * f) Local t:Float = tempv * (1 - temps * (1 - f)) Select i Case 0 rgb.r = v rgb.g = t rgb.b = p Case 1 rgb.r = q rgb.g = v rgb.b = p Case 2 rgb.r = p rgb.g = v rgb.b = t Case 3 rgb.r = p rgb.g = q rgb.b = v Case 4 rgb.r = t rgb.g = p rgb.b = v Default rgb.r = v rgb.g = p rgb.b = q End Select EndIf rgb.a = a Return rgb EndMethod Function fromARGB:TColorHSV(argb:Int) Return TColorRGB.fromARGB(argb).toHSV() EndFunction Method toARGB:Int() Return Self.toRGB().toARGB() EndMethod EndType Type TColorRGB Extends TColor Field r:Float,g:Float,b:Float,a:Float=1.0 Method toHSV:TColorHSV() Local tempr:Float = Min(1.0,Max(0.0,Self.r)) Local tempg:Float = Min(1.0,Max(0.0,Self.g)) Local tempb:Float = Min(1.0,Max(0.0,Self.b)) Local minVal:Float = Min(Min(tempr,tempg),tempb) Local maxVal:Float = Max(Max(tempr,tempg),tempb) Local diff:Float = maxVal - minVal Local hsv:TColorHSV = New TColorHSV hsv.v = maxVal If maxVal = 0.0 Then hsv.s = 0.0 hsv.h = 0.0 Else hsv.s = diff / maxVal If tempr = maxVal hsv.h = (tempg - tempb) / diff ElseIf tempg = maxVal hsv.h = 2.0 + (tempb - tempr) / diff Else hsv.h = 4.0 + (tempr - tempg) / diff EndIf hsv.h = hsv.h * 60.0 If hsv.h < 0 Then hsv.h = hsv.h + 360.0 EndIf If hsv.h< 0.0 Then hsv.h = 0.0 If hsv.h>360.0 Then hsv.h = 0.0 hsv.a = a Return hsv EndMethod Function fromARGB:TColorRGB(argb:Int,alpha:Int=True) Local rgb:TColorRGB = New TColorRGB If alpha rgb.a = ((argb Shr 24) & $FF)/255.0 EndIf rgb.r = ((argb Shr 16) & $FF)/255.0 rgb.g = ((argb Shr 8) & $FF)/255.0 rgb.b = (argb & $FF)/255.0 Return rgb EndFunction Function fromBGR:TColorRGB(argb:Int) Local rgb:TColorRGB = New TColorRGB rgb.r = (argb & $000000FF)/255.0 rgb.g = ((argb Shr 8) & $000000FF)/255.0 rgb.b = ((argb Shr 16) & $000000FF)/255.0 Return rgb EndFunction Method toARGB:Int() Local tempr:Int = Min(255,Max(0,Int(Self.r*255))) Local tempg:Int = Min(255,Max(0,Int(Self.g*255))) Local tempb:Int = Min(255,Max(0,Int(Self.b*255))) Local tempa:Int = Min(255,Max(0,Int(Self.a*255))) Return (tempa Shl 24) | (tempr Shl 16) | (tempg Shl 8) | tempb EndMethod EndType |
Comments
None.
Code Archives Forum