[comp.sys.next] Multiple instantiation of windows laid out with IB

jacob@gore.com (Jacob Gore) (10/22/89)

Is there a way to use the Interface Builder to set up a window, and then
create an arbitrary number of copies of this window from the program, at
run-time? 

For example, suppose I use IB to lay out a DocumentWindow, and my
application requires opening a separate DocumentWindow for each document it
edits.

Jacob
--
Jacob Gore		Jacob@Gore.Com			boulder!gore!jacob

labc-1aa@e260-1d.berkeley.edu (Bob Heiney) (10/22/89)

One way of doing this is to have a separate nib file for the document
window.  A fairly detailed example of this is given in the Interface
Builder chapter of the NeXT Technical Documentation set.

An on-line copy of this chapter appears in

	/NextLibrary/Documentation/NeXT/SysRefMan/08_IntfBuilder.wn

Basically, what you do is have an owner object for each document window
in your application.  Whenever a new document is desired, a new manager
object is created; its factory method looks like this:

@implementation MyManager

+ new
{
	self = [super new];
	[NXApp loadNibSection:"DocWindow.nib" owner:self];
	return self;
}

// more stuff here

@end


I hope this does what you want, and is helpful to you.  If you have
any questions, feel free to ask.

bob

== Bob Heiney, labc-1aa@WEB.Berkeley.edu                                     ==
== NeXT Student Advocate for U. C. Berkeley                                  ==
==      "And in the end, the love you take is equal to the love you make"    ==
==                                    -- The Beatles                         ==

dtgcube (Edward Jung) (10/22/89)

>Is there a way to use the Interface Builder to set up a window, and then
>create an arbitrary number of copies of this window from the program, at
>run-time? 

Yes, you can do that with Interface Builder.  Instructions on how to do
it are in the Interface Builder chapter dealing with a multi-window
editor (Project 4, Chapter 8, pp.47 in the on-line manual
/NextLibrary/Documentation/NeXT/SysRefMan/08_IntfBuilder.wn).
The instructions are relatively straight-forward.

There are also other ways:

You might be tempted to use the message 'copy' to make a copy of the
objects, but avoid this.  'copy' makes an exact copy, including all
*references* to other objects (rather than copying those objects), which
is ALMOST CERTAINLY NOT what you want.  Instead, use typed streams to
copy objects:

	#import <objc/typedstream.h>
	id copyObject(id baseObject)
	{
	    id returnValue;
	    int length;
	    char * buffer = NXWriteRootObjectToBuffer(baseObject, &length);
	    returnValue = NXReadObjectFromBuffer(buffer, length);
	    /* error checking here */
	    NXFreeObjectBuffer(buffer, length);
	    return returnValue;
	}

This writes out a graph of the object and then reads it back in, all in
memory.

Hope this helps.
-- 
=================================================================
Edward Jung			     The Deep Thought Group, L.P.
BIX: ejung				     3400 Swede Hill Road
UUCP: uunet!dtgcube!ed			      Clinton, WA.  98236

jacob@gore.com (Jacob Gore) (10/24/89)

/ comp.sys.next / ed@uunet!dtgcube (Edward Jung) / Oct 22, 1989 /
	#import <objc/typedstream.h>
	id copyObject(id baseObject)
	{
	    id returnValue;
	    int length;
	    char * buffer = NXWriteRootObjectToBuffer(baseObject, &length);
	    returnValue = NXReadObjectFromBuffer(buffer, length);
	    /* error checking here */
	    NXFreeObjectBuffer(buffer, length);
	    return returnValue;
	}
This writes out a graph of the object and then reads it back in, all in memory.
----------

Thanks, this is a nice way to copy an object.  (Looks like NeXT punted on
the -deepCopy method in class Object?)

However, it seems that it does not preserve the outlet connections that
have been set up in the interface builder.

Jacob

P.S. Thanks to everybody who pointed me to Example 4 in the Interface
Builder chapter of the 1.0 manual.

--
Jacob Gore		Jacob@Gore.Com			boulder!gore!jacob

ali@polya.Stanford.EDU (Ali T. Ozer) (10/24/89)

In article <130030@gore.com> jacob@gore.com (Jacob Gore) writes:
>Is there a way to use the Interface Builder to set up a window, and then
>create an arbitrary number of copies of this window from the program, at
>run-time? 
>For example, suppose I use IB to lay out a DocumentWindow, and my
>application requires opening a separate DocumentWindow for each document it
>edits.

Yes; the easist way to do this is to create a separate .nib file for your
window and load it in whenever you need to create a new document. 

Take a look at the Yap source; at the YapDocument.m file. In its "new" 
factory method it loads the YapDocument.nib file, right after creating
a new instance of the class. This new object is specified as the "owner"
to the loadNibSection:owner: method; thus the outlet initialization methods
in this object will be called.  YapDocument.nib has one outlet, "document,"
thus the "setDocument:" method of this new object is invoked, giving it
a handle to the text object in this window. 

Ali Ozer, NeXT Developer Support
Ali_Ozer@NeXT.com

dtgcube (Edward Jung) (10/25/89)

Hmm.  It ought to archive all outlet connections (actually connect
them to the common instances), assuming that the read and write
methods are correctly written...

If I didn't mention it in the previous posting, you must have
working read and write methods for the typed stream archiving
functions to work.

BTW, if the architecture of your application fits to the multiple
controller/.nib file setup, you should use it.  It is very
convenient.

-- 
====================================================================
Edward Jung			        The Deep Thought Group, L.P.
BIX: ejung				        3400 Swede Hill Road
UUCP: uunet!dtgcube!ed			         Clinton, WA.  98236