Chromium Code Reviews| Index: chrome/browser/ui/views/website_settings/permissions_bubble_view.cc |
| diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc |
| index 1bf465a5a919e62c962bdd7ecf46be4c7c8225bb..cb8fea56e0bc474b9a01b25c4e21a0ebab8389ff 100644 |
| --- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc |
| +++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc |
| @@ -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" |
| @@ -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, |
| @@ -155,6 +166,8 @@ class PermissionsBubbleDelegateView : public views::BubbleDelegateView, |
| bool ShouldShowWindowTitle() const override; |
| const gfx::FontList& GetTitleFontList() const override; |
| base::string16 GetWindowTitle() const override; |
| + void OnWidgetBoundsChanged(views::Widget* widget, |
| + const gfx::Rect& new_bounds) override; |
| void OnWidgetDestroying(views::Widget* widget) override; |
| // ButtonListener: |
| @@ -163,6 +176,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,12 +194,13 @@ 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), |
| @@ -325,9 +344,23 @@ void PermissionsBubbleDelegateView::SizeToContents() { |
| BubbleDelegateView::SizeToContents(); |
| } |
| +void PermissionsBubbleDelegateView::OnWidgetBoundsChanged( |
| + views::Widget* widget, const gfx::Rect& new_bounds) { |
|
msw
2015/03/18 18:30:09
nit: one parameter per line, if the whole signatur
hcarmona
2015/03/18 23:50:39
Done.
|
| + if (owner_) |
| + owner_->UpdateAnchorPosition(); |
|
msw
2015/03/18 18:30:09
Is this really necessary on every OnWidgetBoundsCh
hcarmona
2015/03/18 23:50:39
OnWidgetDestroying is only called when the bubble
|
| + BubbleDelegateView::OnWidgetBoundsChanged(widget, new_bounds); |
| +} |
| + |
| void PermissionsBubbleDelegateView::OnWidgetDestroying(views::Widget* widget) { |
| + // It's necessary to check the value of |anchor_widget| first because calling |
| + // |OnWidgetDestroying| updates |anchor_widget|. |
| + bool anchor_is_destroyed = anchor_widget() == widget; |
| views::BubbleDelegateView::OnWidgetDestroying(widget); |
| - if (owner_) { |
| + |
| + if (owner_ && anchor_is_destroyed) { |
| + // Find a new anchor if the old one is destroyed. |
| + owner_->UpdateAnchorPosition(); |
| + } else if (owner_) { |
| owner_->Closing(); |
| owner_ = NULL; |
| } |
| @@ -349,22 +382,63 @@ 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), |
| +PermissionBubbleViewViews::PermissionBubbleViewViews(Browser* browser) |
| + : browser_(browser), |
| delegate_(NULL), |
| - bubble_delegate_(NULL), |
| - languages_(languages) {} |
| + bubble_delegate_(NULL) {} |
|
msw
2015/03/18 18:30:09
nit: nullptr here and elsewhere.
hcarmona
2015/03/18 23:50:39
Done: changed NULL to nullptr in this file and exc
|
| PermissionBubbleViewViews::~PermissionBubbleViewViews() { |
| if (delegate_) |
| delegate_->SetView(NULL); |
| } |
| +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) { |
| delegate_ = delegate; |
| } |
| @@ -376,8 +450,14 @@ void PermissionBubbleViewViews::Show( |
| 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(); |
| } |