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 | |
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
-rw-r--r-- | mojo/examples/browser/browser.cc | 67 | ||||
-rw-r--r-- | mojo/examples/keyboard/DEPS | 10 | ||||
-rw-r--r-- | mojo/examples/keyboard/keyboard.cc | 129 | ||||
-rw-r--r-- | mojo/examples/keyboard/keyboard.mojom | 19 | ||||
-rw-r--r-- | mojo/examples/keyboard/keyboard_delegate.h | 26 | ||||
-rw-r--r-- | mojo/examples/keyboard/keyboard_view.cc | 251 | ||||
-rw-r--r-- | mojo/examples/keyboard/keyboard_view.h | 102 | ||||
-rw-r--r-- | mojo/examples/keyboard/keys.cc | 186 | ||||
-rw-r--r-- | mojo/examples/keyboard/keys.h | 62 | ||||
-rw-r--r-- | mojo/examples/window_manager/window_manager.cc | 136 | ||||
-rw-r--r-- | mojo/examples/window_manager/window_manager.mojom | 11 | ||||
-rw-r--r-- | mojo/mojo.gyp | 1 | ||||
-rw-r--r-- | mojo/mojo_examples.gypi | 64 | ||||
-rw-r--r-- | mojo/mojo_services.gypi | 1 | ||||
-rw-r--r-- | mojo/services/public/cpp/input_events/input_events_type_converters.h | 6 | ||||
-rw-r--r-- | mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc | 6 | ||||
-rw-r--r-- | mojo/views/native_widget_view_manager.cc | 3 | ||||
-rw-r--r-- | mojo/views/native_widget_view_manager.h | 5 |
18 files changed, 1070 insertions, 15 deletions
diff --git a/mojo/examples/browser/browser.cc b/mojo/examples/browser/browser.cc index 7c39da8..fed88b5 100644 --- a/mojo/examples/browser/browser.cc +++ b/mojo/examples/browser/browser.cc @@ -5,7 +5,9 @@ #include "base/basictypes.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.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/view_manager/node.h" #include "mojo/services/public/cpp/view_manager/view.h" #include "mojo/services/public/cpp/view_manager/view_manager.h" @@ -18,9 +20,11 @@ #include "ui/events/event.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/focus/focus_manager.h" #include "ui/views/layout/layout_manager.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" +#include "ui/views/widget/widget_observer.h" #include "url/gurl.h" namespace mojo { @@ -47,6 +51,65 @@ class BrowserLayoutManager : public views::LayoutManager { DISALLOW_COPY_AND_ASSIGN(BrowserLayoutManager); }; +// KeyboardManager handles notifying the windowmanager when views are focused. +// To use create one and KeyboardManager will take care of all other details. +// +// TODO(sky): it would be nice if this were put in NativeWidgetViewManager, but +// that requires NativeWidgetViewManager to take an IWindowManager. That may be +// desirable anyway... +class KeyboardManager : public views::FocusChangeListener, + public views::WidgetObserver { + public: + KeyboardManager(views::Widget* widget, + IWindowManager* window_manager, + view_manager::Node* node) + : widget_(widget), + window_manager_(window_manager), + node_(node), + last_view_id_(0) { + widget_->AddObserver(this); + widget_->GetFocusManager()->AddFocusChangeListener(this); + } + + private: + virtual ~KeyboardManager() { + widget_->GetFocusManager()->RemoveFocusChangeListener(this); + widget_->RemoveObserver(this); + } + + // views::FocusChangeListener: + virtual void OnWillChangeFocus(views::View* focused_before, + views::View* focused_now) OVERRIDE { + } + virtual void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) OVERRIDE { + if (focused_now && + focused_now->GetClassName() == views::Textfield::kViewClassName) { + const gfx::Rect bounds_in_widget = + focused_now->ConvertRectToWidget( + gfx::Rect(focused_now->bounds().size())); + last_view_id_ = node_->active_view()->id(); + window_manager_->ShowKeyboard(last_view_id_, + Rect::From(bounds_in_widget)); + } else { + window_manager_->HideKeyboard(last_view_id_); + last_view_id_ = 0; + } + } + + // views::WidgetObserver: + virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE { + delete this; + } + + views::Widget* widget_; + IWindowManager* window_manager_; + view_manager::Node* node_; + view_manager::Id last_view_id_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardManager); +}; + // This is the basics of creating a views widget with a textfield. // TODO: cleanup! class Browser : public Application, @@ -65,6 +128,7 @@ class Browser : public Application, views_init_.reset(new ViewsInit); view_manager::ViewManager::Create(this, this); ConnectTo("mojo:mojo_window_manager", &navigator_host_); + ConnectTo("mojo:mojo_window_manager", &window_manager_); } void CreateWidget(view_manager::Node* node) { @@ -83,6 +147,8 @@ class Browser : public Application, params.delegate = widget_delegate; params.bounds = gfx::Rect(node->bounds().width(), node->bounds().height()); widget_->Init(params); + // KeyboardManager handles deleting itself when the widget is destroyed. + new KeyboardManager(widget_, window_manager_.get(), node); widget_->Show(); textfield->RequestFocus(); } @@ -132,6 +198,7 @@ class Browser : public Application, view_manager::Node* root_; views::Widget* widget_; navigation::NavigatorHostPtr navigator_host_; + IWindowManagerPtr window_manager_; DISALLOW_COPY_AND_ASSIGN(Browser); }; diff --git a/mojo/examples/keyboard/DEPS b/mojo/examples/keyboard/DEPS new file mode 100644 index 0000000..b65676e --- /dev/null +++ b/mojo/examples/keyboard/DEPS @@ -0,0 +1,10 @@ +include_rules = [ + "+cc", + "+skia/ext", + "+ui/aura", + "+ui/base/hit_test.h", + "+ui/compositor", + "+ui/events", + "+ui/gfx", + "+ui/views", +] diff --git a/mojo/examples/keyboard/keyboard.cc b/mojo/examples/keyboard/keyboard.cc new file mode 100644 index 0000000..ae6d8c9 --- /dev/null +++ b/mojo/examples/keyboard/keyboard.cc @@ -0,0 +1,129 @@ +// 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/basictypes.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "mojo/examples/keyboard/keyboard.mojom.h" +#include "mojo/examples/keyboard/keyboard_delegate.h" +#include "mojo/examples/keyboard/keyboard_view.h" +#include "mojo/public/cpp/application/application.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_manager.h" +#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" +#include "mojo/services/public/cpp/view_manager/view_observer.h" +#include "mojo/services/public/interfaces/navigation/navigation.mojom.h" +#include "mojo/views/native_widget_view_manager.h" +#include "mojo/views/views_init.h" +#include "ui/events/event.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" +#include "url/gurl.h" + +using mojo::view_manager::Id; + +namespace mojo { +namespace examples { + +class Keyboard; + +class KeyboardServiceImpl : public InterfaceImpl<KeyboardService> { + public: + KeyboardServiceImpl(Keyboard* keyboard); + virtual ~KeyboardServiceImpl() {} + + // KeyboardService: + virtual void SetTarget(uint32_t node_id) OVERRIDE; + + private: + Keyboard* keyboard_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardServiceImpl); +}; + +class Keyboard : public Application, + public view_manager::ViewManagerDelegate, + public KeyboardDelegate { + public: + Keyboard() : view_manager_(NULL), keyboard_service_(NULL), target_(0) {} + + virtual ~Keyboard() { + } + + void set_target(Id id) { target_ = id; } + + void set_keyboard_service(KeyboardServiceImpl* keyboard) { + keyboard_service_ = keyboard; + } + + private: + // Overridden from Application: + virtual void Initialize() MOJO_OVERRIDE { + views_init_.reset(new ViewsInit); + view_manager::ViewManager::Create(this, this); + AddService<KeyboardServiceImpl>(this); + } + + void CreateWidget(view_manager::Node* node) { + views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView; + widget_delegate->GetContentsView()->AddChildView(new KeyboardView(this)); + widget_delegate->GetContentsView()->SetLayoutManager(new views::FillLayout); + + views::Widget* widget = new views::Widget; + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.native_widget = new NativeWidgetViewManager(widget, node); + params.delegate = widget_delegate; + params.bounds = gfx::Rect(node->bounds().width(), node->bounds().height()); + widget->Init(params); + widget->Show(); + } + + // view_manager::ViewManagerDelegate: + virtual void OnRootAdded(view_manager::ViewManager* view_manager, + view_manager::Node* root) OVERRIDE { + // TODO: deal with OnRootAdded() being invoked multiple times. + view_manager_ = view_manager; + root->SetActiveView(view_manager::View::Create(view_manager)); + CreateWidget(root); + } + + // KeyboardDelegate: + virtual void OnKeyPressed(int key_code, int event_flags) OVERRIDE { + if (!target_) + return; + keyboard_service_->client()->OnKeyboardEvent(target_, key_code, + event_flags); + } + + scoped_ptr<ViewsInit> views_init_; + + view_manager::ViewManager* view_manager_; + + KeyboardServiceImpl* keyboard_service_; + + Id target_; + + DISALLOW_COPY_AND_ASSIGN(Keyboard); +}; + +KeyboardServiceImpl::KeyboardServiceImpl(Keyboard* keyboard) + : keyboard_(keyboard) { + keyboard_->set_keyboard_service(this); +} + +void KeyboardServiceImpl::SetTarget(uint32_t node_id) { + keyboard_->set_target(node_id); +} + +} // namespace examples + +// static +Application* Application::Create() { + return new examples::Keyboard; +} + +} // namespace mojo diff --git a/mojo/examples/keyboard/keyboard.mojom b/mojo/examples/keyboard/keyboard.mojom new file mode 100644 index 0000000..9377898 --- /dev/null +++ b/mojo/examples/keyboard/keyboard.mojom @@ -0,0 +1,19 @@ +// 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 { + +[Client=KeyboardClient] +interface KeyboardService { + // Sets the view keyboard events are to go to. + SetTarget(uint32 view_id); +}; + +interface KeyboardClient { + // Invoked when the user interacts with the keyboard. |code| is a key code + // |flags| is a bitmask of ui::EventFlags. + OnKeyboardEvent(uint32 view_id, int32 code, int32 flags); +}; + +} diff --git a/mojo/examples/keyboard/keyboard_delegate.h b/mojo/examples/keyboard/keyboard_delegate.h new file mode 100644 index 0000000..bf35fc6 --- /dev/null +++ b/mojo/examples/keyboard/keyboard_delegate.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef MOJO_EXAMPLES_KEYBOARD_KEYBOARD_DELEGATE_H_ +#define MOJO_EXAMPLES_KEYBOARD_KEYBOARD_DELEGATE_H_ + +#include "base/basictypes.h" + +namespace mojo { +namespace examples { + +class KeyboardDelegate { + public: + KeyboardDelegate() {} + + virtual void OnKeyPressed(int key_code, int event_flags) = 0; + + protected: + virtual ~KeyboardDelegate() {} +}; + +} // namespace examples +} // namespace mojo + +#endif // MOJO_EXAMPLES_KEYBOARD_KEYBOARD_DELEGATE_H_ diff --git a/mojo/examples/keyboard/keyboard_view.cc b/mojo/examples/keyboard/keyboard_view.cc new file mode 100644 index 0000000..4dfeecb --- /dev/null +++ b/mojo/examples/keyboard/keyboard_view.cc @@ -0,0 +1,251 @@ +// 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 "mojo/examples/keyboard/keyboard_view.h" + +#include <algorithm> + +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "mojo/examples/keyboard/keyboard_delegate.h" +#include "mojo/examples/keyboard/keys.h" +#include "ui/events/keycodes/keyboard_code_conversion.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/gfx/canvas.h" +#include "ui/views/background.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/button/label_button_border.h" + +namespace mojo { +namespace examples { + +namespace { + +const int kHorizontalPadding = 6; +const int kVerticalPadding = 8; + +base::string16 GetDisplayString(int key_code, int flags) { + return base::string16(1, ui::GetCharacterFromKeyCode( + static_cast<ui::KeyboardCode>(key_code), flags)); +} + +// Returns a font that fits in the space provided. |text| is used as a basis +// for determing the size. +gfx::FontList CalculateFont(int width, int height, const base::string16& text) { + gfx::FontList font; + gfx::FontList last_font; + while (gfx::Canvas::GetStringWidth(text, font) < width && + font.GetHeight() < height) { + last_font = font; + font = font.DeriveWithSizeDelta(2); + } + return last_font; +} + +// Returns the total number of keys in |rows|. +int NumKeys(const std::vector<const Row*>& rows) { + int result = 0; + for (size_t i = 0; i < rows.size(); ++i) + result += static_cast<int>(rows[i]->num_keys); + return result; +} + +} // namespace + +KeyboardView::KeyboardView(KeyboardDelegate* delegate) + : delegate_(delegate), + max_keys_in_row_(0), + keyboard_layout_(KEYBOARD_LAYOUT_ALPHA) { + set_background(views::Background::CreateSolidBackground(SK_ColorBLACK)); + SetRows(GetQWERTYRows()); +} + +KeyboardView::~KeyboardView() { +} + +void KeyboardView::Layout() { + if (width() == 0 || height() == 0 || rows_.empty() || + last_layout_size_ == bounds().size()) + return; + + last_layout_size_ = bounds().size(); + + const int button_width = + (width() - (max_keys_in_row_ - 1) * kHorizontalPadding) / + max_keys_in_row_; + const int button_height = + (height() - (static_cast<int>(rows_.size() - 1) * kVerticalPadding)) / + static_cast<int>(rows_.size()); + for (size_t i = 0; i < rows_.size(); ++i) + LayoutRow(*(rows_[i]), static_cast<int>(i), button_width, button_height); + + views::LabelButtonBorder border(views::Button::STYLE_TEXTBUTTON); + gfx::Insets insets(border.GetInsets()); + gfx::FontList font = CalculateFont(button_width - insets.width(), + button_height - insets.height(), + base::ASCIIToUTF16("W")); + gfx::FontList special_font = CalculateFont(button_width - insets.width(), + button_height - insets.height(), + base::ASCIIToUTF16("?123")); + button_font_ = font; + ResetFonts(font, special_font); +} + +void KeyboardView::SetLayout(KeyboardLayout keyboard_layout) { + if (keyboard_layout_ == keyboard_layout) + return; + + keyboard_layout_ = keyboard_layout; + last_layout_size_ = gfx::Size(); + if (keyboard_layout_ == KEYBOARD_LAYOUT_NUMERIC) + SetRows(GetNumericRows()); + else + SetRows(GetQWERTYRows()); + Layout(); + SchedulePaint(); +} + +void KeyboardView::LayoutRow(const Row& row, + int row_index, + int button_width, + int button_height) { + int x = row.padding * (button_width + kHorizontalPadding); + const int y = row_index * (button_height + kVerticalPadding); + for (size_t i = 0; i < row.num_keys; ++i) { + views::View* button = GetButton(row_index, static_cast<int>(i)); + int actual_width = button_width; + if (row.keys[i].size > 1) { + actual_width = (button_width + kHorizontalPadding) * + row.keys[i].size - kHorizontalPadding; + } + button->SetBounds(x, y, actual_width, button_height); + x += actual_width + kHorizontalPadding; + } +} + +void KeyboardView::SetRows(const std::vector<const Row*>& rows) { + const int num_keys = NumKeys(rows); + while (child_count() > num_keys) + delete child_at(child_count() - 1); + for (int i = child_count(); i < num_keys; ++i) + AddChildView(CreateButton()); + + last_layout_size_ = gfx::Size(); + + rows_ = rows; + + max_keys_in_row_ = 0; + for (size_t i = 0; i < rows_.size(); ++i) { + max_keys_in_row_ = std::max(max_keys_in_row_, + static_cast<int>(rows_[i]->num_keys)); + ConfigureButtonsInRow(static_cast<int>(i), *rows_[i]); + } +} + +void KeyboardView::ConfigureButtonsInRow(int row_index, const Row& row) { + for (size_t i = 0; i < row.num_keys; ++i) { + views::LabelButton* button = GetButton(row_index, static_cast<int>(i)); + const Key& key(row.keys[i]); + switch (key.display_code) { + case SPECIAL_KEY_SHIFT: + // TODO: need image. + button->SetText(base::string16()); + break; + case SPECIAL_KEY_NUMERIC: + button->SetText(base::ASCIIToUTF16("?123")); + break; + case SPECIAL_KEY_ALPHA: + button->SetText(base::ASCIIToUTF16("ABC")); + break; + default: + button->SetText(GetDisplayString(key.display_code, + key.event_flags | event_flags())); + break; + } + button->SetState(views::Button::STATE_NORMAL); + } +} + +views::View* KeyboardView::CreateButton() { + views::LabelButton* button = new views::LabelButton(this, base::string16()); + button->SetTextColor(views::Button::STATE_NORMAL, SK_ColorWHITE); + button->SetHorizontalAlignment(gfx::ALIGN_CENTER); + button->set_background(views::Background::CreateSolidBackground(78, 78, 78)); + button->SetFontList(button_font_); + // button->SetHaloColor(SK_ColorBLACK); + // Turn off animations as we reuse buttons in different layouts. If we didn't + // do this and you click a button to change the layout then the button you + // clicked on would animate the transition even though it may now represent a + // different key. + button->SetAnimationDuration(0); + return button; +} + +views::LabelButton* KeyboardView::GetButton(int row, int column) { + int offset = column; + for (int i = 0; i < row; ++i) + offset += static_cast<int>(rows_[i]->num_keys); + return static_cast<views::LabelButton*>(child_at(offset)); +} + +const Key& KeyboardView::GetKeyForButton(views::Button* button) const { + int index = GetIndexOf(button); + DCHECK_NE(-1, index); + int row = 0; + while (index >= static_cast<int>(rows_[row]->num_keys)) { + index -= static_cast<int>(rows_[row]->num_keys); + row++; + } + return rows_[row]->keys[index]; +} + +void KeyboardView::ResetFonts(const gfx::FontList& button_font, + const gfx::FontList& special_font) { + for (size_t i = 0; i < rows_.size(); ++i) { + for (size_t j = 0; j < rows_[i]->num_keys; ++j) { + views::LabelButton* button = GetButton(static_cast<int>(i), + static_cast<int>(j)); + const Key& key(GetKeyForButton(button)); + switch (key.display_code) { + case SPECIAL_KEY_ALPHA: + case SPECIAL_KEY_NUMERIC: + button->SetFontList(special_font); + break; + default: + button->SetFontList(button_font); + break; + } + } + } +} + +void KeyboardView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + const Key& key(GetKeyForButton(sender)); + switch (key.display_code) { + case SPECIAL_KEY_SHIFT: + SetLayout((keyboard_layout_ == KEYBOARD_LAYOUT_SHIFT) ? + KEYBOARD_LAYOUT_ALPHA : KEYBOARD_LAYOUT_SHIFT); + return; + case SPECIAL_KEY_ALPHA: + SetLayout(KEYBOARD_LAYOUT_ALPHA); + return; + case SPECIAL_KEY_NUMERIC: + SetLayout(KEYBOARD_LAYOUT_NUMERIC); + return; + default: + break; + } + + // Windows isn't happy if we pass in the flags used to get the display string. +#if defined(OS_WIN) + int key_event_flags = 0; +#else + int key_event_flags = key.event_flags; +#endif + delegate_->OnKeyPressed(key.keyboard_code(), key_event_flags | event_flags()); +} + +} // namespace examples +} // namespace mojo diff --git a/mojo/examples/keyboard/keyboard_view.h b/mojo/examples/keyboard/keyboard_view.h new file mode 100644 index 0000000..36c6b42 --- /dev/null +++ b/mojo/examples/keyboard/keyboard_view.h @@ -0,0 +1,102 @@ +// 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. + +#ifndef MOJO_EXAMPLES_KEYBOARD_KEYBOARD_VIEW_H_ +#define MOJO_EXAMPLES_KEYBOARD_KEYBOARD_VIEW_H_ + +#include <vector> + +#include "ui/gfx/font_list.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/view.h" + +namespace views { +class LabelButton; +} + +namespace mojo { +namespace examples { + +class KeyboardDelegate; +struct Key; +struct Row; + +// Shows a keyboard the user can interact with. The delegate is notified any +// time the user presses a button. +class KeyboardView : public views::View, public views::ButtonListener { + public: + explicit KeyboardView(KeyboardDelegate* delegate); + virtual ~KeyboardView(); + + // views::View: + virtual void Layout() OVERRIDE; + + private: + // The type of keys that are shown. + enum KeyboardLayout { + KEYBOARD_LAYOUT_ALPHA, + + // Uppercase characters. + KEYBOARD_LAYOUT_SHIFT, + + // Numeric characters. + KEYBOARD_LAYOUT_NUMERIC, + }; + + int event_flags() const { + return (keyboard_layout_ == KEYBOARD_LAYOUT_SHIFT) ? + ui::EF_SHIFT_DOWN : ui::EF_NONE; + } + + void SetLayout(KeyboardLayout layout); + + // Lays out the buttons for the specified row. + void LayoutRow(const Row& row, + int row_index, + int button_width, + int button_height); + + // Sets the rows to show. + void SetRows(const std::vector<const Row*>& rows); + + // Configures the button in a row. + void ConfigureButtonsInRow(int row_index, const Row& row); + + // Creates a new button. + views::View* CreateButton(); + + // Returns the button corresponding to a key at the specified row/column. + views::LabelButton* GetButton(int row, int column); + + const Key& GetKeyForButton(views::Button* button) const; + + // Reset the fonts of all the buttons. |special_font| is used for the buttons + // that toggle the layout. + void ResetFonts(const gfx::FontList& button_font, + const gfx::FontList& special_font); + + // views::ButtonListener: + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE; + + KeyboardDelegate* delegate_; + + // Maximium number of keys in a row. Determined from |rows_|. + int max_keys_in_row_; + + KeyboardLayout keyboard_layout_; + + std::vector<const Row*> rows_; + + gfx::Size last_layout_size_; + + gfx::FontList button_font_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardView); +}; + +} // namespace examples +} // namespace mojo + +#endif // MOJO_EXAMPLES_KEYBOARD_KEYBOARD_VIEW_H_ diff --git a/mojo/examples/keyboard/keys.cc b/mojo/examples/keyboard/keys.cc new file mode 100644 index 0000000..adf9094 --- /dev/null +++ b/mojo/examples/keyboard/keys.cc @@ -0,0 +1,186 @@ +// 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 "mojo/examples/keyboard/keys.h" + +#include "base/macros.h" +#include "ui/events/event_constants.h" +#include "ui/events/keycodes/keyboard_codes.h" + +namespace mojo { +namespace examples { +namespace { + +const Key kQWERTYKeysRow1[] = +{ + { ui::VKEY_Q, 1, 0, 'q' }, + { ui::VKEY_W, 1, 0, 'w' }, + { ui::VKEY_E, 1, 0, 'e' }, + { ui::VKEY_R, 1, 0, 'r' }, + { ui::VKEY_T, 1, 0, 't' }, + { ui::VKEY_Y, 1, 0, 'y' }, + { ui::VKEY_U, 1, 0, 'u' }, + { ui::VKEY_I, 1, 0, 'i' }, + { ui::VKEY_O, 1, 0, 'o' }, + { ui::VKEY_P, 1, 0, 'p' }, +}; + +const Key kQWERTYKeysRow2[] = +{ + { ui::VKEY_A, 1, 0, 'a' }, + { ui::VKEY_S, 1, 0, 's' }, + { ui::VKEY_D, 1, 0, 'd' }, + { ui::VKEY_F, 1, 0, 'f' }, + { ui::VKEY_G, 1, 0, 'g' }, + { ui::VKEY_H, 1, 0, 'h' }, + { ui::VKEY_J, 1, 0, 'j' }, + { ui::VKEY_K, 1, 0, 'k' }, + { ui::VKEY_L, 1, 0, 'l' }, +}; + +const Key kQWERTYKeysRow3[] = +{ + { SPECIAL_KEY_SHIFT, 1.5, 0, 0 }, + { ui::VKEY_Z, 1, 0, 'z' }, + { ui::VKEY_X, 1, 0, 'x' }, + { ui::VKEY_C, 1, 0, 'c' }, + { ui::VKEY_V, 1, 0, 'v' }, + { ui::VKEY_B, 1, 0, 'b' }, + { ui::VKEY_N, 1, 0, 'n' }, + { ui::VKEY_M, 1, 0, 'm' }, + { ui::VKEY_BACK, 1.5, 0, 0 }, +}; + +const Key kQWERTYKeysRow4[] = +{ + { SPECIAL_KEY_NUMERIC, 1.5, 0, 0 }, + { ui::VKEY_DIVIDE, 1, 0, '/' }, + { ui::VKEY_SPACE, 5, 0, ' ' }, + { ui::VKEY_DECIMAL, 1, 0, '.' }, + { ui::VKEY_RETURN, 1.5, 0, 0 }, +}; + +const Row kQWERTYRow1 = { + 0, + kQWERTYKeysRow1, + arraysize(kQWERTYKeysRow1), +}; + +const Row kQWERTYRow2 = { + .5, + kQWERTYKeysRow2, + arraysize(kQWERTYKeysRow2), +}; + +const Row kQWERTYRow3 = { + 0, + kQWERTYKeysRow3, + arraysize(kQWERTYKeysRow3), +}; + +const Row kQWERTYRow4 = { + 0, + kQWERTYKeysRow4, + arraysize(kQWERTYKeysRow4), +}; + +const Key kNumericKeysRow1[] = +{ + { ui::VKEY_1, 1, 0, 0 }, + { ui::VKEY_2, 1, 0, 0 }, + { ui::VKEY_3, 1, 0, 0 }, + { ui::VKEY_4, 1, 0, 0 }, + { ui::VKEY_5, 1, 0, 0 }, + { ui::VKEY_6, 1, 0, 0 }, + { ui::VKEY_7, 1, 0, 0 }, + { ui::VKEY_8, 1, 0, 0 }, + { ui::VKEY_9, 1, 0, 0 }, + { ui::VKEY_0, 1, 0, 0 }, +}; + +const Key kNumericKeysRow2[] = +{ + // @#$%&-+() + { ui::VKEY_2, 1, ui::EF_SHIFT_DOWN, '@' }, + { ui::VKEY_3, 1, ui::EF_SHIFT_DOWN, '#' }, + { ui::VKEY_4, 1, ui::EF_SHIFT_DOWN, '$' }, + { ui::VKEY_5, 1, ui::EF_SHIFT_DOWN, '%' }, + { ui::VKEY_7, 1, ui::EF_SHIFT_DOWN, '&' }, + { ui::VKEY_SUBTRACT, 1, 0, '-' }, + { ui::VKEY_ADD, 1, 0, '+' }, + { ui::VKEY_9, 1, ui::EF_SHIFT_DOWN, '(' }, + { ui::VKEY_0, 1, ui::EF_SHIFT_DOWN, ')' }, +}; + +const Key kNumericKeysRow3[] = +{ + // *"':;!? backspace + { ui::VKEY_MULTIPLY, 1, 0, '*' }, + { ui::VKEY_OEM_7, 1, ui::EF_SHIFT_DOWN, '"' }, + { ui::VKEY_OEM_7, 1, 0, '\'' }, + { ui::VKEY_OEM_1, 1, ui::EF_SHIFT_DOWN, ':' }, + { ui::VKEY_OEM_1, 1, 0, ';' }, + { ui::VKEY_1, 1, ui::EF_SHIFT_DOWN, '!' }, + { ui::VKEY_OEM_2, 1, ui::EF_SHIFT_DOWN, '?' }, + { ui::VKEY_BACK, 1.5, 0, 0 }, +}; + +const Key kNumericKeysRow4[] = +{ + // ABC _ / space (3) ,.enter + { SPECIAL_KEY_ALPHA, 1.5, 0, 0 }, + { ui::VKEY_OEM_MINUS, 1, ui::EF_SHIFT_DOWN, '_' }, + { ui::VKEY_OEM_2, 1, 0, '/' }, + { ui::VKEY_SPACE, 3, 0, ' ' }, + { ui::VKEY_OEM_COMMA, 1, 0, ',' }, + { ui::VKEY_OEM_PERIOD, 1, 0, '.' }, + { ui::VKEY_RETURN, 1.5, 0, 0 }, +}; + +const Row kNumericRow1 = { + 0, + kNumericKeysRow1, + arraysize(kNumericKeysRow1), +}; + +const Row kNumericRow2 = { + .5, + kNumericKeysRow2, + arraysize(kNumericKeysRow2), +}; + +const Row kNumericRow3 = { + 1.5, + kNumericKeysRow3, + arraysize(kNumericKeysRow3), +}; + +const Row kNumericRow4 = { + 0, + kNumericKeysRow4, + arraysize(kNumericKeysRow4), +}; + +} // namespace + +std::vector<const Row*> GetQWERTYRows() { + std::vector<const Row*> rows; + rows.push_back(&kQWERTYRow1); + rows.push_back(&kQWERTYRow2); + rows.push_back(&kQWERTYRow3); + rows.push_back(&kQWERTYRow4); + return rows; +} + +std::vector<const Row*> GetNumericRows() { + std::vector<const Row*> rows; + rows.push_back(&kNumericRow1); + rows.push_back(&kNumericRow2); + rows.push_back(&kNumericRow3); + rows.push_back(&kNumericRow4); + return rows; +} + +} // namespace examples +} // namespace mojo diff --git a/mojo/examples/keyboard/keys.h b/mojo/examples/keyboard/keys.h new file mode 100644 index 0000000..c09f856 --- /dev/null +++ b/mojo/examples/keyboard/keys.h @@ -0,0 +1,62 @@ +// 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. + +#ifndef MOJO_EXAMPLES_KEYBOARD_KEYS_H_ +#define MOJO_EXAMPLES_KEYBOARD_KEYS_H_ + +#include <vector> + +#include "base/basictypes.h" + +namespace mojo { +namespace examples { + +enum SpecialKey { + SPECIAL_KEY_SHIFT = -1, + SPECIAL_KEY_NUMERIC = -2, + SPECIAL_KEY_ALPHA = -3, +}; + +struct Key { + int keyboard_code() const { + // Handling of keycodes differs between in windows and others. +#if defined(OS_WIN) + return generated_code ? generated_code : display_code; +#else + return display_code; +#endif + } + + // Code used to get the value to display in the UI. This is either a + // KeyboardCode or a SpecialKey. + int display_code; + + // How much space (as a percentage) the key is to take up. + float size; + + // Any ui::EventFlags that are required to produce the key. + int event_flags; + + // If non-zero KeyboardCode to generate. If 0 use the |display_code|. + int generated_code; +}; + +struct Row { + float padding; + const Key* keys; + size_t num_keys; +}; + +// Returns the rows for a qwerty style keyboard. The returned values are owned +// by this object and should not be deleted. +std::vector<const Row*> GetQWERTYRows(); + +// Returns the rows for a numeric keyboard. The returned values are owned +// by this object and should not be deleted. +std::vector<const Row*> GetNumericRows(); + +} // namespace examples +} // namespace mojo + +#endif // MOJO_EXAMPLES_KEYBOARD_KEYS_H_ 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); }; } diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index 14221e6..5621bea 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -75,6 +75,7 @@ 'mojo_browser', 'mojo_demo_launcher', 'mojo_embedded_app', + 'mojo_keyboard', 'mojo_media_viewer', 'mojo_nesting_app', 'mojo_window_manager', diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi index 6447842..a72f964 100644 --- a/mojo/mojo_examples.gypi +++ b/mojo/mojo_examples.gypi @@ -319,6 +319,7 @@ 'mojo_views_support', 'mojo_view_manager_bindings', 'mojo_view_manager_lib', + 'mojo_window_manager_bindings', ], 'sources': [ 'examples/browser/browser.cc', @@ -356,10 +357,51 @@ ], }, { - 'target_name': 'mojo_window_manager_bindings', + 'target_name': 'mojo_keyboard', + 'type': 'shared_library', + 'dependencies': [ + '../base/base.gyp:base', + '../cc/cc.gyp:cc', + '../third_party/icu/icu.gyp:icui18n', + '../third_party/icu/icu.gyp:icuuc', + '../ui/aura/aura.gyp:aura', + '../ui/base/ui_base.gyp:ui_base', + '../ui/compositor/compositor.gyp:compositor', + '../ui/gfx/gfx.gyp:gfx', + '../ui/gfx/gfx.gyp:gfx_geometry', + '../ui/resources/ui_resources.gyp:ui_resources', + '../ui/resources/ui_resources.gyp:ui_test_pak', + '../ui/views/views.gyp:views', + '../url/url.gyp:url_lib', + 'mojo_application', + 'mojo_aura_support', + 'mojo_common_lib', + 'mojo_environment_chromium', + 'mojo_geometry_bindings', + 'mojo_geometry_lib', + 'mojo_input_events_lib', + 'mojo_keyboard_bindings', + 'mojo_navigation_bindings', + 'mojo_system_impl', + 'mojo_views_support', + 'mojo_view_manager_bindings', + 'mojo_view_manager_lib', + ], + 'sources': [ + 'examples/keyboard/keyboard_delegate.h', + 'examples/keyboard/keyboard_view.cc', + 'examples/keyboard/keyboard_view.h', + 'examples/keyboard/keyboard.cc', + 'examples/keyboard/keys.cc', + 'examples/keyboard/keys.h', + 'public/cpp/application/lib/mojo_main_chromium.cc', + ], + }, + { + 'target_name': 'mojo_keyboard_bindings', 'type': 'static_library', 'sources': [ - 'examples/window_manager/window_manager.mojom', + 'examples/keyboard/keyboard.mojom', ], 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ], 'export_dependent_settings': [ @@ -370,6 +412,21 @@ ], }, { + 'target_name': 'mojo_window_manager_bindings', + 'type': 'static_library', + 'sources': [ + 'examples/window_manager/window_manager.mojom', + ], + 'dependencies': [ + 'mojo_cpp_bindings', + 'mojo_geometry_bindings', + ], + 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ], + 'export_dependent_settings': [ + 'mojo_cpp_bindings', + ], + }, + { 'target_name': 'mojo_window_manager', 'type': 'shared_library', 'dependencies': [ @@ -380,7 +437,10 @@ 'mojo_cpp_bindings', 'mojo_environment_chromium', 'mojo_geometry_bindings', + 'mojo_geometry_lib', 'mojo_gles2', + 'mojo_input_events_lib', + 'mojo_keyboard_bindings', 'mojo_launcher_bindings', 'mojo_navigation_bindings', 'mojo_view_manager_lib', diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi index 632b446..b4848597d 100644 --- a/mojo/mojo_services.gypi +++ b/mojo/mojo_services.gypi @@ -304,6 +304,7 @@ 'dependencies': [ '../base/base.gyp:base', '../skia/skia.gyp:skia', + '../ui/events/events.gyp:events', '../ui/gfx/gfx.gyp:gfx', '../ui/gfx/gfx.gyp:gfx_geometry', 'mojo_application', diff --git a/mojo/services/public/cpp/input_events/input_events_type_converters.h b/mojo/services/public/cpp/input_events/input_events_type_converters.h index 7882f62..00a03ac 100644 --- a/mojo/services/public/cpp/input_events/input_events_type_converters.h +++ b/mojo/services/public/cpp/input_events/input_events_type_converters.h @@ -19,6 +19,12 @@ class MOJO_INPUT_EVENTS_EXPORT TypeConverter<EventPtr, ui::Event> { }; template<> +class MOJO_INPUT_EVENTS_EXPORT TypeConverter<EventPtr, ui::KeyEvent> { + public: + static EventPtr ConvertFrom(const ui::KeyEvent& input); +}; + +template<> class MOJO_INPUT_EVENTS_EXPORT TypeConverter<EventPtr, scoped_ptr<ui::Event> > { public: diff --git a/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc b/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc index 230c4a4..402a065 100644 --- a/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc +++ b/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc @@ -42,6 +42,12 @@ EventPtr TypeConverter<EventPtr, ui::Event>::ConvertFrom( } // static +EventPtr TypeConverter<EventPtr, ui::KeyEvent>::ConvertFrom( + const ui::KeyEvent& input) { + return Event::From(static_cast<const ui::Event&>(input)); +} + +// static scoped_ptr<ui::Event> TypeConverter<EventPtr, scoped_ptr<ui::Event> >::ConvertTo( const EventPtr& input) { diff --git a/mojo/views/native_widget_view_manager.cc b/mojo/views/native_widget_view_manager.cc index 49dfeb5..a903e2b 100644 --- a/mojo/views/native_widget_view_manager.cc +++ b/mojo/views/native_widget_view_manager.cc @@ -16,6 +16,7 @@ #include "ui/base/ime/input_method_factory.h" #include "ui/base/ime/text_input_client.h" #include "ui/wm/core/base_focus_rules.h" +#include "ui/wm/core/capture_controller.h" #include "ui/wm/core/focus_controller.h" namespace mojo { @@ -119,6 +120,8 @@ void NativeWidgetViewManager::InitNativeWidget( views::Widget::InitParams params(in_params); params.parent = window_tree_host_->window(); NativeWidgetAura::InitNativeWidget(params); + capture_client_.reset( + new wm::ScopedCaptureClient(window_tree_host_->window())); } void NativeWidgetViewManager::CompositorContentsChanged( diff --git a/mojo/views/native_widget_view_manager.h b/mojo/views/native_widget_view_manager.h index 5981200..c8fa2c9 100644 --- a/mojo/views/native_widget_view_manager.h +++ b/mojo/views/native_widget_view_manager.h @@ -18,6 +18,7 @@ class InputMethodDelegate; namespace wm { class FocusController; +class ScopedCaptureClient; } namespace mojo { @@ -34,7 +35,7 @@ class NativeWidgetViewManager : public views::NativeWidgetAura, virtual ~NativeWidgetViewManager(); private: - // Overridden from internal::NativeWidgetPrivate: + // Overridden from internal::NativeWidgetAura: virtual void InitNativeWidget( const views::Widget::InitParams& in_params) OVERRIDE; @@ -53,6 +54,8 @@ class NativeWidgetViewManager : public views::NativeWidgetAura, view_manager::Node* node_; + scoped_ptr<wm::ScopedCaptureClient> capture_client_; + DISALLOW_COPY_AND_ASSIGN(NativeWidgetViewManager); }; |