This is ToyViewEvent.m in view mode; [Download] [Up]
#import "ToyView.h"
#import <dpsclient/wraps.h>
#import <dpsclient/event.h>
#import <appkit/publicWraps.h>
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/Application.h>
#import <appkit/NXCursor.h>
#import <appkit/TextField.h>
#import <stdlib.h>
#import "PrefControl.h"
#define CrossCursor "cross.tiff"
static NXCursor *xCursor = nil;
static BOOL originUpperLeft = NO;
@implementation ToyView (EventHandling)
+ cursor
{
if (!xCursor) {
NXPoint spot;
xCursor = [NXCursor newFromImage:[NXImage newFromSection:CrossCursor]];
spot.x = 7.0; spot.y = 7.0;
[xCursor setHotSpot:&spot];
}
return xCursor;
}
+ (BOOL)setOriginUpperLeft:(BOOL)flag
{
BOOL oldflag = originUpperLeft;
originUpperLeft = flag;
return oldflag;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (BOOL)acceptsFirstMouse
{
return YES;
}
- resetCursorRects
{
NXRect visible;
if ([self getVisibleRect:&visible])
[self addCursorRect:&visible cursor:xCursor];
return self;
}
/* Local Method */
- drawDraggedLine: (NXCoord)x : (NXCoord)y : (int)dx : (int)dy
{
char buf[20], points[64];
int y1, y2;
if (originUpperLeft) {
y1 = curSize.height - y - dy;
y2 = curSize.height - y - 1;
}else {
y1 = y, y2 = y + dy - 1;
}
sprintf(points, "%d x %d (%d, %d : %d, %d)",
dx, dy, (int)x, y1, (int)x + dx - 1, y2);
[commText setStringValue: points];
// already 'lockFocus'ed
PSnewinstance();
PSsetinstance(YES);
PSsetlinewidth(0.0);
PSsetgray(0.1667);
PSrectstroke(x, y+1, dx-1, dy-1); /* Why +1 ?? */
if ( dx >= 18 && dy >= 10 ) {
sprintf(buf, "%d x %d", dx, dy);
PSmoveto(x+1, y+2);
PSselectfont("Times-Roman", 12.0);
PSshow(buf);
}
PSsetinstance(NO);
NXPing();
return self;
}
- clearDraggedLine
{
NXSize *sz = &selectRect.size;
if (sz->width > 0.0 || sz->height > 0.0) {
[self lockFocus];
PSnewinstance();
[self unlockFocus];
sz->width = 0.0;
sz->height = 0.0;
[commText setStringValue: comInfo->memo];
}
return self;
}
- setDraggedLine: sender
{
NXSize *sz = &selectRect.size;
if (sz->width > 0.0 && sz->height > 0.0) {
[self lockFocus];
[self drawDraggedLine: selectRect.origin.x
: selectRect.origin.y : sz->width : sz->height];
[self unlockFocus];
}
return self;
}
- rewriteComment
{
[commText setStringValue: comInfo->memo];
return self;
}
#define DRAG_MASK (NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK)
#define PRESS_MASK (NX_MOUSEUPMASK|NX_MOUSEDOWNMASK)
/* Local Method */
- mousePress: (int)count
{
NXRect rect;
if (!comInfo->alpha)
return self;
if (count <= 1) {
if (backgray == 1.0) return self;
backgray = 1.0;
}else if (count > 3) backgray = 0.0;
else backgray = (4 - count) / 3.0;
// Double-click = Light Gray, Triple click = Dark Gray
rect.origin.x = rect.origin.y = 0;
rect.size = curSize;
[self lockFocus];
[self drawSelf:&rect : 1];
[self unlockFocus];
[window flushWindow];
return self;
}
/* Code based on pCD.app (H. Danisch & D. Phillips) */
- mouseDown:(NXEvent *)event
{
NXPoint p, start, lowerleft;
BOOL altDrag = NO, sftDrag = NO;
int oldMask, cn;
int xn = 0, yn = 0, xs, ys;
[self mousePress: (cn = event->data.mouse.click)];
if (cn > 1) return self;
oldMask = [window addToEventMask:DRAG_MASK];
p = event->location;
[self convertPoint:&p fromView:nil]; /* View based point */
if (p.x < 0.0) p.x = 0.0;
else if (p.x >= curSize.width) p.x = curSize.width - 1;
p.y--;
if (p.y < 0.0) p.y = 0.0;
else if (p.y > curSize.height) p.y = curSize.height - 1;
start.x = (int)p.x;
start.y = (int)p.y;
if (NX_ALTERNATEMASK & event->flags)
altDrag = YES;
[self lockFocus];
PSnewinstance();
PSsetinstance(YES);
event = [NXApp getNextEvent:DRAG_MASK];
while( event->type != NX_MOUSEUP ) {
if (NX_ALTERNATEMASK & event->flags)
altDrag = YES;
if (NX_SHIFTMASK & event->flags)
sftDrag = YES;
p = event->location;
[self convertPoint:&p fromView:nil];
if (p.x < 0.0) p.x = 0.0;
else if (p.x >= curSize.width) p.x = curSize.width - 1;
p.y--;
if (p.y < 0.0) p.y = 0.0;
else if (p.y > curSize.height) p.y = curSize.height - 1;
if (p.x > start.x)
xn = (int)p.x - start.x + 1, xs = 1;
else
xn = start.x - (int)p.x + 1, xs = -1;
if (p.y > start.y)
yn = (int)p.y - start.y + 1, ys = 1;
else
yn = start.y - (int)p.y + 1, ys = -1;
if (altDrag) {
if (xn < yn) yn = xn;
else xn = yn;
}
if (sftDrag) {
xn = (xn + 1) & ~3;
yn = (yn + 1) & ~3;
}
p.x = start.x + (xn-1)*xs;
p.y = start.y + (yn-1)*ys;
lowerleft.x = (start.x < p.x) ? start.x : p.x;
lowerleft.y = (start.y < p.y) ? start.y : p.y;
[self drawDraggedLine: lowerleft.x : lowerleft.y : xn : yn];
event = [NXApp getNextEvent:DRAG_MASK];
}
[self unlockFocus];
selectRect.origin.x = lowerleft.x;
selectRect.origin.y = lowerleft.y;
selectRect.size.width = xn;
selectRect.size.height = yn;
if (xn == 0 && yn == 0) /* only click */
[commText setStringValue: comInfo->memo];
else if (xn < 3 && yn < 3) /* Too small area */
[self clearDraggedLine];
[window flushWindow];
[window setEventMask:oldMask];
return self;
}
- selectAll:sender
{
[self clearDraggedLine];
selectRect.size = curSize;
selectRect.origin.x = selectRect.origin.y = 0.0;
[self setDraggedLine: sender];
return self;
}
- copy:sender
{
NXStream *st;
NXBitmapImageRep *bm;
int i = 0;
const char *types[2];
id pb = [Pasteboard new];
if (selectRect.size.width < 1.0 || selectRect.size.height < 1.0) {
NXBeep();
return self;
}
// note that "owner:" in the following can not be "self", or the
// id of anything else which might be freed inbetween "Copy"
// operations.
types[i++] = NXTIFFPboardType;
[pb declareTypes:types num:i owner:NXApp];
[self lockFocus];
bm = [[NXBitmapImageRep alloc] initData:NULL fromRect:&selectRect];
[self unlockFocus];
st = NXOpenMemory(NULL, 0, NX_WRITEONLY);
[bm writeTIFF:st];
[pb writeType:NXTIFFPboardType fromStream:st];
NXCloseMemory(st, NX_FREEBUFFER);
[bm free];
return self;
}
- drawSelf:(NXRect *)r :(int) count
{
NXSize *sz;
if (comInfo->alpha) {
PSsetgray(backgray);
NXRectFill(r);
[image composite:NX_SOVER fromRect:r toPoint:&(r->origin)];
}else
[image composite:NX_COPY fromRect:r toPoint:&(r->origin)];
sz = &selectRect.size;
if (sz->width > 0.0 && sz->height > 0.0)
[self perform:@selector(setDraggedLine:) with:self
afterDelay:30 cancelPrevious:YES];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.