This is VisualFontPanel.m in view mode; [Download] [Up]
/* * Filename: VisualFontPanel.m * Created : Tue May 2 08:01:01 1995 * Author : Vince DeMarco <vdemarco@bou.shl.com> * LastEditDate Was "Tue Jan 23 08:35:34 1996" */ #import "VisualFontPanel.h" #import <objc/NXBundle.h> #import <appkit/Application.h> #import <appkit/FontManager.h> #import <appkit/Font.h> #import <appkit/Text.h> #import <appkit/Matrix.h> #import <appkit/NXCType.h> #import <appkit/ButtonCell.h> #import <stdlib.h> #import <sys/param.h> #import <string.h> static id __shared = nil; /* Returns YES if str1 contains str2 */ static BOOL contains(const char *str1, const char *str2) { int len1; int len2; char *s1; char *s2; int i; if (str1 && str2){ len1 = strlen(str1); len2 = strlen(str2); s1 = alloca(len1+1); s2 = alloca(len2+1); for(i=0;i<len1;i++){ s1[i] = NXToLower(str1[i]); } s1[len1] = '\000'; for(i=0;i<len2;i++){ s2[i] = NXToLower(str2[i]); } s2[len2] = '\000'; if (strstr(s1,s2)){ return YES; }else{ if (strcmp(s2,"medium") == 0){ if (rindex(s1,'-')){ /* if the name doesn't have a '-' then it must * be a Medium font (This isn't great but hey) */ return NO; }else{ return YES; } }else{ return NO; } } } return YES; } static BOOL isItalic(const char *str1) { return contains(str1,"italic") || contains(str1,"oblique") || contains(str1,"obl"); } static BOOL isRoman(const char *str1) { return !isItalic(str1); } /* Quick Sort stuff */ extern int gnu_qsort (char *base_ptr, int total_elems, int size, int (*cmp)()); int cmp(const char **p1, const char **p2) { return NXOrderStrings(*p1,*p2,YES,-1,NULL); } @implementation VisualFontPanel + new { if (!__shared){ char buf[MAXPATHLEN+1]; [[NXBundle bundleForClass:[self class]] getPath:buf forResource:"VisualFontPanel" ofType:"nib"]; __shared = self = [NXApp loadNibFile:buf owner:NXApp withNames:NO fromZone:[self zone]]; [self setFrameAutosaveName:"VisualFontSelection"]; [displayMatrix setAutoscroll:YES]; [displayMatrix setTarget:self]; [displayMatrix setDoubleAction:@selector(_setCellFont:)]; [displayMatrix setAction:@selector(_setSelected:)]; [self display:self]; [setButton setEnabled:NO]; [self setBecomeKeyOnlyIfNeeded:YES]; [weightMatrix setTarget:self]; [weightMatrix setAction:@selector(_setWeight:)]; } return __shared; } - free { return self; } - display:sender { char **availableFonts; unsigned int numFonts; unsigned int i,j; char **filteredFonts; unsigned int numFiltered; List *selectedWeights; BOOL selectRoman; BOOL selectItalic; char buf[512]; [self disableDisplay]; availableFonts = [[FontManager new] availableFonts]; numFonts=0; while(availableFonts[numFonts]){ numFonts++; } filteredFonts = NXZoneCalloc([self zone],numFonts,sizeof(char *)); selectedWeights = [weightMatrix cellList]; selectRoman = [[[styleMatrix cellList] objectAt:0] state]; selectItalic = [[[styleMatrix cellList] objectAt:1] state]; numFiltered=0; for(i=0;i<numFonts;i++){ if ([[selectedWeights objectAt:0] state]){ if ((selectRoman && isRoman(availableFonts[i])) || (selectItalic && isItalic(availableFonts[i]))){ filteredFonts[numFiltered++] = availableFonts[i]; /* No break here, or you will end up jump out of outer for loop */ } }else{ /* Notice this starts at 1 not 0, first radio button is the all */ for(j=1;j<[selectedWeights count];j++){ if ([[selectedWeights objectAt:j] state] && contains(availableFonts[i],[[selectedWeights objectAt:j] title])){ if ((selectRoman && isRoman(availableFonts[i])) || (selectItalic && isItalic(availableFonts[i]))){ filteredFonts[numFiltered++] = availableFonts[i]; break; } } } } } filteredFonts[numFiltered] = NULL; gnu_qsort((char *)filteredFonts,numFiltered,sizeof(char *),cmp); [displayMatrix renewRows:numFiltered cols:1]; [displayMatrix sizeToCells]; for(i=0;i<numFiltered;i++){ if (filteredFonts[i]){ [[displayMatrix cellAt:i :0] setTitle:filteredFonts[i]]; }else{ [[displayMatrix cellAt:i :0] setTitle:"<<unusable font>>"]; } [[displayMatrix cellAt:i :0] setFont:[Font systemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]]; } [displayMatrix scrollCellToVisible:0 :0]; [displayMatrix selectCellAt:0 :0]; [[[displayMatrix superview] superview] update]; [self perform:@selector(_setSelected:) with:self]; free(availableFonts); free(filteredFonts); sprintf(buf,"%d/%d",numFiltered,numFonts); [selectedField setStringValue:buf]; [self reenableDisplay]; [self displayIfNeeded]; return self; } - _setWeight:sender { List *selectedWeights; int i; selectedWeights = [weightMatrix cellList]; if ([[sender selectedCell] tag] == -1){ for(i=1;i<[selectedWeights count];i++){ if ([[selectedWeights objectAt:0] state] == 1){ [[selectedWeights objectAt:i] setState:0]; } } }else{ for(i=1;i<[selectedWeights count];i++){ if ([[selectedWeights objectAt:i] state] == 1){ [[selectedWeights objectAt:0] setState:0]; } } } [weightMatrix display]; return self; } - _setSelected:sender { Font *fnt; if ([displayMatrix selectedCell]){ fnt = [Font newFont:[[displayMatrix selectedCell] title] size:12.0]; if (fnt){ [setButton setEnabled:YES]; [[displayMatrix selectedCell] setFont:fnt]; [displayMatrix update]; [fontnameField setStringValue:[fnt displayName]]; }else{ [setButton setEnabled:NO]; [[displayMatrix selectedCell] setFont:[Font systemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]]; [displayMatrix update]; [fontnameField setStringValue:""]; } }else{ [fontnameField setStringValue:""]; } return self; } - _setCellFont:sender { [setButton performClick:self]; return self; } - set:sender { id responder; Font *fnt; fnt = [Font newFont:[[displayMatrix selectedCell] title] size:12.0]; [[FontManager new] setSelFont:fnt isMultiple:NO]; responder = [NXApp calcTargetForAction:@selector(setFont:)]; [responder setFont:fnt]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.