This is IKfunctions.m in view mode; [Download] [Up]
/* File IKfunctions.m Release 1.2, 7 June 1994 Copyright (C) 1994 by H. Scott Roy This code is part of IconKit, a general toolbox for drag-and-drop applications. IconKit is free for noncommercial use, but costs money for a commercial license. You should have received a copy of the license agreement with this file. If not, a copy of the license and the complete source of IconKit can be obtained from the author: H. Scott Roy 2573 Stowe Ct. Northbrook, IL 60062-8103 iconkit@cs.stanford.edu For your editing convenience, this file is best viewed using an editor that automatically wraps long lines, in a fixed point font at 80 columns, with tabs every 4 spaces. */ /* ========================================================================== */ /* This file contains miscellaneous functions that support the IconKit. Currently it contains functions that support copy and paste through local id. */ #import <appkit/appkit.h> #import <sys/time.h> #import "iconkit.h" /* ========================================================================== */ /* The following function is used for error checking. It's 100% equivalent to a simple fprintf statement, but it has the advantage that it can be turned on or off at runtime. */ static int IKDebug = 0; void IKdprintf (const char * format, ...) { static NXDefaultsVector IconKit = {{ "IKDebug", NULL }, { NULL }}; static int firstTime = 1; va_list args; if (firstTime) { const char * app = [NXApp appName]; NXRegisterDefaults (app, IconKit); IKDebug = (NXGetDefaultValue (app, "IKDebug") != NULL); firstTime = 0; } if (IKDebug) { va_start (args, format); vfprintf (stderr, format, args); va_end (args); } } void IKSetDebug (BOOL flag) { IKDebug = flag; } /* ========================================================================== */ /* The following function checks to make sure that an object conforms to the IKDependency protocol and whatever subset of IKIconObject it promises to implement. IKCell uses this function to do error checking on its delegate. */ #define WARNING(s) \ { \ NXLogError(s, [object name]); \ ok = NO; \ } BOOL IKCheckConformance (id object) { BOOL ok = YES; if (object != nil) { if (![object conformsTo: @protocol(IKDependency)]) WARNING ("%s does not conform to IKDependency") if (![object conformsTo: @protocol(IKSimpleObject)]) WARNING ("%s does not conform to IKSimpleObject") else { if ([object isEditable] && ![object conformsTo: @protocol(IKEditableObject)]) WARNING ("%s should conform to IKEditableObject") if ([object isDraggable] && ![object conformsTo: @protocol(IKDraggableObject)]) WARNING ("%s should conform to IKDraggableObject") if ([object isDragAccepting] && ![object conformsTo: @protocol(IKDragAcceptingObject)]) WARNING ("%s should conform to IKDragAcceptingObject") } } return (ok); } /* ========================================================================== */ /* Copy and paste through local object id requires a unique string name to define the type. A static, compile time declaration will not do, since two copies of the same application would then erroneously accept each other's objects. Calls to the following initialization method appear in all the IconKit class initializations. Be sure to call it yourself if you somehow manage to bypass them all. */ NXAtom IKidPboardType = NULL; void IKInitIDpboardType () { if (IKidPboardType == NULL) { struct timeval tp; struct timezone tzp; long randomString[3]; int i; gettimeofday(&tp, &tzp); srandom(tp.tv_usec); for (i = 0; i < 2; i++) randomString[i] = random(); randomString[2] = 0; IKidPboardType = NXUniqueString((const char *) randomString); } } /* ========================================================================== */ /* All draggable object must be able to copy and read using the pasteboard. These functions support those operations through local object id. The IKCopyID method obliterates whatever is currently on the pasteboard. */ void IKCopyID (Pasteboard * pboard, id object) { NXAtom * pasteTypes = IKIDPasteTypes(); [pboard declareTypes: pasteTypes num: 1 owner: nil]; [pboard writeType: IKidPboardType data: (char *) &object length: sizeof(id)]; } id IKReadID (Pasteboard * pboard) { NXAtom * pasteTypes = IKIDPasteTypes(); id object = nil; char * data; int n; if ([pboard findAvailableTypeFrom: pasteTypes num: 1]) { [pboard readType: IKidPboardType data: &data length: &n]; object = ((Object **) data)[0]; [pboard deallocatePasteboardData: data length: n]; } return object; } NXAtom * IKIDPasteTypes (void) { static NXAtom pasteTypes[] = { NULL, NULL }; IKInitIDpboardType(); pasteTypes[0] = IKidPboardType; return pasteTypes; } /* ========================================================================== */ /* Both the IKCell and IKBrowserCell classes use elipses to indicate long names that won't entirely fit in the cell. The function below is the core routine used by both of them. It takes a single text cell as an argument, and shortens the title (in place) to fit within a specified width. */ void IKShortenTitle (Cell * text, float maxWidth) { char * textBuffer = (char *) [text stringValue], * p; NXSize size; [text calcCellSize: &size]; p = rindex (textBuffer, '\0'); while (p > textBuffer + 1 && size.width > maxWidth) { *--p = '\0'; *--p = '¼'; [text calcCellSize: &size]; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.