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 "ui/native_theme/native_theme_aura.h" | 5 #include "ui/native_theme/native_theme_aura.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "ui/base/layout.h" | 12 #include "ui/base/layout.h" |
13 #include "ui/base/nine_image_painter_factory.h" | |
14 #include "ui/base/resource/material_design/material_design_controller.h" | 13 #include "ui/base/resource/material_design/material_design_controller.h" |
14 #include "ui/gfx/animation/tween.h" | |
15 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
16 #include "ui/gfx/color_palette.h" | |
16 #include "ui/gfx/geometry/rect.h" | 17 #include "ui/gfx/geometry/rect.h" |
17 #include "ui/gfx/geometry/size.h" | 18 #include "ui/gfx/geometry/size.h" |
18 #include "ui/gfx/image/image_skia.h" | 19 #include "ui/gfx/image/image_skia.h" |
19 #include "ui/gfx/nine_image_painter.h" | |
20 #include "ui/gfx/path.h" | 20 #include "ui/gfx/path.h" |
21 #include "ui/gfx/skbitmap_operations.h" | |
22 #include "ui/gfx/skia_util.h" | 21 #include "ui/gfx/skia_util.h" |
23 #include "ui/native_theme/common_theme.h" | 22 #include "ui/native_theme/common_theme.h" |
24 #include "ui/native_theme/native_theme_switches.h" | 23 #include "ui/native_theme/native_theme_switches.h" |
25 #include "ui/resources/grit/ui_resources.h" | |
26 | |
27 using gfx::NineImagePainter; | |
28 | |
29 #define EMPTY_IMAGE_GRID { 0, 0, 0, 0, 0, 0, 0, 0, 0 } | |
30 | 24 |
31 namespace ui { | 25 namespace ui { |
32 | 26 |
33 namespace { | 27 namespace { |
34 | 28 |
35 const int kScrollbarThumbImages[NativeTheme::kNumStates][9] = { | 29 SkAlpha ThumbAlphaForState(NativeTheme::State state) { |
36 EMPTY_IMAGE_GRID, | 30 bool overlay = IsOverlayScrollbarEnabled(); |
37 IMAGE_GRID(IDR_SCROLLBAR_THUMB_BASE_HOVER), | 31 switch (state) { |
38 IMAGE_GRID(IDR_SCROLLBAR_THUMB_BASE_NORMAL), | 32 case NativeTheme::kDisabled: |
39 IMAGE_GRID(IDR_SCROLLBAR_THUMB_BASE_PRESSED) | 33 return 0x00; |
40 }; | 34 case NativeTheme::kHovered: |
35 return overlay ? 0xB2 : 0x4D; | |
36 case NativeTheme::kNormal: | |
37 return overlay ? 0x8C : 0x33; | |
38 case NativeTheme::kPressed: | |
39 return overlay ? 0xB2 : 0x80; | |
40 case NativeTheme::kNumStates: | |
41 break; | |
42 } | |
41 | 43 |
42 const int kScrollbarArrowButtonImages[NativeTheme::kNumStates][9] = { | 44 NOTREACHED(); |
43 EMPTY_IMAGE_GRID, | 45 return 0xFF; |
44 IMAGE_GRID(IDR_SCROLLBAR_ARROW_BUTTON_BASE_HOVER), | 46 } |
45 IMAGE_GRID(IDR_SCROLLBAR_ARROW_BUTTON_BASE_NORMAL), | |
46 IMAGE_GRID(IDR_SCROLLBAR_ARROW_BUTTON_BASE_PRESSED) | |
47 }; | |
48 | 47 |
49 const uint8_t kScrollbarOverlayThumbFillAlphas[NativeTheme::kNumStates] = { | 48 SkAlpha ThumbStrokeAlphaForState(NativeTheme::State state) { |
50 0, // Does not matter, will not paint for disabled state. | 49 DCHECK(IsOverlayScrollbarEnabled()); |
51 178, // Hover state, opacity 70%, alpha would be 0.7 * 255. | 50 switch (state) { |
52 140, // Normal state, opacity 55%, alpha would be 0.55 * 255. | 51 case NativeTheme::kDisabled: |
53 178 // Pressed state, opacity 70%, alpha would be 0.7 * 255. | 52 return 0x00; |
54 }; | 53 case NativeTheme::kHovered: |
54 case NativeTheme::kPressed: | |
55 return 0x33; | |
56 case NativeTheme::kNormal: | |
57 return 0x26; | |
58 case NativeTheme::kNumStates: | |
59 break; | |
60 } | |
55 | 61 |
56 const uint8_t kScrollbarOverlayThumbStrokeAlphas[NativeTheme::kNumStates] = { | 62 NOTREACHED(); |
57 0, // Does not matter, will not paint for disabled state. | 63 return 0xFF; |
58 51, // Hover state, opacity 20%, alpha would be 0.2 * 255. | 64 } |
59 38, // Normal state, opacity 15%, alpha would be 0.15 * 255. | |
60 51 // Pressed state, opacity 20%, alpha would be 0.2 * 255. | |
61 }; | |
62 | 65 |
63 const int kScrollbarOverlayThumbStrokeImages[9] = | 66 const SkColor kTrackColor = SkColorSetRGB(0xF1, 0xF1, 0xF1); |
64 IMAGE_GRID_NO_CENTER(IDR_SCROLLBAR_OVERLAY_THUMB_STROKE); | |
65 | |
66 const int kScrollbarOverlayThumbFillImages[9] = | |
67 IMAGE_GRID(IDR_SCROLLBAR_OVERLAY_THUMB_FILL); | |
68 | |
69 const int kScrollbarTrackImages[9] = IMAGE_GRID(IDR_SCROLLBAR_BASE); | |
70 | 67 |
71 } // namespace | 68 } // namespace |
72 | 69 |
73 #if !defined(OS_WIN) | 70 #if !defined(OS_WIN) |
74 // static | 71 // static |
75 NativeTheme* NativeTheme::GetInstanceForWeb() { | 72 NativeTheme* NativeTheme::GetInstanceForWeb() { |
76 return NativeThemeAura::instance(); | 73 return NativeThemeAura::instance(); |
77 } | 74 } |
78 | 75 |
79 // static | 76 // static |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 } | 127 } |
131 | 128 |
132 void NativeThemeAura::PaintMenuItemBackground( | 129 void NativeThemeAura::PaintMenuItemBackground( |
133 SkCanvas* canvas, | 130 SkCanvas* canvas, |
134 State state, | 131 State state, |
135 const gfx::Rect& rect, | 132 const gfx::Rect& rect, |
136 const MenuListExtraParams& menu_list) const { | 133 const MenuListExtraParams& menu_list) const { |
137 CommonThemePaintMenuItemBackground(canvas, state, rect); | 134 CommonThemePaintMenuItemBackground(canvas, state, rect); |
138 } | 135 } |
139 | 136 |
140 void NativeThemeAura::PaintArrowButton( | 137 void NativeThemeAura::PaintArrowButton(SkCanvas* canvas, |
141 SkCanvas* gc, | 138 const gfx::Rect& rect, |
142 const gfx::Rect& rect, | 139 Part direction, |
143 Part direction, | 140 State state) const { |
144 State state) const { | 141 SkColor bg_color = kTrackColor; |
145 if (direction == kInnerSpinButton) { | |
146 NativeThemeBase::PaintArrowButton(gc, rect, direction, state); | |
147 return; | |
148 } | |
149 PaintPainter(GetOrCreatePainter( | |
150 kScrollbarArrowButtonImages, state, | |
151 scrollbar_arrow_button_painters_), | |
152 gc, rect); | |
153 | |
154 // Aura-win uses slightly different arrow colors. | 142 // Aura-win uses slightly different arrow colors. |
155 SkColor arrow_color = GetArrowColor(state); | 143 SkColor arrow_color = gfx::kPlaceholderColor; |
156 switch (state) { | 144 switch (state) { |
145 case kDisabled: | |
146 arrow_color = GetArrowColor(state); | |
147 break; | |
157 case kHovered: | 148 case kHovered: |
149 bg_color = SkColorSetRGB(0xD2, 0xD2, 0xD2); | |
150 // Fall through. | |
158 case kNormal: | 151 case kNormal: |
159 arrow_color = SkColorSetRGB(0x50, 0x50, 0x50); | 152 arrow_color = SkColorSetRGB(0x50, 0x50, 0x50); |
160 break; | 153 break; |
161 case kPressed: | 154 case kPressed: |
155 bg_color = SkColorSetRGB(0x78, 0x78, 0x78); | |
162 arrow_color = SK_ColorWHITE; | 156 arrow_color = SK_ColorWHITE; |
163 default: | 157 break; |
158 case kNumStates: | |
164 break; | 159 break; |
sadrul
2016/01/12 21:57:45
I was going to suggest a NOTREACHED() here, but I
| |
165 } | 160 } |
166 PaintArrow(gc, rect, direction, arrow_color); | 161 DCHECK_NE(arrow_color, gfx::kPlaceholderColor); |
162 | |
163 SkPaint paint; | |
164 paint.setColor(bg_color); | |
165 canvas->drawIRect(gfx::RectToSkIRect(rect), paint); | |
166 | |
167 PaintArrow(canvas, rect, direction, arrow_color); | |
167 } | 168 } |
168 | 169 |
169 void NativeThemeAura::PaintScrollbarTrack( | 170 void NativeThemeAura::PaintScrollbarTrack( |
170 SkCanvas* sk_canvas, | 171 SkCanvas* canvas, |
171 Part part, | 172 Part part, |
172 State state, | 173 State state, |
173 const ScrollbarTrackExtraParams& extra_params, | 174 const ScrollbarTrackExtraParams& extra_params, |
174 const gfx::Rect& rect) const { | 175 const gfx::Rect& rect) const { |
175 // Overlay Scrollbar should never paint a scrollbar track. | 176 // Overlay Scrollbar should never paint a scrollbar track. |
176 DCHECK(!IsOverlayScrollbarEnabled()); | 177 DCHECK(!IsOverlayScrollbarEnabled()); |
177 if (!scrollbar_track_painter_) | 178 SkPaint paint; |
178 scrollbar_track_painter_ = CreateNineImagePainter(kScrollbarTrackImages); | 179 paint.setColor(kTrackColor); |
179 PaintPainter(scrollbar_track_painter_.get(), sk_canvas, rect); | 180 canvas->drawIRect(gfx::RectToSkIRect(rect), paint); |
180 } | 181 } |
181 | 182 |
182 void NativeThemeAura::PaintScrollbarThumb(SkCanvas* sk_canvas, | 183 void NativeThemeAura::PaintScrollbarThumb(SkCanvas* canvas, |
183 Part part, | 184 Part part, |
184 State state, | 185 State state, |
185 const gfx::Rect& rect) const { | 186 const gfx::Rect& rect) const { |
186 gfx::Rect thumb_rect(rect); | 187 // Do not paint if state is disabled. |
187 if (IsOverlayScrollbarEnabled()) { | 188 if (state == kDisabled) |
188 // Overlay scrollbar has no track, just paint thumb directly. | 189 return; |
189 // Do not paint if state is disabled. | |
190 if (state == kDisabled) | |
191 return; | |
192 | 190 |
193 if (!scrollbar_overlay_thumb_painter_) { | 191 PaintScrollbarThumbStateTransition(canvas, part, state, state, 1.0, rect); |
194 scrollbar_overlay_thumb_painter_ = | |
195 CreateDualPainter(kScrollbarOverlayThumbFillImages, | |
196 kScrollbarOverlayThumbFillAlphas, | |
197 kScrollbarOverlayThumbStrokeImages, | |
198 kScrollbarOverlayThumbStrokeAlphas); | |
199 } | |
200 | |
201 PaintDualPainter( | |
202 scrollbar_overlay_thumb_painter_.get(), sk_canvas, thumb_rect, state); | |
203 return; | |
204 } | |
205 // If there are no scrollbuttons then provide some padding so that thumb | |
206 // doesn't touch the top of the track. | |
207 const int extra_padding = (scrollbar_button_length() == 0) ? 2 : 0; | |
208 if (part == NativeTheme::kScrollbarVerticalThumb) | |
209 thumb_rect.Inset(2, extra_padding, 2, extra_padding); | |
210 else | |
211 thumb_rect.Inset(extra_padding, 2, extra_padding, 2); | |
212 PaintPainter(GetOrCreatePainter( | |
213 kScrollbarThumbImages, state, scrollbar_thumb_painters_), | |
214 sk_canvas, | |
215 thumb_rect); | |
216 } | 192 } |
217 | 193 |
218 void NativeThemeAura::PaintScrollbarThumbStateTransition( | 194 void NativeThemeAura::PaintScrollbarThumbStateTransition( |
219 SkCanvas* canvas, | 195 SkCanvas* canvas, |
220 State startState, | 196 Part part, |
221 State endState, | 197 State start_state, |
198 State end_state, | |
222 double progress, | 199 double progress, |
223 const gfx::Rect& rect) const { | 200 const gfx::Rect& rect) const { |
224 // Only Overlay scrollbars should have state transition animation. | 201 gfx::Rect thumb_rect(rect); |
225 DCHECK(IsOverlayScrollbarEnabled()); | 202 if (IsOverlayScrollbarEnabled()) { |
226 if (!scrollbar_overlay_thumb_painter_) { | 203 // In overlay mode, draw a stroke (border). |
227 scrollbar_overlay_thumb_painter_ = | 204 const int kStrokeWidth = 1; |
228 CreateDualPainter(kScrollbarOverlayThumbFillImages, | 205 SkAlpha stroke_alpha = gfx::Tween::IntValueBetween( |
229 kScrollbarOverlayThumbFillAlphas, | 206 progress, ThumbStrokeAlphaForState(start_state), |
230 kScrollbarOverlayThumbStrokeImages, | 207 ThumbStrokeAlphaForState(end_state)); |
231 kScrollbarOverlayThumbStrokeAlphas); | 208 SkPaint paint; |
209 paint.setColor(SkColorSetA(SK_ColorWHITE, stroke_alpha)); | |
210 paint.setStyle(SkPaint::kStroke_Style); | |
211 paint.setStrokeWidth(kStrokeWidth); | |
212 canvas->drawIRect(gfx::RectToSkIRect(thumb_rect), paint); | |
213 | |
214 thumb_rect.Inset(kStrokeWidth, kStrokeWidth, kStrokeWidth, kStrokeWidth); | |
215 } else { | |
216 // If there are no scrollbuttons then provide some padding so that the thumb | |
217 // doesn't touch the top of the track. | |
218 const int kThumbPadding = 2; | |
219 const int extra_padding = | |
220 (scrollbar_button_length() == 0) ? kThumbPadding : 0; | |
221 if (part == NativeTheme::kScrollbarVerticalThumb) | |
222 thumb_rect.Inset(kThumbPadding, extra_padding); | |
223 else | |
224 thumb_rect.Inset(extra_padding, kThumbPadding); | |
232 } | 225 } |
233 | 226 |
234 PaintDualPainterTransition(scrollbar_overlay_thumb_painter_.get(), | 227 SkPaint paint; |
235 canvas, | 228 SkAlpha alpha = gfx::Tween::IntValueBetween( |
236 rect, | 229 progress, ThumbAlphaForState(start_state), ThumbAlphaForState(end_state)); |
237 startState, | 230 paint.setColor(SkColorSetA(SK_ColorBLACK, alpha)); |
238 endState, | 231 canvas->drawIRect(gfx::RectToSkIRect(thumb_rect), paint); |
239 progress); | |
240 } | 232 } |
241 | 233 |
242 void NativeThemeAura::PaintScrollbarCorner(SkCanvas* canvas, | 234 void NativeThemeAura::PaintScrollbarCorner(SkCanvas* canvas, |
243 State state, | 235 State state, |
244 const gfx::Rect& rect) const { | 236 const gfx::Rect& rect) const { |
245 // Overlay Scrollbar should never paint a scrollbar corner. | 237 // Overlay Scrollbar should never paint a scrollbar corner. |
246 DCHECK(!IsOverlayScrollbarEnabled()); | 238 DCHECK(!IsOverlayScrollbarEnabled()); |
247 SkPaint paint; | 239 SkPaint paint; |
248 paint.setColor(SkColorSetRGB(0xF1, 0xF1, 0xF1)); | 240 paint.setColor(SkColorSetRGB(0xDC, 0xDC, 0xDC)); |
249 paint.setStyle(SkPaint::kFill_Style); | |
250 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
251 canvas->drawIRect(RectToSkIRect(rect), paint); | 241 canvas->drawIRect(RectToSkIRect(rect), paint); |
252 } | 242 } |
253 | 243 |
254 NineImagePainter* NativeThemeAura::GetOrCreatePainter( | |
255 const int images[kNumStates][9], | |
256 State state, | |
257 scoped_ptr<NineImagePainter> painters[kNumStates]) const { | |
258 if (painters[state]) | |
259 return painters[state].get(); | |
260 if (images[state][0] == 0) { | |
261 // Must always provide normal state images. | |
262 DCHECK_NE(kNormal, state); | |
263 return GetOrCreatePainter(images, kNormal, painters); | |
264 } | |
265 painters[state] = CreateNineImagePainter(images[state]); | |
266 return painters[state].get(); | |
267 } | |
268 | |
269 void NativeThemeAura::PaintPainter(NineImagePainter* painter, | |
270 SkCanvas* sk_canvas, | |
271 const gfx::Rect& rect) const { | |
272 DCHECK(painter); | |
273 scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas)); | |
274 painter->Paint(canvas.get(), rect); | |
275 } | |
276 | |
277 scoped_ptr<NativeThemeAura::DualPainter> NativeThemeAura::CreateDualPainter( | |
278 const int fill_image_ids[9], | |
279 const uint8_t fill_alphas[kNumStates], | |
280 const int stroke_image_ids[9], | |
281 const uint8_t stroke_alphas[kNumStates]) const { | |
282 scoped_ptr<NativeThemeAura::DualPainter> dual_painter( | |
283 new NativeThemeAura::DualPainter(CreateNineImagePainter(fill_image_ids), | |
284 fill_alphas, | |
285 CreateNineImagePainter(stroke_image_ids), | |
286 stroke_alphas)); | |
287 return dual_painter; | |
288 } | |
289 | |
290 void NativeThemeAura::PaintDualPainter( | |
291 NativeThemeAura::DualPainter* dual_painter, | |
292 SkCanvas* sk_canvas, | |
293 const gfx::Rect& rect, | |
294 State state) const { | |
295 DCHECK(dual_painter); | |
296 scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas)); | |
297 dual_painter->fill_painter->Paint( | |
298 canvas.get(), rect, dual_painter->fill_alphas[state]); | |
299 dual_painter->stroke_painter->Paint( | |
300 canvas.get(), rect, dual_painter->stroke_alphas[state]); | |
301 } | |
302 | |
303 void NativeThemeAura::PaintDualPainterTransition( | |
304 NativeThemeAura::DualPainter* dual_painter, | |
305 SkCanvas* sk_canvas, | |
306 const gfx::Rect& rect, | |
307 State startState, | |
308 State endState, | |
309 double progress) const { | |
310 DCHECK(dual_painter); | |
311 scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas)); | |
312 uint8_t fill_alpha = dual_painter->fill_alphas[startState] + | |
313 (dual_painter->fill_alphas[endState] - | |
314 dual_painter->fill_alphas[startState]) * | |
315 progress; | |
316 uint8_t stroke_alpha = dual_painter->stroke_alphas[startState] + | |
317 (dual_painter->stroke_alphas[endState] - | |
318 dual_painter->stroke_alphas[startState]) * | |
319 progress; | |
320 | |
321 dual_painter->fill_painter->Paint(canvas.get(), rect, fill_alpha); | |
322 dual_painter->stroke_painter->Paint(canvas.get(), rect, stroke_alpha); | |
323 } | |
324 | |
325 NativeThemeAura::DualPainter::DualPainter( | |
326 scoped_ptr<NineImagePainter> fill_painter, | |
327 const uint8_t fill_alphas[kNumStates], | |
328 scoped_ptr<NineImagePainter> stroke_painter, | |
329 const uint8_t stroke_alphas[kNumStates]) | |
330 : fill_painter(std::move(fill_painter)), | |
331 fill_alphas(fill_alphas), | |
332 stroke_painter(std::move(stroke_painter)), | |
333 stroke_alphas(stroke_alphas) {} | |
334 | |
335 NativeThemeAura::DualPainter::~DualPainter() {} | |
336 | |
337 } // namespace ui | 244 } // namespace ui |
OLD | NEW |