This is PopupFormatter.m in view mode; [Download] [Up]
#import "PopupFormatter.h" #define _delWill1 @selector(formatterWillChangeValueFor:at:sender:) #define _delWill2 @selector(formatterWillChangeValueFor:at:to:sender:) #define _delDid @selector(formatterDidChangeValueFor:at:to:sender:) #define String char* char *unitOfMeasurement[] = { "barrels", "gallons", "litres", "inches", "centimeters", "kilometers" , NULL }; @implementation PopupFormatter - init { [super init]; newValue = [[DBValue allocFromZone:[self zone]] init]; return self; } - mouseDown:(NXEvent *)theEvent at:(int)row :(int)column inside:(NXRect *)frame inView:(View *) view withAttributes:(id <DBTableVectors >)rowAttrs :(id <DBTableVectors >)columnAttrs usePositions:(BOOL)useRowPos :(BOOL)useColumnPos { String* strings; int x; [self getValueAt:row :column withAttributes:rowAttrs :columnAttrs usePositions:useRowPos :useColumnPos]; popupList = [[PopUpList alloc] init]; for (strings = unitOfMeasurement; *strings; strings++) { [popupList addItem: *strings]; } popupButton = NXCreatePopUpListButton(popupList); [popupButton setFrame: frame]; for (x = 0; x < [[[popupButton target] itemList]cellCount]; x++) { if (!strcmp([[[[popupButton target] itemList] cellAt: x: 0] title], [value stringValue])) { [[[popupButton target] itemList] selectCellAt:x :0]; [popupButton setTitle:[[[[popupButton target] itemList] selectedCell]title]]; break; } } [view addSubview:popupButton]; [popupList popUp: popupButton]; [newValue setStringValue: [popupList selectedItem]]; [popupButton removeFromSuperview]; [popupList free]; [popupButton free]; [self setValueAt:row :column withAttributes:rowAttrs :columnAttrs usePositions:useRowPos :useColumnPos]; /* Redraw the modified field */ [self drawFieldAt:row :column inside:frame inView:view withAttributes:rowAttrs :columnAttrs usePositions:useRowPos :useColumnPos]; [view display]; return self; } - setValueAt:(int)row :(int)column withAttributes:(id <DBTableVectors >)rowAttrs :(id <DBTableVectors >)columnAttrs usePositions:(BOOL)useRowPos :(BOOL)useColumnPos { BOOL isChangeOk = YES; /* Ask delegate if we can change */ if (useRowPos && !useColumnPos && delWill2) isChangeOk = [delegate formatterWillChangeValueFor: [columnAttrs identifier] at:row to:newValue sender:self]; else if (useColumnPos && !useRowPos && delWill2) isChangeOk = [delegate formatterWillChangeValueFor: [rowAttrs identifier] at:column to:newValue sender:self]; if (!isChangeOk) return nil; /* Tell dataSource our newValue */ if (useRowPos && !useColumnPos) [dataSource setValueFor:[columnAttrs identifier] at:row from:newValue]; else if (useColumnPos && !useRowPos) [dataSource setValueFor:[rowAttrs identifier] at:column from:newValue]; /* Tell delegate we changed */ if (useRowPos && !useColumnPos && delDid) [delegate formatterDidChangeValueFor:[columnAttrs identifier] at:row to:newValue sender:self]; else if (!useRowPos && useColumnPos && delDid) [delegate formatterDidChangeValueFor:[rowAttrs identifier] at:column to:newValue sender:self]; return self; } - setDelegateFlags { delWill1 = delWill2 = delDid = NO; if ([delegate respondsTo:_delWill1]) delWill1 = YES; if ([delegate respondsTo:_delWill2]) delWill2 = YES; if ([delegate respondsTo:_delDid]) delDid = YES; return self; } - setDelegate:newDelegate { if (newDelegate == delegate) return self; else [super setDelegate:newDelegate]; [self setDelegateFlags]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.