diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-25 19:28:31 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-25 19:28:31 +0000 |
commit | 1dfdc0b6586c4a4d2d0afc68222beb92c6dacfe8 (patch) | |
tree | eb441c34709035408af02276536f94ca43f7a611 /mojo/examples/window_manager | |
parent | d1b2d9f5d437061a733ff4523a547fae7cd7464a (diff) | |
download | chromium_src-1dfdc0b6586c4a4d2d0afc68222beb92c6dacfe8.zip chromium_src-1dfdc0b6586c4a4d2d0afc68222beb92c6dacfe8.tar.gz chromium_src-1dfdc0b6586c4a4d2d0afc68222beb92c6dacfe8.tar.bz2 |
Initial version of keyboard
Lots still to do:
. never hides.
. some buttons show nothing (backspace, enter...).
BUG=384433
TEST=none
R=ben@chromium.org
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=279769
Review URL: https://codereview.chromium.org/330883007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279781 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/examples/window_manager')
-rw-r--r-- | mojo/examples/window_manager/window_manager.cc | 136 | ||||
-rw-r--r-- | mojo/examples/window_manager/window_manager.mojom | 11 |
2 files changed, 135 insertions, 12 deletions
diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc index 201af4c..28178ba 100644 --- a/mojo/examples/window_manager/window_manager.cc +++ b/mojo/examples/window_manager/window_manager.cc @@ -5,8 +5,11 @@ #include "base/basictypes.h" #include "base/bind.h" #include "base/strings/stringprintf.h" +#include "mojo/examples/keyboard/keyboard.mojom.h" #include "mojo/examples/window_manager/window_manager.mojom.h" #include "mojo/public/cpp/application/application.h" +#include "mojo/services/public/cpp/geometry/geometry_type_converters.h" +#include "mojo/services/public/cpp/input_events/input_events_type_converters.h" #include "mojo/services/public/cpp/view_manager/node.h" #include "mojo/services/public/cpp/view_manager/view.h" #include "mojo/services/public/cpp/view_manager/view_event_dispatcher.h" @@ -16,6 +19,7 @@ #include "mojo/services/public/interfaces/input_events/input_events.mojom.h" #include "mojo/services/public/interfaces/launcher/launcher.mojom.h" #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" +#include "ui/events/event.h" #include "ui/events/event_constants.h" #if defined CreateWindow @@ -57,6 +61,8 @@ class WindowManagerConnection : public InterfaceImpl<IWindowManager> { private: // Overridden from IWindowManager: virtual void CloseWindow(Id node_id) OVERRIDE; + virtual void ShowKeyboard(Id view_id, RectPtr bounds) OVERRIDE; + virtual void HideKeyboard(Id view_id) OVERRIDE; WindowManager* window_manager_; @@ -70,21 +76,88 @@ class NavigatorHost : public InterfaceImpl<navigation::NavigatorHost> { } virtual ~NavigatorHost() { } + private: virtual void RequestNavigate( uint32 source_node_id, navigation::Target target, navigation::NavigationDetailsPtr nav_details) OVERRIDE; WindowManager* window_manager_; + DISALLOW_COPY_AND_ASSIGN(NavigatorHost); }; +class KeyboardManager : public KeyboardClient { + public: + KeyboardManager() : view_manager_(NULL), node_(NULL) { + } + virtual ~KeyboardManager() { + } + + Node* node() { return node_; } + + void Init(Application* application, + ViewManager* view_manager, + Node* parent, + const gfx::Rect& bounds) { + view_manager_ = view_manager; + node_ = Node::Create(view_manager); + parent->AddChild(node_); + node_->SetBounds(bounds); + node_->Embed("mojo:mojo_keyboard"); + application->ConnectTo("mojo:mojo_keyboard", &keyboard_service_); + keyboard_service_.set_client(this); + } + + void Show(Id view_id, const gfx::Rect& bounds) { + keyboard_service_->SetTarget(view_id); + } + + void Hide(Id view_id) { + keyboard_service_->SetTarget(0); + } + + private: + // KeyboardClient: + virtual void OnKeyboardEvent(Id view_id, + int32_t code, + int32_t flags) OVERRIDE { + View* view = view_manager_->GetViewById(view_id); + if (!view) + return; +#if defined(OS_WIN) + const bool is_char = code != ui::VKEY_BACK && code != ui::VKEY_RETURN; +#else + const bool is_char = false; +#endif + view_manager_->DispatchEvent( + view, + Event::From(ui::KeyEvent(ui::ET_KEY_PRESSED, + static_cast<ui::KeyboardCode>(code), + flags, is_char))); + view_manager_->DispatchEvent( + view, + Event::From(ui::KeyEvent(ui::ET_KEY_RELEASED, + static_cast<ui::KeyboardCode>(code), + flags, false))); + } + + KeyboardServicePtr keyboard_service_; + ViewManager* view_manager_; + + // Node the keyboard is attached to. + Node* node_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardManager); +}; + class WindowManager : public Application, public ViewObserver, public ViewManagerDelegate, public ViewEventDispatcher { public: - WindowManager() : launcher_ui_(NULL), view_manager_(NULL) {} + WindowManager() : launcher_ui_(NULL), view_manager_(NULL) { + } virtual ~WindowManager() {} void CloseWindow(Id node_id) { @@ -97,6 +170,25 @@ class WindowManager : public Application, node->Destroy(); } + void ShowKeyboard(Id view_id, const gfx::Rect& bounds) { + // TODO: this needs to validate |view_id|. That is, it shouldn't assume + // |view_id| is valid and it also needs to make sure the client that sent + // this really owns |view_id|. + if (!keyboard_manager_) { + keyboard_manager_.reset(new KeyboardManager); + keyboard_manager_->Init(this, view_manager_, + view_manager_->GetRoots().back(), + gfx::Rect(0, 400, 400, 200)); + } + keyboard_manager_->Show(view_id, bounds); + } + + void HideKeyboard(Id view_id) { + // See comment in ShowKeyboard() about validating args. + if (keyboard_manager_) + keyboard_manager_->Hide(view_id); + } + void RequestNavigate( uint32 source_node_id, navigation::Target target, @@ -129,7 +221,7 @@ class WindowManager : public Application, if (app_url.empty()) return; - Node* node = view_manager_->GetNodeById(parent_node_id_); + Node* node = view_manager_->GetNodeById(content_node_id_); navigation::NavigationDetailsPtr nav_details( navigation::NavigationDetails::New()); size_t index = node->children().size() - 1; @@ -149,7 +241,7 @@ class WindowManager : public Application, Node* node = Node::Create(view_manager); view_manager->GetRoots().front()->AddChild(node); node->SetBounds(gfx::Rect(800, 600)); - parent_node_id_ = node->id(); + content_node_id_ = node->id(); View* view = View::Create(view_manager); node->SetActiveView(view); @@ -162,8 +254,10 @@ class WindowManager : public Application, // Overridden from ViewEventDispatcher: virtual void DispatchEvent(View* target, EventPtr event) OVERRIDE { // TODO(beng): More sophisticated focus handling than this is required! - if (event->action == ui::ET_MOUSE_PRESSED) + if (event->action == ui::ET_MOUSE_PRESSED && + !IsDescendantOfKeyboard(target)) { target->node()->SetFocus(); + } view_manager_->DispatchEvent(target, event.Pass()); } @@ -189,18 +283,18 @@ class WindowManager : public Application, void CreateLauncherUI() { navigation::NavigationDetailsPtr nav_details; navigation::ResponseDetailsPtr response; - Node* node = view_manager_->GetNodeById(parent_node_id_); + Node* node = view_manager_->GetNodeById(content_node_id_); gfx::Rect bounds = node->bounds(); bounds.Inset(kBorderInset, kBorderInset); bounds.set_height(kTextfieldHeight); - launcher_ui_ = CreateChild("mojo:mojo_browser", bounds, + launcher_ui_ = CreateChild(content_node_id_, "mojo:mojo_browser", bounds, nav_details.Pass(), response.Pass()); } void CreateWindow(const std::string& handler_url, navigation::NavigationDetailsPtr nav_details, navigation::ResponseDetailsPtr response) { - Node* node = view_manager_->GetNodeById(parent_node_id_); + Node* node = view_manager_->GetNodeById(content_node_id_); gfx::Rect bounds(kBorderInset, 2 * kBorderInset + kTextfieldHeight, node->bounds().width() - 2 * kBorderInset, node->bounds().height() - @@ -210,15 +304,16 @@ class WindowManager : public Application, position.Offset(35, 35); bounds.set_origin(position); } - windows_.push_back(CreateChild(handler_url, bounds, nav_details.Pass(), - response.Pass())); + windows_.push_back(CreateChild(content_node_id_, handler_url, bounds, + nav_details.Pass(), response.Pass())); } - Node* CreateChild(const std::string& url, + Node* CreateChild(Id parent_id, + const std::string& url, const gfx::Rect& bounds, navigation::NavigationDetailsPtr nav_details, navigation::ResponseDetailsPtr response) { - Node* node = view_manager_->GetNodeById(parent_node_id_); + Node* node = view_manager_->GetNodeById(parent_id); Node* embedded = Node::Create(view_manager_); node->AddChild(embedded); embedded->SetBounds(bounds); @@ -238,11 +333,20 @@ class WindowManager : public Application, } } + bool IsDescendantOfKeyboard(View* target) { + return !keyboard_manager_.get() || + !keyboard_manager_->node()->Contains(target->node()); + } + launcher::LauncherPtr launcher_; Node* launcher_ui_; std::vector<Node*> windows_; ViewManager* view_manager_; - Id parent_node_id_; + + // Id of the node most content is added to. The keyboard is NOT added here. + Id content_node_id_; + + scoped_ptr<KeyboardManager> keyboard_manager_; DISALLOW_COPY_AND_ASSIGN(WindowManager); }; @@ -251,6 +355,14 @@ void WindowManagerConnection::CloseWindow(Id node_id) { window_manager_->CloseWindow(node_id); } +void WindowManagerConnection::ShowKeyboard(Id view_id, RectPtr bounds) { + window_manager_->ShowKeyboard(view_id, bounds.To<gfx::Rect>()); +} + +void WindowManagerConnection::HideKeyboard(Id node_id) { + window_manager_->HideKeyboard(node_id); +} + void NavigatorHost::RequestNavigate( uint32 source_node_id, navigation::Target target, diff --git a/mojo/examples/window_manager/window_manager.mojom b/mojo/examples/window_manager/window_manager.mojom index 213c5e5..29f0d89 100644 --- a/mojo/examples/window_manager/window_manager.mojom +++ b/mojo/examples/window_manager/window_manager.mojom @@ -2,10 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import "mojo/services/public/interfaces/geometry/geometry.mojom" + module mojo { interface IWindowManager { CloseWindow(uint32 node_id); + + // Shows the keyboard for the specified view. |bounds| is the bounds of the + // view that is showing focus. |bounds| is relative to the bounds of the node. + // Events from the keyboard are routed to the view with id |view_id|. + ShowKeyboard(uint32 view_id, mojo.Rect bounds); + + // Hides the keyboard. This is ignored if |view_id| is not the view that was + // last passed to ShowKeyboard(). + HideKeyboard(uint32 view_id); }; } |