Module cSplitterContainerMixin.pkg

     1// contains mixin support for SplitterContainer and SplitterContainerChild classes. This is required
     2// because we support the non-db (cSplitterContainer / cSplitterContainerChild) and the
     3// db ( cDbSplitterContainer / cDbSplitterContainerChild) classes/
     4
     5Use Windows.Pkg
     6Use cSplitter.pkg
     7
     8Enum_List
     9    Define fpFixFirstPanel      // Top panel height remains fixed on resize
    10    Define fpFixLastPanel   // Bottom panel height remains fixed on resize
    11End_Enum_List
    12
    13Define C_SplitterWidth for 3
    14
    15
    16Class cSplitterContainerMixin is a Mixin
    17
    18    { Visibility=Private}
    19    Procedure Define_cSplitterContainerMixin
    20
    21        // Split vertical or horizontal
    22        { Category=Appearance }
    23        Property Boolean pbSplitVertical True
    24
    25        // determines which panel's height remains fixed during parent resize events
    26        { Category=Behavior }
    27        { EnumList="fpFixFirstPanel, fpFixLastPanel" }
    28        Property Integer peFixedPanel fpFixFirstPanel
    29
    30        { PropertyType=Color }
    31        { EnumList="clScrollBar, clBackground, clActiveCaption, clInactiveCaption, clMenu, clWindow, clWindowFrame, clMenuText, clWindowText, clCaptionText, clActiveBorder, clInactiveBorder" }
    32        { EnumList+="clAppWorkSpace, clHighlight, clHighlightText, clBtnFace, clBtnShadow, clGrayText, clBtnText, clInactiveCaptionText, clBtnHighlight, cl3DDkShadow, cl3DLight, clInfoText, clInfoBk, clDefault, clNone" }
    33        { EnumList+="clAqua, clBlack, clBlue, clDkGray, clFuchsia, clGray, clGreen, clLime, clLtGray, clMaroon, clNavy, clOlive, clPurple, clRed, clSilver, clTeal, clWhite, clYellow" }
    34        { InitialValue=clBtnFace }
    35        { Category=Appearance }
    36        Property Integer piSplitterColor clBtnFace
    37        
    38        // these are normally maintained by the class
    39        { DesignTime=False }
    40        Property Handle phoFirstPanel 0
    41        { DesignTime=False }
    42        Property Handle phoLastPanel 0
    43        { DesignTime=False }
    44        Property Handle phoSplitter 0
    45
    46        { Visibility=Private }
    47        Property Integer piPrivateSplitterLocation 0
    48        { Visibility=Private }
    49        Property Integer piPrivateMinSplitterLocation 20
    50        { Visibility=Private }
    51        Property Integer piPrivateMaxSplitterLocation 20
    52        
    53        Set Border_Style to Border_None
    54
    55    End_Procedure // Construct_Object
    56    
    57    { MethodType=Property }
    58    { InitialValue=20 }
    59    { Category=Behavior }
    60    Procedure Set piMinSplitterLocation Integer iLocation
    61        Handle hoSplitter
    62        Boolean bVert
    63        Set piPrivateMinSplitterLocation to iLocation
    64        // if splitter exists update the splitter with Gui Units
    65        Get phoSplitter to hoSplitter
    66        If hoSplitter Begin
    67            Get pbSplitVertical to bVert
    68            Get DialogToGui iLocation iLocation to iLocation
    69            Set piMinLocation of hoSplitter to (If(bVert,Low(iLocation),Hi(iLocation)))
    70        End
    71    End_Procedure
    72
    73    { MethodType=Property }
    74    Function piMinSplitterLocation Returns Integer
    75        Integer iLocation
    76        Get piPrivateMinSplitterLocation to iLocation
    77        Function_Return iLocation
    78    End_Function
    79
    80    { MethodType=Property }
    81    { InitialValue=20 }
    82    { Category=Behavior }
    83    Procedure Set piMaxSplitterLocation Integer iLocation
    84        Handle hoSplitter
    85        Boolean bVert
    86        Set piPrivateMaxSplitterLocation to iLocation
    87        // if splitter exists update the splitter with Gui Units
    88        Get phoSplitter to hoSplitter
    89        If hoSplitter Begin
    90            Get pbSplitVertical to bVert
    91            Get DialogToGui iLocation iLocation to iLocation
    92            Set piMaxLocation of hoSplitter to (If(bVert,Low(iLocation),Hi(iLocation)))
    93        End
    94    End_Procedure
    95
    96    { MethodType=Property }
    97    Function piMaxSplitterLocation Returns Integer
    98        Integer iLocation
    99        Get piPrivateMaxSplitterLocation to iLocation
   100        Function_Return iLocation
   101    End_Function
   102    
   103    { MethodType=Property }
   104    { DesignTime=False }
   105    Procedure Set piGuiSplitterLocation Integer iPos
   106        Handle hWnd
   107        Get Window_Handle to hWnd
   108        If hWnd Begin
   109            Get SizeSplitterComponents iPos to iPos
   110        End
   111        Set piPrivateSplitterLocation to iPos
   112    End_Procedure
   113    
   114    { MethodType=Property }
   115    Function piGuiSplitterLocation Returns Integer
   116        Integer iPos
   117        Get piPrivateSplitterLocation to iPos
   118        Function_Return iPos
   119    End_Function
   120    
   121    { MethodType=Property }
   122    { InitialValue=0 }
   123    { Category=Appearance }
   124    Procedure Set piSplitterLocation Integer iPos
   125        Boolean bVert
   126        Get pbSplitVertical to bVert
   127        Get DialogToGui iPos iPos to iPos
   128        Set piGuiSplitterLocation to (If(bVert, low(iPos), Hi(iPos)))
   129    End_Procedure
   130    
   131    { MethodType=Property }
   132    Function piSplitterLocation Returns Integer
   133        Integer iPos
   134        Boolean bVert
   135        // we will get the gui units and convert to dialog
   136        Get piPrivateSplitterLocation to iPos
   137        Get pbSplitVertical to bVert
   138        Get GuiToDialog iPos iPos to iPos
   139        Function_Return (If(bVert, low(iPos), Hi(iPos)))
   140    End_Function
   141
   142    // create the appropriate splitter for the object. This could be augmented
   143    // to return a different object class 
   144    { Visibility=Private}
   145    Function CreateSplitter Returns Handle
   146        Boolean bVertical
   147        Handle hoSplitter
   148        
   149        Get pbSplitVertical to bVertical
   150        
   151        If bVertical Begin
   152            Get Create U_cVerticalSplitter to hoSplitter
   153        End
   154        Else Begin
   155            Get Create U_cHorizontalSplitter to hoSplitter
   156        End
   157        
   158        Function_Return hoSplitter
   159    End_Function
   160    
   161    // augmented to test that all components are bound properly and
   162    // to set the initial sizes
   163    { NoDoc=True }
   164    Procedure Page Integer iPageObject 
   165        Handle hoSplitter hoFirst hoLast
   166        Integer iColor iClientSize
   167        Boolean bVertical
   168        Integer iLoc
   169        Integer iVal
   170        
   171        Forward Send Page iPageObject
   172        
   173        If iPageObject Begin
   174
   175            // make the container the size of the parent clientarea
   176            // We use GetContainerClientSize instead of GuiClientSize because
   177            // GetContainerClientSize has a special augmentation in tab pages that
   178            // makes anchors work properly with unpaged tab-pages
   179            Delegate Get GetContainerClientSize to iClientSize
   180            Set GuiSize to (Hi(iClientSize)) (Low(iClientSize))
   181            Set GuiLocation to 0 0
   182            Send Adjust_Logicals
   183            
   184            // destroy existing splitter and create a new one
   185            Get phoSplitter to hoSplitter
   186            If (hoSplitter) Begin
   187                Send Destroy of hoSplitter
   188            End
   189            Get CreateSplitter to hoSplitter
   190            Set phoSplitter to hoSplitter
   191            Get phoFirstPanel to hoFirst
   192            Get phoLastPanel to hoLast
   193            If (hoSplitter=0 or hoFirst=0 or hoLast=0) Begin
   194                Error DFERR_OPERATOR "Splitter container is missing a child splitter or container component"
   195                Procedure_Return
   196            End
   197            
   198            // set various splitter propertues directly in splitter
   199            Get piSplitterColor to iColor
   200            Set Color of hoSplitter to iColor
   201            Get pbSplitVertical to bVertical
   202            Set pbSplitVertical of hoSplitter to bVertical
   203            // Once phoSplitter is set, reseting these will update the splitter as needed
   204            Get piMinSplitterLocation to iVal
   205            Set piMinSplitterLocation to iVal
   206            Get piMaxSplitterLocation to iVal
   207            Set piMaxSplitterLocation to iVal
   208
   209            // this will force a resize
   210            Get piGuiSplitterLocation to iLoc
   211            Set piGuiSplitterLocation to iLoc
   212        End
   213        
   214    End_Procedure
   215    
   216    // called everytime the parent is resized
   217    { NoDoc=True }
   218    Procedure DoApplyAnchors Integer Arg1 Integer Arg2
   219        If (Window_Handle(Self)) Begin
   220            Send ResizeSplitterContainer
   221        End
   222    End_Procedure
   223
   224    // parent has been resized. Adjust everything. 
   225    { Visibility=Private }
   226    Procedure ResizeSplitterContainer
   227        Integer iClientSize
   228        Handle  hoFirstPanel hoLastPanel
   229        Integer cxy cxClient cyClient
   230        Boolean bVertical
   231        Integer iFirstSize
   232        Integer eFixedPanel
   233        
   234        // make the container the size of the parent clientarea
   235        Delegate Get GuiClientSize to iClientSize
   236        Move (Hi(iClientSize))  to cyClient
   237        Move (Low(iClientSize)) to cxClient
   238        Set GuiSize to cyClient cxClient
   239        Set GuiLocation to 0 0
   240        
   241        // resize child objects by determining the size of the first child container
   242        Get pbSplitVertical to bVertical
   243        Get peFixedPanel to eFixedPanel
   244        If (eFixedPanel = fpFixFirstPanel) Begin
   245            // Resize the panels keeping the size of the first panel fixed
   246            Get phoFirstPanel to hoFirstPanel
   247            Get GuiSize of hoFirstPanel to cxy
   248            If bVertical Begin
   249                Move (Low(cxy)) to iFirstSize
   250            End
   251            Else Begin
   252                Move (Hi(cxy)) to iFirstSize
   253            End
   254        End
   255        Else Begin
   256            // Resize the panels keeping the size of the last panel fixed
   257            Get pholastPanel to hoLastPanel
   258            Get GuiSize of hoLastPanel to cxy
   259            If bVertical Begin
   260                Move (cxClient - low(cxy) - C_SplitterWidth) to iFirstSize               
   261            End
   262            Else Begin
   263                Move (cyClient - Hi(cxy) - C_SplitterWidth) to iFirstSize                
   264            End
   265        End
   266        Set piGuiSplitterLocation to iFirstSize
   267    End_Procedure
   268    
   269    // set size of all child objects passing the GUI size of the first child panel
   270    { Visibility=Private }
   271    Function SizeSplitterComponents Integer iFirstSize Returns Integer
   272        Handle  hoFirstPanel hoLastPanel hoSplitter
   273        Integer cyFirstPanel cyLastPanel
   274        Integer cxFirstPanel cxLastPanel
   275        Integer cxy cxClient cyClient
   276        Integer iMin iMax
   277        Boolean bVertical
   278        
   279        Get phoFirstPanel    to hoFirstPanel
   280        Get phoLastPanel to hoLastPanel
   281        Get phoSplitter    to hoSplitter
   282        Get pbSplitVertical to bVertical
   283        Get GuiClientSize to cxy
   284        Move (Hi(cxy))  To cyClient
   285        Move (Low(cxy)) to cxClient
   286        
   287        Get piMinSplitterLocation to iMin
   288        Get piMaxSplitterLocation to iMax
   289        Get DialogToGui iMin iMin to iMin
   290        Move (If(bVertical,Low(iMin),Hi(iMin))) to iMin
   291        Get DialogToGui iMax iMax to iMax
   292        Move (If(bVertical,Low(iMax),Hi(iMax))) to iMax
   293        
   294        If (iFirstSize=0) Begin
   295            Move (If(bVertical, cxClient, cyClient)/2) to iFirstSize
   296        End
   297    
   298        Move (iFirstSize max iMin) to iFirstSize
   299        Move (iFirstSize min (If(bVertical, cxClient, cyClient) - iMax)) to iFirstSize
   300
   301        If bVertical Begin
   302            Move iFirstSize to cxFirstPanel
   303        
   304            // position the splitter
   305            Set GuiLocation of hoSplitter to 0 cxFirstPanel
   306            Set GuiSize     of hoSplitter to cyClient C_SplitterWidth
   307        
   308            // position the left panel
   309            Set GuiLocation of hoFirstPanel to 0 0
   310            Set GuiSize     of hoFirstPanel to  cyClient cxFirstPanel
   311        
   312            // position the right panel
   313            Set GuiLocation of hoLastPanel to 0 (cxFirstPanel + C_SplitterWidth)
   314            Set GuiSize     of hoLastPanel to cyClient (cxClient - cxFirstPanel - C_SplitterWidth) 
   315            Move cxFirstPanel to iFirstSize
   316        End
   317        Else Begin
   318            Move iFirstSize to cyFirstPanel
   319        
   320            // position the splitter
   321            Set GuiLocation of hoSplitter to cyFirstPanel 0 
   322            Set GuiSize     of hoSplitter to C_SplitterWidth cxClient
   323        
   324            // position the top panel
   325            Set GuiLocation of hoFirstPanel to 0 0
   326            Set GuiSize     of hoFirstPanel to cyFirstPanel cxClient
   327        
   328            // position the bottom panel
   329            Set GuiLocation of hoLastPanel to (cyFirstPanel + C_SplitterWidth) 0
   330            Set GuiSize     of hoLastPanel to (cyClient - cyFirstPanel - C_SplitterWidth) cxClient
   331            Move cyFirstPanel to iFirstSize
   332        End
   333        
   334        Function_Return iFirstSize
   335    End_Function
   336    
   337    // move splitter by passed GUI units. Usually called by splitter control 
   338    Procedure MoveSplitter Integer iGuiTrack
   339        Integer cxy
   340        Integer iFirstSize
   341        Handle hoFirstPanel
   342        Boolean bVertical
   343        
   344        Get pbSplitVertical to bVertical
   345        
   346        Get phoFirstPanel to hoFirstPanel
   347        Get GuiSize of hoFirstPanel to cxy
   348        If bVertical Begin
   349            Move (Low(cxy) + iGuiTrack) to iFirstSize
   350        End
   351        Else Begin
   352            Move (Hi(cxy) + iGuiTrack) to iFirstSize
   353        End
   354        
   355        Set piGuiSplitterLocation to iFirstSize
   356    End_Procedure
   357    
   358End_Class
   359
   360
   361Class cSplitterContainerChildMixin is a Mixin
   362
   363    { Visibility=Private}
   364    Procedure Define_cSplitterContainerChildMixin
   365        Handle hoObj
   366        
   367        Forward Send Construct_Object
   368        
   369        // by default we use object order to determine which is the first panel and
   370        // which is the second panel. This class is only valid within a SplitterContainer and
   371        // an error will be raised here if this is not the case
   372        Delegate Get phoFirstPanel to hoObj
   373        If (hoObj=0) Begin
   374            Delegate Set phoFirstPanel to Self
   375        End
   376        Else Begin
   377            Delegate Set phoLastPanel to Self
   378        End
   379    End_Procedure
   380    
   381End_Class
   382
   383