home *** CD-ROM | disk | FTP | other *** search
- //=============================================================================
- //
- // Copyright (C) 1996-1997 by Paul S. McCarthy and Eric Sunshine.
- // Written by Paul S. McCarthy and Eric Sunshine.
- // All Rights Reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the authors
- // and its use is governed by the MiscKit license, found in the file
- // "License.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
- //=============================================================================
- //-----------------------------------------------------------------------------
- // MiscTableScrollKB.M
- //
- // Keyboard event handling for MiscTableScroll.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // $Id: MiscTableScrollKB.M,v 1.7 97/06/18 10:50:46 sunshine Exp $
- // $Log: MiscTableScrollKB.M,v $
- // Revision 1.7 97/06/18 10:50:46 sunshine
- // v125.9: Worked around Objective-C++ compiler crash in OPENSTEP 4.2 for NT
- // when sending message to 'super' from within a category.
- //
- // Revision 1.6 97/04/15 09:08:47 sunshine
- // v0.125.8: Added "MiscTableScroll/" prefix to #import to facilitate new
- // framework organization.
- //
- // Revision 1.5 97/02/09 16:26:47 sunshine
- // v112.1: Now disables flushWindow during methods which scroll and change the
- // keyboard cursor position so that the operations occur in a visually atomic
- // fashion. MiscTableView's moveFocusBy: --> moveCursorBy:.
- //-----------------------------------------------------------------------------
- #import <MiscTableScroll/MiscTableScroll.h>
- #import "MiscTableView.h"
-
- enum KB_Action
- {
- ACT_IGNORE,
- ACT_SELECT,
- ACT_PERFORM,
- ACT_LEFT,
- ACT_RIGHT,
- ACT_UP,
- ACT_DOWN,
- ACT_PAGE_LEFT,
- ACT_PAGE_RIGHT,
- ACT_PAGE_UP,
- ACT_PAGE_DOWN,
- ACT_LEFT_EDGE,
- ACT_RIGHT_EDGE,
- ACT_TOP_EDGE,
- ACT_BOT_EDGE,
-
- ACT_NUM_ACTIONS
- };
-
- enum
- {
- K_RETURN = '\r',
- K_SPACE = ' ' ,
- K_LEFT = NSLeftArrowFunctionKey,
- K_UP = NSUpArrowFunctionKey,
- K_RIGHT = NSRightArrowFunctionKey,
- K_DOWN = NSDownArrowFunctionKey,
- K_KP_LEFT = '4',
- K_KP_UP = '8',
- K_KP_RIGHT = '6',
- K_KP_DOWN = '2',
- K_KP_PAGE_UP = '9',
- K_KP_PAGE_DOWN = '3',
- K_KP_HOME = '7',
- K_KP_END = '1',
- K_KP_INSERT = '0',
- K_KP_ENTER = 0x03,
- K_PAGE_UP = NSPageUpFunctionKey,
- K_PAGE_DOWN = NSPageDownFunctionKey,
- K_HOME = NSHomeFunctionKey,
- K_END = NSEndFunctionKey,
- };
-
-
- //=============================================================================
- // IMPLEMENTATION
- //=============================================================================
- @implementation MiscTableScroll(Keyboard)
-
- //-----------------------------------------------------------------------------
- // - keyboardSelect:
- //-----------------------------------------------------------------------------
- - (void)keyboardSelect:(NSEvent*)p
- {
- [tableView keyboardSelect:p];
- [self clearSlotSelection:MISC_OTHER_BORDER([tableView trackingBy])];
- [self selectionChanged];
- [self sendActionIfEnabled];
- }
-
-
- //-----------------------------------------------------------------------------
- // goFirstSlot:
- //-----------------------------------------------------------------------------
- - (void)goFirstSlot:(MiscBorderType)b
- {
- if ([self numberOfSlots:b] > 0)
- {
- int const s = [self border:b slotAtPosition:0];
- NSWindow* const w = [self window];
- [w disableFlushWindow];
- [self border:b setCursorSlot:s];
- [self border:b setFirstVisibleSlot:s];
- [w enableFlushWindow];
- [w flushWindow];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // goLastSlot
- //-----------------------------------------------------------------------------
- - (void)goLastSlot:(MiscBorderType)b
- {
- int const n = [self numberOfSlots:b];
- if (n > 0)
- {
- int s = [self border:b slotAtPosition:(n - 1)];
- NSWindow* const w = [self window];
- [w disableFlushWindow];
- [self border:b setCursorSlot:s];
- [self border:b setLastVisibleSlot:s];
- [w enableFlushWindow];
- [w flushWindow];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // goPrevPage:
- //-----------------------------------------------------------------------------
- - (void)goPrevPage:(MiscBorderType)b
- {
- if ([self numberOfSlots:b] > 0)
- {
- int sFirst = [self firstVisibleSlot:b];
- int const sLast = [self lastVisibleSlot:b];
- int const v = [self border:b slotPosition:sFirst];
- if (sFirst == sLast && v > 0)
- sFirst = [self border:b slotAtPosition:(v - 1)];
- NSWindow* const w = [self window];
- [w disableFlushWindow];
- [self border:b setLastVisibleSlot:sFirst];
- if (b == [self trackingBy])
- [self border:b setCursorSlot:[self firstVisibleSlot:b]];
- [w enableFlushWindow];
- [w flushWindow];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // goNextPage:
- //-----------------------------------------------------------------------------
- - (void)goNextPage:(MiscBorderType)b
- {
- int const lim = [self numberOfSlots:b];
- if (lim > 0)
- {
- int const sFirst = [self firstVisibleSlot:b];
- int sLast = [self lastVisibleSlot:b];
- int const v = [self border:b slotPosition:sLast];
- if (sFirst == sLast && v < lim - 1)
- sLast = [self border:b slotAtPosition:(v + 1)];
- NSWindow* const w = [self window];
- [w disableFlushWindow];
- [self border:b setFirstVisibleSlot:sLast];
- if (b == [self trackingBy])
- [self border:b setCursorSlot:[self lastVisibleSlot:b]];
- [w enableFlushWindow];
- [w flushWindow];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - classifyFunctionKey:
- //-----------------------------------------------------------------------------
- - (KB_Action)classifyFunctionKey:(NSEvent*)p
- {
- KB_Action deed = ACT_IGNORE;
- switch ([[p charactersIgnoringModifiers] characterAtIndex:0])
- {
- case K_LEFT: deed = ACT_LEFT; break;
- case K_RIGHT: deed = ACT_RIGHT; break;
- case K_UP: deed = ACT_UP; break;
- case K_DOWN: deed = ACT_DOWN; break;
- case K_PAGE_UP: deed = ACT_PAGE_UP; break;
- case K_PAGE_DOWN: deed = ACT_PAGE_DOWN; break;
- case K_HOME: deed = ACT_TOP_EDGE; break;
- case K_END: deed = ACT_BOT_EDGE; break;
- }
- return deed;
- }
-
-
- //-----------------------------------------------------------------------------
- // - classifyOtherKey:
- //-----------------------------------------------------------------------------
- - (KB_Action)classifyOtherKey:(NSEvent*)p
- {
- KB_Action deed = ACT_IGNORE;
- switch ([[p charactersIgnoringModifiers] characterAtIndex:0])
- {
- case K_SPACE: deed = ACT_SELECT; break;
- case K_RETURN: deed = ACT_PERFORM; break;
- }
- return deed;
- }
-
-
- //-----------------------------------------------------------------------------
- // - classifyNumericPadKey:
- //-----------------------------------------------------------------------------
- - (KB_Action)classifyNumericPadKey:(NSEvent*)p
- {
- KB_Action deed = ACT_IGNORE;
- unichar const charCode =
- [[p charactersIgnoringModifiers] characterAtIndex:0];
-
- if (charCode == K_KP_ENTER)
- deed = ACT_PERFORM;
- else if ('0' <= charCode && charCode <= '9')
- {
- static KB_Action const ACTS[] =
- {
- ACT_SELECT, // KP 0 (insert)
- ACT_BOT_EDGE, // KP 1 (end)
- ACT_DOWN, // KP 2 (arrow down)
- ACT_PAGE_DOWN, // KP 3 (page down)
- ACT_LEFT, // KP 4 (arrow left)
- ACT_IGNORE, // KP 5
- ACT_RIGHT, // KP 6 (arrow right)
- ACT_TOP_EDGE, // KP 7 (home)
- ACT_UP, // KP 8 (arrow up)
- ACT_PAGE_UP // KP 9 (page up)
- };
- deed = ACTS[ charCode - '0' ];
- }
- return deed;
- }
-
-
- //-----------------------------------------------------------------------------
- // - classifyFlags:forAction:
- //-----------------------------------------------------------------------------
- - (KB_Action)classifyFlags:(int)flags forAction:(KB_Action)deed
- {
- static KB_Action const MODIFIED_ACTIONS[ ACT_NUM_ACTIONS ] =
- {
- //-- Becomes... Was... --//
- ACT_IGNORE, // ACT_IGNORE
- ACT_SELECT, // ACT_SELECT
- ACT_PERFORM, // ACT_PERFORM
- ACT_PAGE_LEFT, // ACT_LEFT
- ACT_PAGE_RIGHT, // ACT_RIGHT
- ACT_PAGE_UP, // ACT_UP
- ACT_PAGE_DOWN, // ACT_DOWN
- ACT_PAGE_LEFT, // ACT_PAGE_LEFT
- ACT_PAGE_RIGHT, // ACT_PAGE_RIGHT
- ACT_PAGE_LEFT, // ACT_PAGE_UP
- ACT_PAGE_RIGHT, // ACT_PAGE_DOWN
- ACT_LEFT_EDGE, // ACT_LEFT_EDGE
- ACT_RIGHT_EDGE, // ACT_RIGHT_EDGE
- ACT_LEFT_EDGE, // ACT_TOP_EDGE
- ACT_RIGHT_EDGE // ACT_BOT_EDG
- };
- int const FLAGS = NSControlKeyMask | NSAlternateKeyMask | NSShiftKeyMask;
- if ((flags & FLAGS) != 0)
- return MODIFIED_ACTIONS[ deed ];
- return deed;
- }
-
-
- //-----------------------------------------------------------------------------
- // - classifyKeyDown:
- //-----------------------------------------------------------------------------
- - (KB_Action)classifyKeyDown:(NSEvent*)p
- {
- KB_Action deed = ACT_IGNORE;
- unsigned int const flags = [p modifierFlags];
- if ((flags & NSCommandKeyMask) == 0)
- {
- if ((flags & NSFunctionKeyMask) != 0)
- deed = [self classifyFunctionKey:p];
- else if ((flags & NSNumericPadKeyMask) != 0)
- deed = [self classifyNumericPadKey:p];
- else
- deed = [self classifyOtherKey:p];
-
- if (deed != ACT_IGNORE)
- deed = [self classifyFlags:flags forAction:deed];
- }
- return deed;
- }
-
-
- //-----------------------------------------------------------------------------
- // - keyDown:
- //-----------------------------------------------------------------------------
- - (void)keyDown:(NSEvent*)p
- {
- KB_Action deed = [self classifyKeyDown:p];
- BOOL handled = (deed != ACT_IGNORE);
- if (handled)
- {
- switch (deed)
- {
- case ACT_SELECT: [self keyboardSelect:p]; break;
- case ACT_PERFORM: [self sendDoubleActionIfEnabled]; break;
- case ACT_UP: [tableView moveCursorBy:-1]; break;
- case ACT_DOWN: [tableView moveCursorBy: 1]; break;
- case ACT_LEFT: [tableView moveCursorBy:-1]; break;
- case ACT_RIGHT: [tableView moveCursorBy: 1]; break;
- case ACT_PAGE_LEFT: [self goPrevPage: MISC_COL_BORDER]; break;
- case ACT_PAGE_RIGHT:[self goNextPage: MISC_COL_BORDER]; break;
- case ACT_PAGE_UP: [self goPrevPage: MISC_ROW_BORDER]; break;
- case ACT_PAGE_DOWN: [self goNextPage: MISC_ROW_BORDER]; break;
- case ACT_LEFT_EDGE: [self goFirstSlot:MISC_COL_BORDER]; break;
- case ACT_RIGHT_EDGE:[self goLastSlot: MISC_COL_BORDER]; break;
- case ACT_TOP_EDGE: [self goFirstSlot:MISC_ROW_BORDER]; break;
- case ACT_BOT_EDGE: [self goLastSlot: MISC_ROW_BORDER]; break;
- default: handled = NO; break;
- }
- }
-
- if (!handled && ![self incrementalSearch:p])
- [self superKeyDown:p];
- }
-
- @end
-