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

Unified Diff: mash/browser/browser.cc

Issue 2055553002: Send Navigation notifications to clients. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | mash/webtest/webtest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mash/browser/browser.cc
diff --git a/mash/browser/browser.cc b/mash/browser/browser.cc
index 5094674b278692b92b142b20bfdfcc038bd56f69..c746ef0e5a76a0620c74c29df4ad8780c6ca063a 100644
--- a/mash/browser/browser.cc
+++ b/mash/browser/browser.cc
@@ -5,11 +5,13 @@
#include "mash/browser/browser.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
#include "components/mus/public/cpp/window.h"
#include "components/mus/public/cpp/window_tree_client.h"
@@ -22,12 +24,15 @@
#include "services/shell/public/cpp/shell_client.h"
#include "services/tracing/public/cpp/tracing_impl.h"
#include "ui/aura/mus/mus_util.h"
+#include "ui/base/models/menu_model.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/paint_throbber.h"
#include "ui/gfx/text_constants.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
+#include "ui/views/controls/menu/menu_model_adapter.h"
+#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/mus/aura_init.h"
@@ -43,6 +48,175 @@ void EnableButton(views::CustomButton* button, bool enabled) {
: views::Button::STATE_DISABLED);
}
+class NavMenuModel : public ui::MenuModel {
+ public:
+ class Delegate {
+ public:
+ virtual void NavigateToOffset(int offset) = 0;
+ };
+
+ struct Entry {
+ Entry(const base::string16& title, int offset)
+ : title(title), offset(offset) {}
+ ~Entry() {}
+
+ // Title of the entry in the menu.
+ base::string16 title;
+ // Offset from the currently visible page to navigate to this item.
+ int offset;
+ };
+
+ NavMenuModel(const std::vector<Entry>& entries, Delegate* delegate)
+ : navigation_delegate_(delegate), entries_(entries) {}
+ ~NavMenuModel() override {}
+
+ private:
+ bool HasIcons() const override { return false; }
+ int GetItemCount() const override {
+ return static_cast<int>(entries_.size());
+ }
+ ui::MenuModel::ItemType GetTypeAt(int index) const override {
+ return ui::MenuModel::TYPE_COMMAND;
+ }
+ ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override {
+ return ui::NORMAL_SEPARATOR;
+ }
+ int GetCommandIdAt(int index) const override {
+ return index;
+ }
+ base::string16 GetLabelAt(int index) const override {
+ return entries_[index].title;
+ }
+ base::string16 GetSublabelAt(int index) const override {
+ return base::string16();
+ }
+ base::string16 GetMinorTextAt(int index) const override {
+ return base::string16();
+ }
+ bool IsItemDynamicAt(int index) const override { return false; }
+ bool GetAcceleratorAt(int index,
+ ui::Accelerator* accelerator) const override {
+ return false;
+ }
+ bool IsItemCheckedAt(int index) const override { return false; }
+ int GetGroupIdAt(int index) const override { return -1; }
+ bool GetIconAt(int index, gfx::Image* icon) override { return false; }
+ ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
+ return nullptr;
+ }
+ bool IsEnabledAt(int index) const override { return true; }
+ bool IsVisibleAt(int index) const override { return true; }
+ ui::MenuModel* GetSubmenuModelAt(int index) const override { return nullptr; }
+ void HighlightChangedTo(int index) override {}
+ void ActivatedAt(int index) override {
+ ActivatedAt(index, 0);
+ }
+ void ActivatedAt(int index, int event_flags) override {
+ navigation_delegate_->NavigateToOffset(entries_[index].offset);
+ }
+ void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) override {
+ delegate_ = delegate;
+ }
+ ui::MenuModelDelegate* GetMenuModelDelegate() const override {
+ return delegate_;
+ }
+
+ ui::MenuModelDelegate* delegate_ = nullptr;
+ Delegate* navigation_delegate_;
+ std::vector<Entry> entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavMenuModel);
+};
+
+class NavButton : public views::LabelButton {
+ public:
+ enum class Type {
+ BACK,
+ FORWARD
+ };
+
+ class ModelProvider {
+ public:
+ virtual std::unique_ptr<ui::MenuModel> CreateMenuModel(Type type) = 0;
+ };
+
+ NavButton(Type type,
+ ModelProvider* model_provider,
+ views::ButtonListener* listener,
+ const base::string16& label)
+ : views::LabelButton(listener, label),
+ type_(type),
+ model_provider_(model_provider),
+ show_menu_factory_(this) {}
+ ~NavButton() override {}
+
+ private:
+ // views::LabelButton overrides:
+ bool OnMousePressed(const ui::MouseEvent& event) override {
+ if (IsTriggerableEvent(event) && enabled() &&
+ HitTestPoint(event.location())) {
+ y_pos_on_lbuttondown_ = event.y();
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&NavButton::ShowMenu, show_menu_factory_.GetWeakPtr(),
+ ui::GetMenuSourceTypeForEvent(event)),
+ base::TimeDelta::FromMilliseconds(500));
+ }
+ return LabelButton::OnMousePressed(event);
+ }
+ bool OnMouseDragged(const ui::MouseEvent& event) override {
+ bool result = LabelButton::OnMouseDragged(event);
+ if (show_menu_factory_.HasWeakPtrs()) {
+ if (event.y() > y_pos_on_lbuttondown_ + GetHorizontalDragThreshold()) {
+ show_menu_factory_.InvalidateWeakPtrs();
+ ShowMenu(ui::GetMenuSourceTypeForEvent(event));
+ }
+ }
+ return result;
+ }
+ void OnMouseReleased(const ui::MouseEvent& event) override {
+ if (IsTriggerableEvent(event))
+ show_menu_factory_.InvalidateWeakPtrs();
+ LabelButton::OnMouseReleased(event);
+ }
+
+ void ShowMenu(ui::MenuSourceType source_type) {
+ gfx::Rect local = GetLocalBounds();
+ gfx::Point menu_position(local.origin());
+ menu_position.Offset(0, local.height() - 1);
+ View::ConvertPointToScreen(this, &menu_position);
+
+ model_ = model_provider_->CreateMenuModel(type_);
+ menu_model_adapter_.reset(new views::MenuModelAdapter(
+ model_.get(),
+ base::Bind(&NavButton::OnMenuClosed, base::Unretained(this))));
+ menu_model_adapter_->set_triggerable_event_flags(triggerable_event_flags());
+ menu_runner_.reset(new views::MenuRunner(
+ menu_model_adapter_->CreateMenu(),
+ views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::ASYNC));
+ ignore_result(menu_runner_->RunMenuAt(
+ GetWidget(), nullptr, gfx::Rect(menu_position, gfx::Size(0, 0)),
+ views::MENU_ANCHOR_TOPLEFT, source_type));
+ }
+
+ void OnMenuClosed() {
+ SetMouseHandler(nullptr);
+ model_.reset();
+ menu_runner_.reset();
+ menu_model_adapter_.reset();
+ }
+
+ Type type_;
+ ModelProvider* model_provider_;
+ int y_pos_on_lbuttondown_ = 0;
+ std::unique_ptr<ui::MenuModel> model_;
+ std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_;
+ std::unique_ptr<views::MenuRunner> menu_runner_;
+ base::WeakPtrFactory<NavButton> show_menu_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavButton);
+};
+
class ProgressBar : public views::View {
public:
ProgressBar() {}
@@ -115,7 +289,9 @@ class Throbber : public views::View {
class UI : public views::WidgetDelegateView,
public views::ButtonListener,
public views::TextfieldController,
- public navigation::mojom::ViewClient {
+ public navigation::mojom::ViewClient,
+ public NavButton::ModelProvider,
+ public NavMenuModel::Delegate {
public:
enum class Type { WINDOW, POPUP };
@@ -125,9 +301,10 @@ class UI : public views::WidgetDelegateView,
navigation::mojom::ViewClientRequest request)
: browser_(browser),
type_(type),
- back_button_(new views::LabelButton(this, base::ASCIIToUTF16("Back"))),
- forward_button_(
- new views::LabelButton(this, base::ASCIIToUTF16("Forward"))),
+ back_button_(new NavButton(NavButton::Type::BACK, this, this,
+ base::ASCIIToUTF16("Back"))),
+ forward_button_(new NavButton(NavButton::Type::FORWARD, this, this,
+ base::ASCIIToUTF16("Forward"))),
reload_button_(
new views::LabelButton(this, base::ASCIIToUTF16("Reload"))),
prompt_(new views::Textfield),
@@ -321,6 +498,66 @@ class UI : public views::WidgetDelegateView,
browser_->AddWindow(window);
}
void Close() override { GetWidget()->Close(); }
+ void NavigationPending(navigation::mojom::NavigationEntryPtr entry) override {
+ pending_nav_ = std::move(entry);
+ }
+ void NavigationCommitted(
+ navigation::mojom::NavigationCommittedDetailsPtr details,
+ int current_index) override {
+ switch (details->type) {
+ case navigation::mojom::NavigationType::NEW_PAGE: {
+ navigation_list_.push_back(std::move(pending_nav_));
+ navigation_list_position_ = current_index;
+ break;
+ }
+ case navigation::mojom::NavigationType::EXISTING_PAGE:
+ navigation_list_position_ = current_index;
+ break;
+ default:
+ break;
+ }
+ }
+ void NavigationEntryChanged(navigation::mojom::NavigationEntryPtr entry,
+ int entry_index) override {
+ navigation_list_[entry_index] = std::move(entry);
+ }
+ void NavigationListPruned(bool from_front, int count) override {
+ DCHECK(count < static_cast<int>(navigation_list_.size()));
+ if (from_front) {
+ auto it = navigation_list_.begin() + count;
+ navigation_list_.erase(navigation_list_.begin(), it);
+ } else {
+ auto it = navigation_list_.end() - count;
+ navigation_list_.erase(it, navigation_list_.end());
+ }
+ }
+
+ // NavButton::ModelProvider:
+ std::unique_ptr<ui::MenuModel> CreateMenuModel(
+ NavButton::Type type) override {
+ std::vector<NavMenuModel::Entry> entries;
+ if (type == NavButton::Type::BACK) {
+ for (int i = navigation_list_position_ - 1, offset = -1;
+ i >= 0; --i, --offset) {
+ std::string title = navigation_list_[i]->title;
+ entries.push_back(
+ NavMenuModel::Entry(base::UTF8ToUTF16(title), offset));
+ }
+ } else {
+ for (int i = navigation_list_position_ + 1, offset = 1;
+ i < static_cast<int>(navigation_list_.size()); ++i, ++offset) {
+ std::string title = navigation_list_[i]->title;
+ entries.push_back(
+ NavMenuModel::Entry(base::UTF8ToUTF16(title), offset));
+ }
+ }
+ return base::WrapUnique(new NavMenuModel(entries, this));
+ }
+
+ // NavMenuModel::Delegate:
+ void NavigateToOffset(int offset) override {
+ view_->NavigateToOffset(offset);
+ }
void ToggleDebugView() {
showing_debug_view_ = !showing_debug_view_;
@@ -350,6 +587,10 @@ class UI : public views::WidgetDelegateView,
base::string16 current_title_;
GURL current_url_;
+ navigation::mojom::NavigationEntryPtr pending_nav_;
+ std::vector<navigation::mojom::NavigationEntryPtr> navigation_list_;
+ int navigation_list_position_ = 0;
+
bool showing_debug_view_ = false;
DISALLOW_COPY_AND_ASSIGN(UI);
« no previous file with comments | « no previous file | mash/webtest/webtest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698