Tips_tutorials   >   Studio104   >   Parent Window

Parent Window

A parent window is a window class which contains one or more subwindow fields. The subwindow is considered a child window of the parent window.

A subwindow field is a special window object which allows you to instantiate a window class inside of another window class instance.

A child window knows nothing about the world outside of itself. The child window doesn't even know who its parent is. The parent is responsible to inform the child who its parent is.

Communication between parent and child window instances is accomplished by sending messages via the public class methods of the parent and child windows.

In this section we will create a parent window class with two subwindows. Each subwindow will be an instance of wHeadedList. One subwindow will display a list of the countries, the other subwindow class will display a list of states/provs for the selected country.

Create Parent Window

To create the parent window class:

  1. F2 Browser > select Contacts library > click New Class > click Window.
  2. Name the window class, wCountryStateprovContainer.
  3. Right-click on the window class in the F2 Browser and select Methods... in the context menu.
  4. Add the following instance variables in the Variables pane:

    iCountriesList - Type - List
    iStateprovsList - Type - List
    irswCountries - Type Item Reference - Countries subwindow field
    irswStateprovs - Type Item Reference - Stateprovs subwindow field
  5. Add a constructDefineLists method to the class methods.
  6. Add the following code to the constructDefineLists method.

    ; Define the list binding it to the table class.
    Do iCountriesList.$definefromsqlclass('tCountry')

    ; Set the session object in the list variable so that the SQL statements will be issued to that session's database.
    Do iCountriesList.$sessionobject.$assign($ctask.dbsessionobj)

    ; Define the list binding it to the table class.
    Do iStateprovsList.$definefromsqlclass('tStateprov')

    ; Set the session object in the list variable so that the SQL statements will be issued to that session's database.
    Do iStateprovsList.$sessionobject.$assign(dbsessionobj)

    Quit method kTrue

  7. Add a constructSubWin_Countries method to the class methods.
  8. Add the following code to the constructSubWin_Countries method.

    ; Register this window as the parent.
    Do irswCountries.$setParentRef($cinst) Returns FlagOK
    If FlagOK
       
       ; Set a reference to the data list variable.
       Do irswCountries.$setDataListRef(iCountriesList) Returns FlagOK
       If FlagOK
          
          ; Get a reference to the list object.
          Do irswCountries.$:ListObjRef() Returns rListObj
          
          ; Set the list object properties.
          Do rListObj.$name.$assign('CountriesList')
          Do rListObj.$colcount.$assign(1)
          Do rListObj.$columnnames.$assign('Country')
          Do rListObj.$calculation.$assign('irDataList.CountryName')
          
       End If
    End If
    Quit method FlagOK

  9. Add a constructSubWin_Stateprovs method to the class methods.
  10. Add the following code to the constructSubWin_Stateprovs method.

    ; Register this window as the parent.
    Do irswStateprovs.$setParentRef($cinst) Returns FlagOK
    If FlagOK
       
       ; Set a reference to the data list variable.
       Do irswStateprovs.$setDataListRef(iStateprovsList) Returns FlagOK
       If FlagOK
          
          ; Get a reference to the list object.
          Do irswStateprovs.$:ListObjRef() Returns rListObj
          
          ; Set the list object properties.
          Do rListObj.$name.$assign('StateprovsList')
          Do rListObj.$colcount.$assign(2)
          Do rListObj.$columnnames.$assign('State/Prov,Abbrev')
          Do rListObj.$calculation.$assign('con(irDataList.StateProvName,kTab,irDataList.StateProvAbbrev)')
          
       End If
    End If
    Quit method FlagOK

  11. Add a buildCountriesList method to the class methods.
  12. Add the following code to the buildCountriesList method.

    Do iCountriesList.$getAllRecords() Returns FlagOK
    Quit method FlagOK

  13. Add a buildStateprovsListForCurrCountry method to the class methods.
  14. Add the following code to the buildStateprovsListForCurrCountry method.

    If iCountriesList.$line
       
       ; Fetch the state/prov records linked to the selected country.
       Calculate SQLText as con("WHERE Country_fkey = ",iCountriesList.Country_pkey)
       Do iStateprovsList.$select(SQLText) Returns FlagOK
       If FlagOK
          Do iStateprovsList.$fetch(kFetchAll) Returns FlagOK
       End If
       
       ; Redraw the state/prov subwindow.
       Do irswStateprovs.$redraw()
       
    End If
    Quit method FlagOK

  15. Add the following code to the existing $construct class method.

    Do method constructDefineLists Returns FlagOK

    If FlagOK
       Do method constructSubWin_Countries Returns FlagOK
       
       If FlagOK
          Do method constructSubWin_Stateprovs Returns FlagOK
          
          If FlagOK
             Do method buildCountriesList Returns FlagOK
             
             If FlagOK
                Do method buildStateprovsListForCurrCountry Returns FlagOK
                
             End If
          End If
       End If
    End If
    If not(FlagOK)
       Do errhndlr.$promptonceLastError()
    End If
    Quit method FlagOK

  16. Add an $event_HeadedListObj method to the class methods.
  17. Add the following code to the $event_HeadedListObj method.

    Calculate FlagOK as kTrue ;; Preset flag to true

    Switch low($cobj().$name)
       Case 'countrieslist'
          
          If pEventCode=evClick
             Do method buildStateprovsListForCurrCountry Returns FlagOK
          End If
          
       Case 'stateprovslist'
          
          ; Do nothing.
          
    End Switch
    Quit method FlagOK

