Index: mojo/examples/window_manager/window_manager.cc |
diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc |
index 1b03688150ebed7951cf974a4ebe7faf772c1697..d533d5033c9fbd6ffdc3d87804090d68f2b524e8 100644 |
--- a/mojo/examples/window_manager/window_manager.cc |
+++ b/mojo/examples/window_manager/window_manager.cc |
@@ -13,6 +13,7 @@ |
#include "mojo/services/public/cpp/view_manager/view_manager.h" |
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" |
#include "mojo/services/public/cpp/view_manager/view_observer.h" |
+#include "mojo/services/public/interfaces/launcher/launcher.mojom.h" |
#include "ui/events/event_constants.h" |
#if defined CreateWindow |
@@ -39,10 +40,6 @@ const SkColor kColors[] = { SK_ColorYELLOW, |
SK_ColorGREEN, |
SK_ColorMAGENTA }; |
-const char kEmbeddedAppURL[] = "mojo:mojo_embedded_app"; |
-const char kNestingAppURL[] = "mojo:mojo_nesting_app"; |
-const char kMojoBrowserURL[] = "mojo:mojo_browser"; |
- |
} // namespace |
class WindowManagerConnection : public InterfaceImpl<IWindowManager> { |
@@ -60,33 +57,75 @@ class WindowManagerConnection : public InterfaceImpl<IWindowManager> { |
DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); |
}; |
+class NavigatorHost : public InterfaceImpl<navigation::NavigatorHost> { |
+ public: |
+ explicit NavigatorHost(WindowManager* window_manager) |
+ : window_manager_(window_manager) { |
+ } |
+ virtual ~NavigatorHost() { |
+ } |
+ private: |
+ virtual void RequestNavigate( |
+ uint32 source_node_id, |
+ navigation::NavigationDetailsPtr nav_details) OVERRIDE; |
+ WindowManager* window_manager_; |
+ DISALLOW_COPY_AND_ASSIGN(NavigatorHost); |
+}; |
+ |
class WindowManager : public Application, |
public ViewObserver, |
- public ViewManagerDelegate { |
+ public ViewManagerDelegate, |
+ public InterfaceImpl<launcher::LauncherClient> { |
public: |
- WindowManager() : view_manager_(NULL) {} |
+ WindowManager() : launcher_ui_(NULL), view_manager_(NULL) {} |
virtual ~WindowManager() {} |
void CloseWindow(Id node_id) { |
Node* node = view_manager_->GetNodeById(node_id); |
DCHECK(node); |
+ std::vector<Node*>::iterator iter = |
+ std::find(windows_.begin(), windows_.end(), node); |
+ DCHECK(iter != windows_.end()); |
+ windows_.erase(iter); |
node->Destroy(); |
} |
+ void RequestNavigate( |
+ uint32 source_node_id, |
+ navigation::NavigationDetailsPtr nav_details) { |
+ if (!launcher_.get()) { |
+ ConnectTo("mojo:mojo_launcher", &launcher_); |
+ launcher_.set_client(this); |
+ } |
+ launcher_->Launch(nav_details->url); |
+ } |
+ |
private: |
// Overridden from Application: |
virtual void Initialize() MOJO_OVERRIDE { |
AddService<WindowManagerConnection>(this); |
+ AddService<NavigatorHost>(this); |
ViewManager::Create(this, this); |
} |
// Overridden from ViewObserver: |
virtual void OnViewInputEvent(View* view, const EventPtr& event) OVERRIDE { |
if (event->action == ui::ET_MOUSE_RELEASED) { |
+ std::string app_url; |
if (event->flags & ui::EF_LEFT_MOUSE_BUTTON) |
- CreateWindow(kEmbeddedAppURL); |
+ app_url = "mojo:mojo_embedded_app"; |
else if (event->flags & ui::EF_RIGHT_MOUSE_BUTTON) |
- CreateWindow(kNestingAppURL); |
+ app_url = "mojo:mojo_nesting_app"; |
+ DCHECK(!app_url.empty()); |
+ |
+ Node* node = view_manager_->GetNodeById(parent_node_id_); |
+ navigation::NavigationDetailsPtr nav_details( |
+ navigation::NavigationDetails::New()); |
+ size_t index = node->children().size() - 1; |
+ nav_details->url = base::StringPrintf( |
+ "%s/%x", app_url.c_str(), kColors[index % arraysize(kColors)]); |
+ navigation::ResponseDetailsPtr response; |
+ CreateWindow(app_url, nav_details.Pass(), response.Pass()); |
} |
} |
@@ -105,49 +144,65 @@ class WindowManager : public Application, |
view->SetColor(SK_ColorBLUE); |
view->AddObserver(this); |
- CreateWindow(kMojoBrowserURL); |
+ CreateLauncherUI(); |
} |
- void CreateWindow(const std::string& url) { |
- Node* node = view_manager_->GetNodeById(parent_node_id_); |
+ // Overridden from LauncherClient: |
+ virtual void OnLaunch( |
+ const mojo::String& handler_url, mojo::URLResponsePtr response, |
+ mojo::ScopedDataPipeConsumerHandle response_body_stream) OVERRIDE { |
+ navigation::NavigationDetailsPtr nav_details( |
+ navigation::NavigationDetails::New()); |
+ nav_details->url = response->url; |
+ navigation::ResponseDetailsPtr response_details( |
+ navigation::ResponseDetails::New()); |
+ response_details->response = response.Pass(); |
+ response_details->response_body_stream = response_body_stream.Pass(); |
+ CreateWindow(handler_url, nav_details.Pass(), response_details.Pass()); |
+ } |
- gfx::Rect bounds(node->bounds().size()); |
- bounds.Inset(25, 25); |
- if (!node->children().empty()) { |
- gfx::Point position = node->children().back()->bounds().origin(); |
- position.Offset(25, 25); |
+ void CreateLauncherUI() { |
+ navigation::NavigationDetailsPtr nav_details; |
+ navigation::ResponseDetailsPtr response; |
+ launcher_ui_ = CreateChild("mojo:mojo_browser", gfx::Rect(25, 25, 400, 25), |
+ nav_details.Pass(), response.Pass()); |
+ } |
+ |
+ void CreateWindow(const std::string& handler_url, |
+ navigation::NavigationDetailsPtr nav_details, |
+ navigation::ResponseDetailsPtr response) { |
+ gfx::Rect bounds(25, 75, 400, 400); |
+ if (!windows_.empty()) { |
+ gfx::Point position = windows_.back()->bounds().origin(); |
+ position.Offset(35, 35); |
bounds.set_origin(position); |
} |
+ windows_.push_back(CreateChild(handler_url, bounds, nav_details.Pass(), |
+ response.Pass())); |
+ } |
+ Node* CreateChild(const std::string& url, |
+ const gfx::Rect& bounds, |
+ navigation::NavigationDetailsPtr nav_details, |
+ navigation::ResponseDetailsPtr response) { |
+ Node* node = view_manager_->GetNodeById(parent_node_id_); |
Node* embedded = Node::Create(view_manager_); |
node->AddChild(embedded); |
embedded->SetBounds(bounds); |
embedded->Embed(url); |
- // TODO(aa): Is there a way to ask for an interface and test whether it |
- // succeeded? That would be nicer than hard-coding the URLs that are known |
- // to support navigation. |
- if (url == kEmbeddedAppURL || url == kNestingAppURL) { |
- // TODO(aa): This means that there can only ever be one instance of every |
- // app, which seems wrong. Instead, perhaps embedder should get back a |
- // service provider that allows it to talk to embeddee. |
+ if (nav_details.get()) { |
navigation::NavigatorPtr navigator; |
ConnectTo(url, &navigator); |
- navigation::NavigationDetailsPtr details( |
- navigation::NavigationDetails::New()); |
- size_t index = node->children().size() - 1; |
- details->url = base::StringPrintf( |
- "%s/%x", kEmbeddedAppURL, kColors[index % arraysize(kColors)]); |
- |
- // TODO(beng): remove once nullable parameters land. |
- navigation::ResponseDetailsPtr response_details( |
- navigation::ResponseDetails::New()); |
- navigator->Navigate(embedded->id(), |
- details.Pass(), |
- response_details.Pass()); |
+ navigator->Navigate(embedded->id(), nav_details.Pass(), response.Pass()); |
} |
+ |
+ return embedded; |
} |
+ launcher::LauncherPtr launcher_; |
+ Node* launcher_ui_; |
+ std::vector<Node*> windows_; |
ViewManager* view_manager_; |
Id parent_node_id_; |
@@ -158,6 +213,12 @@ void WindowManagerConnection::CloseWindow(Id node_id) { |
window_manager_->CloseWindow(node_id); |
} |
+void NavigatorHost::RequestNavigate( |
+ uint32 source_node_id, |
+ navigation::NavigationDetailsPtr nav_details) { |
+ window_manager_->RequestNavigate(source_node_id, nav_details.Pass()); |
+} |
+ |
} // namespace examples |
// static |