| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "mojo/examples/window_manager/window_manager.mojom.h" | 8 #include "mojo/examples/window_manager/window_manager.mojom.h" |
| 9 #include "mojo/public/cpp/application/application.h" | 9 #include "mojo/public/cpp/application/application.h" |
| 10 #include "mojo/services/navigation/navigation.mojom.h" | 10 #include "mojo/services/navigation/navigation.mojom.h" |
| 11 #include "mojo/services/public/cpp/view_manager/node.h" | 11 #include "mojo/services/public/cpp/view_manager/node.h" |
| 12 #include "mojo/services/public/cpp/view_manager/view.h" | 12 #include "mojo/services/public/cpp/view_manager/view.h" |
| 13 #include "mojo/services/public/cpp/view_manager/view_manager.h" | 13 #include "mojo/services/public/cpp/view_manager/view_manager.h" |
| 14 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" | 14 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" |
| 15 #include "mojo/services/public/cpp/view_manager/view_observer.h" | 15 #include "mojo/services/public/cpp/view_manager/view_observer.h" |
| 16 #include "mojo/services/public/interfaces/launcher/launcher.mojom.h" |
| 16 #include "ui/events/event_constants.h" | 17 #include "ui/events/event_constants.h" |
| 17 | 18 |
| 18 #if defined CreateWindow | 19 #if defined CreateWindow |
| 19 #undef CreateWindow | 20 #undef CreateWindow |
| 20 #endif | 21 #endif |
| 21 | 22 |
| 22 using mojo::view_manager::Id; | 23 using mojo::view_manager::Id; |
| 23 using mojo::view_manager::Node; | 24 using mojo::view_manager::Node; |
| 24 using mojo::view_manager::NodeObserver; | 25 using mojo::view_manager::NodeObserver; |
| 25 using mojo::view_manager::View; | 26 using mojo::view_manager::View; |
| 26 using mojo::view_manager::ViewManager; | 27 using mojo::view_manager::ViewManager; |
| 27 using mojo::view_manager::ViewManagerDelegate; | 28 using mojo::view_manager::ViewManagerDelegate; |
| 28 using mojo::view_manager::ViewObserver; | 29 using mojo::view_manager::ViewObserver; |
| 29 | 30 |
| 30 namespace mojo { | 31 namespace mojo { |
| 31 namespace examples { | 32 namespace examples { |
| 32 | 33 |
| 33 class WindowManager; | 34 class WindowManager; |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 | 37 |
| 37 const SkColor kColors[] = { SK_ColorYELLOW, | 38 const SkColor kColors[] = { SK_ColorYELLOW, |
| 38 SK_ColorRED, | 39 SK_ColorRED, |
| 39 SK_ColorGREEN, | 40 SK_ColorGREEN, |
| 40 SK_ColorMAGENTA }; | 41 SK_ColorMAGENTA }; |
| 41 | 42 |
| 42 const char kEmbeddedAppURL[] = "mojo:mojo_embedded_app"; | |
| 43 const char kNestingAppURL[] = "mojo:mojo_nesting_app"; | |
| 44 const char kMojoBrowserURL[] = "mojo:mojo_browser"; | |
| 45 | |
| 46 } // namespace | 43 } // namespace |
| 47 | 44 |
| 48 class WindowManagerConnection : public InterfaceImpl<IWindowManager> { | 45 class WindowManagerConnection : public InterfaceImpl<IWindowManager> { |
| 49 public: | 46 public: |
| 50 explicit WindowManagerConnection(WindowManager* window_manager) | 47 explicit WindowManagerConnection(WindowManager* window_manager) |
| 51 : window_manager_(window_manager) {} | 48 : window_manager_(window_manager) {} |
| 52 virtual ~WindowManagerConnection() {} | 49 virtual ~WindowManagerConnection() {} |
| 53 | 50 |
| 54 private: | 51 private: |
| 55 // Overridden from IWindowManager: | 52 // Overridden from IWindowManager: |
| 56 virtual void CloseWindow(Id node_id) OVERRIDE; | 53 virtual void CloseWindow(Id node_id) OVERRIDE; |
| 57 | 54 |
| 58 WindowManager* window_manager_; | 55 WindowManager* window_manager_; |
| 59 | 56 |
| 60 DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); | 57 DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); |
| 61 }; | 58 }; |
| 62 | 59 |
| 60 class NavigatorHost : public InterfaceImpl<navigation::NavigatorHost> { |
| 61 public: |
| 62 explicit NavigatorHost(WindowManager* window_manager) |
| 63 : window_manager_(window_manager) { |
| 64 } |
| 65 virtual ~NavigatorHost() { |
| 66 } |
| 67 private: |
| 68 virtual void RequestNavigate( |
| 69 uint32 source_node_id, |
| 70 navigation::NavigationDetailsPtr nav_details) OVERRIDE; |
| 71 WindowManager* window_manager_; |
| 72 DISALLOW_COPY_AND_ASSIGN(NavigatorHost); |
| 73 }; |
| 74 |
| 63 class WindowManager : public Application, | 75 class WindowManager : public Application, |
| 64 public ViewObserver, | 76 public ViewObserver, |
| 65 public ViewManagerDelegate { | 77 public ViewManagerDelegate, |
| 78 public InterfaceImpl<launcher::LauncherClient> { |
| 66 public: | 79 public: |
| 67 WindowManager() : view_manager_(NULL) {} | 80 WindowManager() : launcher_ui_(NULL), view_manager_(NULL) {} |
| 68 virtual ~WindowManager() {} | 81 virtual ~WindowManager() {} |
| 69 | 82 |
| 70 void CloseWindow(Id node_id) { | 83 void CloseWindow(Id node_id) { |
| 71 Node* node = view_manager_->GetNodeById(node_id); | 84 Node* node = view_manager_->GetNodeById(node_id); |
| 72 DCHECK(node); | 85 DCHECK(node); |
| 86 std::vector<Node*>::iterator iter = |
| 87 std::find(windows_.begin(), windows_.end(), node); |
| 88 DCHECK(iter != windows_.end()); |
| 89 windows_.erase(iter); |
| 73 node->Destroy(); | 90 node->Destroy(); |
| 74 } | 91 } |
| 75 | 92 |
| 93 void RequestNavigate( |
| 94 uint32 source_node_id, |
| 95 navigation::NavigationDetailsPtr nav_details) { |
| 96 if (!launcher_.get()) { |
| 97 ConnectTo("mojo:mojo_launcher", &launcher_); |
| 98 launcher_.set_client(this); |
| 99 } |
| 100 launcher_->Launch(nav_details->url); |
| 101 } |
| 102 |
| 76 private: | 103 private: |
| 77 // Overridden from Application: | 104 // Overridden from Application: |
| 78 virtual void Initialize() MOJO_OVERRIDE { | 105 virtual void Initialize() MOJO_OVERRIDE { |
| 79 AddService<WindowManagerConnection>(this); | 106 AddService<WindowManagerConnection>(this); |
| 107 AddService<NavigatorHost>(this); |
| 80 ViewManager::Create(this, this); | 108 ViewManager::Create(this, this); |
| 81 } | 109 } |
| 82 | 110 |
| 83 // Overridden from ViewObserver: | 111 // Overridden from ViewObserver: |
| 84 virtual void OnViewInputEvent(View* view, const EventPtr& event) OVERRIDE { | 112 virtual void OnViewInputEvent(View* view, const EventPtr& event) OVERRIDE { |
| 85 if (event->action == ui::ET_MOUSE_RELEASED) { | 113 if (event->action == ui::ET_MOUSE_RELEASED) { |
| 114 std::string app_url; |
| 86 if (event->flags & ui::EF_LEFT_MOUSE_BUTTON) | 115 if (event->flags & ui::EF_LEFT_MOUSE_BUTTON) |
| 87 CreateWindow(kEmbeddedAppURL); | 116 app_url = "mojo:mojo_embedded_app"; |
| 88 else if (event->flags & ui::EF_RIGHT_MOUSE_BUTTON) | 117 else if (event->flags & ui::EF_RIGHT_MOUSE_BUTTON) |
| 89 CreateWindow(kNestingAppURL); | 118 app_url = "mojo:mojo_nesting_app"; |
| 90 else if (event->flags & ui::EF_MIDDLE_MOUSE_BUTTON) | 119 DCHECK(!app_url.empty()); |
| 91 CreateWindow(kMojoBrowserURL); | 120 |
| 121 Node* node = view_manager_->GetNodeById(parent_node_id_); |
| 122 navigation::NavigationDetailsPtr nav_details( |
| 123 navigation::NavigationDetails::New()); |
| 124 size_t index = node->children().size() - 1; |
| 125 nav_details->url = base::StringPrintf( |
| 126 "%s/%x", app_url.c_str(), kColors[index % arraysize(kColors)]); |
| 127 CreateWindow(app_url, nav_details.Pass()); |
| 92 } | 128 } |
| 93 } | 129 } |
| 94 | 130 |
| 95 // Overridden from ViewManagerDelegate: | 131 // Overridden from ViewManagerDelegate: |
| 96 virtual void OnRootAdded(ViewManager* view_manager, Node* root) OVERRIDE { | 132 virtual void OnRootAdded(ViewManager* view_manager, Node* root) OVERRIDE { |
| 97 DCHECK(!view_manager_); | 133 DCHECK(!view_manager_); |
| 98 view_manager_ = view_manager; | 134 view_manager_ = view_manager; |
| 99 | 135 |
| 100 Node* node = Node::Create(view_manager); | 136 Node* node = Node::Create(view_manager); |
| 101 view_manager->GetRoots().front()->AddChild(node); | 137 view_manager->GetRoots().front()->AddChild(node); |
| 102 node->SetBounds(gfx::Rect(800, 600)); | 138 node->SetBounds(gfx::Rect(800, 600)); |
| 103 parent_node_id_ = node->id(); | 139 parent_node_id_ = node->id(); |
| 104 | 140 |
| 105 View* view = View::Create(view_manager); | 141 View* view = View::Create(view_manager); |
| 106 node->SetActiveView(view); | 142 node->SetActiveView(view); |
| 107 view->SetColor(SK_ColorBLUE); | 143 view->SetColor(SK_ColorBLUE); |
| 108 view->AddObserver(this); | 144 view->AddObserver(this); |
| 145 |
| 146 CreateLauncherUI(); |
| 109 } | 147 } |
| 110 | 148 |
| 111 void CreateWindow(const std::string& url) { | 149 // Overridden from LauncherClient: |
| 112 Node* node = view_manager_->GetNodeById(parent_node_id_); | 150 virtual void OnLaunch( |
| 151 const mojo::String& handler_url, |
| 152 URLResponsePtr response, |
| 153 ScopedDataPipeConsumerHandle response_body_stream) OVERRIDE { |
| 154 navigation::NavigationDetailsPtr nav_details( |
| 155 navigation::NavigationDetails::New()); |
| 156 nav_details->url = response->url; |
| 157 nav_details->response = response.Pass(); |
| 158 nav_details->response_body_stream = response_body_stream.Pass(); |
| 159 CreateWindow(handler_url, nav_details.Pass()); |
| 160 } |
| 113 | 161 |
| 114 gfx::Rect bounds(50, 50, 400, 400); | 162 void CreateLauncherUI() { |
| 115 if (!node->children().empty()) { | 163 navigation::NavigationDetailsPtr nav_details; |
| 116 gfx::Point position = node->children().back()->bounds().origin(); | 164 launcher_ui_ = CreateChild("mojo:mojo_browser", gfx::Rect(25, 25, 400, 25), |
| 117 position.Offset(50, 50); | 165 nav_details.Pass()); |
| 166 } |
| 167 |
| 168 void CreateWindow(const std::string& handler_url, |
| 169 navigation::NavigationDetailsPtr nav_details) { |
| 170 gfx::Rect bounds(25, 75, 400, 400); |
| 171 if (!windows_.empty()) { |
| 172 gfx::Point position = windows_.back()->bounds().origin(); |
| 173 position.Offset(35, 35); |
| 118 bounds.set_origin(position); | 174 bounds.set_origin(position); |
| 119 } | 175 } |
| 176 windows_.push_back(CreateChild(handler_url, bounds, nav_details.Pass())); |
| 177 } |
| 120 | 178 |
| 179 Node* CreateChild(const std::string& url, |
| 180 const gfx::Rect& bounds, |
| 181 navigation::NavigationDetailsPtr nav_details) { |
| 182 Node* node = view_manager_->GetNodeById(parent_node_id_); |
| 121 Node* embedded = Node::Create(view_manager_); | 183 Node* embedded = Node::Create(view_manager_); |
| 122 node->AddChild(embedded); | 184 node->AddChild(embedded); |
| 123 embedded->SetBounds(bounds); | 185 embedded->SetBounds(bounds); |
| 124 embedded->Embed(url); | 186 embedded->Embed(url); |
| 125 | 187 |
| 126 // TODO(aa): Is there a way to ask for an interface and test whether it | 188 if (nav_details.get()) { |
| 127 // succeeded? That would be nicer than hard-coding the URLs that are known | |
| 128 // to support navigation. | |
| 129 if (url == kEmbeddedAppURL || url == kNestingAppURL) { | |
| 130 // TODO(aa): This means that there can only ever be one instance of every | |
| 131 // app, which seems wrong. Instead, perhaps embedder should get back a | |
| 132 // service provider that allows it to talk to embeddee. | |
| 133 navigation::NavigatorPtr navigator; | 189 navigation::NavigatorPtr navigator; |
| 134 ConnectTo(url, &navigator); | 190 ConnectTo(url, &navigator); |
| 135 navigation::NavigationDetailsPtr details( | 191 navigator->Navigate(embedded->id(), nav_details.Pass()); |
| 136 navigation::NavigationDetails::New()); | |
| 137 size_t index = node->children().size() - 1; | |
| 138 details->url = base::StringPrintf( | |
| 139 "%s/%x", kEmbeddedAppURL, kColors[index % arraysize(kColors)]); | |
| 140 navigator->Navigate(embedded->id(), details.Pass()); | |
| 141 } | 192 } |
| 193 |
| 194 return embedded; |
| 142 } | 195 } |
| 143 | 196 |
| 197 launcher::LauncherPtr launcher_; |
| 198 Node* launcher_ui_; |
| 199 std::vector<Node*> windows_; |
| 144 ViewManager* view_manager_; | 200 ViewManager* view_manager_; |
| 145 Id parent_node_id_; | 201 Id parent_node_id_; |
| 146 | 202 |
| 147 DISALLOW_COPY_AND_ASSIGN(WindowManager); | 203 DISALLOW_COPY_AND_ASSIGN(WindowManager); |
| 148 }; | 204 }; |
| 149 | 205 |
| 150 void WindowManagerConnection::CloseWindow(Id node_id) { | 206 void WindowManagerConnection::CloseWindow(Id node_id) { |
| 151 window_manager_->CloseWindow(node_id); | 207 window_manager_->CloseWindow(node_id); |
| 152 } | 208 } |
| 153 | 209 |
| 210 void NavigatorHost::RequestNavigate( |
| 211 uint32 source_node_id, |
| 212 navigation::NavigationDetailsPtr nav_details) { |
| 213 window_manager_->RequestNavigate(source_node_id, nav_details.Pass()); |
| 214 } |
| 215 |
| 154 } // namespace examples | 216 } // namespace examples |
| 155 | 217 |
| 156 // static | 218 // static |
| 157 Application* Application::Create() { | 219 Application* Application::Create() { |
| 158 return new examples::WindowManager; | 220 return new examples::WindowManager; |
| 159 } | 221 } |
| 160 | 222 |
| 161 } // namespace mojo | 223 } // namespace mojo |
| OLD | NEW |