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

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

Issue 16209002: ContentSettingImageView cleanup, phase 2. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/location_bar/content_setting_image_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 8 #include "chrome/browser/content_settings/tab_specific_content_settings.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 "content/public/browser/web_contents.h"
14 #include "third_party/skia/include/core/SkShader.h"
15 #include "ui/base/animation/slide_animation.h"
16 #include "ui/base/animation/tween.h"
17 #include "ui/base/l10n/l10n_util.h" 13 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h" 14 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/skia_util.h"
21 #include "ui/views/border.h"
22 #include "ui/views/controls/image_view.h" 15 #include "ui/views/controls/image_view.h"
23 #include "ui/views/controls/label.h" 16 #include "ui/views/controls/label.h"
24 #include "ui/views/layout/box_layout.h" 17 #include "ui/views/layout/box_layout.h"
25 #include "ui/views/widget/widget.h" 18 #include "ui/views/widget/widget.h"
26 19
27 using content::WebContents;
28
29 20
30 namespace { 21 namespace {
31 // Animation parameters. 22 const int kStayOpenTimeMS = 3200; // Time spent with animation fully open.
32 const int kFrameRateHz = 60;
33 const int kOpenTimeMs = 150;
34 const int kFullOpenedTimeMs = 3200;
35 const int kMoveTimeMs = kFullOpenedTimeMs + 2 * kOpenTimeMs;
36
37 // The fraction of the animation we'll spend animating the string into view, and
38 // then again animating it closed - total animation (slide out, show, then
39 // slide in) is 1.0.
40 const double kAnimatingFraction = kOpenTimeMs * 1.0 / kMoveTimeMs;
41 23
42 // Margins for animated box (pixels). 24 // Margins for animated box (pixels).
43 const int kHorizMargin = 4; 25 const int kHorizMargin = 4;
44 const int kIconLabelSpacing = 4; 26 const int kIconLabelSpacing = 4;
45 } 27 }
46 28
47 29
30 // static
31 const int ContentSettingImageView::kOpenTimeMS = 150;
32 const int ContentSettingImageView::kAnimationDurationMS =
33 (kOpenTimeMS * 2) + kStayOpenTimeMS;
34
48 ContentSettingImageView::ContentSettingImageView( 35 ContentSettingImageView::ContentSettingImageView(
49 ContentSettingsType content_type, 36 ContentSettingsType content_type,
50 const int background_images[], 37 const int background_images[],
51 LocationBarView* parent, 38 LocationBarView* parent,
52 const gfx::Font& font, 39 const gfx::Font& font,
53 int font_y_offset, 40 int font_y_offset,
54 SkColor font_color) 41 SkColor font_color)
55 : parent_(parent), 42 : parent_(parent),
56 content_setting_image_model_( 43 content_setting_image_model_(
57 ContentSettingImageModel::CreateContentSettingImageModel( 44 ContentSettingImageModel::CreateContentSettingImageModel(
58 content_type)), 45 content_type)),
59 background_painter_(background_images), 46 background_painter_(new views::HorizontalPainter(background_images)),
60 icon_(new views::ImageView), 47 icon_(new views::ImageView),
61 text_label_(NULL), 48 text_label_(NULL),
62 slide_animator_(this), 49 slide_animator_(this),
63 pause_animation_(false), 50 pause_animation_(false),
64 pause_animation_state_(0.0), 51 pause_animation_state_(0.0),
65 bubble_widget_(NULL), 52 bubble_widget_(NULL),
66 font_(font), 53 font_(font),
67 text_size_(0), 54 text_size_(0) {
68 visible_text_size_(0) {
69 SetLayoutManager(new views::BoxLayout( 55 SetLayoutManager(new views::BoxLayout(
70 views::BoxLayout::kHorizontal, 0, 0, 0)); 56 views::BoxLayout::kHorizontal, 0, 0, 0));
71 icon_->SetHorizontalAlignment(views::ImageView::LEADING); 57 icon_->SetHorizontalAlignment(views::ImageView::LEADING);
72 AddChildView(icon_); 58 AddChildView(icon_);
73 TouchableLocationBarView::Init(this); 59 TouchableLocationBarView::Init(this);
74 60
75 slide_animator_.SetSlideDuration(kMoveTimeMs); 61 slide_animator_.SetSlideDuration(kAnimationDurationMS);
76 slide_animator_.SetTweenType(ui::Tween::LINEAR); 62 slide_animator_.SetTweenType(ui::Tween::LINEAR);
77 } 63 }
78 64
79 ContentSettingImageView::~ContentSettingImageView() { 65 ContentSettingImageView::~ContentSettingImageView() {
80 if (bubble_widget_) { 66 if (bubble_widget_)
81 bubble_widget_->RemoveObserver(this); 67 bubble_widget_->RemoveObserver(this);
82 bubble_widget_ = NULL;
83 }
84 } 68 }
85 69
86 int ContentSettingImageView::GetBuiltInHorizontalPadding() const { 70 int ContentSettingImageView::GetBuiltInHorizontalPadding() const {
87 return GetBuiltInHorizontalPaddingImpl(); 71 return GetBuiltInHorizontalPaddingImpl();
88 } 72 }
89 73
90 void ContentSettingImageView::Update(WebContents* web_contents) { 74 void ContentSettingImageView::Update(content::WebContents* web_contents) {
91 if (web_contents) { 75 if (web_contents)
92 content_setting_image_model_->UpdateFromWebContents(web_contents); 76 content_setting_image_model_->UpdateFromWebContents(web_contents);
93 } 77
94 if (!content_setting_image_model_->is_visible()) { 78 if (!content_setting_image_model_->is_visible()) {
95 SetVisible(false); 79 SetVisible(false);
96 return; 80 return;
97 } 81 }
82
98 icon_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 83 icon_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
99 content_setting_image_model_->get_icon())); 84 content_setting_image_model_->get_icon()));
100 icon_->SetTooltipText( 85 icon_->SetTooltipText(
101 UTF8ToUTF16(content_setting_image_model_->get_tooltip())); 86 UTF8ToUTF16(content_setting_image_model_->get_tooltip()));
102 SetVisible(true); 87 SetVisible(true);
103 88
104 TabSpecificContentSettings* content_settings = NULL; 89 // If the content blockage should be indicated to the user, start the
105 if (web_contents) { 90 // animation and record that we indicated the blockage.
106 content_settings = 91 TabSpecificContentSettings* content_settings = web_contents ?
107 TabSpecificContentSettings::FromWebContents(web_contents); 92 TabSpecificContentSettings::FromWebContents(web_contents) : NULL;
108 }
109
110 if (!content_settings || content_settings->IsBlockageIndicated( 93 if (!content_settings || content_settings->IsBlockageIndicated(
111 content_setting_image_model_->get_content_settings_type())) 94 content_setting_image_model_->get_content_settings_type()))
112 return; 95 return;
113 96
114 // The content blockage was not yet indicated to the user. Start indication 97 // We just ignore this blockage if we're already showing some other string to
115 // animation and clear "not yet shown" flag. 98 // the user. If this becomes a problem, we could design some sort of queueing
116 content_settings->SetBlockageHasBeenIndicated( 99 // mechanism to show one after the other, but it doesn't seem important now.
117 content_setting_image_model_->get_content_settings_type()); 100 int string_id = content_setting_image_model_->explanatory_string_id();
118 101 if (string_id && !background_showing()) {
119 int animated_string_id =
120 content_setting_image_model_->explanatory_string_id();
121 // Check if the string for animation is available.
122 if (!animated_string_id)
123 return;
124
125 // Do not start animation if already in progress.
126 if (!slide_animator_.is_animating()) {
127 // Initialize animated string. It will be cleared when animation is 102 // Initialize animated string. It will be cleared when animation is
128 // completed. 103 // completed.
129 if (!text_label_) { 104 if (!text_label_) {
130 text_label_ = new views::Label; 105 text_label_ = new views::Label;
131 text_label_->SetElideBehavior(views::Label::NO_ELIDE); 106 text_label_->SetElideBehavior(views::Label::NO_ELIDE);
132 text_label_->SetFont(font_); 107 text_label_->SetFont(font_);
133 SetLayoutManager(new views::BoxLayout( 108 SetLayoutManager(new views::BoxLayout(
134 views::BoxLayout::kHorizontal, kHorizMargin, 0, kIconLabelSpacing)); 109 views::BoxLayout::kHorizontal, kHorizMargin, 0, kIconLabelSpacing));
135 AddChildView(text_label_); 110 AddChildView(text_label_);
136 } 111 }
137 text_label_->SetText(l10n_util::GetStringUTF16(animated_string_id)); 112 text_label_->SetText(l10n_util::GetStringUTF16(string_id));
138 text_size_ = font_.GetStringWidth(text_label_->text()); 113 text_size_ = font_.GetStringWidth(text_label_->text());
139 text_size_ += kHorizMargin; 114 text_size_ += kHorizMargin;
140 slide_animator_.Show(); 115 slide_animator_.Show();
141 } 116 }
117
118 content_settings->SetBlockageHasBeenIndicated(
119 content_setting_image_model_->get_content_settings_type());
142 } 120 }
143 121
144 void ContentSettingImageView::AnimationEnded(const ui::Animation* animation) { 122 void ContentSettingImageView::AnimationEnded(const ui::Animation* animation) {
123 slide_animator_.Reset();
145 if (!pause_animation_) { 124 if (!pause_animation_) {
146 SetLayoutManager(new views::BoxLayout( 125 SetLayoutManager(new views::BoxLayout(
147 views::BoxLayout::kHorizontal, 0, 0, 0)); 126 views::BoxLayout::kHorizontal, 0, 0, 0));
148 RemoveChildView(text_label_); // will also delete the view. 127 RemoveChildView(text_label_); // will also delete the view.
149 text_label_ = NULL; 128 text_label_ = NULL;
150 parent_->Layout(); 129 parent_->Layout();
151 parent_->SchedulePaint(); 130 parent_->SchedulePaint();
152 } 131 }
153 slide_animator_.Reset();
154 } 132 }
155 133
156 void ContentSettingImageView::AnimationProgressed( 134 void ContentSettingImageView::AnimationProgressed(
157 const ui::Animation* animation) { 135 const ui::Animation* animation) {
158 if (pause_animation_) 136 if (!pause_animation_) {
159 return; 137 parent_->Layout();
160 138 parent_->SchedulePaint();
161 visible_text_size_ = GetTextAnimationSize(slide_animator_.GetCurrentValue(), 139 }
162 text_size_);
163
164 parent_->Layout();
165 parent_->SchedulePaint();
166 } 140 }
167 141
168 void ContentSettingImageView::AnimationCanceled( 142 void ContentSettingImageView::AnimationCanceled(
169 const ui::Animation* animation) { 143 const ui::Animation* animation) {
170 AnimationEnded(animation); 144 AnimationEnded(animation);
171 } 145 }
172 146
173 gfx::Size ContentSettingImageView::GetPreferredSize() { 147 gfx::Size ContentSettingImageView::GetPreferredSize() {
174 // Height will be ignored by the LocationBarView. 148 // Height will be ignored by the LocationBarView.
175 gfx::Size preferred_size(views::View::GetPreferredSize()); 149 gfx::Size preferred_size(views::View::GetPreferredSize());
176 int non_label_width = preferred_size.width() - 150 int non_label_width = preferred_size.width() -
177 (text_label_ ? text_label_->GetPreferredSize().width() : 0); 151 (text_label_ ? text_label_->GetPreferredSize().width() : 0);
178 // When view is animated |visible_text_size_| > 0, it is 0 otherwise. 152
179 preferred_size.set_width(non_label_width + visible_text_size_); 153 int visible_text_size = 0;
154 if (background_showing()) {
155 double state = slide_animator_.GetCurrentValue();
156 // The fraction of the animation we'll spend animating the string into view,
157 // which is also the fraction we'll spend animating it closed; total
158 // animation (slide out, show, then slide in) is 1.0.
159 const double kOpenFraction =
160 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS;
161 double size_fraction = 1.0;
162 if (state < kOpenFraction)
163 size_fraction = state / kOpenFraction;
164 if (state > (1.0 - kOpenFraction))
165 size_fraction = (1.0 - state) / kOpenFraction;
166 visible_text_size = size_fraction * text_size_;
167 }
168
169 preferred_size.set_width(non_label_width + visible_text_size);
180 return preferred_size; 170 return preferred_size;
181 } 171 }
182 172
183 bool ContentSettingImageView::OnMousePressed(const ui::MouseEvent& event) { 173 bool ContentSettingImageView::OnMousePressed(const ui::MouseEvent& event) {
184 // We want to show the bubble on mouse release; that is the standard behavior 174 // We want to show the bubble on mouse release; that is the standard behavior
185 // for buttons. 175 // for buttons.
186 return true; 176 return true;
187 } 177 }
188 178
189 void ContentSettingImageView::OnMouseReleased(const ui::MouseEvent& event) { 179 void ContentSettingImageView::OnMouseReleased(const ui::MouseEvent& event) {
190 if (!HitTestPoint(event.location())) 180 if (HitTestPoint(event.location()))
191 return; 181 OnClick();
192
193 OnClick(parent_);
194 } 182 }
195 183
196 void ContentSettingImageView::OnGestureEvent(ui::GestureEvent* event) { 184 void ContentSettingImageView::OnGestureEvent(ui::GestureEvent* event) {
197 if (event->type() == ui::ET_GESTURE_TAP) { 185 if (event->type() == ui::ET_GESTURE_TAP)
198 OnClick(parent_); 186 OnClick();
187 if ((event->type() == ui::ET_GESTURE_TAP) ||
188 (event->type() == ui::ET_GESTURE_TAP_DOWN))
199 event->SetHandled(); 189 event->SetHandled();
200 } else if (event->type() == ui::ET_GESTURE_TAP_DOWN) { 190 }
201 event->SetHandled(); 191
192 void ContentSettingImageView::OnPaintBackground(gfx::Canvas* canvas) {
193 if (background_showing())
194 background_painter_->Paint(canvas, size());
195 }
196
197 void ContentSettingImageView::OnWidgetDestroying(views::Widget* widget) {
198 DCHECK_EQ(bubble_widget_, widget);
199 bubble_widget_->RemoveObserver(this);
200 bubble_widget_ = NULL;
201
202 if (pause_animation_) {
203 slide_animator_.Reset(pause_animation_state_);
204 pause_animation_ = false;
205 slide_animator_.Show();
202 } 206 }
203 } 207 }
204 208
205 void ContentSettingImageView::OnPaintBackground(gfx::Canvas* canvas) { 209 void ContentSettingImageView::OnClick() {
206 if (slide_animator_.is_animating() || pause_animation_)
207 background_painter_.Paint(canvas, size());
208 }
209
210 void ContentSettingImageView::OnWidgetDestroying(views::Widget* widget) {
211 if (bubble_widget_) {
212 bubble_widget_->RemoveObserver(this);
213 bubble_widget_ = NULL;
214 }
215
216 if (!pause_animation_)
217 return;
218
219 slide_animator_.Reset(pause_animation_state_);
220 pause_animation_ = false;
221 slide_animator_.Show();
222 }
223
224 void ContentSettingImageView::OnClick(LocationBarView* parent) {
225 // Stop animation.
226 if (slide_animator_.is_animating()) { 210 if (slide_animator_.is_animating()) {
227 if (!pause_animation_) { 211 if (!pause_animation_) {
228 pause_animation_ = true; 212 pause_animation_ = true;
229 pause_animation_state_ = slide_animator_.GetCurrentValue(); 213 pause_animation_state_ = slide_animator_.GetCurrentValue();
230 } 214 }
231 slide_animator_.Reset(); 215 slide_animator_.Reset();
232 } 216 }
233 217
234 WebContents* web_contents = parent->GetWebContents(); 218 content::WebContents* web_contents = parent_->GetWebContents();
235 if (!web_contents) 219 if (web_contents && !bubble_widget_) {
236 return; 220 bubble_widget_ =
237 if (bubble_widget_) 221 parent_->delegate()->CreateViewsBubble(new ContentSettingBubbleContents(
238 return; 222 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
239 223 parent_->delegate()->GetContentSettingBubbleModelDelegate(),
240 Profile* profile = parent->profile(); 224 web_contents, parent_->profile(),
241 ContentSettingBubbleContents* bubble = new ContentSettingBubbleContents( 225 content_setting_image_model_->get_content_settings_type()),
242 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 226 web_contents, this, views::BubbleBorder::TOP_RIGHT));
243 parent->delegate()->GetContentSettingBubbleModelDelegate(), 227 bubble_widget_->AddObserver(this);
244 web_contents, 228 bubble_widget_->Show();
245 profile,
246 content_setting_image_model_->get_content_settings_type()),
247 web_contents,
248 this,
249 views::BubbleBorder::TOP_RIGHT);
250 bubble_widget_ = parent->delegate()->CreateViewsBubble(bubble);
251 bubble_widget_->AddObserver(this);
252 bubble->GetWidget()->Show();
253 }
254
255 int ContentSettingImageView::GetTextAnimationSize(double state,
256 int text_size) {
257 if (state >= 1.0) {
258 // Animaton is over, clear the variables.
259 return 0;
260 } else if (state < kAnimatingFraction) {
261 return static_cast<int>(text_size * state / kAnimatingFraction);
262 } else if (state > (1.0 - kAnimatingFraction)) {
263 return static_cast<int>(text_size * (1.0 - state) / kAnimatingFraction);
264 } else {
265 return text_size;
266 } 229 }
267 } 230 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/location_bar/content_setting_image_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698