ftp.nice.ch/pub/next/graphics/viewer/ToyViewer.2.6a.s.tar.gz#/ToyViewer2.6a/src/ToyWin.m

This is ToyWin.m in view mode; [Download] [Up]

#import <appkit/Application.h>
#import <appkit/publicWraps.h>
#import <appkit/Control.h>
#import <appkit/TextField.h>
#import <appkit/ScrollView.h>
#import <appkit/Panel.h>
#import <appkit/graphics.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import "ToyWin.h"
#import "ToyView.h"
#import "TVController.h"
#import "strfunc.h"

#define  MiniIcon	"miniwin.tiff"
#define  DiffStep	18.0
#define  MinWinXSIZE	120.0
#define  MinWinYSIZE	32.0
#define  MinResizeXSIZE	200.0
#define  MinResizeYSIZE	150.0
#define  FixedXPos	280.0
#define  FixedYPos	12.0


@implementation ToyWin

/* extern */ BOOL displayOverKeyWindowFlag = NO;

+ (BOOL)displayOverKeyWindow:(BOOL)flag
{
	BOOL old = displayOverKeyWindowFlag;
	displayOverKeyWindowFlag = flag;
	return old;
}

- init
{
	parental = nil;
	operation = 0;
	scaleFactor = 1.0;
	imageFilename = NULL;
	miniFlag = mini_YET;
	makeMapOnly = NO;
	return self;
}

- init: parent by:(int)op
{
	[self init];
	[NXApp loadNibSection:"ToyWin.nib" owner:self];
	[thiswindow setFreeWhenClosed: YES];
	parental = parent;
	operation = op;
	return self;
}

- initMapOnly
{
	/* An instance of ToyWin initialized by this method does not
		display a window.  It is used to make the bitmap of
		a image file to support pasteboard service. */
	[self init];
	makeMapOnly = YES;
	return self;
}

- free
{
	// printf("FREE(%s)\n", imageFilename);
	if (imageFilename) free((void *)imageFilename);
	if (scalePanel) [scalePanel free];
	[super free];
	return nil;
}

- (const char *)filename
{
	return (const char *)imageFilename;
}

- resetFilename:(const char *)fileName
{
	if (imageFilename) free((void *)imageFilename);
	imageFilename = str_dup(fileName);
	[thiswindow setTitleAsFilename: imageFilename];
	return self;
}

- (Window *)window
{
	return thiswindow;
}

- toyView
{
	return [scView docView];
}

- parent
{
	return parental;
}

- (int)madeby
{
	return operation;
}

