Native Client - Application - View Change, Focus, and Input Events
2016-11-25 10:08
645 查看
View Change, Focus, and Input Events
This section describes view change, focus, and input event handling for a Native Client module. The section assumes you are familiar with the material presented in the TechnicalOverview.
There are two examples used in this section to illustrate basic programming techniques. The
input_eventsexample
is used to illustrate how your module can react to keyboard and mouse input event. The
mouse_lockexample is used
to illustrate how your module can react to view change events. You can find these examples in the
/pepper_<version>/examples/api/input_eventand
/pepper_<version>/examples/api/mouse_lockdirectories
in the Native Client SDK. There is also the ppapi_simple library that can be used to to implement most of the boiler plate. The
pi_generatorexample
in
/pepper_<version>/examples/demo/pi_generatoruses ppapi_simple to manage view change events and 2D graphics.
Overview
When a user interacts with the web page using a keyboard, mouse or some other input device, the browser generates input events. In a traditional web application, these input events are passed to and handled in JavaScript, typically through event listeners andevent handlers. In a Native Client application, user interaction with an instance of a module (e.g., clicking inside the rectangle managed by a module) also generates input events, which are passed to the module. The browser also passes view change and focus
events that affect a module’s instance to the module. Native Client modules can override certain functions in the pp::Instanceclass
to handle input and browser events. These functions are listed in the table below:
Function | Use |
---|---|
DidChangeViewCalled when the position, size, or clip rectangle of the module’s instance in the browser has changed. This event also occurs when the browser window is resized or the mouse wheel is scrolled. | An implementation of this function might check the size of the module instance’s rectangle has changed and reallocate the graphcs context when a different size is received. |
DidChangeFocusCalled when the module’s instance in the browser has gone in or out of focus (usually by clicking inside or outside the module instance). Having focus means that keyboard events will be sent to the module instance. An instance’s default condition is that it does not have focus. | An implementation of this function might start or stop an animation or a blinking cursor. |
HandleDocumentLoad pp::Instance::Init()for a full-frame module instance that was instantiated based on the MIME type of a DOMWindow navigation. This situation only applies to modules that are pre-registered to handle certain MIME types. If you haven’t specifically registered to handle a MIME type or aren’t positive this applies to you, your implementation of this function can just return false. | This API is only applicable when you are writing an extension to enhance the abilities of the Chrome web browser. For example, a PDF viewer might implement this function to download and display a PDF file. |
HandleInputEventCalled when a user interacts with the module’s instance in the browser using an input device such as a mouse or keyboard. You must register your module to accept input events using RequestInputEvents()for mouse events and RequestFilteringInputEvents()for keyboard events prior to overriding this function. | An implementation of this function examines the input event type and branches accordingly. |
events.
Handling browser events
DidChangeView()
In the mouse_lockexample,
DidChangeView()checks
the previous size of instance’s rectangle versus the new size. It also compares other state such as whether or not the app is running in full screen mode. If none of the state has actually changed, no action is needed. However, if the size of the view or other
state has changed, it frees the old graphics context and allocates a new one.
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(); // ... }
For more information about graphics contexts and how to manipulate images, see:
pp::ImageData class
pp::Graphics2D class
DidChangeFocus()
DidChangeFocus()is called when you click inside or outside of a module’s instance in the web page. When the instance
goes out of focus (click outside of the instance), you might do something like stop an animation. When the instance regains focus, you can restart the animation.
void DidChangeFocus(bool focus) { // Do something like stopping animation or a blinking cursor in // the instance. }
Handling input events
Input events are events that occur when the user interacts with a module instance using the mouse, keyboard, or other input device (e.g., touch screen). This section describes how the input_eventsexample
handles input events.
Registering a module to accept input events
Before your module can handle these events, you must register your module to accept input events usingRequestInputEvents()for
mouse events and
RequestFilteringInputEvents()for keyboard events. For the
input_eventsexample,
this is done in the constructor of the
InputEventInstanceclass:
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()and
RequestFilteringInputEvents()accept
a combination of flags that identify the class of events that the instance is requesting to receive. Input event classes are defined in thePP_InputEvent_Class enumeration
in ppb_input_event.h.
Determining and branching on event types
In a typical implementation, the HandleInputEvent()function determines the type of each event using the
GetType()function
found in the
InputEventclass. The
HandleInputEvent()function
then uses a switch statement to branch on the type of input event. Input events are defined in the PP_InputEvent_Typeenumeration
in ppb_input_event.h.
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; }
Notice that the generic
InputEventreceived by
HandleInputEvent()is
converted into a specific type after the event type is determined. The event types handled in the example code are
MouseInputEvent,
WheelInputEvent,
and
KeyboardInputEvent. There are also
TouchInputEvents.
For the latest list of event types, see the InputEvent documentation. For reference information related to
the these event classes, see the following documentation:
pp::MouseInputEvent class
pp::WheelInputEvent class
pp::KeyboardInputEvent class
Threading and blocking
HandleInputEvent()in this example runs on the main module thread. However, the bulk of the work happens on a separate
worker thread (see
ProcessEventOnWorkerThread).
HandleInputEvent()puts
events in the
event_queue_and the worker thread takes events from the
event_queue_.
This processing happens independently of the main thread, so as not to slow down the browser.
Content available under the CC-By 3.0 license
相关文章推荐
- 1.4 Dynamically change the look of an application by using view states,transitions and effects
- 怎样控制Qt标题栏(How can I handle events in the titlebar and change its color etc ? )
- xml无法显示(Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again la
- TextView with SingleLine as true and Gravity as Center not passing the events to the ViewPager if it has a Click Event
- android的xml中<viewStub />, <requestFocus />, <merge /> and <include />的用法
- Focus on Application Support and Maintenance
- Creating custom headers and footers in Application level events using global.asax
- Spring Boot(二)Application events and listeners
- Change ICON of MFC Application and Dialog
- SearchView Get focus and pop soft keyboard
- 补充UIAlertView的一些知识,包括UIAlertViewStyleLoginAndPasswordInput和代理方法
- 电子书下载:Pro WPF and Silverlight MVVM: Effective Application Development with Model-View-ViewModel
- android <viewStub />, <requestFocus />, <merge /> and <include />用法
- <viewStub/>, <requestFocus />, <merge />and<include
- View and Change the Disk Signature in the MBR
- Xcode and iOS Simulator issue report: got 'Thread 1: Signal SIGABRT' for single view application
- Axure RP Pro - 翻译 - 5.5 Tutorial教程 - AXURE 202 Article 4: Rich Functionality复杂功能 - OnFocus and OnLostFocus Events - OnFocus和OnLo
- Model View Controller (MVC) Using C#, Delegates and Events in .NET
- android <viewStub />, <requestFocus />, <merge /> and <include />用法
- [React Native] State and Touch Events -- TextInput, TouchableHighLight