Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/page_info_bubble_view.h" | 5 #include "chrome/browser/ui/views/page_info_bubble_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/certificate_viewer.h" | 10 #include "chrome/browser/certificate_viewer.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "ui/gfx/image/image.h" | 23 #include "ui/gfx/image/image.h" |
| 24 #include "views/controls/image_view.h" | 24 #include "views/controls/image_view.h" |
| 25 #include "views/controls/label.h" | 25 #include "views/controls/label.h" |
| 26 #include "views/controls/link.h" | 26 #include "views/controls/link.h" |
| 27 #include "views/controls/separator.h" | 27 #include "views/controls/separator.h" |
| 28 #include "views/layout/grid_layout.h" | 28 #include "views/layout/grid_layout.h" |
| 29 #include "views/widget/widget.h" | 29 #include "views/widget/widget.h" |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 // TODO(msw): Get color from theme/window color. | |
| 34 const SkColor kColor = SK_ColorWHITE; | |
| 35 | |
| 33 // Layout constants. | 36 // Layout constants. |
| 34 const int kHGapToBorder = 11; | 37 const int kHGapToBorder = 11; |
| 35 const int kVerticalSectionPadding = 8; | 38 const int kVerticalSectionPadding = 8; |
| 36 const int kVGapToHeadline = 5; | 39 const int kVGapToHeadline = 5; |
| 37 const int kHGapImageToDescription = 6; | 40 const int kHGapImageToDescription = 6; |
| 38 const int kTextPaddingRight = 10; | 41 const int kTextPaddingRight = 10; |
| 39 const int kPaddingBelowSeparator = 6; | 42 const int kPaddingBelowSeparator = 6; |
| 40 const int kPaddingAboveSeparator = 4; | 43 const int kPaddingAboveSeparator = 4; |
| 41 const int kIconHorizontalOffset = 27; | 44 const int kIconHorizontalOffset = 27; |
| 42 const int kIconVerticalOffset = -7; | 45 const int kIconVerticalOffset = -7; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 double animation_value_; | 94 double animation_value_; |
| 92 | 95 |
| 93 DISALLOW_COPY_AND_ASSIGN(Section); | 96 DISALLOW_COPY_AND_ASSIGN(Section); |
| 94 }; | 97 }; |
| 95 | 98 |
| 96 } // namespace | 99 } // namespace |
| 97 | 100 |
| 98 //////////////////////////////////////////////////////////////////////////////// | 101 //////////////////////////////////////////////////////////////////////////////// |
| 99 // PageInfoBubbleView | 102 // PageInfoBubbleView |
| 100 | 103 |
| 101 Bubble* PageInfoBubbleView::bubble_ = NULL; | 104 PageInfoBubbleView::PageInfoBubbleView(views::View* anchor_view, |
| 102 | |
| 103 PageInfoBubbleView::PageInfoBubbleView(gfx::NativeWindow parent_window, | |
| 104 Profile* profile, | 105 Profile* profile, |
| 105 const GURL& url, | 106 const GURL& url, |
| 106 const NavigationEntry::SSLStatus& ssl, | 107 const NavigationEntry::SSLStatus& ssl, |
| 107 bool show_history) | 108 bool show_history) |
| 108 : ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl, | 109 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT, kColor), |
| 110 ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl, | |
| 109 show_history, this)), | 111 show_history, this)), |
| 110 parent_window_(parent_window), | |
| 111 cert_id_(ssl.cert_id()), | 112 cert_id_(ssl.cert_id()), |
| 112 help_center_link_(NULL), | 113 help_center_link_(NULL), |
| 113 ALLOW_THIS_IN_INITIALIZER_LIST(resize_animation_(this)), | 114 ALLOW_THIS_IN_INITIALIZER_LIST(resize_animation_(this)), |
| 114 animation_start_height_(0) { | 115 animation_start_height_(0) { |
| 115 if (bubble_) | 116 |
| 116 bubble_->Close(); | |
| 117 if (cert_id_ > 0) { | 117 if (cert_id_ > 0) { |
| 118 scoped_refptr<net::X509Certificate> cert; | 118 scoped_refptr<net::X509Certificate> cert; |
| 119 CertStore::GetInstance()->RetrieveCert(cert_id_, &cert); | 119 CertStore::GetInstance()->RetrieveCert(cert_id_, &cert); |
| 120 // When running with fake certificate (Chrome Frame), we have no os | 120 // When running with fake certificate (Chrome Frame), we have no os |
| 121 // certificate, so there is no cert to show. Don't bother showing the cert | 121 // certificate, so there is no cert to show. Don't bother showing the cert |
| 122 // info link in that case. | 122 // info link in that case. |
| 123 if (!cert.get() || !cert->os_cert_handle()) | 123 if (!cert.get() || !cert->os_cert_handle()) |
| 124 cert_id_ = 0; | 124 cert_id_ = 0; |
| 125 } | 125 } |
| 126 LayoutSections(); | 126 LayoutSections(); |
| 127 } | 127 } |
| 128 | 128 |
| 129 PageInfoBubbleView::~PageInfoBubbleView() { | 129 PageInfoBubbleView::~PageInfoBubbleView() { |
| 130 resize_animation_.Reset(); | |
| 130 } | 131 } |
| 131 | 132 |
| 132 void PageInfoBubbleView::ShowCertDialog() { | 133 void PageInfoBubbleView::ShowCertDialog() { |
| 133 ShowCertificateViewerByID(parent_window_, cert_id_); | 134 gfx::NativeWindow parent = |
| 135 anchor_view() ? anchor_view()->GetWidget()->GetNativeWindow() : NULL; | |
|
Ben Goodger (Google)
2011/11/16 22:26:38
nit: 4-space indent
msw
2011/11/16 22:37:53
Done.
| |
| 136 ShowCertificateViewerByID(parent, cert_id_); | |
| 134 } | 137 } |
| 135 | 138 |
| 136 gfx::Size PageInfoBubbleView::GetSeparatorSize() { | 139 gfx::Size PageInfoBubbleView::GetSeparatorSize() { |
| 137 // Calculate how much space the separators take up (with padding). | 140 // Calculate how much space the separators take up (with padding). |
| 138 views::Separator separator; | 141 views::Separator separator; |
| 139 gfx::Size separator_size = separator.GetPreferredSize(); | 142 gfx::Size separator_size = separator.GetPreferredSize(); |
| 140 gfx::Size separator_plus_padding(0, separator_size.height() + | 143 gfx::Size separator_plus_padding(0, separator_size.height() + |
| 141 kPaddingAboveSeparator + | 144 kPaddingAboveSeparator + |
| 142 kPaddingBelowSeparator); | 145 kPaddingBelowSeparator); |
| 143 return separator_plus_padding; | 146 return separator_plus_padding; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 // _NET_WM_SYNC_REQUEST messages to clients before resizing to ask for notice | 284 // _NET_WM_SYNC_REQUEST messages to clients before resizing to ask for notice |
| 282 // after the window has been repainted at the new size. Chrome appears to | 285 // after the window has been repainted at the new size. Chrome appears to |
| 283 // fall behind in handling the repaints, and the sync request responses | 286 // fall behind in handling the repaints, and the sync request responses |
| 284 // typically don't get sent back to the window manager until the animation is | 287 // typically don't get sent back to the window manager until the animation is |
| 285 // done, which results in the window being invisible until then: | 288 // done, which results in the window being invisible until then: |
| 286 // http://crosbug.com/14993. Trying to e.g. just animate the first-visit | 289 // http://crosbug.com/14993. Trying to e.g. just animate the first-visit |
| 287 // section's opacity has the same negative effect, so we avoid doing any | 290 // section's opacity has the same negative effect, so we avoid doing any |
| 288 // animation. | 291 // animation. |
| 289 // TODO(derat): Remove this once we're not using a toplevel X window for the | 292 // TODO(derat): Remove this once we're not using a toplevel X window for the |
| 290 // bubble. | 293 // bubble. |
| 291 bubble_->SizeToContents(); | 294 SizeToContents(); |
| 292 #else | 295 #else |
| 293 resize_animation_.SetSlideDuration(kPageInfoSlideDuration); | 296 resize_animation_.SetSlideDuration(kPageInfoSlideDuration); |
| 294 resize_animation_.Show(); | 297 resize_animation_.Show(); |
| 295 #endif | 298 #endif |
| 296 } | 299 } |
| 297 | 300 |
| 298 void PageInfoBubbleView::BubbleClosing(Bubble* bubble, bool closed_by_escape) { | 301 gfx::Point PageInfoBubbleView::GetAnchorPoint() { |
| 299 resize_animation_.Reset(); | 302 // Compensate for some built-in padding in the icon. |
| 300 bubble_ = NULL; | 303 gfx::Point anchor(BubbleDelegateView::GetAnchorPoint()); |
| 301 } | 304 return anchor_view() ? anchor.Subtract(gfx::Point(0, 5)) : anchor; |
| 302 | |
| 303 bool PageInfoBubbleView::CloseOnEscape() { | |
| 304 return true; | |
| 305 } | |
| 306 | |
| 307 bool PageInfoBubbleView::FadeInOnShow() { | |
| 308 return false; | |
| 309 } | |
| 310 | |
| 311 string16 PageInfoBubbleView::GetAccessibleName() { | |
| 312 return ASCIIToUTF16("PageInfoBubble"); | |
| 313 } | 305 } |
| 314 | 306 |
| 315 void PageInfoBubbleView::LinkClicked(views::Link* source, int event_flags) { | 307 void PageInfoBubbleView::LinkClicked(views::Link* source, int event_flags) { |
| 316 // We want to make sure the info bubble closes once the link is activated. So | |
| 317 // we close it explicitly rather than relying on a side-effect of opening a | |
| 318 // new tab (see http://crosbug.com/10186). | |
| 319 bubble_->Close(); | |
| 320 | |
| 321 GURL url = google_util::AppendGoogleLocaleParam( | 308 GURL url = google_util::AppendGoogleLocaleParam( |
| 322 GURL(chrome::kPageInfoHelpCenterURL)); | 309 GURL(chrome::kPageInfoHelpCenterURL)); |
| 323 Browser* browser = BrowserList::GetLastActive(); | 310 Browser* browser = BrowserList::GetLastActive(); |
| 324 browser->OpenURL( | 311 browser->OpenURL( |
| 325 url, GURL(), NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK); | 312 url, GURL(), NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK); |
| 313 // NOTE: The bubble closes automatically on deactivation as the link opens. | |
| 326 } | 314 } |
| 327 | 315 |
| 328 void PageInfoBubbleView::AnimationEnded(const ui::Animation* animation) { | 316 void PageInfoBubbleView::AnimationEnded(const ui::Animation* animation) { |
| 329 LayoutSections(); | 317 if (animation == &resize_animation_) { |
| 330 bubble_->SizeToContents(); | 318 LayoutSections(); |
| 319 SizeToContents(); | |
| 320 } | |
| 321 BubbleDelegateView::AnimationEnded(animation); | |
| 331 } | 322 } |
| 332 | 323 |
| 333 void PageInfoBubbleView::AnimationProgressed(const ui::Animation* animation) { | 324 void PageInfoBubbleView::AnimationProgressed(const ui::Animation* animation) { |
| 334 LayoutSections(); | 325 if (animation == &resize_animation_) { |
| 335 bubble_->SizeToContents(); | 326 LayoutSections(); |
| 327 SizeToContents(); | |
| 328 } | |
| 329 BubbleDelegateView::AnimationProgressed(animation); | |
| 336 } | 330 } |
| 337 | 331 |
| 338 //////////////////////////////////////////////////////////////////////////////// | 332 //////////////////////////////////////////////////////////////////////////////// |
| 339 // Section | 333 // Section |
| 340 | 334 |
| 341 Section::Section(PageInfoBubbleView* owner, | 335 Section::Section(PageInfoBubbleView* owner, |
| 342 const PageInfoModel::SectionInfo& section_info, | 336 const PageInfoModel::SectionInfo& section_info, |
| 343 const SkBitmap* state_icon, | 337 const SkBitmap* state_icon, |
| 344 bool show_cert) | 338 bool show_cert) |
| 345 : owner_(owner), | 339 : owner_(owner), |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 y += size.height(); | 464 y += size.height(); |
| 471 } | 465 } |
| 472 | 466 |
| 473 // Make sure the image is not truncated if the text doesn't contain much. | 467 // Make sure the image is not truncated if the text doesn't contain much. |
| 474 y = std::max(y, (2 * kVerticalSectionPadding) + image_height); | 468 y = std::max(y, (2 * kVerticalSectionPadding) + image_height); |
| 475 return gfx::Size(width, y); | 469 return gfx::Size(width, y); |
| 476 } | 470 } |
| 477 | 471 |
| 478 namespace browser { | 472 namespace browser { |
| 479 | 473 |
| 480 void ShowPageInfoBubble(BrowserView* browser_view, | 474 void ShowPageInfoBubble(views::View* anchor_view, |
| 481 Profile* profile, | 475 Profile* profile, |
| 482 const GURL& url, | 476 const GURL& url, |
| 483 const NavigationEntry::SSLStatus& ssl, | 477 const NavigationEntry::SSLStatus& ssl, |
| 484 bool show_history) { | 478 bool show_history) { |
| 485 // Find where to point the bubble at. | 479 PageInfoBubbleView* page_info_bubble = |
| 486 gfx::Point point; | 480 new PageInfoBubbleView(anchor_view, profile, url, ssl, show_history); |
| 487 if (base::i18n::IsRTL()) { | 481 views::BubbleDelegateView::CreateBubble(page_info_bubble); |
| 488 int width = browser_view->toolbar()->location_bar()->width(); | 482 page_info_bubble->Show(); |
| 489 point = gfx::Point(width - kIconHorizontalOffset, 0); | 483 } |
| 490 } | |
| 491 point.Offset(0, kIconVerticalOffset); | |
| 492 views::View::ConvertPointToScreen(browser_view->toolbar()->location_bar(), | |
| 493 &point); | |
| 494 gfx::Rect bounds = browser_view->toolbar()->location_bar()->bounds(); | |
| 495 bounds.set_origin(point); | |
| 496 bounds.set_width(kIconHorizontalOffset); | |
| 497 | 484 |
| 498 // Show the bubble. If the bubble already exist - it will be closed first. | |
| 499 PageInfoBubbleView* page_info_bubble = | |
| 500 new PageInfoBubbleView(browser_view->GetNativeHandle(), | |
| 501 profile, url, ssl, show_history); | |
| 502 Bubble* bubble = | |
| 503 Bubble::Show(browser_view->GetWidget(), bounds, | |
| 504 views::BubbleBorder::TOP_LEFT, | |
| 505 views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, | |
| 506 page_info_bubble, page_info_bubble); | |
| 507 page_info_bubble->set_bubble(bubble); | |
| 508 } | 485 } |
| 509 } | |
| OLD | NEW |