/* ----------------------------------------------------------------
¡ü¥¦¥£¥ó¥É¥¦¥µ¥¤¥º·èÄêÊý¿Ë
¢¦½é´ü²½»þ
    ¡¦É½¼¨¥µ¥¤¥º
	²èÁü¤ÎÂ礭¤µ¤Ë¹ç¤ï¤»¤ë¡£
	¤¿¤À¤·¡¢¥¹¥¯¥ê¡¼¥óÉý¤è¤ê²èÁüÉý¤¬Â礭¤¤¾ì¹ç¤Ï¥¹¥¯¥ê¡¼¥óÉý¡£
	¹â¤µ¤âƱÍÍ¡£
	¤Þ¤¿¡¢¤·¤­¤¤ÃÍ(MinWinXSIZE=120, MinWinYSIZE=32)¤è¤ê¾®¤µ¤¤
	¾ì¹ç¤Ï¤·¤­¤¤Ãͤò»È¤¦¡£
    ¡¦É½¼¨°ÌÃÖ
	atpoint¤Î°ÌÃÖ¤Ëɽ¼¨¡£NULL¤Ê¤é¥¦¥£¥ó¥É¥¦¤ÎÈÖ¹æ¤Ë¤è¤Ã¤Æ·èÄê¡£
	¤¿¤À¤·¡¢¥¹¥¯¥ê¡¼¥óÉý¤è¤ê²èÁüÉý¤¬Â礭¤¤¾ì¹ç¤Ïº¸Ã¼¡£
	¥¹¥¯¥ê¡¼¥ó¹â¤è¤ê²èÁü¹â¤¬Â礭¤¤¾ì¹ç¤Ï¾åü¡£
    ¡¦¥ê¥µ¥¤¥º¤ÎºÇÂ祵¥¤¥º
	²èÁü¼«ÂΤÎÂ礭¤µ¤Ë¹ç¤ï¤»¤ë¡£
	¡Êº£¤Î¤È¤³¤í¡¢¥¹¥¯¥ê¡¼¥ó¤ÎÂ礭¤µ¤Ç²¡¤µ¤¨¤ë¤³¤È¤Ï¤·¤Ê¤¤¡Ë
    ¡¦¥ê¥µ¥¤¥º¤ÎºÇ¾®¥µ¥¤¥º
	Äê¿ô(MinResizeXSIZE=200, MinResizeYSIZE=150)¤È¤¹¤ë¡£
	¤¿¤À¤·¡¢¤³¤ì¤è¤ê²èÁü¤¬¾®¤µ¤¤¾ì¹ç¤Ï²èÁü¤Ë¹ç¤ï¤»¤ë¡£
¢¦¥¤¥á¡¼¥¸¤Î¥ê¥µ¥¤¥º»þ
    ¡¦É½¼¨¥µ¥¤¥º
	¸µ¤è¤êÂ礭¤¯¤Ê¤Ã¤¿¾ì¹ç¤ÏÊѲ½¤Ê¤·¡£
	¾®¤µ¤¯¤Ê¤Ã¤¿¾ì¹ç¤Ç¡¢¸µ¤Î¥¦¥£¥ó¥É¥¦¤Ç¤ÏÂ礭¤¤¾ì¹ç¤Ï¾å¤Îµ¬Â§
	¤Ë¤è¤Ã¤ÆÊѲ½¤µ¤»¤ë¡£
    ¡¦É½¼¨°ÌÃÖ
	ÊѲ½¤Ê¤·¡£
    ¡¦¥ê¥µ¥¤¥º¤ÎºÇÂ硦ºÇ¾®¥µ¥¤¥º
	¸µ¤Î¥µ¥¤¥º¤¬¾å¤Î¡Ö¥ê¥µ¥¤¥º¤ÎºÇ¾®¥µ¥¤¥º¡×¤è¤ê¾®¤µ¤¤¾ì¹ç¤Ï
	¤½¤ì¤òºÇ¾®¥µ¥¤¥º¤È¤¹¤ë¡£
	¤½¤ì°Ê³°¤Ï¾å¤ÎÄ̤ꡣ
---------------------------------------------------------------- */

#define  loc_INIT	0	/* Window is initialized */
#define  loc_RESZ	1	/* Window is resized */
#define  loc_SPEC	2	/* Window is initialized */
				/* and displayed at specified point */

