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, catalog::mojom::CatalogPtr catalog) |
35 : connector_(connector), prompt_(new views::Textfield) { | 36 : connector_(connector), |
| 37 prompt_(new views::Textfield), |
| 38 catalog_(std::move(catalog)) { |
36 set_background(views::Background::CreateStandardPanelBackground()); | 39 set_background(views::Background::CreateStandardPanelBackground()); |
37 prompt_->set_controller(this); | 40 prompt_->set_controller(this); |
38 AddChildView(prompt_); | 41 AddChildView(prompt_); |
| 42 |
| 43 UpdateEntries(); |
39 } | 44 } |
40 ~QuickLaunchUI() override {} | 45 ~QuickLaunchUI() override {} |
41 | 46 |
42 private: | 47 private: |
43 // Overridden from views::WidgetDelegate: | 48 // Overridden from views::WidgetDelegate: |
44 views::View* GetContentsView() override { return this; } | 49 views::View* GetContentsView() override { return this; } |
45 base::string16 GetWindowTitle() const override { | 50 base::string16 GetWindowTitle() const override { |
46 // TODO(beng): use resources. | 51 // TODO(beng): use resources. |
47 return base::ASCIIToUTF16("QuickLaunch"); | 52 return base::ASCIIToUTF16("QuickLaunch"); |
48 } | 53 } |
49 | 54 |
50 // Overridden from views::View: | 55 // Overridden from views::View: |
51 void Layout() override { | 56 void Layout() override { |
52 gfx::Rect bounds = GetLocalBounds(); | 57 gfx::Rect bounds = GetLocalBounds(); |
53 bounds.Inset(5, 5); | 58 bounds.Inset(5, 5); |
54 prompt_->SetBoundsRect(bounds); | 59 prompt_->SetBoundsRect(bounds); |
55 } | 60 } |
56 gfx::Size GetPreferredSize() const override { | 61 gfx::Size GetPreferredSize() const override { |
57 gfx::Size ps = prompt_->GetPreferredSize(); | 62 gfx::Size ps = prompt_->GetPreferredSize(); |
58 ps.Enlarge(500, 10); | 63 ps.Enlarge(500, 10); |
59 return ps; | 64 return ps; |
60 } | 65 } |
61 | 66 |
62 // Overridden from views::TextFieldController: | 67 // Overridden from views::TextFieldController: |
63 bool HandleKeyEvent(views::Textfield* sender, | 68 bool HandleKeyEvent(views::Textfield* sender, |
64 const ui::KeyEvent& key_event) override { | 69 const ui::KeyEvent& key_event) override { |
65 if (key_event.key_code() == ui::VKEY_RETURN) { | 70 suggestion_rejected_ = false; |
66 std::string url = Canonicalize(prompt_->text()); | 71 switch (key_event.key_code()) { |
67 connections_.push_back(connector_->Connect(url)); | 72 case ui::VKEY_RETURN: { |
68 prompt_->SetText(base::string16()); | 73 std::string url = Canonicalize(prompt_->text()); |
| 74 connections_.push_back(connector_->Connect(url)); |
| 75 prompt_->SetText(base::string16()); |
| 76 UpdateEntries(); |
| 77 } break; |
| 78 case ui::VKEY_BACK: |
| 79 case ui::VKEY_DELETE: |
| 80 // The user didn't like our suggestion, don't make another until they |
| 81 // type another character. |
| 82 suggestion_rejected_ = true; |
| 83 break; |
| 84 default: |
| 85 break; |
69 } | 86 } |
70 return false; | 87 return false; |
71 } | 88 } |
| 89 void ContentsChanged(views::Textfield* sender, |
| 90 const base::string16& new_contents) override { |
| 91 // Don't keep making a suggestion if the user didn't like what we offered. |
| 92 if (suggestion_rejected_) |
| 93 return; |
| 94 |
| 95 // TODO(beng): it'd be nice if we persisted some history/scoring here. |
| 96 for (const auto& name : app_names_) { |
| 97 if (base::StartsWith(name, new_contents, |
| 98 base::CompareCase::INSENSITIVE_ASCII)) { |
| 99 base::string16 suffix = name; |
| 100 base::ReplaceSubstringsAfterOffset(&suffix, 0, new_contents, |
| 101 base::string16()); |
| 102 gfx::Range range(new_contents.size(), name.size()); |
| 103 prompt_->SetText(name); |
| 104 prompt_->SelectRange(range); |
| 105 break; |
| 106 } |
| 107 } |
| 108 } |
72 | 109 |
73 std::string Canonicalize(const base::string16& input) const { | 110 std::string Canonicalize(const base::string16& input) const { |
74 base::string16 working; | 111 base::string16 working; |
75 base::TrimWhitespace(input, base::TRIM_ALL, &working); | 112 base::TrimWhitespace(input, base::TRIM_ALL, &working); |
76 GURL url(working); | 113 GURL url(working); |
77 if (url.scheme() != "mojo" && url.scheme() != "exe") | 114 if (url.scheme() != "mojo" && url.scheme() != "exe") |
78 working = base::ASCIIToUTF16("mojo:") + working; | 115 working = base::ASCIIToUTF16("mojo:") + working; |
79 return base::UTF16ToUTF8(working); | 116 return base::UTF16ToUTF8(working); |
80 } | 117 } |
81 | 118 |
| 119 void UpdateEntries() { |
| 120 catalog_->GetEntries(nullptr, |
| 121 base::Bind(&QuickLaunchUI::OnGotCatalogEntries, |
| 122 base::Unretained(this))); |
| 123 } |
| 124 |
| 125 void OnGotCatalogEntries( |
| 126 mojo::Map<mojo::String, catalog::mojom::CatalogEntryPtr> entries) { |
| 127 for (const auto& entry : entries) |
| 128 app_names_.insert(base::UTF8ToUTF16(entry.first.get())); |
| 129 } |
| 130 |
82 mojo::Connector* connector_; | 131 mojo::Connector* connector_; |
83 views::Textfield* prompt_; | 132 views::Textfield* prompt_; |
84 std::vector<scoped_ptr<mojo::Connection>> connections_; | 133 std::vector<scoped_ptr<mojo::Connection>> connections_; |
| 134 catalog::mojom::CatalogPtr catalog_; |
| 135 std::set<base::string16> app_names_; |
| 136 bool suggestion_rejected_ = false; |
85 | 137 |
86 DISALLOW_COPY_AND_ASSIGN(QuickLaunchUI); | 138 DISALLOW_COPY_AND_ASSIGN(QuickLaunchUI); |
87 }; | 139 }; |
88 | 140 |
89 QuickLaunchApplication::QuickLaunchApplication() {} | 141 QuickLaunchApplication::QuickLaunchApplication() {} |
90 QuickLaunchApplication::~QuickLaunchApplication() {} | 142 QuickLaunchApplication::~QuickLaunchApplication() {} |
91 | 143 |
92 void QuickLaunchApplication::Initialize(mojo::Connector* connector, | 144 void QuickLaunchApplication::Initialize(mojo::Connector* connector, |
93 const mojo::Identity& identity, | 145 const mojo::Identity& identity, |
94 uint32_t id) { | 146 uint32_t id) { |
95 tracing_.Initialize(connector, identity.name()); | 147 tracing_.Initialize(connector, identity.name()); |
96 | 148 |
97 aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); | 149 aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); |
98 views::WindowManagerConnection::Create(connector); | 150 views::WindowManagerConnection::Create(connector); |
99 | 151 |
| 152 catalog::mojom::CatalogPtr catalog; |
| 153 connector->ConnectToInterface("mojo:catalog", &catalog); |
| 154 |
100 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds( | 155 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds( |
101 new QuickLaunchUI(connector), nullptr, gfx::Rect(10, 640, 0, 0)); | 156 new QuickLaunchUI(connector, std::move(catalog)), nullptr, |
| 157 gfx::Rect(10, 640, 0, 0)); |
102 window->Show(); | 158 window->Show(); |
103 } | 159 } |
104 | 160 |
105 bool QuickLaunchApplication::AcceptConnection(mojo::Connection* connection) { | |
106 return true; | |
107 } | |
108 | |
109 } // namespace quick_launch | 161 } // namespace quick_launch |
110 } // namespace mash | 162 } // namespace mash |
OLD | NEW |