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

Side by Side Diff: ui/app_list/views/page_switcher_vertical.cc

Issue 2942523002: Add new style to page switcher (Closed)
Patch Set: Clean up code Created 3 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
« no previous file with comments | « ui/app_list/views/page_switcher_vertical.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 "ui/app_list/views/page_switcher_vertical.h" 5 #include "ui/app_list/views/page_switcher_vertical.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "third_party/skia/include/core/SkPath.h" 10 #include "third_party/skia/include/core/SkPath.h"
11 #include "ui/app_list/app_list_constants.h" 11 #include "ui/app_list/app_list_constants.h"
12 #include "ui/app_list/pagination_model.h" 12 #include "ui/app_list/pagination_model.h"
13 #include "ui/gfx/animation/throb_animation.h" 13 #include "ui/gfx/animation/throb_animation.h"
14 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/canvas.h"
15 #include "ui/gfx/geometry/insets.h" 15 #include "ui/gfx/geometry/insets.h"
16 #include "ui/gfx/skia_util.h" 16 #include "ui/gfx/skia_util.h"
17 #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
18 #include "ui/views/animation/ink_drop_highlight.h"
19 #include "ui/views/animation/ink_drop_impl.h"
20 #include "ui/views/animation/ink_drop_mask.h"
21 #include "ui/views/animation/ink_drop_painted_layer_delegates.h"
17 #include "ui/views/controls/button/custom_button.h" 22 #include "ui/views/controls/button/custom_button.h"
18 #include "ui/views/layout/box_layout.h" 23 #include "ui/views/layout/box_layout.h"
19 24
20 namespace app_list { 25 namespace app_list {
21 26
22 namespace { 27 namespace {
23 28
24 const int kPreferredWidth = 58; 29 constexpr int kNormalButtonRadius = 3;
30 constexpr int kSelectedButtonRadius = 4;
31 constexpr int kInkDropRadius = 8;
32 // The padding on top/bottom side of each button.
33 constexpr int kButtonPadding = 12;
34 // The padding of a list of buttons as a button strip.
35 constexpr int kButtonStripPadding = 24;
36 constexpr int kMaxButtonRadius = 8;
37 constexpr int kPreferredButtonStripWidth =
38 kMaxButtonRadius * 2 + kButtonStripPadding * 2;
25 39
26 const int kMaxButtonSpacing = 18; 40 // The selected button color.
27 const int kMinButtonSpacing = 4; 41 constexpr SkColor kSelectedButtonColor = SK_ColorWHITE;
28 const int kMaxButtonHeight = 68; 42 // The normal button color (54% white).
29 const int kMinButtonHeight = 28; 43 constexpr SkColor kNormalColor = SkColorSetA(SK_ColorWHITE, 138);
30 const int kButtonWidth = 6; 44 constexpr SkColor kInkDropBaseColor = SK_ColorWHITE;
31 const int kButtonCornerRadius = 2; 45 constexpr SkColor kInkDropRippleColor = SkColorSetA(kInkDropBaseColor, 20);
32 const int kButtonStripPadding = 20; 46 constexpr SkColor kInkDropHighlightColor = SkColorSetA(kInkDropBaseColor, 15);
47
48 constexpr SkScalar kStrokeWidth = SkIntToScalar(1);
33 49
34 class PageSwitcherButton : public views::CustomButton { 50 class PageSwitcherButton : public views::CustomButton {
35 public: 51 public:
36 explicit PageSwitcherButton(views::ButtonListener* listener) 52 explicit PageSwitcherButton(views::ButtonListener* listener)
37 : views::CustomButton(listener), 53 : views::CustomButton(listener) {
38 button_height_(kMaxButtonHeight), 54 SetInkDropMode(InkDropMode::ON);
39 selected_range_(0) {} 55 }
56
40 ~PageSwitcherButton() override {} 57 ~PageSwitcherButton() override {}
41 58
42 void SetSelectedRange(double selected_range) { 59 void SetSelected(bool selected) {
43 if (selected_range_ == selected_range) 60 if (selected == selected_)
44 return; 61 return;
45 62
46 selected_range_ = selected_range; 63 selected_ = selected;
47 SchedulePaint(); 64 SchedulePaint();
48 } 65 }
49 66
50 void set_button_height(int button_height) { button_height_ = button_height; }
51
52 // Overridden from views::View: 67 // Overridden from views::View:
53 gfx::Size CalculatePreferredSize() const override { 68 gfx::Size CalculatePreferredSize() const override {
54 return gfx::Size(kButtonWidth, button_height_); 69 return gfx::Size(kMaxButtonRadius * 2, kMaxButtonRadius * 2);
55 } 70 }
56 71
57 void PaintButtonContents(gfx::Canvas* canvas) override { 72 void PaintButtonContents(gfx::Canvas* canvas) override {
58 if (state() == STATE_HOVERED) 73 PaintButton(canvas, BuildPaintButtonInfo());
59 PaintButton(canvas, kPagerHoverColor);
60 else
61 PaintButton(canvas, kPagerNormalColor);
62 } 74 }
63 75
64 void OnGestureEvent(ui::GestureEvent* event) override { 76 protected:
65 CustomButton::OnGestureEvent(event); 77 bool IsTriggerableEvent(const ui::Event& event) override {
78 return event.IsMouseEvent() &&
79 (triggerable_event_flags() & event.flags()) != 0;
80 }
66 81
67 if (event->type() == ui::ET_GESTURE_TAP_DOWN) 82 std::unique_ptr<views::InkDrop> CreateInkDrop() override {
68 SetState(views::CustomButton::STATE_HOVERED); 83 std::unique_ptr<views::InkDropImpl> ink_drop =
69 else if (event->type() == ui::ET_GESTURE_TAP_CANCEL || 84 CustomButton::CreateDefaultInkDropImpl();
70 event->type() == ui::ET_GESTURE_TAP) 85 ink_drop->SetShowHighlightOnHover(false);
71 SetState(views::CustomButton::STATE_NORMAL); 86 ink_drop->SetAutoHighlightMode(
72 SchedulePaint(); 87 views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE);
88 return std::move(ink_drop);
89 }
90
91 std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override {
92 return base::MakeUnique<views::CircleInkDropMask>(
93 size(), GetLocalBounds().CenterPoint(), kMaxButtonRadius);
94 }
95
96 std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override {
97 gfx::Point center = GetLocalBounds().CenterPoint();
98 gfx::Rect bounds(center.x() - kMaxButtonRadius,
99 center.y() - kMaxButtonRadius, 2 * kMaxButtonRadius,
100 2 * kMaxButtonRadius);
101 return base::MakeUnique<views::FloodFillInkDropRipple>(
102 size(), GetLocalBounds().InsetsFrom(bounds),
103 GetInkDropCenterBasedOnLastEvent(), kInkDropRippleColor, 1.0f);
104 }
105
106 std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
107 const override {
108 return base::MakeUnique<views::InkDropHighlight>(
109 gfx::PointF(GetLocalBounds().CenterPoint()),
110 base::MakeUnique<views::CircleLayerDelegate>(kInkDropHighlightColor,
111 kInkDropRadius));
112 }
113
114 void NotifyClick(const ui::Event& event) override {
115 CustomButton::NotifyClick(event);
116 GetInkDrop()->AnimateToState(views::InkDropState::ACTION_TRIGGERED);
73 } 117 }
74 118
75 private: 119 private:
76 // Paints a button that has two rounded corner at bottom. 120 // Stores the information of how to paint the button.
77 void PaintButton(gfx::Canvas* canvas, SkColor base_color) { 121 struct PaintButtonInfo {
122 SkColor color;
123 cc::PaintFlags::Style style;
124 SkScalar radius;
125 SkScalar stroke_width;
126 };
127
128 // Returns the information of how to paint selected/normal button.
129 PaintButtonInfo BuildPaintButtonInfo() {
130 PaintButtonInfo info;
131 if (selected_) {
132 info.color = kSelectedButtonColor;
133 info.style = cc::PaintFlags::kFill_Style;
134 info.radius = SkIntToScalar(kSelectedButtonRadius);
135 info.stroke_width = SkIntToScalar(0);
136 } else {
137 info.color = kNormalColor;
138 info.style = cc::PaintFlags::kStroke_Style;
139 info.radius = SkIntToScalar(kNormalButtonRadius);
140 info.stroke_width = kStrokeWidth;
141 }
142 return info;
143 }
144
145 // Paints a button based on the |info|.
146 void PaintButton(gfx::Canvas* canvas, PaintButtonInfo info) {
78 gfx::Rect rect(GetContentsBounds()); 147 gfx::Rect rect(GetContentsBounds());
79 rect.ClampToCenteredSize(gfx::Size(kButtonWidth, button_height_));
80
81 SkPath path; 148 SkPath path;
82 path.addRoundRect(gfx::RectToSkRect(rect), 149 path.addCircle(rect.CenterPoint().x(), rect.CenterPoint().y(), info.radius);
83 SkIntToScalar(kButtonCornerRadius),
84 SkIntToScalar(kButtonCornerRadius));
85 150
86 cc::PaintFlags flags; 151 cc::PaintFlags flags;
87 flags.setAntiAlias(true); 152 flags.setAntiAlias(true);
88 flags.setStyle(cc::PaintFlags::kFill_Style); 153 flags.setStyle(info.style);
89 flags.setColor(base_color); 154 flags.setColor(info.color);
90 canvas->DrawPath(path, flags); 155 canvas->DrawPath(path, flags);
91
92 int selected_start_y = 0;
93 int selected_height = 0;
94 if (selected_range_ > 0) {
95 selected_height = selected_range_ * rect.height();
96 } else if (selected_range_ < 0) {
97 selected_height = -selected_range_ * rect.height();
98 selected_start_y = rect.bottom() - selected_height;
99 }
100
101 if (selected_height) {
102 gfx::Rect selected_rect(rect);
103 selected_rect.set_y(selected_start_y);
104 selected_rect.set_height(selected_height);
105
106 SkPath selected_path;
107 selected_path.addRoundRect(gfx::RectToSkRect(selected_rect),
108 SkIntToScalar(kButtonCornerRadius),
109 SkIntToScalar(kButtonCornerRadius));
110 flags.setColor(kPagerSelectedColor);
111 canvas->DrawPath(selected_path, flags);
112 }
113 } 156 }
114 157
115 int button_height_; 158 // If this button is selected, set to true. By default, set to false;
116 159 bool selected_ = false;
117 // [-1, 1] range that represents the portion of the button that should be
118 // painted with kSelectedColor. Positive range starts from top side and
119 // negative range starts from the bottom side.
120 double selected_range_;
121 160
122 DISALLOW_COPY_AND_ASSIGN(PageSwitcherButton); 161 DISALLOW_COPY_AND_ASSIGN(PageSwitcherButton);
123 }; 162 };
124 163
125 // Gets PageSwitcherButton at |index| in |buttons|. 164 // Gets PageSwitcherButton at |index| in |buttons|.
126 PageSwitcherButton* GetButtonByIndex(views::View* buttons, int index) { 165 PageSwitcherButton* GetButtonByIndex(views::View* buttons, int index) {
127 return static_cast<PageSwitcherButton*>(buttons->child_at(index)); 166 return static_cast<PageSwitcherButton*>(buttons->child_at(index));
128 } 167 }
129 168
130 } // namespace 169 } // namespace
131 170
132 PageSwitcherVertical::PageSwitcherVertical(PaginationModel* model) 171 PageSwitcherVertical::PageSwitcherVertical(PaginationModel* model)
133 : model_(model), buttons_(new views::View) { 172 : model_(model), buttons_(new views::View) {
173 buttons_->SetLayoutManager(new views::BoxLayout(
174 views::BoxLayout::kVertical,
175 gfx::Insets(kButtonStripPadding, kButtonStripPadding), kButtonPadding));
176
134 AddChildView(buttons_); 177 AddChildView(buttons_);
135 178
136 TotalPagesChanged(); 179 TotalPagesChanged();
137 SelectedPageChanged(-1, model->selected_page()); 180 SelectedPageChanged(-1, model->selected_page());
138 model_->AddObserver(this); 181 model_->AddObserver(this);
139 } 182 }
140 183
141 PageSwitcherVertical::~PageSwitcherVertical() { 184 PageSwitcherVertical::~PageSwitcherVertical() {
142 model_->RemoveObserver(this); 185 model_->RemoveObserver(this);
143 } 186 }
(...skipping 28 matching lines...) Expand all
172 for (int i = 0; i < button_count; ++i) { 215 for (int i = 0; i < button_count; ++i) {
173 PageSwitcherButton* button = 216 PageSwitcherButton* button =
174 static_cast<PageSwitcherButton*>(buttons_->child_at(i)); 217 static_cast<PageSwitcherButton*>(buttons_->child_at(i));
175 button->SetState(views::CustomButton::STATE_NORMAL); 218 button->SetState(views::CustomButton::STATE_NORMAL);
176 } 219 }
177 } 220 }
178 221
179 gfx::Size PageSwitcherVertical::CalculatePreferredSize() const { 222 gfx::Size PageSwitcherVertical::CalculatePreferredSize() const {
180 // Always return a size with correct width so that container resize is not 223 // Always return a size with correct width so that container resize is not
181 // needed when more pages are added. 224 // needed when more pages are added.
182 return gfx::Size(kPreferredWidth, buttons_->GetPreferredSize().height()); 225 return gfx::Size(kPreferredButtonStripWidth,
226 buttons_->GetPreferredSize().height());
183 } 227 }
184 228
185 void PageSwitcherVertical::Layout() { 229 void PageSwitcherVertical::Layout() {
186 gfx::Rect rect(GetContentsBounds()); 230 gfx::Rect rect(GetContentsBounds());
187 231
188 CalculateButtonHeightAndSpacing(rect.height());
189
190 // Makes |buttons_| vertically center and horizontally fill. 232 // Makes |buttons_| vertically center and horizontally fill.
191 gfx::Size buttons_size(buttons_->GetPreferredSize()); 233 gfx::Size buttons_size(buttons_->GetPreferredSize());
192 gfx::Rect buttons_bounds(rect.x(), 234 gfx::Rect buttons_bounds(rect.x(),
193 rect.CenterPoint().y() - buttons_size.height() / 2, 235 rect.CenterPoint().y() - buttons_size.height() / 2,
194 rect.width(), buttons_size.height()); 236 rect.width(), buttons_size.height());
195 buttons_->SetBoundsRect(gfx::IntersectRects(rect, buttons_bounds)); 237 buttons_->SetBoundsRect(gfx::IntersectRects(rect, buttons_bounds));
196 } 238 }
197 239
198 void PageSwitcherVertical::CalculateButtonHeightAndSpacing(
199 int contents_height) {
200 const int button_count = buttons_->child_count();
201 if (!button_count)
202 return;
203
204 contents_height -= 2 * kButtonStripPadding;
205
206 int button_height = kMinButtonHeight;
207 int button_spacing = kMinButtonSpacing;
208 if (button_count > 1) {
209 button_spacing =
210 (contents_height - button_height * button_count) / (button_count - 1);
211 button_spacing = std::min(kMaxButtonSpacing,
212 std::max(kMinButtonSpacing, button_spacing));
213 }
214
215 button_height =
216 (contents_height - (button_count - 1) * button_spacing) / button_count;
217 button_height =
218 std::min(kMaxButtonHeight, std::max(kMinButtonHeight, button_height));
219
220 buttons_->SetLayoutManager(new views::BoxLayout(
221 views::BoxLayout::kVertical, gfx::Insets(kButtonStripPadding, 0),
222 button_spacing));
223 for (int i = 0; i < button_count; ++i) {
224 PageSwitcherButton* button =
225 static_cast<PageSwitcherButton*>(buttons_->child_at(i));
226 button->set_button_height(button_height);
227 }
228 }
229
230 void PageSwitcherVertical::ButtonPressed(views::Button* sender, 240 void PageSwitcherVertical::ButtonPressed(views::Button* sender,
231 const ui::Event& event) { 241 const ui::Event& event) {
232 for (int i = 0; i < buttons_->child_count(); ++i) { 242 for (int i = 0; i < buttons_->child_count(); ++i) {
233 if (sender == static_cast<views::Button*>(buttons_->child_at(i))) { 243 if (sender == static_cast<views::Button*>(buttons_->child_at(i))) {
234 model_->SelectPage(i, true /* animate */); 244 model_->SelectPage(i, true /* animate */);
235 break; 245 break;
236 } 246 }
237 } 247 }
238 } 248 }
239 249
240 void PageSwitcherVertical::TotalPagesChanged() { 250 void PageSwitcherVertical::TotalPagesChanged() {
241 buttons_->RemoveAllChildViews(true); 251 buttons_->RemoveAllChildViews(true);
242 for (int i = 0; i < model_->total_pages(); ++i) { 252 for (int i = 0; i < model_->total_pages(); ++i) {
243 PageSwitcherButton* button = new PageSwitcherButton(this); 253 PageSwitcherButton* button = new PageSwitcherButton(this);
244 button->SetSelectedRange(i == model_->selected_page() ? 1 : 0); 254 button->SetSelected(i == model_->selected_page() ? true : false);
245 buttons_->AddChildView(button); 255 buttons_->AddChildView(button);
246 } 256 }
247 buttons_->SetVisible(model_->total_pages() > 1); 257 buttons_->SetVisible(model_->total_pages() > 1);
248 Layout(); 258 Layout();
249 } 259 }
250 260
251 void PageSwitcherVertical::SelectedPageChanged(int old_selected, 261 void PageSwitcherVertical::SelectedPageChanged(int old_selected,
252 int new_selected) { 262 int new_selected) {
253 if (old_selected >= 0 && old_selected < buttons_->child_count()) 263 if (old_selected >= 0 && old_selected < buttons_->child_count())
254 GetButtonByIndex(buttons_, old_selected)->SetSelectedRange(0); 264 GetButtonByIndex(buttons_, old_selected)->SetSelected(false);
255 if (new_selected >= 0 && new_selected < buttons_->child_count()) 265 if (new_selected >= 0 && new_selected < buttons_->child_count())
256 GetButtonByIndex(buttons_, new_selected)->SetSelectedRange(1); 266 GetButtonByIndex(buttons_, new_selected)->SetSelected(true);
257 } 267 }
258 268
259 void PageSwitcherVertical::TransitionStarted() {} 269 void PageSwitcherVertical::TransitionStarted() {}
260 270
261 void PageSwitcherVertical::TransitionChanged() { 271 void PageSwitcherVertical::TransitionChanged() {}
262 const int current_page = model_->selected_page();
263 const int target_page = model_->transition().target_page;
264
265 double progress = model_->transition().progress;
266 double remaining = progress - 1;
267
268 if (current_page > target_page) {
269 remaining = -remaining;
270 progress = -progress;
271 }
272
273 GetButtonByIndex(buttons_, current_page)->SetSelectedRange(remaining);
274 if (model_->is_valid_page(target_page))
275 GetButtonByIndex(buttons_, target_page)->SetSelectedRange(progress);
276 }
277 272
278 } // namespace app_list 273 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/views/page_switcher_vertical.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698