This is PatchWindow.m in view mode; [Download] [Up]
// PatchWindow.m
// By Jayson Adams, NeXT Developer Support Team
// You may freely copy, distribute and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.
#import <stdlib.h>
#import <objc/Storage.h>
#import "PatchView.h"
#import "PatchWindow.h"
#define NOVIEWRECT -1
typedef struct _ViewRectPair {
id view;
NXRect rect;
} ViewRectPair;
@implementation PatchWindow
/* instance methods */
- initContent:(const NXRect *)contentRect style:(int)aStyle
backing:(int)bufferingType buttonMask:(int)mask defer:(BOOL)flag
{
[super initContent:contentRect
style:aStyle
backing:bufferingType
buttonMask:mask
defer:flag];
viewRectList = [[Storage alloc] initCount:0
elementSize:sizeof(ViewRectPair)
description:"{@ffff}"];
viewRectUnderPoint = NOVIEWRECT;
return self;
}
- registerRect:(NXRect *)rect forView:view
{
ViewRectPair *newViewRect;
/* add the view-rect pair to our list */
newViewRect = (ViewRectPair *)malloc(sizeof(ViewRectPair));
newViewRect->view = view;
newViewRect->rect = *rect;
[viewRectList addElement:newViewRect];
return self;
}
- (BOOL)windowEntered:(NXPoint *)mouseLocation fromSource:dragSource
{
NXPoint windowPoint;
int newViewRectUnderPoint;
ViewRectPair *viewRect, *oldViewRect;
BOOL oldViewDrew = NO, newViewDrew = NO;
/* convert the mouse location to local coordinates */
windowPoint = *mouseLocation;
[self convertScreenToBase:&windowPoint];
/* see if any of the views in our list lay under the mouse point */
newViewRectUnderPoint = [viewRectList count];
while (newViewRectUnderPoint--) {
viewRect = (ViewRectPair *)[viewRectList
elementAt:newViewRectUnderPoint];
if (NXPointInRect(&windowPoint, &(viewRect->rect))) {
break;
}
}
/* see if the mouse has moved over a different view */
if (viewRectUnderPoint != newViewRectUnderPoint) {
/* tell the view previously under the mouse that the window has exited */
if (viewRectUnderPoint != NOVIEWRECT) {
oldViewRect = (ViewRectPair *)[viewRectList
elementAt:viewRectUnderPoint];
oldViewDrew = [oldViewRect->view windowExited:dragSource];
}
/* save the new view under the mouse */
viewRectUnderPoint = newViewRectUnderPoint;
/*
* if there's a view under the mouse point, tell it that a window has
* entered it
*/
if (viewRectUnderPoint != NOVIEWRECT) {
viewRect = (ViewRectPair *)[viewRectList
elementAt:viewRectUnderPoint];
newViewDrew = [viewRect->view windowEntered:dragSource];
}
}
/* let the caller know if any of our views has done any drawing */
return (oldViewDrew || newViewDrew);
}
- (BOOL)windowExited:dragSource
{
ViewRectPair *viewRect;
BOOL viewDrew = NO;
/* tell any view previously under the mouse point that it no longer is */
if (viewRectUnderPoint != NOVIEWRECT) {
viewRect = [viewRectList elementAt:viewRectUnderPoint];
viewDrew = [viewRect->view windowExited:dragSource];
viewRectUnderPoint = NOVIEWRECT;
}
/* tell the caller whether or not the view did some drawing */
return viewDrew;
}
- (BOOL)windowDropped:(NXPoint *)mouseLocation fromSource:source
{
NXPoint windowPoint;
int newViewRectUnderPoint;
ViewRectPair *viewRect;
BOOL accepted = NO;
/* convert the mouse location to local coordinates */
windowPoint = *mouseLocation;
[self convertScreenToBase:&windowPoint];
/* see if any of the views in our list lay under the mouse point */
newViewRectUnderPoint = [viewRectList count];
while (newViewRectUnderPoint--) {
viewRect = (ViewRectPair *)[viewRectList
elementAt:newViewRectUnderPoint];
if (NXPointInRect(&windowPoint, &(viewRect->rect))) {
break;
}
}
/* tell any view previously under the mouse point that the window moved */
if (viewRectUnderPoint != NOVIEWRECT &&
viewRectUnderPoint != newViewRectUnderPoint) {
viewRect = (ViewRectPair *)[viewRectList elementAt:viewRectUnderPoint];
[viewRect->view windowExited:source];
}
/*
* tell the view under the mouse point (if any) that the user dropped a
* window on it
*/
if (newViewRectUnderPoint != NOVIEWRECT) {
viewRect = (ViewRectPair *)[viewRectList
elementAt:newViewRectUnderPoint];
accepted = [viewRect->view windowDropped:source:&windowPoint];
}
/* no window under the mouse now */
viewRectUnderPoint = NOVIEWRECT;
return accepted;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.