mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 21:17:03 +00:00
666 lines
22 KiB
Plaintext
666 lines
22 KiB
Plaintext
/*
|
|
* CPEvent.j
|
|
* AppKit
|
|
*
|
|
* Created by Francisco Tolmasky.
|
|
* Copyright 2008, 280 North, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
@import "CPEvent_Constants.j"
|
|
|
|
@import <Foundation/CPObject.j>
|
|
@import <Foundation/CPObjJRuntime.j>
|
|
@import <Foundation/CPString.j>
|
|
|
|
@import "CPCompatibility.j"
|
|
@import "CGGeometry.j"
|
|
@import "CPText.j"
|
|
@import "CPTrackingArea.j"
|
|
|
|
@class CPTextField
|
|
@class CPWindow
|
|
@class CPGraphicsContext
|
|
|
|
@global CPApp
|
|
|
|
@typedef DOMEvent
|
|
@typedef CPEventType
|
|
|
|
|
|
var _CPEventPeriodicEventPeriod = 0,
|
|
_CPEventPeriodicEventTimer = nil,
|
|
_CPEventUpperCaseRegex = new RegExp("[A-Z]"),
|
|
_CPEventStartupMilliseconds = new Date().getTime();
|
|
|
|
/*!
|
|
@ingroup appkit
|
|
@class CPEvent
|
|
CPEvent encapsulates the details of a Cappuccino keyboard or mouse event.
|
|
*/
|
|
@implementation CPEvent : CPObject
|
|
{
|
|
CPEventType _type;
|
|
CGPoint _location;
|
|
unsigned _modifierFlags;
|
|
CPTimeInterval _timestamp;
|
|
CPGraphicsContext _context;
|
|
int _eventNumber;
|
|
unsigned _clickCount;
|
|
float _pressure;
|
|
CPWindow _window;
|
|
Number _windowNumber;
|
|
CPString _characters;
|
|
CPString _charactersIgnoringModifiers
|
|
BOOL _isARepeat;
|
|
unsigned _keyCode;
|
|
DOMEvent _DOMEvent;
|
|
int _data1;
|
|
int _data2;
|
|
short _subtype;
|
|
|
|
float _deltaX;
|
|
float _deltaY;
|
|
float _deltaZ;
|
|
float _scrollingDeltaX;
|
|
float _scrollingDeltaY;
|
|
BOOL _hasPreciseScrollingDeltas;
|
|
|
|
#if PLATFORM(DOM)
|
|
BOOL _suppressCappuccinoCut;
|
|
BOOL _suppressCappuccinoPaste;
|
|
#endif
|
|
|
|
CPTrackingArea _trackingArea;
|
|
}
|
|
|
|
/*!
|
|
Returns the current time in fractional seconds since startup.
|
|
*/
|
|
+ (CPTimeInterval)currentTimestamp
|
|
{
|
|
return (new Date().getTime() - _CPEventStartupMilliseconds) / 1000;
|
|
}
|
|
|
|
/*!
|
|
Creates a new keyboard event.
|
|
|
|
@param anEventType the event type. Must be one of CPKeyDown, CPKeyUp or CPFlagsChanged
|
|
@param aPoint the location of the cursor in the window specified by \c aWindowNumber
|
|
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
|
|
@param aTimestamp the time the event occurred
|
|
@param aWindowNumber the number of the CPWindow where the event occurred
|
|
@param aGraphicsContext the graphics context where the event occurred
|
|
@param characters the characters associated with the event
|
|
@param unmodCharacters the string of keys pressed without the presence of any modifiers other than Shift
|
|
@param repeatKey \c YES if this is caused by the system repeat as opposed to the user pressing the key again
|
|
@param code a number associated with the keyboard key of this event
|
|
@throws CPInternalInconsistencyException if \c anEventType is not a CPKeyDown,
|
|
CPKeyUp or CPFlagsChanged
|
|
@return the keyboard event
|
|
*/
|
|
+ (CPEvent)keyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)repeatKey keyCode:(unsigned short)code
|
|
{
|
|
return [[self alloc] _initKeyEventWithType:anEventType location:aPoint modifierFlags:modifierFlags
|
|
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext
|
|
characters:characters charactersIgnoringModifiers:unmodCharacters isARepeat:repeatKey keyCode:code];
|
|
}
|
|
|
|
/*!
|
|
Creates a new mouse event.
|
|
|
|
@param anEventType the event type
|
|
@param aPoint the location of the cursor in the window specified by \c aWindowNumber
|
|
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
|
|
@param aTimestamp the time the event occurred
|
|
@param aWindowNumber the number of the CPWindow where the event occurred
|
|
@param aGraphicsContext the graphics context where the event occurred
|
|
@param anEventNumber a number for this event
|
|
@param aClickCount the number of clicks that caused this event
|
|
@param aPressure the amount of pressure applied to the input device (ranges from 0.0 to 1.0)
|
|
@throws CPInternalInconsistencyException if an invalid event type is provided
|
|
@return the new mouse event
|
|
*/
|
|
+ (id)mouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
|
|
{
|
|
return [[self alloc] _initMouseEventWithType:anEventType location:aPoint modifierFlags:modifierFlags
|
|
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber clickCount:aClickCount pressure:aPressure];
|
|
}
|
|
|
|
/*!
|
|
Creates a new mouse tracking event.
|
|
|
|
@param anEventType the event type
|
|
@param aPoint the location of the cursor in the window specified by \c aWindowNumber
|
|
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
|
|
@param aTimestamp the time the event occurred
|
|
@param aWindowNumber the number of the CPWindow where the event occurred
|
|
@param aGraphicsContext the graphics context where the event occurred
|
|
@param anEventNumber a number for this event
|
|
@param aTrackingArea the tracking area that triggered the event
|
|
@throws CPInternalInconsistencyException if an invalid event type is provided
|
|
@return the new mouse event
|
|
*/
|
|
+ (id)enterExitEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
eventNumber:(int)anEventNumber trackingArea:(CPTrackingArea)aTrackingArea
|
|
{
|
|
return [[self alloc] _initEnterExitEventWithType:anEventType location:aPoint modifierFlags:modifierFlags timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber trackingArea:aTrackingArea];
|
|
}
|
|
|
|
/*!
|
|
Creates a new custom event.
|
|
|
|
@param anEventType the event type. Must be one of CPAppKitDefined, CPSystemDefined, CPApplicationDefined or CPPeriodic
|
|
@param aLocation the location of the cursor in the window specified by \c aWindowNumber
|
|
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
|
|
@param aTimestamp the time the event occurred
|
|
@param aWindowNumber the number of the CPWindow where the event occurred
|
|
@param aGraphicsContext the graphics context where the event occurred
|
|
@param aSubtype a numeric identifier to differentiate this event from other custom events
|
|
@param aData1 more data that describes the event
|
|
@param aData2 even more data that describes the event
|
|
@throws CPInternalInconsistencyException if an invalid event type is provided
|
|
@return the new custom event
|
|
*/
|
|
+ (CPEvent)otherEventWithType:(CPEventType)anEventType location:(CGPoint)aLocation modifierFlags:(unsigned)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
subtype:(short)aSubtype data1:(int)aData1 data2:(int)aData2
|
|
{
|
|
return [[self alloc] _initOtherEventWithType:anEventType location:aLocation modifierFlags:modifierFlags
|
|
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext subtype:aSubtype data1:aData1 data2:aData2];
|
|
}
|
|
|
|
- (id)_initWithType:(CPEventType)anEventType
|
|
{
|
|
if (self = [super init])
|
|
{
|
|
_type = anEventType;
|
|
|
|
// Make sure these are 0 rather than nil.
|
|
_deltaX = 0;
|
|
_scrollingDeltaX = 0;
|
|
_deltaY = 0;
|
|
_scrollingDeltaY = 0;
|
|
_deltaZ = 0;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/* @ignore */
|
|
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
|
|
{
|
|
if (self = [self _initWithType:anEventType])
|
|
{
|
|
_location = CGPointCreateCopy(aPoint);
|
|
_modifierFlags = modifierFlags;
|
|
_timestamp = aTimestamp;
|
|
_context = aGraphicsContext;
|
|
_eventNumber = anEventNumber;
|
|
_clickCount = aClickCount;
|
|
_pressure = aPressure;
|
|
_window = [CPApp windowWithWindowNumber:aWindowNumber];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/* @ignore */
|
|
- (id)_initEnterExitEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
eventNumber:(int)anEventNumber trackingArea:(CPTrackingArea)aTrackingArea
|
|
{
|
|
if ((anEventType != CPMouseEntered) && (anEventType != CPMouseExited) && (anEventType != CPCursorUpdate))
|
|
[CPException raise:CPInternalInconsistencyException reason:"Invalid event type"];
|
|
|
|
if (self = [self _initWithType:anEventType])
|
|
{
|
|
_location = CGPointCreateCopy(aPoint);
|
|
_modifierFlags = modifierFlags;
|
|
_timestamp = aTimestamp;
|
|
_context = aGraphicsContext;
|
|
_eventNumber = anEventNumber;
|
|
_trackingArea = aTrackingArea;
|
|
_window = [CPApp windowWithWindowNumber:aWindowNumber];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/* @ignore */
|
|
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)isARepeat keyCode:(unsigned short)code
|
|
{
|
|
if (self = [self _initWithType:anEventType])
|
|
{
|
|
_location = CGPointCreateCopy(aPoint);
|
|
_modifierFlags = modifierFlags;
|
|
_timestamp = aTimestamp;
|
|
_context = aGraphicsContext;
|
|
_characters = characters;
|
|
_charactersIgnoringModifiers = unmodCharacters;
|
|
_isARepeat = isARepeat;
|
|
_keyCode = code;
|
|
_windowNumber = aWindowNumber;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/* @ignore */
|
|
- (id)_initOtherEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
|
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
|
subtype:(short)aSubtype data1:(int)aData1 data2:(int)aData2
|
|
{
|
|
if (self = [self _initWithType:anEventType])
|
|
{
|
|
_location = CGPointCreateCopy(aPoint);
|
|
_modifierFlags = modifierFlags;
|
|
_timestamp = aTimestamp;
|
|
_context = aGraphicsContext;
|
|
_subtype = aSubtype;
|
|
_data1 = aData1;
|
|
_data2 = aData2;
|
|
_windowNumber = aWindowNumber;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/*!
|
|
Returns the location of the mouse (for mouse events).
|
|
If the receiver is not a mouse event, it returns \c nil.
|
|
If \c window returns \c nil, then the mouse coordinates will be based on the screen coordinates.
|
|
Otherwise, the coordinates are relative to the window's coordinates.
|
|
|
|
@return the location of the mouse, or \c nil for non-mouse events.
|
|
*/
|
|
- (CGPoint)locationInWindow
|
|
{
|
|
return CGPointMakeCopy(_location);
|
|
}
|
|
|
|
- (CGPoint)globalLocation
|
|
{
|
|
var theWindow = [self window],
|
|
location = [self locationInWindow];
|
|
|
|
if (theWindow)
|
|
return [theWindow convertBaseToGlobal:location];
|
|
|
|
return location;
|
|
}
|
|
|
|
/*!
|
|
Returns event information as a bit mask.
|
|
*/
|
|
- (unsigned)modifierFlags
|
|
{
|
|
return _modifierFlags;
|
|
}
|
|
|
|
/*!
|
|
Returns the time the event occurred in seconds since startup.
|
|
*/
|
|
- (CPTimeInterval)timestamp
|
|
{
|
|
return _timestamp;
|
|
}
|
|
|
|
/*!
|
|
Returns the type of event.
|
|
*/
|
|
- (CPEventType)type
|
|
{
|
|
return _type;
|
|
}
|
|
|
|
/*!
|
|
Returns the event's associated window.
|
|
*/
|
|
- (CPWindow)window
|
|
{
|
|
if (!_window)
|
|
_window = [CPApp windowWithWindowNumber:_windowNumber];
|
|
|
|
return _window;
|
|
}
|
|
|
|
/*!
|
|
The number of the window associated with the event.
|
|
*/
|
|
- (int)windowNumber
|
|
{
|
|
return _windowNumber;
|
|
}
|
|
|
|
// Mouse Event Information
|
|
/*!
|
|
Returns the button number for the mouse that generated the event.
|
|
*/
|
|
- (int)buttonNumber
|
|
{
|
|
if (_type === CPRightMouseDown || _type === CPRightMouseUp || _type === CPRightMouseDragged)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*!
|
|
Returns the number of clicks that caused this event (mouse only).
|
|
*/
|
|
- (int)clickCount
|
|
{
|
|
return _clickCount;
|
|
}
|
|
|
|
/*!
|
|
Returns the characters associated with this event (keyboard only).
|
|
|
|
@throws CPInternalInconsistencyException if this method is called on a non-key event
|
|
*/
|
|
- (CPString)characters
|
|
{
|
|
return _characters;
|
|
}
|
|
|
|
/*!
|
|
Returns the character ignoring any modifiers (except shift).
|
|
|
|
@throws CPInternalInconsistencyException if this method is called on a non-key event
|
|
*/
|
|
- (CPString)charactersIgnoringModifiers
|
|
{
|
|
return _charactersIgnoringModifiers;
|
|
}
|
|
|
|
/*!
|
|
Returns \c YES if the keyboard event was caused by the key being held down.
|
|
|
|
@throws CPInternalInconsistencyException if this method is called on a non-key event
|
|
*/
|
|
- (BOOL)isARepeat
|
|
{
|
|
return _isARepeat;
|
|
}
|
|
|
|
/*!
|
|
Returns the key's key code.
|
|
|
|
@throws CPInternalInconsistencyException if this method is called on a non-key event
|
|
*/
|
|
- (unsigned short)keyCode
|
|
{
|
|
return _keyCode;
|
|
}
|
|
|
|
+ (CGPoint)mouseLocation
|
|
{
|
|
// FIXME: this is incorrect, we shouldn't depend on the current event.
|
|
var event = [CPApp currentEvent],
|
|
eventWindow = [event window];
|
|
|
|
if (eventWindow)
|
|
return [eventWindow convertBaseToGlobal:[event locationInWindow]];
|
|
|
|
return [event locationInWindow];
|
|
}
|
|
|
|
- (float)pressure
|
|
{
|
|
return _pressure;
|
|
}
|
|
|
|
/*
|
|
@ignore
|
|
*/
|
|
- (DOMEvent)_DOMEvent
|
|
{
|
|
return _DOMEvent;
|
|
}
|
|
|
|
- (int)data1
|
|
{
|
|
return _data1;
|
|
}
|
|
|
|
- (int)data2
|
|
{
|
|
return _data2;
|
|
}
|
|
|
|
// Getting Scroll Wheel Event Information
|
|
/*!
|
|
Returns the change in the x-axis for a mouse event.
|
|
*/
|
|
- (float)deltaX
|
|
{
|
|
return _deltaX;
|
|
}
|
|
|
|
/*!
|
|
Returns the change in the y-axis for a mouse event.
|
|
*/
|
|
- (float)deltaY
|
|
{
|
|
return _deltaY;
|
|
}
|
|
|
|
/*!
|
|
Returns the change in the x-axis for a mouse event.
|
|
*/
|
|
- (float)deltaZ
|
|
{
|
|
return _deltaZ;
|
|
}
|
|
|
|
- (BOOL)hasPreciseScrollingDeltas
|
|
{
|
|
return !!_hasPreciseScrollingDeltas;
|
|
}
|
|
|
|
/*!
|
|
Returns the change in points on the x-axis for a mouse movement, unless hasPreciseScrollingDeltas is NO,
|
|
in which case the change is measured in number of "lines" or "rows" and needs to be multiplied as appropriate
|
|
to get change in pixels.
|
|
*/
|
|
- (float)scrollingDeltaX
|
|
{
|
|
return _scrollingDeltaX;
|
|
}
|
|
|
|
/*!
|
|
Returns the change in points on the y-axis for a mouse movement, unless hasPreciseScrollingDeltas is NO,
|
|
in which case the change is measured in number of "lines" or "columns" and needs to be multiplied as appropriate
|
|
to get change in pixels.
|
|
*/
|
|
- (float)scrollingDeltaY
|
|
{
|
|
return _scrollingDeltaY;
|
|
}
|
|
|
|
- (BOOL)_triggersKeyEquivalent:(CPString)aKeyEquivalent withModifierMask:aKeyEquivalentModifierMask
|
|
{
|
|
if (!aKeyEquivalent)
|
|
return NO;
|
|
|
|
if (_CPEventUpperCaseRegex.test(aKeyEquivalent))
|
|
aKeyEquivalentModifierMask |= CPShiftKeyMask;
|
|
|
|
// Windows and Linux don't have command keys, so just switch it to ctrl.
|
|
if (!CPBrowserIsOperatingSystem(CPMacOperatingSystem) && (aKeyEquivalentModifierMask & CPCommandKeyMask))
|
|
{
|
|
aKeyEquivalentModifierMask |= CPControlKeyMask;
|
|
aKeyEquivalentModifierMask &= ~CPCommandKeyMask;
|
|
}
|
|
|
|
if ((_modifierFlags & (CPShiftKeyMask | CPAlternateKeyMask | CPCommandKeyMask | CPControlKeyMask)) !== aKeyEquivalentModifierMask)
|
|
return NO;
|
|
|
|
// Treat \r and \n as the same key equivalent. See issue #710.
|
|
if (_characters === CPNewlineCharacter || _characters === CPCarriageReturnCharacter)
|
|
return CPNewlineCharacter === aKeyEquivalent || CPCarriageReturnCharacter === aKeyEquivalent;
|
|
|
|
return [_characters caseInsensitiveCompare:aKeyEquivalent] === CPOrderedSame;
|
|
}
|
|
|
|
- (BOOL)_couldBeKeyEquivalent
|
|
{
|
|
if (_type !== CPKeyDown)
|
|
return NO;
|
|
|
|
var characterCount = _characters.length;
|
|
|
|
if (!characterCount)
|
|
return NO;
|
|
|
|
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
|
|
return YES;
|
|
|
|
// Cocoa allows almost any key as a key equivalent unless the first responder is a
|
|
// text field (presumably a subclass of NSText.)
|
|
var firstResponderIsText = [[_window firstResponder] isKindOfClass:[CPTextField class]];
|
|
|
|
// Some keys are accepted as key equivalents even if the first responder is a text
|
|
// field.
|
|
for (var i = 0; i < characterCount; i++)
|
|
{
|
|
var c = _characters.charAt(i);
|
|
|
|
if ((c >= CPUpArrowFunctionKey && c <= CPModeSwitchFunctionKey) ||
|
|
c === CPEnterCharacter ||
|
|
c === CPNewlineCharacter ||
|
|
c === CPCarriageReturnCharacter ||
|
|
c === CPEscapeFunctionKey)
|
|
{
|
|
return YES;
|
|
}
|
|
}
|
|
|
|
return !firstResponderIsText;
|
|
}
|
|
|
|
/*!
|
|
Return YES if this event is a part of processing a browser controlled cut or paste event
|
|
where the browser will go ahead and do the work of cutting or pasting within the input
|
|
element after processing of this event. The implication is that it should not be done by
|
|
the CPTextField (or whatever else is controlling the input) since this would result in
|
|
nothing being cut (because the field already cut the text out), or a double paste
|
|
(because the field pasted as well as the browser).
|
|
*/
|
|
- (BOOL)_platformIsEffectingCutOrPaste
|
|
{
|
|
#if PLATFORM(DOM)
|
|
return _suppressCappuccinoCut || _suppressCappuccinoPaste;
|
|
#else
|
|
return NO;
|
|
#endif
|
|
}
|
|
|
|
|
|
/*!
|
|
Generates periodic events every \c aPeriod seconds.
|
|
|
|
@param aDelay the number of seconds before the first event
|
|
@param aPeriod the length of time in seconds between successive events
|
|
*/
|
|
+ (void)startPeriodicEventsAfterDelay:(CPTimeInterval)aDelay withPeriod:(CPTimeInterval)aPeriod
|
|
{
|
|
_CPEventPeriodicEventPeriod = aPeriod;
|
|
|
|
// FIXME: OH TIMERS!!!
|
|
_CPEventPeriodicEventTimer = window.setTimeout(function() { _CPEventPeriodicEventTimer = window.setInterval(_CPEventFirePeriodEvent, aPeriod * 1000.0); }, aDelay * 1000.0);
|
|
}
|
|
|
|
/*!
|
|
Stops the periodic events from being generated.
|
|
*/
|
|
+ (void)stopPeriodicEvents
|
|
{
|
|
if (_CPEventPeriodicEventTimer === nil)
|
|
return;
|
|
|
|
window.clearTimeout(_CPEventPeriodicEventTimer);
|
|
|
|
_CPEventPeriodicEventTimer = nil;
|
|
}
|
|
|
|
- (CPString)description
|
|
{
|
|
switch (_type)
|
|
{
|
|
case CPKeyDown:
|
|
case CPKeyUp:
|
|
case CPFlagsChanged:
|
|
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ chars=\"%@\" unmodchars=\"%@\" repeat=%d keyCode=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _characters, _charactersIgnoringModifiers, _isARepeat, _keyCode];
|
|
case CPLeftMouseDown:
|
|
case CPLeftMouseUp:
|
|
case CPRightMouseDown:
|
|
case CPRightMouseUp:
|
|
case CPMouseMoved:
|
|
case CPLeftMouseDragged:
|
|
case CPRightMouseDragged:
|
|
case CPMouseEntered:
|
|
case CPMouseExited:
|
|
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ evNum=%d click=%d buttonNumber=%d pressure=%f", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _eventNumber, _clickCount, [self buttonNumber], _pressure];
|
|
default:
|
|
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ subtype=%d data1=%d data2=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _subtype, _data1, _data2];
|
|
}
|
|
}
|
|
|
|
- (CPTrackingArea)trackingArea
|
|
{
|
|
if ((_type !== CPMouseEntered) && (_type !== CPMouseExited) && (_type !== CPCursorUpdate))
|
|
[CPException raise:CPInternalInconsistencyException format:@"You can't call trackingArea for events of type %#x", _type]
|
|
|
|
return _trackingArea;
|
|
}
|
|
|
|
@end
|
|
|
|
function _CPEventFirePeriodEvent()
|
|
{
|
|
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:CGPointMakeZero() modifierFlags:0 timestamp:[CPEvent currentTimestamp] windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
|
|
}
|
|
|
|
var CPEventClass = [CPEvent class];
|
|
|
|
function _CPEventFromNativeMouseEvent(aNativeEvent, anEventType, aPoint, modifierFlags, aTimestamp, aWindowNumber, aGraphicsContext, anEventNumber, aClickCount, aPressure)
|
|
{
|
|
aNativeEvent.isa = CPEventClass;
|
|
|
|
aNativeEvent._type = anEventType;
|
|
aNativeEvent._location = aPoint;
|
|
aNativeEvent._modifierFlags = modifierFlags;
|
|
aNativeEvent._timestamp = aTimestamp;
|
|
aNativeEvent._windowNumber = aWindowNumber;
|
|
aNativeEvent._window = nil;
|
|
aNativeEvent._context = aGraphicsContext;
|
|
aNativeEvent._eventNumber = anEventNumber;
|
|
aNativeEvent._clickCount = aClickCount;
|
|
aNativeEvent._pressure = aPressure;
|
|
|
|
return aNativeEvent;
|
|
}
|