VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /usr/share/doc/renaissance-doc/html/manual/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/doc/renaissance-doc/html/manual/node20.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<!--Converted with LaTeX2HTML 2002-2-1 (1.71)
original version by:  Nikos Drakos, CBLU, University of Leeds
* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>2.6 Integrating Renaissance in your application</TITLE>
<META NAME="description" CONTENT="2.6 Integrating Renaissance in your application">
<META NAME="keywords" CONTENT="manual">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">

<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">

<LINK REL="STYLESHEET" HREF="manual.css">

<LINK REL="next" HREF="node21.html">
<LINK REL="previous" HREF="node19.html">
<LINK REL="up" HREF="node14.html">
<LINK REL="next" HREF="node21.html">
</HEAD>

<BODY BGCOLOR="#FFFFFF" text="#000000" link="#0000FF" vlink="#4444FF" alink="#3388FF">
<B> Next: <A NAME="tex2html734"
  HREF="node21.html">2.7 Object tag reference</A> </B>
<B>Up: <A NAME="tex2html730"
  HREF="node14.html">2. The GNUstep Markup</A>  </B>
<B> Previous: <A NAME="tex2html724"
  HREF="node19.html">2.5 The GSMarkup NSBundle</A> </B>
<BR> <P>

<!--End of Navigation Panel-->
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A>

<UL>
<LI><A NAME="tex2html735"
  HREF="node20.html#SECTION00361000000000000000">2.6.1 The application main nib</A>
<LI><A NAME="tex2html736"
  HREF="node20.html#SECTION00362000000000000000">2.6.2 When to load the main menu gsmarkup</A>
<LI><A NAME="tex2html737"
  HREF="node20.html#SECTION00363000000000000000">2.6.3 When to load the main window gsmarkup</A>
<LI><A NAME="tex2html738"
  HREF="node20.html#SECTION00364000000000000000">2.6.4 When to load other gsmarkup files</A>
<LI><A NAME="tex2html739"
  HREF="node20.html#SECTION00365000000000000000">2.6.5 Renaissance and NSDocument-based applications</A>
<UL>
<LI><A NAME="tex2html740"
  HREF="node20.html#SECTION00365100000000000000">2.6.5.1 GSMarkupWindowController</A>
<LI><A NAME="tex2html741"
  HREF="node20.html#SECTION00365200000000000000">2.6.5.2 GSMarkupDocument</A>
</UL></UL>
<!--End of Table of Child-Links-->
<HR>

<H1><A NAME="SECTION00360000000000000000">
2.6 Integrating Renaissance in your application</A>
</H1>
In this part of manual we examine practical issues involved in
integrating Renaissance in your application - in practice, how to
write an application which uses gsmarkup files for creating menus and
windows.  Our main concern here is teaching you the traps and tricks
involved in switching from nib/gorm files to gsmarkup files.  There is
nothing essentially different: the structure and the organization of
the application is the same; everything is the same except that you
need to load Renaissance files instead of nib ones.  A few details
might confuse you the first time you try to do it - in this part of
the manual we examine all the details step to step to make sure you
won't get confused or upset by a small silly detail.

<P>

<H2><A NAME="SECTION00361000000000000000">
2.6.1 The application main nib</A>
</H2>
Traditionally, an application has a main nib file, and support for
automatically loading this nib file at the application startup is
built into the system libraries.  Because we can't modify the system
libraries, if you are using a gsmarkup file instead of the main nib
file, you will have to load this gsmarkup file manually.  Normally,
you would have a main gsmarkup file creating the main menu, and, if
needed, another one creating the main application window (if there is
one).  We now examine those separately in the next sections.

<P>

<H2><A NAME="SECTION00362000000000000000">&#160;</A><A NAME="integrating-renaissance-menu">&#160;</A>
<BR>
2.6.2 When to load the main menu gsmarkup
</H2>
If you are creating the main menu from a gsmarkup file, you need to
load the gsmarkup file as soon as possible, typically in your
<TT>main</TT> function.  Here is the classical example:
<PRE>
#include &lt;Foundation/Foundation.h&gt;
#include &lt;AppKit/AppKit.h&gt;
#include &lt;Renaissance/Renaissance.h&gt;

/* Dummy function pointer to get it working on Windows.  */
int (*linkRenaissanceIn)(int, const char **) = GSMarkupApplicationMain;

