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(const 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; | |
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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 // after being resized), compositing window managers also send | 283 // after being resized), compositing window managers also send |
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. |
Finnur
2011/11/15 10:05:01
What's the status on this comment? Is there still
msw
2011/11/15 20:16:57
Just tested; the jank is still there; leaving this
| |
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() { | |
alicet1
2011/11/15 02:02:13
where did this go?
msw
2011/11/15 20:16:57
GetAccessibleName was only ever used on the Window
| |
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(); | |
Finnur
2011/11/15 10:05:01
I remember this problem. Do you now guarantee that
msw
2011/11/15 20:16:57
This bubble does indeed close on deactivate on my
| |
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); |
326 } | 313 } |
alicet1
2011/11/15 02:02:13
The bubble will be closed on deactivation. add a c
msw
2011/11/15 20:16:57
Done.
| |
327 | 314 |
328 void PageInfoBubbleView::AnimationEnded(const ui::Animation* animation) { | 315 void PageInfoBubbleView::AnimationEnded(const ui::Animation* animation) { |
329 LayoutSections(); | 316 if (animation == &resize_animation_) { |
330 bubble_->SizeToContents(); | 317 LayoutSections(); |
318 SizeToContents(); | |
319 } else { | |
320 BubbleDelegateView::AnimationEnded(animation); | |
321 } | |
Finnur
2011/11/15 10:05:01
Out of curiosity... is there a specific reason for
msw
2011/11/15 20:16:57
BubbleDelegateView was DCHECKing that it only gets
| |
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 } else { | |
329 BubbleDelegateView::AnimationProgressed(animation); | |
330 } | |
336 } | 331 } |
337 | 332 |
338 //////////////////////////////////////////////////////////////////////////////// | 333 //////////////////////////////////////////////////////////////////////////////// |
339 // Section | 334 // Section |
340 | 335 |
341 Section::Section(PageInfoBubbleView* owner, | 336 Section::Section(PageInfoBubbleView* owner, |
342 const PageInfoModel::SectionInfo& section_info, | 337 const PageInfoModel::SectionInfo& section_info, |
343 const SkBitmap* state_icon, | 338 const SkBitmap* state_icon, |
344 bool show_cert) | 339 bool show_cert) |
345 : owner_(owner), | 340 : owner_(owner), |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 y += size.height(); | 465 y += size.height(); |
471 } | 466 } |
472 | 467 |
473 // Make sure the image is not truncated if the text doesn't contain much. | 468 // Make sure the image is not truncated if the text doesn't contain much. |
474 y = std::max(y, (2 * kVerticalSectionPadding) + image_height); | 469 y = std::max(y, (2 * kVerticalSectionPadding) + image_height); |
475 return gfx::Size(width, y); | 470 return gfx::Size(width, y); |
476 } | 471 } |
477 | 472 |
478 namespace browser { | 473 namespace browser { |
479 | 474 |
480 void ShowPageInfoBubble(BrowserView* browser_view, | 475 void ShowPageInfoBubble(const views::View* anchor_view, |
481 Profile* profile, | 476 Profile* profile, |
482 const GURL& url, | 477 const GURL& url, |
483 const NavigationEntry::SSLStatus& ssl, | 478 const NavigationEntry::SSLStatus& ssl, |
484 bool show_history) { | 479 bool show_history) { |
485 // Find where to point the bubble at. | 480 PageInfoBubbleView* page_info_bubble = |
486 gfx::Point point; | 481 new PageInfoBubbleView(anchor_view, profile, url, ssl, show_history); |
487 if (base::i18n::IsRTL()) { | 482 views::BubbleDelegateView::CreateBubble(page_info_bubble); |
488 int width = browser_view->toolbar()->location_bar()->width(); | 483 page_info_bubble->Show(); |
489 point = gfx::Point(width - kIconHorizontalOffset, 0); | 484 } |
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 | 485 |
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 } | 486 } |
509 } | |
OLD | NEW |