This is Window.m in view mode; [Download] [Up]
/* Implementation of Window class
*
* Copyright (C) 1993 The Board of Trustees of
* The Leland Stanford Junior University. All Rights Reserved.
*
* Authors: Scott Francis, Paul Kunz, Tom Pavel,
* Imran Qureshi, and Libing Wang (SLAC)
* Mike Kienenberger (Alaska)
*
* This file is part of an Objective-C class library for a window system
*
* Window.m,v 1.120 1995/12/13 22:33:26 fedor Exp
*/
#include "Window.h"
/* Required for implementation: */
#include "Application.h"
#include "Menu.h"
#include "Responder.h"
#include "CustomView.h"
#include <objc/List.h>
#include <stdlib.h> /* for free() */
#include <objc/hashtable.h>
#ifdef sgi
#include <malloc.h> /* although you might need to edit malloc.h */
#endif /* sgi */
#include "Scroller.h"
#include <objc/typedstream2.h>
#ifdef RESIZE_DEBUG
#include <Xm/Xm.h> /* Position, Dimension declarations for debugging */
#endif /* RESIZE_DEBUG */
extern char *WindowInstanceName( void );
/* private View methods */
@interface View(WidgetSet)
- _flushView;
@end
@implementation Window
/* Factory methods */
+ alloc
{
self = [super alloc];
return self;
}
/* Public methods */
- init
{
NXRect defaultRect = { {0, 0}, {612, 792} };
return [self initContent:&defaultRect style:0
backing:0
buttonMask:0
defer:YES
screen:(const NXScreen *)NULL];
}
- initContent:(const NXRect *)contentRect
{
return [self initContent:contentRect style:0
backing:0
buttonMask:0
defer:YES
screen:(const NXScreen *)NULL];
}
- initContent:(const NXRect *)contentRect style:(int)aStyle
backing:(int)bufferingType
buttonMask:(int)mask
defer:(BOOL)flag
{
return [self initContent:contentRect style:aStyle
backing:bufferingType
buttonMask:mask
defer:flag
screen:(const NXScreen *)NULL];
}
- initContent:(const NXRect *)contentRect style:(int)aStyle
backing:(int)bufferingType
buttonMask:(int)mask
defer:(BOOL)flag
screen:(const NXScreen *)screen
{
View *aView;
[super init];
_inResizeFlag = NO;
wFlags.style = aStyle;
wFlags.backing = bufferingType;
wFlags.buttonMask = mask;
wFlags.visible = NO;
wFlags.isMainWindow = NO;
wFlags.isKeyWindow = NO;
wFlags.isPanel = NO;
wFlags.hideOnDeactivate = NO;
wFlags.dontFreeWhenClosed = NO;
wFlags.oneShot = NO;
wFlags2.deferred = flag;
wFlags2.docEdited = NO;
wFlags2.dynamicDepthLimit = NO;
instancename = WindowInstanceName();
if ( !title ) {
title = NXCopyStringBuffer("Untitled");
}
/* Make room for title bar and resize bar */
NX_X(&frame) = NX_X(contentRect) - 1;
NX_Y(&frame) = NX_X(contentRect) - 9;
NX_WIDTH(&frame) = NX_WIDTH(contentRect) + 2;
NX_HEIGHT(&frame) = NX_HEIGHT(contentRect) + 9 + 23;
_contentViewFrameRect = *contentRect;
NX_X(&_contentViewFrameRect) = 1;
NX_Y(&_contentViewFrameRect) = 9;
aView = [[View alloc] initFrame:&_contentViewFrameRect];
[self setContentView:aView];
[self _initFrame];
if (wFlags2.deferred == NO) {
[self _setWindowAreas];
[self _realize];
}
return self;
}
- setHasMenu:(BOOL)menuFlag hasScroller:(BOOL)scrolFlag
{
hasMenu = menuFlag;
hasScroller = scrolFlag;
return self;
}
- free
{
if (title) {
free(title);
}
[NXApp _removeWindow:self];
[contentView free];
[menu free];
if (hasScroller) {
[verticalScrol free];
[horizontalScrol free];
}
return [super free];
}
- setTitle:(const char*)aString
{
if ( title ) {
free(title);
}
title = NXCopyStringBuffer(aString);
[self _setTitle];
return self;
}
- (const char *)title;
{
return title;
}
- (int) windowNum;
{
return windowNum;
}
- setContentView:aView
{
View *temp;
temp = contentView;
[temp _setWindow:nil];
if (nil != aView)
{
[aView getFrame:&_contentViewFrameRect];
contentView = aView;
[aView _setWindow:self];
}
else
{
_contentViewFrameRect.size.width = -1;
_contentViewFrameRect.size.height = -1;
_contentViewFrameRect.origin.x = -1;
_contentViewFrameRect.origin.y = -1;
contentView = nil;
}
return temp;
}
- setMenu:(id)aMenu
{
menu = aMenu;
hasMenu = YES;
[self _setWindowAreas];
return self;
}
- contentView
{
return contentView;
}
- delegate
{
return delegate;
}
- setDelegate:newDelegate
{
delegate = newDelegate;
return self;
}
- becomeMainWindow
{
wFlags.isMainWindow = YES;
if ( delegate && [delegate respondsTo:@selector(windowDidBecomeMain:) ] ) {
[delegate windowDidBecomeMain:self];
}
return self;
}
- resignMainWindow
{
wFlags.isMainWindow = NO;
if ( delegate && [delegate respondsTo:@selector(windowDidResignMain:) ] ) {
[delegate windowDidResignMain:self];
}
return self;
}
- orderOut:sender
{
if (NO == wFlags.visible) return self;
[self resignMainWindow];
wFlags.visible = NO;
[NXApp _removeWindow:self];
[self _orderOut];
return self;
}
- setMiniwindowIcon:(const char *)anIcon
{
return self;
}
- orderFront:sender
{
if (YES == wFlags.visible) return self;
[self _setWindowAreas];
[NXApp _willBecomeMain:self];
[NXApp _addWindow:self];
wFlags.visible = YES;
[self _realize];
[self _orderFront];
return self;
}
- orderBack:sender
{
return self;
}
- makeKeyAndOrderFront:sender
{
[self makeKeyWindow];
[self orderFront:self];
return self;
}
- getFrame:(NXRect *)theRect
{
*theRect = frame;
return self;
}
- (int)style
{
return (int)wFlags.style;
}
- performClose:sender
{
if (delegate && [delegate respondsTo:@selector(windowWillClose:)])
{
if (![delegate perform:@selector(windowWillClose:) with:self])
return nil;
}
return [self close];
}
- setDocEdited:(BOOL)flag
{
wFlags2.docEdited = YES;
return self;
}
- (BOOL)isDocEdited
{
return (BOOL)wFlags2.docEdited;
}
- (BOOL)isVisible
{
return (BOOL)wFlags.visible;
}
/* Handle a window expose event. This routine should only get called if the
Window is NX_NONRETAINED
*/
- windowExposed:(NXEvent *)theEvent
{
// Here we should figure out which views need re-display and tell them that
// for now, do nothing...
if ([delegate respondsTo:@selector(windowDidExpose:)])
[delegate windowDidExpose:self];
return self;
}
- (BOOL)isKeyWindow
{
return (BOOL)wFlags.isKeyWindow;
}
- (BOOL)isMainWindow
{
return wFlags.isMainWindow;
}
// - (BOOL)canBecomeKeyWindow;
- (BOOL)canBecomeMainWindow
{
if ( wFlags.isPanel ) {
return NO;
}
return YES;
}
// - (BOOL)worksWhenModal;
// - convertBaseToScreen:(NXPoint *)aPoint;
// - convertScreenToBase:(NXPoint *)aPoint;
- getFieldEditor:(BOOL)createFlag for:anObject
{
/* No field editor yet */
return nil;
}
// - endEditingFor:anObject;
// - placeWindowAndDisplay:(const NXRect *)frameRect;
- placeWindow:(const NXRect *)frameRect
/* There very well may be a subtlety to this function that we are
missing or didn't notice in NeXT docs...
*/
{
frame = *frameRect;
return self;
}
- _resizeWindow:(const NXRect *)frameRect
{
NXRect oldFrame = frame;
#ifdef RESIZE_DEBUG
Position x,y;
Dimension w,h;
if (YES == _inResizeFlag)
{
fprintf(stderr, "skipping window size event (%d, %d), (%d, %d)\n",
frameRect->origin.x, frameRect->origin.y,
frameRect->size.width, frameRect->size.height);
}
#endif /* RESIZE_DEBUG */
_inResizeFlag = YES;
#ifdef RESIZE_DEBUG
fprintf(stderr, "\nwindow size was (%d, %d), (%d, %d)\n",
frame.origin.x, frame.origin.y,
frame.size.width, frame.size.height);
XtVaGetValues(widgetid, XmNx, &x, NULL);
XtVaGetValues(widgetid, XmNy, &y, NULL);
XtVaGetValues(widgetid, XmNwidth, &w, NULL);
XtVaGetValues(widgetid, XmNheight, &h, NULL);
fprintf(stderr, "widget size was (%d, %d), (%d, %d)\n",
(int)x, (int)y, (int)w, (int)h);
fprintf(stderr, "contentView size was (%d, %d), (%d, %d)\n",
_contentViewFrameRect.origin.x, _contentViewFrameRect.origin.y,
_contentViewFrameRect.size.width,
_contentViewFrameRect.size.height);
XtVaGetValues([contentView _widget], XmNx, &x, NULL);
XtVaGetValues([contentView _widget], XmNy, &y, NULL);
XtVaGetValues([contentView _widget], XmNwidth, &w, NULL);
XtVaGetValues([contentView _widget], XmNheight, &h, NULL);
fprintf(stderr, "widget size was (%d, %d), (%d, %d)\n",
(int)x, (int)y, (int)w, (int)h);
XtVaGetValues(_shell, XmNx, &x, NULL);
XtVaGetValues(_shell, XmNy, &y, NULL);
XtVaGetValues(_shell, XmNwidth, &w, NULL);
XtVaGetValues(_shell, XmNheight, &h, NULL);
fprintf(stderr, "shell size was (%d, %d), (%d, %d)\n",
(int)x, (int)y, (int)w, (int)h);
fprintf(stderr, "window size will change to (%d, %d), (%d, %d)\n",
frameRect->origin.x, frameRect->origin.y,
frameRect->size.width, frameRect->size.height);
#endif /* RESIZE_DEBUG */
frame.size.height = frameRect->size.height;
frame.size.width = frameRect->size.width;
// frame.origin.x = frameRect->origin.x;
// frame.origin.y = frameRect->origin.y;
// XtVaGetValues(widgetid, XmNwidth, &w, NULL);
// XtVaGetValues(widgetid, XmNheight, &h, NULL);
// frame.size.width = w;
// frame.size.height = h;
// frame.origin.x = oldFrame.origin.x;
// frame.origin.y = oldFrame.origin.y;
[contentView _windowRectChangedFrom:&oldFrame to:&frame];
_inResizeFlag = NO;
return self;
}
- (void)saveFrameToString:(char *)string
{
sprintf( string, "%d %d %d %d",
frame.origin.x, frame.origin.y,
frame.size.width, frame.size.height);
return;
}
- (void)setFrameFromString:(const char *)frameString
{
sscanf(frameString, "%d%d%d%d",
&(frame.origin.x), &(frame.origin.y),
&(frame.size.width), &(frame.size.height));
return;
}
- read:(TypedStream*)typedStream
{
int anInt;
char aChar;
[super read:typedStream];
NXReadRect(typedStream,&frame);
objc_read_string(typedStream,&title);
objc_read_object(typedStream,&contentView);
[contentView getFrame:&_contentViewFrameRect];
objc_read_type( typedStream, "i", &anInt );
wFlags.style = anInt & 0xF;
objc_read_type( typedStream, "i", &anInt );
wFlags.backing = anInt & 0x3;
objc_read_type( typedStream, "i", &anInt );
wFlags.buttonMask = anInt & 0x7;
objc_read_type( typedStream, "c", &aChar );
wFlags.visible = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags.isMainWindow = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags.isKeyWindow = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags.isPanel = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags.hideOnDeactivate = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags.dontFreeWhenClosed = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags.oneShot = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags2.deferred = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags2.docEdited = (0 != aChar);
objc_read_type( typedStream, "c", &aChar );
wFlags2.dynamicDepthLimit = (0 != aChar);
return self;
}
- awake
{
if (widgetid)
return self;
_inResizeFlag = NO;
[self _initFrame];
return self;
}
- awakeFromNib
{
View *custom;
/*
* what's implmented here is that which has to wait until all objects in the
* heirarchy get a chance to receive their awake method.
*/
if ( [contentView isKindOf:[CustomView class]] ) {
custom = contentView;
contentView = [(CustomView *)custom nibInstantiate];
[custom free];
} else {
[contentView awakeFromNib];
}
if (nil != contentView)
{
[contentView getFrame:&_contentViewFrameRect];
[contentView _setWindow:self];
}
if ( wFlags.visible )
{
wFlags.visible = NO;
[self orderFront:nil];
}
// Note: _setWindowAreas will create the widgetid for contentView
// and all subviews. But this Window might be just a holder
// for a view that goes into a box or something. Thus, we
// should defer no matter what the flag says -- Paul Kunz
// if (wFlags2.deferred == NO) {
// [self _setWindowAreas];
// [self _realize];
// }
return self;
}
- makeKeyWindow
{
return self;
}
- close
{
[self orderOut:self];
if (!wFlags.dontFreeWhenClosed) [self free];
return self;
}
- setFreeWhenClosed:(BOOL)flag
{
wFlags.dontFreeWhenClosed = !flag;
return self;
}
- makeFirstResponder:aResponder
{
return self;
}
- setTitleAsFilename:(const char *)aString
{
return self;
}
- firstResponder
{
return self;
}
- disableDisplay
{
displaying = NO;
return self;
}
- reenableDisplay
{
displaying = YES;
return self;
}
- displayIfNeeded
{
/* Probably don't need this method under X */
return self;
}
- display
{
return self;
}
- update
{
if ( delegate && [delegate respondsTo:@selector(windowDidUpdate:) ] ) {
[delegate windowDidUpdate:self];
}
return self;
}
- (int)setEventMask:(int)newMask
{
return 0;
}
- (int)addToEventMask:(int)newEvents
{
return 0;
}
- (int)removeFromEventMask:(int)oldEvents
{
return 0;
}
- (int)eventMask
{
return 0;
}
- sizeWindow:(NXCoord)width :(NXCoord)height
/*
Checks for delegate method first, if delegate returns anything
other than nil, execute resize code.
NOTE: there is some code here, but this is not a fully
functional method. It doesn't handle subviews at all for
instance!
*/
{
// Here we would need to resize subviews of this window accordingly...
// we may not support this...
NXSize temp;
temp.width = width;
temp.height = height;
if (delegate && [delegate respondsTo:@selector(windowWillResize:toSize:)]
&& ([delegate perform:@selector(windowWillResize:)
with:self with:(id)&temp]))
{
frame.size.width = width;
frame.size.height = height;
return self;
}
return self;
}
/* Returns the gstate of our contentView (at least in X-Windows)
*/
- (int)gState
{
int gstate;
gstate = [contentView gState];
if (!gstate) {
// We really want a gstate for our contentView
[contentView allocateGState];
[contentView lockFocus];
[contentView unlockFocus];
gstate = [contentView gState];
}
return gstate;
}
- setBackingType:(int)bufferingType
{
// NOT IMPLEMENTED
return nil;
}
- (int)backingType
{
return wFlags.backing;
}
- flushWindow
{
[contentView _flushView];
return self;
}
- disableFlushWindow
{
return self;
}
- reenableFlushWindow
{
return self;
}
- (BOOL)setFrameAutosaveName:(const char *)name
{
/*
* This fancy feature we don't need now. Wasn't even in NeXTSTEP until 3.0
*/
return NO;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.