int main (int argc, const char **argv, char** env)
{
  CREATE_AUTORELEASE_POOL (pool);
  [NSApplication sharedApplication];
  [NSApp setDelegate: [MyApplicationDelegate new]];

  /* Load the menu before calling NSApplicationMain(), because on
   * Apple Mac OS X NSApplicationMain() creates automatically a menu
   * if none is there, and when we try to replace it later, it doesn't
   * really get replaced ... (?)
   *
   * After extensive experiments, loading the menu at this stage is the best
   * way of having it work on both platforms.
   */
#ifdef GNUSTEP
  [NSBundle loadGSMarkupNamed: @"MainMenu-GNUstep"  owner: [NSApp delegate]];
#else
  [NSBundle loadGSMarkupNamed: @"MainMenu-OSX"  owner: [NSApp delegate]];
#endif

  RELEASE (pool);

  return NSApplicationMain (argc, argv);
}
</PRE>
Please note that in the example we have two separate gsmarkup files
for the menu on the different platforms.  While it can be clumsy to do
so, it's certainly the way which works best at the moment - unless
you know what you are doing, it's recommended that you do it this way
(and that you check/use default template examples of main menu
gsmarkup files).  Finally, we set an instance of an hypothetic
<TT>MyApplicationDelegate</TT> as the application delegate.  
That is only an example, but implementing an application delegate
custom class can be useful for loading the main window gsmarkup if you
need so, as explained in the next section.

<P>

<H2><A NAME="SECTION00363000000000000000">
2.6.3 When to load the main window gsmarkup</A>
</H2>
If you are creating the main window of your application from a
gsmarkup file, I'd suggest to load this file after the application has
been launched.  That makes sure the window can immediately be
displayed on screen.

<P>
In practice, you can implement your own application delegate class,
and have it implement the 
<PRE>
- (void)applicationDidFinishLaunching: (NSNotification *)aNotification;
</PRE>
method.  This method will be called when the application has finished
launching; you can load the main window gsmarkup from there.  For
example:
<PRE>
@interface MyApplicationDelegate : NSObject
{
  /* ... */
}
- (void)applicationDidFinishLaunching: (NSNotification *)aNotification;
@end

@implementation MyApplicationDelegate
- (void)applicationDidFinishLaunching: (NSNotification *)aNotification
{
  [NSBundle loadGSMarkupNamed: @"MainWindow"  owner: self];  
}
@end
</PRE>
Of course, in your <TT>main</TT> function, you need to set an instance
of <TT>MyApplicationDelegate</TT> as the application delegate (as
demonstrated in the previous section).  Please note that this is just
a very simple example: depending on how you are organizing the code in
your application, you might be loading the <TT>MainWindow</TT> from a
different object, or with a different owner - as a classical variant,
in <TT>-applicationDidFinishLaunching:</TT> you could be creating a
controller object, and that object might be loading the gsmarkup file
during initialization.

<P>
Renaissance includes full examples of applications demonstrating how
to do all this - the first example you should look at is probably the
CurrencyConverter example -
<PRE>
/Examples/Applications/CurrencyConverter
</PRE>

<P>

<H2><A NAME="SECTION00364000000000000000">
2.6.4 When to load other gsmarkup files</A>
</H2>
You can literally load other gsmarkup files whenever you want.
Typically, you simply do -
<PRE>
  /* ... code here ... */
  [NSBundle loadGSMarkupNamed: @"HighScores"  owner: self];  
  /* ... more code here ... */
</PRE>
that would load the <TT>HighScores.gsmarkup</TT> file from the main
bundle, create the window(s) from the file, using self as the owner
(assuming this method call is done inside a method implementation).
The owner used when loading is quite important, because instance
variables of the owner can be set to point to objects in the window
(by using outlets in the gsmarkup file), and vice versa objects in the
window can have some of their instance variables (/attributes) set to
point to the file owner, so it is particularly natural to use as owner
the object which will be interacting more closely and directly with
the window while the program is running.

<P>

