This is CustomMenu.m in view mode; [Download] [Up]
// Written by Gideon King
//
// Source file : CustomMenu.m
// Created by : gideon@berd
// Created on : Fri Sep 8 16:26:38 NZST 1995
// RCS File : $Source: /Ramoth/Black.Albatross/CVS/CustomMenu/CustomMenu.subproj/CustomMenu.m,v $
// Last modified : $Date: 1995/09/10 22:38:07 $
// Last modified by : $Author: gideon $
// Current Revision : $Revision: 1.1.1.1 $
//
static const char RCSId[] = "$Id: CustomMenu.m,v 1.1.1.1 1995/09/10 22:38:07 gideon Exp $";
// This class is set up to be the destination of the drag operation. It creates new menu items as required,
// and deletes unwanted items when you Control-click on the item. I tried all sorts of strategies to remove
// submenus, and didn't sort it out. What I therefore do is remove the item from the submenu and close myself,
// so you can't get at me again. This means that you can't access the menu again, and it is not saved to the
// menu list file, so it only takes up a bit of memory until you restart the app. Not very nice, and I'd like
// to sort it out. Any suggestions???
#import "CustomMenu.h"
@implementation CustomMenu
- (const char *)version
{
return RCSId;
}
- myInit
{
const char *const types[] = {MHMenuCellPboardType};
// Register which pasteboard we you will accept
[self registerForDraggedTypes:(const char *const*)&types count:1];
return self;
}
// Normal menu initialisers
- init
{
[super init];
[self myInit];
return self;
}
- initTitle:(const char *)aTitle
{
[super initTitle:aTitle];
[self myInit];
return self;
}
// Used in this case for removing menu items when a Control key is down
- mouseDown:(NXEvent *)theEvent
{
// Only remove the item from the menu a Control key is down
// This is not really a very destructive operation, so we won't ask for confirmation
if (theEvent->flags & NX_CONTROLMASK)
{
if ([matrix cellCount] > 1)
{
// To avoid removing it from the view hierarchy while it is still lockFocused
[self perform:@selector(removeCell:) with:[matrix selectedCell] afterDelay:0 cancelPrevious:YES];
}
else
{
// They have just thrown away the last item on this menu - let's get rid of the menu itself
id itemList = [supermenu itemList];
int i;
for (i = 0; i < [itemList cellCount]; i++)
{
id thisCell = [itemList cellAt:i :0];
if((strcmp([self title], [thisCell title]) == 0) && ([thisCell tag] == 42131))
{ // We have found the cell which controls us
[itemList removeRowAt:i andFree:YES];
[supermenu setItemList:itemList];
[supermenu display];
// The following doesn't work for some reason - when you click on the main menu again, it tells you that it
// is trying to send the message isSelectable to a freed object. I don't understand!
// [self perform:@selector(free) with:nil afterDelay:10 cancelPrevious:YES];
[self perform:@selector(close) with:nil afterDelay:10 cancelPrevious:YES];
return self;
}
}
}
}
else
{
[super mouseDown:theEvent];
}
return self;
}
// methods to be the destination of a dragging operation
- (NXDragOperation)draggingEntered:sender
{
return NX_DragOperationCopy;
}
- (BOOL)prepareForDragOperation:sender
{
return YES;
}
- (BOOL)performDragOperation:sender
{
// Here is where we do the real work
id pboard = [sender draggingPasteboard];
NXStream *stream;
NXTypedStream *ts;
id newCell;
// Read the dragged cell from the pasteboard
stream = [pboard readTypeToStream:MHMenuCellPboardType];
ts = NXOpenTypedStream(stream, NX_READONLY);
newCell = NXReadObject(ts);
NXCloseTypedStream(ts);
NXCloseMemory(stream, NX_FREEBUFFER);
// Now add the cell to the end of the menu
// This could be enhanced to note where they dropped and insert a cell at the appropriate place
[matrix addRow];
[matrix putCell:newCell at:[matrix cellCount]-1 :0];
[self setItemList:matrix];
[self display];
return YES;
}
// Done with a performWith... to avoid lockFocus problems
- removeCell:aCell
{
int row, col;
[matrix getRow:&row andCol:&col ofCell:aCell];
[matrix removeRowAt:row andFree:YES];
[self setItemList:matrix];
[self display];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.