gecko/widget/nsGUIEvent.h
2013-09-24 19:04:15 +09:00

489 lines
14 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsGUIEvent_h__
#define nsGUIEvent_h__
#include "mozilla/BasicEvents.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
#include "nsPoint.h"
#include "nsRect.h"
#include "nsIDOMDataTransfer.h"
#include "nsWeakPtr.h"
#include "nsITransferable.h"
class nsIContent;
#define NS_EVENT_TYPE_NULL 0
#define NS_EVENT_TYPE_ALL 1 // Not a real event type
/**
* Script error event
*/
class nsScriptErrorEvent : public nsEvent
{
public:
nsScriptErrorEvent(bool isTrusted, uint32_t msg)
: nsEvent(isTrusted, msg, NS_SCRIPT_ERROR_EVENT),
lineNr(0), errorMsg(nullptr), fileName(nullptr)
{
}
int32_t lineNr;
const PRUnichar* errorMsg;
const PRUnichar* fileName;
// XXX Not tested by test_assign_event_data.html
void AssignScriptErrorEventData(const nsScriptErrorEvent& aEvent,
bool aCopyTargets)
{
AssignEventData(aEvent, aCopyTargets);
lineNr = aEvent.lineNr;
// We don't copy errorMsg and fileName. If it's necessary, perhaps, this
// should duplicate the characters and free them at destructing.
errorMsg = nullptr;
fileName = nullptr;
}
};
class nsScrollPortEvent : public nsGUIEvent
{
public:
enum orientType {
vertical = 0,
horizontal = 1,
both = 2
};
nsScrollPortEvent(bool isTrusted, uint32_t msg, nsIWidget *w)
: nsGUIEvent(isTrusted, msg, w, NS_SCROLLPORT_EVENT),
orient(vertical)
{
}
orientType orient;
void AssignScrollPortEventData(const nsScrollPortEvent& aEvent,
bool aCopyTargets)
{
AssignGUIEventData(aEvent, aCopyTargets);
orient = aEvent.orient;
}
};
class nsScrollAreaEvent : public nsGUIEvent
{
public:
nsScrollAreaEvent(bool isTrusted, uint32_t msg, nsIWidget *w)
: nsGUIEvent(isTrusted, msg, w, NS_SCROLLAREA_EVENT)
{
}
nsRect mArea;
void AssignScrollAreaEventData(const nsScrollAreaEvent& aEvent,
bool aCopyTargets)
{
AssignGUIEventData(aEvent, aCopyTargets);
mArea = aEvent.mArea;
}
};
class nsContentCommandEvent : public nsGUIEvent
{
public:
nsContentCommandEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget,
bool aOnlyEnabledCheck = false) :
nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_CONTENT_COMMAND_EVENT),
mOnlyEnabledCheck(bool(aOnlyEnabledCheck)),
mSucceeded(false), mIsEnabled(false)
{
}
// NS_CONTENT_COMMAND_PASTE_TRANSFERABLE
nsCOMPtr<nsITransferable> mTransferable; // [in]
// NS_CONTENT_COMMAND_SCROLL
// for mScroll.mUnit
enum {
eCmdScrollUnit_Line,
eCmdScrollUnit_Page,
eCmdScrollUnit_Whole
};
struct ScrollInfo {
ScrollInfo() :
mAmount(0), mUnit(eCmdScrollUnit_Line), mIsHorizontal(false)
{
}
int32_t mAmount; // [in]
uint8_t mUnit; // [in]
bool mIsHorizontal; // [in]
} mScroll;
bool mOnlyEnabledCheck; // [in]
bool mSucceeded; // [out]
bool mIsEnabled; // [out]
};
/**
* Form event
*
* We hold the originating form control for form submit and reset events.
* originator is a weak pointer (does not hold a strong reference).
*/
class nsFormEvent : public nsEvent
{
public:
nsFormEvent(bool isTrusted, uint32_t msg)
: nsEvent(isTrusted, msg, NS_FORM_EVENT),
originator(nullptr)
{
}
nsIContent *originator;
void AssignFormEventData(const nsFormEvent& aEvent, bool aCopyTargets)
{
AssignEventData(aEvent, aCopyTargets);
// Don't copy originator due to a weak pointer.
}
};
/**
* Command event
*
* Custom commands for example from the operating system.
*/
class nsCommandEvent : public nsGUIEvent
{
public:
nsCommandEvent(bool isTrusted, nsIAtom* aEventType,
nsIAtom* aCommand, nsIWidget* w)
: nsGUIEvent(isTrusted, NS_USER_DEFINED_EVENT, w, NS_COMMAND_EVENT)
{
userType = aEventType;
command = aCommand;
}
nsCOMPtr<nsIAtom> command;
// XXX Not tested by test_assign_event_data.html
void AssignCommandEventData(const nsCommandEvent& aEvent, bool aCopyTargets)
{
AssignGUIEventData(aEvent, aCopyTargets);
// command must have been initialized with the constructor.
}
};
/**
* Clipboard event
*/
class nsClipboardEvent : public nsEvent
{
public:
nsClipboardEvent(bool isTrusted, uint32_t msg)
: nsEvent(isTrusted, msg, NS_CLIPBOARD_EVENT)
{
}
nsCOMPtr<nsIDOMDataTransfer> clipboardData;
void AssignClipboardEventData(const nsClipboardEvent& aEvent,
bool aCopyTargets)
{
AssignEventData(aEvent, aCopyTargets);
clipboardData = aEvent.clipboardData;
}
};
class nsFocusEvent : public nsUIEvent
{
public:
nsFocusEvent(bool isTrusted, uint32_t msg)
: nsUIEvent(isTrusted, msg, 0),
fromRaise(false),
isRefocus(false)
{
eventStructType = NS_FOCUS_EVENT;
}
/// The possible related target
nsCOMPtr<mozilla::dom::EventTarget> relatedTarget;
bool fromRaise;
bool isRefocus;
void AssignFocusEventData(const nsFocusEvent& aEvent, bool aCopyTargets)
{
AssignUIEventData(aEvent, aCopyTargets);
relatedTarget = aCopyTargets ? aEvent.relatedTarget : nullptr;
fromRaise = aEvent.fromRaise;
isRefocus = aEvent.isRefocus;
}
};
class nsTransitionEvent : public nsEvent
{
public:
nsTransitionEvent(bool isTrusted, uint32_t msg,
const nsAString& propertyNameArg, float elapsedTimeArg,
const nsAString& pseudoElementArg)
: nsEvent(isTrusted, msg, NS_TRANSITION_EVENT),
propertyName(propertyNameArg), elapsedTime(elapsedTimeArg),
pseudoElement(pseudoElementArg)
{
}
nsString propertyName;
float elapsedTime;
nsString pseudoElement;
void AssignTransitionEventData(const nsTransitionEvent& aEvent,
bool aCopyTargets)
{
AssignEventData(aEvent, aCopyTargets);
// propertyName, elapsedTime and pseudoElement must have been initialized
// with the constructor.
}
};
class nsAnimationEvent : public nsEvent
{
public:
nsAnimationEvent(bool isTrusted, uint32_t msg,
const nsAString &animationNameArg, float elapsedTimeArg,
const nsAString &pseudoElementArg)
: nsEvent(isTrusted, msg, NS_ANIMATION_EVENT),
animationName(animationNameArg), elapsedTime(elapsedTimeArg),
pseudoElement(pseudoElementArg)
{
}
nsString animationName;
float elapsedTime;
nsString pseudoElement;
void AssignAnimationEventData(const nsAnimationEvent& aEvent,
bool aCopyTargets)
{
AssignEventData(aEvent, aCopyTargets);
// animationName, elapsedTime and pseudoElement must have been initialized
// with the constructor.
}
};
/**
* Native event pluginEvent for plugins.
*/
class nsPluginEvent : public nsGUIEvent
{
public:
nsPluginEvent(bool isTrusted, uint32_t msg, nsIWidget *w)
: nsGUIEvent(isTrusted, msg, w, NS_PLUGIN_EVENT),
retargetToFocusedDocument(false)
{
}
// If TRUE, this event needs to be retargeted to focused document.
// Otherwise, never retargeted.
// Defaults to false.
bool retargetToFocusedDocument;
};
#define NS_IS_INPUT_EVENT(evnt) \
(((evnt)->eventStructType == NS_INPUT_EVENT) || \
((evnt)->eventStructType == NS_MOUSE_EVENT) || \
((evnt)->eventStructType == NS_KEY_EVENT) || \
((evnt)->eventStructType == NS_TOUCH_EVENT) || \
((evnt)->eventStructType == NS_DRAG_EVENT) || \
((evnt)->eventStructType == NS_MOUSE_SCROLL_EVENT) || \
((evnt)->eventStructType == NS_WHEEL_EVENT) || \
((evnt)->eventStructType == NS_SIMPLE_GESTURE_EVENT))
#define NS_IS_MOUSE_EVENT(evnt) \
(((evnt)->message == NS_MOUSE_BUTTON_DOWN) || \
((evnt)->message == NS_MOUSE_BUTTON_UP) || \
((evnt)->message == NS_MOUSE_CLICK) || \
((evnt)->message == NS_MOUSE_DOUBLECLICK) || \
((evnt)->message == NS_MOUSE_ENTER) || \
((evnt)->message == NS_MOUSE_EXIT) || \
((evnt)->message == NS_MOUSE_ACTIVATE) || \
((evnt)->message == NS_MOUSE_ENTER_SYNTH) || \
((evnt)->message == NS_MOUSE_EXIT_SYNTH) || \
((evnt)->message == NS_MOUSE_MOZHITTEST) || \
((evnt)->message == NS_MOUSE_MOVE))
#define NS_IS_MOUSE_EVENT_STRUCT(evnt) \
((evnt)->eventStructType == NS_MOUSE_EVENT || \
(evnt)->eventStructType == NS_DRAG_EVENT)
#define NS_IS_MOUSE_LEFT_CLICK(evnt) \
((evnt)->eventStructType == NS_MOUSE_EVENT && \
(evnt)->message == NS_MOUSE_CLICK && \
static_cast<nsMouseEvent*>((evnt))->button == nsMouseEvent::eLeftButton)
#define NS_IS_CONTEXT_MENU_KEY(evnt) \
((evnt)->eventStructType == NS_MOUSE_EVENT && \
(evnt)->message == NS_CONTEXTMENU && \
static_cast<nsMouseEvent*>((evnt))->context == nsMouseEvent::eContextMenuKey)
#define NS_IS_DRAG_EVENT(evnt) \
(((evnt)->message == NS_DRAGDROP_ENTER) || \
((evnt)->message == NS_DRAGDROP_OVER) || \
((evnt)->message == NS_DRAGDROP_EXIT) || \
((evnt)->message == NS_DRAGDROP_DRAGDROP) || \
((evnt)->message == NS_DRAGDROP_GESTURE) || \
((evnt)->message == NS_DRAGDROP_DRAG) || \
((evnt)->message == NS_DRAGDROP_END) || \
((evnt)->message == NS_DRAGDROP_START) || \
((evnt)->message == NS_DRAGDROP_DROP) || \
((evnt)->message == NS_DRAGDROP_LEAVE_SYNTH))
#define NS_IS_KEY_EVENT(evnt) \
(((evnt)->message == NS_KEY_DOWN) || \
((evnt)->message == NS_KEY_PRESS) || \
((evnt)->message == NS_KEY_UP))
#define NS_IS_IME_EVENT(evnt) \
(((evnt)->message == NS_TEXT_TEXT) || \
((evnt)->message == NS_COMPOSITION_START) || \
((evnt)->message == NS_COMPOSITION_END) || \
((evnt)->message == NS_COMPOSITION_UPDATE))
#define NS_IS_ACTIVATION_EVENT(evnt) \
(((evnt)->message == NS_PLUGIN_ACTIVATE) || \
((evnt)->message == NS_PLUGIN_FOCUS))
#define NS_IS_QUERY_CONTENT_EVENT(evnt) \
((evnt)->eventStructType == NS_QUERY_CONTENT_EVENT)
#define NS_IS_SELECTION_EVENT(evnt) \
(((evnt)->message == NS_SELECTION_SET))
#define NS_IS_CONTENT_COMMAND_EVENT(evnt) \
((evnt)->eventStructType == NS_CONTENT_COMMAND_EVENT)
#define NS_IS_PLUGIN_EVENT(evnt) \
(((evnt)->message == NS_PLUGIN_INPUT_EVENT) || \
((evnt)->message == NS_PLUGIN_FOCUS_EVENT))
#define NS_IS_RETARGETED_PLUGIN_EVENT(evnt) \
(NS_IS_PLUGIN_EVENT(evnt) && \
(static_cast<nsPluginEvent*>(evnt)->retargetToFocusedDocument))
#define NS_IS_NON_RETARGETED_PLUGIN_EVENT(evnt) \
(NS_IS_PLUGIN_EVENT(evnt) && \
!(static_cast<nsPluginEvent*>(evnt)->retargetToFocusedDocument))
// Be aware the query content events and the selection events are a part of IME
// processing. So, you shouldn't use NS_IS_IME_EVENT macro directly in most
// cases, you should use NS_IS_IME_RELATED_EVENT instead.
#define NS_IS_IME_RELATED_EVENT(evnt) \
(NS_IS_IME_EVENT(evnt) || \
NS_IS_QUERY_CONTENT_EVENT(evnt) || \
NS_IS_SELECTION_EVENT(evnt))
/**
* Whether the event should be handled by the frame of the mouse cursor
* position or not. When it should be handled there (e.g., the mouse events),
* this returns TRUE.
*/
inline bool NS_IsEventUsingCoordinates(nsEvent* aEvent)
{
return !NS_IS_KEY_EVENT(aEvent) && !NS_IS_IME_RELATED_EVENT(aEvent) &&
!NS_IS_CONTEXT_MENU_KEY(aEvent) && !NS_IS_ACTIVATION_EVENT(aEvent) &&
!NS_IS_PLUGIN_EVENT(aEvent) &&
!NS_IS_CONTENT_COMMAND_EVENT(aEvent) &&
aEvent->message != NS_PLUGIN_RESOLUTION_CHANGED;
}
/**
* Whether the event should be handled by the focused DOM window in the
* same top level window's or not. E.g., key events, IME related events
* (including the query content events, they are used in IME transaction)
* should be handled by the (last) focused window rather than the dispatched
* window.
*
* NOTE: Even if this returns TRUE, the event isn't going to be handled by the
* application level active DOM window which is on another top level window.
* So, when the event is fired on a deactive window, the event is going to be
* handled by the last focused DOM window in the last focused window.
*/
inline bool NS_IsEventTargetedAtFocusedWindow(nsEvent* aEvent)
{
return NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_RELATED_EVENT(aEvent) ||
NS_IS_CONTEXT_MENU_KEY(aEvent) ||
NS_IS_CONTENT_COMMAND_EVENT(aEvent) ||
NS_IS_RETARGETED_PLUGIN_EVENT(aEvent);
}
/**
* Whether the event should be handled by the focused content or not. E.g.,
* key events, IME related events and other input events which are not handled
* by the frame of the mouse cursor position.
*
* NOTE: Even if this returns TRUE, the event isn't going to be handled by the
* application level active DOM window which is on another top level window.
* So, when the event is fired on a deactive window, the event is going to be
* handled by the last focused DOM element of the last focused DOM window in
* the last focused window.
*/
inline bool NS_IsEventTargetedAtFocusedContent(nsEvent* aEvent)
{
return NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_RELATED_EVENT(aEvent) ||
NS_IS_CONTEXT_MENU_KEY(aEvent) ||
NS_IS_RETARGETED_PLUGIN_EVENT(aEvent);
}
/**
* Whether the event should cause a DOM event.
*/
inline bool NS_IsAllowedToDispatchDOMEvent(nsEvent* aEvent)
{
switch (aEvent->eventStructType) {
case NS_MOUSE_EVENT:
// We want synthesized mouse moves to cause mouseover and mouseout
// DOM events (nsEventStateManager::PreHandleEvent), but not mousemove
// DOM events.
// Synthesized button up events also do not cause DOM events because they
// do not have a reliable refPoint.
return static_cast<nsMouseEvent*>(aEvent)->reason == nsMouseEvent::eReal;
case NS_WHEEL_EVENT: {
// wheel event whose all delta values are zero by user pref applied, it
// shouldn't cause a DOM event.
mozilla::WheelEvent* wheelEvent =
static_cast<mozilla::WheelEvent*>(aEvent);
return wheelEvent->deltaX != 0.0 || wheelEvent->deltaY != 0.0 ||
wheelEvent->deltaZ != 0.0;
}
default:
return true;
}
}
#endif // nsGUIEvent_h__