This is MiscSwapView.m in view mode; [Download] [Up]
/* MiscSwapView.m
*
* This subclass of View is able to swap different views into itself. It's
* used to implement any kind of multipage windows. (Inspectors, Prefs...)
*
* For more interface-info see the header file. More in depth information
* can be found here in the source-code.
*
* Notes: There is one Cateogry for this class includes automatic swapping.
*
* Improved by: Thomas Engel
* First changes: 24.01.1994 (Copyleft)
* Last modified: 27.07.1997
* Copyright (C) 1995 Thomas Engel
*/
#import "MiscSwapView.h"
#import "MiscSwapViewItem.h"
// The following are for keeping track of versions when archiving instances
// of this class. If you change the encodeWithCoder: method, make sure to
// bump up the version below and make the appropriate changes to the initWithCoder:
// method so all previously archived instances will be unarchivable.
#define MISC_SV_VERSION 2
#define MISC_SV_CLASSNAME @"MiscSwapView"
@implementation MiscSwapView
+ (void)initialize
{
// Initialize the current version number which is used when archiving
// objects. This way we will be able to read all versions if we are
// careful.
if( self == [MiscSwapView class] ) [self setVersion: MISC_SV_VERSION];
}
- (id)init
{
NSRect theFrame = {{0.0, 0.0}, {0.0, 0.0}};
return [self initWithFrame: theFrame];
}
- (id)initWithFrame:(NSRect)frameRect
{
// Designated initilizer. We will set allow resizing by default and
// we will draw in Lightgray if we have to swap 'nil' in.
self = [super initWithFrame:frameRect];
if( !self ) return nil;
// All instances can remain nil .. we just have a few settings to make.
backgroundColor = [NSColor controlBackgroundColor];
[self setDrawsBackground:NO];
// Well the ByObject Category want's some other defaults too.
itemArray = [NSMutableArray new];
[self setTagComparison:YES];
[self awake];
return self;
}
- (void)dealloc
{
// We do not free the contentsitemArray of this list! Well we didin't
// allocate them..but maybe we should free them...hmmm. I'm not sure yet.
[contentView release];
[contentViewsHomeView release];
[self _unregisterNotificationObserver:delegate];
[delegate release];
[backgroundColor release];
[identifier release];
// Before release our items...we will first remove them... this ensures that they are properly removed
// from all our notifications.
[self removeAllSwapViewItems];
[itemArray release];
[currentSwapItem release];
[super dealloc];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
int version;
[super initWithCoder:aDecoder];
version = [aDecoder versionForClassName:MISC_SV_CLASSNAME];
switch (version)
{
case 0:
// <<HACK>> We should never get that one since this was the encoding of the NeXTSTEP version of this class.
break;
case 1:
// We skip this version so that we can start of with encoding #2 since this is
// mapping a lot better MiscKit 2.0
break;
case 2:
contentView = [[aDecoder decodeObject] retain]; // These usually should be nil !!
contentViewsHomeView = [[aDecoder decodeObject] retain]; // These usually should be nil !!
delegate = [[aDecoder decodeObject] retain];
backgroundColor = [[aDecoder decodeObject] retain];
identifier = [[aDecoder decodeObject] retain];
[aDecoder decodeValueOfObjCType:"c" at:&tagComparison];
[aDecoder decodeValueOfObjCType:"c" at:&backgroundDrawing];
[aDecoder decodeValueOfObjCType:"i" at:&alignment];
currentSwapItem = nil;
itemArray = [NSMutableArray new];
default:
break;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeConditionalObject:contentView];
[aCoder encodeConditionalObject:contentViewsHomeView];
[aCoder encodeConditionalObject:delegate];
[aCoder encodeObject:backgroundColor];
[aCoder encodeConditionalObject:identifier];
[aCoder encodeValueOfObjCType:"c" at:&tagComparison];
[aCoder encodeValueOfObjCType:"c" at:&backgroundDrawing];
[aCoder encodeValueOfObjCType:"i" at:&alignment];
}
- (void)awake
/*"
This is a general awake method which can be reused by all different awake methods.
"*/
{
// <<HACK>> This is a really evil and mean hack. I have not had the time to check out the details.
// But for some strage reasons our autoresize state is NO after we get unarchived from a NIB.
// This caused the UI's not to resize properly. However...since the default NSView subclass should be
// autoresizign its subviews by default...I really have no clue what is going wrong where.
// Ergo: This is a fix...but definitly uncool.
[self setAutoresizesSubviews:YES];
}
- (void)awakeFromNib
/*"
Awake the object after getting instantiated from a NIB.
"*/
{
// Nothing to do here...we already handle the coder based awaking so that does a proper awake in our case.
}
- (id)awakeAfterUsingCoder:(NSCoder *)aCoder
/*"
Perform awaking after unarchiving from a stream controlled by aCoder.
"*/
{
[self awake];
return self;
}
- (void)setDelegate:(id)anObject
/*"
Sets our delegate and registers it with all our notifications.
"*/
{
if( delegate == anObject ) return;
[self _unregisterNotificationObserver:delegate];
[self _registerNotificationObserver:anObject];
// Changing of the guards...
[delegate release];
delegate = [anObject retain];
}
- (id)delegate
/*"
Returns our current delegate.
"*/
{
return delegate;
}
- (void)setBackgroundColor:(NSColor *)aColor
/*"
Sets our background color to aColor. The default is NSColor's controlBackgroundColor.
"*/
{
// <<NOTE>> There was something about releasing colors. ??
[backgroundColor autorelease];
backgroundColor = [aColor retain];
}
- (NSColor *)backgroundColor
/*"
Returns our background color.
"*/
{
return backgroundColor;
}
- (void)setDrawsBackground:(BOOL)flag
/*"
Returns our background color. By default this is set to NO.
"*/
{
backgroundDrawing = flag;
}
- (BOOL)drawsBackground
/*"
Returns YES if we have to draw our background and NO otherwise.
"*/
{
return backgroundDrawing;
}
- (BOOL)isOpaque
{
if( backgroundDrawing &&
[backgroundColor alphaComponent] == 1.0 )
return YES;
return NO;
}
- (void)setContentView:(NSView *)aView
/*"
This method explicitly puts in a new subview and puts the current content view back to were it came from.
"*/
{
// This is the real method !!
// Here we process the swapping and resizing.
// If the new view is different from our current contentView we should
// put the current back where it came from.
if( aView != contentView )
{
// This is the place to fire off some notifications since we will be changing our contentView
if( contentView && contentViewsHomeView )
{
//<<BUG>> this actually needs some different handling if our views do _not_ have
// a superview !! This currently is a hack that works perfectly if you set up things inside
// IB and don't create views programatically.
[contentViewsHomeView addSubview:contentView];
[contentView setFrame:contentViewsHomeRect];
// We don't need that one...but all these retain release lines make sure that the views stay around
// In a later version we might go through the code an remove the unnecessary ones...but since I don't
// want to possible break this class I'll just keep it that way for now.
[contentViewsHomeView release];
[contentView release];
contentViewsHomeView = nil;
contentView = nil;
}
// If we really have a subview we will take care of it.
if( aView )
{
NSSize newSize;
contentView = [aView retain];
contentViewsHomeView = [[contentView superview] retain];
contentViewsHomeRect = [contentView frame];
[self addSubview:contentView];
// <<HACK>> This needs some additional work since we have not yet considered the alignment
// settings.
[contentView setFrameOrigin:NSMakePoint(0.0, 0.0)];
newSize = [self bounds].size;
if( !([contentView autoresizingMask] & NSViewWidthSizable) )
newSize.width = contentViewsHomeRect.size.width;
if( !([contentView autoresizingMask] & NSViewHeightSizable) )
newSize.height = contentViewsHomeRect.size.height;
[contentView setFrameSize:newSize];
}
[self display];
}
}
- (NSView *)contentView
{
return contentView;
}
- (void)drawRect:(NSRect)rect
{
if( [self drawsBackground] )
{
[backgroundColor set];
NSRectFill( rect );
}
// As long as you have a identifier (e.g. button) connected to the identifier outlet, this
// should select an initial view for you automatically on the first draw.
// IMHO there should be a better place to drop this !
if( contentView == nil ) [self swapContentView:identifier];
}
@end
/*
* History: 25.09.94 Added archiving. (read:, write: awake, initialize)
* Also added drawSelf:: so it would select an initial view.
*
* 24.02.94 Added Greg's quick composing.
*
* 24.01.94 Redesign from my old swapView. Added Buffering.
*
* 21.01.94 Added the resizing job the Greg's swapView.
*
*
* Bugs: - Could be. Yes.
*/These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.