Home | History | Annotate | Download | only in nesting_app
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/basictypes.h"
      6 #include "base/bind.h"
      7 #include "base/strings/stringprintf.h"
      8 #include "mojo/examples/window_manager/window_manager.mojom.h"
      9 #include "mojo/public/cpp/application/application.h"
     10 #include "mojo/services/public/cpp/view_manager/node.h"
     11 #include "mojo/services/public/cpp/view_manager/node_observer.h"
     12 #include "mojo/services/public/cpp/view_manager/view.h"
     13 #include "mojo/services/public/cpp/view_manager/view_manager.h"
     14 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
     15 #include "mojo/services/public/cpp/view_manager/view_observer.h"
     16 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
     17 #include "ui/events/event_constants.h"
     18 #include "url/gurl.h"
     19 
     20 using mojo::view_manager::Node;
     21 using mojo::view_manager::NodeObserver;
     22 using mojo::view_manager::View;
     23 using mojo::view_manager::ViewManager;
     24 using mojo::view_manager::ViewManagerDelegate;
     25 using mojo::view_manager::ViewObserver;
     26 
     27 namespace mojo {
     28 namespace examples {
     29 
     30 namespace {
     31 const char kEmbeddedAppURL[] = "mojo:mojo_embedded_app";
     32 }
     33 
     34 // An app that embeds another app.
     35 class NestingApp : public Application,
     36                    public ViewManagerDelegate,
     37                    public ViewObserver,
     38                    public NodeObserver {
     39  public:
     40   NestingApp() : nested_(NULL) {}
     41   virtual ~NestingApp() {}
     42 
     43  private:
     44   class Navigator : public InterfaceImpl<navigation::Navigator> {
     45    public:
     46     explicit Navigator(NestingApp* app) : app_(app) {}
     47    private:
     48     virtual void Navigate(
     49         uint32 node_id,
     50         navigation::NavigationDetailsPtr navigation_details,
     51         navigation::ResponseDetailsPtr response_details) OVERRIDE {
     52       GURL url(navigation_details->url.To<std::string>());
     53       if (!url.is_valid()) {
     54         LOG(ERROR) << "URL is invalid.";
     55         return;
     56       }
     57       app_->color_ = url.path().substr(1);
     58       app_->NavigateChild();
     59     }
     60     NestingApp* app_;
     61     DISALLOW_COPY_AND_ASSIGN(Navigator);
     62   };
     63 
     64   // Overridden from Application:
     65   virtual void Initialize() MOJO_OVERRIDE {
     66     ViewManager::Create(this, this);
     67     ConnectTo<IWindowManager>("mojo:mojo_window_manager", &window_manager_);
     68     AddService<Navigator>(this);
     69   }
     70 
     71   // Overridden from ViewManagerDelegate:
     72   virtual void OnRootAdded(ViewManager* view_manager, Node* root) OVERRIDE {
     73     root->AddObserver(this);
     74 
     75     View* view = View::Create(view_manager);
     76     root->SetActiveView(view);
     77     view->SetColor(SK_ColorCYAN);
     78     view->AddObserver(this);
     79 
     80     nested_ = Node::Create(view_manager);
     81     root->AddChild(nested_);
     82     nested_->SetBounds(gfx::Rect(20, 20, 50, 50));
     83     nested_->Embed(kEmbeddedAppURL);
     84 
     85     if (!navigator_.get())
     86       ConnectTo(kEmbeddedAppURL, &navigator_);
     87 
     88     NavigateChild();
     89   }
     90 
     91   // Overridden from ViewObserver:
     92   virtual void OnViewInputEvent(View* view, const EventPtr& event) OVERRIDE {
     93     if (event->action == ui::ET_MOUSE_RELEASED)
     94       window_manager_->CloseWindow(view->node()->id());
     95   }
     96 
     97   // Overridden from NodeObserver:
     98   virtual void OnNodeDestroy(
     99       Node* node,
    100       NodeObserver::DispositionChangePhase phase) OVERRIDE {
    101     if (phase != NodeObserver::DISPOSITION_CHANGED)
    102       return;
    103     // TODO(beng): reap views & child nodes.
    104     nested_ = NULL;
    105   }
    106 
    107   void NavigateChild() {
    108     if (!color_.empty() && nested_) {
    109       navigation::NavigationDetailsPtr details(
    110           navigation::NavigationDetails::New());
    111       details->url =
    112           base::StringPrintf("%s/%s", kEmbeddedAppURL, color_.c_str());
    113       navigation::ResponseDetailsPtr response_details(
    114           navigation::ResponseDetails::New());
    115       navigator_->Navigate(nested_->id(),
    116                            details.Pass(),
    117                            response_details.Pass());
    118     }
    119   }
    120 
    121   std::string color_;
    122   Node* nested_;
    123   navigation::NavigatorPtr navigator_;
    124   IWindowManagerPtr window_manager_;
    125 
    126   DISALLOW_COPY_AND_ASSIGN(NestingApp);
    127 };
    128 
    129 }  // namespace examples
    130 
    131 // static
    132 Application* Application::Create() {
    133   return new examples::NestingApp;
    134 }
    135 
    136 }  // namespace mojo
    137