home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / MiscKit1.2.6 / Examples / DragViewTest / MiscIconWell.m < prev    next >
Encoding:
Text File  |  1994-06-17  |  8.2 KB  |  328 lines

  1. /***************************************************************************
  2.  * CLASS:        MiscIconWell
  3.  *
  4.  *    See the header file for more information.
  5.  *
  6.  * This object is included in the MiscKit by permission from the author
  7.  * and its use is governed by the MiscKit license, found in the file
  8.  * "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  9.  * for a list of all applicable permissions and restrictions.
  10.  ***************************************************************************/
  11.  
  12. #import <misckit/MiscString.h>
  13. #import <misckit/MiscIconWell.h>
  14.  
  15. /*
  16.  * A proper implementation of versioning. If you add ivars to the class (or
  17.  * just want to dork with the reading/writing) check out the comments tagged
  18.  * "Archiving: READ ME". BJM 5/24/94
  19.  */
  20.  
  21. /*
  22.  * **** Archiving: READ ME **** This is the current and defined version of the
  23.  * class. It is used to identify what data will be written and how that will
  24.  * happen. If the read/write stuff is modified AT ALL, this must be bumped up
  25.  * (I always bump by one) and the other comments must be followed. Failure to
  26.  * do so will result in palettes and nibs that cannot be read. BJM 5/24/94
  27.  */
  28. #define MISC_ICON_WELL_VERSION 0
  29.  
  30. @implementation MiscIconWell
  31.  
  32. + initialize
  33. {
  34.     if (self == [MiscIconWell class]) 
  35.     {
  36.         /*
  37.          * **** Archiving: READ ME **** After bumping the _VERSION, it is
  38.          * considered common practice to add a comment line indicating the new
  39.          * version number, date, and modifier. Optionally, the reason for the
  40.          * change. There is no need to modify the setVersion message. BJM
  41.          * 5/24/94 
  42.          */
  43.         // version 0: initial.  (bjm)
  44.            [[MiscIconWell class] setVersion:MISC_ICON_WELL_VERSION];
  45.     }
  46.     
  47.     return self;
  48. }
  49.  
  50. - initFrame: (const NXRect *)frameRect
  51. {
  52.   const char *const types[] = {NXFilenamePboardType};
  53.   
  54.       [super initFrame: frameRect];
  55.     [self registerForDraggedTypes: (const char *const *)&types count: 1];
  56.     
  57.     filename = [ [MiscString alloc] init];
  58.     [self setAllowDoubleClickLaunch: YES];
  59.     
  60.     return self;
  61. }
  62.  
  63.  
  64.  
  65. - awake
  66.   const char *const types[] = {NXFilenamePboardType};
  67.   
  68.     [super awake];    
  69.     [self registerForDraggedTypes: (const char *const *)&types count: 1];
  70.     
  71.     return self;
  72. }
  73.  
  74.  
  75.  
  76. - free
  77. {
  78.     [filename free];
  79.     return [super free];
  80. }
  81.  
  82.  
  83. // Return the filename associated with the image. Kind of a hack to return
  84. // nil if no filename set, I suppose.
  85.  
  86. - (const char *)filename
  87. {   
  88.     /*
  89.      * convert an empty string (because the filename ivar is always valid) to a
  90.      * return value of NULL. BJM 5/24/94
  91.      */
  92.      if ( [filename length] == 0)
  93.         return NULL;
  94.     else
  95.           return [filename stringValue];
  96. }
  97.  
  98.  
  99.  
  100. // Overridden from MiscDragView so the icon representation of the file
  101. // is fetched instead of the image itself (likely the filename is not
  102. // an image). It also has a small hack that if there are more than one
  103. // filename that it steals that multiple.tiff from Librarian.app. 
  104.  
  105. - setImageByFilename: (const char *)aFilename
  106. {
  107.     [filename setStringValue: aFilename];
  108.     
  109.     /*
  110.      * Multiple filenames are separated by tabs. We can't use -numWords because
  111.      * numWords checks for any NXIsSpace which includes spaces. Result: if we
  112.      * use numWords, it treats any filename with spaces as "multiple". BJM
  113.      * 5/24/94    
  114.      */
  115.     if ([filename index:'\t'] != NULL)
  116.         [super setImageByFilename: "/NextApps/Librarian.app/multiple.tiff"];
  117.     else    
  118.         [self setImage: [ [Application workspace] getIconForFile: aFilename] ];
  119.     
  120.     return self;
  121. }
  122.  
  123.  
  124.  
  125. // Add additional options that only apply to MiscIconWell.
  126.  
  127. - setAllowDoubleClickLaunch: (BOOL)aBool
  128. {
  129.     allowDoubleClickLaunch = aBool;
  130.     return self;
  131. }
  132.  
  133.  
  134.  
  135. - (BOOL)allowDoubleClickLaunch
  136. {
  137.     return allowDoubleClickLaunch;
  138. }
  139.  
  140.  
  141. /*
  142.  * Launch/open file in WS: BJM 5/24/94
  143.  */
  144. - launch:sender
  145. {
  146.     if ([filename length])
  147.         [[Application workspace] openFile:[filename stringValue]];
  148.     return self;
  149. }
  150.  
  151. // Override mouseDown to check if the icon was double clicked. If so, then
  152. // launch it from workspace, else let super handle it.
  153.  
  154. - mouseDown: (NXEvent *)theEvent
  155. {
  156.     /*
  157.      * Only attempt to open file if there (1) DC is allowed, (2) this is a DC
  158.      * event, and (3) there is a file to open. BJM 5/24/94
  159.      */
  160.     if ([self allowDoubleClickLaunch] && theEvent->data.mouse.click == 2)
  161.         [self launch:self];
  162.         
  163.     else
  164.         [super mouseDown: theEvent];
  165.     return self;
  166. }
  167.  
  168.  
  169.  
  170. // Make the dragPoint be the middle of the image, so it looks nice.
  171.  
  172. - calculateDragPoint: (NXPoint *)dragPoint andOffset: (NXPoint *)offset
  173. {
  174.     dragPoint->x -= imageSize.width/2.0;
  175.     dragPoint->y -= imageSize.width/2.0;
  176.  
  177.     return self;
  178. }
  179.  
  180.  
  181.     
  182. // Put the data on the pasteboard when a source drag takes place, and
  183. // also choose the image to drag. 
  184.  
  185. - (BOOL)setupForSourceDrag
  186. {
  187.     /*
  188.      * only if there is something to drag... BJM 5/24/94
  189.      */
  190.     if ([filename length] > 0)
  191.     {
  192.         id dragPB = [Pasteboard newName: NXDragPboard];
  193.         
  194.         [dragPB declareTypes:&NXFilenamePboardType num:1 owner:self];
  195.         
  196.         [dragPB writeType:NXFilenamePboard 
  197.             data:[filename stringValue]
  198.             length:[filename length] ];
  199.             
  200.         dragImage = theImage;
  201.         
  202.         return YES;
  203.     }
  204.     
  205.     return NO;
  206. }
  207.  
  208.  
  209.  
  210.  
  211. // Check if an incoming dragged icon is using the NXFilenamePboardType. If
  212. // not, then don't accept the drag.
  213.  
  214. - (BOOL)performDragOperation: sender
  215. {
  216.   id  dragPB = [Pasteboard newName: NXDragPboard];
  217.   char  *pbData;
  218.   int  pbLength;
  219.  
  220.     if ([dragPB readType: NXFilenamePboardType data: &pbData 
  221.             length: &pbLength] == nil)
  222.         return NO;    
  223.      
  224.     return YES;
  225. }
  226.  
  227.  
  228. // Take the data from the pasteboard and set the new image.
  229.  
  230. - concludeDragOperation: sender
  231. {
  232.   id  dragPB = [Pasteboard newName: NXDragPboard];
  233.   char  *pbData;
  234.   int  pbLength;
  235.   
  236.     [dragPB readType: NXFilenamePboardType data: &pbData 
  237.             length: &pbLength];
  238.  
  239.     [self setImageByFilename: pbData];
  240.             
  241.     [dragPB deallocatePasteboardData: pbData length: pbLength];
  242.     
  243.     [super concludeDragOperation: sender];
  244.     
  245.     return self;
  246. }
  247.  
  248.  
  249.  
  250. /*********** Archiving *************/
  251.  
  252. - read:(NXTypedStream *)stream
  253. {
  254.     int version;
  255.  
  256.     [super read:stream];
  257.     
  258.     version = NXTypedStreamClassVersion(stream, "MiscIconWell");
  259.         
  260.     /*
  261.      * **** Archiving: READ ME **** This code (and its analogue in write:) is
  262.      * critical. When you bump MISC_ICON_WELL_VERSION, copy the whole _current_
  263.      * case ("case MISC_ICON_WELL_VERSION: ... break;"), and duplicate it.
  264.      * Change the "MISC_ICON_WELL_VERSION" in the old case to the OLD
  265.      * (pre-bump) version number. Now, dork the "new current" version into
  266.      * whatever you want. See how this code can now read EITHER version out of
  267.      * the typed stream?
  268.      *
  269.      * If you are adding yet another version, leave the previous versionS in
  270.      * place. That way you can still read archived objects that are more than
  271.      * one version old. Don't forget to take whatever actions are necessary to
  272.      * harmonize those old values. For example, if you converted an "int" ivar
  273.      * to "double", you'd need to (in the old version) to read the int version
  274.      * into a temp variable, and convert it in to the double var. BJM 5/24/94
  275.      */
  276.     switch (version)
  277.     {
  278.     case MISC_ICON_WELL_VERSION:
  279.         filename = NXReadObject (stream);
  280.         NXReadTypes (stream, "c", 
  281.             &allowDoubleClickLaunch
  282.         );
  283.         break;
  284.  
  285.     default:
  286.         NXLogError("[%s %s] - unknown version of %s in typed stream",
  287.             [[self class] name], sel_getName(_cmd), [[self class] name]);
  288.         break;
  289.     }
  290.  
  291.     return self;
  292. }
  293.  
  294. - write:(NXTypedStream *)stream
  295. {
  296.     [super write:stream];
  297.     
  298.     /*
  299.      * **** Archiving: READ ME **** Home stretch. Now (just like read:)
  300.      * duplicate the current case ("case MISC_ICON_WELL_VERSION: ... break;").
  301.      * Once again, change the "MISC_ICON_WELL_VERSION" of the first one to the
  302.      * OLD version number. Now adjust the new/current MISC_ICON_WELL_VERSION
  303.      * (remember, you've bumped it) to the new way of writing vars. See how
  304.      * this code (because the constant is in the switch statement) always
  305.      * writes out ONLY the current version, but leaves the old version(s)
  306.      * around to posterity. DO NOT DELETE THE OLD VERSIONS. Leave them to
  307.      * clutter up the world. BJM 5/24/94  
  308.      */
  309.     switch (MISC_ICON_WELL_VERSION)
  310.     {
  311.     case MISC_ICON_WELL_VERSION:
  312.         NXWriteObject(stream, filename);
  313.         NXWriteTypes (stream, "c", 
  314.             &allowDoubleClickLaunch
  315.         );
  316.         break;
  317.  
  318.     default:
  319.         NXLogError("[%s %s] - unknown version of %s in typed stream",
  320.             [[self class] name], sel_getName(_cmd), [[self class] name]);
  321.         break;
  322.     }
  323.  
  324.     return self;
  325. }
  326.  
  327. @end