Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/views/backspace_new_shortcut_bubble.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/macros.h" | |
| 10 #include "base/message_loop/message_loop.h" | |
| 11 #include "base/strings/stringprintf.h" | |
| 12 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "build/build_config.h" | |
| 14 #include "chrome/app/chrome_command_ids.h" | |
| 15 #include "chrome/browser/chrome_notification_types.h" | |
| 16 #include "chrome/browser/ui/views/exclusive_access_bubble_views_context.h" | |
| 17 #include "chrome/browser/ui/views/frame/top_container_view.h" | |
| 18 #include "chrome/browser/ui/views/subtle_notification_view.h" | |
| 19 #include "chrome/grit/generated_resources.h" | |
| 20 #include "ui/base/l10n/l10n_util.h" | |
| 21 #include "ui/gfx/animation/animation.h" | |
| 22 #include "ui/gfx/animation/slide_animation.h" | |
| 23 #include "ui/gfx/geometry/rect.h" | |
| 24 #include "ui/strings/grit/ui_strings.h" | |
| 25 #include "ui/views/bubble/bubble_border.h" | |
| 26 #include "ui/views/view.h" | |
| 27 #include "ui/views/widget/widget.h" | |
| 28 | |
| 29 #if defined(OS_WIN) | |
| 30 #include "ui/base/l10n/l10n_util_win.h" | |
| 31 #endif | |
|
Peter Kasting
2016/05/19 10:08:36
Doesn't seem like this is used.
Check other #incl
Matt Giuca
2016/05/23 04:22:56
Done.
| |
| 32 | |
| 33 namespace { | |
| 34 | |
| 35 const int kPopupTopPx = 45; | |
| 36 const int kSlideInDurationMs = 350; | |
| 37 const int kSlideOutDurationMs = 700; | |
| 38 const int kShowDurationMs = 3800; | |
| 39 | |
| 40 } | |
| 41 | |
| 42 BackspaceNewShortcutBubble::BackspaceNewShortcutBubble( | |
| 43 ExclusiveAccessBubbleViewsContext* context, | |
| 44 bool forward) | |
| 45 : bubble_view_context_(context), | |
| 46 popup_(nullptr), | |
| 47 animation_(new gfx::SlideAnimation(this)) { | |
| 48 // Initially hide the bubble. | |
| 49 double initial_value = 0; | |
| 50 animation_->Reset(initial_value); | |
| 51 | |
| 52 // Create the contents view. | |
| 53 view_ = new SubtleNotificationView(nullptr); | |
| 54 UpdateViewContent(forward); | |
| 55 | |
| 56 // Initialize the popup. | |
| 57 popup_ = SubtleNotificationView::CreatePopupWidget( | |
| 58 bubble_view_context_->GetBubbleParentView(), view_, false); | |
| 59 gfx::Size size = GetPopupRect(true).size(); | |
| 60 // Bounds are in screen coordinates. | |
| 61 popup_->SetBounds(GetPopupRect(false)); | |
| 62 view_->SetBounds(0, 0, size.width(), size.height()); | |
|
Peter Kasting
2016/05/19 10:08:36
Nit: Can we just do view_->SetSize(size) like Upda
Matt Giuca
2016/05/23 04:22:56
Actually this was all duplicated with UpdateConten
| |
| 63 | |
| 64 Show(); | |
| 65 | |
| 66 // Do not allow the notification to hide for a few seconds. | |
|
Peter Kasting
2016/05/19 10:08:36
Nit: "Wait a few seconds before hiding"? After al
Matt Giuca
2016/05/23 04:22:56
Done.
| |
| 67 hide_timeout_.Start(FROM_HERE, | |
| 68 base::TimeDelta::FromMilliseconds(kShowDurationMs), this, | |
| 69 &BackspaceNewShortcutBubble::TimerElapsed); | |
| 70 } | |
| 71 | |
| 72 BackspaceNewShortcutBubble::~BackspaceNewShortcutBubble() { | |
| 73 // This is tricky. We may be in an ATL message handler stack, in which case | |
| 74 // the popup cannot be deleted yet. We also can't set the popup's ownership | |
| 75 // model to NATIVE_WIDGET_OWNS_WIDGET because if the user closed the last tab | |
| 76 // while in fullscreen mode, Windows has already destroyed the popup HWND by | |
|
Peter Kasting
2016/05/19 10:08:36
Is this all still relevant, given that this bubble
Matt Giuca
2016/05/23 04:22:57
I have no idea what the consequences of not doing
| |
| 77 // the time we get here, and thus either the popup will already have been | |
| 78 // deleted (if we set this in our constructor) or the popup will never get | |
| 79 // another OnFinalMessage() call (if not, as currently). So instead, we tell | |
| 80 // the popup to synchronously hide, and then asynchronously close and delete | |
| 81 // itself. | |
| 82 popup_->Close(); | |
| 83 base::MessageLoop::current()->DeleteSoon(FROM_HERE, popup_); | |
| 84 } | |
| 85 | |
| 86 void BackspaceNewShortcutBubble::UpdateContent(bool forward) { | |
| 87 UpdateViewContent(forward); | |
| 88 | |
| 89 gfx::Size size = GetPopupRect(true).size(); | |
|
Peter Kasting
2016/05/19 10:08:36
Nit: I'd just inline thie into the next line.
Matt Giuca
2016/05/23 04:22:56
Done.
| |
| 90 view_->SetSize(size); | |
| 91 popup_->SetBounds(GetPopupRect(false)); | |
| 92 Show(); | |
| 93 } | |
| 94 | |
| 95 void BackspaceNewShortcutBubble::UpdateBounds() { | |
|
Peter Kasting
2016/05/19 10:08:36
Who calls this method? It seems unused.
Matt Giuca
2016/05/23 04:22:56
Done.
| |
| 96 gfx::Rect popup_rect(GetPopupRect(false)); | |
| 97 if (!popup_rect.IsEmpty()) { | |
| 98 popup_->SetBounds(popup_rect); | |
| 99 view_->SetY(popup_rect.height() - view_->height()); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 void BackspaceNewShortcutBubble::UpdateViewContent(bool forward) { | |
| 104 base::string16 exit_instruction_text; | |
|
Peter Kasting
2016/05/19 10:08:36
Nit: Declare this down as close to initialization
Matt Giuca
2016/05/23 04:22:56
Done.
| |
| 105 // Note: The key names are parameters so that we can vary by operating system | |
| 106 // or change the direction of the arrow as necessary (see | |
| 107 // https://crbug.com/612685). | |
| 108 | |
| 109 #if defined(OS_MACOSX) | |
| 110 // U+2318 = PLACE OF INTEREST SIGN (Mac Command symbol). | |
| 111 base::string16 accelerator = base::WideToUTF16(L"\x2318"); | |
| 112 #else | |
| 113 base::string16 accelerator = l10n_util::GetStringUTF16(IDS_APP_ALT_KEY); | |
| 114 #endif | |
| 115 | |
| 116 if (forward) { | |
| 117 // U+2192 = RIGHTWARDS ARROW. | |
| 118 exit_instruction_text = | |
| 119 l10n_util::GetStringFUTF16(IDS_PRESS_ALT_RIGHT_TO_GO_FORWARD, | |
| 120 accelerator, base::WideToUTF16(L"\x2192")); | |
| 121 } else { | |
| 122 // U+2190 = LEFTWARDS ARROW. | |
| 123 exit_instruction_text = | |
| 124 l10n_util::GetStringFUTF16(IDS_PRESS_ALT_LEFT_TO_GO_BACK, accelerator, | |
| 125 base::WideToUTF16(L"\x2190")); | |
| 126 } | |
|
Peter Kasting
2016/05/19 10:08:36
Nit: Shorter:
// U+2192 = RIGHTWARDS ARROW; U+2
Matt Giuca
2016/05/23 04:22:57
Not a fan of a 5-line expression with multiple ter
| |
| 127 view_->UpdateContent(exit_instruction_text, base::string16()); | |
| 128 } | |
| 129 | |
| 130 views::View* BackspaceNewShortcutBubble::GetBrowserRootView() const { | |
|
Peter Kasting
2016/05/19 10:08:36
Another unused function?
Matt Giuca
2016/05/23 04:22:57
Done.
| |
| 131 return bubble_view_context_->GetBubbleAssociatedWidget()->GetRootView(); | |
| 132 } | |
| 133 | |
| 134 void BackspaceNewShortcutBubble::AnimationProgressed( | |
| 135 const gfx::Animation* animation) { | |
| 136 int opacity = animation_->CurrentValueBetween(0, 255); | |
| 137 if (opacity == 0) { | |
| 138 popup_->Hide(); | |
| 139 } else { | |
| 140 popup_->Show(); | |
| 141 popup_->SetOpacity(opacity); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 void BackspaceNewShortcutBubble::AnimationEnded( | |
| 146 const gfx::Animation* animation) { | |
| 147 AnimationProgressed(animation); | |
| 148 } | |
| 149 | |
| 150 gfx::Rect BackspaceNewShortcutBubble::GetPopupRect( | |
| 151 bool ignore_animation_state) const { | |
| 152 gfx::Size size(view_->GetPreferredSize()); | |
|
Peter Kasting
2016/05/19 10:08:36
Nit: Use = rather than () where possible
Matt Giuca
2016/05/23 04:22:56
Done.
| |
| 153 gfx::Rect widget_bounds = bubble_view_context_->GetClientAreaBoundsInScreen(); | |
| 154 int x = widget_bounds.x() + (widget_bounds.width() - size.width()) / 2; | |
| 155 int top_container_bottom = widget_bounds.y(); | |
| 156 // |desired_top| is the top of the bubble area including the shadow. | |
| 157 int desired_top = kPopupTopPx - view_->border()->GetInsets().top(); | |
| 158 int y = top_container_bottom + desired_top; | |
| 159 return gfx::Rect(gfx::Point(x, y), size); | |
| 160 } | |
| 161 | |
| 162 void BackspaceNewShortcutBubble::Hide() { | |
| 163 animation_->SetSlideDuration(kSlideOutDurationMs); | |
| 164 animation_->Hide(); | |
| 165 } | |
| 166 | |
| 167 void BackspaceNewShortcutBubble::Show() { | |
| 168 animation_->SetSlideDuration(kSlideInDurationMs); | |
| 169 animation_->Show(); | |
| 170 } | |
| 171 | |
| 172 void BackspaceNewShortcutBubble::TimerElapsed() { | |
| 173 Hide(); | |
| 174 } | |
| OLD | NEW |