Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mash/quick_launch/quick_launch_application.h" | 5 #include "mash/quick_launch/quick_launch_application.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/strings/string16.h" | |
| 9 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 11 #include "mojo/public/c/system/main.h" | 12 #include "mojo/public/c/system/main.h" |
| 12 #include "mojo/services/tracing/public/cpp/tracing_impl.h" | 13 #include "mojo/services/tracing/public/cpp/tracing_impl.h" |
| 13 #include "mojo/shell/public/cpp/application_runner.h" | 14 #include "mojo/shell/public/cpp/application_runner.h" |
| 14 #include "mojo/shell/public/cpp/connector.h" | 15 #include "mojo/shell/public/cpp/connector.h" |
| 15 #include "mojo/shell/public/cpp/shell_client.h" | 16 #include "mojo/shell/public/cpp/shell_client.h" |
| 16 #include "ui/views/background.h" | 17 #include "ui/views/background.h" |
| 17 #include "ui/views/controls/textfield/textfield.h" | 18 #include "ui/views/controls/textfield/textfield.h" |
| 18 #include "ui/views/controls/textfield/textfield_controller.h" | 19 #include "ui/views/controls/textfield/textfield_controller.h" |
| 19 #include "ui/views/mus/aura_init.h" | 20 #include "ui/views/mus/aura_init.h" |
| 20 #include "ui/views/mus/window_manager_connection.h" | 21 #include "ui/views/mus/window_manager_connection.h" |
| 21 #include "ui/views/widget/widget_delegate.h" | 22 #include "ui/views/widget/widget_delegate.h" |
| 22 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 23 | 24 |
| 24 namespace views { | 25 namespace views { |
| 25 class AuraInit; | 26 class AuraInit; |
| 26 } | 27 } |
| 27 | 28 |
| 28 namespace mash { | 29 namespace mash { |
| 29 namespace quick_launch { | 30 namespace quick_launch { |
| 30 | 31 |
| 31 class QuickLaunchUI : public views::WidgetDelegateView, | 32 class QuickLaunchUI : public views::WidgetDelegateView, |
| 32 public views::TextfieldController { | 33 public views::TextfieldController { |
| 33 public: | 34 public: |
| 34 QuickLaunchUI(mojo::Connector* connector) | 35 QuickLaunchUI(mojo::Connector* connector, |
| 35 : connector_(connector), prompt_(new views::Textfield) { | 36 catalog::mojom::CatalogPtr catalog) |
| 37 : connector_(connector), | |
| 38 catalog_(std::move(catalog)), | |
| 39 prompt_(new views::Textfield) { | |
| 36 set_background(views::Background::CreateStandardPanelBackground()); | 40 set_background(views::Background::CreateStandardPanelBackground()); |
| 37 prompt_->set_controller(this); | 41 prompt_->set_controller(this); |
| 38 AddChildView(prompt_); | 42 AddChildView(prompt_); |
| 43 | |
| 44 UpdateEntries(); | |
| 39 } | 45 } |
| 40 ~QuickLaunchUI() override {} | 46 ~QuickLaunchUI() override {} |
| 41 | 47 |
| 42 private: | 48 private: |
| 43 // Overridden from views::WidgetDelegate: | 49 // Overridden from views::WidgetDelegate: |
| 44 views::View* GetContentsView() override { return this; } | 50 views::View* GetContentsView() override { return this; } |
| 45 base::string16 GetWindowTitle() const override { | 51 base::string16 GetWindowTitle() const override { |
| 46 // TODO(beng): use resources. | 52 // TODO(beng): use resources. |
| 47 return base::ASCIIToUTF16("QuickLaunch"); | 53 return base::ASCIIToUTF16("QuickLaunch"); |
| 48 } | 54 } |
| 49 | 55 |
| 50 // Overridden from views::View: | 56 // Overridden from views::View: |
| 51 void Layout() override { | 57 void Layout() override { |
| 52 gfx::Rect bounds = GetLocalBounds(); | 58 gfx::Rect bounds = GetLocalBounds(); |
| 53 bounds.Inset(5, 5); | 59 bounds.Inset(5, 5); |
| 54 prompt_->SetBoundsRect(bounds); | 60 prompt_->SetBoundsRect(bounds); |
| 55 } | 61 } |
| 56 gfx::Size GetPreferredSize() const override { | 62 gfx::Size GetPreferredSize() const override { |
| 57 gfx::Size ps = prompt_->GetPreferredSize(); | 63 gfx::Size ps = prompt_->GetPreferredSize(); |
| 58 ps.Enlarge(500, 10); | 64 ps.Enlarge(500, 10); |
| 59 return ps; | 65 return ps; |
| 60 } | 66 } |
| 61 | 67 |
| 62 // Overridden from views::TextFieldController: | 68 // Overridden from views::TextFieldController: |
| 63 bool HandleKeyEvent(views::Textfield* sender, | 69 bool HandleKeyEvent(views::Textfield* sender, |
| 64 const ui::KeyEvent& key_event) override { | 70 const ui::KeyEvent& key_event) override { |
| 65 if (key_event.key_code() == ui::VKEY_RETURN) { | 71 suggestion_rejected_ = false; |
| 66 std::string url = Canonicalize(prompt_->text()); | 72 switch (key_event.key_code()) { |
| 67 connections_.push_back(connector_->Connect(url)); | 73 case ui::VKEY_RETURN: { |
|
sky
2016/03/31 17:29:32
nit: run git cl format as your indentation is off.
| |
| 68 prompt_->SetText(base::string16()); | 74 std::string url = Canonicalize(prompt_->text()); |
| 75 connections_.push_back(connector_->Connect(url)); | |
| 76 prompt_->SetText(base::string16()); | |
| 77 UpdateEntries(); | |
| 78 } | |
| 79 break; | |
| 80 case ui::VKEY_BACK: | |
| 81 case ui::VKEY_DELETE: | |
| 82 // The user didn't like our suggestion, don't make another until they | |
| 83 // type another character. | |
| 84 suggestion_rejected_ = true; | |
| 85 break; | |
| 86 default: | |
| 87 break; | |
| 69 } | 88 } |
| 70 return false; | 89 return false; |
| 71 } | 90 } |
| 91 void ContentsChanged(views::Textfield* sender, | |
| 92 const base::string16& new_contents) override { | |
| 93 // Don't keep making a suggestion if the user didn't like what we offered. | |
| 94 if (suggestion_rejected_) | |
| 95 return; | |
| 96 | |
| 97 // TODO(beng): it'd be nice if we persisted some history/scoring here. | |
| 98 for (const auto& name : names_) { | |
| 99 if (base::StartsWith(name, new_contents, | |
| 100 base::CompareCase::INSENSITIVE_ASCII)) { | |
| 101 base::string16 suffix = name; | |
| 102 base::ReplaceSubstringsAfterOffset(&suffix, 0, new_contents, | |
| 103 base::string16()); | |
| 104 gfx::Range range(new_contents.size(), name.size()); | |
| 105 prompt_->SetText(name); | |
| 106 prompt_->SelectRange(range); | |
| 107 break; | |
| 108 } | |
| 109 } | |
| 110 } | |
| 72 | 111 |
| 73 std::string Canonicalize(const base::string16& input) const { | 112 std::string Canonicalize(const base::string16& input) const { |
| 74 base::string16 working; | 113 base::string16 working; |
| 75 base::TrimWhitespace(input, base::TRIM_ALL, &working); | 114 base::TrimWhitespace(input, base::TRIM_ALL, &working); |
| 76 GURL url(working); | 115 GURL url(working); |
| 77 if (url.scheme() != "mojo" && url.scheme() != "exe") | 116 if (url.scheme() != "mojo" && url.scheme() != "exe") |
| 78 working = base::ASCIIToUTF16("mojo:") + working; | 117 working = base::ASCIIToUTF16("mojo:") + working; |
| 79 return base::UTF16ToUTF8(working); | 118 return base::UTF16ToUTF8(working); |
| 80 } | 119 } |
| 81 | 120 |
| 121 void UpdateEntries() { | |
| 122 catalog_->GetEntries(nullptr, | |
| 123 base::Bind(&QuickLaunchUI::OnGotCatalogEntries, | |
| 124 base::Unretained(this))); | |
| 125 } | |
| 126 | |
| 127 void OnGotCatalogEntries( | |
| 128 mojo::Map<mojo::String, catalog::mojom::CatalogEntryPtr> entries) { | |
| 129 for (const auto& entry : entries) | |
| 130 names_.insert(base::UTF8ToUTF16(entry.first.get())); | |
| 131 } | |
| 132 | |
| 82 mojo::Connector* connector_; | 133 mojo::Connector* connector_; |
| 83 views::Textfield* prompt_; | 134 views::Textfield* prompt_; |
| 84 std::vector<scoped_ptr<mojo::Connection>> connections_; | 135 std::vector<scoped_ptr<mojo::Connection>> connections_; |
| 136 catalog::mojom::CatalogPtr catalog_; | |
| 137 std::set<base::string16> names_; | |
|
sky
2016/03/31 17:29:32
names_ is rather vague, app_names_?
| |
| 138 bool suggestion_rejected_ = false; | |
| 85 | 139 |
| 86 DISALLOW_COPY_AND_ASSIGN(QuickLaunchUI); | 140 DISALLOW_COPY_AND_ASSIGN(QuickLaunchUI); |
| 87 }; | 141 }; |
| 88 | 142 |
| 89 QuickLaunchApplication::QuickLaunchApplication() {} | 143 QuickLaunchApplication::QuickLaunchApplication() {} |
| 90 QuickLaunchApplication::~QuickLaunchApplication() {} | 144 QuickLaunchApplication::~QuickLaunchApplication() {} |
| 91 | 145 |
| 92 void QuickLaunchApplication::Initialize(mojo::Connector* connector, | 146 void QuickLaunchApplication::Initialize(mojo::Connector* connector, |
| 93 const mojo::Identity& identity, | 147 const mojo::Identity& identity, |
| 94 uint32_t id) { | 148 uint32_t id) { |
| 95 tracing_.Initialize(connector, identity.name()); | 149 tracing_.Initialize(connector, identity.name()); |
| 96 | 150 |
| 97 aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); | 151 aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); |
| 98 views::WindowManagerConnection::Create(connector); | 152 views::WindowManagerConnection::Create(connector); |
| 99 | 153 |
| 154 catalog::mojom::CatalogPtr catalog; | |
| 155 connector->ConnectToInterface("mojo:catalog", &catalog); | |
| 156 | |
| 100 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds( | 157 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds( |
| 101 new QuickLaunchUI(connector), nullptr, gfx::Rect(10, 640, 0, 0)); | 158 new QuickLaunchUI(connector, std::move(catalog)), nullptr, |
| 159 gfx::Rect(10, 640, 0, 0)); | |
| 102 window->Show(); | 160 window->Show(); |
| 103 } | 161 } |
| 104 | 162 |
| 105 bool QuickLaunchApplication::AcceptConnection(mojo::Connection* connection) { | |
| 106 return true; | |
| 107 } | |
| 108 | |
| 109 } // namespace quick_launch | 163 } // namespace quick_launch |
| 110 } // namespace mash | 164 } // namespace mash |
| OLD | NEW |