/* Local Method */
- locateWindow: (int)width : (int)height by:(int)is_init : (NXPoint *)atpoint;
	/* width, height  ¥¤¥á¡¼¥¸¤ÎÂ礭¤µ */
{
	NXSize screenSize;
	NXSize req;	/* ¥¤¥á¡¼¥¸¤ò´Ý¤´¤Èɽ¼¨¤Ç¤­¤ëÂ礭¤µ */
	NXSize rsmin;	/* ¥ê¥µ¥¤¥º¤ÎºÇ¾®¥µ¥¤¥º */
	NXRect orig;	/* ¸½ºß¤Î¥¦¥£¥ó¥É¥¦¤Î¾öÊó */
	NXRect wrect;
	double xp, yp;	/* ¥¦¥£¥ó¥É¥¦°ÌÃÖ */
	static int winCounter = 6; /* because small window is under the menu */

	[NXApp getScreenSize: &screenSize];
	req.width = ((MinWinXSIZE > width) ? MinWinXSIZE : width) + 23.0;
	req.height = ((MinWinYSIZE > height) ? MinWinYSIZE : height) + 74.0;
	rsmin.width = (req.width < MinResizeXSIZE)
			? req.width : MinResizeXSIZE;
	rsmin.height = (req.height < MinResizeYSIZE)
			? req.height : MinResizeYSIZE;
	wrect.size = req;

	if (is_init == loc_RESZ) {
		[thiswindow getFrame: &orig];
		wrect.origin = orig.origin;
		if (req.width > orig.size.width)
			wrect.size.width = orig.size.width;
		if (req.height >= orig.size.height)
			wrect.size.height = orig.size.height;
		else
			wrect.origin.y += orig.size.height - wrect.size.height;
		if (orig.size.width < rsmin.width)
			rsmin.width = orig.size.width;
		if (orig.size.height < rsmin.height)
			rsmin.height = orig.size.height;
	}else {
		screenSize.width -= 64.0;
		if (is_init == loc_INIT || atpoint == NULL) {
			int xm = 13, ym = 15;
			if (screenSize.height <= 600.0)
				xm = 7, ym = 9;
			xp = (req.width > screenSize.width)
				? 0.0 : (120.0 + (winCounter % xm) * DiffStep);
			yp = (req.height > screenSize.height)
				? 0.0 : (20.0 + (winCounter % ym) * DiffStep);
		}else { /* loc_SPEC */
			double w;
			xp = atpoint->x;
			yp = screenSize.height - atpoint->y;
			if (xp < 0) xp = 0.0;
			else if (xp > (w = screenSize.width - MinResizeXSIZE))
				xp = w;
			if (yp < 0) yp = 0.0;
			else if (yp > (w = screenSize.height - MinResizeYSIZE))
				yp = w;
		}
		if (xp + req.width > screenSize.width)
			wrect.size.width = screenSize.width - xp;
		if (yp + req.height > screenSize.height)
			wrect.size.height = screenSize.height - yp;
		wrect.origin.x = xp;
		yp = screenSize.height - wrect.size.height - yp;
		wrect.origin.y = (yp > 0.0) ? yp : 0.0;
		winCounter++;
	}

	[thiswindow placeWindow: &wrect];
	[thiswindow setMaxSize: &req];
	[thiswindow setMinSize: &rsmin];
	return self;
}

/* Scroll image to be top & center */
- scrollProperly
{
	NXSize imgsz;
	NXRect wrect;
	NXPoint scorig;
	int	xp, yp;
	id	tv;

	tv = [self toyView];
	[[tv image] getSize: &imgsz];
	[scView getDocVisibleRect: &wrect];
	scorig.x = ((xp = imgsz.width - wrect.size.width) > 0) ? (xp / 2) : 0;
	scorig.y = ((yp = imgsz.height - wrect.size.height) > 0) ? yp : 0;
	if (xp > 0 || yp > 0)
		[tv scrollPoint: &scorig];
	return self;
}


#define  FilenameLimit	120

static void stripHistory(char *buf)
{
	int n, lx, rx;

	if ((n = strlen(buf)) < FilenameLimit || buf[n-1] != ')')
		return;
	for (rx = n-1; buf[rx] != '('; )
		if (--rx <= 0) return;
	for (lx = 0; buf[lx] != '('; )
		if (++lx >= n) return;
	if (lx == rx) return;
	if (lx > 0 && buf[lx-1] != '_')
		buf[lx++] = '_';
	while (lx <= n)
		buf[lx++] = buf[rx++];
}

- initLocateWindow:(const char *)fileName width:(int)width height:(int)height 
{
	ToyWin *keytw;
	BOOL	hasKey;
	NXPoint point;
	NXRect	rect;

	imageFilename = str_dup(fileName);
	stripHistory(imageFilename);
	keytw = [theController keyWindow];
	hasKey = (keytw != nil && keytw->miniFlag != mini_MINI);
	if (displayOverKeyWindowFlag) {
		if (hasKey) {
			[[keytw window] getFrame: &rect];
			point = rect.origin;
			point.y += rect.size.height;
		}else {
			NXSize  screenSize;
			[NXApp getScreenSize: &screenSize];
			point.x = FixedXPos;
			point.y = screenSize.height - FixedYPos;
		}
		[self locateWindow: width : height by:loc_SPEC : &point];
	}else
		[self locateWindow: width : height by:loc_INIT : NULL];
	[thiswindow setTitleAsFilename: imageFilename];
	if (hasKey)
		[thiswindow orderWindow:NX_BELOW
				relativeTo:[[keytw window] windowNum]];
	else
		[thiswindow orderFront: self];
	NXPing();
	[thiswindow display];
	return self;
}

