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/icon_label_bubble_view.h" | 5 #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" |
6 | 6 |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
8 #include "chrome/browser/ui/layout_constants.h" | 8 #include "chrome/browser/ui/layout_constants.h" |
9 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" | 9 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" |
10 #include "ui/base/material_design/material_design_controller.h" | 10 #include "ui/base/material_design/material_design_controller.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 103 |
104 double IconLabelBubbleView::WidthMultiplier() const { | 104 double IconLabelBubbleView::WidthMultiplier() const { |
105 return 1.0; | 105 return 1.0; |
106 } | 106 } |
107 | 107 |
108 bool IconLabelBubbleView::IsShrinking() const { | 108 bool IconLabelBubbleView::IsShrinking() const { |
109 return false; | 109 return false; |
110 } | 110 } |
111 | 111 |
112 int IconLabelBubbleView::GetImageAndPaddingWidth() const { | 112 int IconLabelBubbleView::GetImageAndPaddingWidth() const { |
113 const int image_width = image_->GetPreferredSize().width(); | 113 return image_->GetPreferredSize().width() + GetInternalSpacing(); |
114 return image_width | |
115 ? image_width + GetLayoutConstant(ICON_LABEL_VIEW_INTERNAL_PADDING) | |
116 : 0; | |
117 } | 114 } |
118 | 115 |
119 gfx::Size IconLabelBubbleView::GetPreferredSize() const { | 116 gfx::Size IconLabelBubbleView::GetPreferredSize() const { |
120 // Height will be ignored by the LocationBarView. | 117 // Height will be ignored by the LocationBarView. |
121 return GetSizeForLabelWidth(label_->GetPreferredSize().width()); | 118 return GetSizeForLabelWidth(label_->GetPreferredSize().width()); |
122 } | 119 } |
123 | 120 |
124 void IconLabelBubbleView::Layout() { | 121 void IconLabelBubbleView::Layout() { |
125 // Compute the label bounds. The label gets whatever size is left over after | 122 // Compute the label bounds. The label gets whatever size is left over after |
126 // accounting for the preferred image width and padding amounts. Note that if | 123 // accounting for the preferred image width and padding amounts. Note that if |
127 // the label has zero size it doesn't actually matter what we compute its X | 124 // the label has zero size it doesn't actually matter what we compute its X |
128 // value to be, since it won't be visible, so the X value can be "wrong" | 125 // value to be, since it won't be visible, so the X value can be "wrong" |
129 // compared to where the right edge of the image is computed to be below. | 126 // compared to where the right edge of the image is computed to be below. |
130 // This means doing this layout doesn't doesn't depend on any of the layout | 127 // This means doing this layout doesn't doesn't depend on any of the layout |
131 // below. That layout, however, may need for this layout to have already | 128 // below. That layout, however, may need for this layout to have already |
132 // happened, since the value of ShouldShowBackground() we read below may | 129 // happened, since the value of ShouldShowBackground() we read below may |
133 // depend on whether the label has nonzero size. Therefore, we do this first. | 130 // depend on whether the label has nonzero size. Therefore, we do this first. |
134 const int label_x = GetBubbleOuterPadding(true) + GetImageAndPaddingWidth(); | 131 const int label_x = GetOuterPadding(true) + GetImageAndPaddingWidth(); |
135 const int label_width = | 132 const int label_width = |
136 std::max(0, width() - label_x - GetBubbleOuterPadding(false)); | 133 std::max(0, width() - label_x - GetOuterPadding(false)); |
137 label_->SetBounds(label_x, 0, label_width, height()); | 134 label_->SetBounds(label_x, 0, label_width, height()); |
138 | 135 |
139 // Now compute the image bounds. In non-MD, the leading padding depends on | 136 // Now compute the image bounds. In non-MD, the leading padding depends on |
140 // whether this is an extension icon, since extension icons and | 137 // whether this is an extension icon, since extension icons and |
141 // Chrome-provided icons are different sizes. In MD, these sizes are the | 138 // Chrome-provided icons are different sizes. In MD, these sizes are the |
142 // same, so it's not necessary to handle the two types differently. | 139 // same, so it's not necessary to handle the two types differently. |
143 const bool icon_has_enough_padding = | 140 const bool icon_has_enough_padding = |
144 !is_extension_icon_ || ui::MaterialDesignController::IsModeMaterial(); | 141 !is_extension_icon_ || ui::MaterialDesignController::IsModeMaterial(); |
145 int image_x = GetBubbleOuterPadding(icon_has_enough_padding); | 142 int image_x = GetOuterPadding(icon_has_enough_padding); |
146 const int image_preferred_width = image_->GetPreferredSize().width(); | 143 int bubble_trailing_padding = GetOuterPadding(false); |
147 int bubble_trailing_padding = GetBubbleOuterPadding(false); | |
148 | 144 |
149 // If ShouldShowBackground() is true, then either we show a background in the | 145 // If ShouldShowBackground() is true, then either we show a background in the |
150 // steady state, or we're not yet in the last portion of the animation. In | 146 // steady state, or we're not yet in the last portion of the animation. In |
151 // these cases, we leave the leading and trailing padding alone; we don't want | 147 // these cases, we leave the leading and trailing padding alone; we don't want |
152 // to let the image overlap the edge of the background, as this looks glitchy. | 148 // to let the image overlap the edge of the background, as this looks glitchy. |
153 // If this is false, however, then we're only showing the image, and either | 149 // If this is false, however, then we're only showing the image, and either |
154 // the view width is the image width, or it's animating downwards and getting | 150 // the view width is the image width, or it's animating downwards and getting |
155 // close to it. In these cases, we want to shrink the trailing padding first, | 151 // close to it. In these cases, we want to shrink the trailing padding first, |
156 // so the image slides all the way to the trailing edge before slowing or | 152 // so the image slides all the way to the trailing edge before slowing or |
157 // stopping; then we want to shrink the leading padding down to zero. | 153 // stopping; then we want to shrink the leading padding down to zero. |
| 154 const int image_preferred_width = image_->GetPreferredSize().width(); |
158 if (!ShouldShowBackground()) { | 155 if (!ShouldShowBackground()) { |
159 image_x = std::min(image_x, width() - image_preferred_width); | 156 image_x = std::min(image_x, width() - image_preferred_width); |
160 bubble_trailing_padding = std::min( | 157 bubble_trailing_padding = std::min( |
161 bubble_trailing_padding, width() - image_preferred_width - image_x); | 158 bubble_trailing_padding, width() - image_preferred_width - image_x); |
162 } | 159 } |
163 | 160 |
164 // Now that we've computed the padding values, give the image all the | 161 // Now that we've computed the padding values, give the image all the |
165 // remaining width. This will be less than the image's preferred width during | 162 // remaining width. This will be less than the image's preferred width during |
166 // the first portion of the animation; during the very beginning there may not | 163 // the first portion of the animation; during the very beginning there may not |
167 // be enough room to show the image at all. | 164 // be enough room to show the image at all. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 | 206 |
210 SkColor IconLabelBubbleView::GetParentBackgroundColor() const { | 207 SkColor IconLabelBubbleView::GetParentBackgroundColor() const { |
211 return ui::MaterialDesignController::IsModeMaterial() | 208 return ui::MaterialDesignController::IsModeMaterial() |
212 ? GetNativeTheme()->GetSystemColor( | 209 ? GetNativeTheme()->GetSystemColor( |
213 ui::NativeTheme::kColorId_TextfieldDefaultBackground) | 210 ui::NativeTheme::kColorId_TextfieldDefaultBackground) |
214 : parent_background_color_; | 211 : parent_background_color_; |
215 } | 212 } |
216 | 213 |
217 gfx::Size IconLabelBubbleView::GetSizeForLabelWidth(int label_width) const { | 214 gfx::Size IconLabelBubbleView::GetSizeForLabelWidth(int label_width) const { |
218 gfx::Size size(image_->GetPreferredSize()); | 215 gfx::Size size(image_->GetPreferredSize()); |
219 bool shrinking = IsShrinking(); | 216 const bool shrinking = IsShrinking(); |
220 // Animation continues for the last few pixels even after the label is not | 217 // Animation continues for the last few pixels even after the label is not |
221 // visible in order to slide the icon into its final position. Therefore it | 218 // visible in order to slide the icon into its final position. Therefore it |
222 // is necessary to animate |total_width| even when the background is hidden | 219 // is necessary to animate |total_width| even when the background is hidden |
223 // as long as the animation is still shrinking. | 220 // as long as the animation is still shrinking. |
224 if (ShouldShowBackground() || shrinking) { | 221 if (ShouldShowBackground() || shrinking) { |
225 const int image_width = size.width(); | |
226 const int padding = GetLayoutConstant(ICON_LABEL_VIEW_INTERNAL_PADDING) + | |
227 GetBubbleOuterPadding(true) + | |
228 GetBubbleOuterPadding(false); | |
229 // |multiplier| grows from zero to one, stays equal to one and then shrinks | 222 // |multiplier| grows from zero to one, stays equal to one and then shrinks |
230 // to zero again. The view width should correspondingly grow from zero to | 223 // to zero again. The view width should correspondingly grow from zero to |
231 // fully showing both label and icon, stay there, then shrink to just large | 224 // fully showing both label and icon, stay there, then shrink to just large |
232 // enough to show the icon. We don't want to shrink all the way back to | 225 // enough to show the icon. We don't want to shrink all the way back to |
233 // zero, since this would mean the view would completely disappear and then | 226 // zero, since this would mean the view would completely disappear and then |
234 // pop back to an icon after the animation finishes. | 227 // pop back to an icon after the animation finishes. |
235 int total_width = WidthMultiplier() * (label_width + image_width + padding); | 228 const int max_width = MinimumWidthForImageWithBackgroundShown() + |
236 if (shrinking) | 229 GetInternalSpacing() + label_width; |
237 total_width = std::max(total_width, image_width); | 230 const int current_width = WidthMultiplier() * max_width; |
238 size.set_width(total_width); | 231 size.set_width( |
| 232 shrinking ? std::max(current_width, size.width()) : current_width); |
239 } | 233 } |
240 return size; | 234 return size; |
241 } | 235 } |
242 | 236 |
243 int IconLabelBubbleView::GetBubbleOuterPadding(bool leading) const { | 237 int IconLabelBubbleView::MinimumWidthForImageWithBackgroundShown() const { |
244 if (ui::MaterialDesignController::IsModeMaterial()) | 238 return GetOuterPadding(true) + image_->GetPreferredSize().width() + |
245 return GetBubbleOuterPaddingMd(leading); | 239 GetOuterPadding(false); |
246 | |
247 return GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING) - | |
248 GetLayoutConstant(LOCATION_BAR_BUBBLE_HORIZONTAL_PADDING) + | |
249 (leading ? 0 : GetLayoutConstant(ICON_LABEL_VIEW_TRAILING_PADDING)); | |
250 } | 240 } |
251 | 241 |
252 void IconLabelBubbleView::SetLabelBackgroundColor( | 242 void IconLabelBubbleView::SetLabelBackgroundColor( |
253 SkColor chip_background_color) { | 243 SkColor chip_background_color) { |
254 // The background images are painted atop |parent_background_color_|. | 244 // The background images are painted atop |parent_background_color_|. |
255 // Alpha-blend |chip_background_color| with |parent_background_color_| to | 245 // Alpha-blend |chip_background_color| with |parent_background_color_| to |
256 // determine the actual color the label text will sit atop. | 246 // determine the actual color the label text will sit atop. |
257 // Tricky bit: We alpha blend an opaque version of |chip_background_color| | 247 // Tricky bit: We alpha blend an opaque version of |chip_background_color| |
258 // against |parent_background_color_| using the original image grid color's | 248 // against |parent_background_color_| using the original image grid color's |
259 // alpha. This is because AlphaBlend(a, b, 255) always returns |a| unchanged | 249 // alpha. This is because AlphaBlend(a, b, 255) always returns |a| unchanged |
260 // even if |a| is a color with non-255 alpha. | 250 // even if |a| is a color with non-255 alpha. |
261 label_->SetBackgroundColor(color_utils::AlphaBlend( | 251 label_->SetBackgroundColor(color_utils::AlphaBlend( |
262 SkColorSetA(chip_background_color, 255), GetParentBackgroundColor(), | 252 SkColorSetA(chip_background_color, 255), GetParentBackgroundColor(), |
263 SkColorGetA(chip_background_color))); | 253 SkColorGetA(chip_background_color))); |
264 } | 254 } |
265 | 255 |
266 int IconLabelBubbleView::GetBubbleOuterPaddingMd(bool leading) const { | 256 int IconLabelBubbleView::GetOuterPadding(bool leading) const { |
267 // When the image is empty, leading and trailing padding are equal. | 257 if (ui::MaterialDesignController::IsModeMaterial()) { |
268 if (image_->GetPreferredSize().IsEmpty() || !leading) | 258 // Leading and trailing padding are equal. |
269 return GetLayoutConstant(ICON_LABEL_VIEW_TRAILING_PADDING); | 259 return GetLayoutConstant(ICON_LABEL_VIEW_TRAILING_PADDING); |
| 260 } |
270 | 261 |
271 // Leading padding is 2dp. | 262 return GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING) - |
272 return 2; | 263 GetLayoutConstant(LOCATION_BAR_BUBBLE_HORIZONTAL_PADDING) + |
| 264 (leading ? 0 : GetLayoutConstant(ICON_LABEL_VIEW_TRAILING_PADDING)); |
| 265 } |
| 266 |
| 267 int IconLabelBubbleView::GetInternalSpacing() const { |
| 268 return image_->GetPreferredSize().IsEmpty() ? |
| 269 0 : GetLayoutConstant(ICON_LABEL_VIEW_INTERNAL_SPACING); |
273 } | 270 } |
274 | 271 |
275 const char* IconLabelBubbleView::GetClassName() const { | 272 const char* IconLabelBubbleView::GetClassName() const { |
276 return "IconLabelBubbleView"; | 273 return "IconLabelBubbleView"; |
277 } | 274 } |
278 | 275 |
279 void IconLabelBubbleView::OnPaint(gfx::Canvas* canvas) { | 276 void IconLabelBubbleView::OnPaint(gfx::Canvas* canvas) { |
280 if (!ShouldShowBackground()) | 277 if (!ShouldShowBackground()) |
281 return; | 278 return; |
282 if (background_painter_) { | 279 if (background_painter_) { |
283 views::Painter::PaintPainterAt(canvas, background_painter_.get(), | 280 views::Painter::PaintPainterAt(canvas, background_painter_.get(), |
284 GetContentsBounds()); | 281 GetContentsBounds()); |
285 } | 282 } |
286 if (background()) | 283 if (background()) |
287 background()->Paint(canvas, this); | 284 background()->Paint(canvas, this); |
288 } | 285 } |
OLD | NEW |