Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: chrome/browser/ui/views/location_bar/content_setting_image_view.cc

Issue 1763713004: Adjusts content bubble animation with respect to icon size (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adjusts content bubble animation with respect to icon size (nits) Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/location_bar/content_setting_image_view.h" 5 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/themes/theme_properties.h" 8 #include "chrome/browser/themes/theme_properties.h"
9 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" 9 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
10 #include "chrome/browser/ui/content_settings/content_setting_image_model.h" 10 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 pause_animation_state_(0.0), 49 pause_animation_state_(0.0),
50 bubble_view_(nullptr), 50 bubble_view_(nullptr),
51 suppress_mouse_released_action_(false), 51 suppress_mouse_released_action_(false),
52 ink_drop_delegate_(new views::ButtonInkDropDelegate(this, this)) { 52 ink_drop_delegate_(new views::ButtonInkDropDelegate(this, this)) {
53 if (!ui::MaterialDesignController::IsModeMaterial()) { 53 if (!ui::MaterialDesignController::IsModeMaterial()) {
54 static const int kBackgroundImages[] = 54 static const int kBackgroundImages[] =
55 IMAGE_GRID(IDR_OMNIBOX_CONTENT_SETTING_BUBBLE); 55 IMAGE_GRID(IDR_OMNIBOX_CONTENT_SETTING_BUBBLE);
56 SetBackgroundImageGrid(kBackgroundImages); 56 SetBackgroundImageGrid(kBackgroundImages);
57 } 57 }
58 58
59 image()->SetHorizontalAlignment(views::ImageView::LEADING); 59 image()->SetHorizontalAlignment(base::i18n::IsRTL()
60 ? views::ImageView::TRAILING
61 : views::ImageView::LEADING);
60 image()->set_interactive(true); 62 image()->set_interactive(true);
61 image()->EnableCanvasFlippingForRTLUI(true); 63 image()->EnableCanvasFlippingForRTLUI(true);
62 image()->SetAccessibilityFocusable(true); 64 image()->SetAccessibilityFocusable(true);
63 label()->SetElideBehavior(gfx::NO_ELIDE); 65 label()->SetElideBehavior(gfx::NO_ELIDE);
64 label()->SetVisible(false); 66 label()->SetVisible(false);
65 67
66 slide_animator_.SetSlideDuration(kAnimationDurationMS); 68 slide_animator_.SetSlideDuration(kAnimationDurationMS);
67 slide_animator_.SetTweenType(gfx::Tween::LINEAR); 69 slide_animator_.SetTweenType(gfx::Tween::LINEAR);
68 } 70 }
69 71
(...skipping 17 matching lines...) Expand all
87 89
88 // If the content usage or blockage should be indicated to the user, start the 90 // If the content usage or blockage should be indicated to the user, start the
89 // animation and record that the icon has been shown. 91 // animation and record that the icon has been shown.
90 if (!content_setting_image_model_->ShouldRunAnimation(web_contents)) 92 if (!content_setting_image_model_->ShouldRunAnimation(web_contents))
91 return; 93 return;
92 94
93 // We just ignore this blockage if we're already showing some other string to 95 // We just ignore this blockage if we're already showing some other string to
94 // the user. If this becomes a problem, we could design some sort of queueing 96 // the user. If this becomes a problem, we could design some sort of queueing
95 // mechanism to show one after the other, but it doesn't seem important now. 97 // mechanism to show one after the other, but it doesn't seem important now.
96 int string_id = content_setting_image_model_->explanatory_string_id(); 98 int string_id = content_setting_image_model_->explanatory_string_id();
97 if (string_id && !ShouldShowBackground()) { 99 if (string_id && !label()->visible()) {
100 ink_drop_delegate_->OnAction(views::InkDropState::HIDDEN);
98 SetLabel(l10n_util::GetStringUTF16(string_id)); 101 SetLabel(l10n_util::GetStringUTF16(string_id));
99 label()->SetVisible(true); 102 label()->SetVisible(true);
100 slide_animator_.Show(); 103 slide_animator_.Show();
101 } 104 }
102 105
103 content_setting_image_model_->SetAnimationHasRun(web_contents); 106 content_setting_image_model_->SetAnimationHasRun(web_contents);
104 } 107 }
105 108
106 SkColor ContentSettingImageView::GetTextColor() const { 109 SkColor ContentSettingImageView::GetTextColor() const {
107 return GetNativeTheme()->GetSystemColor( 110 return GetNativeTheme()->GetSystemColor(
108 ui::NativeTheme::kColorId_TextfieldDefaultColor); 111 ui::NativeTheme::kColorId_TextfieldDefaultColor);
109 } 112 }
110 113
111 SkColor ContentSettingImageView::GetBorderColor() const { 114 SkColor ContentSettingImageView::GetBorderColor() const {
112 return gfx::kGoogleYellow700; 115 return gfx::kGoogleYellow700;
113 } 116 }
114 117
115 bool ContentSettingImageView::ShouldShowBackground() const { 118 bool ContentSettingImageView::ShouldShowBackground() const {
116 return slide_animator_.is_animating() || pause_animation_; 119 return (!IsShrinking() || label()->width() > 0) &&
120 (slide_animator_.is_animating() || pause_animation_);
117 } 121 }
118 122
119 double ContentSettingImageView::WidthMultiplier() const { 123 double ContentSettingImageView::WidthMultiplier() const {
120 double state = pause_animation_ ? pause_animation_state_ 124 double state = pause_animation_ ? pause_animation_state_
121 : slide_animator_.GetCurrentValue(); 125 : slide_animator_.GetCurrentValue();
122 // The fraction of the animation we'll spend animating the string into view, 126 // The fraction of the animation we'll spend animating the string into view,
123 // which is also the fraction we'll spend animating it closed; total 127 // which is also the fraction we'll spend animating it closed; total
124 // animation (slide out, show, then slide in) is 1.0. 128 // animation (slide out, show, then slide in) is 1.0.
125 const double kOpenFraction = 129 const double kOpenFraction =
126 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS; 130 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS;
127 double size_fraction = 1.0; 131 double size_fraction = 1.0;
128 if (state < kOpenFraction) 132 if (state < kOpenFraction)
129 size_fraction = state / kOpenFraction; 133 size_fraction = state / kOpenFraction;
130 if (state > (1.0 - kOpenFraction)) 134 if (state > (1.0 - kOpenFraction))
131 size_fraction = (1.0 - state) / kOpenFraction; 135 size_fraction = (1.0 - state) / kOpenFraction;
132 return size_fraction; 136 return size_fraction;
133 } 137 }
134 138
139 bool ContentSettingImageView::IsShrinking() const {
140 const double kOpenFraction =
141 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS;
142 return (!pause_animation_ && slide_animator_.is_animating() &&
143 slide_animator_.GetCurrentValue() > (1.0 - kOpenFraction));
144 }
145
135 void ContentSettingImageView::AnimationEnded(const gfx::Animation* animation) { 146 void ContentSettingImageView::AnimationEnded(const gfx::Animation* animation) {
136 slide_animator_.Reset(); 147 slide_animator_.Reset();
137 if (!pause_animation_) { 148 if (!pause_animation_) {
138 label()->SetVisible(false); 149 label()->SetVisible(false);
139 parent_->Layout(); 150 parent_->Layout();
140 parent_->SchedulePaint(); 151 parent_->SchedulePaint();
141 } 152 }
142 } 153 }
143 154
144 void ContentSettingImageView::AnimationProgressed( 155 void ContentSettingImageView::AnimationProgressed(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 188
178 void ContentSettingImageView::OnMouseReleased(const ui::MouseEvent& event) { 189 void ContentSettingImageView::OnMouseReleased(const ui::MouseEvent& event) {
179 // If this is the second click on this view then the bubble was showing on the 190 // If this is the second click on this view then the bubble was showing on the
180 // mouse pressed event and is hidden now. Prevent the bubble from reshowing by 191 // mouse pressed event and is hidden now. Prevent the bubble from reshowing by
181 // doing nothing here. 192 // doing nothing here.
182 if (suppress_mouse_released_action_) { 193 if (suppress_mouse_released_action_) {
183 suppress_mouse_released_action_ = false; 194 suppress_mouse_released_action_ = false;
184 return; 195 return;
185 } 196 }
186 const bool activated = HitTestPoint(event.location()); 197 const bool activated = HitTestPoint(event.location());
187 if (!label()->visible()) { 198 if (!label()->visible() && !activated)
188 ink_drop_delegate_->OnAction(activated ? views::InkDropState::ACTIVATED 199 ink_drop_delegate_->OnAction(views::InkDropState::HIDDEN);
189 : views::InkDropState::HIDDEN);
190 }
191 if (activated) 200 if (activated)
192 OnClick(); 201 OnClick();
193 } 202 }
194 203
195 bool ContentSettingImageView::OnKeyPressed(const ui::KeyEvent& event) { 204 bool ContentSettingImageView::OnKeyPressed(const ui::KeyEvent& event) {
196 if (event.key_code() != ui::VKEY_SPACE && event.key_code() != ui::VKEY_RETURN) 205 if (event.key_code() != ui::VKEY_SPACE && event.key_code() != ui::VKEY_RETURN)
197 return false; 206 return false;
198 207
199 ink_drop_delegate_->OnAction(views::InkDropState::ACTIVATED);
200 OnClick(); 208 OnClick();
201 return true; 209 return true;
202 } 210 }
203 211
204 void ContentSettingImageView::OnGestureEvent(ui::GestureEvent* event) { 212 void ContentSettingImageView::OnGestureEvent(ui::GestureEvent* event) {
205 if (event->type() == ui::ET_GESTURE_TAP) { 213 if (event->type() == ui::ET_GESTURE_TAP)
206 if (!label()->visible())
207 ink_drop_delegate_->OnAction(views::InkDropState::ACTIVATED);
208 OnClick(); 214 OnClick();
209 }
210 if ((event->type() == ui::ET_GESTURE_TAP) || 215 if ((event->type() == ui::ET_GESTURE_TAP) ||
211 (event->type() == ui::ET_GESTURE_TAP_DOWN)) 216 (event->type() == ui::ET_GESTURE_TAP_DOWN))
212 event->SetHandled(); 217 event->SetHandled();
213 } 218 }
214 219
215 void ContentSettingImageView::OnNativeThemeChanged( 220 void ContentSettingImageView::OnNativeThemeChanged(
216 const ui::NativeTheme* native_theme) { 221 const ui::NativeTheme* native_theme) {
217 if (ui::MaterialDesignController::IsModeMaterial()) 222 if (ui::MaterialDesignController::IsModeMaterial())
218 UpdateImage(); 223 UpdateImage();
219 224
(...skipping 15 matching lines...) Expand all
235 240
236 void ContentSettingImageView::OnWidgetVisibilityChanged(views::Widget* widget, 241 void ContentSettingImageView::OnWidgetVisibilityChanged(views::Widget* widget,
237 bool visible) { 242 bool visible) {
238 // |widget| is a bubble that has just got shown / hidden. 243 // |widget| is a bubble that has just got shown / hidden.
239 if (!visible && !label()->visible()) 244 if (!visible && !label()->visible())
240 ink_drop_delegate_->OnAction(views::InkDropState::DEACTIVATED); 245 ink_drop_delegate_->OnAction(views::InkDropState::DEACTIVATED);
241 } 246 }
242 247
243 void ContentSettingImageView::OnClick() { 248 void ContentSettingImageView::OnClick() {
244 if (slide_animator_.is_animating()) { 249 if (slide_animator_.is_animating()) {
245 if (!pause_animation_) { 250 // If the user clicks while we're animating, the bubble arrow will be
251 // pointing to the image, and if we allow the animation to keep running, the
252 // image will move away from the arrow (or we'll have to move the bubble,
253 // which is even worse). So we want to stop the animation. We have two
254 // choices: jump to the final post-animation state (no label visible), or
255 // pause the animation where we are and continue running after the bubble
256 // closes. The former looks more jerky, so we avoid it unless the animation
257 // hasn't even fully exposed the image yet, in which case pausing with half
258 // an image visible will look broken.
259 const int final_width = image()->GetPreferredSize().width() +
260 GetBubbleOuterPadding(true) +
261 GetBubbleOuterPadding(false);
262 if (!pause_animation_ && ShouldShowBackground() && width() > final_width) {
246 pause_animation_ = true; 263 pause_animation_ = true;
247 pause_animation_state_ = slide_animator_.GetCurrentValue(); 264 pause_animation_state_ = slide_animator_.GetCurrentValue();
248 } 265 }
249 slide_animator_.Reset(); 266 slide_animator_.Reset();
250 } 267 }
251 268
252 content::WebContents* web_contents = parent_->GetWebContents(); 269 content::WebContents* web_contents = parent_->GetWebContents();
253 if (web_contents && !bubble_view_) { 270 if (web_contents && !bubble_view_) {
254 bubble_view_ = new ContentSettingBubbleContents( 271 bubble_view_ = new ContentSettingBubbleContents(
255 content_setting_image_model_->CreateBubbleModel( 272 content_setting_image_model_->CreateBubbleModel(
256 parent_->delegate()->GetContentSettingBubbleModelDelegate(), 273 parent_->delegate()->GetContentSettingBubbleModelDelegate(),
257 web_contents, parent_->profile()), 274 web_contents, parent_->profile()),
258 web_contents, this, views::BubbleBorder::TOP_RIGHT); 275 web_contents, this, views::BubbleBorder::TOP_RIGHT);
259 views::Widget* bubble_widget = 276 views::Widget* bubble_widget =
260 parent_->delegate()->CreateViewsBubble(bubble_view_); 277 parent_->delegate()->CreateViewsBubble(bubble_view_);
261 bubble_widget->AddObserver(this); 278 bubble_widget->AddObserver(this);
262 // This is triggered by an input event. If the user clicks the icon while 279 // This is triggered by an input event. If the user clicks the icon while
263 // it's not animating, the icon will be placed in an active state, so the 280 // it's not animating, the icon will be placed in an active state, so the
264 // bubble doesn't need an arrow. If the user clicks during an animation, 281 // bubble doesn't need an arrow. If the user clicks during an animation,
265 // the animation simply pauses and no other visible state change occurs, so 282 // the animation simply pauses and no other visible state change occurs, so
266 // show the arrow in this case. 283 // show the arrow in this case.
267 if (ui::MaterialDesignController::IsModeMaterial() && !pause_animation_) 284 if (ui::MaterialDesignController::IsModeMaterial() && !pause_animation_) {
285 ink_drop_delegate_->OnAction(views::InkDropState::ACTIVATED);
268 bubble_view_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT); 286 bubble_view_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT);
287 }
269 bubble_widget->Show(); 288 bubble_widget->Show();
270 } 289 }
271 } 290 }
272 291
273 void ContentSettingImageView::UpdateImage() { 292 void ContentSettingImageView::UpdateImage() {
274 SetImage(content_setting_image_model_->GetIcon(GetTextColor()).AsImageSkia()); 293 SetImage(content_setting_image_model_->GetIcon(GetTextColor()).AsImageSkia());
275 image()->SetTooltipText(content_setting_image_model_->get_tooltip()); 294 image()->SetTooltipText(content_setting_image_model_->get_tooltip());
276 } 295 }
277 296
278 bool ContentSettingImageView::IsBubbleShowing() const { 297 bool ContentSettingImageView::IsBubbleShowing() const {
279 return bubble_view_ != nullptr; 298 return bubble_view_ != nullptr;
280 } 299 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698