| 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/infobars/infobar_view.h" | 5 #include "chrome/browser/ui/views/infobars/infobar_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "chrome/browser/ui/infobar_container_delegate.h" | 13 #include "chrome/browser/ui/infobar_container_delegate.h" |
| 14 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" |
| 14 #include "chrome/browser/ui/views/infobars/infobar_background.h" | 15 #include "chrome/browser/ui/views/infobars/infobar_background.h" |
| 15 #include "chrome/grit/generated_resources.h" | 16 #include "chrome/grit/generated_resources.h" |
| 16 #include "chrome/grit/theme_resources.h" | 17 #include "chrome/grit/theme_resources.h" |
| 17 #include "components/infobars/core/infobar_delegate.h" | 18 #include "components/infobars/core/infobar_delegate.h" |
| 18 #include "components/strings/grit/components_strings.h" | 19 #include "components/strings/grit/components_strings.h" |
| 19 #include "third_party/skia/include/effects/SkGradientShader.h" | 20 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 20 #include "ui/accessibility/ax_node_data.h" | 21 #include "ui/accessibility/ax_node_data.h" |
| 21 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
| 22 #include "ui/gfx/canvas.h" | 23 #include "ui/gfx/canvas.h" |
| 23 #include "ui/gfx/color_palette.h" | 24 #include "ui/gfx/color_palette.h" |
| 24 #include "ui/gfx/image/image.h" | 25 #include "ui/gfx/image/image.h" |
| 25 #include "ui/gfx/paint_vector_icon.h" | 26 #include "ui/gfx/paint_vector_icon.h" |
| 26 #include "ui/native_theme/common_theme.h" | 27 #include "ui/native_theme/common_theme.h" |
| 27 #include "ui/native_theme/native_theme.h" | 28 #include "ui/native_theme/native_theme.h" |
| 28 #include "ui/vector_icons/vector_icons.h" | 29 #include "ui/vector_icons/vector_icons.h" |
| 29 #include "ui/views/controls/button/image_button.h" | 30 #include "ui/views/controls/button/image_button.h" |
| 30 #include "ui/views/controls/button/image_button_factory.h" | 31 #include "ui/views/controls/button/image_button_factory.h" |
| 31 #include "ui/views/controls/button/label_button_border.h" | 32 #include "ui/views/controls/button/label_button_border.h" |
| 32 #include "ui/views/controls/button/md_text_button.h" | 33 #include "ui/views/controls/button/md_text_button.h" |
| 33 #include "ui/views/controls/button/menu_button.h" | 34 #include "ui/views/controls/button/menu_button.h" |
| 34 #include "ui/views/controls/image_view.h" | 35 #include "ui/views/controls/image_view.h" |
| 35 #include "ui/views/controls/label.h" | 36 #include "ui/views/controls/label.h" |
| 36 #include "ui/views/controls/link.h" | 37 #include "ui/views/controls/link.h" |
| 37 #include "ui/views/controls/menu/menu_runner.h" | 38 #include "ui/views/controls/menu/menu_runner.h" |
| 38 #include "ui/views/layout/layout_constants.h" | |
| 39 #include "ui/views/widget/widget.h" | 39 #include "ui/views/widget/widget.h" |
| 40 #include "ui/views/window/non_client_view.h" | 40 #include "ui/views/window/non_client_view.h" |
| 41 | 41 |
| 42 | 42 |
| 43 // Helpers -------------------------------------------------------------------- | 43 // Helpers -------------------------------------------------------------------- |
| 44 | 44 |
| 45 namespace { | 45 namespace { |
| 46 | 46 |
| 47 const int kEdgeItemPadding = views::kRelatedControlHorizontalSpacing; | |
| 48 const int kIconToLabelSpacing = views::kRelatedControlHorizontalSpacing; | |
| 49 const int kBeforeCloseButtonSpacing = views::kUnrelatedControlHorizontalSpacing; | |
| 50 | |
| 51 bool SortLabelsByDecreasingWidth(views::Label* label_1, views::Label* label_2) { | 47 bool SortLabelsByDecreasingWidth(views::Label* label_1, views::Label* label_2) { |
| 52 return label_1->GetPreferredSize().width() > | 48 return label_1->GetPreferredSize().width() > |
| 53 label_2->GetPreferredSize().width(); | 49 label_2->GetPreferredSize().width(); |
| 54 } | 50 } |
| 55 | 51 |
| 56 constexpr SkColor GetInfobarTextColor() { | 52 constexpr SkColor GetInfobarTextColor() { |
| 57 return SK_ColorBLACK; | 53 return SK_ColorBLACK; |
| 58 } | 54 } |
| 59 | 55 |
| 60 } // namespace | 56 } // namespace |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 AssignWidthsSorted(labels, available_width); | 119 AssignWidthsSorted(labels, available_width); |
| 124 } | 120 } |
| 125 | 121 |
| 126 void InfoBarView::Layout() { | 122 void InfoBarView::Layout() { |
| 127 child_container_->SetBounds( | 123 child_container_->SetBounds( |
| 128 0, arrow_height(), width(), | 124 0, arrow_height(), width(), |
| 129 bar_height() - InfoBarContainerDelegate::kSeparatorLineHeight); | 125 bar_height() - InfoBarContainerDelegate::kSeparatorLineHeight); |
| 130 // |child_container_| should be the only child. | 126 // |child_container_| should be the only child. |
| 131 DCHECK_EQ(1, child_count()); | 127 DCHECK_EQ(1, child_count()); |
| 132 | 128 |
| 129 ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get(); |
| 130 |
| 131 const int related_control_distance = layout_provider->GetDistanceMetric( |
| 132 views::DISTANCE_RELATED_CONTROL_HORIZONTAL); |
| 133 const int unrelated_control_distance = |
| 134 layout_provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL); |
| 135 |
| 133 // Even though other views are technically grandchildren, we'll lay them out | 136 // Even though other views are technically grandchildren, we'll lay them out |
| 134 // here on behalf of |child_container_|. | 137 // here on behalf of |child_container_|. |
| 135 int start_x = kEdgeItemPadding; | 138 int start_x = related_control_distance; |
| 136 if (icon_ != NULL) { | 139 if (icon_ != NULL) { |
| 137 icon_->SetPosition(gfx::Point(start_x, OffsetY(icon_))); | 140 icon_->SetPosition(gfx::Point(start_x, OffsetY(icon_))); |
| 138 start_x = icon_->bounds().right() + kIconToLabelSpacing; | 141 start_x = icon_->bounds().right() + related_control_distance; |
| 139 } | 142 } |
| 140 | 143 |
| 141 int content_minimum_width = ContentMinimumWidth(); | 144 int content_minimum_width = ContentMinimumWidth(); |
| 142 close_button_->SizeToPreferredSize(); | 145 close_button_->SizeToPreferredSize(); |
| 143 close_button_->SetPosition(gfx::Point( | 146 close_button_->SetPosition(gfx::Point( |
| 144 std::max( | 147 std::max( |
| 145 start_x + content_minimum_width + | 148 start_x + content_minimum_width + |
| 146 ((content_minimum_width > 0) ? kBeforeCloseButtonSpacing : 0), | 149 ((content_minimum_width > 0) ? unrelated_control_distance : 0), |
| 147 width() - kEdgeItemPadding - close_button_->width()), | 150 width() - related_control_distance - close_button_->width()), |
| 148 OffsetY(close_button_))); | 151 OffsetY(close_button_))); |
| 149 | 152 |
| 150 // For accessibility reasons, the close button should come last. | 153 // For accessibility reasons, the close button should come last. |
| 151 DCHECK_EQ(close_button_->parent()->child_count() - 1, | 154 DCHECK_EQ(close_button_->parent()->child_count() - 1, |
| 152 close_button_->parent()->GetIndexOf(close_button_)); | 155 close_button_->parent()->GetIndexOf(close_button_)); |
| 153 } | 156 } |
| 154 | 157 |
| 155 void InfoBarView::ViewHierarchyChanged( | 158 void InfoBarView::ViewHierarchyChanged( |
| 156 const ViewHierarchyChangedDetails& details) { | 159 const ViewHierarchyChangedDetails& details) { |
| 157 View::ViewHierarchyChanged(details); | 160 View::ViewHierarchyChanged(details); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 } | 200 } |
| 198 | 201 |
| 199 int InfoBarView::ContentMinimumWidth() const { | 202 int InfoBarView::ContentMinimumWidth() const { |
| 200 return 0; | 203 return 0; |
| 201 } | 204 } |
| 202 | 205 |
| 203 int InfoBarView::StartX() const { | 206 int InfoBarView::StartX() const { |
| 204 // Ensure we don't return a value greater than EndX(), so children can safely | 207 // Ensure we don't return a value greater than EndX(), so children can safely |
| 205 // set something's width to "EndX() - StartX()" without risking that being | 208 // set something's width to "EndX() - StartX()" without risking that being |
| 206 // negative. | 209 // negative. |
| 207 return std::min(EndX(), (icon_ != NULL) ? | 210 const int padding = ChromeLayoutProvider::Get()->GetDistanceMetric( |
| 208 (icon_->bounds().right() + kIconToLabelSpacing) : kEdgeItemPadding); | 211 views::DISTANCE_RELATED_CONTROL_HORIZONTAL); |
| 212 return std::min((icon_ ? icon_->bounds().right() : 0) + padding, EndX()); |
| 209 } | 213 } |
| 210 | 214 |
| 211 int InfoBarView::EndX() const { | 215 int InfoBarView::EndX() const { |
| 212 return close_button_->x() - kBeforeCloseButtonSpacing; | 216 return close_button_->x() - ChromeLayoutProvider::Get()->GetDistanceMetric( |
| 217 DISTANCE_UNRELATED_CONTROL_HORIZONTAL); |
| 213 } | 218 } |
| 214 | 219 |
| 215 int InfoBarView::OffsetY(views::View* view) const { | 220 int InfoBarView::OffsetY(views::View* view) const { |
| 216 return std::max((bar_target_height() - view->height()) / 2, 0) - | 221 return std::max((bar_target_height() - view->height()) / 2, 0) - |
| 217 (bar_target_height() - bar_height()); | 222 (bar_target_height() - bar_height()); |
| 218 } | 223 } |
| 219 | 224 |
| 220 void InfoBarView::AddViewToContentArea(views::View* view) { | 225 void InfoBarView::AddViewToContentArea(views::View* view) { |
| 221 child_container_->AddChildView(view); | 226 child_container_->AddChildView(view); |
| 222 } | 227 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 void InfoBarView::GetAccessibleNodeData(ui::AXNodeData* node_data) { | 278 void InfoBarView::GetAccessibleNodeData(ui::AXNodeData* node_data) { |
| 274 node_data->SetName(l10n_util::GetStringUTF8( | 279 node_data->SetName(l10n_util::GetStringUTF8( |
| 275 (delegate()->GetInfoBarType() == infobars::InfoBarDelegate::WARNING_TYPE) | 280 (delegate()->GetInfoBarType() == infobars::InfoBarDelegate::WARNING_TYPE) |
| 276 ? IDS_ACCNAME_INFOBAR_WARNING | 281 ? IDS_ACCNAME_INFOBAR_WARNING |
| 277 : IDS_ACCNAME_INFOBAR_PAGE_ACTION)); | 282 : IDS_ACCNAME_INFOBAR_PAGE_ACTION)); |
| 278 node_data->role = ui::AX_ROLE_ALERT; | 283 node_data->role = ui::AX_ROLE_ALERT; |
| 279 node_data->AddStringAttribute(ui::AX_ATTR_SHORTCUT, "Alt+Shift+A"); | 284 node_data->AddStringAttribute(ui::AX_ATTR_SHORTCUT, "Alt+Shift+A"); |
| 280 } | 285 } |
| 281 | 286 |
| 282 gfx::Size InfoBarView::GetPreferredSize() const { | 287 gfx::Size InfoBarView::GetPreferredSize() const { |
| 288 ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get(); |
| 289 |
| 290 const int related_control_spacing = layout_provider->GetDistanceMetric( |
| 291 views::DISTANCE_RELATED_CONTROL_HORIZONTAL); |
| 292 const int unrelated_control_spacing = |
| 293 layout_provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL); |
| 294 |
| 283 return gfx::Size( | 295 return gfx::Size( |
| 284 kEdgeItemPadding + (icon_ ? (icon_->width() + kIconToLabelSpacing) : 0) + | 296 related_control_spacing + |
| 285 ContentMinimumWidth() + kBeforeCloseButtonSpacing + | 297 (icon_ ? (icon_->width() + related_control_spacing) : 0) + |
| 286 close_button_->width() + kEdgeItemPadding, | 298 ContentMinimumWidth() + unrelated_control_spacing + |
| 299 close_button_->width() + related_control_spacing, |
| 287 total_height()); | 300 total_height()); |
| 288 } | 301 } |
| 289 | 302 |
| 290 void InfoBarView::OnWillChangeFocus(View* focused_before, View* focused_now) { | 303 void InfoBarView::OnWillChangeFocus(View* focused_before, View* focused_now) { |
| 291 views::ExternalFocusTracker::OnWillChangeFocus(focused_before, focused_now); | 304 views::ExternalFocusTracker::OnWillChangeFocus(focused_before, focused_now); |
| 292 | 305 |
| 293 // This will trigger some screen readers to read the entire contents of this | 306 // This will trigger some screen readers to read the entire contents of this |
| 294 // infobar. | 307 // infobar. |
| 295 if (focused_before && focused_now && !Contains(focused_before) && | 308 if (focused_before && focused_now && !Contains(focused_before) && |
| 296 Contains(focused_now)) { | 309 Contains(focused_now)) { |
| 297 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); | 310 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); |
| 298 } | 311 } |
| 299 } | 312 } |
| 300 | 313 |
| 301 bool InfoBarView::DoesIntersectRect(const View* target, | 314 bool InfoBarView::DoesIntersectRect(const View* target, |
| 302 const gfx::Rect& rect) const { | 315 const gfx::Rect& rect) const { |
| 303 DCHECK_EQ(this, target); | 316 DCHECK_EQ(this, target); |
| 304 // Only events that intersect the portion below the arrow are interesting. | 317 // Only events that intersect the portion below the arrow are interesting. |
| 305 gfx::Rect non_arrow_bounds = GetLocalBounds(); | 318 gfx::Rect non_arrow_bounds = GetLocalBounds(); |
| 306 non_arrow_bounds.Inset(0, arrow_height(), 0, 0); | 319 non_arrow_bounds.Inset(0, arrow_height(), 0, 0); |
| 307 return rect.Intersects(non_arrow_bounds); | 320 return rect.Intersects(non_arrow_bounds); |
| 308 } | 321 } |
| OLD | NEW |