| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/profiles/avatar_button.h" | 5 #include "chrome/browser/ui/views/profiles/avatar_button.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "chrome/app/vector_icons/vector_icons.h" | 9 #include "chrome/app/vector_icons/vector_icons.h" |
| 10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| 11 #include "chrome/browser/profiles/profile_manager.h" | 11 #include "chrome/browser/profiles/profile_manager.h" |
| 12 #include "chrome/browser/profiles/profiles_state.h" | 12 #include "chrome/browser/profiles/profiles_state.h" |
| 13 #include "chrome/browser/signin/signin_manager_factory.h" | 13 #include "chrome/browser/signin/signin_manager_factory.h" |
| 14 #include "chrome/browser/themes/theme_properties.h" |
| 14 #include "chrome/browser/themes/theme_service.h" | 15 #include "chrome/browser/themes/theme_service.h" |
| 15 #include "chrome/browser/themes/theme_service_factory.h" | 16 #include "chrome/browser/themes/theme_service_factory.h" |
| 17 #include "chrome/browser/ui/views/profiles/profile_chooser_view.h" |
| 16 #include "chrome/grit/theme_resources.h" | 18 #include "chrome/grit/theme_resources.h" |
| 17 #include "components/signin/core/browser/signin_manager.h" | 19 #include "components/signin/core/browser/signin_manager.h" |
| 18 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/base/theme_provider.h" |
| 22 #include "ui/gfx/canvas.h" |
| 19 #include "ui/gfx/color_palette.h" | 23 #include "ui/gfx/color_palette.h" |
| 20 #include "ui/gfx/paint_vector_icon.h" | 24 #include "ui/gfx/paint_vector_icon.h" |
| 21 #include "ui/views/animation/flood_fill_ink_drop_ripple.h" | 25 #include "ui/views/animation/flood_fill_ink_drop_ripple.h" |
| 22 #include "ui/views/animation/ink_drop_impl.h" | 26 #include "ui/views/animation/ink_drop_impl.h" |
| 27 #include "ui/views/animation/ink_drop_mask.h" |
| 23 #include "ui/views/controls/button/label_button_border.h" | 28 #include "ui/views/controls/button/label_button_border.h" |
| 24 | 29 |
| 25 #if defined(OS_WIN) | 30 #if defined(OS_WIN) |
| 26 #include "base/win/windows_version.h" | 31 #include "base/win/windows_version.h" |
| 27 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" | 32 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" |
| 28 #endif | 33 #endif |
| 29 | 34 |
| 30 namespace { | 35 namespace { |
| 31 | 36 |
| 32 constexpr int kLeftRightInset = 8; | 37 constexpr gfx::Insets kBorderInsets(2, 8, 4, 8); |
| 33 constexpr int kTopInset = 2; | |
| 34 constexpr int kBottomInset = 4; | |
| 35 | 38 |
| 36 // TODO(emx): Calculate width based on caption button [http://crbug.com/716365] | 39 // TODO(emx): Calculate width based on caption button [http://crbug.com/716365] |
| 37 constexpr int kMdButtonMinWidth = 46; | 40 constexpr int kCondensibleButtonMinWidth = 46; |
| 41 // TODO(emx): Should this be calculated based on average character width? |
| 42 constexpr int kCondensibleButtonMaxWidth = 98; |
| 38 | 43 |
| 39 std::unique_ptr<views::Border> CreateThemedBorder( | 44 std::unique_ptr<views::Border> CreateThemedBorder( |
| 40 const int normal_image_set[], | 45 const int normal_image_set[], |
| 41 const int hot_image_set[], | 46 const int hot_image_set[], |
| 42 const int pushed_image_set[]) { | 47 const int pushed_image_set[]) { |
| 43 std::unique_ptr<views::LabelButtonAssetBorder> border( | 48 std::unique_ptr<views::LabelButtonAssetBorder> border( |
| 44 new views::LabelButtonAssetBorder(views::Button::STYLE_TEXTBUTTON)); | 49 new views::LabelButtonAssetBorder(views::Button::STYLE_TEXTBUTTON)); |
| 45 | 50 |
| 46 border->SetPainter(false, views::Button::STATE_NORMAL, | 51 border->SetPainter(false, views::Button::STATE_NORMAL, |
| 47 views::Painter::CreateImageGridPainter(normal_image_set)); | 52 views::Painter::CreateImageGridPainter(normal_image_set)); |
| 48 border->SetPainter(false, views::Button::STATE_HOVERED, | 53 border->SetPainter(false, views::Button::STATE_HOVERED, |
| 49 views::Painter::CreateImageGridPainter(hot_image_set)); | 54 views::Painter::CreateImageGridPainter(hot_image_set)); |
| 50 border->SetPainter(false, views::Button::STATE_PRESSED, | 55 border->SetPainter(false, views::Button::STATE_PRESSED, |
| 51 views::Painter::CreateImageGridPainter(pushed_image_set)); | 56 views::Painter::CreateImageGridPainter(pushed_image_set)); |
| 52 | 57 |
| 53 border->set_insets( | 58 border->set_insets(kBorderInsets); |
| 54 gfx::Insets(kTopInset, kLeftRightInset, kBottomInset, kLeftRightInset)); | |
| 55 | 59 |
| 56 return std::move(border); | 60 return std::move(border); |
| 57 } | 61 } |
| 58 | 62 |
| 59 std::unique_ptr<views::Border> CreateWin10NativeBorder() { | 63 // This class draws the border (and background) of the avatar button for |
| 60 return views::CreateEmptyBorder(kTopInset, kLeftRightInset, kBottomInset, | 64 // "themed" browser windows, i.e. OpaqueBrowserFrameView. Currently it's only |
| 61 kLeftRightInset); | 65 // used on Linux as the shape specifically matches the Linux caption buttons. |
| 62 } | 66 // TODO(estade): make this look nice on Windows and use it there as well. |
| 67 class AvatarButtonThemedBorder : public views::Border { |
| 68 public: |
| 69 AvatarButtonThemedBorder() {} |
| 70 ~AvatarButtonThemedBorder() override {} |
| 71 |
| 72 void Paint(const views::View& view, gfx::Canvas* canvas) override { |
| 73 // Start with an outer dark stroke. |
| 74 cc::PaintFlags stroke_flags; |
| 75 stroke_flags.setStyle(cc::PaintFlags::kStroke_Style); |
| 76 // The colors are chosen to match the assets we use for Linux. |
| 77 stroke_flags.setColor(SkColorSetA(SK_ColorBLACK, 0x2B)); |
| 78 stroke_flags.setStrokeWidth(kStrokeWidth); |
| 79 stroke_flags.setAntiAlias(true); |
| 80 gfx::RectF stroke_bounds(view.GetLocalBounds()); |
| 81 stroke_bounds.Inset(gfx::InsetsF(0.5f)); |
| 82 canvas->DrawRoundRect(stroke_bounds, kCornerRadius, stroke_flags); |
| 83 |
| 84 // There's a second, light stroke that matches the fill bounds. |
| 85 stroke_bounds.Inset(gfx::InsetsF(kStrokeWidth)); |
| 86 stroke_flags.setColor(SkColorSetA(SK_ColorWHITE, 0x3F)); |
| 87 canvas->DrawRoundRect(stroke_bounds, kCornerRadius, stroke_flags); |
| 88 } |
| 89 |
| 90 gfx::Insets GetInsets() const override { |
| 91 auto insets = views::LabelButtonAssetBorder::GetDefaultInsetsForStyle( |
| 92 views::Button::STYLE_TEXTBUTTON); |
| 93 return kBorderStrokeInsets + |
| 94 gfx::Insets(0, insets.left(), 0, insets.right()); |
| 95 } |
| 96 |
| 97 gfx::Size GetMinimumSize() const override { |
| 98 return gfx::Size(GetInsets().width(), GetInsets().height()); |
| 99 } |
| 100 |
| 101 static std::unique_ptr<views::InkDropMask> CreateInkDropMask( |
| 102 const gfx::Size& size) { |
| 103 return base::MakeUnique<views::RoundRectInkDropMask>( |
| 104 size, kBorderStrokeInsets, kCornerRadius); |
| 105 } |
| 106 |
| 107 private: |
| 108 static constexpr int kStrokeWidth = 1; |
| 109 |
| 110 // Insets between view bounds and the interior of the strokes. |
| 111 static constexpr gfx::Insets kBorderStrokeInsets{kStrokeWidth * 2}; |
| 112 |
| 113 // Corner radius of the roundrect. |
| 114 static constexpr float kCornerRadius = 1; |
| 115 |
| 116 DISALLOW_COPY_AND_ASSIGN(AvatarButtonThemedBorder); |
| 117 }; |
| 118 |
| 119 constexpr int AvatarButtonThemedBorder::kStrokeWidth; |
| 120 constexpr gfx::Insets AvatarButtonThemedBorder::kBorderStrokeInsets; |
| 121 constexpr float AvatarButtonThemedBorder::kCornerRadius; |
| 63 | 122 |
| 64 } // namespace | 123 } // namespace |
| 65 | 124 |
| 66 AvatarButton::AvatarButton(views::ButtonListener* listener, | 125 AvatarButton::AvatarButton(views::ButtonListener* listener, |
| 67 AvatarButtonStyle button_style, | 126 AvatarButtonStyle button_style, |
| 68 Profile* profile) | 127 Profile* profile) |
| 69 : LabelButton(listener, base::string16()), | 128 : LabelButton(listener, base::string16()), |
| 70 error_controller_(this, profile), | 129 error_controller_(this, profile), |
| 71 profile_(profile), | 130 profile_(profile), |
| 72 profile_observer_(this), | 131 profile_observer_(this), |
| 73 use_win10_native_button_(false) { | 132 button_style_(button_style) { |
| 74 set_notify_action(CustomButton::NOTIFY_ON_PRESS); | 133 set_notify_action(CustomButton::NOTIFY_ON_PRESS); |
| 75 set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON | | 134 set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON | |
| 76 ui::EF_RIGHT_MOUSE_BUTTON); | 135 ui::EF_RIGHT_MOUSE_BUTTON); |
| 77 set_animate_on_state_change(false); | 136 set_animate_on_state_change(false); |
| 78 SetEnabledTextColors(SK_ColorWHITE); | 137 SetEnabledTextColors(SK_ColorWHITE); |
| 79 SetTextSubpixelRenderingEnabled(false); | 138 SetTextSubpixelRenderingEnabled(false); |
| 80 SetHorizontalAlignment(gfx::ALIGN_CENTER); | 139 SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| 81 | 140 |
| 82 profile_observer_.Add( | 141 profile_observer_.Add( |
| 83 &g_browser_process->profile_manager()->GetProfileAttributesStorage()); | 142 &g_browser_process->profile_manager()->GetProfileAttributesStorage()); |
| 84 | 143 |
| 85 // The largest text height that fits in the button. If the font list height | 144 // The largest text height that fits in the button. If the font list height |
| 86 // is larger than this, it will be shrunk to match it. | 145 // is larger than this, it will be shrunk to match it. |
| 87 // TODO(noms): Calculate this constant algorithmically from the button's size. | 146 // TODO(noms): Calculate this constant algorithmically from the button's size. |
| 88 const int kDisplayFontHeight = 16; | 147 const int kDisplayFontHeight = 16; |
| 89 label()->SetFontList( | 148 label()->SetFontList( |
| 90 label()->font_list().DeriveWithHeightUpperBound(kDisplayFontHeight)); | 149 label()->font_list().DeriveWithHeightUpperBound(kDisplayFontHeight)); |
| 91 | 150 |
| 92 #if defined(OS_WIN) | 151 bool apply_ink_drop = IsCondensible(); |
| 93 // TODO(estade): Use MD button in other cases, too [http://crbug.com/591586] | 152 #if defined(OS_LINUX) |
| 94 if ((base::win::GetVersion() >= base::win::VERSION_WIN10) && | 153 DCHECK_EQ(AvatarButtonStyle::THEMED, button_style); |
| 95 ThemeServiceFactory::GetForProfile(profile)->UsingSystemTheme() && | 154 apply_ink_drop = true; |
| 96 button_style == AvatarButtonStyle::NATIVE) | 155 #endif |
| 97 use_win10_native_button_ = true; | |
| 98 #endif // defined(OS_WIN) | |
| 99 | 156 |
| 100 if (use_win10_native_button_) { | 157 if (apply_ink_drop) { |
| 101 constexpr int kMdButtonIconHeight = 16; | 158 constexpr int kIconSize = 16; |
| 102 constexpr SkColor kMdButtonIconColor = | 159 constexpr SkColor kIconColor = |
| 103 SkColorSetA(SK_ColorBLACK, static_cast<SkAlpha>(0.54 * 0xFF)); | 160 SkColorSetA(SK_ColorBLACK, static_cast<SkAlpha>(0.54 * 0xFF)); |
| 104 generic_avatar_ = gfx::CreateVectorIcon( | 161 generic_avatar_ = |
| 105 kAccountCircleIcon, kMdButtonIconHeight, kMdButtonIconColor); | 162 gfx::CreateVectorIcon(kAccountCircleIcon, kIconSize, kIconColor); |
| 106 SetBorder(CreateWin10NativeBorder()); | |
| 107 | 163 |
| 108 SetInkDropMode(InkDropMode::ON); | 164 SetInkDropMode(InkDropMode::ON); |
| 109 set_has_ink_drop_action_on_click(true); | |
| 110 SetFocusPainter(nullptr); | 165 SetFocusPainter(nullptr); |
| 166 #if defined(OS_LINUX) |
| 167 set_ink_drop_base_color(SK_ColorWHITE); |
| 168 SetBorder(base::MakeUnique<AvatarButtonThemedBorder>()); |
| 169 #elif defined(OS_WIN) |
| 170 DCHECK_EQ(AvatarButtonStyle::NATIVE, button_style); |
| 111 set_ink_drop_base_color(SK_ColorBLACK); | 171 set_ink_drop_base_color(SK_ColorBLACK); |
| 172 SetBorder(views::CreateEmptyBorder(kBorderInsets)); |
| 173 #endif // defined(OS_WIN) |
| 174 } else if (button_style == AvatarButtonStyle::THEMED) { |
| 175 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_NORMAL); |
| 176 const int kHoverImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_HOVER); |
| 177 const int kPressedImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_PRESSED); |
| 178 SetButtonAvatar(IDR_AVATAR_THEMED_BUTTON_AVATAR); |
| 179 SetBorder( |
| 180 CreateThemedBorder(kNormalImageSet, kHoverImageSet, kPressedImageSet)); |
| 181 #if defined(OS_WIN) |
| 182 } else if (base::win::GetVersion() < base::win::VERSION_WIN8) { |
| 183 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_NORMAL); |
| 184 const int kHoverImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_HOVER); |
| 185 const int kPressedImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_PRESSED); |
| 186 SetButtonAvatar(IDR_AVATAR_GLASS_BUTTON_AVATAR); |
| 187 SetBorder( |
| 188 CreateThemedBorder(kNormalImageSet, kHoverImageSet, kPressedImageSet)); |
| 189 #endif |
| 112 } else { | 190 } else { |
| 113 if (button_style == AvatarButtonStyle::THEMED) { | 191 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_NORMAL); |
| 114 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_NORMAL); | 192 const int kHoverImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_HOVER); |
| 115 const int kHoverImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_HOVER); | 193 const int kPressedImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_PRESSED); |
| 116 const int kPressedImageSet[] = | 194 SetButtonAvatar(IDR_AVATAR_NATIVE_BUTTON_AVATAR); |
| 117 IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_PRESSED); | 195 SetBorder( |
| 118 SetButtonAvatar(IDR_AVATAR_THEMED_BUTTON_AVATAR); | 196 CreateThemedBorder(kNormalImageSet, kHoverImageSet, kPressedImageSet)); |
| 119 SetBorder(CreateThemedBorder(kNormalImageSet, kHoverImageSet, | |
| 120 kPressedImageSet)); | |
| 121 #if defined(OS_WIN) | |
| 122 } else if (base::win::GetVersion() < base::win::VERSION_WIN8) { | |
| 123 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_NORMAL); | |
| 124 const int kHoverImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_HOVER); | |
| 125 const int kPressedImageSet[] = | |
| 126 IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_PRESSED); | |
| 127 SetButtonAvatar(IDR_AVATAR_GLASS_BUTTON_AVATAR); | |
| 128 SetBorder(CreateThemedBorder(kNormalImageSet, kHoverImageSet, | |
| 129 kPressedImageSet)); | |
| 130 #endif | |
| 131 } else { | |
| 132 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_NORMAL); | |
| 133 const int kHoverImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_HOVER); | |
| 134 const int kPressedImageSet[] = | |
| 135 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_PRESSED); | |
| 136 SetButtonAvatar(IDR_AVATAR_NATIVE_BUTTON_AVATAR); | |
| 137 SetBorder(CreateThemedBorder(kNormalImageSet, kHoverImageSet, | |
| 138 kPressedImageSet)); | |
| 139 } | |
| 140 } | 197 } |
| 141 | 198 |
| 142 Update(); | 199 Update(); |
| 143 SchedulePaint(); | 200 SchedulePaint(); |
| 144 } | 201 } |
| 145 | 202 |
| 146 AvatarButton::~AvatarButton() {} | 203 AvatarButton::~AvatarButton() {} |
| 147 | 204 |
| 148 void AvatarButton::OnGestureEvent(ui::GestureEvent* event) { | 205 void AvatarButton::OnGestureEvent(ui::GestureEvent* event) { |
| 149 // TODO(wjmaclean): The check for ET_GESTURE_LONG_PRESS is done here since | 206 // TODO(wjmaclean): The check for ET_GESTURE_LONG_PRESS is done here since |
| 150 // no other UI button based on CustomButton appears to handle mouse | 207 // no other UI button based on CustomButton appears to handle mouse |
| 151 // right-click. If other cases are identified, it may make sense to move this | 208 // right-click. If other cases are identified, it may make sense to move this |
| 152 // check to CustomButton. | 209 // check to CustomButton. |
| 153 if (event->type() == ui::ET_GESTURE_LONG_PRESS) | 210 if (event->type() == ui::ET_GESTURE_LONG_PRESS) |
| 154 NotifyClick(*event); | 211 NotifyClick(*event); |
| 155 else | 212 else |
| 156 LabelButton::OnGestureEvent(event); | 213 LabelButton::OnGestureEvent(event); |
| 157 } | 214 } |
| 158 | 215 |
| 159 gfx::Size AvatarButton::GetMinimumSize() const { | 216 gfx::Size AvatarButton::GetMinimumSize() const { |
| 160 if (use_win10_native_button_) { | 217 if (IsCondensible()) { |
| 161 // Returns the size of the button when it is atop the tabstrip. Called by | 218 // Returns the size of the button when it is atop the tabstrip. Called by |
| 162 // GlassBrowserFrameView::LayoutProfileSwitcher(). | 219 // GlassBrowserFrameView::LayoutProfileSwitcher(). |
| 163 // TODO(emx): Calculate the height based on the top of the new tab button. | 220 // TODO(emx): Calculate the height based on the top of the new tab button. |
| 164 return gfx::Size(kMdButtonMinWidth, 20); | 221 return gfx::Size(kCondensibleButtonMinWidth, 20); |
| 165 } | 222 } |
| 166 | 223 |
| 167 return LabelButton::GetMinimumSize(); | 224 return LabelButton::GetMinimumSize(); |
| 168 } | 225 } |
| 169 | 226 |
| 170 gfx::Size AvatarButton::GetPreferredSize() const { | 227 gfx::Size AvatarButton::GetPreferredSize() const { |
| 171 gfx::Size size = LabelButton::GetPreferredSize(); | 228 // TODO(estade): Calculate the height instead of hardcoding to 20 for the |
| 229 // not-condensible case. |
| 230 gfx::Size size(LabelButton::GetPreferredSize().width(), 20); |
| 172 | 231 |
| 173 if (use_win10_native_button_) { | 232 if (IsCondensible()) { |
| 233 // Returns the normal size of the button (when it does not overlap the |
| 234 // tabstrip). |
| 235 size.set_width(std::min(std::max(size.width(), kCondensibleButtonMinWidth), |
| 236 kCondensibleButtonMaxWidth)); |
| 174 #if defined(OS_WIN) | 237 #if defined(OS_WIN) |
| 175 // Returns the normal size of the button (when it does not overlap the | |
| 176 // tabstrip). Its height should match the caption button height. | |
| 177 // The minimum width is the caption button width and the maximum is fixed | |
| 178 // as per the spec in http://crbug.com/635699. | |
| 179 // TODO(emx): Should this be calculated based on average character width? | |
| 180 constexpr int kMdButtonMaxWidth = 98; | |
| 181 size.set_width( | |
| 182 std::min(std::max(size.width(), kMdButtonMinWidth), kMdButtonMaxWidth)); | |
| 183 size.set_height(MinimizeButtonMetrics::GetCaptionButtonHeightInDIPs()); | 238 size.set_height(MinimizeButtonMetrics::GetCaptionButtonHeightInDIPs()); |
| 184 #endif | 239 #endif |
| 185 } else { | |
| 186 size.set_height(20); | |
| 187 } | 240 } |
| 188 | 241 |
| 189 return size; | 242 return size; |
| 190 } | 243 } |
| 191 | 244 |
| 245 std::unique_ptr<views::InkDropMask> AvatarButton::CreateInkDropMask() const { |
| 246 if (button_style_ == AvatarButtonStyle::THEMED) |
| 247 return AvatarButtonThemedBorder::CreateInkDropMask(size()); |
| 248 return LabelButton::CreateInkDropMask(); |
| 249 } |
| 250 |
| 192 std::unique_ptr<views::InkDropHighlight> AvatarButton::CreateInkDropHighlight() | 251 std::unique_ptr<views::InkDropHighlight> AvatarButton::CreateInkDropHighlight() |
| 193 const { | 252 const { |
| 194 auto center = gfx::RectF(GetLocalBounds()).CenterPoint(); | 253 if (button_style_ == AvatarButtonStyle::THEMED) |
| 254 return LabelButton::CreateInkDropHighlight(); |
| 255 |
| 195 auto ink_drop_highlight = base::MakeUnique<views::InkDropHighlight>( | 256 auto ink_drop_highlight = base::MakeUnique<views::InkDropHighlight>( |
| 196 size(), 0, center, GetInkDropBaseColor()); | 257 size(), 0, gfx::RectF(GetLocalBounds()).CenterPoint(), |
| 258 GetInkDropBaseColor()); |
| 197 constexpr float kInkDropHighlightOpacity = 0.08f; | 259 constexpr float kInkDropHighlightOpacity = 0.08f; |
| 198 ink_drop_highlight->set_visible_opacity(kInkDropHighlightOpacity); | 260 ink_drop_highlight->set_visible_opacity(kInkDropHighlightOpacity); |
| 199 return ink_drop_highlight; | 261 return ink_drop_highlight; |
| 200 } | 262 } |
| 201 | 263 |
| 264 void AvatarButton::NotifyClick(const ui::Event& event) { |
| 265 LabelButton::NotifyClick(event); |
| 266 |
| 267 views::Widget* bubble_widget = ProfileChooserView::GetCurrentBubbleWidget(); |
| 268 if (bubble_widget && !bubble_widget->HasObserver(this)) { |
| 269 ProfileChooserView::GetCurrentBubbleWidget()->AddObserver(this); |
| 270 AnimateInkDrop(views::InkDropState::ACTIVATED, |
| 271 ui::LocatedEvent::FromIfValid(&event)); |
| 272 } |
| 273 } |
| 274 |
| 275 bool AvatarButton::ShouldEnterPushedState(const ui::Event& event) { |
| 276 if (ProfileChooserView::IsShowing()) |
| 277 return false; |
| 278 |
| 279 return LabelButton::ShouldEnterPushedState(event); |
| 280 } |
| 281 |
| 202 bool AvatarButton::ShouldUseFloodFillInkDrop() const { | 282 bool AvatarButton::ShouldUseFloodFillInkDrop() const { |
| 203 return true; | 283 return true; |
| 204 } | 284 } |
| 205 | 285 |
| 206 void AvatarButton::OnAvatarErrorChanged() { | 286 void AvatarButton::OnAvatarErrorChanged() { |
| 207 Update(); | 287 Update(); |
| 208 } | 288 } |
| 209 | 289 |
| 210 void AvatarButton::OnProfileAdded(const base::FilePath& profile_path) { | 290 void AvatarButton::OnProfileAdded(const base::FilePath& profile_path) { |
| 211 Update(); | 291 Update(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 225 if (profile_->GetPath() == profile_path) | 305 if (profile_->GetPath() == profile_path) |
| 226 Update(); | 306 Update(); |
| 227 } | 307 } |
| 228 | 308 |
| 229 void AvatarButton::OnProfileSupervisedUserIdChanged( | 309 void AvatarButton::OnProfileSupervisedUserIdChanged( |
| 230 const base::FilePath& profile_path) { | 310 const base::FilePath& profile_path) { |
| 231 if (profile_->GetPath() == profile_path) | 311 if (profile_->GetPath() == profile_path) |
| 232 Update(); | 312 Update(); |
| 233 } | 313 } |
| 234 | 314 |
| 315 void AvatarButton::OnWidgetClosing(views::Widget* widget) { |
| 316 AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); |
| 317 } |
| 318 |
| 235 void AvatarButton::Update() { | 319 void AvatarButton::Update() { |
| 236 ProfileAttributesStorage& storage = | 320 ProfileAttributesStorage& storage = |
| 237 g_browser_process->profile_manager()->GetProfileAttributesStorage(); | 321 g_browser_process->profile_manager()->GetProfileAttributesStorage(); |
| 238 | 322 |
| 239 // If we have a single local profile, then use the generic avatar | 323 // If we have a single local profile, then use the generic avatar |
| 240 // button instead of the profile name. Never use the generic button if | 324 // button instead of the profile name. Never use the generic button if |
| 241 // the active profile is Guest. | 325 // the active profile is Guest. |
| 242 const bool use_generic_button = | 326 const bool use_generic_button = |
| 243 !profile_->IsGuestSession() && storage.GetNumberOfProfiles() == 1 && | 327 !profile_->IsGuestSession() && storage.GetNumberOfProfiles() == 1 && |
| 244 !SigninManagerFactory::GetForProfile(profile_)->IsAuthenticated(); | 328 !SigninManagerFactory::GetForProfile(profile_)->IsAuthenticated(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 272 const int kDefaultImageTextSpacing = 5; | 356 const int kDefaultImageTextSpacing = 5; |
| 273 SetImageLabelSpacing(use_generic_button ? 0 : kDefaultImageTextSpacing); | 357 SetImageLabelSpacing(use_generic_button ? 0 : kDefaultImageTextSpacing); |
| 274 | 358 |
| 275 PreferredSizeChanged(); | 359 PreferredSizeChanged(); |
| 276 } | 360 } |
| 277 | 361 |
| 278 void AvatarButton::SetButtonAvatar(int avatar_idr) { | 362 void AvatarButton::SetButtonAvatar(int avatar_idr) { |
| 279 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 363 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
| 280 generic_avatar_ = *rb->GetImageNamed(avatar_idr).ToImageSkia(); | 364 generic_avatar_ = *rb->GetImageNamed(avatar_idr).ToImageSkia(); |
| 281 } | 365 } |
| 366 |
| 367 // TODO(estade): all versions of this button should condense. |
| 368 bool AvatarButton::IsCondensible() const { |
| 369 #if defined(OS_WIN) |
| 370 return (base::win::GetVersion() >= base::win::VERSION_WIN10) && |
| 371 ThemeServiceFactory::GetForProfile(profile_)->UsingSystemTheme() && |
| 372 button_style_ == AvatarButtonStyle::NATIVE; |
| 373 #else |
| 374 return false; |
| 375 #endif |
| 376 } |
| OLD | NEW |