原文连接:https://developer.chrome.com/native-client/devguide/coding/view-focus-input-events html
注意:已针对ChromeOS之外的平台公布了此处所述技术的弃用。
请访问咱们的 迁移指南 了解详情。chrome
本节介绍Native Client模块的视图更改,焦点和输入事件处理。本节假定您熟悉技术概述中提供的材料。编程
本节中使用了两个示例来讲明基本编程技术。该input_events
示例用于说明您的模块如何对键盘和鼠标输入事件作出反应。该mouse_lock
示例用于说明您的模块如何响应以查看更改事件。您能够在Native Client SDK 中的/pepper_<version>/examples/api/input_event
和/pepper_<version>/examples/api/mouse_lock
目录中找到这些示例 。还有ppapi_simple库可用于实现大部分锅炉板。该pi_generator
示例 /pepper_<version>/examples/demo/pi_generator
使用ppapi_simple来管理视图更改事件和2D图形。api
当用户使用键盘,鼠标或其余输入设备与网页交互时,浏览器会生成输入事件。在传统的Web应用程序中,这些输入事件一般经过事件侦听器和事件处理程序传递给JavaScript并在JavaScript中处理。在Native Client应用程序中,用户与模块实例的交互(例如,在模块管理的矩形内部单击)也会生成输入事件,这些事件将传递给模块。浏览器还将影响模块实例的视图更改和焦点事件传递给模块。Native Client模块能够覆盖pp :: Instance类中的某些函数来处理输入和浏览器事件。这些功能列于下表中:浏览器
功能 | 使用 |
---|---|
在浏览器中模块实例的位置,大小或剪切矩形发生更改时调用。调整浏览器窗口大小或滚动鼠标滚轮时也会发生此事件。ide |
此函数的实现可能会检查模块实例的矩形的大小是否已更改,并在收到不一样大小时从新分配graphcs上下文。 |
当模块在浏览器中的实例进入或失焦时调用(一般经过单击模块实例的内部或外部)。拥有焦点意味着键盘事件将被发送到模块实例。实例的默认条件是它没有焦点。动画 |
此函数的实现可能会启动或中止动画或闪烁的光标。 |
|
只有在您编写扩展程序以加强Chrome网络浏览器的功能时,此API才适用。例如,PDF查看器可能会实现此功能如下载和显示PDF文件。 |
当用户使用输入设备(如鼠标或键盘)与浏览器中的模块实例进行交互时调用。 在重写此功能以前,必须注册模块以接受 |
此函数的实现检查输入事件类型并相应地分支。 |
这些接口位于pp :: Instance类中。如下部分提供了如何处理这些事件的示例。
在该mouse_lock
示例中,DidChangeView()
检查实例的矩形的先前大小与新大小。它还会比较其余状态,例如应用程序是否以全屏模式运行。若是状态实际上没有变化,则不须要采起任何措施。可是,若是视图或其余状态的大小已更改,则会释放旧的图形上下文并分配新的图形上下文。
void MouseLockInstance::DidChangeView(const pp::View& view) { // DidChangeView can get called for many reasons, so we only want to // rebuild the device context if we really need to. if ((size_ == view.GetRect().size()) && (was_fullscreen_ == view.IsFullscreen()) && is_context_bound_) { return; } // ... // Reallocate the graphics context. size_ = view.GetRect().size(); device_context_ = pp::Graphics2D(this, size_, false); waiting_for_flush_completion_ = false; is_context_bound_ = BindGraphics(device_context_); // ... // Remember if we are fullscreen or not was_fullscreen_ = view.IsFullscreen(); // ... }
有关图形上下文以及如何操做图像的更多信息,请参阅:
DidChangeFocus()
单击网页中模块实例的内部或外部时调用。当实例失焦时(单击实例外部),您可能会执行诸如中止动画之类的操做。当实例从新得到焦点时,您能够从新启动动画。
void DidChangeFocus(bool focus) { // Do something like stopping animation or a blinking cursor in // the instance. }
输入事件是当用户使用鼠标,键盘或其余输入设备(例如,触摸屏)与模块实例交互时发生的事件。本节介绍input_events
示例如何处理输入事件。
在模块处理这些事件以前,必须注册模块以接受RequestInputEvents()
用于鼠标事件和RequestFilteringInputEvents()
键盘事件的输入事件。对于 input_events
例如,这是在的构造函数中完成InputEventInstance
等级:
class InputEventInstance : public pp::Instance { public: explicit InputEventInstance(PP_Instance instance) : pp::Instance(instance), event_thread_(NULL), callback_factory_(this) { RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_TOUCH); RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); } // ... };
RequestInputEvents()
并RequestFilteringInputEvents()
接受标识的组合,这些标志标识实例请求接收的事件类。输入事件类在ppb_input_event.h中的 PP_InputEvent_Class 枚举中定义。
在典型的实现中,该HandleInputEvent()
函数使用类中的函数肯定每一个事件GetType()
的InputEvent
类型。HandleInputEvent()
而后,该函数使用switch语句来分支输入事件的类型。输入事件在ppb_input_event.h中的PP_InputEvent_Type 枚举中定义。
virtual bool HandleInputEvent(const pp::InputEvent& event) { Event* event_ptr = NULL; switch (event.GetType()) { case PP_INPUTEVENT_TYPE_UNDEFINED: break; case PP_INPUTEVENT_TYPE_MOUSEDOWN: case PP_INPUTEVENT_TYPE_MOUSEUP: case PP_INPUTEVENT_TYPE_MOUSEMOVE: case PP_INPUTEVENT_TYPE_MOUSEENTER: case PP_INPUTEVENT_TYPE_MOUSELEAVE: case PP_INPUTEVENT_TYPE_CONTEXTMENU: { pp::MouseInputEvent mouse_event(event); PP_InputEvent_MouseButton pp_button = mouse_event.GetButton(); MouseEvent::MouseButton mouse_button = MouseEvent::kNone; switch (pp_button) { case PP_INPUTEVENT_MOUSEBUTTON_NONE: mouse_button = MouseEvent::kNone; break; case PP_INPUTEVENT_MOUSEBUTTON_LEFT: mouse_button = MouseEvent::kLeft; break; case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: mouse_button = MouseEvent::kMiddle; break; case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: mouse_button = MouseEvent::kRight; break; } event_ptr = new MouseEvent(ConvertEventModifier(mouse_event.GetModifiers()), mouse_button, mouse_event.GetPosition().x(), mouse_event.GetPosition().y(), mouse_event.GetClickCount(), mouse_event.GetTimeStamp(), event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU); } break; case PP_INPUTEVENT_TYPE_WHEEL: { pp::WheelInputEvent wheel_event(event); event_ptr = new WheelEvent(ConvertEventModifier(wheel_event.GetModifiers()), wheel_event.GetDelta().x(), wheel_event.GetDelta().y(), wheel_event.GetTicks().x(), wheel_event.GetTicks().y(), wheel_event.GetScrollByPage(), wheel_event.GetTimeStamp()); } break; case PP_INPUTEVENT_TYPE_RAWKEYDOWN: case PP_INPUTEVENT_TYPE_KEYDOWN: case PP_INPUTEVENT_TYPE_KEYUP: case PP_INPUTEVENT_TYPE_CHAR: { pp::KeyboardInputEvent key_event(event); event_ptr = new KeyEvent(ConvertEventModifier(key_event.GetModifiers()), key_event.GetKeyCode(), key_event.GetTimeStamp(), key_event.GetCharacterText().DebugString()); } break; default: { // For any unhandled events, send a message to the browser // so that the user is aware of these and can investigate. std::stringstream oss; oss << "Default (unhandled) event, type=" << event.GetType(); PostMessage(oss.str()); } break; } event_queue_.Push(event_ptr); return true; }
请注意,在肯定事件类型后,将InputEvent
收到的通用HandleInputEvent()
转换为特定类型。在示例代码处理的事件类型是 MouseInputEvent
,WheelInputEvent
,和KeyboardInputEvent
,还有TouchInputEvents
。有关事件类型的最新列表,请参阅InputEvent文档。有关这些事件类的参考信息,请参阅如下文档:
HandleInputEvent()
在此示例中,在主模块线程上运行。可是,大部分工做都发生在一个单独的工做线程上(请参阅参考资料 ProcessEventOnWorkerThread
)。HandleInputEvent()
将事件放入event_queue_
而且工做线程从中获取事件 event_queue_
。此处理独立于主线程发生,以避免减慢浏览器的速度。
CC-By 3.0许可下提供的内容