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

Side by Side Diff: ui/views/controls/button/chrome_style.cc

Issue 10933085: Update ConstrainedWindowViews appearance according to mock (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Browser test fixes Created 8 years, 2 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/views/controls/button/chrome_style.h"
6
7 #include <algorithm>
8
9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/color_utils.h"
11 #include "ui/views/painter.h"
12 #include "ui/views/background.h"
13
14 namespace views {
15 namespace {
16 const int kMinWidth = 72;
17 const int kMinHeight = 27;
18
19 // Fractional position between top and bottom of button where the
20 // gradient starts.
21 const SkScalar kGradientStartLocation = SkFloatToScalar(0.38f);
22 const SkColor kNormalBackgroundTopColor = SkColorSetRGB(0xf0, 0xf0, 0xf0);
23 const SkColor kNormalBackgroundBottomColor = SkColorSetRGB(0xe0, 0xe0, 0xe0);
24 const SkColor kHotBackgroundTopColor = SkColorSetRGB(0xf4, 0xf4, 0xf4);
25 const SkColor kHotBackgroundBottomColor = SkColorSetRGB(0xe4, 0xe4, 0xe4);
26 const SkColor kPushedBackgroundTopColor = SkColorSetRGB(0xeb, 0xeb, 0xeb);
27 const SkColor kPushedBackgroundBottomColor = SkColorSetRGB(0xdb, 0xdb, 0xdb);
28 const SkColor kDisabledBackgroundTopColor = SkColorSetRGB(0xed, 0xed, 0xed);
29 const SkColor kDisabledBackgroundBottomColor = SkColorSetRGB(0xde, 0xde, 0xde);
30
31 const SkColor kEnabledTextColor = SkColorSetRGB(0x33, 0x33, 0x33);
32 const SkColor kDisabledTextColor = SkColorSetRGB(0xaa, 0xaa, 0xaa);
33 const SkColor kHoverTextColor = SkColorSetRGB(0x0, 0x0, 0x0);
34
35 const SkColor kTextShadowColor = SkColorSetRGB(0xf0, 0xf0, 0xf0);
36 const int kTextShadowOffsetX = 0;
37 const int kTextShadowOffsetY = 1;
38
39 const int kBorderWidth = 1;
40 const int kBorderRadius = 2;
41 const SkColor kBorderNormalColor = SkColorSetARGB(0x3f, 0x0, 0x0, 0x0);
42 const SkColor kBorderActiveColor = SkColorSetARGB(0x4b, 0x0, 0x0, 0x0);
43 const SkColor kBorderDisabledColor = SkColorSetARGB(0x1d, 0x0, 0x0, 0x0);
44
45 const int kFocusRingWidth = 2;
46 const int kFocusRingRadius = 2;
47 const SkColor kFocusRingColor = SkColorSetARGB(0x7f, 0xe5, 0x97, 0x00);
48
49 // Returns the uniform inset of the button from its local bounds.
50 int GetButtonInset() {
51 return std::max(kBorderWidth, kFocusRingWidth);
52 }
53
54 class ChromeStyleTextButtonBackground : public Background {
55 public:
56 ChromeStyleTextButtonBackground() {
57 }
58
59 virtual ~ChromeStyleTextButtonBackground() {
60 }
61
62 // Overriden from Background
63 virtual void Paint(gfx::Canvas* canvas, View* view) const {
64 if (painter_.get())
65 {
66 gfx::Rect bounds = view->GetLocalBounds();
67 // Inset to the actual button region.
68 int inset = GetButtonInset();
69 bounds.Inset(inset, inset, inset, inset);
70 Painter::PaintPainterAt(canvas, painter_.get(), bounds);
71 }
72 }
73
74 void SetColors(SkColor top, SkColor bottom) {
75 static const int count = 3;
76 SkColor colors[count] = { top, top, bottom };
77 SkScalar pos[count] = {
78 SkFloatToScalar(0.0f), kGradientStartLocation, SkFloatToScalar(1.0f) };
79
80 painter_.reset(
81 Painter::CreateVerticalMultiColorGradient(colors, pos, count));
82 SetNativeControlColor(
83 color_utils::AlphaBlend(colors[0], colors[count - 1], 128));
84 }
85
86 private:
87 scoped_ptr<Painter> painter_;
88
89 DISALLOW_COPY_AND_ASSIGN(ChromeStyleTextButtonBackground);
90 };
91
92 class ChromeStyleTextButtonBorderPainter : public views::Painter {
93 public:
94 ChromeStyleTextButtonBorderPainter()
95 // This value should be updated prior to rendering; it's set to a
96 // well-defined value here defensively.
97 : color_(SkColorSetRGB(0x0, 0x0, 0x0)) {
98 }
99
100 // Overriden from Painter
101 virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) {
102 SkPaint paint;
103 paint.setStyle(SkPaint::kStroke_Style);
104 paint.setColor(color_);
105 paint.setStrokeWidth(kBorderWidth);
106
107 // Inset by 1/2 pixel to align the stroke with pixel centers.
108 SkScalar inset = SkFloatToScalar(0.5f);
109 SkRect rect = SkRect::MakeLTRB(inset, inset,
110 SkIntToScalar(size.width()) - inset,
111 SkIntToScalar(size.height()) - inset);
112
113 canvas->sk_canvas()->drawRoundRect(
114 rect, kBorderRadius, kBorderRadius, paint);
115 }
116
117 void set_color(SkColor color) {
118 color_ = color;
119 }
120
121 private:
122 SkColor color_;
123
124 DISALLOW_COPY_AND_ASSIGN(ChromeStyleTextButtonBorderPainter);
125 };
126
127
128 class ChromeStyleTextButtonBorder : public views::Border {
129 public:
130 ChromeStyleTextButtonBorder()
131 : painter_(new ChromeStyleTextButtonBorderPainter) {
132 }
133
134 // Overriden from Border
135 virtual void Paint(const View& view, gfx::Canvas* canvas) const {
136 gfx::Rect bounds = view.GetLocalBounds();
137 int border_inset = GetButtonInset() - kBorderWidth;
138 bounds.Inset(border_inset, border_inset, border_inset, border_inset);
139 Painter::PaintPainterAt(canvas, painter_, bounds);
140 }
141 virtual void GetInsets(gfx::Insets* insets) const {
142 DCHECK(insets);
143 int inset = GetButtonInset();
144 insets->Set(inset, inset, inset, inset);
145 }
146
147 void SetColor(SkColor color) {
148 painter_->set_color(color);
149 }
150
151 private:
152 ChromeStyleTextButtonBorderPainter* painter_;
153
154 DISALLOW_COPY_AND_ASSIGN(ChromeStyleTextButtonBorder);
155 };
156
157 class ChromeStyleFocusBorder : public views::FocusBorder {
158 public:
159 ChromeStyleFocusBorder() {}
160
161 // Overriden from Border
162 virtual void Paint(const View& view, gfx::Canvas* canvas) const {
163 gfx::Rect rect(view.GetLocalBounds());
164 SkScalar inset = SkFloatToScalar(GetButtonInset() - kFocusRingWidth / 2.0f);
165 rect.Inset(inset, inset);
166 SkPaint paint;
167 paint.setStyle(SkPaint::kStroke_Style);
168 paint.setStrokeWidth(SkIntToScalar(kFocusRingWidth));
169 paint.setColor(kFocusRingColor);
170 canvas->DrawRoundRect(rect, SkIntToScalar(kFocusRingRadius), paint);
171 }
172
173 private:
174 DISALLOW_COPY_AND_ASSIGN(ChromeStyleFocusBorder);
175 };
176
177 class ChromeStyleStateChangedUpdater
178 : public CustomButtonStateChangedDelegate {
179 public:
180 // The background and border may be NULL.
181 ChromeStyleStateChangedUpdater(TextButton* button,
182 ChromeStyleTextButtonBackground* background,
183 ChromeStyleTextButtonBorder* border)
184 : button_(button),
185 background_(background),
186 border_(border),
187 prior_state_(button->state()) {
188 SetBackgroundForState(button->state());
189 SetShadowForState(button->state());
190 SetBorderColorForState(button->state());
191 }
192
193 virtual void StateChanged(CustomButton::ButtonState state) {
194 SetBackgroundForState(state);
195
196 // Update text shadow when transitioning to/from pushed state.
197 if (state == CustomButton::BS_PUSHED ||
198 prior_state_ == CustomButton::BS_PUSHED) {
199 SetShadowForState(state);
200 }
201
202 // Update border color. We need to change it in all cases except hot
203 // followed by pushed.
204 if (!(state == CustomButton::BS_PUSHED &&
205 prior_state_ == CustomButton::BS_HOT)) {
206 SetBorderColorForState(state);
207 }
208
209 prior_state_ = state;
210 }
211
212 private:
213 void SetBackgroundForState(CustomButton::ButtonState state) {
214 if (!background_)
215 return;
216
217 SkColor top;
218 SkColor bottom;
219
220 switch (state) {
221 case CustomButton::BS_NORMAL:
222 top = kNormalBackgroundTopColor;
223 bottom = kNormalBackgroundBottomColor;
224 break;
225
226 case CustomButton::BS_HOT:
227 top = kHotBackgroundTopColor;
228 bottom = kHotBackgroundBottomColor;
229 break;
230
231 case CustomButton::BS_PUSHED:
232 top = kPushedBackgroundTopColor;
233 bottom = kPushedBackgroundBottomColor;
234 break;
235
236 case CustomButton::BS_DISABLED:
237 top = kDisabledBackgroundTopColor;
238 bottom = kDisabledBackgroundBottomColor;
239 break;
240
241 default:
242 NOTREACHED();
243 return;
244 break;
245 }
246
247 background_->SetColors(top, bottom);
248 }
249
250 void SetShadowForState(CustomButton::ButtonState state) {
251 if (state == CustomButton::BS_PUSHED) {
252 // Turn off text shadow.
253 button_->ClearEmbellishing();
254 } else {
255 button_->SetTextShadowColors(kTextShadowColor, kTextShadowColor);
256 button_->SetTextShadowOffset(kTextShadowOffsetX, kTextShadowOffsetY);
257 }
258 }
259
260 void SetBorderColorForState(CustomButton::ButtonState state) {
261 if (!border_)
262 return;
263
264 SkColor border_color;
265
266 switch (state) {
267 case CustomButton::BS_NORMAL:
268 border_color = kBorderNormalColor;
269 break;
270
271 case CustomButton::BS_HOT:
272 case CustomButton::BS_PUSHED:
273 border_color = kBorderActiveColor;
274 break;
275
276 case CustomButton::BS_DISABLED:
277 border_color = kBorderDisabledColor;
278 break;
279
280 default:
281 NOTREACHED();
282 return;
283 break;
284 }
285
286 border_->SetColor(border_color);
287 }
288
289 // Weak pointer to the associated button.
290 TextButton* button_;
291
292 // Weak pointers to background and border owned by the CustomButton.
293 ChromeStyleTextButtonBackground* background_;
294 ChromeStyleTextButtonBorder* border_;
295
296 CustomButton::ButtonState prior_state_;
297
298 DISALLOW_COPY_AND_ASSIGN(ChromeStyleStateChangedUpdater);
299 };
300 } // namespace
301
302
303 void ApplyChromeStyle(TextButton* button) {
304 button->set_focusable(true);
305 button->set_request_focus_on_press(false);
306
307 button->set_alignment(TextButton::ALIGN_CENTER);
308 button->set_min_width(kMinWidth);
309 button->set_min_height(kMinHeight);
310
311 button->SetEnabledColor(kEnabledTextColor);
312 button->SetDisabledColor(kDisabledTextColor);
313 button->SetHoverColor(kHoverTextColor);
314
315 ChromeStyleTextButtonBackground* background =
316 new ChromeStyleTextButtonBackground;
317 button->set_background(background);
318
319 ChromeStyleTextButtonBorder* border = new ChromeStyleTextButtonBorder;
320 button->set_border(border);
321
322 button->set_focus_border(new ChromeStyleFocusBorder);
323
324 ChromeStyleStateChangedUpdater* state_changed_updater =
325 new ChromeStyleStateChangedUpdater(button, background, border);
326
327 button->set_state_changed_delegate(state_changed_updater);
328 }
329
330 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698