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

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

Issue 2901613002: Remove navigation_service_unittests, along with the service itself. (Closed)
Patch Set: Fix isolate files? Created 3 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/debug_view.h » ('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/ptr_util.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/timer/timer.h"
16 #include "content/public/common/service_names.mojom.h"
17 #include "mash/browser/debug_view.h"
18 #include "mash/public/interfaces/launchable.mojom.h"
19 #include "services/navigation/public/cpp/view.h"
20 #include "services/navigation/public/cpp/view_delegate.h"
21 #include "services/navigation/public/cpp/view_observer.h"
22 #include "services/navigation/public/interfaces/view.mojom.h"
23 #include "services/service_manager/public/c/main.h"
24 #include "services/service_manager/public/cpp/connector.h"
25 #include "services/service_manager/public/cpp/service.h"
26 #include "services/service_manager/public/cpp/service_context.h"
27 #include "services/service_manager/public/cpp/service_runner.h"
28 #include "ui/aura/window.h"
29 #include "ui/base/models/menu_model.h"
30 #include "ui/gfx/canvas.h"
31 #include "ui/gfx/paint_throbber.h"
32 #include "ui/gfx/text_constants.h"
33 #include "ui/native_theme/native_theme.h"
34 #include "ui/views/background.h"
35 #include "ui/views/controls/button/label_button.h"
36 #include "ui/views/controls/menu/menu_model_adapter.h"
37 #include "ui/views/controls/menu/menu_runner.h"
38 #include "ui/views/controls/textfield/textfield.h"
39 #include "ui/views/controls/textfield/textfield_controller.h"
40 #include "ui/views/layout/box_layout.h"
41 #include "ui/views/mus/aura_init.h"
42 #include "ui/views/widget/widget.h"
43 #include "ui/views/widget/widget_delegate.h"
44 #include "url/gurl.h"
45
46 namespace mash {
47 namespace browser {
48
49 void EnableButton(views::CustomButton* button, bool enabled) {
50 button->SetState(enabled ? views::Button::STATE_NORMAL
51 : views::Button::STATE_DISABLED);
52 }
53
54 class Tab;
55
56 class TabStripObserver {
57 public:
58 virtual void OnTabAdded(Tab* added) {}
59 virtual void OnTabRemoved(Tab* removed) {}
60 virtual void OnTabSelected(Tab* selected) {}
61 };
62
63 class Tab : public views::LabelButton,
64 public navigation::ViewObserver,
65 public TabStripObserver {
66 public:
67 class Background : public views::Background {
68 public:
69 explicit Background(Tab* tab) : tab_(tab) {}
70 ~Background() override {}
71
72 private:
73 // views::Background:
74 void Paint(gfx::Canvas* canvas, views::View* view) const override {
75 DCHECK_EQ(view, tab_);
76 SkColor bg = tab_->selected() ? SK_ColorGRAY : SK_ColorLTGRAY;
77 gfx::Rect lb = view->GetLocalBounds();
78 canvas->FillRect(lb, bg);
79 if (!tab_->selected()) {
80 lb.set_y(lb.bottom() - 1);
81 lb.set_height(1);
82 canvas->FillRect(lb, SK_ColorGRAY);
83 }
84 }
85
86 Tab* tab_;
87
88 DISALLOW_COPY_AND_ASSIGN(Background);
89 };
90
91 Tab(std::unique_ptr<navigation::View> view,
92 views::ButtonListener* listener)
93 : views::LabelButton(listener, base::ASCIIToUTF16("Blank")),
94 view_(std::move(view)) {
95 view_->AddObserver(this);
96 set_background(new Background(this));
97 }
98 ~Tab() override {
99 view_->RemoveObserver(this);
100 }
101
102 bool selected() const { return selected_; }
103
104 aura::Window* window() { return window_; }
105 void SetWindow(aura::Window* window) {
106 window_ = window;
107 if (selected_)
108 window_->Show();
109 else
110 window_->Hide();
111 view_->EmbedInWindow(window_);
112 }
113 navigation::View* view() { return view_.get(); }
114
115 private:
116 // views::View:
117 gfx::Size GetPreferredSize() const override {
118 gfx::Size ps = views::LabelButton::GetPreferredSize();
119 ps.set_width(180);
120 return ps;
121 }
122
123 // navigation::ViewObserver:
124 void NavigationStateChanged(navigation::View* view) override {
125 if (!view->title().empty())
126 SetText(view->title());
127 }
128
129 // TabStripObserver:
130 void OnTabSelected(Tab* selected) override {
131 selected_ = selected == this;
132 SetTextColor(views::Button::STATE_NORMAL,
133 selected_ ? SK_ColorWHITE : SK_ColorBLACK);
134 SetTextColor(views::Button::STATE_HOVERED,
135 selected_ ? SK_ColorWHITE : SK_ColorBLACK);
136 SetTextColor(views::Button::STATE_PRESSED,
137 selected_ ? SK_ColorWHITE : SK_ColorBLACK);
138 if (window_) {
139 if (selected_)
140 window_->Show();
141 else
142 window_->Hide();
143 }
144 }
145
146 aura::Window* window_ = nullptr;
147 std::unique_ptr<navigation::View> view_;
148 bool selected_ = false;
149
150 DISALLOW_COPY_AND_ASSIGN(Tab);
151 };
152
153 class TabStrip : public views::View,
154 public views::ButtonListener {
155 public:
156 class Delegate {
157 public:
158 virtual void NewTab() = 0;
159 };
160
161 explicit TabStrip(Delegate* delegate)
162 : delegate_(delegate),
163 tab_container_(new views::View),
164 new_tab_button_(
165 new views::LabelButton(this, base::ASCIIToUTF16("+"))) {
166 views::BoxLayout* layout =
167 new views::BoxLayout(views::BoxLayout::kHorizontal, 5, 0, 0);
168 layout->set_main_axis_alignment(
169 views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
170 layout->set_cross_axis_alignment(
171 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
172 layout->SetDefaultFlex(0);
173 SetLayoutManager(layout);
174
175 views::BoxLayout* tab_container_layout =
176 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
177 tab_container_layout->set_main_axis_alignment(
178 views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
179 tab_container_layout->set_cross_axis_alignment(
180 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
181 tab_container_layout->SetDefaultFlex(0);
182 tab_container_->SetLayoutManager(tab_container_layout);
183 AddChildView(tab_container_);
184 layout->SetFlexForView(tab_container_, 1);
185 AddChildView(new_tab_button_);
186 }
187 ~TabStrip() override {
188 for (auto* tab : tabs_)
189 RemoveObserver(tab);
190 }
191
192 void SetContainerWindow(aura::Window* container) {
193 DCHECK(!container_);
194 container_ = container;
195 for (auto* tab : tabs_) {
196 aura::Window* window = new aura::Window(nullptr);
197 window->Init(ui::LAYER_NOT_DRAWN);
198 container_->AddChild(window);
199 tab->SetWindow(window);
200 }
201 }
202
203 void AddTab(std::unique_ptr<navigation::View> view) {
204 selected_index_ = static_cast<int>(tabs_.size());
205 Tab* tab = new Tab(std::move(view), this);
206 // We won't have a WindowTree until we're added to a view hierarchy.
207 if (container_) {
208 aura::Window* window = new aura::Window(nullptr);
209 window->Init(ui::LAYER_NOT_DRAWN);
210 container_->AddChild(window);
211 tab->SetWindow(window);
212 }
213 AddObserver(tab);
214 tabs_.push_back(tab);
215 tab_container_->AddChildView(tab);
216 for (auto& observer : observers_)
217 observer.OnTabAdded(tab);
218 SelectTab(tab);
219 }
220
221 void CloseTabForView(navigation::View* view) {
222 for (auto it = tabs_.begin(); it != tabs_.end(); ++it) {
223 Tab* tab = *it;
224 if (tab->view() == view) {
225 CloseTab(tab);
226 break;
227 }
228 }
229 }
230
231 void CloseTab(Tab* tab) {
232 auto it = std::find(tabs_.begin(), tabs_.end(), tab);
233 int tab_index = static_cast<int>(it - tabs_.begin());
234 if (tab_index < selected_index_)
235 --selected_index_;
236 DCHECK(it != tabs_.end());
237 tabs_.erase(it);
238 RemoveObserver(tab);
239 tab_container_->RemoveChildView(tab);
240 if (tab->selected()) {
241 int next_selected_index = selected_index_;
242 if (selected_index_ == static_cast<int>(tabs_.size()))
243 --next_selected_index;
244 if (next_selected_index >= 0)
245 SelectTab(tabs_[next_selected_index]);
246 }
247 Layout();
248 for (auto& observer : observers_)
249 observer.OnTabRemoved(tab);
250 delete tab;
251 }
252
253 bool empty() const { return tabs_.empty(); }
254
255 void SelectTab(Tab* tab) {
256 auto it = std::find(tabs_.begin(), tabs_.end(), tab);
257 DCHECK(it != tabs_.end());
258 selected_index_ = it - tabs_.begin();
259 for (auto& observer : observers_)
260 observer.OnTabSelected(tab);
261 }
262 Tab* selected_tab() {
263 return selected_index_ != -1 ? tabs_[selected_index_] : nullptr;
264 }
265
266 void AddObserver(TabStripObserver* observer) {
267 observers_.AddObserver(observer);
268 }
269 void RemoveObserver(TabStripObserver* observer) {
270 observers_.RemoveObserver(observer);
271 }
272
273 private:
274 // views::View:
275 void OnPaint(gfx::Canvas* canvas) override {
276 gfx::Rect lb = GetLocalBounds();
277 lb.set_y(lb.bottom() - 1);
278 lb.set_height(1);
279 canvas->FillRect(lb, SK_ColorGRAY);
280 }
281
282 // views::ButtonListener:
283 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
284 auto it = std::find(tabs_.begin(), tabs_.end(), sender);
285 if (it != tabs_.end()) {
286 if (event.IsControlDown())
287 CloseTab(*it);
288 else
289 SelectTab(*it);
290 }
291 else if (sender == new_tab_button_ && delegate_)
292 delegate_->NewTab();
293 }
294
295 Delegate* delegate_;
296 views::View* tab_container_;
297 views::LabelButton* new_tab_button_;
298 std::vector<Tab*> tabs_;
299 int selected_index_ = -1;
300 base::ObserverList<TabStripObserver> observers_;
301 aura::Window* container_ = nullptr;
302
303 DISALLOW_COPY_AND_ASSIGN(TabStrip);
304 };
305
306 class NavMenuModel : public ui::MenuModel {
307 public:
308 class Delegate {
309 public:
310 virtual void NavigateToOffset(int offset) = 0;
311 };
312
313 NavMenuModel(const std::vector<navigation::NavigationListItem>& entries,
314 Delegate* delegate)
315 : navigation_delegate_(delegate), entries_(entries) {}
316 ~NavMenuModel() override {}
317
318 private:
319 bool HasIcons() const override { return false; }
320 int GetItemCount() const override {
321 return static_cast<int>(entries_.size());
322 }
323 ui::MenuModel::ItemType GetTypeAt(int index) const override {
324 return ui::MenuModel::TYPE_COMMAND;
325 }
326 ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override {
327 return ui::NORMAL_SEPARATOR;
328 }
329 int GetCommandIdAt(int index) const override {
330 return index;
331 }
332 base::string16 GetLabelAt(int index) const override {
333 return entries_[index].title;
334 }
335 base::string16 GetSublabelAt(int index) const override {
336 return base::string16();
337 }
338 base::string16 GetMinorTextAt(int index) const override {
339 return base::string16();
340 }
341 bool IsItemDynamicAt(int index) const override { return false; }
342 bool GetAcceleratorAt(int index,
343 ui::Accelerator* accelerator) const override {
344 return false;
345 }
346 bool IsItemCheckedAt(int index) const override { return false; }
347 int GetGroupIdAt(int index) const override { return -1; }
348 bool GetIconAt(int index, gfx::Image* icon) override { return false; }
349 ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
350 return nullptr;
351 }
352 bool IsEnabledAt(int index) const override { return true; }
353 bool IsVisibleAt(int index) const override { return true; }
354 ui::MenuModel* GetSubmenuModelAt(int index) const override { return nullptr; }
355 void HighlightChangedTo(int index) override {}
356 void ActivatedAt(int index) override {
357 ActivatedAt(index, 0);
358 }
359 void ActivatedAt(int index, int event_flags) override {
360 navigation_delegate_->NavigateToOffset(entries_[index].offset);
361 }
362 void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) override {
363 delegate_ = delegate;
364 }
365 ui::MenuModelDelegate* GetMenuModelDelegate() const override {
366 return delegate_;
367 }
368
369 ui::MenuModelDelegate* delegate_ = nullptr;
370 Delegate* navigation_delegate_;
371 std::vector<navigation::NavigationListItem> entries_;
372
373 DISALLOW_COPY_AND_ASSIGN(NavMenuModel);
374 };
375
376 class NavButton : public views::LabelButton {
377 public:
378 enum class Type {
379 BACK,
380 FORWARD
381 };
382
383 class ModelProvider {
384 public:
385 virtual std::unique_ptr<ui::MenuModel> CreateMenuModel(Type type) = 0;
386 };
387
388 NavButton(Type type,
389 ModelProvider* model_provider,
390 views::ButtonListener* listener,
391 const base::string16& label)
392 : views::LabelButton(listener, label),
393 type_(type),
394 model_provider_(model_provider),
395 show_menu_factory_(this) {}
396 ~NavButton() override {}
397
398 private:
399 // views::LabelButton overrides:
400 bool OnMousePressed(const ui::MouseEvent& event) override {
401 if (IsTriggerableEvent(event) && enabled() &&
402 HitTestPoint(event.location())) {
403 y_pos_on_lbuttondown_ = event.y();
404 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
405 FROM_HERE,
406 base::Bind(&NavButton::ShowMenu, show_menu_factory_.GetWeakPtr(),
407 ui::GetMenuSourceTypeForEvent(event)),
408 base::TimeDelta::FromMilliseconds(500));
409 }
410 return LabelButton::OnMousePressed(event);
411 }
412 bool OnMouseDragged(const ui::MouseEvent& event) override {
413 bool result = LabelButton::OnMouseDragged(event);
414 if (show_menu_factory_.HasWeakPtrs()) {
415 if (event.y() > y_pos_on_lbuttondown_ + GetHorizontalDragThreshold()) {
416 show_menu_factory_.InvalidateWeakPtrs();
417 ShowMenu(ui::GetMenuSourceTypeForEvent(event));
418 }
419 }
420 return result;
421 }
422 void OnMouseReleased(const ui::MouseEvent& event) override {
423 if (IsTriggerableEvent(event))
424 show_menu_factory_.InvalidateWeakPtrs();
425 LabelButton::OnMouseReleased(event);
426 }
427
428 void ShowMenu(ui::MenuSourceType source_type) {
429 gfx::Rect local = GetLocalBounds();
430 gfx::Point menu_position(local.origin());
431 menu_position.Offset(0, local.height() - 1);
432 View::ConvertPointToScreen(this, &menu_position);
433
434 model_ = model_provider_->CreateMenuModel(type_);
435 menu_model_adapter_.reset(new views::MenuModelAdapter(
436 model_.get(),
437 base::Bind(&NavButton::OnMenuClosed, base::Unretained(this))));
438 menu_model_adapter_->set_triggerable_event_flags(triggerable_event_flags());
439 menu_runner_.reset(new views::MenuRunner(menu_model_adapter_->CreateMenu(),
440 views::MenuRunner::HAS_MNEMONICS));
441 menu_runner_->RunMenuAt(GetWidget(), nullptr,
442 gfx::Rect(menu_position, gfx::Size(0, 0)),
443 views::MENU_ANCHOR_TOPLEFT, source_type);
444 }
445
446 void OnMenuClosed() {
447 SetMouseHandler(nullptr);
448 model_.reset();
449 menu_runner_.reset();
450 menu_model_adapter_.reset();
451 }
452
453 Type type_;
454 ModelProvider* model_provider_;
455 int y_pos_on_lbuttondown_ = 0;
456 std::unique_ptr<ui::MenuModel> model_;
457 std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_;
458 std::unique_ptr<views::MenuRunner> menu_runner_;
459 base::WeakPtrFactory<NavButton> show_menu_factory_;
460
461 DISALLOW_COPY_AND_ASSIGN(NavButton);
462 };
463
464 class ProgressBar : public views::View {
465 public:
466 ProgressBar() {}
467 ~ProgressBar() override {}
468
469 void SetProgress(double progress) {
470 progress_ = progress;
471 SchedulePaint();
472 }
473
474 private:
475 void OnPaint(gfx::Canvas* canvas) override {
476 gfx::Rect stroke_rect = GetLocalBounds();
477 stroke_rect.set_y(stroke_rect.bottom() - 1);
478 stroke_rect.set_height(1);
479 canvas->FillRect(stroke_rect, SK_ColorGRAY);
480 if (progress_ != 0.f) {
481 gfx::Rect progress_rect = GetLocalBounds();
482 progress_rect.set_width(progress_rect.width() * progress_);
483 canvas->FillRect(progress_rect, SK_ColorRED);
484 }
485 }
486
487 double progress_ = 0.f;
488
489 DISALLOW_COPY_AND_ASSIGN(ProgressBar);
490 };
491
492 class Throbber : public views::View {
493 public:
494 Throbber() : timer_(false, true), weak_factory_(this) {}
495 ~Throbber() override {}
496
497 void Start() {
498 throbbing_ = true;
499 start_time_ = base::TimeTicks::Now();
500 SchedulePaint();
501 timer_.Start(
502 FROM_HERE, base::TimeDelta::FromMilliseconds(30),
503 base::Bind(&Throbber::SchedulePaint, weak_factory_.GetWeakPtr()));
504 }
505
506 void Stop() {
507 throbbing_ = false;
508 if (timer_.IsRunning())
509 timer_.Stop();
510 SchedulePaint();
511 }
512
513 private:
514 void OnPaint(gfx::Canvas* canvas) override {
515 if (!throbbing_)
516 return;
517
518 gfx::PaintThrobberSpinning(
519 canvas, GetLocalBounds(),
520 GetNativeTheme()->GetSystemColor(
521 ui::NativeTheme::kColorId_ThrobberSpinningColor),
522 base::TimeTicks::Now() - start_time_);
523 }
524
525 bool throbbing_ = false;
526 base::TimeTicks start_time_;
527 base::Timer timer_;
528 base::WeakPtrFactory<Throbber> weak_factory_;
529
530 DISALLOW_COPY_AND_ASSIGN(Throbber);
531 };
532
533 class UI : public views::WidgetDelegateView,
534 public views::ButtonListener,
535 public views::TextfieldController,
536 public TabStrip::Delegate,
537 public TabStripObserver,
538 public navigation::ViewDelegate,
539 public navigation::ViewObserver,
540 public NavButton::ModelProvider,
541 public NavMenuModel::Delegate {
542 public:
543 enum class Type { WINDOW, POPUP };
544
545 UI(Browser* browser, Type type, std::unique_ptr<navigation::View> view)
546 : browser_(browser),
547 type_(type),
548 tab_strip_(new TabStrip(this)),
549 back_button_(new NavButton(NavButton::Type::BACK, this, this,
550 base::ASCIIToUTF16("Back"))),
551 forward_button_(new NavButton(NavButton::Type::FORWARD, this, this,
552 base::ASCIIToUTF16("Forward"))),
553 reload_button_(
554 new views::LabelButton(this, base::ASCIIToUTF16("Reload"))),
555 prompt_(new views::Textfield),
556 debug_button_(new views::LabelButton(this, base::ASCIIToUTF16("DV"))),
557 throbber_(new Throbber),
558 progress_bar_(new ProgressBar),
559 debug_view_(new DebugView) {
560 set_background(views::Background::CreateStandardPanelBackground());
561 prompt_->set_controller(this);
562 back_button_->set_request_focus_on_press(false);
563 forward_button_->set_request_focus_on_press(false);
564 reload_button_->set_request_focus_on_press(false);
565 AddChildView(tab_strip_);
566 AddChildView(back_button_);
567 AddChildView(forward_button_);
568 AddChildView(reload_button_);
569 AddChildView(prompt_);
570 AddChildView(debug_button_);
571 AddChildView(throbber_);
572 AddChildView(progress_bar_);
573 AddChildView(debug_view_);
574
575 tab_strip_->AddObserver(this);
576 tab_strip_->AddTab(std::move(view));
577 }
578 ~UI() override {
579 browser_->RemoveWindow(GetWidget());
580 }
581
582 void NavigateTo(const GURL& url) {
583 selected_view()->NavigateToURL(url);
584 }
585
586 private:
587 // Overridden from views::WidgetDelegate:
588 base::string16 GetWindowTitle() const override {
589 // TODO(beng): use resources.
590 if (selected_view()->title().empty())
591 return base::ASCIIToUTF16("Browser");
592 base::string16 format = base::ASCIIToUTF16("%s - Browser");
593 base::ReplaceFirstSubstringAfterOffset(&format, 0, base::ASCIIToUTF16("%s"),
594 selected_view()->title());
595 return format;
596 }
597 bool CanResize() const override { return true; }
598 bool CanMaximize() const override { return true; }
599 bool CanMinimize() const override { return true; }
600
601 // views::ButtonListener:
602 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
603 if (sender == back_button_) {
604 selected_view()->GoBack();
605 } else if (sender == forward_button_) {
606 selected_view()->GoForward();
607 } else if (sender == reload_button_) {
608 if (selected_view()->is_loading())
609 selected_view()->Stop();
610 else
611 selected_view()->Reload(false);
612 } else if (sender == debug_button_) {
613 ToggleDebugView();
614 }
615 }
616
617 // Overridden from views::View:
618 void Layout() override {
619 gfx::Rect local_bounds = GetLocalBounds();
620
621 gfx::Size ps = tab_strip_->GetPreferredSize();
622 tab_strip_->SetBoundsRect(
623 gfx::Rect(0, 5, local_bounds.width(), ps.height()));
624
625 gfx::Rect bounds = local_bounds;
626 bounds.set_y(tab_strip_->bounds().bottom());
627 bounds.Inset(5, 5);
628
629 ps = back_button_->GetPreferredSize();
630 back_button_->SetBoundsRect(
631 gfx::Rect(bounds.x(), bounds.y(), ps.width(), ps.height()));
632 ps = forward_button_->GetPreferredSize();
633 forward_button_->SetBoundsRect(gfx::Rect(back_button_->bounds().right() + 5,
634 bounds.y(), ps.width(),
635 ps.height()));
636 ps = reload_button_->GetPreferredSize();
637 reload_button_->SetBoundsRect(
638 gfx::Rect(forward_button_->bounds().right() + 5, bounds.y(), ps.width(),
639 ps.height()));
640
641 ps = prompt_->GetPreferredSize();
642 int throbber_size = ps.height();
643 gfx::Size debug_ps = debug_button_->GetPreferredSize();
644 int prompt_y =
645 bounds.y() + (reload_button_->bounds().height() - ps.height()) / 2;
646 int width =
647 bounds.width() - reload_button_->bounds().right() - throbber_size - 15 -
648 debug_ps.width();
649 prompt_->SetBoundsRect(gfx::Rect(reload_button_->bounds().right() + 5,
650 prompt_y, width, ps.height()));
651
652 debug_button_->SetBoundsRect(
653 gfx::Rect(prompt_->bounds().right() + 5,
654 prompt_->bounds().y(), debug_ps.width(), debug_ps.height()));
655
656 throbber_->SetBoundsRect(gfx::Rect(debug_button_->bounds().right() + 5,
657 prompt_->bounds().y(), throbber_size,
658 throbber_size));
659
660 gfx::Rect progress_bar_rect(local_bounds.x(),
661 back_button_->bounds().bottom() + 5,
662 local_bounds.width(), 2);
663 progress_bar_->SetBoundsRect(progress_bar_rect);
664
665 int debug_view_height = 0;
666 if (showing_debug_view_)
667 debug_view_height = debug_view_->GetPreferredSize().height();
668 debug_view_->SetBoundsRect(
669 gfx::Rect(local_bounds.x(), local_bounds.height() - debug_view_height,
670 local_bounds.width(), debug_view_height));
671
672 if (content_area_) {
673 int x = local_bounds.x();
674 int y = type_ == Type::POPUP ? 0 : progress_bar_->bounds().bottom();
675 gfx::Point offset(x, y);
676 ConvertPointToWidget(this, &offset);
677 int width = local_bounds.width();
678 int height = local_bounds.height() - y - debug_view_height;
679 content_area_->SetBounds(
680 gfx::Rect(offset.x(), offset.y(), width, height));
681 for (auto* child : content_area_->children())
682 child->SetBounds(gfx::Rect(0, 0, width, height));
683 }
684 }
685 void ViewHierarchyChanged(
686 const views::View::ViewHierarchyChangedDetails& details) override {
687 if (details.is_add && GetWidget() && !content_area_) {
688 aura::Window* window = GetWidget()->GetNativeWindow();
689 content_area_ = new aura::Window(nullptr);
690 content_area_->Init(ui::LAYER_NOT_DRAWN);
691 content_area_->Show();
692 window->AddChild(content_area_);
693 tab_strip_->SetContainerWindow(content_area_);
694 }
695 }
696
697 // Overridden from views::TextFieldController:
698 bool HandleKeyEvent(views::Textfield* sender,
699 const ui::KeyEvent& key_event) override {
700 if (key_event.type() == ui::ET_KEY_PRESSED &&
701 key_event.key_code() == ui::VKEY_RETURN)
702 selected_view()->NavigateToURL(GURL(prompt_->text()));
703 return false;
704 }
705
706 // TabStrip::Delegate:
707 void NewTab() override {
708 tab_strip_->AddTab(browser_->CreateView());
709 tab_strip_->selected_tab()->view()->NavigateToURL(GURL("about:blank"));
710 }
711
712 // TabStripObserver:
713 void OnTabAdded(Tab* added) override {
714 added->view()->AddObserver(this);
715 added->view()->set_delegate(this);
716 }
717 void OnTabSelected(Tab* selected) override {
718 debug_view_->set_view(selected->view());
719 prompt_->SetText(base::UTF8ToUTF16(selected->view()->url().spec()));
720 if (GetWidget())
721 GetWidget()->UpdateWindowTitle();
722 }
723
724 // navigation::ViewDelegate:
725 void ViewCreated(navigation::View* source,
726 std::unique_ptr<navigation::View> view,
727 bool is_popup,
728 const gfx::Rect& initial_rect,
729 bool user_gesture) override {
730 if (is_popup)
731 CreateNewWindow(std::move(view), initial_rect, is_popup);
732 else
733 tab_strip_->AddTab(std::move(view));
734 }
735 void Close(navigation::View* source) override {
736 tab_strip_->CloseTabForView(source);
737 if (tab_strip_->empty())
738 GetWidget()->Close();
739 }
740 void OpenURL(navigation::View* source,
741 navigation::mojom::OpenURLParamsPtr params) override {
742 switch (params->disposition) {
743 case navigation::mojom::WindowOpenDisposition::CURRENT_TAB:
744 selected_view()->NavigateToURL(params->url);
745 break;
746 case navigation::mojom::WindowOpenDisposition::NEW_FOREGROUND_TAB:
747 tab_strip_->AddTab(browser_->CreateView());
748 tab_strip_->selected_tab()->view()->NavigateToURL(params->url);
749 break;
750 case navigation::mojom::WindowOpenDisposition::NEW_POPUP:
751 case navigation::mojom::WindowOpenDisposition::NEW_WINDOW: {
752 std::unique_ptr<navigation::View> view = browser_->CreateView();
753 view->NavigateToURL(params->url);
754 CreateNewWindow(
755 std::move(view), gfx::Rect(),
756 params->disposition ==
757 navigation::mojom::WindowOpenDisposition::NEW_POPUP);
758 break;
759 }
760 default:
761 break;
762 }
763 }
764
765 // navigation::ViewObserver:
766 void LoadingStateChanged(navigation::View* view) override {
767 if (view->is_loading()) {
768 reload_button_->SetText(base::ASCIIToUTF16("Stop"));
769 throbber_->Start();
770 } else {
771 reload_button_->SetText(base::ASCIIToUTF16("Reload"));
772 throbber_->Stop();
773 progress_bar_->SetProgress(0.f);
774 }
775 }
776 void LoadProgressChanged(navigation::View* view, double progress) override {
777 progress_bar_->SetProgress(progress);
778 }
779 void NavigationStateChanged(navigation::View* view) override {
780 EnableButton(back_button_, view->can_go_back());
781 EnableButton(forward_button_, view->can_go_forward());
782 prompt_->SetText(base::UTF8ToUTF16(view->url().spec()));
783 GetWidget()->UpdateWindowTitle();
784 }
785 void HoverTargetURLChanged(navigation::View* view, const GURL& url) override {
786 if (url.is_valid())
787 prompt_->SetText(base::UTF8ToUTF16(url.spec()));
788 else
789 prompt_->SetText(base::UTF8ToUTF16(selected_view()->url().spec()));
790 }
791
792 // NavButton::ModelProvider:
793 std::unique_ptr<ui::MenuModel> CreateMenuModel(
794 NavButton::Type type) override {
795 std::vector<navigation::NavigationListItem> entries;
796 if (type == NavButton::Type::BACK) {
797 selected_view()->GetBackMenuItems(&entries);
798 } else {
799 selected_view()->GetForwardMenuItems(&entries);
800 }
801 return base::MakeUnique<NavMenuModel>(entries, this);
802 }
803
804 // NavMenuModel::Delegate:
805 void NavigateToOffset(int offset) override {
806 selected_view()->NavigateToOffset(offset);
807 }
808
809 navigation::View* selected_view() {
810 return const_cast<navigation::View*>(
811 static_cast<const UI*>(this)->selected_view());
812 }
813 const navigation::View* selected_view() const {
814 return tab_strip_->selected_tab()->view();
815 }
816
817 void CreateNewWindow(std::unique_ptr<navigation::View> view,
818 const gfx::Rect& initial_bounds,
819 bool is_popup) {
820 gfx::Rect bounds = initial_bounds;
821 if (bounds.IsEmpty())
822 bounds = gfx::Rect(10, 10, 400, 300);
823 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
824 new UI(browser_, is_popup ? UI::Type::POPUP : UI::Type::WINDOW,
825 std::move(view)),
826 nullptr, bounds);
827 window->Show();
828 browser_->AddWindow(window);
829 }
830
831 void ToggleDebugView() {
832 showing_debug_view_ = !showing_debug_view_;
833 Layout();
834 }
835
836 Browser* browser_;
837
838 Type type_;
839
840 TabStrip* tab_strip_;
841 views::LabelButton* back_button_;
842 views::LabelButton* forward_button_;
843 views::LabelButton* reload_button_;
844 views::Textfield* prompt_;
845 views::LabelButton* debug_button_;
846 Throbber* throbber_;
847 ProgressBar* progress_bar_;
848
849 aura::Window* content_area_ = nullptr;
850
851 DebugView* debug_view_;
852 bool showing_debug_view_ = false;
853
854 DISALLOW_COPY_AND_ASSIGN(UI);
855 };
856
857 Browser::Browser() {
858 registry_.AddInterface<mojom::Launchable>(
859 base::Bind(&Browser::Create, base::Unretained(this)));
860 }
861 Browser::~Browser() {}
862
863 void Browser::AddWindow(views::Widget* window) {
864 windows_.push_back(window);
865 }
866
867 void Browser::RemoveWindow(views::Widget* window) {
868 auto it = std::find(windows_.begin(), windows_.end(), window);
869 DCHECK(it != windows_.end());
870 windows_.erase(it);
871 if (windows_.empty())
872 base::MessageLoop::current()->QuitWhenIdle();
873 }
874
875 std::unique_ptr<navigation::View> Browser::CreateView() {
876 navigation::mojom::ViewFactoryPtr factory;
877 context()->connector()->BindInterface(content::mojom::kBrowserServiceName,
878 &factory);
879 return base::MakeUnique<navigation::View>(std::move(factory));
880 }
881
882 void Browser::OnStart() {
883 aura_init_ = base::MakeUnique<views::AuraInit>(
884 context()->connector(), context()->identity(), "views_mus_resources.pak",
885 std::string(), nullptr, views::AuraInit::Mode::AURA_MUS);
886 }
887
888 void Browser::OnBindInterface(
889 const service_manager::BindSourceInfo& source_info,
890 const std::string& interface_name,
891 mojo::ScopedMessagePipeHandle interface_pipe) {
892 registry_.BindInterface(source_info, interface_name,
893 std::move(interface_pipe));
894 }
895
896 void Browser::Launch(uint32_t what, mojom::LaunchMode how) {
897 bool reuse =
898 how == mojom::LaunchMode::REUSE || how == mojom::LaunchMode::DEFAULT;
899 if (reuse && !windows_.empty()) {
900 windows_.back()->Activate();
901 return;
902 }
903
904 UI* ui = new UI(this, UI::Type::WINDOW, CreateView());
905 views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
906 ui, nullptr, gfx::Rect(10, 10, 1024, 600));
907 ui->NavigateTo(GURL("http://www.google.com/"));
908 window->Show();
909 AddWindow(window);
910 }
911
912 void Browser::Create(const service_manager::BindSourceInfo& source_info,
913 mojom::LaunchableRequest request) {
914 bindings_.AddBinding(this, std::move(request));
915 }
916
917 } // namespace browser
918 } // namespace mash
OLDNEW
« no previous file with comments | « mash/browser/browser.h ('k') | mash/browser/debug_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698