This is Ivy_main.m in view mode; [Download] [Up]
/* Set up the Ivy Application,
Copyright (C) 1996, Felix H. Gatzemeier.
This file is part of Ivy.app, the minimal NeXTstep(TM) Editor..
Ivy.app is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Ivy.app is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Ivy.app; see the file COPYING. If not, write to
fxg@imib.rwth-aachen.de
or the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#import "MiniText.h"
#import <appkit/appkit.h>
/* Default defaults. Just some coordinates that should work ok on all screens */
#define XOFFSNAME "NXWindow X"
#define XOFFSVALUE "300.0"
#define XOFFSVALUEFLOAT 300.0
#define YOFFSNAME "NXWindow Y"
#define YOFFSVALUE "250.0"
#define YOFFSVALUEFLOAT 250.0
#define WINEXT 400.0 /* Maximal Text height */
void main(void);
void main(void)
{
NXApp = [Application new]; /* connect to the window server */
if (NXArgc == 2)
{
MiniText *theMiniText;
NXRect frame1 = {origin:{x:0.0, y:0.0}, size:{width:WINEXT, width:WINEXT}};
/*
* Do the Defaults
* =================
*/
int i;
/* The list of defaults in use */
static NXDefaultsVector IvyDefaults = {
{FONTSIZENAME, FONTSIZEVALUE},
{MAXWIDTHNAME, MAXWIDTHVALUE},
{XOFFSNAME, XOFFSVALUE},
{YOFFSNAME, YOFFSVALUE},
{NULL}
};
/* Enter the defaults into the cache. */
NXRegisterDefaults(DEFAULTOWNER, IvyDefaults);
/* Force a write to the database for each default not already there. */
for (i = 0; IvyDefaults[i].name != NULL; i++)
if (NXReadDefault(DEFAULTOWNER, IvyDefaults[i].name) == NULL)
NXWriteDefault(DEFAULTOWNER, IvyDefaults[i].name, IvyDefaults[i].value);
/*
* Set up the Text
* ===================
* Reads the file, resizes itself. May very well fail.
*/
if (theMiniText = [[MiniText alloc] initFrame:&frame1])
{
Menu *theMenu;
Menu *subMenu;
Window *theWindow;
ScrollView *theScrollView;
NXRect frame2;
const char *defStr;
/*
* Set up the ScrollView
* =========================
* Wrap it around the Text.
*/
[theMiniText getFrame:&frame1];
/* The height may be extravagant for a Window, so limit THAT. */
if (NX_HEIGHT(&frame1) > WINEXT)
NX_HEIGHT(&frame1) = WINEXT;
[ScrollView getFrameSize:&(frame2.size)
forContentSize :&(frame1.size)
horizScroller :NO
vertScroller:YES
borderType:NX_NOBORDER];
theScrollView = [[ScrollView alloc] initFrame:&frame2];
[[theScrollView setDocView:theMiniText] free];
/*
* The ScrollView will resize by default, only its contentView, a
* ClipView won't. It's not accessible from the ScrollView, so we sneak
* up on it from behind...
*/
[[[theMiniText superview]
setAutoresizeSubviews:YES]
setAutosizing:NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
/*
* For things to look ok, the scroller has to be added AFTER the
* docView! As a result, the contentView's size changes. The docView is
* resized also iff the contentView has been set up to
* AutoresizeSubviews! (Which means that the MiniText is uselessly
* rewrapped once or twice)
*/
[theScrollView setVertScrollerRequired:YES];
/*
* Set up the Window
* =====================
*/
[theScrollView getFrame:&frame2];
if ((defStr = NXGetDefaultValue(DEFAULTOWNER, XOFFSNAME)) != NULL)
frame2.origin.x = atof(defStr);
else
frame2.origin.x = XOFFSVALUEFLOAT;
if ((defStr = NXGetDefaultValue(DEFAULTOWNER, YOFFSNAME)) != NULL)
frame2.origin.y = atof(defStr);
else
frame2.origin.y = YOFFSVALUEFLOAT;
[Window getFrameRect:&frame1
forContentRect:&frame2
style:NX_RESIZEBARSTYLE];
theWindow = [[Window alloc] initContent:&frame1
style:NX_RESIZEBARSTYLE
backing:NX_BUFFERED
buttonMask:NX_MINIATURIZEBUTTONMASK | NX_CLOSEBUTTONMASK
defer:YES];
/* This may resize the ScrollView */
[[theWindow setContentView:theScrollView] free];
[theWindow setTitleAsFilename:NXArgv[NXArgc - 1]];
/* see to it that the window is neatly propped up. The text guarantees a maximum width and height, but the offsets from the defaults might have been too large. The height is tested by makeKeyAndOrderFront, too. But this should feel a little more integrated. */
[NXApp getScreenSize: &frame1.size];
[theWindow getFrame: &frame2];
if(frame1.size.width < NX_MAXX(&frame2))
frame1.origin.x = (frame1.size.width - frame2.size.width) / 2;
else
frame1.origin.x = frame2 .origin.x;
if(frame1.size.height < NX_MAXY(&frame2))
frame1.origin.y = (frame1.size.height - frame2.size.height) / 2;
else
frame1.origin.y = frame2 .origin.y;
[theWindow moveTo:frame1.origin.x :frame1.origin.y];
/*
* Set up the Menu
* ===================
*/
theMenu = [[Menu alloc] initTitle:"Ivy"];
/* The Edit Menu */
subMenu = [[Menu alloc] initTitle:"Edit"];
[subMenu addItem:"Cut" action:@selector(cut:) keyEquivalent :'x'];
[subMenu addItem:"Copy" action:@selector(copy:) keyEquivalent :'c'];
[subMenu addItem:"Paste" action:@selector(paste:) keyEquivalent :'v'];
[subMenu addItem:"Select All" action:@selector(selectAll:) keyEquivalent :'a'];
[subMenu sizeToFit];
[[subMenu itemList] setTarget:theMiniText];
[theMenu setSubmenu:subMenu forItem:
[theMenu addItem:"Edit" action:(SEL)nil keyEquivalent:0]];
/* The Print entry */
[theMenu addItem:"Print..."
action:@selector(printPSCode:)
keyEquivalent:'p'];
[[theMenu itemList] setTarget: theMiniText at:1:0];
/* The Services Menu */
subMenu = [[Menu alloc] initTitle:"Services"];
[theMenu setSubmenu:subMenu forItem:
[theMenu addItem:"Services" action:(SEL)nil keyEquivalent:0]];
/* The Hide entry */
[theMenu addItem:"Hide" action:@selector(hide:) keyEquivalent :'h'];
/* The Quit entry */
[theMenu addItem:"Quit" action:@selector(terminate:) keyEquivalent :'q'];
[NXApp setMainMenu:theMenu];
[NXApp setServicesMenu: subMenu];
/*
* Delegating
* ==============
*/
/*
* Being the Window and the Application delegate enables the Text to
* react to window closing.
*/
[theWindow setDelegate:theMiniText];
[NXApp setDelegate:theMiniText];
/*
* Finally, launch
* ===================
*/
[theWindow makeKeyAndOrderFront:NXApp];
/*
* This isn't what I'd call good style, but such a little editor should
* be visible immediately.
*/
[NXApp activateSelf:YES];
[NXApp run];
}
}
else
{
NXRunAlertPanel("Sorry",
"Ivy takes exactly one non-defaults argument: a file to be opened.",
"Terminate", NULL, NULL);
}
[NXApp free];
exit(0);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.