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.