home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------------------------------------
- //
- // 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 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 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 [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;
- 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