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

Side by Side Diff: base/gfx/native_theme.cc

Issue 42451: Chromium side of trackbar drawing. This is needed to support <input type="ra... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 9 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
« no previous file with comments | « base/gfx/native_theme.h ('k') | webkit/glue/webthemeengine_impl_win.h » ('j') | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "base/gfx/native_theme.h" 5 #include "base/gfx/native_theme.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <uxtheme.h> 8 #include <uxtheme.h>
9 #include <vsstyle.h> 9 #include <vsstyle.h>
10 #include <vssym32.h> 10 #include <vssym32.h>
11 11
12 #include "base/gfx/gdi_util.h" 12 #include "base/gfx/gdi_util.h"
13 #include "base/gfx/rect.h" 13 #include "base/gfx/rect.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/scoped_handle.h" 15 #include "base/scoped_handle.h"
16 #include "skia/ext/platform_canvas.h" 16 #include "skia/ext/platform_canvas.h"
17 #include "skia/ext/skia_utils_win.h" 17 #include "skia/ext/skia_utils_win.h"
18 #include "skia/include/SkShader.h" 18 #include "skia/include/SkShader.h"
19 19
20 namespace {
21
22 void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) {
23 // Create a 2x2 checkerboard pattern using the 3D face and highlight colors.
24 SkColor face = skia::COLORREFToSkColor(GetSysColor(COLOR_3DFACE));
25 SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT));
26 SkColor buffer[] = { face, highlight, highlight, face };
27 // Confusing bit: we first create a temporary bitmap with our desired pattern,
28 // then copy it to another bitmap. The temporary bitmap doesn't take
29 // ownership of the pixel data, and so will point to garbage when this
30 // function returns. The copy will copy the pixel data into a place owned by
31 // the bitmap, which is in turn owned by the shader, etc., so it will live
32 // until we're done using it.
33 SkBitmap temp_bitmap;
34 temp_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
35 temp_bitmap.setPixels(buffer);
36 SkBitmap bitmap;
37 temp_bitmap.copyTo(&bitmap, temp_bitmap.config());
38 SkShader* shader = SkShader::CreateBitmapShader(bitmap,
39 SkShader::kRepeat_TileMode,
40 SkShader::kRepeat_TileMode);
41
42 // Align the pattern with the upper corner of |align_rect|.
43 SkMatrix matrix;
44 matrix.setTranslate(SkIntToScalar(align_rect.left),
45 SkIntToScalar(align_rect.top));
46 shader->setLocalMatrix(matrix);
47 paint->setShader(shader)->safeUnref();
48 }
49
50 } // namespace
51
20 namespace gfx { 52 namespace gfx {
21 53
22 /* static */ 54 /* static */
23 const NativeTheme* NativeTheme::instance() { 55 const NativeTheme* NativeTheme::instance() {
24 // The global NativeTheme instance. 56 // The global NativeTheme instance.
25 static const NativeTheme s_native_theme; 57 static const NativeTheme s_native_theme;
26 return &s_native_theme; 58 return &s_native_theme;
27 } 59 }
28 60
29 NativeTheme::NativeTheme() 61 NativeTheme::NativeTheme()
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (handle && draw_theme_) 335 if (handle && draw_theme_)
304 return draw_theme_(handle, hdc, part_id, state_id, target_rect, NULL); 336 return draw_theme_(handle, hdc, part_id, state_id, target_rect, NULL);
305 337
306 // Draw it manually. 338 // Draw it manually.
307 const DWORD colorScrollbar = GetSysColor(COLOR_SCROLLBAR); 339 const DWORD colorScrollbar = GetSysColor(COLOR_SCROLLBAR);
308 const DWORD color3DFace = GetSysColor(COLOR_3DFACE); 340 const DWORD color3DFace = GetSysColor(COLOR_3DFACE);
309 if ((colorScrollbar != color3DFace) && 341 if ((colorScrollbar != color3DFace) &&
310 (colorScrollbar != GetSysColor(COLOR_WINDOW))) { 342 (colorScrollbar != GetSysColor(COLOR_WINDOW))) {
311 FillRect(hdc, target_rect, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); 343 FillRect(hdc, target_rect, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1));
312 } else { 344 } else {
313 // Create a 2x2 checkerboard pattern using the 3D face and highlight
314 // colors.
315 SkColor face = skia::COLORREFToSkColor(color3DFace);
316 SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT));
317 SkColor buffer[] = { face, highlight, highlight, face };
318 SkBitmap bitmap;
319 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
320 bitmap.setPixels(buffer);
321 SkShader* shader = SkShader::CreateBitmapShader(bitmap,
322 SkShader::kRepeat_TileMode,
323 SkShader::kRepeat_TileMode);
324
325 // Draw that pattern into the target rect, setting the origin to the top
326 // left corner of the scrollbar track (so the checked rect below the thumb
327 // aligns properly with the portion above the thumb).
328 SkMatrix matrix;
329 matrix.setTranslate(SkIntToScalar(align_rect->left),
330 SkIntToScalar(align_rect->top));
331 shader->setLocalMatrix(matrix);
332 SkPaint paint; 345 SkPaint paint;
333 paint.setShader(shader)->unref(); 346 SetCheckerboardShader(&paint, *align_rect);
334 canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint); 347 canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint);
335 } 348 }
336 if (classic_state & DFCS_PUSHED) 349 if (classic_state & DFCS_PUSHED)
337 InvertRect(hdc, target_rect); 350 InvertRect(hdc, target_rect);
338 return S_OK; 351 return S_OK;
339 } 352 }
340 353
341 HRESULT NativeTheme::PaintScrollbarThumb(HDC hdc, 354 HRESULT NativeTheme::PaintScrollbarThumb(HDC hdc,
342 int part_id, 355 int part_id,
343 int state_id, 356 int state_id,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 HRESULT NativeTheme::PaintTabPanelBackground(HDC hdc, RECT* rect) const { 389 HRESULT NativeTheme::PaintTabPanelBackground(HDC hdc, RECT* rect) const {
377 HANDLE handle = GetThemeHandle(TAB); 390 HANDLE handle = GetThemeHandle(TAB);
378 if (handle && draw_theme_) 391 if (handle && draw_theme_)
379 return draw_theme_(handle, hdc, TABP_BODY, 0, rect, NULL); 392 return draw_theme_(handle, hdc, TABP_BODY, 0, rect, NULL);
380 393
381 // Classic just renders a flat color background. 394 // Classic just renders a flat color background.
382 FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1)); 395 FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1));
383 return S_OK; 396 return S_OK;
384 } 397 }
385 398
399 HRESULT NativeTheme::PaintTrackbar(HDC hdc,
400 int part_id,
401 int state_id,
402 int classic_state,
403 RECT* rect,
404 skia::PlatformCanvasWin* canvas) const {
405 // Make the channel be 4 px thick in the center of the supplied rect. (4 px
406 // matches what XP does in various menus; GetThemePartSize() doesn't seem to
407 // return good values here.)
408 RECT channel_rect = *rect;
409 const int channel_thickness = 4;
410 if (part_id == TKP_TRACK) {
411 channel_rect.top +=
412 ((channel_rect.bottom - channel_rect.top - channel_thickness) / 2);
413 channel_rect.bottom = channel_rect.top + channel_thickness;
414 } else if (part_id == TKP_TRACKVERT) {
415 channel_rect.left +=
416 ((channel_rect.right - channel_rect.left - channel_thickness) / 2);
417 channel_rect.right = channel_rect.left + channel_thickness;
418 } // else this isn't actually a channel, so |channel_rect| == |rect|.
419
420 HANDLE handle = GetThemeHandle(TRACKBAR);
421 if (handle && draw_theme_)
422 return draw_theme_(handle, hdc, part_id, state_id, &channel_rect, NULL);
423
424 // Classic mode, draw it manually.
425 if ((part_id == TKP_TRACK) || (part_id == TKP_TRACKVERT)) {
426 DrawEdge(hdc, &channel_rect, EDGE_SUNKEN, BF_RECT);
427 } else if (part_id == TKP_THUMBVERT) {
428 DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE);
429 } else {
430 // Split rect into top and bottom pieces.
431 RECT top_section = *rect;
432 RECT bottom_section = *rect;
433 top_section.bottom -= ((bottom_section.right - bottom_section.left) / 2);
434 bottom_section.top = top_section.bottom;
435 DrawEdge(hdc, &top_section, EDGE_RAISED,
436 BF_LEFT | BF_TOP | BF_RIGHT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
437
438 // Split triangular piece into two diagonals.
439 RECT& left_half = bottom_section;
440 RECT right_half = bottom_section;
441 right_half.left += ((bottom_section.right - bottom_section.left) / 2);
442 left_half.right = right_half.left;
443 DrawEdge(hdc, &left_half, EDGE_RAISED,
444 BF_DIAGONAL_ENDTOPLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
445 DrawEdge(hdc, &right_half, EDGE_RAISED,
446 BF_DIAGONAL_ENDBOTTOMLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
447
448 // If the button is pressed, draw hatching.
449 if (classic_state & DFCS_PUSHED) {
450 SkPaint paint;
451 SetCheckerboardShader(&paint, *rect);
452
453 // Fill all three pieces with the pattern.
454 canvas->drawIRect(skia::RECTToSkIRect(top_section), paint);
455
456 SkScalar left_triangle_top = SkIntToScalar(left_half.top);
457 SkScalar left_triangle_right = SkIntToScalar(left_half.right);
458 SkPath left_triangle;
459 left_triangle.moveTo(SkIntToScalar(left_half.left), left_triangle_top);
460 left_triangle.lineTo(left_triangle_right, left_triangle_top);
461 left_triangle.lineTo(left_triangle_right,
462 SkIntToScalar(left_half.bottom));
463 left_triangle.close();
464 canvas->drawPath(left_triangle, paint);
465
466 SkScalar right_triangle_left = SkIntToScalar(right_half.left);
467 SkScalar right_triangle_top = SkIntToScalar(right_half.top);
468 SkPath right_triangle;
469 right_triangle.moveTo(right_triangle_left, right_triangle_top);
470 right_triangle.lineTo(SkIntToScalar(right_half.right),
471 right_triangle_top);
472 right_triangle.lineTo(right_triangle_left,
473 SkIntToScalar(right_half.bottom));
474 right_triangle.close();
475 canvas->drawPath(right_triangle, paint);
476 }
477 }
478 return S_OK;
479 }
480
386 HRESULT NativeTheme::PaintTextField(HDC hdc, 481 HRESULT NativeTheme::PaintTextField(HDC hdc,
387 int part_id, 482 int part_id,
388 int state_id, 483 int state_id,
389 int classic_state, 484 int classic_state,
390 RECT* rect, 485 RECT* rect,
391 COLORREF color, 486 COLORREF color,
392 bool fill_content_area, 487 bool fill_content_area,
393 bool draw_edges) const { 488 bool draw_edges) const {
394 // TODO(ojan): http://b/1210017 Figure out how to give the ability to 489 // TODO(ojan): http://b/1210017 Figure out how to give the ability to
395 // exclude individual edges from being drawn. 490 // exclude individual edges from being drawn.
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 break; 687 break;
593 case STATUS: 688 case STATUS:
594 handle = open_theme_(NULL, L"Status"); 689 handle = open_theme_(NULL, L"Status");
595 break; 690 break;
596 case TAB: 691 case TAB:
597 handle = open_theme_(NULL, L"Tab"); 692 handle = open_theme_(NULL, L"Tab");
598 break; 693 break;
599 case TEXTFIELD: 694 case TEXTFIELD:
600 handle = open_theme_(NULL, L"Edit"); 695 handle = open_theme_(NULL, L"Edit");
601 break; 696 break;
697 case TRACKBAR:
698 handle = open_theme_(NULL, L"Trackbar");
699 break;
602 case WINDOW: 700 case WINDOW:
603 handle = open_theme_(NULL, L"Window"); 701 handle = open_theme_(NULL, L"Window");
604 break; 702 break;
605 default: 703 default:
606 NOTREACHED(); 704 NOTREACHED();
607 } 705 }
608 theme_handles_[theme_name] = handle; 706 theme_handles_[theme_name] = handle;
609 return handle; 707 return handle;
610 } 708 }
611 709
612 } // namespace gfx 710 } // namespace gfx
OLDNEW
« no previous file with comments | « base/gfx/native_theme.h ('k') | webkit/glue/webthemeengine_impl_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698