<H2><A NAME="SECTION00365000000000000000">
2.6.5 Renaissance and NSDocument-based applications</A>
</H2>
The AppKit contains a set of classes (NSDocumentController,
NSDocument, NSWindowController) which are meant to simplify building
document-based application.  The default implementation uses nib/gorm
files to create windows.  Renaissance provides subclasses which behave
exactly in the same way, but they use gsmarkup files to create windows
instead of nib/gorm files.  In the next sections we will examine these
subclasses.

<P>

<H3><A NAME="SECTION00365100000000000000">
2.6.5.1 GSMarkupWindowController</A>
</H3>
Renaissance provides <TT>GSMarkupWindowController</TT> - a subclass
of NSWindowController which behaves exactly in the same way as
NSWindowController does, but that creates the window from a gsmarkup
file rather than from a nib/gorm file.

<P>
So, if you want to use NSWindowController with Renaissance, instead of
using NSWindowController, you just need to use
GSMarkupWindowController; the API is precisely the same.  You can
subclass a GSMarkupWindowController in the same way as you subclass a
NSWindowController.

<P>
It's worth making an example of a gsmarkup file which can be loaded by 
a GSMarkupWindowController:
<PRE>
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE gsmarkup&gt;

&lt;gsmarkup&gt;
  &lt;objects&gt;
    &lt;window id="window"&gt;
      &lt;!-- ... your code here ... --&gt;
    &lt;/window&gt;
  &lt;/objects&gt;

  &lt;connectors&gt;
    &lt;outlet source="#NSOwner" target="#window" key="window" /&gt;
  &lt;/connectors&gt;
&lt;/gsmarkup&gt;
</PRE>
Please note the outlet which sets the window outlet of the NSOwner to
the window objects in your file (in practice, it calls
<TT>[#NSOwner setWindow: #window]</TT>) - it's essential that you have
this outlet in your file, or it won't work.  It's the same outlet that
is required in a nib/gorm file which is meant to be loaded by a 
NSWindowController.

<P>
Please refer to the NSWindowController documentation for more information
on using window controllers.

<P>

<H3><A NAME="SECTION00365200000000000000">
2.6.5.2 GSMarkupDocument</A>
</H3>
Because the default implementation of NSDocument uses
NSWindowController (which is only able to load nib/gorm files, and not
gsmarkup files), Renaissance provides <TT>GSMarkupDocument</TT> - a
subclass of NSDocument which uses GSMarkupWindowController instead of
NSWindowController, and so which uses gsmarkup files instead of
nib/gorm files.  <TT>GSMarkupDocument</TT> behaves exactly in the same
way as NSDocument, but uses GSMarkupWindowController to load windows
from files.

<P>
So, if you want to use Renaissance with NSDocument, instead of using
NSDocument, you just need to use GSMarkupDocument; the API is
precisely the same.  You can subclass a GSMarkupDocument in the same
way as you subclass a NSDocument.

<P>
In a typical document-based application, you add entries to the
application <TT>Info.plist</TT> describing the type of files/documents
that your application can manage (TODO: make examples); you then load
your main menu at startup (as explained in section
<A HREF="#integrating-renaissance-menu">2.6.2</A>).  Actions in the <TT>File</TT>
menu will typically be about creating, opening, saving, printing
document.  You should probably start with a standard document menu
copied from a template.

<P>
Finally, you implement a subclass of GSMarkupDocument able to
read/write those data; you override <TT>windowNibName</TT> to return
the name of the gsmarkup file (without the <TT>.gsmarkup</TT>
extension) to use to create the window which the user can use to edit
the data.  Make sure the gsmarkup file sets the window outlet of the
NSOwner to point to the window (as described/exemplified in the
example code in the previous section).

<P>
Please refer to the documentation on NSDocument for more information;
the Renaissance distribution provides complete examples of
document-based application built using Renaissace which can be a
useful starting point - for example
<PRE>
Examples/Applications/Ink
Examples/Applications/SimpleEditor
</PRE>

<P>
<HR><B> Next: <A NAME="tex2html734"
  HREF="node21.html">2.7 Object tag reference</A> </B>
<B>Up: <A NAME="tex2html730"
  HREF="node14.html">2. The GNUstep Markup</A> </B>
<B> Previous: <A NAME="tex2html724"
  HREF="node19.html">2.5 The GSMarkup NSBundle</A> </B>

<!--End of Navigation Panel-->
<ADDRESS>

2008-03-19
</ADDRESS>
</BODY>
</HTML>

VaKeR 2022