Commit 32a02419 authored by hcarmona's avatar hcarmona Committed by Commit bot

Update permission bubble anchor when omnibar is hidden

The permission bubble is created once. It now chooses an appropriate
anchor if the omnibar is not visible.

The bubble's anchor is updated when fullscreen is toggled.

Screenshots of change:
http://imgur.com/a/PmEQz

BUG=440403,440401

Review URL: https://codereview.chromium.org/962453002

Cr-Commit-Position: refs/heads/master@{#321864}
parent 05b0457f
......@@ -62,7 +62,7 @@ class ButtonView : public views::View {
ButtonView::ButtonView(views::ButtonListener* listener,
int between_button_spacing)
: accept_button_(NULL), deny_button_(NULL) {
: accept_button_(nullptr), deny_button_(nullptr) {
accept_button_ = new views::LabelButton(listener, base::string16());
accept_button_->SetStyle(views::Button::STYLE_BUTTON);
accept_button_->SetFocusable(false);
......@@ -126,10 +126,10 @@ ExclusiveAccessBubbleViews::ExclusiveAccessView::ExclusiveAccessView(
const GURL& url,
ExclusiveAccessBubbleType bubble_type)
: bubble_(bubble),
link_(NULL),
mouse_lock_exit_instruction_(NULL),
message_label_(NULL),
button_view_(NULL),
link_(nullptr),
mouse_lock_exit_instruction_(nullptr),
message_label_(nullptr),
button_view_(nullptr),
browser_fullscreen_exit_accelerator_(accelerator) {
scoped_ptr<views::BubbleBorder> bubble_border(
new views::BubbleBorder(views::BubbleBorder::NONE,
......@@ -263,7 +263,7 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews(
url,
bubble_type),
bubble_view_context_(context),
popup_(NULL),
popup_(nullptr),
animation_(new gfx::SlideAnimation(this)),
animated_attribute_(ANIMATED_ATTRIBUTE_BOUNDS) {
animation_->Reset(1);
......@@ -291,11 +291,11 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews(
popup_->Init(params);
gfx::Size size = GetPopupRect(true).size();
popup_->SetContentsView(view_);
// We set layout manager to NULL to prevent the widget from sizing its
// We set layout manager to nullptr to prevent the widget from sizing its
// contents to the same size as itself. This prevents the widget contents from
// shrinking while we animate the height of the popup to give the impression
// that it is sliding off the top of the screen.
popup_->GetRootView()->SetLayoutManager(NULL);
popup_->GetRootView()->SetLayoutManager(nullptr);
view_->SetBounds(0, 0, size.width(), size.height());
popup_->ShowInactive(); // This does not activate the popup.
......@@ -354,6 +354,10 @@ void ExclusiveAccessBubbleViews::RepositionIfVisible() {
UpdateBounds();
}
views::View* ExclusiveAccessBubbleViews::GetView() {
return view_;
}
void ExclusiveAccessBubbleViews::UpdateMouseWatcher() {
bool should_watch_mouse = false;
if (popup_->IsVisible())
......
......@@ -40,6 +40,8 @@ class ExclusiveAccessBubbleViews : public ExclusiveAccessBubble,
// Repositions |popup_| if it is visible.
void RepositionIfVisible();
views::View* GetView();
private:
class ExclusiveAccessView;
......
......@@ -540,13 +540,6 @@ void BrowserView::InitStatusBubble() {
contents_web_view_->SetStatusBubble(status_bubble_.get());
}
void BrowserView::InitPermissionBubbleView() {
std::string languages =
browser_->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
permission_bubble_view_.reset(new PermissionBubbleViewViews(
GetLocationBarView()->location_icon_view(), languages));
}
gfx::Rect BrowserView::GetToolbarBounds() const {
gfx::Rect toolbar_bounds(toolbar_->bounds());
if (toolbar_bounds.IsEmpty())
......@@ -865,8 +858,11 @@ void BrowserView::OnActiveTabChanged(content::WebContents* old_contents,
PermissionBubbleManager::FromWebContents(old_contents)->SetView(nullptr);
if (new_contents && PermissionBubbleManager::FromWebContents(new_contents)) {
if (!permission_bubble_.get())
permission_bubble_.reset(new PermissionBubbleViewViews(browser_.get()));
PermissionBubbleManager::FromWebContents(new_contents)->SetView(
permission_bubble_view_.get());
permission_bubble_.get());
}
UpdateUIForContents(new_contents);
......@@ -2051,7 +2047,6 @@ void BrowserView::InitViews() {
toolbar_->Init();
InitStatusBubble();
InitPermissionBubbleView();
// Create do-nothing view for the sake of controlling the z-order of the find
// bar widget.
......@@ -2302,6 +2297,9 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
// order to let the layout occur.
in_process_fullscreen_ = false;
ToolbarSizeChanged(false);
if (permission_bubble_.get())
permission_bubble_->UpdateAnchorPosition();
}
bool BrowserView::ShouldUseImmersiveFullscreenForUrl(const GURL& url) const {
......
......@@ -124,11 +124,6 @@ class BrowserView : public BrowserWindow,
// to change some of the bubble's creation parameters.
void InitStatusBubble();
// Initializes the permission bubble view. This class is intended to be
// created once and then re-used for the life of the browser window. The
// bubbles it creates will be associated with a single visible tab.
void InitPermissionBubbleView();
// Returns the apparent bounds of the toolbar, in BrowserView coordinates.
// These differ from |toolbar_.bounds()| in that they match where the toolbar
// background image is drawn -- slightly outside the "true" bounds
......@@ -664,7 +659,7 @@ class BrowserView : public BrowserWindow,
// The permission bubble view is the toolkit-specific implementation of the
// interface used by the manager to display permissions bubbles.
scoped_ptr<PermissionBubbleViewViews> permission_bubble_view_;
scoped_ptr<PermissionBubbleViewViews> permission_bubble_;
// A mapping between accelerators and commands.
std::map<ui::Accelerator, int> accelerator_table_;
......
......@@ -4,10 +4,19 @@
#include "chrome/browser/ui/views/website_settings/permissions_bubble_view.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string16.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/exclusive_access_bubble_views.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
#include "chrome/browser/ui/views/website_settings/permission_selector_view.h"
#include "chrome/browser/ui/views/website_settings/permission_selector_view_observer.h"
#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "net/base/net_util.h"
#include "ui/accessibility/ax_view_state.h"
......@@ -16,6 +25,7 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/button/label_button_border.h"
......@@ -88,7 +98,7 @@ PermissionCombobox::PermissionCombobox(Listener* listener,
int index,
const GURL& url,
ContentSetting setting)
: MenuButton(NULL, base::string16(), this, true),
: MenuButton(nullptr, base::string16(), this, true),
index_(index),
listener_(listener),
model_(new PermissionMenuModel(
......@@ -140,7 +150,8 @@ class PermissionsBubbleDelegateView : public views::BubbleDelegateView,
public PermissionCombobox::Listener {
public:
PermissionsBubbleDelegateView(
views::View* anchor,
views::View* anchor_view,
views::BubbleBorder::Arrow anchor_arrow,
PermissionBubbleViewViews* owner,
const std::string& languages,
const std::vector<PermissionBubbleRequest*>& requests,
......@@ -163,6 +174,11 @@ class PermissionsBubbleDelegateView : public views::BubbleDelegateView,
// PermissionCombobox::Listener:
void PermissionSelectionChanged(int index, bool allowed) override;
// Updates the anchor's arrow and view. Also repositions the bubble so it's
// displayed in the correct location.
void UpdateAnchor(views::View* anchor_view,
views::BubbleBorder::Arrow anchor_arrow);
private:
PermissionBubbleViewViews* owner_;
views::Button* allow_;
......@@ -176,16 +192,17 @@ class PermissionsBubbleDelegateView : public views::BubbleDelegateView,
};
PermissionsBubbleDelegateView::PermissionsBubbleDelegateView(
views::View* anchor,
views::View* anchor_view,
views::BubbleBorder::Arrow anchor_arrow,
PermissionBubbleViewViews* owner,
const std::string& languages,
const std::vector<PermissionBubbleRequest*>& requests,
const std::vector<bool>& accept_state)
: views::BubbleDelegateView(anchor, views::BubbleBorder::TOP_LEFT),
: views::BubbleDelegateView(anchor_view, anchor_arrow),
owner_(owner),
allow_(NULL),
deny_(NULL),
allow_combobox_(NULL) {
allow_(nullptr),
deny_(nullptr),
allow_combobox_(nullptr) {
DCHECK(!requests.empty());
RemoveAllChildViews(true);
......@@ -200,7 +217,8 @@ PermissionsBubbleDelegateView::PermissionsBubbleDelegateView(
languages,
net::kFormatUrlOmitUsernamePassword |
net::kFormatUrlOmitTrailingSlashOnBareHostname,
net::UnescapeRule::SPACES, NULL, NULL, NULL);
net::UnescapeRule::SPACES,
nullptr, nullptr, nullptr);
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
for (size_t index = 0; index < requests.size(); index++) {
......@@ -299,7 +317,7 @@ PermissionsBubbleDelegateView::~PermissionsBubbleDelegateView() {
}
void PermissionsBubbleDelegateView::Close() {
owner_ = NULL;
owner_ = nullptr;
GetWidget()->Close();
}
......@@ -329,7 +347,7 @@ void PermissionsBubbleDelegateView::OnWidgetDestroying(views::Widget* widget) {
views::BubbleDelegateView::OnWidgetDestroying(widget);
if (owner_) {
owner_->Closing();
owner_ = NULL;
owner_ = nullptr;
}
}
......@@ -349,20 +367,61 @@ void PermissionsBubbleDelegateView::PermissionSelectionChanged(
owner_->Toggle(index, allowed);
}
void PermissionsBubbleDelegateView::UpdateAnchor(
views::View* anchor_view,
views::BubbleBorder::Arrow anchor_arrow) {
if (GetAnchorView() == anchor_view && arrow() == anchor_arrow)
return;
set_arrow(anchor_arrow);
// Update the border in the bubble: will either add or remove the arrow.
views::BubbleFrameView* frame =
views::BubbleDelegateView::GetBubbleFrameView();
views::BubbleBorder::Arrow adjusted_arrow = anchor_arrow;
if (base::i18n::IsRTL())
adjusted_arrow = views::BubbleBorder::horizontal_mirror(adjusted_arrow);
frame->SetBubbleBorder(scoped_ptr<views::BubbleBorder>(
new views::BubbleBorder(adjusted_arrow, shadow(), color())));
// Reposition the bubble based on the updated arrow and view.
SetAnchorView(anchor_view);
}
//////////////////////////////////////////////////////////////////////////////
// PermissionBubbleViewViews
PermissionBubbleViewViews::PermissionBubbleViewViews(
views::View* anchor_view,
const std::string& languages)
: anchor_view_(anchor_view),
delegate_(NULL),
bubble_delegate_(NULL),
languages_(languages) {}
PermissionBubbleViewViews::PermissionBubbleViewViews(Browser* browser)
: browser_(browser),
delegate_(nullptr),
bubble_delegate_(nullptr) {}
PermissionBubbleViewViews::~PermissionBubbleViewViews() {
if (delegate_)
delegate_->SetView(NULL);
delegate_->SetView(nullptr);
}
views::View* PermissionBubbleViewViews::GetAnchorView() {
BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
if (browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR))
return browser_view->GetLocationBarView()->location_icon_view();
if (browser_view->IsFullscreenBubbleVisible())
return browser_view->exclusive_access_bubble()->GetView();
return browser_view->top_container();
}
views::BubbleBorder::Arrow PermissionBubbleViewViews::GetAnchorArrow() {
if (browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR))
return views::BubbleBorder::TOP_LEFT;
return views::BubbleBorder::NONE;
}
void PermissionBubbleViewViews::UpdateAnchorPosition() {
if (IsVisible())
bubble_delegate_->UpdateAnchor(GetAnchorView(), GetAnchorArrow());
}
void PermissionBubbleViewViews::SetDelegate(Delegate* delegate) {
......@@ -372,12 +431,18 @@ void PermissionBubbleViewViews::SetDelegate(Delegate* delegate) {
void PermissionBubbleViewViews::Show(
const std::vector<PermissionBubbleRequest*>& requests,
const std::vector<bool>& values) {
if (bubble_delegate_ != NULL)
if (bubble_delegate_)
bubble_delegate_->Close();
bubble_delegate_ =
new PermissionsBubbleDelegateView(anchor_view_, this, languages_,
requests, values);
new PermissionsBubbleDelegateView(
GetAnchorView(), GetAnchorArrow(), this,
browser_->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages),
requests, values);
// Set |parent_window| because some valid anchors can become hidden.
bubble_delegate_->set_parent_window(browser_->window()->GetNativeWindow());
views::BubbleDelegateView::CreateBubble(bubble_delegate_)->Show();
bubble_delegate_->SizeToContents();
}
......@@ -389,17 +454,17 @@ bool PermissionBubbleViewViews::CanAcceptRequestUpdate() {
void PermissionBubbleViewViews::Hide() {
if (bubble_delegate_) {
bubble_delegate_->Close();
bubble_delegate_ = NULL;
bubble_delegate_ = nullptr;
}
}
bool PermissionBubbleViewViews::IsVisible() {
return bubble_delegate_ != NULL;
return bubble_delegate_ != nullptr;
}
void PermissionBubbleViewViews::Closing() {
if (bubble_delegate_)
bubble_delegate_ = NULL;
bubble_delegate_ = nullptr;
if (delegate_)
delegate_->Closing();
}
......
......@@ -10,19 +10,23 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "chrome/browser/ui/website_settings/permission_bubble_view.h"
#include "ui/views/bubble/bubble_border.h"
namespace views {
class View;
}
class Browser;
class PermissionsBubbleDelegateView;
class PermissionBubbleViewViews : public PermissionBubbleView {
public:
PermissionBubbleViewViews(views::View* anchor_view,
const std::string& languages);
explicit PermissionBubbleViewViews(Browser* browser);
~PermissionBubbleViewViews() override;
// Updates anchor on fullscreen changes, etc.
void UpdateAnchorPosition();
// PermissionBubbleView:
void SetDelegate(Delegate* delegate) override;
void Show(const std::vector<PermissionBubbleRequest*>& requests,
......@@ -37,10 +41,12 @@ class PermissionBubbleViewViews : public PermissionBubbleView {
void Deny();
private:
views::View* anchor_view_;
views::View* GetAnchorView();
views::BubbleBorder::Arrow GetAnchorArrow();
Browser* browser_;
Delegate* delegate_;
PermissionsBubbleDelegateView* bubble_delegate_;
const std::string languages_;
DISALLOW_COPY_AND_ASSIGN(PermissionBubbleViewViews);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment