Children of Exported Protos Are Missing

One of the Newton 2.x OS Q&As
Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.


Children of Exported Protos Are Missing (9/20/96)

Q: I have a template that is based on a user proto imported by my package. When the view based on my template opens, none of the exported proto's children show up. What is going on?

A: When you create children of templates in Newton Toolkit, they are collected in the stepChildren slot of the base view of the template file. If both the exported and importing template have children, they will both have a stepChildren slot. The result is that the stepChildren slot of the importing prototemplate is masking the one in the exported proto. The instantiated view does not collect all the children from the entire proto chain (though NTK does do this at compile time for user proto templates).

The solution for exported user protos with stepChildren is to add a viewSetupChildrenScript to either your exported proto template or the importer that collects all of the stepChildren into a runtime stepChildren array.

// AFTER setting up stepChildren, views which "import" this proto
// must call inherited:?viewSetupChildrenScript();
exporter.viewSetupChildrenScript := func()
  begin
    // get the current value of the "extra" kids
    // ...unless the importer added NO kids, in which case, these are OURS
    local extraKids := stepChildren;
        
    local items := clone(extraKids);
    local kids;
    
    local whichFrame := self; 
    
    while (whichFrame) do
      begin
        // get kids, but NOT using inheritance
        kids := GetSlot(whichFrame, 'stepChildren); 
        
        // copy any extra stepChildren (but if NO extra kids are defined, don't copy twice!)
        if kids and kids <> extraKids then 
          ArrayMunger(items, 0, 0, kids, 0, nil);
          
        // go deeper into the _proto chain (or set whichFrame to nil)
        whichFrame := whichFrame._proto; 
      end;        

    stepChildren := items;
  end;


Note that you will have similar problems with declared children. If you have declared children you will also need to collect the stepAllocateContext slot.