summaryrefslogtreecommitdiffstats
path: root/mojo/examples/window_manager
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-25 19:28:31 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-25 19:28:31 +0000
commit1dfdc0b6586c4a4d2d0afc68222beb92c6dacfe8 (patch)
treeeb441c34709035408af02276536f94ca43f7a611 /mojo/examples/window_manager
parentd1b2d9f5d437061a733ff4523a547fae7cd7464a (diff)
downloadchromium_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.cc136
-rw-r--r--mojo/examples/window_manager/window_manager.mojom11
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);
};
}