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/new_avatar_button.h" | 5 #include "chrome/browser/ui/views/profiles/new_avatar_button.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
10 #include "chrome/app/vector_icons/vector_icons.h" | 10 #include "chrome/app/vector_icons/vector_icons.h" |
11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
12 #include "chrome/browser/profiles/profile_attributes_entry.h" | 12 #include "chrome/browser/profiles/profile_attributes_entry.h" |
13 #include "chrome/browser/profiles/profile_manager.h" | 13 #include "chrome/browser/profiles/profile_manager.h" |
14 #include "chrome/browser/profiles/profiles_state.h" | 14 #include "chrome/browser/profiles/profiles_state.h" |
15 #include "chrome/browser/themes/theme_properties.h" | |
15 #include "chrome/browser/ui/views/profiles/avatar_button_delegate.h" | 16 #include "chrome/browser/ui/views/profiles/avatar_button_delegate.h" |
16 #include "chrome/browser/ui/views/profiles/profile_chooser_view.h" | 17 #include "chrome/browser/ui/views/profiles/profile_chooser_view.h" |
17 #include "chrome/grit/theme_resources.h" | 18 #include "chrome/grit/theme_resources.h" |
18 #include "components/signin/core/common/profile_management_switches.h" | 19 #include "components/signin/core/common/profile_management_switches.h" |
19 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
21 #include "ui/base/theme_provider.h" | |
20 #include "ui/gfx/canvas.h" | 22 #include "ui/gfx/canvas.h" |
21 #include "ui/gfx/color_palette.h" | 23 #include "ui/gfx/color_palette.h" |
22 #include "ui/gfx/geometry/vector2d.h" | 24 #include "ui/gfx/geometry/vector2d.h" |
23 #include "ui/gfx/paint_vector_icon.h" | 25 #include "ui/gfx/paint_vector_icon.h" |
24 #include "ui/vector_icons/vector_icons.h" | 26 #include "ui/vector_icons/vector_icons.h" |
27 #include "ui/views/animation/ink_drop_mask.h" | |
25 #include "ui/views/border.h" | 28 #include "ui/views/border.h" |
26 #include "ui/views/controls/button/label_button_border.h" | 29 #include "ui/views/controls/button/label_button_border.h" |
27 #include "ui/views/painter.h" | 30 #include "ui/views/painter.h" |
28 | 31 |
29 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
30 #include "base/win/windows_version.h" | 33 #include "base/win/windows_version.h" |
31 #endif | 34 #endif |
32 | 35 |
33 namespace { | 36 namespace { |
34 | 37 |
38 // Insets between view bounds and the filled region for | |
39 // AvatarButtonThemedBorder. | |
40 static constexpr gfx::InsetsF kFillInsets(1); | |
41 | |
42 // Corner radius of the roundrect for AvatarButtonThemedBorder. | |
43 static constexpr float kCornerRadius = 1; | |
44 | |
45 // This class draws the border (and background) of the avatar button for | |
46 // "themed" browser windows, i.e. OpaqueBrowserFrameView. Currently it's only | |
47 // used on Linux as the shape specifically matches the Linux caption buttons. | |
48 // TODO(estade): make this look nice on Windows and use it there as well. | |
49 class AvatarButtonThemedBorder : public views::Border { | |
50 public: | |
51 AvatarButtonThemedBorder() {} | |
52 ~AvatarButtonThemedBorder() override {} | |
53 | |
54 void Paint(const views::View& view, gfx::Canvas* canvas) override { | |
55 gfx::RectF fill_bounds(view.GetLocalBounds()); | |
56 fill_bounds.Inset(kFillInsets); | |
57 cc::PaintFlags fill_flags; | |
58 fill_flags.setStyle(cc::PaintFlags::kFill_Style); | |
59 fill_flags.setColor(view.GetThemeProvider()->GetColor( | |
60 ThemeProperties::COLOR_BUTTON_BACKGROUND)); | |
61 fill_flags.setAntiAlias(true); | |
62 canvas->DrawRoundRect(fill_bounds, kCornerRadius, fill_flags); | |
63 | |
64 // Start with an outer dark stroke. | |
65 cc::PaintFlags stroke_flags; | |
66 stroke_flags.setStyle(cc::PaintFlags::kStroke_Style); | |
67 stroke_flags.setColor(SkColorSetA(SK_ColorBLACK, 0x2B)); | |
68 stroke_flags.setStrokeWidth(1); | |
69 stroke_flags.setAntiAlias(true); | |
70 gfx::RectF stroke_bounds(view.GetLocalBounds()); | |
71 stroke_bounds.Inset(gfx::InsetsF(0.5f)); | |
72 canvas->DrawRoundRect(stroke_bounds, kCornerRadius, stroke_flags); | |
73 | |
74 // There's a second, light stroke that matches the fill bounds. | |
Peter Kasting
2017/04/27 02:13:18
I'm a little worried about the radii of the corner
| |
75 stroke_bounds.Inset(kFillInsets); | |
76 stroke_flags.setColor(SkColorSetA(SK_ColorWHITE, 0x3F)); | |
77 canvas->DrawRoundRect(stroke_bounds, kCornerRadius, stroke_flags); | |
78 } | |
79 | |
80 gfx::Insets GetInsets() const override { | |
81 const int kLeftRightInset = 8; | |
82 const int kTopInset = 2; | |
83 const int kBottomInset = 4; | |
84 return gfx::Insets(kTopInset, kLeftRightInset, kBottomInset, | |
85 kLeftRightInset); | |
86 } | |
87 | |
88 gfx::Size GetMinimumSize() const override { | |
89 return gfx::Size(GetInsets().width(), GetInsets().height()); | |
90 } | |
91 | |
92 private: | |
93 DISALLOW_COPY_AND_ASSIGN(AvatarButtonThemedBorder); | |
94 }; | |
95 | |
96 #if !defined(OS_LINUX) | |
35 std::unique_ptr<views::Border> CreateBorder(const int normal_image_set[], | 97 std::unique_ptr<views::Border> CreateBorder(const int normal_image_set[], |
36 const int hot_image_set[], | 98 const int hot_image_set[], |
37 const int pushed_image_set[]) { | 99 const int pushed_image_set[]) { |
38 std::unique_ptr<views::LabelButtonAssetBorder> border( | 100 std::unique_ptr<views::LabelButtonAssetBorder> border( |
39 new views::LabelButtonAssetBorder(views::Button::STYLE_TEXTBUTTON)); | 101 new views::LabelButtonAssetBorder(views::Button::STYLE_TEXTBUTTON)); |
40 border->SetPainter(false, views::Button::STATE_NORMAL, | 102 border->SetPainter(false, views::Button::STATE_NORMAL, |
41 views::Painter::CreateImageGridPainter(normal_image_set)); | 103 views::Painter::CreateImageGridPainter(normal_image_set)); |
42 border->SetPainter(false, views::Button::STATE_HOVERED, | 104 border->SetPainter(false, views::Button::STATE_HOVERED, |
43 views::Painter::CreateImageGridPainter(hot_image_set)); | 105 views::Painter::CreateImageGridPainter(hot_image_set)); |
44 border->SetPainter(false, views::Button::STATE_PRESSED, | 106 border->SetPainter(false, views::Button::STATE_PRESSED, |
45 views::Painter::CreateImageGridPainter(pushed_image_set)); | 107 views::Painter::CreateImageGridPainter(pushed_image_set)); |
46 | 108 |
47 const int kLeftRightInset = 8; | 109 const int kLeftRightInset = 8; |
48 const int kTopInset = 2; | 110 const int kTopInset = 2; |
49 const int kBottomInset = 4; | 111 const int kBottomInset = 4; |
50 border->set_insets(gfx::Insets(kTopInset, kLeftRightInset, | 112 border->set_insets(gfx::Insets(kTopInset, kLeftRightInset, |
51 kBottomInset, kLeftRightInset)); | 113 kBottomInset, kLeftRightInset)); |
52 | 114 |
53 return std::move(border); | 115 return std::move(border); |
54 } | 116 } |
117 #endif | |
55 | 118 |
56 } // namespace | 119 } // namespace |
57 | 120 |
58 NewAvatarButton::NewAvatarButton(AvatarButtonDelegate* delegate, | 121 NewAvatarButton::NewAvatarButton(AvatarButtonDelegate* delegate, |
59 AvatarButtonStyle button_style, | 122 AvatarButtonStyle button_style, |
60 Profile* profile) | 123 Profile* profile) |
61 : LabelButton(delegate, base::string16()), | 124 : LabelButton(delegate, base::string16()), |
62 delegate_(delegate), | 125 delegate_(delegate), |
63 error_controller_(this, profile), | 126 error_controller_(this, profile), |
64 profile_(profile), | 127 profile_(profile), |
65 suppress_mouse_released_action_(false) { | 128 suppress_mouse_released_action_(false) { |
66 set_triggerable_event_flags( | 129 set_triggerable_event_flags( |
67 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON); | 130 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON); |
68 set_animate_on_state_change(false); | 131 set_animate_on_state_change(false); |
69 SetEnabledTextColors(SK_ColorWHITE); | 132 SetEnabledTextColors(SK_ColorWHITE); |
70 SetTextSubpixelRenderingEnabled(false); | 133 SetTextSubpixelRenderingEnabled(false); |
71 SetHorizontalAlignment(gfx::ALIGN_CENTER); | 134 SetHorizontalAlignment(gfx::ALIGN_CENTER); |
72 | 135 |
73 // The largest text height that fits in the button. If the font list height | 136 // The largest text height that fits in the button. If the font list height |
74 // is larger than this, it will be shrunk to match it. | 137 // is larger than this, it will be shrunk to match it. |
75 // TODO(noms): Calculate this constant algorithmically from the button's size. | 138 // TODO(noms): Calculate this constant algorithmically from the button's size. |
76 const int kDisplayFontHeight = 16; | 139 const int kDisplayFontHeight = 16; |
77 SetFontList( | 140 SetFontList( |
78 label()->font_list().DeriveWithHeightUpperBound(kDisplayFontHeight)); | 141 label()->font_list().DeriveWithHeightUpperBound(kDisplayFontHeight)); |
79 | 142 |
80 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 143 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
144 generic_avatar_ = | |
145 rb->GetImageNamed(IDR_AVATAR_THEMED_BUTTON_AVATAR).AsImageSkia(); | |
146 #if defined(OS_LINUX) | |
147 DCHECK_EQ(AvatarButtonStyle::THEMED, button_style); | |
148 SetBorder(base::MakeUnique<AvatarButtonThemedBorder>()); | |
149 SetInkDropMode(InkDropMode::ON); | |
150 #else // !defined(OS_LINUX) | |
81 if (button_style == AvatarButtonStyle::THEMED) { | 151 if (button_style == AvatarButtonStyle::THEMED) { |
152 SetBorder(base::MakeUnique<AvatarButtonThemedBorder>()); | |
153 SetInkDropMode(InkDropMode::ON); | |
82 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_NORMAL); | 154 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_NORMAL); |
83 const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_HOVER); | 155 const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_HOVER); |
84 const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_PRESSED); | 156 const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_PRESSED); |
85 | 157 |
86 SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet)); | 158 SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet)); |
87 generic_avatar_ = | |
88 *rb->GetImageNamed(IDR_AVATAR_THEMED_BUTTON_AVATAR).ToImageSkia(); | |
89 #if defined(OS_WIN) | 159 #if defined(OS_WIN) |
90 } else if (base::win::GetVersion() < base::win::VERSION_WIN8) { | 160 } else if (base::win::GetVersion() < base::win::VERSION_WIN8) { |
91 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_NORMAL); | 161 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_NORMAL); |
92 const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_HOVER); | 162 const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_HOVER); |
93 const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_PRESSED); | 163 const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_PRESSED); |
94 | 164 |
95 SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet)); | 165 SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet)); |
96 generic_avatar_ = | 166 generic_avatar_ = |
97 *rb->GetImageNamed(IDR_AVATAR_GLASS_BUTTON_AVATAR).ToImageSkia(); | 167 *rb->GetImageNamed(IDR_AVATAR_GLASS_BUTTON_AVATAR).ToImageSkia(); |
98 #endif | 168 #endif |
99 } else { | 169 } else { |
100 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_NORMAL); | 170 const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_NORMAL); |
101 const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_HOVER); | 171 const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_HOVER); |
102 const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_PRESSED); | 172 const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_PRESSED); |
103 | 173 |
104 SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet)); | 174 SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet)); |
105 generic_avatar_ = | 175 generic_avatar_ = |
106 *rb->GetImageNamed(IDR_AVATAR_NATIVE_BUTTON_AVATAR).ToImageSkia(); | 176 *rb->GetImageNamed(IDR_AVATAR_NATIVE_BUTTON_AVATAR).ToImageSkia(); |
107 } | 177 } |
178 #endif // !defined(OS_LINUX) | |
108 | 179 |
109 g_browser_process->profile_manager()-> | 180 g_browser_process->profile_manager()-> |
110 GetProfileAttributesStorage().AddObserver(this); | 181 GetProfileAttributesStorage().AddObserver(this); |
111 Update(); | 182 Update(); |
112 SchedulePaint(); | 183 SchedulePaint(); |
113 } | 184 } |
114 | 185 |
115 NewAvatarButton::~NewAvatarButton() { | 186 NewAvatarButton::~NewAvatarButton() { |
116 g_browser_process->profile_manager()-> | 187 g_browser_process->profile_manager()-> |
117 GetProfileAttributesStorage().RemoveObserver(this); | 188 GetProfileAttributesStorage().RemoveObserver(this); |
118 } | 189 } |
119 | 190 |
120 bool NewAvatarButton::OnMousePressed(const ui::MouseEvent& event) { | 191 bool NewAvatarButton::OnMousePressed(const ui::MouseEvent& event) { |
121 // Prevent the bubble from being re-shown if it's already showing. | 192 // Prevent the bubble from being re-shown if it's already showing. |
122 suppress_mouse_released_action_ = ProfileChooserView::IsShowing(); | 193 suppress_mouse_released_action_ = ProfileChooserView::IsShowing(); |
123 return LabelButton::OnMousePressed(event); | 194 return LabelButton::OnMousePressed(event); |
124 } | 195 } |
125 | 196 |
126 void NewAvatarButton::OnMouseReleased(const ui::MouseEvent& event) { | 197 void NewAvatarButton::OnMouseReleased(const ui::MouseEvent& event) { |
127 if (suppress_mouse_released_action_) | 198 if (suppress_mouse_released_action_) |
128 suppress_mouse_released_action_ = false; | 199 suppress_mouse_released_action_ = false; |
129 else | 200 else |
130 LabelButton::OnMouseReleased(event); | 201 LabelButton::OnMouseReleased(event); |
131 } | 202 } |
132 | 203 |
204 SkColor NewAvatarButton::GetInkDropBaseColor() const { | |
205 return SK_ColorWHITE; | |
Evan Stade
2017/04/26 19:24:49
I stuck with white because the theme-colored backg
Peter Kasting
2017/04/27 02:13:18
Is the drop visible at all on a pure-white toolbar
| |
206 } | |
207 | |
208 std::unique_ptr<views::InkDropMask> NewAvatarButton::CreateInkDropMask() const { | |
209 return base::MakeUnique<views::RoundRectInkDropMask>(size(), kFillInsets, | |
210 kCornerRadius); | |
211 } | |
212 | |
213 void NewAvatarButton::NotifyClick(const ui::Event& event) { | |
214 LabelButton::NotifyClick(event); | |
215 | |
216 if (ProfileChooserView::IsShowing() && ink_drop_mode() == InkDropMode::ON) { | |
217 ProfileChooserView::GetCurrentBubbleWidget()->AddObserver(this); | |
218 AnimateInkDrop(views::InkDropState::ACTIVATED, | |
219 ui::LocatedEvent::FromIfValid(&event)); | |
220 } | |
221 } | |
222 | |
133 void NewAvatarButton::OnGestureEvent(ui::GestureEvent* event) { | 223 void NewAvatarButton::OnGestureEvent(ui::GestureEvent* event) { |
134 // TODO(wjmaclean): The check for ET_GESTURE_LONG_PRESS is done here since | 224 // TODO(wjmaclean): The check for ET_GESTURE_LONG_PRESS is done here since |
135 // no other UI button based on CustomButton appears to handle mouse | 225 // no other UI button based on CustomButton appears to handle mouse |
136 // right-click. If other cases are identified, it may make sense to move this | 226 // right-click. If other cases are identified, it may make sense to move this |
137 // check to CustomButton. | 227 // check to CustomButton. |
138 if (event->type() == ui::ET_GESTURE_LONG_PRESS) | 228 if (event->type() == ui::ET_GESTURE_LONG_PRESS) |
139 NotifyClick(*event); | 229 NotifyClick(*event); |
140 else | 230 else |
141 LabelButton::OnGestureEvent(event); | 231 LabelButton::OnGestureEvent(event); |
142 } | 232 } |
(...skipping 21 matching lines...) Expand all Loading... | |
164 if (profile_->GetPath() == profile_path) | 254 if (profile_->GetPath() == profile_path) |
165 Update(); | 255 Update(); |
166 } | 256 } |
167 | 257 |
168 void NewAvatarButton::OnProfileSupervisedUserIdChanged( | 258 void NewAvatarButton::OnProfileSupervisedUserIdChanged( |
169 const base::FilePath& profile_path) { | 259 const base::FilePath& profile_path) { |
170 if (profile_->GetPath() == profile_path) | 260 if (profile_->GetPath() == profile_path) |
171 Update(); | 261 Update(); |
172 } | 262 } |
173 | 263 |
264 void NewAvatarButton::OnWidgetClosing(views::Widget* widget) { | |
265 if (ink_drop_mode() == InkDropMode::ON) | |
266 AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); | |
267 } | |
268 | |
174 void NewAvatarButton::Update() { | 269 void NewAvatarButton::Update() { |
175 ProfileAttributesStorage& storage = | 270 ProfileAttributesStorage& storage = |
176 g_browser_process->profile_manager()->GetProfileAttributesStorage(); | 271 g_browser_process->profile_manager()->GetProfileAttributesStorage(); |
177 | 272 |
178 // If we have a single local profile, then use the generic avatar | 273 // If we have a single local profile, then use the generic avatar |
179 // button instead of the profile name. Never use the generic button if | 274 // button instead of the profile name. Never use the generic button if |
180 // the active profile is Guest. | 275 // the active profile is Guest. |
181 const bool use_generic_button = | 276 const bool use_generic_button = |
182 !profile_->IsGuestSession() && | 277 !profile_->IsGuestSession() && |
183 storage.GetNumberOfProfiles() == 1 && | 278 storage.GetNumberOfProfiles() == 1 && |
(...skipping 24 matching lines...) Expand all Loading... | |
208 } | 303 } |
209 | 304 |
210 // If we are not using the generic button, then reset the spacing between | 305 // If we are not using the generic button, then reset the spacing between |
211 // the text and the possible authentication error icon. | 306 // the text and the possible authentication error icon. |
212 const int kDefaultImageTextSpacing = 5; | 307 const int kDefaultImageTextSpacing = 5; |
213 SetImageLabelSpacing(use_generic_button ? 0 : kDefaultImageTextSpacing); | 308 SetImageLabelSpacing(use_generic_button ? 0 : kDefaultImageTextSpacing); |
214 | 309 |
215 PreferredSizeChanged(); | 310 PreferredSizeChanged(); |
216 delegate_->ButtonPreferredSizeChanged(); | 311 delegate_->ButtonPreferredSizeChanged(); |
217 } | 312 } |
OLD | NEW |