zoukankan      html  css  js  c++  java
  • 编写你的应用程序(十)、视图更改、焦点、输入事件

    原文链接:https://developer.chrome.com/native-client/devguide/coding/view-focus-input-events 

    注意:已针对ChromeOS以外的平台公布了此处所述技术的弃用。
    请访问我们的 迁移指南 了解详情。


    视图更改,焦点和输入事件

    本节介绍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图形。

    概观

    当用户使用键盘,鼠标或其他输入设备与网页交互时,浏览器会生成输入事件。在传统的Web应用程序中,这些输入事件通常通过事件侦听器和事件处理程序传递给JavaScript并在JavaScript中处理。在Native Client应用程序中,用户与模块实例的交互(例如,在模块管理的矩形内部单击)也会生成输入事件,这些事件将传递给模块。浏览器还将影响模块实例的视图更改和焦点事件传递给模块。Native Client模块可以覆盖pp :: Instance类中的某些函数来处理输入和浏览器事件。这些功能列于下表中:

    功能 使用

    DidChangeView

    在浏览器中模块实例的位置,大小或剪切矩形发生更改时调用。调整浏览器窗口大小或滚动鼠标滚轮时也会发生此事件。

    此函数的实现可能会检查模块实例的矩形的大小是否已更改,并在收到不同大小时重新分配graphcs上下文。

    DidChangeFocus

    当模块在浏览器中的实例进入或失焦时调用(通常通过单击模块实例的内部或外部)。拥有焦点意味着键盘事件将被发送到模块实例。实例的默认条件是它没有焦点。

    此函数的实现可能会启动或停止动画或闪烁的光标。

    HandleDocumentLoad

    pp::Instance::Init()对于基于DOMWindow导航的MIME类型实例化的全帧模块实例。这种情况仅适用于预先注册以处理某些MIME类型的模块。如果您没有专门注册处理MIME类型或不是肯定的,这适用于您,您的此函数的实现只能返回false。

    只有在您编写扩展程序以增强Chrome网络浏览器的功能时,此API才适用。例如,PDF查看器可能会实现此功能以下载和显示PDF文件。

    HandleInputEvent

    当用户使用输入设备(如鼠标或键盘)与浏览器中的模块实例进行交互时调用。 在重写此功能之前,必须注册模块以接受RequestInputEvents() 用于鼠标事件和RequestFilteringInputEvents()键盘事件的输入事件。

    此函数的实现检查输入事件类型并相应地分支。

    这些接口位于pp :: Instance类中。以下部分提供了如何处理这些事件的示例。

    处理浏览器事件

    DidChangeView()

    在该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()

    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()转换为特定类型。在示例代码处理的事件类型是 MouseInputEventWheelInputEvent,和KeyboardInputEvent,还有TouchInputEvents。有关事件类型的最新列表,请参阅InputEvent文档。有关这些事件类的参考信息,请参阅以下文档:

    线程和阻塞

    HandleInputEvent()在此示例中,在主模块线程上运行。但是,大部分工作都发生在一个单独的工作线程上(请参阅参考资料 ProcessEventOnWorkerThread)。HandleInputEvent()将事件放入event_queue_并且工作线程从中获取事件 event_queue_。此处理独立于主线程发生,以免减慢浏览器的速度。

    CC-By 3.0许可下提供的内容

  • 相关阅读:
    Eclipse导入Ant项目
    Eclipse修改默认包路径的起始文件夹
    Java中DAO/DTO/PO/VO/BO/QO/POJO
    FreeMarker与Spring MVC 4集合的HelloWorld示例
    FreeMarker与Spring MVC 4结合错误:Caused by: java.lang.NoClassDefFoundError: org/springframework/ui/freemarker/FreeMarkerConfiguration
    FreeMarker与Servlet结合示例
    FreeMarker-简单示例
    Java模板引擎-FreeMarker
    SiteMesh2-sitemesh.xml的其它映射器的用法
    SiteMesh2-sitemesh.xml的ParameterDecoratorMapper映射器的用法
  • 原文地址:https://www.cnblogs.com/SunkingYang/p/11049124.html
Copyright © 2011-2022 走看看