Add Subwindow Fields

We will now add the subwindow fields to the wCountryStateprovContainer window class.

  1. If you are still in the window methods editor, press F3 to switch to the window class editor, otherwise double-click on wCountryStateprovContainer in the F2 Browser.
  2. F3 Component Store > drag the Subwindow field onto the window class.
  3. With the subwindow field selected press F6 Property Manager and set the following properties:

    General tab
    $name - swCountries
    $classname - wHeadedList
    $height - 200
    $left - 10
    $top - 10
    $width - 400
  4. Dag another Subwindow field from the Component Store onto the window class.
  5. With the subwindow field selected press F6 Property Manager and set the following properties:

    General tab
    $name - swStateprov
    $classname - wHeadedList
    $height - 200
    $left - 10
    $top - 220
    $width - 400
  6. Double-click the swCountries subwindow field to get to its methods.
  7. Add a $construct method to the swCountries subwindow field and enter the following code:

    Set reference irswCountries to $cfield

  8. Add a $construct method to the swStateprovs subwindow field and enter the following code:

    Set reference irswStateprovs to $cfield

Main Menu

We are just about ready to test the wCountryStateprovContainer window.

In order to open and instance of the window class we will add a menu line to the main menu.

  1. F2 Browser > double-click mMainMenu.
  2. Add a menu line to mMainMenu and set its F6 properties as follows:

    $name - Countries, States/Provinces Browser
    $text - Countries, States/Provinces Browser
  3. Add the following code to the $event method of the menu line.

    ; Find and open an instance of the town/city list window class.
    Calculate ClassName as 'wCountryStateProvContainer'
    Do $clib.$windows.$findname(ClassName) Returns rClass
    If isnull(rClass)
       OK message [sys(85)] (Icon) {Unable to find the window class '[ClassName]'.}
    Else
       Do rClass.$openonce('*') Returns rWin
       If isnull(rWin)
          OK message [sys(85)] (Icon) {Unable to open an instance of the window class [ClassName].}
       End If
    End If
    Quit method rWin

  4. Close the menu class.
  5. Close and reopen the Startup_Task to reinstall the main menu. (F2 Browser > right-click Startup_Task > select Close Task, then right-click again and select Open Task.)

Testing the Parent Window

We are now ready to test the parent window.

  1. Contacts menu > select Counties, States/Provs Browser
  2. All going well and instance of the wCountyStateprovContainer window will be instantiated. The top subwindow will display a list of the countries and the bottom subwindow will display a list of states/provs for the selected country.
  3. If you select a different country, the list of states/provs will be rebuilt to display the states and provinces connected to the country.

Parent Window Sequence of Events

The following is an overview of the sequence of events that occur when the parent window is instantiated.

  1. When the wCountryStateprovContainer window begins to be instantiated, the two subwindow fields are first instantiated in order of the $order field property.
  2. The subwindows fields each open a separate instance of wHeadedList. When the window is instantiated the $construct methods of the window objects are first run. In this case the HeadedListObj $construct method expands the headed list object to fill the available area and sets the ivar irListObj to point to the headed list object.
  3. The $construct class method of wHeadedList runs next, but there isn't any code in the method.
  4. The $construct method of the subwindow fields in wCountryStateprovContainer set the ivars irswCountries and irswStateprovs to point to the respective subwindow fields.
  5. The $construct class method of wCountryStateprovContainer runs next. This method calls a series of private construct methods.
  6. constructDefineLists defines the data list variables iCountriesList and iStateprovsList of wCountryStateprovContainer.
  7. constructSubWin_Countries sends a $setParentRef($cinst) message to the swCountries subwindow field. The subwindow field automatically redirects the message to the window class instance of the subwindow field (wHeadedList). Redirecting messages to the window class instance is a feature of subwindow fields.
  8. The swCountries instance of wHeadedList sets its ivar irParent to point to the instance of wCountryStateprovContainer.
  9. constructSubWin_Countries sends a $setDataList(iCountriesList) message to the swCountries subwindow field which is redirected to its instance of wHeadedList.
  10. The swCountries instance of wHeadedList sets its ivar irDataList to point to the ivar iCountriesList of wCountryStateprovContainer.
  11. constructSubWin_Countries sends a $:ListObjRef message to the swCountries subwindow field which returns a reference to the headed list object.
  12. constructSubWin_Countries sets various properties of the headed list object. ($name, $colcount, $calculation, $columnnames) Additional properties could be set as needed.

    Note

    A better alternative would be to add a public method to wHeadedList for setting the headed list properties. e.g. $setListObjColumns(pDataListColNamesCSV,pColNamesCSV,pColAlignCSV) The method would then parse the CSV strings and set the $colcount, $columnnames, $calculation properties and set the alignment for each column.

  13. constructSubWin_Stateprovs repeats the steps completed by constructSubWin_Countries but for the swStateprovs subwindow field and the iStateprovsList variable.
  14. Finally the $construct class method of wCountryStateprovContainer calls the buildCountriesList method and then the buildStateprovsListForCurrCountry method.
  15. The parent window instance along with its two subwindow instances appears to the user.
  16. When the user clicks on a different country in the countries list, the $event method of wHeadedList sends an $event_HeadedListObj message to the registered parent.
  17. The instance of wCountryStateprovContainer receives the $event_HeadedListObj message, figures out that the message came from the countries list instance of wHeadedList and calls the buildStateprovsListForCurrCountry method which then rebuilds the lista and redraws the state/provs list subwindow.