Commit 2457ca9a authored by ben@chromium.org's avatar ben@chromium.org

Provide an API to the example window manager app that supports closing a window.

Listen for clicks in the embedded app and close the corresponding view when clicked.

R=sky@chromium.org
http://crbug.com/365012

Review URL: https://codereview.chromium.org/311423003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275322 0039d316-1c4b-4281-b951-d872f2087c98
parent 3ef5ee22
include_rules = [
"+ui/events",
]
......@@ -4,15 +4,35 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "mojo/examples/window_manager/window_manager.mojom.h"
#include "mojo/public/cpp/application/application.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
#include "ui/events/event_constants.h"
using mojo::view_manager::View;
using mojo::view_manager::ViewManager;
using mojo::view_manager::ViewObserver;
using mojo::view_manager::ViewTreeNode;
using mojo::view_manager::ViewTreeNodeObserver;
namespace mojo {
namespace examples {
namespace {
const SkColor kColors[] = { SK_ColorYELLOW,
SK_ColorRED,
SK_ColorGREEN,
SK_ColorMAGENTA };
} // namespace
class EmbeddedApp : public Application {
class EmbeddedApp : public Application,
public ViewObserver,
public ViewTreeNodeObserver {
public:
EmbeddedApp() : view_manager_(NULL) {}
virtual ~EmbeddedApp() {}
......@@ -20,27 +40,52 @@ class EmbeddedApp : public Application {
private:
// Overridden from Application:
virtual void Initialize() MOJO_OVERRIDE {
view_manager::ViewManager::Create(this,
base::Bind(&EmbeddedApp::OnRootAdded, base::Unretained(this)));
ViewManager::Create(this,
base::Bind(&EmbeddedApp::OnRootAdded, base::Unretained(this)),
base::Bind(&EmbeddedApp::OnRootRemoved, base::Unretained(this)));
ConnectTo<IWindowManager>("mojo:mojo_window_manager", &window_manager_);
}
// Overridden from ViewObserver:
virtual void OnViewInputEvent(View* view, EventPtr event) OVERRIDE {
if (event->action == ui::ET_MOUSE_RELEASED)
window_manager_->CloseWindow(view->node()->id());
}
void OnRootAdded(view_manager::ViewManager* view_manager) {
// Overridden from ViewTreeNodeObserver:
virtual void OnNodeActiveViewChange(
ViewTreeNode* node,
View* old_view,
View* new_view,
ViewTreeNodeObserver::DispositionChangePhase phase) OVERRIDE {
if (new_view == 0)
views_to_reap_[node] = old_view;
}
void OnRootAdded(ViewManager* view_manager, ViewTreeNode* root) {
if (!view_manager_)
view_manager_ = view_manager;
DCHECK_EQ(view_manager_, view_manager);
if (view_manager_->roots().size() == 1) {
view_manager::View* view = view_manager::View::Create(view_manager_);
view_manager_->roots().front()->SetActiveView(view);
view->SetColor(SK_ColorYELLOW);
} else {
view_manager::View* view = view_manager::View::Create(view_manager_);
view_manager_->roots().back()->SetActiveView(view);
view->SetColor(SK_ColorRED);
}
View* view = View::Create(view_manager_);
view->AddObserver(this);
root->SetActiveView(view);
root->AddObserver(this);
size_t index = view_manager_->roots().size() - 1;
view->SetColor(kColors[index % arraysize(kColors)]);
}
void OnRootRemoved(ViewManager* view_manager,
ViewTreeNode* root) {
std::map<ViewTreeNode*, View*>::const_iterator it =
views_to_reap_.find(root);
if (it != views_to_reap_.end())
it->second->Destroy();
}
view_manager::ViewManager* view_manager_;
IWindowManagerPtr window_manager_;
ViewManager* view_manager_;
std::map<ViewTreeNode*, View*> views_to_reap_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedApp);
};
......
include_rules = [
"+ui/events",
]
......@@ -4,53 +4,105 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "mojo/examples/window_manager/window_manager.mojom.h"
#include "mojo/public/cpp/application/application.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
#include "ui/events/event_constants.h"
#if defined CreateWindow
#undef CreateWindow
#endif
namespace mojo {
namespace examples {
class WindowManager : public Application {
class WindowManager;
class WindowManagerConnection : public InterfaceImpl<IWindowManager> {
public:
explicit WindowManagerConnection(WindowManager* window_manager)
: window_manager_(window_manager) {}
virtual ~WindowManagerConnection() {}
private:
// Overridden from IWindowManager:
virtual void CloseWindow(view_manager::TransportNodeId node_id) OVERRIDE;
WindowManager* window_manager_;
DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection);
};
class WindowManager : public Application,
public view_manager::ViewObserver {
public:
WindowManager() {}
virtual ~WindowManager() {}
void CloseWindow(view_manager::TransportNodeId node_id) {
DCHECK(view_manager_);
view_manager::ViewTreeNode* node = view_manager_->GetNodeById(node_id);
DCHECK(node);
node->Destroy();
}
private:
// Overridden from Application:
virtual void Initialize() MOJO_OVERRIDE {
view_manager_ = view_manager::ViewManager::CreateBlocking(this,
base::Bind(&WindowManager::OnRootAdded, base::Unretained(this)));
AddService<WindowManagerConnection>(this);
view_manager_ = view_manager::ViewManager::CreateBlocking(this);
view_manager::ViewTreeNode* node =
view_manager::ViewTreeNode::Create(view_manager_);
view_manager_->roots().front()->AddChild(node);
node->SetBounds(gfx::Rect(800, 600));
parent_node_id_ = node->id();
view_manager::View* view = view_manager::View::Create(view_manager_);
node->SetActiveView(view);
view->SetColor(SK_ColorBLUE);
view->AddObserver(this);
}
// Overridden from ViewObserver:
virtual void OnViewInputEvent(view_manager::View* view,
EventPtr event) OVERRIDE {
if (event->action == ui::ET_MOUSE_RELEASED)
CreateWindow();
}
void CreateWindow() {
view_manager::ViewTreeNode* node =
view_manager_->GetNodeById(parent_node_id_);
gfx::Rect bounds(50, 50, 200, 200);
if (!node->children().empty()) {
gfx::Point position = node->children().back()->bounds().origin();
position.Offset(50, 50);
bounds.set_origin(position);
}
view_manager::ViewTreeNode* embedded =
view_manager::ViewTreeNode::Create(view_manager_);
node->AddChild(embedded);
embedded->SetBounds(gfx::Rect(50, 50, 200, 200));
embedded->SetBounds(bounds);
embedded->Embed("mojo:mojo_embedded_app");
view_manager::ViewTreeNode* embedded2 =
view_manager::ViewTreeNode::Create(view_manager_);
node->AddChild(embedded2);
embedded2->SetBounds(gfx::Rect(250, 250, 200, 200));
embedded2->Embed("mojo:mojo_embedded_app");
}
void OnRootAdded(view_manager::ViewManager* view_manager) {}
view_manager::ViewManager* view_manager_;
view_manager::TransportNodeId parent_node_id_;
DISALLOW_COPY_AND_ASSIGN(WindowManager);
};
void WindowManagerConnection::CloseWindow(
view_manager::TransportNodeId node_id) {
window_manager_->CloseWindow(node_id);
}
} // namespace examples
// static
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module mojo {
interface IWindowManager {
CloseWindow(uint32 node_id);
};
}
......@@ -311,6 +311,20 @@
'public/cpp/application/lib/mojo_main_chromium.cc',
],
},
{
'target_name': 'mojo_window_manager_bindings',
'type': 'static_library',
'sources': [
'examples/window_manager/window_manager.mojom',
],
'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
'export_dependent_settings': [
'mojo_cpp_bindings',
],
'dependencies': [
'mojo_cpp_bindings',
],
},
{
'target_name': 'mojo_window_manager',
'type': 'shared_library',
......@@ -324,6 +338,7 @@
'mojo_geometry_bindings',
'mojo_gles2',
'mojo_view_manager_lib',
'mojo_window_manager_bindings',
'mojo_system_impl',
'mojo_utility',
],
......@@ -345,6 +360,7 @@
'mojo_geometry_bindings',
'mojo_gles2',
'mojo_view_manager_lib',
'mojo_window_manager_bindings',
'mojo_system_impl',
'mojo_utility',
],
......
......@@ -16,7 +16,9 @@ namespace mojo {
namespace view_manager {
namespace {
void OnViewManagerReady(base::RunLoop* loop, ViewManager* manager) {
void OnViewManagerReady(base::RunLoop* loop,
ViewManager* manager,
ViewTreeNode* root) {
loop->Quit();
}
......@@ -43,13 +45,12 @@ ViewManager::~ViewManager() {
}
// static
ViewManager* ViewManager::CreateBlocking(
Application* application,
const base::Callback<void(ViewManager*)>& root_added_callback) {
ViewManager* ViewManager::CreateBlocking(Application* application) {
base::RunLoop init_loop;
ViewManager* manager = new ViewManager(
application,
base::Bind(&OnViewManagerReady, &init_loop));
base::Bind(&OnViewManagerReady, &init_loop),
RootCallback());
init_loop.Run();
return manager;
}
......@@ -57,8 +58,9 @@ ViewManager* ViewManager::CreateBlocking(
// static
void ViewManager::Create(
Application* application,
const base::Callback<void(ViewManager*)>& root_added_callback) {
new ViewManager(application, root_added_callback);
const RootCallback& root_added_callback,
const RootCallback& root_removed_callback) {
new ViewManager(application, root_added_callback, root_removed_callback);
}
ViewTreeNode* ViewManager::GetNodeById(TransportNodeId id) {
......@@ -76,8 +78,10 @@ View* ViewManager::GetViewById(TransportViewId id) {
ViewManager::ViewManager(
Application* application,
const base::Callback<void(ViewManager*)>& root_added_callback)
const RootCallback& root_added_callback,
const RootCallback& root_removed_callback)
: root_added_callback_(root_added_callback),
root_removed_callback_(root_removed_callback),
synchronizer_(NULL) {
application->AddService<ViewManagerSynchronizer>(this);
}
......
......@@ -50,14 +50,18 @@ void ViewManagerPrivate::AddRoot(ViewTreeNode* root) {
}
manager_->roots_.push_back(root);
root->AddObserver(new RootObserver(root));
manager_->root_added_callback_.Run(manager_);
if (!manager_->root_added_callback_.is_null())
manager_->root_added_callback_.Run(manager_, root);
}
void ViewManagerPrivate::RemoveRoot(ViewTreeNode* root) {
std::vector<ViewTreeNode*>::iterator it =
std::find(manager_->roots_.begin(), manager_->roots_.end(), root);
if (it != manager_->roots_.end())
if (it != manager_->roots_.end()) {
manager_->roots_.erase(it);
if (!manager_->root_removed_callback_.is_null())
manager_->root_removed_callback_.Run(manager_, root);
}
}
void ViewManagerPrivate::AddNode(TransportNodeId node_id, ViewTreeNode* node) {
......
......@@ -234,6 +234,7 @@ class DestroyViewTreeNodeTransaction : public ViewManagerTransaction {
private:
// Overridden from ViewManagerTransaction:
virtual void DoCommit() OVERRIDE {
GetAndAdvanceNextServerChangeId();
service()->DeleteNode(node_id_, ActionCompletedCallback());
}
virtual void DoActionCompleted(bool success) OVERRIDE {
......
......@@ -52,7 +52,7 @@ void WaitForAllChangesToBeAcked(ViewManager* manager) {
class ConnectServiceLoader : public ServiceLoader {
public:
explicit ConnectServiceLoader(base::Callback<void(ViewManager*)> callback)
explicit ConnectServiceLoader(const ViewManager::RootCallback& callback)
: callback_(callback) {}
virtual ~ConnectServiceLoader() {}
......@@ -62,7 +62,8 @@ class ConnectServiceLoader : public ServiceLoader {
const GURL& url,
ScopedMessagePipeHandle shell_handle) OVERRIDE {
scoped_ptr<Application> app(new Application(shell_handle.Pass()));
ViewManager::Create(app.get(), callback_);
// TODO(beng): test removed callback.
ViewManager::Create(app.get(), callback_, ViewManager::RootCallback());
apps_.push_back(app.release());
}
virtual void OnServiceError(ServiceManager* manager,
......@@ -70,7 +71,7 @@ class ConnectServiceLoader : public ServiceLoader {
}
ScopedVector<Application> apps_;
base::Callback<void(ViewManager*)> callback_;
ViewManager::RootCallback callback_;
DISALLOW_COPY_AND_ASSIGN(ConnectServiceLoader);
};
......@@ -327,7 +328,7 @@ class ViewManagerTest : public testing::Test {
private:
// Overridden from testing::Test:
virtual void SetUp() OVERRIDE {
base::Callback<void(ViewManager*)> ready_callback =
ViewManager::RootCallback ready_callback =
base::Bind(&ViewManagerTest::OnViewManagerLoaded,
base::Unretained(this));
test_helper_.Init();
......@@ -362,7 +363,7 @@ class ViewManagerTest : public testing::Test {
return result;
}
void OnViewManagerLoaded(ViewManager* view_manager) {
void OnViewManagerLoaded(ViewManager* view_manager, ViewTreeNode* root) {
loaded_view_manager_ = view_manager;
connect_loop_->Quit();
}
......
......@@ -28,17 +28,18 @@ class ViewTreeNode;
// TODO: displays
class ViewManager {
public:
typedef base::Callback<void(ViewManager*, ViewTreeNode*)> RootCallback;
~ViewManager();
// |ready_callback| is run when the ViewManager connection is established
// and ready to use.
static void Create(
Application* application,
const base::Callback<void(ViewManager*)>& root_added_callback);
const RootCallback& root_added_callback,
const RootCallback& root_removed_callback);
// Blocks until ViewManager is ready to use.
static ViewManager* CreateBlocking(
Application* application,
const base::Callback<void(ViewManager*)>& root_added_callback);
static ViewManager* CreateBlocking(Application* application);
const std::vector<ViewTreeNode*>& roots() { return roots_; }
......@@ -51,9 +52,11 @@ class ViewManager {
typedef std::map<TransportViewId, View*> IdToViewMap;
ViewManager(Application* application,
const base::Callback<void(ViewManager*)>& root_added_callback);
const RootCallback& root_added_callback,
const RootCallback& root_removed_callback);
base::Callback<void(ViewManager*)> root_added_callback_;
RootCallback root_added_callback_;
RootCallback root_removed_callback_;
ViewManagerSynchronizer* synchronizer_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment