Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: mash/browser/browser.cc

Issue 1986003002: Revert of Add a basic browser to mash that uses the navigation service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mash/browser/browser.h ('k') | mash/browser/main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mash/browser/browser.h"
6
7 #include "base/macros.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/timer/timer.h"
14 #include "components/mus/public/cpp/window.h"
15 #include "components/mus/public/cpp/window_tree_connection.h"
16 #include "mash/public/interfaces/launchable.mojom.h"
17 #include "mojo/converters/geometry/geometry_type_converters.h"
18 #include "mojo/public/c/system/main.h"
19 #include "services/navigation/public/interfaces/view.mojom.h"
20 #include "services/shell/public/cpp/application_runner.h"
21 #include "services/shell/public/cpp/connector.h"
22 #include "services/shell/public/cpp/shell_client.h"
23 #include "services/tracing/public/cpp/tracing_impl.h"
24 #include "ui/aura/mus/mus_util.h"
25 #include "ui/gfx/canvas.h"
26 #include "ui/gfx/paint_throbber.h"
27 #include "ui/gfx/text_constants.h"
28 #include "ui/native_theme/native_theme.h"
29 #include "ui/views/background.h"
30 #include "ui/views/controls/button/label_button.h"
31 #include "ui/views/controls/textfield/textfield.h"
32 #include "ui/views/controls/textfield/textfield_controller.h"
33 #include "ui/views/mus/aura_init.h"
34 #include "ui/views/mus/window_manager_connection.h"
35 #include "ui/views/widget/widget_delegate.h"
36 #include "url/gurl.h"
37
38 namespace mash {
39 namespace browser {
40
41 void EnableButton(views::CustomButton* button, bool enabled) {
42 button->SetState(enabled ? views::Button::STATE_NORMAL
43 : views::Button::STATE_DISABLED);
44 }
45
46 class ProgressBar : public views::View {
47 public:
48 ProgressBar() {}
49 ~ProgressBar() override {}
50
51 void SetProgress(double progress) {
52 progress_ = progress;
53 SchedulePaint();
54 }
55
56 private:
57 void OnPaint(gfx::Canvas* canvas) override {
58 gfx::Rect stroke_rect = GetLocalBounds();
59 stroke_rect.set_y(stroke_rect.bottom() - 1);
60 stroke_rect.set_height(1);
61 canvas->FillRect(stroke_rect, SK_ColorGRAY);
62 if (progress_ != 0.f) {
63 gfx::Rect progress_rect = GetLocalBounds();
64 progress_rect.set_width(progress_rect.width() * progress_);
65 canvas->FillRect(progress_rect, SK_ColorRED);
66 }
67 }
68
69 double progress_ = 0.f;
70
71 DISALLOW_COPY_AND_ASSIGN(ProgressBar);
72 };
73
74 class Throbber : public views::View {
75 public:
76 Throbber() : timer_(false, true), weak_factory_(this) {}
77 ~Throbber() override {}
78
79 void Start() {
80 throbbing_ = true;
81 start_time_ = base::TimeTicks::Now();
82 SchedulePaint();
83 timer_.Start(
84 FROM_HERE, base::TimeDelta::FromMilliseconds(30),
85 base::Bind(&Throbber::SchedulePaint, weak_factory_.GetWeakPtr()));
86 }
87
88 void Stop() {
89 throbbing_ = false;
90 if (timer_.IsRunning())
91 timer_.Stop();
92 SchedulePaint();
93 }
94
95 private:
96 void OnPaint(gfx::Canvas* canvas) override {
97 if (!throbbing_)
98 return;
99
100 gfx::PaintThrobberSpinning(
101 canvas, GetLocalBounds(),
102 GetNativeTheme()->GetSystemColor(
103 ui::NativeTheme::kColorId_ThrobberSpinningColor),
104 base::TimeTicks::Now() - start_time_);
105 }
106
107 bool throbbing_ = false;
108 base::TimeTicks start_time_;
109 base::Timer timer_;
110 base::WeakPtrFactory<Throbber> weak_factory_;
111
112 DISALLOW_COPY_AND_ASSIGN(Throbber);
113 };
114
115 class UI : public views::WidgetDelegateView,
116 public views::ButtonListener,
117 public views::TextfieldController,
118 public navigation::mojom::ViewClient {
119 public:
120 enum class Type { WINDOW, POPUP };
121
122 UI(Browser* browser,
123 Type type,
124 navigation::mojom::ViewPtr view,
125 navigation::mojom::ViewClientRequest request)
126 : browser_(browser),
127 type_(type),
128 back_button_(new views::LabelButton(this, base::ASCIIToUTF16("Back"))),
129 forward_button_(
130 new views::LabelButton(this, base::ASCIIToUTF16("Forward"))),
131 reload_button_(
132 new views::LabelButton(this, base::ASCIIToUTF16("Reload"))),
133 prompt_(new views::Textfield),
134 throbber_(new Throbber),
135 progress_bar_(new ProgressBar),
136 view_(std::move(view)),
137 view_client_binding_(this, std::move(request)) {
138 set_background(views::Background::CreateStandardPanelBackground());
139 prompt_->set_controller(this);
140 back_button_->set_request_focus_on_press(false);
141 forward_button_->set_request_focus_on_press(false);
142 reload_button_->set_request_focus_on_press(false);
143 AddChildView(back_button_);
144 AddChildView(forward_button_);
145 AddChildView(reload_button_);
146 AddChildView(prompt_);
147 AddChildView(throbber_);
148 AddChildView(progress_bar_);
149 }
150 ~UI() override { browser_->RemoveWindow(GetWidget()); }
151
152 void NavigateTo(const GURL& url) { view_->NavigateTo(url); }
153
154 private:
155 // Overridden from views::WidgetDelegate:
156 views::View* GetContentsView() override { return this; }
157 base::string16 GetWindowTitle() const override {
158 // TODO(beng): use resources.
159 if (current_title_.empty())
160 return base::ASCIIToUTF16("Browser");
161 base::string16 format = base::ASCIIToUTF16("%s - Browser");
162 base::ReplaceFirstSubstringAfterOffset(&format, 0, base::ASCIIToUTF16("%s"),
163 current_title_);
164 return format;
165 }
166 bool CanResize() const override { return true; }
167 bool CanMaximize() const override { return true; }
168 bool CanMinimize() const override { return true; }
169
170 // views::ButtonListener:
171 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
172 if (sender == back_button_) {
173 view_->GoBack();
174 } else if (sender == forward_button_) {
175 view_->GoForward();
176 } else if (sender == reload_button_) {
177 if (is_loading_)
178 view_->Stop();
179 else
180 view_->Reload(false);
181 }
182 }
183
184 // Overridden from views::View:
185 void Layout() override {
186 gfx::Rect local_bounds = GetLocalBounds();
187 gfx::Rect bounds = local_bounds;
188 bounds.Inset(5, 5);
189
190 gfx::Size ps = back_button_->GetPreferredSize();
191 back_button_->SetBoundsRect(
192 gfx::Rect(bounds.x(), bounds.y(), ps.width(), ps.height()));
193 ps = forward_button_->GetPreferredSize();
194 forward_button_->SetBoundsRect(gfx::Rect(back_button_->bounds().right() + 5,
195 bounds.y(), ps.width(),
196 ps.height()));
197 ps = reload_button_->GetPreferredSize();
198 reload_button_->SetBoundsRect(
199 gfx::Rect(forward_button_->bounds().right() + 5, bounds.y(), ps.width(),
200 ps.height()));
201
202 ps = prompt_->GetPreferredSize();
203 int prompt_y =
204 bounds.y() + (reload_button_->bounds().height() - ps.height()) / 2;
205 int width =
206 bounds.width() - reload_button_->bounds().right() - ps.height() - 10;
207 prompt_->SetBoundsRect(gfx::Rect(reload_button_->bounds().right() + 5,
208 prompt_y, width, ps.height()));
209 throbber_->SetBoundsRect(gfx::Rect(prompt_->bounds().right() + 5,
210 prompt_->bounds().y(), ps.height(),
211 ps.height()));
212
213 gfx::Rect progress_bar_rect(local_bounds.x(),
214 back_button_->bounds().bottom() + 5,
215 local_bounds.width(), 2);
216 progress_bar_->SetBoundsRect(progress_bar_rect);
217
218 if (content_area_) {
219 int x = local_bounds.x();
220 int y = type_ == Type::POPUP ? 0 : progress_bar_->bounds().bottom();
221 gfx::Point offset(x, y);
222 ConvertPointToWidget(this, &offset);
223 int width = local_bounds.width();
224 int height = local_bounds.height() - y;
225 content_area_->SetBounds(
226 gfx::Rect(offset.x(), offset.y(), width, height));
227 }
228 }
229 void ViewHierarchyChanged(
230 const views::View::ViewHierarchyChangedDetails& details) override {
231 if (details.is_add && GetWidget() && !content_area_) {
232 mus::Window* window = aura::GetMusWindow(GetWidget()->GetNativeWindow());
233 content_area_ = window->connection()->NewWindow(nullptr);
234 window->AddChild(content_area_);
235
236 mus::mojom::WindowTreeClientPtr client;
237 view_->GetWindowTreeClient(GetProxy(&client));
238 content_area_->Embed(std::move(client));
239 }
240 }
241
242 // Overridden from views::TextFieldController:
243 bool HandleKeyEvent(views::Textfield* sender,
244 const ui::KeyEvent& key_event) override {
245 switch (key_event.key_code()) {
246 case ui::VKEY_RETURN: {
247 view_->NavigateTo(GURL(prompt_->text()));
248 } break;
249 default:
250 break;
251 }
252 return false;
253 }
254
255 // navigation::mojom::ViewClient:
256 void LoadingStateChanged(bool is_loading) override {
257 is_loading_ = is_loading;
258 if (is_loading_) {
259 reload_button_->SetText(base::ASCIIToUTF16("Stop"));
260 throbber_->Start();
261 } else {
262 reload_button_->SetText(base::ASCIIToUTF16("Reload"));
263 throbber_->Stop();
264 progress_bar_->SetProgress(0.f);
265 }
266 }
267 void NavigationStateChanged(const GURL& url,
268 const mojo::String& title,
269 bool can_go_back,
270 bool can_go_forward) override {
271 EnableButton(back_button_, can_go_back);
272 EnableButton(forward_button_, can_go_forward);
273 prompt_->SetText(base::UTF8ToUTF16(url.spec()));
274 current_title_ = base::UTF8ToUTF16(title.get());
275 GetWidget()->UpdateWindowTitle();
276 }
277 void LoadProgressChanged(double progress) override {
278 progress_bar_->SetProgress(progress);
279 }
280 void ViewCreated(navigation::mojom::ViewPtr view,
281 navigation::mojom::ViewClientRequest request,
282 bool is_popup,
283 mojo::RectPtr initial_rect,
284 bool user_gesture) override {
285 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
286 new UI(browser_, is_popup ? UI::Type::POPUP : UI::Type::WINDOW,
287 std::move(view), std::move(request)),
288 nullptr, initial_rect.To<gfx::Rect>());
289 window->Show();
290 browser_->AddWindow(window);
291 }
292 void Close() override { GetWidget()->Close(); }
293
294 Browser* browser_;
295
296 Type type_;
297
298 views::LabelButton* back_button_;
299 views::LabelButton* forward_button_;
300 views::LabelButton* reload_button_;
301 views::Textfield* prompt_;
302 Throbber* throbber_;
303 ProgressBar* progress_bar_;
304
305 mus::Window* content_area_ = nullptr;
306
307 navigation::mojom::ViewPtr view_;
308 mojo::Binding<navigation::mojom::ViewClient> view_client_binding_;
309
310 bool is_loading_ = false;
311 base::string16 current_title_;
312
313 DISALLOW_COPY_AND_ASSIGN(UI);
314 };
315
316 Browser::Browser() {}
317 Browser::~Browser() {}
318
319 void Browser::AddWindow(views::Widget* window) {
320 windows_.push_back(window);
321 }
322
323 void Browser::RemoveWindow(views::Widget* window) {
324 auto it = std::find(windows_.begin(), windows_.end(), window);
325 DCHECK(it != windows_.end());
326 windows_.erase(it);
327 if (windows_.empty())
328 base::MessageLoop::current()->QuitWhenIdle();
329 }
330
331 void Browser::Initialize(shell::Connector* connector,
332 const shell::Identity& identity,
333 uint32_t id) {
334 connector_ = connector;
335 tracing_.Initialize(connector, identity.name());
336
337 aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
338 views::WindowManagerConnection::Create(connector, identity);
339 }
340
341 bool Browser::AcceptConnection(shell::Connection* connection) {
342 connection->AddInterface<mojom::Launchable>(this);
343 return true;
344 }
345
346 void Browser::Launch(uint32_t what, mojom::LaunchMode how) {
347 bool reuse =
348 how == mojom::LaunchMode::REUSE || how == mojom::LaunchMode::DEFAULT;
349 if (reuse && !windows_.empty()) {
350 windows_.back()->Activate();
351 return;
352 }
353
354 navigation::mojom::ViewFactoryPtr view_factory;
355 connector_->ConnectToInterface("exe:navigation", &view_factory);
356 navigation::mojom::ViewPtr view;
357 navigation::mojom::ViewClientPtr view_client;
358 navigation::mojom::ViewClientRequest view_client_request =
359 GetProxy(&view_client);
360 view_factory->CreateView(std::move(view_client), GetProxy(&view));
361 UI* ui = new UI(this, UI::Type::WINDOW, std::move(view),
362 std::move(view_client_request));
363 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
364 ui, nullptr, gfx::Rect(10, 10, 1024, 600));
365 ui->NavigateTo(GURL("http://www.google.com/"));
366 window->Show();
367 AddWindow(window);
368 }
369
370 void Browser::Create(shell::Connection* connection,
371 mojom::LaunchableRequest request) {
372 bindings_.AddBinding(this, std::move(request));
373 }
374
375 } // namespace browser
376 } // namespace mash
OLDNEW
« no previous file with comments | « mash/browser/browser.h ('k') | mash/browser/main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698