Index: examples/window_manager/window_manager.cc |
diff --git a/examples/window_manager/window_manager.cc b/examples/window_manager/window_manager.cc |
deleted file mode 100644 |
index 1fbd4914ad967beceda12d436ee94ab94b0e4532..0000000000000000000000000000000000000000 |
--- a/examples/window_manager/window_manager.cc |
+++ /dev/null |
@@ -1,560 +0,0 @@ |
-// 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. |
- |
-#include "base/bind.h" |
-#include "base/macros.h" |
-#include "examples/window_manager/debug_panel_host.mojom.h" |
-#include "examples/window_manager/window_manager.mojom.h" |
-#include "mojo/application/application_runner_chromium.h" |
-#include "mojo/common/binding_set.h" |
-#include "mojo/converters/geometry/geometry_type_converters.h" |
-#include "mojo/converters/input_events/input_events_type_converters.h" |
-#include "mojo/public/c/system/main.h" |
-#include "mojo/public/cpp/application/application_connection.h" |
-#include "mojo/public/cpp/application/application_delegate.h" |
-#include "mojo/public/cpp/application/application_impl.h" |
-#include "mojo/public/cpp/application/service_provider_impl.h" |
-#include "mojo/public/cpp/bindings/strong_binding.h" |
-#include "mojo/services/input_events/interfaces/input_events.mojom.h" |
-#include "mojo/services/navigation/interfaces/navigation.mojom.h" |
-#include "mojo/services/view_manager/cpp/view.h" |
-#include "mojo/services/view_manager/cpp/view_manager.h" |
-#include "mojo/services/view_manager/cpp/view_manager_delegate.h" |
-#include "mojo/services/view_manager/cpp/view_observer.h" |
-#include "services/window_manager/basic_focus_rules.h" |
-#include "services/window_manager/view_target.h" |
-#include "services/window_manager/window_manager_app.h" |
-#include "services/window_manager/window_manager_delegate.h" |
-#include "services/window_manager/window_manager_root.h" |
-#include "ui/events/event.h" |
-#include "ui/events/event_constants.h" |
-#include "url/gurl.h" |
- |
-#if defined CreateWindow |
-#undef CreateWindow |
-#endif |
- |
-namespace mojo { |
-namespace examples { |
- |
-class WindowManagerController; |
- |
-namespace { |
- |
-const int kBorderInset = 25; |
-const int kControlPanelWidth = 200; |
-const int kTextfieldHeight = 39; |
- |
-} // namespace |
- |
-class WindowManagerConnection : public ::examples::IWindowManager { |
- public: |
- WindowManagerConnection(WindowManagerController* window_manager, |
- InterfaceRequest<::examples::IWindowManager> request) |
- : window_manager_(window_manager), binding_(this, request.Pass()) {} |
- ~WindowManagerConnection() override {} |
- |
- private: |
- // Overridden from ::examples::IWindowManager: |
- void CloseWindow(Id view_id) override; |
- |
- WindowManagerController* window_manager_; |
- StrongBinding<::examples::IWindowManager> binding_; |
- |
- DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); |
-}; |
- |
-class NavigatorHostImpl : public NavigatorHost { |
- public: |
- NavigatorHostImpl(WindowManagerController* window_manager, Id view_id) |
- : window_manager_(window_manager), |
- view_id_(view_id), |
- current_index_(-1) {} |
- ~NavigatorHostImpl() override {} |
- |
- void Bind(InterfaceRequest<NavigatorHost> request) { |
- bindings_.AddBinding(this, request.Pass()); |
- } |
- |
- void RecordNavigation(const std::string& url); |
- |
- private: |
- void DidNavigateLocally(const mojo::String& url) override; |
- void RequestNavigate(Target target, URLRequestPtr request) override; |
- void RequestNavigateHistory(int32_t delta) override; |
- |
- WindowManagerController* window_manager_; |
- Id view_id_; |
- std::vector<std::string> history_; |
- int32_t current_index_; |
- |
- BindingSet<NavigatorHost> bindings_; |
- |
- DISALLOW_COPY_AND_ASSIGN(NavigatorHostImpl); |
-}; |
- |
-class RootLayoutManager : public ViewObserver { |
- public: |
- RootLayoutManager(ViewManager* view_manager, |
- View* root, |
- Id content_view_id, |
- Id launcher_ui_view_id, |
- Id control_panel_view_id) |
- : root_(root), |
- view_manager_(view_manager), |
- content_view_id_(content_view_id), |
- launcher_ui_view_id_(launcher_ui_view_id), |
- control_panel_view_id_(control_panel_view_id) {} |
- ~RootLayoutManager() override { |
- if (root_) |
- root_->RemoveObserver(this); |
- } |
- |
- private: |
- // Overridden from ViewObserver: |
- void OnViewBoundsChanged(View* view, |
- const Rect& old_bounds, |
- const Rect& new_bounds) override { |
- DCHECK_EQ(view, root_); |
- |
- View* content_view = view_manager_->GetViewById(content_view_id_); |
- content_view->SetBounds(new_bounds); |
- |
- int delta_width = new_bounds.width - old_bounds.width; |
- int delta_height = new_bounds.height - old_bounds.height; |
- |
- View* launcher_ui_view = view_manager_->GetViewById(launcher_ui_view_id_); |
- Rect launcher_ui_bounds(launcher_ui_view->bounds()); |
- launcher_ui_bounds.width += delta_width; |
- launcher_ui_view->SetBounds(launcher_ui_bounds); |
- |
- View* control_panel_view = |
- view_manager_->GetViewById(control_panel_view_id_); |
- Rect control_panel_bounds(control_panel_view->bounds()); |
- control_panel_bounds.x += delta_width; |
- control_panel_view->SetBounds(control_panel_bounds); |
- |
- const View::Children& content_views = content_view->children(); |
- View::Children::const_iterator iter = content_views.begin(); |
- for (; iter != content_views.end(); ++iter) { |
- View* view = *iter; |
- if (view->id() == control_panel_view->id() || |
- view->id() == launcher_ui_view->id()) |
- continue; |
- Rect view_bounds(view->bounds()); |
- view_bounds.width += delta_width; |
- view_bounds.height += delta_height; |
- view->SetBounds(view_bounds); |
- } |
- } |
- void OnViewDestroyed(View* view) override { |
- DCHECK_EQ(view, root_); |
- root_->RemoveObserver(this); |
- root_ = NULL; |
- } |
- |
- View* root_; |
- ViewManager* view_manager_; |
- const Id content_view_id_; |
- const Id launcher_ui_view_id_; |
- const Id control_panel_view_id_; |
- |
- DISALLOW_COPY_AND_ASSIGN(RootLayoutManager); |
-}; |
- |
-class Window : public InterfaceFactory<NavigatorHost> { |
- public: |
- Window(WindowManagerController* window_manager, View* view) |
- : window_manager_(window_manager), |
- view_(view), |
- navigator_host_(window_manager_, view_->id()) { |
- exposed_services_impl_.AddService<NavigatorHost>(this); |
- } |
- |
- ~Window() override {} |
- |
- View* view() const { return view_; } |
- |
- NavigatorHost* navigator_host() { return &navigator_host_; } |
- |
- void Embed(const std::string& url) { |
- // TODO: Support embedding multiple times? |
- ServiceProviderPtr exposed_services; |
- exposed_services_impl_.Bind(GetProxy(&exposed_services)); |
- view_->Embed(url, nullptr, exposed_services.Pass()); |
- navigator_host_.RecordNavigation(url); |
- } |
- |
- private: |
- // InterfaceFactory<NavigatorHost> |
- void Create(ApplicationConnection* connection, |
- InterfaceRequest<NavigatorHost> request) override { |
- navigator_host_.Bind(request.Pass()); |
- } |
- |
- WindowManagerController* window_manager_; |
- View* view_; |
- ServiceProviderImpl exposed_services_impl_; |
- NavigatorHostImpl navigator_host_; |
-}; |
- |
-class WindowManagerController |
- : public examples::DebugPanelHost, |
- public window_manager::WindowManagerController, |
- public ui::EventHandler, |
- public ui::AcceleratorTarget, |
- public mojo::InterfaceFactory<examples::DebugPanelHost>, |
- public InterfaceFactory<::examples::IWindowManager> { |
- public: |
- WindowManagerController(Shell* shell, |
- ApplicationImpl* app, |
- ApplicationConnection* connection, |
- window_manager::WindowManagerRoot* wm_root) |
- : shell_(shell), |
- launcher_ui_(NULL), |
- view_manager_(NULL), |
- window_manager_root_(wm_root), |
- navigation_target_(Target::DEFAULT), |
- app_(app), |
- binding_(this) { |
- connection->AddService<::examples::IWindowManager>(this); |
- } |
- |
- ~WindowManagerController() override { |
- // host() may be destroyed by the time we get here. |
- // TODO: figure out a way to always cleanly remove handler. |
- |
- // TODO(erg): In the aura version, we removed ourselves from the |
- // PreTargetHandler list here. We may need to do something analogous when |
- // we get event handling without aura working. |
- } |
- |
- void CloseWindow(Id view_id) { |
- WindowVector::iterator iter = GetWindowByViewId(view_id); |
- DCHECK(iter != windows_.end()); |
- Window* window = *iter; |
- windows_.erase(iter); |
- window->view()->Destroy(); |
- } |
- |
- void DidNavigateLocally(uint32 source_view_id, const mojo::String& url) { |
- LOG(ERROR) << "DidNavigateLocally: source_view_id: " << source_view_id |
- << " url: " << url.To<std::string>(); |
- } |
- |
- void RequestNavigate(uint32 source_view_id, |
- Target target, |
- const mojo::String& url) { |
- OnLaunch(source_view_id, target, url); |
- } |
- |
- // Overridden from mojo::DebugPanelHost: |
- void CloseTopWindow() override { |
- if (!windows_.empty()) |
- CloseWindow(windows_.back()->view()->id()); |
- } |
- |
- void NavigateTo(const String& url) override { |
- OnLaunch(control_panel_id_, Target::NEW_NODE, url); |
- } |
- |
- void SetNavigationTarget(Target t) override { navigation_target_ = t; } |
- |
- // mojo::InterfaceFactory<examples::DebugPanelHost> implementation. |
- void Create( |
- mojo::ApplicationConnection* connection, |
- mojo::InterfaceRequest<examples::DebugPanelHost> request) override { |
- binding_.Bind(request.Pass()); |
- } |
- |
- // mojo::InterfaceFactory<::examples::IWindowManager> implementation. |
- void Create( |
- mojo::ApplicationConnection* connection, |
- mojo::InterfaceRequest<::examples::IWindowManager> request) override { |
- new WindowManagerConnection(this, request.Pass()); |
- } |
- |
- private: |
- typedef std::vector<Window*> WindowVector; |
- |
- // Overridden from ViewManagerDelegate: |
- void OnEmbed(View* root, |
- InterfaceRequest<ServiceProvider> services, |
- ServiceProviderPtr exposed_services) override { |
- DCHECK(!view_manager_); |
- view_manager_ = root->view_manager(); |
- |
- View* view = view_manager_->CreateView(); |
- root->AddChild(view); |
- Rect rect; |
- rect.width = root->bounds().width; |
- rect.height = root->bounds().height; |
- view->SetBounds(rect); |
- view->SetVisible(true); |
- content_view_id_ = view->id(); |
- |
- Id launcher_ui_id = CreateLauncherUI(); |
- control_panel_id_ = CreateControlPanel(view); |
- |
- root_layout_manager_.reset( |
- new RootLayoutManager(view_manager_, root, content_view_id_, |
- launcher_ui_id, control_panel_id_)); |
- root->AddObserver(root_layout_manager_.get()); |
- |
- // TODO(erg): In the aura version, we explicitly added ourselves as a |
- // PreTargetHandler to the window() here. We probably have to do something |
- // analogous here. |
- |
- window_manager_root_->InitFocus( |
- make_scoped_ptr(new window_manager::BasicFocusRules(root))); |
- window_manager_root_->accelerator_manager()->Register( |
- ui::Accelerator(ui::VKEY_BROWSER_BACK, 0), |
- ui::AcceleratorManager::kNormalPriority, this); |
- } |
- void OnViewManagerDisconnected(ViewManager* view_manager) override { |
- DCHECK_EQ(view_manager_, view_manager); |
- view_manager_ = NULL; |
- base::MessageLoop::current()->Quit(); |
- } |
- |
- // Overridden from WindowManagerDelegate: |
- void Embed(const String& url, |
- InterfaceRequest<ServiceProvider> services, |
- ServiceProviderPtr exposed_services) override { |
- const Id kInvalidSourceViewId = 0; |
- OnLaunch(kInvalidSourceViewId, Target::DEFAULT, url); |
- } |
- |
- // Overridden from ui::EventHandler: |
- void OnEvent(ui::Event* event) override { |
- View* view = |
- static_cast<window_manager::ViewTarget*>(event->target())->view(); |
- if (event->type() == ui::ET_MOUSE_PRESSED) |
- view->SetFocus(); |
- } |
- |
- // Overriden from ui::AcceleratorTarget: |
- bool AcceleratorPressed(const ui::Accelerator& accelerator, |
- mojo::View* view) override { |
- if (accelerator.key_code() != ui::VKEY_BROWSER_BACK) |
- return false; |
- |
- WindowVector::iterator iter = GetWindowByViewId(view->id()); |
- DCHECK(iter != windows_.end()); |
- Window* window = *iter; |
- window->navigator_host()->RequestNavigateHistory(-1); |
- return true; |
- } |
- |
- // Overriden from ui::AcceleratorTarget: |
- bool CanHandleAccelerators() const override { return true; } |
- |
- void OnLaunch(uint32 source_view_id, |
- Target requested_target, |
- const mojo::String& url) { |
- Target target = navigation_target_; |
- if (target == Target::DEFAULT) { |
- if (requested_target != Target::DEFAULT) { |
- target = requested_target; |
- } else { |
- // TODO(aa): Should be Target::NEW_NODE if source origin and dest origin |
- // are different? |
- target = Target::SOURCE_NODE; |
- } |
- } |
- |
- Window* dest_view = NULL; |
- if (target == Target::SOURCE_NODE) { |
- WindowVector::iterator source_view = GetWindowByViewId(source_view_id); |
- bool app_initiated = source_view != windows_.end(); |
- if (app_initiated) |
- dest_view = *source_view; |
- else if (!windows_.empty()) |
- dest_view = windows_.back(); |
- } |
- |
- if (!dest_view) { |
- dest_view = CreateWindow(); |
- windows_.push_back(dest_view); |
- } |
- |
- dest_view->Embed(url); |
- } |
- |
- // TODO(beng): proper layout manager!! |
- Id CreateLauncherUI() { |
- View* view = view_manager_->GetViewById(content_view_id_); |
- Rect bounds = view->bounds(); |
- bounds.x += kBorderInset; |
- bounds.y += kBorderInset; |
- bounds.width -= 2 * kBorderInset; |
- bounds.height = kTextfieldHeight; |
- launcher_ui_ = CreateWindow(bounds); |
- launcher_ui_->Embed("mojo:browser"); |
- return launcher_ui_->view()->id(); |
- } |
- |
- Window* CreateWindow() { |
- View* view = view_manager_->GetViewById(content_view_id_); |
- Rect bounds; |
- bounds.x = kBorderInset; |
- bounds.y = 2 * kBorderInset + kTextfieldHeight; |
- bounds.width = view->bounds().width - 3 * kBorderInset - kControlPanelWidth; |
- bounds.height = |
- view->bounds().height - (3 * kBorderInset + kTextfieldHeight); |
- if (!windows_.empty()) { |
- bounds.x = windows_.back()->view()->bounds().x + 35; |
- bounds.y = windows_.back()->view()->bounds().y + 35; |
- } |
- return CreateWindow(bounds); |
- } |
- |
- Window* CreateWindow(const Rect& bounds) { |
- View* content = view_manager_->GetViewById(content_view_id_); |
- View* view = view_manager_->CreateView(); |
- content->AddChild(view); |
- view->SetBounds(bounds); |
- view->SetVisible(true); |
- view->SetFocus(); |
- return new Window(this, view); |
- } |
- |
- Id CreateControlPanel(View* root) { |
- View* view = view_manager_->CreateView(); |
- root->AddChild(view); |
- |
- Rect bounds; |
- bounds.x = root->bounds().width - kControlPanelWidth - kBorderInset; |
- bounds.y = kBorderInset * 2 + kTextfieldHeight; |
- bounds.width = kControlPanelWidth; |
- bounds.height = root->bounds().height - kBorderInset * 3 - kTextfieldHeight; |
- view->SetBounds(bounds); |
- view->SetVisible(true); |
- |
- ServiceProviderPtr exposed_services; |
- control_panel_exposed_services_impl_.Bind(GetProxy(&exposed_services)); |
- control_panel_exposed_services_impl_.AddService<::examples::IWindowManager>( |
- this); |
- |
- GURL frame_url = url_.Resolve("/examples/window_manager/debug_panel.sky"); |
- view->Embed(frame_url.spec(), nullptr, exposed_services.Pass()); |
- |
- return view->id(); |
- } |
- |
- WindowVector::iterator GetWindowByViewId(Id view_id) { |
- for (std::vector<Window*>::iterator iter = windows_.begin(); |
- iter != windows_.end(); ++iter) { |
- if ((*iter)->view()->id() == view_id) { |
- return iter; |
- } |
- } |
- return windows_.end(); |
- } |
- |
- Shell* shell_; |
- |
- Window* launcher_ui_; |
- WindowVector windows_; |
- ViewManager* view_manager_; |
- scoped_ptr<RootLayoutManager> root_layout_manager_; |
- ServiceProviderImpl control_panel_exposed_services_impl_; |
- |
- window_manager::WindowManagerRoot* window_manager_root_; |
- |
- // Id of the view most content is added to. |
- Id content_view_id_; |
- |
- // Id of the debug panel. |
- Id control_panel_id_; |
- |
- GURL url_; |
- Target navigation_target_; |
- |
- ApplicationImpl* app_; |
- |
- mojo::Binding<examples::DebugPanelHost> binding_; |
- |
- DISALLOW_COPY_AND_ASSIGN(WindowManagerController); |
-}; |
- |
-class WindowManager : public ApplicationDelegate, |
- public window_manager::WindowManagerControllerFactory { |
- public: |
- WindowManager() |
- : window_manager_app_(new window_manager::WindowManagerApp(this)) {} |
- |
- scoped_ptr<window_manager::WindowManagerController> |
- CreateWindowManagerController( |
- ApplicationConnection* connection, |
- window_manager::WindowManagerRoot* wm_root) override { |
- return scoped_ptr<WindowManagerController>( |
- new WindowManagerController(shell_, app_, connection, wm_root)); |
- } |
- |
- private: |
- // Overridden from ApplicationDelegate: |
- void Initialize(ApplicationImpl* app) override { |
- window_manager_app_.reset(new window_manager::WindowManagerApp(this)); |
- shell_ = app->shell(); |
- app_ = app; |
- // FIXME: Mojo applications don't know their URLs yet: |
- // https://docs.google.com/a/chromium.org/document/d/1AQ2y6ekzvbdaMF5WrUQmneyXJnke-MnYYL4Gz1AKDos |
- url_ = GURL(app->args()[1]); |
- window_manager_app_->Initialize(app); |
- } |
- |
- bool ConfigureIncomingConnection(ApplicationConnection* connection) override { |
- window_manager_app_->ConfigureIncomingConnection(connection); |
- return true; |
- } |
- |
- ApplicationImpl* app_; |
- Shell* shell_; |
- GURL url_; |
- |
- scoped_ptr<window_manager::WindowManagerApp> window_manager_app_; |
- DISALLOW_COPY_AND_ASSIGN(WindowManager); |
-}; |
- |
-void WindowManagerConnection::CloseWindow(Id view_id) { |
- window_manager_->CloseWindow(view_id); |
-} |
- |
-void NavigatorHostImpl::DidNavigateLocally(const mojo::String& url) { |
- window_manager_->DidNavigateLocally(view_id_, url); |
- RecordNavigation(url); |
-} |
- |
-void NavigatorHostImpl::RequestNavigate(Target target, URLRequestPtr request) { |
- window_manager_->RequestNavigate(view_id_, target, request->url); |
-} |
- |
-void NavigatorHostImpl::RequestNavigateHistory(int32_t delta) { |
- if (history_.empty()) |
- return; |
- current_index_ = |
- std::max(0, std::min(current_index_ + delta, |
- static_cast<int32_t>(history_.size()) - 1)); |
- window_manager_->RequestNavigate(view_id_, Target::SOURCE_NODE, |
- history_[current_index_]); |
-} |
- |
-void NavigatorHostImpl::RecordNavigation(const std::string& url) { |
- if (current_index_ >= 0 && history_[current_index_] == url) { |
- // This is a navigation to the current entry, ignore. |
- return; |
- } |
- history_.erase(history_.begin() + (current_index_ + 1), history_.end()); |
- history_.push_back(url); |
- ++current_index_; |
-} |
- |
-} // namespace examples |
-} // namespace mojo |
- |
-MojoResult MojoMain(MojoHandle application_request) { |
- mojo::ApplicationRunnerChromium runner(new mojo::examples::WindowManager); |
- return runner.Run(application_request); |
-} |