/* Local */
- Do_reScale: (float)factor
{
	float r;
	NXSize *sz;
	BOOL showmsg;

	r = (scaleFactor > factor)
		? (scaleFactor / factor):(factor / scaleFactor);
	if (r < 1.0025)
		return self;
	sz = [[self toyView] resize: factor];
	if (sz == NULL) {
		NXBeep();
		return self;
	}
	scaleFactor = factor;
	showmsg = (r > 1.7 || (sz->width * sz->height) > 60000);

	if (showmsg)
		[theController messageDisplay:"Resizing..."];
	[self locateWindow: sz->width : sz->height by:loc_RESZ : NULL];
	// DON'T -> [scView sizeTo: sz->width + 21.0 : sz->height + 21.0];
	[self scrollProperly];
	[thiswindow display];
	if (showmsg)
		[theController messageDisplay:NULL];
	return self;
}

/* Local */
- select_reScale: sender
{
	static float scale[13] = { 0.0, /* never */
		4.0, 3.0, 2.0, 1.5, 1.2, 1.0,
		0.86603, 0.7071, 0.5, 0.33333, 0.25, 0.125 };

	return [self Do_reScale: scale[[sender selectedTag]]];
}

/* Local */
- setScaleValue:(float)val
{
	char buf[24];
	int i = val * 100.0;
	int f = (val * 100.0 - (float)i) * 10.0 + 0.5;
	if (f)
		sprintf(buf, "%d.%01d", i, f);
	else
		sprintf(buf, "%d", i);
	[scaleText setStringValue: buf];
	return self;
}

- reScale: sender
{
	if ([sender selectedTag] == 0) { /* Set... */
		[self setScaleValue: scaleFactor];
		[scalePanel makeKeyAndOrderFront: self];
		[scaleText selectText:self];
	}else {
		[scalePanel close];
		[self perform:@selector(select_reScale:) with:sender
			afterDelay: 5 cancelPrevious: YES];
	}
	return self;
}

#ifdef  OLD_VERSIONS
- fitScale: sender
{
	NXSize	screenSize, *sz;
	float	wf, hf, sc;

	[NXApp getScreenSize: &screenSize];
	sz = [[self toyView] originalSize];
	wf = screenSize.width / sz->width;
	hf = screenSize.height / sz->height;
	sc = ([sender selectedTag] == 0)
		? ((wf < hf) ? wf : hf)    /* Entire Image */
		: ((wf > hf) ? wf : hf);   /* Cover Screen */
	return [self setScaleValue: sc];
}
#endif  /* OLD_VERSIONS */

- setScale: sender
{
	if ([sender selectedTag] == 0) {
		float f = (int)([scaleText floatValue] * 1000.0 + 0.5) / 100000.0;
		[scalePanel close];
		if (f >= 0.01 && f <= 100.0)
			[self Do_reScale: f];
	}else
		[scalePanel close];
	return self;
}

- windowWillMiniaturize:sender toMiniwindow:miniwindow
{
	[[self toyView] clearDraggedLine];
	if (miniFlag == mini_YET)
		[thiswindow setMiniwindowIcon: MiniIcon];
	miniFlag = mini_MINI;
	return self;
}

- windowDidDeminiaturize:sender
{
	miniFlag = mini_DEMINI;
	return self;
}

- windowWillClose:sender
{
	// printf("Window will be freed\n");
	[theController checkWindow: self delete: YES];
	[scView free];
	[thiswindow setDelegate: nil];
	[self free];
	return thiswindow;
}

- windowDidBecomeKey:sender
{
	id tv = [self toyView];
	[thiswindow makeFirstResponder: tv];
	[tv setDraggedLine: self];
	return self;
}

- windowDidExpose:sender
{
	[[self toyView] setDraggedLine: self];
	return self;
}

- windowDidMove:sender
{
	[[self toyView] setDraggedLine: self];
	return self;
}

@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.