OLD | NEW |
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" |
11 #include "chrome/browser/ui/views/content_setting_bubble_contents.h" | 11 #include "chrome/browser/ui/views/content_setting_bubble_contents.h" |
12 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 12 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
13 #include "chrome/grit/theme_resources.h" | 13 #include "chrome/grit/theme_resources.h" |
14 #include "ui/base/l10n/l10n_util.h" | 14 #include "ui/base/l10n/l10n_util.h" |
15 #include "ui/base/material_design/material_design_controller.h" | 15 #include "ui/base/material_design/material_design_controller.h" |
16 #include "ui/base/theme_provider.h" | 16 #include "ui/base/theme_provider.h" |
17 #include "ui/events/event_utils.h" | 17 #include "ui/events/event_utils.h" |
18 #include "ui/gfx/color_palette.h" | 18 #include "ui/gfx/color_palette.h" |
19 #include "ui/gfx/color_utils.h" | 19 #include "ui/gfx/color_utils.h" |
| 20 #include "ui/views/animation/ink_drop.h" |
20 #include "ui/views/animation/ink_drop_impl.h" | 21 #include "ui/views/animation/ink_drop_impl.h" |
21 #include "ui/views/controls/image_view.h" | 22 #include "ui/views/controls/image_view.h" |
22 #include "ui/views/controls/label.h" | 23 #include "ui/views/controls/label.h" |
23 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
24 | 25 |
25 namespace { | 26 namespace { |
26 // Time spent with animation fully open. | 27 // Time spent with animation fully open. |
27 const int kStayOpenTimeMS = 3200; | 28 const int kStayOpenTimeMS = 3200; |
28 } | 29 } |
29 | 30 |
30 // static | 31 // static |
31 const int ContentSettingImageView::kAnimationDurationMS = | 32 const int ContentSettingImageView::kAnimationDurationMS = |
32 (IconLabelBubbleView::kOpenTimeMS * 2) + kStayOpenTimeMS; | 33 (IconLabelBubbleView::kOpenTimeMS * 2) + kStayOpenTimeMS; |
33 | 34 |
34 ContentSettingImageView::ContentSettingImageView( | 35 ContentSettingImageView::ContentSettingImageView( |
35 std::unique_ptr<ContentSettingImageModel> image_model, | 36 std::unique_ptr<ContentSettingImageModel> image_model, |
36 LocationBarView* parent, | 37 LocationBarView* parent, |
37 const gfx::FontList& font_list) | 38 const gfx::FontList& font_list) |
38 : IconLabelBubbleView(font_list, false), | 39 : IconLabelBubbleView(font_list, false), |
39 parent_(parent), | 40 parent_(parent), |
40 content_setting_image_model_(std::move(image_model)), | 41 content_setting_image_model_(std::move(image_model)), |
41 slide_animator_(this), | 42 slide_animator_(this), |
42 pause_animation_(false), | 43 pause_animation_(false), |
43 pause_animation_state_(0.0), | 44 pause_animation_state_(0.0), |
44 bubble_view_(nullptr), | 45 bubble_view_(nullptr) { |
45 suppress_mouse_released_action_(false) { | |
46 set_next_element_interior_padding(LocationBarView::kIconInteriorPadding); | 46 set_next_element_interior_padding(LocationBarView::kIconInteriorPadding); |
47 SetInkDropMode(InkDropMode::ON); | 47 SetInkDropMode(InkDropMode::ON); |
48 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); | 48 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); |
49 image()->EnableCanvasFlippingForRTLUI(true); | 49 image()->EnableCanvasFlippingForRTLUI(true); |
50 label()->SetElideBehavior(gfx::NO_ELIDE); | 50 label()->SetElideBehavior(gfx::NO_ELIDE); |
51 label()->SetVisible(false); | 51 label()->SetVisible(false); |
52 | 52 |
53 slide_animator_.SetSlideDuration(kAnimationDurationMS); | 53 slide_animator_.SetSlideDuration(kAnimationDurationMS); |
54 slide_animator_.SetTweenType(gfx::Tween::LINEAR); | 54 slide_animator_.SetTweenType(gfx::Tween::LINEAR); |
55 } | 55 } |
(...skipping 18 matching lines...) Expand all Loading... |
74 | 74 |
75 // If the content usage or blockage should be indicated to the user, start the | 75 // If the content usage or blockage should be indicated to the user, start the |
76 // animation and record that the icon has been shown. | 76 // animation and record that the icon has been shown. |
77 if (!content_setting_image_model_->ShouldRunAnimation(web_contents)) | 77 if (!content_setting_image_model_->ShouldRunAnimation(web_contents)) |
78 return; | 78 return; |
79 | 79 |
80 // We just ignore this blockage if we're already showing some other string to | 80 // We just ignore this blockage if we're already showing some other string to |
81 // the user. If this becomes a problem, we could design some sort of queueing | 81 // the user. If this becomes a problem, we could design some sort of queueing |
82 // mechanism to show one after the other, but it doesn't seem important now. | 82 // mechanism to show one after the other, but it doesn't seem important now. |
83 int string_id = content_setting_image_model_->explanatory_string_id(); | 83 int string_id = content_setting_image_model_->explanatory_string_id(); |
| 84 AnimateInkDrop(views::InkDropState::HIDDEN, nullptr /* event */); |
84 if (string_id && !label()->visible()) { | 85 if (string_id && !label()->visible()) { |
85 AnimateInkDrop(views::InkDropState::HIDDEN, nullptr /* event */); | |
86 SetLabel(l10n_util::GetStringUTF16(string_id)); | 86 SetLabel(l10n_util::GetStringUTF16(string_id)); |
87 label()->SetVisible(true); | 87 label()->SetVisible(true); |
88 slide_animator_.Show(); | 88 AnimateIn(); |
89 } | 89 } |
90 | 90 |
91 content_setting_image_model_->SetAnimationHasRun(web_contents); | 91 content_setting_image_model_->SetAnimationHasRun(web_contents); |
92 } | 92 } |
93 | 93 |
94 const char* ContentSettingImageView::GetClassName() const { | 94 const char* ContentSettingImageView::GetClassName() const { |
95 return "ContentSettingsImageView"; | 95 return "ContentSettingsImageView"; |
96 } | 96 } |
97 | 97 |
98 void ContentSettingImageView::OnBoundsChanged( | 98 void ContentSettingImageView::OnBoundsChanged( |
99 const gfx::Rect& previous_bounds) { | 99 const gfx::Rect& previous_bounds) { |
100 if (bubble_view_) | 100 if (bubble_view_) |
101 bubble_view_->OnAnchorBoundsChanged(); | 101 bubble_view_->OnAnchorBoundsChanged(); |
102 } | 102 IconLabelBubbleView::OnBoundsChanged(previous_bounds); |
103 | |
104 bool ContentSettingImageView::OnMousePressed(const ui::MouseEvent& event) { | |
105 // If the bubble is showing then don't reshow it when the mouse is released. | |
106 suppress_mouse_released_action_ = bubble_view_ != nullptr; | |
107 if (!suppress_mouse_released_action_ && !label()->visible()) | |
108 AnimateInkDrop(views::InkDropState::ACTION_PENDING, &event); | |
109 | |
110 // We want to show the bubble on mouse release; that is the standard behavior | |
111 // for buttons. | |
112 return true; | |
113 } | |
114 | |
115 void ContentSettingImageView::OnMouseReleased(const ui::MouseEvent& event) { | |
116 // If this is the second click on this view then the bubble was showing on the | |
117 // mouse pressed event and is hidden now. Prevent the bubble from reshowing by | |
118 // doing nothing here. | |
119 if (suppress_mouse_released_action_) { | |
120 suppress_mouse_released_action_ = false; | |
121 return; | |
122 } | |
123 const bool activated = HitTestPoint(event.location()); | |
124 if (!label()->visible() && !activated) | |
125 AnimateInkDrop(views::InkDropState::HIDDEN, &event); | |
126 if (activated) | |
127 OnActivate(event); | |
128 } | |
129 | |
130 void ContentSettingImageView::OnGestureEvent(ui::GestureEvent* event) { | |
131 if (event->type() == ui::ET_GESTURE_TAP) | |
132 OnActivate(*event); | |
133 if ((event->type() == ui::ET_GESTURE_TAP) || | |
134 (event->type() == ui::ET_GESTURE_TAP_DOWN)) | |
135 event->SetHandled(); | |
136 } | 103 } |
137 | 104 |
138 bool ContentSettingImageView::GetTooltipText(const gfx::Point& p, | 105 bool ContentSettingImageView::GetTooltipText(const gfx::Point& p, |
139 base::string16* tooltip) const { | 106 base::string16* tooltip) const { |
140 *tooltip = content_setting_image_model_->get_tooltip(); | 107 *tooltip = content_setting_image_model_->get_tooltip(); |
141 return !tooltip->empty(); | 108 return !tooltip->empty(); |
142 } | 109 } |
143 | 110 |
144 void ContentSettingImageView::OnNativeThemeChanged( | 111 void ContentSettingImageView::OnNativeThemeChanged( |
145 const ui::NativeTheme* native_theme) { | 112 const ui::NativeTheme* native_theme) { |
146 UpdateImage(); | 113 UpdateImage(); |
147 IconLabelBubbleView::OnNativeThemeChanged(native_theme); | 114 IconLabelBubbleView::OnNativeThemeChanged(native_theme); |
148 } | 115 } |
149 | 116 |
150 std::unique_ptr<views::InkDrop> ContentSettingImageView::CreateInkDrop() { | |
151 std::unique_ptr<views::InkDropImpl> ink_drop = CreateDefaultInkDropImpl(); | |
152 ink_drop->SetShowHighlightOnFocus(true); | |
153 return std::move(ink_drop); | |
154 } | |
155 | |
156 SkColor ContentSettingImageView::GetTextColor() const { | 117 SkColor ContentSettingImageView::GetTextColor() const { |
157 return GetNativeTheme()->GetSystemColor( | 118 return GetNativeTheme()->GetSystemColor( |
158 ui::NativeTheme::kColorId_TextfieldDefaultColor); | 119 ui::NativeTheme::kColorId_TextfieldDefaultColor); |
159 } | 120 } |
160 | 121 |
161 bool ContentSettingImageView::ShouldShowLabel() const { | 122 bool ContentSettingImageView::ShouldShowLabel() const { |
162 return (!IsShrinking() || (width() > image()->GetPreferredSize().width())) && | 123 return (!IsShrinking() || (width() > image()->GetPreferredSize().width())) && |
163 (slide_animator_.is_animating() || pause_animation_); | 124 (slide_animator_.is_animating() || pause_animation_); |
164 } | 125 } |
165 | 126 |
(...skipping 13 matching lines...) Expand all Loading... |
179 return size_fraction; | 140 return size_fraction; |
180 } | 141 } |
181 | 142 |
182 bool ContentSettingImageView::IsShrinking() const { | 143 bool ContentSettingImageView::IsShrinking() const { |
183 const double kOpenFraction = | 144 const double kOpenFraction = |
184 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS; | 145 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS; |
185 return (!pause_animation_ && slide_animator_.is_animating() && | 146 return (!pause_animation_ && slide_animator_.is_animating() && |
186 slide_animator_.GetCurrentValue() > (1.0 - kOpenFraction)); | 147 slide_animator_.GetCurrentValue() > (1.0 - kOpenFraction)); |
187 } | 148 } |
188 | 149 |
189 bool ContentSettingImageView::OnActivate(const ui::Event& event) { | 150 bool ContentSettingImageView::ShowBubble(const ui::Event& event) { |
190 if (slide_animator_.is_animating()) { | 151 if (slide_animator_.is_animating()) { |
191 // If the user clicks while we're animating, the bubble arrow will be | 152 // If the user clicks while we're animating, the bubble arrow will be |
192 // pointing to the image, and if we allow the animation to keep running, the | 153 // pointing to the image, and if we allow the animation to keep running, the |
193 // image will move away from the arrow (or we'll have to move the bubble, | 154 // image will move away from the arrow (or we'll have to move the bubble, |
194 // which is even worse). So we want to stop the animation. We have two | 155 // which is even worse). So we want to stop the animation. We have two |
195 // choices: jump to the final post-animation state (no label visible), or | 156 // choices: jump to the final post-animation state (no label visible), or |
196 // pause the animation where we are and continue running after the bubble | 157 // pause the animation where we are and continue running after the bubble |
197 // closes. The former looks more jerky, so we avoid it unless the animation | 158 // closes. The former looks more jerky, so we avoid it unless the animation |
198 // hasn't even fully exposed the image yet, in which case pausing with half | 159 // hasn't even fully exposed the image yet, in which case pausing with half |
199 // an image visible will look broken. | 160 // an image visible will look broken. |
(...skipping 26 matching lines...) Expand all Loading... |
226 AnimateInkDrop(views::InkDropState::ACTIVATED, | 187 AnimateInkDrop(views::InkDropState::ACTIVATED, |
227 ui::LocatedEvent::FromIfValid(&event)); | 188 ui::LocatedEvent::FromIfValid(&event)); |
228 bubble_view_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT); | 189 bubble_view_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT); |
229 } | 190 } |
230 bubble_widget->Show(); | 191 bubble_widget->Show(); |
231 } | 192 } |
232 | 193 |
233 return true; | 194 return true; |
234 } | 195 } |
235 | 196 |
| 197 bool ContentSettingImageView::IsBubbleShowing() const { |
| 198 return bubble_view_ != nullptr; |
| 199 } |
| 200 |
236 void ContentSettingImageView::AnimationEnded(const gfx::Animation* animation) { | 201 void ContentSettingImageView::AnimationEnded(const gfx::Animation* animation) { |
237 slide_animator_.Reset(); | 202 slide_animator_.Reset(); |
238 if (!pause_animation_) { | 203 if (!pause_animation_) { |
239 label()->SetVisible(false); | 204 label()->SetVisible(false); |
240 parent_->Layout(); | 205 parent_->Layout(); |
241 parent_->SchedulePaint(); | 206 parent_->SchedulePaint(); |
242 } | 207 } |
| 208 |
| 209 GetInkDrop()->SetShowHighlightOnHover(true); |
| 210 GetInkDrop()->SetShowHighlightOnFocus(true); |
243 } | 211 } |
244 | 212 |
245 void ContentSettingImageView::AnimationProgressed( | 213 void ContentSettingImageView::AnimationProgressed( |
246 const gfx::Animation* animation) { | 214 const gfx::Animation* animation) { |
247 if (!pause_animation_) { | 215 if (!pause_animation_) { |
248 parent_->Layout(); | 216 parent_->Layout(); |
249 parent_->SchedulePaint(); | 217 parent_->SchedulePaint(); |
250 } | 218 } |
251 } | 219 } |
252 | 220 |
253 void ContentSettingImageView::AnimationCanceled( | 221 void ContentSettingImageView::AnimationCanceled( |
254 const gfx::Animation* animation) { | 222 const gfx::Animation* animation) { |
255 AnimationEnded(animation); | 223 AnimationEnded(animation); |
256 } | 224 } |
257 | 225 |
258 void ContentSettingImageView::OnWidgetDestroying(views::Widget* widget) { | 226 void ContentSettingImageView::OnWidgetDestroying(views::Widget* widget) { |
259 DCHECK(bubble_view_); | 227 DCHECK(bubble_view_); |
260 DCHECK_EQ(bubble_view_->GetWidget(), widget); | 228 DCHECK_EQ(bubble_view_->GetWidget(), widget); |
261 widget->RemoveObserver(this); | 229 widget->RemoveObserver(this); |
262 bubble_view_ = nullptr; | 230 bubble_view_ = nullptr; |
263 | 231 |
264 if (pause_animation_) { | 232 if (pause_animation_) { |
265 slide_animator_.Reset(pause_animation_state_); | 233 slide_animator_.Reset(pause_animation_state_); |
266 pause_animation_ = false; | 234 pause_animation_ = false; |
267 slide_animator_.Show(); | 235 AnimateIn(); |
268 } | 236 } |
269 } | 237 } |
270 | 238 |
271 void ContentSettingImageView::OnWidgetVisibilityChanged(views::Widget* widget, | 239 void ContentSettingImageView::OnWidgetVisibilityChanged(views::Widget* widget, |
272 bool visible) { | 240 bool visible) { |
273 // |widget| is a bubble that has just got shown / hidden. | 241 // |widget| is a bubble that has just got shown / hidden. |
274 if (!visible && !label()->visible()) | 242 if (!visible) |
275 AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr /* event */); | 243 AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr /* event */); |
276 } | 244 } |
277 | 245 |
278 void ContentSettingImageView::UpdateImage() { | 246 void ContentSettingImageView::UpdateImage() { |
279 SetImage(content_setting_image_model_->GetIcon(GetTextColor()).AsImageSkia()); | 247 SetImage(content_setting_image_model_->GetIcon(GetTextColor()).AsImageSkia()); |
280 } | 248 } |
| 249 |
| 250 void ContentSettingImageView::AnimateIn() { |
| 251 slide_animator_.Show(); |
| 252 GetInkDrop()->SetShowHighlightOnHover(false); |
| 253 GetInkDrop()->SetShowHighlightOnFocus(false); |
| 254 } |
OLD | NEW |