1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/c/dev/ppb_file_chooser_dev.h"
6#include "ppapi/c/pp_input_event.h"
7#include "ppapi/cpp/completion_callback.h"
8#include "ppapi/cpp/dev/file_chooser_dev.h"
9#include "ppapi/cpp/file_ref.h"
10#include "ppapi/cpp/input_event.h"
11#include "ppapi/cpp/module.h"
12#include "ppapi/cpp/private/instance_private.h"
13#include "ppapi/cpp/private/var_private.h"
14#include "ppapi/utility/completion_callback_factory.h"
15
16class MyInstance : public pp::InstancePrivate {
17 public:
18  MyInstance(PP_Instance instance)
19      : pp::InstancePrivate(instance) {
20    callback_factory_.Initialize(this);
21    RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
22  }
23
24  virtual bool HandleInputEvent(const pp::InputEvent& event) {
25    switch (event.GetType()) {
26      case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
27        pp::MouseInputEvent mouse_event(event);
28        if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
29          ShowFileChooser(false);
30        else if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_RIGHT)
31          ShowFileChooser(true);
32        else
33          return false;
34
35        return true;
36      }
37      default:
38        return false;
39    }
40  }
41
42 private:
43  void ShowFileChooser(bool multi_select) {
44    RecreateConsole();
45
46    PP_FileChooserMode_Dev mode =
47        (multi_select ? PP_FILECHOOSERMODE_OPENMULTIPLE
48                      : PP_FILECHOOSERMODE_OPEN);
49    std::string accept_types = (multi_select ? "" : "text/plain");
50
51    chooser_ = pp::FileChooser_Dev(this, mode, accept_types);
52    chooser_.Show(callback_factory_.NewCallbackWithOutput(
53        &MyInstance::ShowSelectedFileNames));
54  }
55
56  void ShowSelectedFileNames(int32_t result,
57                             const std::vector<pp::FileRef>& files) {
58    if (result != PP_OK)
59      return;
60    for (size_t i = 0; i < files.size(); i++)
61      Log(files[i].GetName());
62  }
63
64  void RecreateConsole() {
65    pp::VarPrivate doc = GetWindowObject().GetProperty("document");
66    pp::VarPrivate body = doc.GetProperty("body");
67    if (!console_.is_undefined())
68      body.Call("removeChild", console_);
69
70    console_ = doc.Call("createElement", "pre");
71    console_.SetProperty("id", "console");
72    console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
73    body.Call("appendChild", console_);
74  }
75
76  void Log(const pp::Var& var) {
77    pp::VarPrivate doc = GetWindowObject().GetProperty("document");
78    console_.Call("appendChild", doc.Call("createTextNode", var));
79    console_.Call("appendChild", doc.Call("createTextNode", "\n"));
80  }
81
82  pp::FileChooser_Dev chooser_;
83
84  pp::CompletionCallbackFactory<MyInstance> callback_factory_;
85  pp::VarPrivate console_;
86};
87
88class MyModule : public pp::Module {
89 public:
90  MyModule() : pp::Module() {}
91  virtual ~MyModule() {}
92
93  virtual pp::Instance* CreateInstance(PP_Instance instance) {
94    return new MyInstance(instance);
95  }
96};
97
98namespace pp {
99
100// Factory function for your specialization of the Module object.
101Module* CreateModule() {
102  return new MyModule();
103}
104
105}  // namespace pp
106