This is KeyDownBrowser.m in view mode; [Download] [Up]
//--------------------------------------------------------------------------------------------------------- // // KeyDownBrowser // // Inherits From: NXBrowser // // Declared In: KeyDownBrowser.h // // Disclaimer // // You may freely copy, distribute and reuse this software and its // associated documentation. I disclaim any warranty of any kind, // expressed or implied, as to its fitness for any particular use. // //--------------------------------------------------------------------------------------------------------- #import "KeyDownBrowser.h" #import "KeyDownMatrix.h" #define RETURN 13 #define LEFTARROW 172 #define UPARROW 173 #define RIGHTARROW 174 #define DOWNARROW 175 #define DELETE 127 #define CHUNK 64 @implementation KeyDownBrowser //--------------------------------------------------------------------------------------------------------- // Timed Entry Methods (Private) //--------------------------------------------------------------------------------------------------------- void Search (timedEntry, now, self) DPSTimedEntry timedEntry; double now; void* self; { [(id)self perform: @selector (_search)]; } - _addTimedEntry { timedEntry = DPSAddTimedEntry (inputTimeOut, Search, (void*) self, NX_MODALRESPTHRESHOLD); NXPing(); return self; } - _removeTimedEntry { if ( ! timedEntry) return self; DPSRemoveTimedEntry (timedEntry); timedEntry = 0; return self; } //--------------------------------------------------------------------------------------------------------- // Miscellaneous Methods (Private) //--------------------------------------------------------------------------------------------------------- - _chunk { // Allocate memory for input buffer. if ( ! searchString) searchString = NX_MALLOC (searchString, char, CHUNK); else searchString = NX_REALLOC (searchString, char, strlen(searchString) + CHUNK); if ( ! searchString) NXLogError ("Out of Memory in _chunk!"); return self; } - _selectCellInRow:(int)aRow ofMatrix:aMatrix andDoClick:(BOOL)doClick { [aMatrix selectCellAt: aRow :0]; [aMatrix scrollCellToVisible: aRow :0]; if (doClick) [self doClick: aMatrix]; return self; } //--------------------------------------------------------------------------------------------------------- // Search Methods (Private) //--------------------------------------------------------------------------------------------------------- - (int) _searchColumn { // If there is no selection within the browser, return column 0. If there are multiple selections // return the current selected column. If there is 1 selection, then if it is a leaf, return the // current selected column. If it is a branch, return the current selected column + 1. id selectedCellList; int searchColumn = [self selectedColumn]; if (searchColumn < 0) return 0; if ([self isMultipleSelectionEnabled]) { selectedCellList = [self getSelectedCells: nil]; if ([selectedCellList count] == 1) if ([[selectedCellList objectAt: 0] isLeaf] == NO) searchColumn++; selectedCellList = [selectedCellList free]; return searchColumn; } if ([self selectedCell]) if ([[self selectedCell] isLeaf] == NO) searchColumn++; return searchColumn; } - _search { // Searches current search column for first occurrence of searchString. int iterator; int searchColumn = [self _searchColumn]; id matrix = [self matrixInColumn: searchColumn]; id currentCell; BOOL found = NO; [self _removeTimedEntry]; for (iterator = 0; iterator < [matrix numRows]; iterator++) { currentCell = [matrix cellAt: iterator :0]; if (NXOrderStrings([currentCell stringValue], searchString, wantsCaseSensitiveSearch, strlen (searchString), NULL) == 0) { [matrix selectCellAt: -1 :-1]; [self _selectCellInRow:iterator ofMatrix:matrix andDoClick:YES]; found = YES; break; } } if (! found) NXBeep(); memset (searchString, 0, strlen (searchString)); return self; } //--------------------------------------------------------------------------------------------------------- // Key Down Methods (Private) //--------------------------------------------------------------------------------------------------------- - _upArrow: (NXEvent *) theEvent { id matrix; int selectedRow; int selectedColumn = [self selectedColumn]; if (selectedColumn == -1) return self; matrix = [self matrixInColumn:selectedColumn]; selectedRow = [matrix selectedRow] - 1; if (selectedRow < 0) selectedRow = 0; [self _selectCellInRow:selectedRow ofMatrix:matrix andDoClick:YES]; return self; } - _downArrow: (NXEvent *) theEvent { id matrix; int selectedRow; int selectedColumn = [self selectedColumn]; if (selectedColumn == -1) return self; matrix = [self matrixInColumn: selectedColumn]; selectedRow = [matrix selectedRow] + 1; if (selectedRow > [matrix numRows] - 1) selectedRow = [matrix numRows] - 1; [self _selectCellInRow:selectedRow ofMatrix:matrix andDoClick:YES]; return self; } - _leftArrow: (NXEvent *) theEvent { id matrix; int selectedColumn = [self selectedColumn]; if (selectedColumn == -1) return self; matrix = [self matrixInColumn: selectedColumn]; [self setLastColumn: selectedColumn]; [matrix selectCellAt: -1 :-1]; [matrix sendAction:action to:target]; if (selectedColumn == 0) return self; selectedColumn -= 1; matrix = [self matrixInColumn: selectedColumn]; if ([self firstVisibleColumn] > selectedColumn) [self scrollColumnsRightBy: 1]; [matrix scrollCellToVisible: [matrix selectedRow] :[matrix selectedCol]]; return self; } - _rightArrow: (NXEvent *) theEvent { id matrix = [self matrixInColumn: ([self selectedColumn] + 1)]; if (! matrix) return self; [self _selectCellInRow:0 ofMatrix:matrix andDoClick:YES]; return self; } - _return: (NXEvent *) theEvent { int selectedColumn = [self selectedColumn]; if (selectedColumn == -1) return self; [self doDoubleClick: [self matrixInColumn:selectedColumn]]; return self; } //--------------------------------------------------------------------------------------------------------- // Initialization //--------------------------------------------------------------------------------------------------------- - initFrame: (const NXRect *) frameRect { // Give it default IB characteristics, set the Matrix class, enable keys. [super initFrame: frameRect]; [self setMatrixClass: [KeyDownMatrix class]]; [self separateColumns: YES]; [self setHorizontalScrollerEnabled: YES]; [self setEmptySelectionEnabled: YES]; [self setTitle: "KeyDownBrowser" ofColumn: 0]; [self acceptArrowKeys:YES andSendActionMessages:YES]; [self wantsCaseSensitiveSearch: NO]; [self inputTimeOut: 0.5]; [self _chunk]; memset (searchString, 0, CHUNK); return self; } - free { [self _removeTimedEntry]; if (searchString) free (searchString); return self = [super free]; } //--------------------------------------------------------------------------------------------------------- // Accessors //--------------------------------------------------------------------------------------------------------- - wantsCaseSensitiveSearch: (BOOL) aFlag { wantsCaseSensitiveSearch = aFlag; return self; } - (BOOL) wantsCaseSensitiveSearch { return wantsCaseSensitiveSearch; } - inputTimeOut: (float) aFloat { inputTimeOut = aFloat; return self; } - (float) inputTimeOut { return inputTimeOut; } //--------------------------------------------------------------------------------------------------------- // Event Handling //--------------------------------------------------------------------------------------------------------- - mouseDown: (NXEvent*) theEvent { if ([self isEnabled] == NO) return self; [super mouseDown: theEvent]; [[self window] makeFirstResponder: self] ; return self; } - keyDown: (NXEvent *) theEvent { if ([self isEnabled] == NO) return self; [self _removeTimedEntry]; switch (theEvent->data.key.charCode) { case UPARROW: [self _upArrow: theEvent]; break; case DOWNARROW: [self _downArrow: theEvent]; break; case LEFTARROW: [self _leftArrow: theEvent]; break; case RIGHTARROW: [self _rightArrow: theEvent]; break; case RETURN: [self _return: theEvent]; break; case DELETE: if ([[self delegate] respondsTo:@selector(delete:)]) [[self delegate] delete:self]; break; default: if (theEvent->data.key.repeat) return self; sprintf (searchString, "%s%c", searchString, theEvent->data.key.charCode); if (! (strlen (searchString) % (CHUNK - 1))) [self _chunk]; [self _addTimedEntry]; break; } return self; } - (BOOL)acceptsFirstResponder { return YES; } //---------------------------------------------------------------------------------------------------- // Archiving Methods //---------------------------------------------------------------------------------------------------- - read: (NXTypedStream*) stream { [super read: stream]; NXReadTypes (stream, "cf", &wantsCaseSensitiveSearch, &inputTimeOut); return self; } - write: (NXTypedStream*) stream { [super write: stream]; NXWriteTypes (stream, "cf", &wantsCaseSensitiveSearch, &inputTimeOut); return self; } - awake { [super awake]; [self _chunk]; memset (searchString, 0, CHUNK); return self; } //---------------------------------------------------------------------------------------------------- // Superclass Overrides //---------------------------------------------------------------------------------------------------- - acceptArrowKeys:(BOOL)acceptFlag andSendActionMessages:(BOOL)sendFlag { [super acceptArrowKeys:YES andSendActionMessages:sendFlag]; return self; } - acceptArrowKeys:(BOOL)acceptFlag { // 2.1 method. [super acceptArrowKeys:YES andSendActionMessages:YES]; return self; } //--------------------------------------------------------------------------------------------------------- // IB Methods //--------------------------------------------------------------------------------------------------------- - (const char*) getInspectorClassName { return "KeyDownBrowserInspector"; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.