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_win.h" | 5 #include "ui/native_theme/native_theme_win.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> |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 gfx::Rect result(*rect); | 125 gfx::Rect result(*rect); |
126 result.Inset(size, size); | 126 result.Inset(size, size); |
127 return result.ToRECT(); | 127 return result.ToRECT(); |
128 } | 128 } |
129 | 129 |
130 } // namespace | 130 } // namespace |
131 | 131 |
132 namespace ui { | 132 namespace ui { |
133 | 133 |
134 bool NativeThemeWin::IsThemingActive() const { | 134 bool NativeThemeWin::IsThemingActive() const { |
135 if (is_theme_active_) | 135 return is_theme_active_ && is_theme_active_(); |
136 return !!is_theme_active_(); | |
137 return false; | |
138 } | 136 } |
139 | 137 |
140 bool NativeThemeWin::IsUsingHighContrastTheme() const { | 138 bool NativeThemeWin::IsUsingHighContrastTheme() const { |
141 if (is_using_high_contrast_valid_) | 139 if (is_using_high_contrast_valid_) |
142 return is_using_high_contrast_; | 140 return is_using_high_contrast_; |
143 HIGHCONTRAST result; | 141 HIGHCONTRAST result; |
144 result.cbSize = sizeof(HIGHCONTRAST); | 142 result.cbSize = sizeof(HIGHCONTRAST); |
145 is_using_high_contrast_ = | 143 is_using_high_contrast_ = |
146 SystemParametersInfo(SPI_GETHIGHCONTRAST, result.cbSize, &result, 0) && | 144 SystemParametersInfo(SPI_GETHIGHCONTRAST, result.cbSize, &result, 0) && |
147 (result.dwFlags & HCF_HIGHCONTRASTON) == HCF_HIGHCONTRASTON; | 145 (result.dwFlags & HCF_HIGHCONTRASTON) == HCF_HIGHCONTRASTON; |
148 is_using_high_contrast_valid_ = true; | 146 is_using_high_contrast_valid_ = true; |
149 return is_using_high_contrast_; | 147 return is_using_high_contrast_; |
150 } | 148 } |
151 | 149 |
152 HRESULT NativeThemeWin::GetThemeColor(ThemeName theme, | 150 HRESULT NativeThemeWin::GetThemeColor(ThemeName theme, |
153 int part_id, | 151 int part_id, |
154 int state_id, | 152 int state_id, |
155 int prop_id, | 153 int prop_id, |
156 SkColor* color) const { | 154 SkColor* color) const { |
157 HANDLE handle = GetThemeHandle(theme); | 155 HANDLE handle = GetThemeHandle(theme); |
158 if (handle && get_theme_color_) { | 156 if (!handle || !get_theme_color_) |
159 COLORREF color_ref; | 157 return E_NOTIMPL; |
160 if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) == | 158 COLORREF color_ref; |
161 S_OK) { | 159 if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) != S_OK) |
162 *color = skia::COLORREFToSkColor(color_ref); | 160 return E_NOTIMPL; |
163 return S_OK; | 161 *color = skia::COLORREFToSkColor(color_ref); |
164 } | 162 return S_OK; |
165 } | |
166 return E_NOTIMPL; | |
167 } | 163 } |
168 | 164 |
169 SkColor NativeThemeWin::GetThemeColorWithDefault(ThemeName theme, | 165 SkColor NativeThemeWin::GetThemeColorWithDefault(ThemeName theme, |
170 int part_id, | 166 int part_id, |
171 int state_id, | 167 int state_id, |
172 int prop_id, | 168 int prop_id, |
173 int default_sys_color) const { | 169 int default_sys_color) const { |
174 SkColor color; | 170 SkColor color; |
175 if (GetThemeColor(theme, part_id, state_id, prop_id, &color) != S_OK) | 171 return (GetThemeColor(theme, part_id, state_id, prop_id, &color) == S_OK) ? |
176 color = color_utils::GetSysSkColor(default_sys_color); | 172 color : color_utils::GetSysSkColor(default_sys_color); |
177 return color; | |
178 } | 173 } |
179 | 174 |
180 gfx::Size NativeThemeWin::GetThemeBorderSize(ThemeName theme) const { | 175 gfx::Size NativeThemeWin::GetThemeBorderSize(ThemeName theme) const { |
181 // For simplicity use the wildcard state==0, part==0, since it works | 176 // For simplicity use the wildcard state==0, part==0, since it works |
182 // for the cases we currently depend on. | 177 // for the cases we currently depend on. |
183 int border; | 178 int border; |
184 if (GetThemeInt(theme, 0, 0, TMT_BORDERSIZE, &border) == S_OK) | 179 return (GetThemeInt(theme, 0, 0, TMT_BORDERSIZE, &border) == S_OK) ? |
185 return gfx::Size(border, border); | 180 gfx::Size(border, border) : |
186 else | 181 gfx::Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); |
187 return gfx::Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); | |
188 } | 182 } |
189 | 183 |
190 void NativeThemeWin::DisableTheming() const { | 184 void NativeThemeWin::DisableTheming() const { |
191 if (!set_theme_properties_) | 185 if (set_theme_properties_) |
192 return; | 186 set_theme_properties_(0); |
193 set_theme_properties_(0); | |
194 } | 187 } |
195 | 188 |
196 void NativeThemeWin::CloseHandles() const { | 189 void NativeThemeWin::CloseHandles() const { |
197 if (!close_theme_) | 190 if (!close_theme_) |
198 return; | 191 return; |
199 | 192 |
200 for (int i = 0; i < LAST; ++i) { | 193 for (int i = 0; i < LAST; ++i) { |
201 if (theme_handles_[i]) { | 194 if (theme_handles_[i]) { |
202 close_theme_(theme_handles_[i]); | 195 close_theme_(theme_handles_[i]); |
203 theme_handles_[i] = NULL; | 196 theme_handles_[i] = NULL; |
204 } | 197 } |
205 } | 198 } |
206 } | 199 } |
207 | 200 |
208 bool NativeThemeWin::IsClassicTheme(ThemeName name) const { | 201 bool NativeThemeWin::IsClassicTheme(ThemeName name) const { |
209 if (!theme_dll_) | 202 return !theme_dll_ || !GetThemeHandle(name); |
210 return true; | |
211 | |
212 return !GetThemeHandle(name); | |
213 } | 203 } |
214 | 204 |
215 // static | 205 // static |
216 NativeThemeWin* NativeThemeWin::instance() { | 206 NativeThemeWin* NativeThemeWin::instance() { |
217 CR_DEFINE_STATIC_LOCAL(NativeThemeWin, s_native_theme, ()); | 207 CR_DEFINE_STATIC_LOCAL(NativeThemeWin, s_native_theme, ()); |
218 return &s_native_theme; | 208 return &s_native_theme; |
219 } | 209 } |
220 | 210 |
221 gfx::Size NativeThemeWin::GetPartSize(Part part, | 211 gfx::Size NativeThemeWin::GetPartSize(Part part, |
222 State state, | 212 State state, |
(...skipping 16 matching lines...) Expand all Loading... | |
239 int size = gfx::win::GetSystemMetricsInDIP(SM_CXVSCROLL); | 229 int size = gfx::win::GetSystemMetricsInDIP(SM_CXVSCROLL); |
240 if (size == 0) | 230 if (size == 0) |
241 size = 17; | 231 size = 17; |
242 return gfx::Size(size, size); | 232 return gfx::Size(size, size); |
243 } | 233 } |
244 } | 234 } |
245 | 235 |
246 int part_id = GetWindowsPart(part, state, extra); | 236 int part_id = GetWindowsPart(part, state, extra); |
247 int state_id = GetWindowsState(part, state, extra); | 237 int state_id = GetWindowsState(part, state, extra); |
248 | 238 |
239 base::win::ScopedGetDC screen_dc(NULL); | |
249 SIZE size; | 240 SIZE size; |
250 HDC hdc = GetDC(NULL); | 241 if (SUCCEEDED(GetThemePartSize(GetThemeName(part), screen_dc, part_id, |
251 HRESULT hr = GetThemePartSize(GetThemeName(part), hdc, part_id, state_id, | 242 state_id, NULL, TS_TRUE, &size))) |
252 NULL, TS_TRUE, &size); | 243 return gfx::Size(size.cx, size.cy); |
253 ReleaseDC(NULL, hdc); | |
254 | 244 |
255 if (FAILED(hr)) { | 245 // TODO(rogerta): For now, we need to support radio buttons and checkboxes |
256 // TODO(rogerta): For now, we need to support radio buttons and checkboxes | 246 // when theming is not enabled. Support for other parts can be added |
257 // when theming is not enabled. Support for other parts can be added | 247 // if/when needed. |
258 // if/when needed. | 248 return (part == kCheckbox || part == kRadio) ? |
259 switch (part) { | 249 gfx::Size(13, 13) : gfx::Size(); |
260 case kCheckbox: | |
261 case kRadio: | |
262 // TODO(rogerta): I was not able to find any API to get the default | |
263 // size of these controls, so determined these values empirically. | |
264 size.cx = 13; | |
265 size.cy = 13; | |
266 break; | |
267 default: | |
268 size.cx = 0; | |
269 size.cy = 0; | |
270 break; | |
271 } | |
272 } | |
273 | |
274 return gfx::Size(size.cx, size.cy); | |
275 } | 250 } |
276 | 251 |
277 void NativeThemeWin::Paint(SkCanvas* canvas, | 252 void NativeThemeWin::Paint(SkCanvas* canvas, |
278 Part part, | 253 Part part, |
279 State state, | 254 State state, |
280 const gfx::Rect& rect, | 255 const gfx::Rect& rect, |
281 const ExtraParams& extra) const { | 256 const ExtraParams& extra) const { |
282 if (rect.IsEmpty()) | 257 if (rect.IsEmpty()) |
283 return; | 258 return; |
284 | 259 |
(...skipping 23 matching lines...) Expand all Loading... | |
308 // Scrollbar components on Windows Classic theme (on all Windows versions) | 283 // Scrollbar components on Windows Classic theme (on all Windows versions) |
309 // have particularly problematic alpha values, so always draw them | 284 // have particularly problematic alpha values, so always draw them |
310 // indirectly. In addition, scrollbar thumbs and grippers for the Windows XP | 285 // indirectly. In addition, scrollbar thumbs and grippers for the Windows XP |
311 // theme (available only on Windows XP) also need their alpha values | 286 // theme (available only on Windows XP) also need their alpha values |
312 // fixed. | 287 // fixed. |
313 switch (part) { | 288 switch (part) { |
314 case kScrollbarDownArrow: | 289 case kScrollbarDownArrow: |
315 case kScrollbarUpArrow: | 290 case kScrollbarUpArrow: |
316 case kScrollbarLeftArrow: | 291 case kScrollbarLeftArrow: |
317 case kScrollbarRightArrow: | 292 case kScrollbarRightArrow: |
318 if (!GetThemeHandle(SCROLLBAR)) | 293 needs_paint_indirect = !GetThemeHandle(SCROLLBAR); |
319 needs_paint_indirect = true; | |
320 break; | 294 break; |
321 case kScrollbarHorizontalThumb: | 295 case kScrollbarHorizontalThumb: |
322 case kScrollbarVerticalThumb: | 296 case kScrollbarVerticalThumb: |
323 case kScrollbarHorizontalGripper: | 297 case kScrollbarHorizontalGripper: |
324 case kScrollbarVerticalGripper: | 298 case kScrollbarVerticalGripper: |
325 if (!GetThemeHandle(SCROLLBAR) || | 299 needs_paint_indirect = !GetThemeHandle(SCROLLBAR) || |
326 base::win::GetVersion() == base::win::VERSION_XP) | 300 base::win::GetVersion() == base::win::VERSION_XP; |
327 needs_paint_indirect = true; | |
328 break; | |
329 default: | |
330 break; | 301 break; |
331 } | 302 } |
332 } | 303 } |
333 | 304 |
334 if (needs_paint_indirect) | 305 if (needs_paint_indirect) |
335 PaintIndirect(canvas, part, state, rect, extra); | 306 PaintIndirect(canvas, part, state, rect, extra); |
336 else | 307 else |
337 PaintDirect(canvas, part, state, rect, extra); | 308 PaintDirect(canvas, part, state, rect, extra); |
338 } | 309 } |
339 | 310 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
406 Part part, | 377 Part part, |
407 State state, | 378 State state, |
408 const gfx::Rect& rect, | 379 const gfx::Rect& rect, |
409 const ExtraParams& extra) const { | 380 const ExtraParams& extra) const { |
410 skia::ScopedPlatformPaint scoped_platform_paint(canvas); | 381 skia::ScopedPlatformPaint scoped_platform_paint(canvas); |
411 HDC hdc = scoped_platform_paint.GetPlatformSurface(); | 382 HDC hdc = scoped_platform_paint.GetPlatformSurface(); |
412 | 383 |
413 switch (part) { | 384 switch (part) { |
414 case kCheckbox: | 385 case kCheckbox: |
415 PaintCheckbox(hdc, part, state, rect, extra.button); | 386 PaintCheckbox(hdc, part, state, rect, extra.button); |
416 break; | 387 return; |
417 case kRadio: | 388 case kRadio: |
418 PaintRadioButton(hdc, part, state, rect, extra.button); | 389 PaintRadioButton(hdc, part, state, rect, extra.button); |
419 break; | 390 return; |
420 case kPushButton: | 391 case kPushButton: |
421 PaintPushButton(hdc, part, state, rect, extra.button); | 392 PaintPushButton(hdc, part, state, rect, extra.button); |
422 break; | 393 return; |
423 case kMenuPopupArrow: | 394 case kMenuPopupArrow: |
424 PaintMenuArrow(hdc, state, rect, extra.menu_arrow); | 395 PaintMenuArrow(hdc, state, rect, extra.menu_arrow); |
425 break; | 396 return; |
426 case kMenuPopupGutter: | 397 case kMenuPopupGutter: |
427 PaintMenuGutter(hdc, rect); | 398 PaintMenuGutter(hdc, rect); |
428 break; | 399 return; |
429 case kMenuPopupSeparator: | 400 case kMenuPopupSeparator: |
430 PaintMenuSeparator(hdc, rect, extra.menu_separator); | 401 PaintMenuSeparator(hdc, rect, extra.menu_separator); |
431 break; | 402 return; |
432 case kMenuPopupBackground: | 403 case kMenuPopupBackground: |
433 PaintMenuBackground(hdc, rect); | 404 PaintMenuBackground(hdc, rect); |
434 break; | 405 return; |
435 case kMenuCheck: | 406 case kMenuCheck: |
436 PaintMenuCheck(hdc, state, rect, extra.menu_check); | 407 PaintMenuCheck(hdc, state, rect, extra.menu_check); |
437 break; | 408 return; |
438 case kMenuCheckBackground: | 409 case kMenuCheckBackground: |
439 PaintMenuCheckBackground(hdc, state, rect); | 410 PaintMenuCheckBackground(hdc, state, rect); |
440 break; | 411 return; |
441 case kMenuItemBackground: | 412 case kMenuItemBackground: |
442 PaintMenuItemBackground(hdc, state, rect, extra.menu_item); | 413 PaintMenuItemBackground(hdc, state, rect, extra.menu_item); |
443 break; | 414 return; |
444 case kMenuList: | 415 case kMenuList: |
445 PaintMenuList(hdc, state, rect, extra.menu_list); | 416 PaintMenuList(hdc, state, rect, extra.menu_list); |
446 break; | 417 return; |
447 case kScrollbarDownArrow: | 418 case kScrollbarDownArrow: |
448 case kScrollbarUpArrow: | 419 case kScrollbarUpArrow: |
449 case kScrollbarLeftArrow: | 420 case kScrollbarLeftArrow: |
450 case kScrollbarRightArrow: | 421 case kScrollbarRightArrow: |
451 PaintScrollbarArrow(hdc, part, state, rect, extra.scrollbar_arrow); | 422 PaintScrollbarArrow(hdc, part, state, rect, extra.scrollbar_arrow); |
452 break; | 423 return; |
453 case kScrollbarHorizontalTrack: | 424 case kScrollbarHorizontalTrack: |
454 case kScrollbarVerticalTrack: | 425 case kScrollbarVerticalTrack: |
455 PaintScrollbarTrack(canvas, hdc, part, state, rect, | 426 PaintScrollbarTrack(canvas, hdc, part, state, rect, |
456 extra.scrollbar_track); | 427 extra.scrollbar_track); |
457 break; | 428 return; |
458 case kScrollbarCorner: | 429 case kScrollbarCorner: |
459 canvas->drawColor(SK_ColorWHITE, SkXfermode::kSrc_Mode); | 430 canvas->drawColor(SK_ColorWHITE, SkXfermode::kSrc_Mode); |
460 break; | 431 return; |
461 case kScrollbarHorizontalThumb: | 432 case kScrollbarHorizontalThumb: |
462 case kScrollbarVerticalThumb: | 433 case kScrollbarVerticalThumb: |
463 case kScrollbarHorizontalGripper: | 434 case kScrollbarHorizontalGripper: |
464 case kScrollbarVerticalGripper: | 435 case kScrollbarVerticalGripper: |
465 PaintScrollbarThumb(hdc, part, state, rect, extra.scrollbar_thumb); | 436 PaintScrollbarThumb(hdc, part, state, rect, extra.scrollbar_thumb); |
466 break; | 437 return; |
467 case kInnerSpinButton: | 438 case kInnerSpinButton: |
468 PaintSpinButton(hdc, part, state, rect, extra.inner_spin); | 439 PaintSpinButton(hdc, part, state, rect, extra.inner_spin); |
469 break; | 440 return; |
470 case kTrackbarThumb: | 441 case kTrackbarThumb: |
471 case kTrackbarTrack: | 442 case kTrackbarTrack: |
472 PaintTrackbar(canvas, hdc, part, state, rect, extra.trackbar); | 443 PaintTrackbar(canvas, hdc, part, state, rect, extra.trackbar); |
473 break; | 444 return; |
474 case kProgressBar: | 445 case kProgressBar: |
475 PaintProgressBar(hdc, rect, extra.progress_bar); | 446 PaintProgressBar(hdc, rect, extra.progress_bar); |
476 break; | 447 return; |
477 case kWindowResizeGripper: | 448 case kWindowResizeGripper: |
478 PaintWindowResizeGripper(hdc, rect); | 449 PaintWindowResizeGripper(hdc, rect); |
479 break; | 450 return; |
480 case kTabPanelBackground: | 451 case kTabPanelBackground: |
481 PaintTabPanelBackground(hdc, rect); | 452 PaintTabPanelBackground(hdc, rect); |
482 break; | 453 return; |
483 case kTextField: | 454 case kTextField: |
484 PaintTextField(hdc, part, state, rect, extra.text_field); | 455 PaintTextField(hdc, part, state, rect, extra.text_field); |
485 break; | 456 return; |
486 | 457 |
487 case kSliderTrack: | 458 case kSliderTrack: |
488 case kSliderThumb: | 459 case kSliderThumb: |
489 default: | 460 default: |
490 // While transitioning NativeThemeWin to the single Paint() entry point, | |
491 // unsupported parts will DCHECK here. | |
492 NOTREACHED(); | 461 NOTREACHED(); |
462 return; | |
493 } | 463 } |
494 } | 464 } |
495 | 465 |
496 SkColor NativeThemeWin::GetSystemColor(ColorId color_id) const { | 466 SkColor NativeThemeWin::GetSystemColor(ColorId color_id) const { |
497 SkColor color; | 467 SkColor color; |
498 if (CommonThemeGetSystemColor(color_id, &color)) | 468 if (CommonThemeGetSystemColor(color_id, &color)) |
499 return color; | 469 return color; |
500 | 470 |
501 switch (color_id) { | 471 switch (color_id) { |
502 // Windows | 472 // Windows |
503 case kColorId_WindowBackground: | 473 case kColorId_WindowBackground: |
504 return system_colors_[COLOR_WINDOW]; | 474 return system_colors_[COLOR_WINDOW]; |
505 | 475 |
506 // Dialogs | 476 // Dialogs |
507 case kColorId_DialogBackground: | 477 case kColorId_DialogBackground: |
508 if (gfx::IsInvertedColorScheme()) | 478 return gfx::IsInvertedColorScheme() ? |
509 return color_utils::InvertColor(kDialogBackgroundColor); | 479 color_utils::InvertColor(kDialogBackgroundColor) : |
510 return kDialogBackgroundColor; | 480 kDialogBackgroundColor; |
511 | 481 |
512 // FocusableBorder | 482 // FocusableBorder |
513 case kColorId_FocusedBorderColor: | 483 case kColorId_FocusedBorderColor: |
514 return kFocusedBorderColor; | 484 return kFocusedBorderColor; |
515 case kColorId_UnfocusedBorderColor: | 485 case kColorId_UnfocusedBorderColor: |
516 return kUnfocusedBorderColor; | 486 return kUnfocusedBorderColor; |
517 | 487 |
518 // Button | 488 // Button |
519 case kColorId_ButtonBackgroundColor: | 489 case kColorId_ButtonBackgroundColor: |
520 return kButtonBackgroundColor; | 490 return kButtonBackgroundColor; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 case kColorId_ResultsTableHoveredDivider: | 607 case kColorId_ResultsTableHoveredDivider: |
638 return color_utils::AlphaBlend( | 608 return color_utils::AlphaBlend( |
639 system_colors_[COLOR_WINDOWTEXT], | 609 system_colors_[COLOR_WINDOWTEXT], |
640 GetSystemColor(kColorId_ResultsTableHoveredBackground), 0x34); | 610 GetSystemColor(kColorId_ResultsTableHoveredBackground), 0x34); |
641 case kColorId_ResultsTableSelectedDivider: | 611 case kColorId_ResultsTableSelectedDivider: |
642 return color_utils::AlphaBlend(system_colors_[COLOR_HIGHLIGHTTEXT], | 612 return color_utils::AlphaBlend(system_colors_[COLOR_HIGHLIGHTTEXT], |
643 system_colors_[COLOR_HIGHLIGHT], 0x34); | 613 system_colors_[COLOR_HIGHLIGHT], 0x34); |
644 | 614 |
645 default: | 615 default: |
646 NOTREACHED(); | 616 NOTREACHED(); |
647 break; | 617 return kInvalidColorIdColor; |
648 } | 618 } |
649 return kInvalidColorIdColor; | |
650 } | 619 } |
651 | 620 |
652 void NativeThemeWin::PaintIndirect(SkCanvas* canvas, | 621 void NativeThemeWin::PaintIndirect(SkCanvas* canvas, |
653 Part part, | 622 Part part, |
654 State state, | 623 State state, |
655 const gfx::Rect& rect, | 624 const gfx::Rect& rect, |
656 const ExtraParams& extra) const { | 625 const ExtraParams& extra) const { |
657 // TODO(asvitkine): This path is pretty inefficient - for each paint operation | 626 // TODO(asvitkine): This path is pretty inefficient - for each paint operation |
658 // it creates a new offscreen bitmap Skia canvas. This can | 627 // it creates a new offscreen bitmap Skia canvas. This can |
659 // be sped up by doing it only once per part/state and | 628 // be sped up by doing it only once per part/state and |
660 // keeping a cache of the resulting bitmaps. | 629 // keeping a cache of the resulting bitmaps. |
661 | 630 |
662 // Create an offscreen canvas that is backed by an HDC. | 631 // Create an offscreen canvas that is backed by an HDC. |
663 skia::RefPtr<skia::BitmapPlatformDevice> device = skia::AdoptRef( | 632 skia::RefPtr<skia::BitmapPlatformDevice> device = skia::AdoptRef( |
664 skia::BitmapPlatformDevice::Create( | 633 skia::BitmapPlatformDevice::Create( |
665 rect.width(), rect.height(), false, NULL)); | 634 rect.width(), rect.height(), false, NULL)); |
666 DCHECK(device); | 635 DCHECK(device); |
667 if (!device) | |
668 return; | |
669 SkCanvas offscreen_canvas(device.get()); | 636 SkCanvas offscreen_canvas(device.get()); |
670 DCHECK(skia::SupportsPlatformPaint(&offscreen_canvas)); | 637 DCHECK(skia::SupportsPlatformPaint(&offscreen_canvas)); |
671 | 638 |
672 // Some of the Windows theme drawing operations do not write correct alpha | 639 // Some of the Windows theme drawing operations do not write correct alpha |
673 // values for fully-opaque pixels; instead the pixels get alpha 0. This is | 640 // values for fully-opaque pixels; instead the pixels get alpha 0. This is |
674 // especially a problem on Windows XP or when using the Classic theme. | 641 // especially a problem on Windows XP or when using the Classic theme. |
675 // | 642 // |
676 // To work-around this, mark all pixels with a placeholder value, to detect | 643 // To work-around this, mark all pixels with a placeholder value, to detect |
677 // which pixels get touched by the paint operation. After paint, set any | 644 // which pixels get touched by the paint operation. After paint, set any |
678 // pixels that have alpha 0 to opaque and placeholders to fully-transparent. | 645 // pixels that have alpha 0 to opaque and placeholders to fully-transparent. |
679 const SkColor placeholder = SkColorSetARGB(1, 0, 0, 0); | 646 const SkColor placeholder = SkColorSetARGB(1, 0, 0, 0); |
680 offscreen_canvas.clear(placeholder); | 647 offscreen_canvas.clear(placeholder); |
681 | 648 |
682 // Offset destination rects to have origin (0,0). | 649 // Offset destination rects to have origin (0,0). |
683 gfx::Rect adjusted_rect(rect.size()); | 650 gfx::Rect adjusted_rect(rect.size()); |
684 ExtraParams adjusted_extra(extra); | 651 ExtraParams adjusted_extra(extra); |
685 switch (part) { | 652 switch (part) { |
686 case kProgressBar: | 653 case kProgressBar: |
687 adjusted_extra.progress_bar.value_rect_x = 0; | 654 adjusted_extra.progress_bar.value_rect_x = 0; |
688 adjusted_extra.progress_bar.value_rect_y = 0; | 655 adjusted_extra.progress_bar.value_rect_y = 0; |
689 break; | 656 break; |
690 case kScrollbarHorizontalTrack: | 657 case kScrollbarHorizontalTrack: |
691 case kScrollbarVerticalTrack: | 658 case kScrollbarVerticalTrack: |
692 adjusted_extra.scrollbar_track.track_x = 0; | 659 adjusted_extra.scrollbar_track.track_x = 0; |
693 adjusted_extra.scrollbar_track.track_y = 0; | 660 adjusted_extra.scrollbar_track.track_y = 0; |
694 break; | 661 break; |
695 default: break; | |
696 } | 662 } |
697 // Draw the theme controls using existing HDC-drawing code. | 663 // Draw the theme controls using existing HDC-drawing code. |
698 PaintDirect(&offscreen_canvas, | 664 PaintDirect(&offscreen_canvas, part, state, adjusted_rect, adjusted_extra); |
699 part, | |
700 state, | |
701 adjusted_rect, | |
702 adjusted_extra); | |
703 | 665 |
704 // Copy the pixels to a bitmap that has ref-counted pixel storage, which is | 666 // Copy the pixels to a bitmap that has ref-counted pixel storage, which is |
705 // necessary to have when drawing to a SkPicture. | 667 // necessary to have when drawing to a SkPicture. |
706 const SkBitmap& hdc_bitmap = | 668 const SkBitmap& hdc_bitmap = |
707 offscreen_canvas.getDevice()->accessBitmap(false); | 669 offscreen_canvas.getDevice()->accessBitmap(false); |
708 SkBitmap bitmap; | 670 SkBitmap bitmap; |
709 hdc_bitmap.copyTo(&bitmap, kN32_SkColorType); | 671 hdc_bitmap.copyTo(&bitmap, kN32_SkColorType); |
710 | 672 |
711 // Post-process the pixels to fix up the alpha values (see big comment above). | 673 // Post-process the pixels to fix up the alpha values (see big comment above). |
712 const SkPMColor placeholder_value = SkPreMultiplyColor(placeholder); | 674 const SkPMColor placeholder_value = SkPreMultiplyColor(placeholder); |
(...skipping 17 matching lines...) Expand all Loading... | |
730 } | 692 } |
731 | 693 |
732 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, | 694 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, |
733 HDC hdc, | 695 HDC hdc, |
734 int part_id, | 696 int part_id, |
735 int state_id, | 697 int state_id, |
736 RECT* rect, | 698 RECT* rect, |
737 int ts, | 699 int ts, |
738 SIZE* size) const { | 700 SIZE* size) const { |
739 HANDLE handle = GetThemeHandle(theme_name); | 701 HANDLE handle = GetThemeHandle(theme_name); |
740 if (handle && get_theme_part_size_) | 702 return (handle && get_theme_part_size_) ? |
741 return get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size); | 703 get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size) : |
742 | 704 E_NOTIMPL; |
743 return E_NOTIMPL; | |
744 } | 705 } |
745 | 706 |
746 HRESULT NativeThemeWin::PaintButton(HDC hdc, | 707 HRESULT NativeThemeWin::PaintButton(HDC hdc, |
747 State state, | 708 State state, |
748 const ButtonExtraParams& extra, | 709 const ButtonExtraParams& extra, |
749 int part_id, | 710 int part_id, |
750 int state_id, | 711 int state_id, |
751 RECT* rect) const { | 712 RECT* rect) const { |
752 HANDLE handle = GetThemeHandle(BUTTON); | 713 HANDLE handle = GetThemeHandle(BUTTON); |
753 if (handle && draw_theme_) | 714 if (handle && draw_theme_) |
754 return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); | 715 return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); |
755 | 716 |
756 // Adjust classic_state based on part, state, and extras. | 717 // Adjust classic_state based on part, state, and extras. |
757 int classic_state = extra.classic_state; | 718 int classic_state = extra.classic_state; |
758 switch (part_id) { | 719 switch (part_id) { |
759 case BP_CHECKBOX: | 720 case BP_CHECKBOX: |
760 classic_state |= DFCS_BUTTONCHECK; | 721 classic_state |= DFCS_BUTTONCHECK; |
761 break; | 722 break; |
762 case BP_RADIOBUTTON: | 723 case BP_RADIOBUTTON: |
763 classic_state |= DFCS_BUTTONRADIO; | 724 classic_state |= DFCS_BUTTONRADIO; |
764 break; | 725 break; |
765 case BP_PUSHBUTTON: | 726 case BP_PUSHBUTTON: |
766 classic_state |= DFCS_BUTTONPUSH; | 727 classic_state |= DFCS_BUTTONPUSH; |
767 break; | 728 break; |
768 default: | 729 default: |
769 NOTREACHED() << "Unknown part_id: " << part_id; | 730 NOTREACHED(); |
770 break; | 731 break; |
771 } | 732 } |
772 | 733 |
773 switch (state) { | 734 if (state == kDisabled) |
774 case kDisabled: | 735 classic_state |= DFCS_INACTIVE; |
775 classic_state |= DFCS_INACTIVE; | 736 else if (state == kPressed) |
776 break; | 737 classic_state |= DFCS_PUSHED; |
777 case kPressed: | |
778 classic_state |= DFCS_PUSHED; | |
779 break; | |
780 case kNormal: | |
781 case kHovered: | |
782 break; | |
783 default: | |
784 NOTREACHED() << "Unknown state: " << state; | |
785 break; | |
786 } | |
787 | 738 |
788 if (extra.checked) | 739 if (extra.checked) |
789 classic_state |= DFCS_CHECKED; | 740 classic_state |= DFCS_CHECKED; |
790 | 741 |
791 // Draw it manually. | 742 // Draw it manually. |
792 // All pressed states have both low bits set, and no other states do. | 743 // All pressed states have both low bits set, and no other states do. |
793 const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED); | 744 const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED); |
794 const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED); | 745 const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED); |
795 if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) { | 746 if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) { |
796 // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the | 747 // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 } | 798 } |
848 | 799 |
849 DrawEdge(hdc, &rect_win, EDGE_ETCHED, BF_TOP); | 800 DrawEdge(hdc, &rect_win, EDGE_ETCHED, BF_TOP); |
850 return S_OK; | 801 return S_OK; |
851 } | 802 } |
852 | 803 |
853 HRESULT NativeThemeWin::PaintMenuGutter(HDC hdc, | 804 HRESULT NativeThemeWin::PaintMenuGutter(HDC hdc, |
854 const gfx::Rect& rect) const { | 805 const gfx::Rect& rect) const { |
855 RECT rect_win = rect.ToRECT(); | 806 RECT rect_win = rect.ToRECT(); |
856 HANDLE handle = GetThemeHandle(MENU); | 807 HANDLE handle = GetThemeHandle(MENU); |
857 if (handle && draw_theme_) | 808 return (handle && draw_theme_) ? |
858 return draw_theme_(handle, hdc, MENU_POPUPGUTTER, MPI_NORMAL, &rect_win, | 809 draw_theme_(handle, hdc, MENU_POPUPGUTTER, MPI_NORMAL, &rect_win, NULL) : |
859 NULL); | 810 E_NOTIMPL; |
860 return E_NOTIMPL; | |
861 } | 811 } |
862 | 812 |
863 HRESULT NativeThemeWin::PaintMenuArrow(HDC hdc, | 813 HRESULT NativeThemeWin::PaintMenuArrow( |
864 State state, | 814 HDC hdc, |
865 const gfx::Rect& rect, | 815 State state, |
866 const MenuArrowExtraParams& extra) | 816 const gfx::Rect& rect, |
867 const { | 817 const MenuArrowExtraParams& extra) const { |
868 int state_id = MSM_NORMAL; | 818 int state_id = MSM_NORMAL; |
869 if (state == kDisabled) | 819 if (state == kDisabled) |
870 state_id = MSM_DISABLED; | 820 state_id = MSM_DISABLED; |
871 | 821 |
872 HANDLE handle = GetThemeHandle(MENU); | 822 HANDLE handle = GetThemeHandle(MENU); |
873 RECT rect_win = rect.ToRECT(); | 823 RECT rect_win = rect.ToRECT(); |
874 if (handle && draw_theme_) { | 824 if (handle && draw_theme_) { |
875 if (extra.pointing_right) { | 825 if (extra.pointing_right) { |
876 return draw_theme_(handle, hdc, MENU_POPUPSUBMENU, state_id, &rect_win, | 826 return draw_theme_(handle, hdc, MENU_POPUPSUBMENU, state_id, &rect_win, |
877 NULL); | 827 NULL); |
878 } else { | |
879 // There is no way to tell the uxtheme API to draw a left pointing arrow; | |
880 // it doesn't have a flag equivalent to DFCS_MENUARROWRIGHT. But they | |
881 // are needed for RTL locales on Vista. So use a memory DC and mirror | |
882 // the region with GDI's StretchBlt. | |
883 gfx::Rect r(rect); | |
884 base::win::ScopedCreateDC mem_dc(CreateCompatibleDC(hdc)); | |
885 base::win::ScopedBitmap mem_bitmap(CreateCompatibleBitmap(hdc, r.width(), | |
886 r.height())); | |
887 base::win::ScopedSelectObject select_bitmap(mem_dc, mem_bitmap); | |
888 // Copy and horizontally mirror the background from hdc into mem_dc. Use | |
889 // a negative-width source rect, starting at the rightmost pixel. | |
890 StretchBlt(mem_dc, 0, 0, r.width(), r.height(), | |
891 hdc, r.right()-1, r.y(), -r.width(), r.height(), SRCCOPY); | |
892 // Draw the arrow. | |
893 RECT theme_rect = {0, 0, r.width(), r.height()}; | |
894 HRESULT result = draw_theme_(handle, mem_dc, MENU_POPUPSUBMENU, | |
895 state_id, &theme_rect, NULL); | |
896 // Copy and mirror the result back into mem_dc. | |
897 StretchBlt(hdc, r.x(), r.y(), r.width(), r.height(), | |
898 mem_dc, r.width()-1, 0, -r.width(), r.height(), SRCCOPY); | |
899 return result; | |
900 } | 828 } |
829 // There is no way to tell the uxtheme API to draw a left pointing arrow; it | |
830 // doesn't have a flag equivalent to DFCS_MENUARROWRIGHT. But they are | |
831 // needed for RTL locales on Vista. So use a memory DC and mirror the | |
832 // region with GDI's StretchBlt. | |
833 gfx::Rect r(rect); | |
834 base::win::ScopedCreateDC mem_dc(CreateCompatibleDC(hdc)); | |
835 base::win::ScopedBitmap mem_bitmap(CreateCompatibleBitmap(hdc, r.width(), | |
836 r.height())); | |
837 base::win::ScopedSelectObject select_bitmap(mem_dc, mem_bitmap); | |
838 // Copy and horizontally mirror the background from hdc into mem_dc. Use | |
839 // a negative-width source rect, starting at the rightmost pixel. | |
840 StretchBlt(mem_dc, 0, 0, r.width(), r.height(), | |
841 hdc, r.right()-1, r.y(), -r.width(), r.height(), SRCCOPY); | |
842 // Draw the arrow. | |
843 RECT theme_rect = {0, 0, r.width(), r.height()}; | |
844 HRESULT result = draw_theme_(handle, mem_dc, MENU_POPUPSUBMENU, | |
845 state_id, &theme_rect, NULL); | |
846 // Copy and mirror the result back into mem_dc. | |
847 StretchBlt(hdc, r.x(), r.y(), r.width(), r.height(), | |
848 mem_dc, r.width()-1, 0, -r.width(), r.height(), SRCCOPY); | |
849 return result; | |
901 } | 850 } |
902 | 851 |
903 // For some reason, Windows uses the name DFCS_MENUARROWRIGHT to indicate a | 852 // For some reason, Windows uses the name DFCS_MENUARROWRIGHT to indicate a |
904 // left pointing arrow. This makes the following 'if' statement slightly | 853 // left pointing arrow. This makes the following statement counterintuitive. |
905 // counterintuitive. | 854 UINT pfc_state = extra.pointing_right ? DFCS_MENUARROW : DFCS_MENUARROWRIGHT; |
906 UINT pfc_state; | |
907 if (extra.pointing_right) | |
908 pfc_state = DFCS_MENUARROW; | |
909 else | |
910 pfc_state = DFCS_MENUARROWRIGHT; | |
911 return PaintFrameControl(hdc, rect, DFC_MENU, pfc_state, extra.is_selected, | 855 return PaintFrameControl(hdc, rect, DFC_MENU, pfc_state, extra.is_selected, |
912 state); | 856 state); |
913 } | 857 } |
914 | 858 |
915 HRESULT NativeThemeWin::PaintMenuBackground(HDC hdc, | 859 HRESULT NativeThemeWin::PaintMenuBackground(HDC hdc, |
916 const gfx::Rect& rect) const { | 860 const gfx::Rect& rect) const { |
917 HANDLE handle = GetThemeHandle(MENU); | 861 HANDLE handle = GetThemeHandle(MENU); |
918 RECT rect_win = rect.ToRECT(); | 862 RECT rect_win = rect.ToRECT(); |
919 if (handle && draw_theme_) { | 863 if (handle && draw_theme_) { |
920 HRESULT result = draw_theme_(handle, hdc, MENU_POPUPBACKGROUND, 0, | 864 HRESULT result = draw_theme_(handle, hdc, MENU_POPUPBACKGROUND, 0, |
921 &rect_win, NULL); | 865 &rect_win, NULL); |
922 FrameRect(hdc, &rect_win, GetSysColorBrush(COLOR_3DSHADOW)); | 866 FrameRect(hdc, &rect_win, GetSysColorBrush(COLOR_3DSHADOW)); |
923 return result; | 867 return result; |
924 } | 868 } |
925 | 869 |
926 FillRect(hdc, &rect_win, GetSysColorBrush(COLOR_MENU)); | 870 FillRect(hdc, &rect_win, GetSysColorBrush(COLOR_MENU)); |
927 DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT); | 871 DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT); |
928 return S_OK; | 872 return S_OK; |
929 } | 873 } |
930 | 874 |
931 HRESULT NativeThemeWin::PaintMenuCheck( | 875 HRESULT NativeThemeWin::PaintMenuCheck( |
932 HDC hdc, | 876 HDC hdc, |
933 State state, | 877 State state, |
934 const gfx::Rect& rect, | 878 const gfx::Rect& rect, |
935 const MenuCheckExtraParams& extra) const { | 879 const MenuCheckExtraParams& extra) const { |
936 HANDLE handle = GetThemeHandle(MENU); | 880 HANDLE handle = GetThemeHandle(MENU); |
937 int state_id; | 881 if (handle && draw_theme_) { |
938 if (extra.is_radio) { | 882 const int state_id = extra.is_radio ? |
939 state_id = state == kDisabled ? MC_BULLETDISABLED : MC_BULLETNORMAL; | 883 ((state == kDisabled) ? MC_BULLETDISABLED : MC_BULLETNORMAL) : |
940 } else { | 884 ((state == kDisabled) ? MC_CHECKMARKDISABLED : MC_CHECKMARKNORMAL); |
Peter Kasting
2014/07/09 20:31:01
I usually try to avoid nested ternaries, but in th
| |
941 state_id = state == kDisabled ? MC_CHECKMARKDISABLED : MC_CHECKMARKNORMAL; | 885 RECT rect_win = rect.ToRECT(); |
886 return draw_theme_(handle, hdc, MENU_POPUPCHECK, state_id, &rect_win, NULL); | |
942 } | 887 } |
943 | 888 |
944 RECT rect_win = rect.ToRECT(); | |
945 if (handle && draw_theme_) | |
946 return draw_theme_(handle, hdc, MENU_POPUPCHECK, state_id, &rect_win, NULL); | |
947 | |
948 return PaintFrameControl(hdc, rect, DFC_MENU, | 889 return PaintFrameControl(hdc, rect, DFC_MENU, |
949 extra.is_radio ? DFCS_MENUBULLET : DFCS_MENUCHECK, | 890 extra.is_radio ? DFCS_MENUBULLET : DFCS_MENUCHECK, |
950 extra.is_selected, state); | 891 extra.is_selected, state); |
951 } | 892 } |
952 | 893 |
953 HRESULT NativeThemeWin::PaintMenuCheckBackground(HDC hdc, | 894 HRESULT NativeThemeWin::PaintMenuCheckBackground(HDC hdc, |
954 State state, | 895 State state, |
955 const gfx::Rect& rect) const { | 896 const gfx::Rect& rect) const { |
956 HANDLE handle = GetThemeHandle(MENU); | 897 HANDLE handle = GetThemeHandle(MENU); |
898 if (!handle || !draw_theme_) | |
899 return S_OK; // Nothing to do for background. | |
900 | |
957 int state_id = state == kDisabled ? MCB_DISABLED : MCB_NORMAL; | 901 int state_id = state == kDisabled ? MCB_DISABLED : MCB_NORMAL; |
958 RECT rect_win = rect.ToRECT(); | 902 RECT rect_win = rect.ToRECT(); |
959 if (handle && draw_theme_) | 903 return draw_theme_(handle, hdc, MENU_POPUPCHECKBACKGROUND, state_id, |
960 return draw_theme_(handle, hdc, MENU_POPUPCHECKBACKGROUND, state_id, | 904 &rect_win, NULL); |
961 &rect_win, NULL); | |
962 // Nothing to do for background. | |
963 return S_OK; | |
964 } | 905 } |
965 | 906 |
966 HRESULT NativeThemeWin::PaintMenuItemBackground( | 907 HRESULT NativeThemeWin::PaintMenuItemBackground( |
967 HDC hdc, | 908 HDC hdc, |
968 State state, | 909 State state, |
969 const gfx::Rect& rect, | 910 const gfx::Rect& rect, |
970 const MenuItemExtraParams& extra) const { | 911 const MenuItemExtraParams& extra) const { |
971 HANDLE handle = GetThemeHandle(MENU); | 912 HANDLE handle = GetThemeHandle(MENU); |
972 RECT rect_win = rect.ToRECT(); | 913 RECT rect_win = rect.ToRECT(); |
973 int state_id; | 914 int state_id; |
974 switch (state) { | 915 switch (state) { |
975 case kNormal: | |
976 state_id = MPI_NORMAL; | |
977 break; | |
978 case kDisabled: | 916 case kDisabled: |
979 state_id = extra.is_selected ? MPI_DISABLEDHOT : MPI_DISABLED; | 917 state_id = extra.is_selected ? MPI_DISABLEDHOT : MPI_DISABLED; |
980 break; | 918 break; |
981 case kHovered: | 919 case kHovered: |
982 state_id = MPI_HOT; | 920 state_id = MPI_HOT; |
983 break; | 921 break; |
922 case kNormal: | |
923 state_id = MPI_NORMAL; | |
924 break; | |
984 default: | 925 default: |
985 NOTREACHED() << "Invalid state " << state; | 926 NOTREACHED(); |
986 break; | 927 break; |
987 } | 928 } |
988 | 929 |
989 if (handle && draw_theme_) | 930 if (handle && draw_theme_) |
990 return draw_theme_(handle, hdc, MENU_POPUPITEM, state_id, &rect_win, NULL); | 931 return draw_theme_(handle, hdc, MENU_POPUPITEM, state_id, &rect_win, NULL); |
991 | 932 |
992 if (extra.is_selected) | 933 if (extra.is_selected) |
993 FillRect(hdc, &rect_win, GetSysColorBrush(COLOR_HIGHLIGHT)); | 934 FillRect(hdc, &rect_win, GetSysColorBrush(COLOR_HIGHLIGHT)); |
994 return S_OK; | 935 return S_OK; |
995 } | 936 } |
(...skipping 11 matching lines...) Expand all Loading... | |
1007 case kHovered: | 948 case kHovered: |
1008 state_id = PBS_HOT; | 949 state_id = PBS_HOT; |
1009 break; | 950 break; |
1010 case kNormal: | 951 case kNormal: |
1011 state_id = extra.is_default ? PBS_DEFAULTED : PBS_NORMAL; | 952 state_id = extra.is_default ? PBS_DEFAULTED : PBS_NORMAL; |
1012 break; | 953 break; |
1013 case kPressed: | 954 case kPressed: |
1014 state_id = PBS_PRESSED; | 955 state_id = PBS_PRESSED; |
1015 break; | 956 break; |
1016 default: | 957 default: |
1017 NOTREACHED() << "Invalid state: " << state; | 958 NOTREACHED(); |
1018 break; | 959 break; |
1019 } | 960 } |
1020 | 961 |
1021 RECT rect_win = rect.ToRECT(); | 962 RECT rect_win = rect.ToRECT(); |
1022 return PaintButton(hdc, state, extra, BP_PUSHBUTTON, state_id, &rect_win); | 963 return PaintButton(hdc, state, extra, BP_PUSHBUTTON, state_id, &rect_win); |
1023 } | 964 } |
1024 | 965 |
1025 HRESULT NativeThemeWin::PaintRadioButton(HDC hdc, | 966 HRESULT NativeThemeWin::PaintRadioButton(HDC hdc, |
1026 Part part, | 967 Part part, |
1027 State state, | 968 State state, |
1028 const gfx::Rect& rect, | 969 const gfx::Rect& rect, |
1029 const ButtonExtraParams& extra) const { | 970 const ButtonExtraParams& extra) const { |
1030 int state_id; | 971 int state_id; |
1031 switch (state) { | 972 switch (state) { |
1032 case kDisabled: | 973 case kDisabled: |
1033 state_id = extra.checked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; | 974 state_id = extra.checked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; |
1034 break; | 975 break; |
1035 case kHovered: | 976 case kHovered: |
1036 state_id = extra.checked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; | 977 state_id = extra.checked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; |
1037 break; | 978 break; |
1038 case kNormal: | 979 case kNormal: |
1039 state_id = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; | 980 state_id = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; |
1040 break; | 981 break; |
1041 case kPressed: | 982 case kPressed: |
1042 state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; | 983 state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; |
1043 break; | 984 break; |
1044 default: | 985 default: |
1045 NOTREACHED() << "Invalid state: " << state; | 986 NOTREACHED(); |
1046 break; | 987 break; |
1047 } | 988 } |
1048 | 989 |
1049 RECT rect_win = rect.ToRECT(); | 990 RECT rect_win = rect.ToRECT(); |
1050 return PaintButton(hdc, state, extra, BP_RADIOBUTTON, state_id, &rect_win); | 991 return PaintButton(hdc, state, extra, BP_RADIOBUTTON, state_id, &rect_win); |
1051 } | 992 } |
1052 | 993 |
1053 HRESULT NativeThemeWin::PaintCheckbox(HDC hdc, | 994 HRESULT NativeThemeWin::PaintCheckbox(HDC hdc, |
1054 Part part, | 995 Part part, |
1055 State state, | 996 State state, |
1056 const gfx::Rect& rect, | 997 const gfx::Rect& rect, |
1057 const ButtonExtraParams& extra) const { | 998 const ButtonExtraParams& extra) const { |
1058 int state_id; | 999 int state_id; |
1059 switch (state) { | 1000 switch (state) { |
1060 case kDisabled: | 1001 case kDisabled: |
1061 state_id = extra.checked ? CBS_CHECKEDDISABLED : | 1002 state_id = extra.checked ? |
1062 extra.indeterminate ? CBS_MIXEDDISABLED : | 1003 CBS_CHECKEDDISABLED : |
1063 CBS_UNCHECKEDDISABLED; | 1004 (extra.indeterminate ? CBS_MIXEDDISABLED : CBS_UNCHECKEDDISABLED); |
1064 break; | 1005 break; |
1065 case kHovered: | 1006 case kHovered: |
1066 state_id = extra.checked ? CBS_CHECKEDHOT : | 1007 state_id = extra.checked ? |
1067 extra.indeterminate ? CBS_MIXEDHOT : | 1008 CBS_CHECKEDHOT : |
1068 CBS_UNCHECKEDHOT; | 1009 (extra.indeterminate ? CBS_MIXEDHOT : CBS_UNCHECKEDHOT); |
1069 break; | 1010 break; |
1070 case kNormal: | 1011 case kNormal: |
1071 state_id = extra.checked ? CBS_CHECKEDNORMAL : | 1012 state_id = extra.checked ? |
1072 extra.indeterminate ? CBS_MIXEDNORMAL : | 1013 CBS_CHECKEDNORMAL : |
1073 CBS_UNCHECKEDNORMAL; | 1014 (extra.indeterminate ? CBS_MIXEDNORMAL : CBS_UNCHECKEDNORMAL); |
1074 break; | 1015 break; |
1075 case kPressed: | 1016 case kPressed: |
1076 state_id = extra.checked ? CBS_CHECKEDPRESSED : | 1017 state_id = extra.checked ? |
1077 extra.indeterminate ? CBS_MIXEDPRESSED : | 1018 CBS_CHECKEDPRESSED : |
1078 CBS_UNCHECKEDPRESSED; | 1019 (extra.indeterminate ? CBS_MIXEDPRESSED : CBS_UNCHECKEDPRESSED); |
1079 break; | 1020 break; |
1080 default: | 1021 default: |
1081 NOTREACHED() << "Invalid state: " << state; | 1022 NOTREACHED(); |
1082 break; | 1023 break; |
1083 } | 1024 } |
1084 | 1025 |
1085 RECT rect_win = rect.ToRECT(); | 1026 RECT rect_win = rect.ToRECT(); |
1086 return PaintButton(hdc, state, extra, BP_CHECKBOX, state_id, &rect_win); | 1027 return PaintButton(hdc, state, extra, BP_CHECKBOX, state_id, &rect_win); |
1087 } | 1028 } |
1088 | 1029 |
1089 HRESULT NativeThemeWin::PaintMenuList(HDC hdc, | 1030 HRESULT NativeThemeWin::PaintMenuList(HDC hdc, |
1090 State state, | 1031 State state, |
1091 const gfx::Rect& rect, | 1032 const gfx::Rect& rect, |
1092 const MenuListExtraParams& extra) const { | 1033 const MenuListExtraParams& extra) const { |
1093 HANDLE handle = GetThemeHandle(MENULIST); | 1034 HANDLE handle = GetThemeHandle(MENULIST); |
1094 RECT rect_win = rect.ToRECT(); | 1035 RECT rect_win = rect.ToRECT(); |
1095 int state_id; | 1036 int state_id; |
1096 switch (state) { | 1037 switch (state) { |
1097 case kNormal: | |
1098 state_id = CBXS_NORMAL; | |
1099 break; | |
1100 case kDisabled: | 1038 case kDisabled: |
1101 state_id = CBXS_DISABLED; | 1039 state_id = CBXS_DISABLED; |
1102 break; | 1040 break; |
1103 case kHovered: | 1041 case kHovered: |
1104 state_id = CBXS_HOT; | 1042 state_id = CBXS_HOT; |
1105 break; | 1043 break; |
1044 case kNormal: | |
1045 state_id = CBXS_NORMAL; | |
1046 break; | |
1106 case kPressed: | 1047 case kPressed: |
1107 state_id = CBXS_PRESSED; | 1048 state_id = CBXS_PRESSED; |
1108 break; | 1049 break; |
1109 default: | 1050 default: |
1110 NOTREACHED() << "Invalid state " << state; | 1051 NOTREACHED(); |
1111 break; | 1052 break; |
1112 } | 1053 } |
1113 | 1054 |
1114 if (handle && draw_theme_) | 1055 if (handle && draw_theme_) |
1115 return draw_theme_(handle, hdc, CP_DROPDOWNBUTTON, state_id, &rect_win, | 1056 return draw_theme_(handle, hdc, CP_DROPDOWNBUTTON, state_id, &rect_win, |
1116 NULL); | 1057 NULL); |
1117 | 1058 |
1118 // Draw it manually. | 1059 // Draw it manually. |
1119 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, | 1060 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, |
1120 DFCS_SCROLLCOMBOBOX | extra.classic_state); | 1061 DFCS_SCROLLCOMBOBOX | extra.classic_state); |
1121 return S_OK; | 1062 return S_OK; |
1122 } | 1063 } |
1123 | 1064 |
1124 HRESULT NativeThemeWin::PaintScrollbarArrow( | 1065 HRESULT NativeThemeWin::PaintScrollbarArrow( |
1125 HDC hdc, | 1066 HDC hdc, |
1126 Part part, | 1067 Part part, |
1127 State state, | 1068 State state, |
1128 const gfx::Rect& rect, | 1069 const gfx::Rect& rect, |
1129 const ScrollbarArrowExtraParams& extra) const { | 1070 const ScrollbarArrowExtraParams& extra) const { |
1130 static const int state_id_matrix[4][kMaxState] = { | 1071 static const int state_id_matrix[4][kNumStates] = { |
1131 ABS_DOWNDISABLED, ABS_DOWNHOT, ABS_DOWNNORMAL, ABS_DOWNPRESSED, | 1072 ABS_DOWNDISABLED, ABS_DOWNHOT, ABS_DOWNNORMAL, ABS_DOWNPRESSED, |
1132 ABS_LEFTDISABLED, ABS_LEFTHOT, ABS_LEFTNORMAL, ABS_LEFTPRESSED, | 1073 ABS_LEFTDISABLED, ABS_LEFTHOT, ABS_LEFTNORMAL, ABS_LEFTPRESSED, |
1133 ABS_RIGHTDISABLED, ABS_RIGHTHOT, ABS_RIGHTNORMAL, ABS_RIGHTPRESSED, | 1074 ABS_RIGHTDISABLED, ABS_RIGHTHOT, ABS_RIGHTNORMAL, ABS_RIGHTPRESSED, |
1134 ABS_UPDISABLED, ABS_UPHOT, ABS_UPNORMAL, ABS_UPPRESSED | 1075 ABS_UPDISABLED, ABS_UPHOT, ABS_UPNORMAL, ABS_UPPRESSED |
1135 }; | 1076 }; |
1136 HANDLE handle = GetThemeHandle(SCROLLBAR); | 1077 HANDLE handle = GetThemeHandle(SCROLLBAR); |
1137 RECT rect_win = rect.ToRECT(); | 1078 RECT rect_win = rect.ToRECT(); |
1138 if (handle && draw_theme_) { | 1079 if (handle && draw_theme_) { |
1139 int index = part - kScrollbarDownArrow; | 1080 int index = part - kScrollbarDownArrow; |
1140 DCHECK(index >=0 && index < 4); | 1081 DCHECK_GE(index, 0); |
1082 DCHECK_LT(static_cast<size_t>(index), arraysize(state_id_matrix)); | |
1141 int state_id = state_id_matrix[index][state]; | 1083 int state_id = state_id_matrix[index][state]; |
1142 | 1084 |
1143 // Hovering means that the cursor is over the scroolbar, but not over the | 1085 // Hovering means that the cursor is over the scroolbar, but not over the |
1144 // specific arrow itself. We don't want to show it "hot" mode, but only | 1086 // specific arrow itself. We don't want to show it "hot" mode, but only |
1145 // in "hover" mode. | 1087 // in "hover" mode. |
1146 if (state == kHovered && extra.is_hovering) { | 1088 if (state == kHovered && extra.is_hovering) { |
1147 switch (part) { | 1089 switch (part) { |
1148 case kScrollbarDownArrow: | 1090 case kScrollbarDownArrow: |
1149 state_id = ABS_DOWNHOVER; | 1091 state_id = ABS_DOWNHOVER; |
1150 break; | 1092 break; |
1151 case kScrollbarLeftArrow: | 1093 case kScrollbarLeftArrow: |
1152 state_id = ABS_LEFTHOVER; | 1094 state_id = ABS_LEFTHOVER; |
1153 break; | 1095 break; |
1154 case kScrollbarRightArrow: | 1096 case kScrollbarRightArrow: |
1155 state_id = ABS_RIGHTHOVER; | 1097 state_id = ABS_RIGHTHOVER; |
1156 break; | 1098 break; |
1157 case kScrollbarUpArrow: | 1099 case kScrollbarUpArrow: |
1158 state_id = ABS_UPHOVER; | 1100 state_id = ABS_UPHOVER; |
1159 break; | 1101 break; |
1160 default: | 1102 default: |
1161 NOTREACHED() << "Invalid part: " << part; | 1103 NOTREACHED(); |
1162 break; | 1104 break; |
1163 } | 1105 } |
1164 } | 1106 } |
1165 return PaintScaledTheme(handle, hdc, SBP_ARROWBTN, state_id, rect); | 1107 return PaintScaledTheme(handle, hdc, SBP_ARROWBTN, state_id, rect); |
1166 } | 1108 } |
1167 | 1109 |
1168 int classic_state = DFCS_SCROLLDOWN; | 1110 int classic_state = DFCS_SCROLLDOWN; |
1169 switch (part) { | 1111 switch (part) { |
1170 case kScrollbarDownArrow: | 1112 case kScrollbarDownArrow: |
1171 classic_state = DFCS_SCROLLDOWN; | 1113 classic_state = DFCS_SCROLLDOWN; |
1172 break; | 1114 break; |
1173 case kScrollbarLeftArrow: | 1115 case kScrollbarLeftArrow: |
1174 classic_state = DFCS_SCROLLLEFT; | 1116 classic_state = DFCS_SCROLLLEFT; |
1175 break; | 1117 break; |
1176 case kScrollbarRightArrow: | 1118 case kScrollbarRightArrow: |
1177 classic_state = DFCS_SCROLLRIGHT; | 1119 classic_state = DFCS_SCROLLRIGHT; |
1178 break; | 1120 break; |
1179 case kScrollbarUpArrow: | 1121 case kScrollbarUpArrow: |
1180 classic_state = DFCS_SCROLLUP; | 1122 classic_state = DFCS_SCROLLUP; |
1181 break; | 1123 break; |
1182 default: | 1124 default: |
1183 NOTREACHED() << "Invalid part: " << part; | 1125 NOTREACHED(); |
1184 break; | 1126 break; |
1185 } | 1127 } |
1186 switch (state) { | 1128 if (state == kDisabled) |
1187 case kDisabled: | 1129 classic_state |= DFCS_INACTIVE; |
1188 classic_state |= DFCS_INACTIVE; | 1130 else if (state == kHovered) |
1189 break; | 1131 classic_state |= DFCS_HOT; |
1190 case kHovered: | 1132 else if (state == kPressed) |
1191 classic_state |= DFCS_HOT; | 1133 classic_state |= DFCS_PUSHED; |
1192 break; | |
1193 case kNormal: | |
1194 break; | |
1195 case kPressed: | |
1196 classic_state |= DFCS_PUSHED; | |
1197 break; | |
1198 default: | |
1199 NOTREACHED() << "Invalid state: " << state; | |
1200 break; | |
1201 } | |
1202 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, classic_state); | 1134 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, classic_state); |
1203 return S_OK; | 1135 return S_OK; |
1204 } | 1136 } |
1205 | 1137 |
1206 HRESULT NativeThemeWin::PaintScrollbarThumb( | 1138 HRESULT NativeThemeWin::PaintScrollbarThumb( |
1207 HDC hdc, | 1139 HDC hdc, |
1208 Part part, | 1140 Part part, |
1209 State state, | 1141 State state, |
1210 const gfx::Rect& rect, | 1142 const gfx::Rect& rect, |
1211 const ScrollbarThumbExtraParams& extra) const { | 1143 const ScrollbarThumbExtraParams& extra) const { |
1212 HANDLE handle = GetThemeHandle(SCROLLBAR); | 1144 HANDLE handle = GetThemeHandle(SCROLLBAR); |
1213 RECT rect_win = rect.ToRECT(); | 1145 RECT rect_win = rect.ToRECT(); |
1146 | |
1214 int part_id; | 1147 int part_id; |
1215 int state_id; | |
1216 | |
1217 switch (part) { | 1148 switch (part) { |
1218 case NativeTheme::kScrollbarHorizontalThumb: | 1149 case NativeTheme::kScrollbarHorizontalThumb: |
1219 part_id = SBP_THUMBBTNHORZ; | 1150 part_id = SBP_THUMBBTNHORZ; |
1220 break; | 1151 break; |
1221 case NativeTheme::kScrollbarVerticalThumb: | 1152 case NativeTheme::kScrollbarVerticalThumb: |
1222 part_id = SBP_THUMBBTNVERT; | 1153 part_id = SBP_THUMBBTNVERT; |
1223 break; | 1154 break; |
1224 case NativeTheme::kScrollbarHorizontalGripper: | 1155 case NativeTheme::kScrollbarHorizontalGripper: |
1225 part_id = SBP_GRIPPERHORZ; | 1156 part_id = SBP_GRIPPERHORZ; |
1226 break; | 1157 break; |
1227 case NativeTheme::kScrollbarVerticalGripper: | 1158 case NativeTheme::kScrollbarVerticalGripper: |
1228 part_id = SBP_GRIPPERVERT; | 1159 part_id = SBP_GRIPPERVERT; |
1229 break; | 1160 break; |
1230 default: | 1161 default: |
1231 NOTREACHED() << "Invalid part: " << part; | 1162 NOTREACHED(); |
1232 break; | 1163 break; |
1233 } | 1164 } |
1234 | 1165 |
1166 int state_id; | |
1235 switch (state) { | 1167 switch (state) { |
1236 case kDisabled: | 1168 case kDisabled: |
1237 state_id = SCRBS_DISABLED; | 1169 state_id = SCRBS_DISABLED; |
1238 break; | 1170 break; |
1239 case kHovered: | 1171 case kHovered: |
1240 state_id = extra.is_hovering ? SCRBS_HOVER : SCRBS_HOT; | 1172 state_id = extra.is_hovering ? SCRBS_HOVER : SCRBS_HOT; |
1241 break; | 1173 break; |
1242 case kNormal: | 1174 case kNormal: |
1243 state_id = SCRBS_NORMAL; | 1175 state_id = SCRBS_NORMAL; |
1244 break; | 1176 break; |
1245 case kPressed: | 1177 case kPressed: |
1246 state_id = SCRBS_PRESSED; | 1178 state_id = SCRBS_PRESSED; |
1247 break; | 1179 break; |
1248 default: | 1180 default: |
1249 NOTREACHED() << "Invalid state: " << state; | 1181 NOTREACHED(); |
1250 break; | 1182 break; |
1251 } | 1183 } |
1252 | 1184 |
1253 if (handle && draw_theme_) | 1185 if (handle && draw_theme_) |
1254 return PaintScaledTheme(handle, hdc, part_id, state_id, rect); | 1186 return PaintScaledTheme(handle, hdc, part_id, state_id, rect); |
1255 | 1187 |
1256 // Draw it manually. | 1188 // Draw it manually. |
1257 if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT)) | 1189 if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT)) |
1258 DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT | BF_MIDDLE); | 1190 DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT | BF_MIDDLE); |
1259 // Classic mode doesn't have a gripper. | 1191 // Classic mode doesn't have a gripper. |
1260 return S_OK; | 1192 return S_OK; |
1261 } | 1193 } |
1262 | 1194 |
1263 HRESULT NativeThemeWin::PaintScrollbarTrack( | 1195 HRESULT NativeThemeWin::PaintScrollbarTrack( |
1264 SkCanvas* canvas, | 1196 SkCanvas* canvas, |
1265 HDC hdc, | 1197 HDC hdc, |
1266 Part part, | 1198 Part part, |
1267 State state, | 1199 State state, |
1268 const gfx::Rect& rect, | 1200 const gfx::Rect& rect, |
1269 const ScrollbarTrackExtraParams& extra) const { | 1201 const ScrollbarTrackExtraParams& extra) const { |
1270 HANDLE handle = GetThemeHandle(SCROLLBAR); | 1202 HANDLE handle = GetThemeHandle(SCROLLBAR); |
1271 RECT rect_win = rect.ToRECT(); | 1203 RECT rect_win = rect.ToRECT(); |
1204 | |
1272 int part_id; | 1205 int part_id; |
1273 int state_id; | |
1274 | |
1275 switch (part) { | 1206 switch (part) { |
1276 case NativeTheme::kScrollbarHorizontalTrack: | 1207 case NativeTheme::kScrollbarHorizontalTrack: |
1277 part_id = extra.is_upper ? SBP_UPPERTRACKHORZ : SBP_LOWERTRACKHORZ; | 1208 part_id = extra.is_upper ? SBP_UPPERTRACKHORZ : SBP_LOWERTRACKHORZ; |
1278 break; | 1209 break; |
1279 case NativeTheme::kScrollbarVerticalTrack: | 1210 case NativeTheme::kScrollbarVerticalTrack: |
1280 part_id = extra.is_upper ? SBP_UPPERTRACKVERT : SBP_LOWERTRACKVERT; | 1211 part_id = extra.is_upper ? SBP_UPPERTRACKVERT : SBP_LOWERTRACKVERT; |
1281 break; | 1212 break; |
1282 default: | 1213 default: |
1283 NOTREACHED() << "Invalid part: " << part; | 1214 NOTREACHED(); |
1284 break; | 1215 break; |
1285 } | 1216 } |
1286 | 1217 |
1218 int state_id; | |
1287 switch (state) { | 1219 switch (state) { |
1288 case kDisabled: | 1220 case kDisabled: |
1289 state_id = SCRBS_DISABLED; | 1221 state_id = SCRBS_DISABLED; |
1290 break; | 1222 break; |
1291 case kHovered: | 1223 case kHovered: |
1292 state_id = SCRBS_HOVER; | 1224 state_id = SCRBS_HOVER; |
1293 break; | 1225 break; |
1294 case kNormal: | 1226 case kNormal: |
1295 state_id = SCRBS_NORMAL; | 1227 state_id = SCRBS_NORMAL; |
1296 break; | 1228 break; |
1297 case kPressed: | 1229 case kPressed: |
1298 state_id = SCRBS_PRESSED; | 1230 state_id = SCRBS_PRESSED; |
1299 break; | 1231 break; |
1300 default: | 1232 default: |
1301 NOTREACHED() << "Invalid state: " << state; | 1233 NOTREACHED(); |
1302 break; | 1234 break; |
1303 } | 1235 } |
1304 | 1236 |
1305 if (handle && draw_theme_) | 1237 if (handle && draw_theme_) |
1306 return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); | 1238 return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); |
1307 | 1239 |
1308 // Draw it manually. | 1240 // Draw it manually. |
1309 if ((system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_3DFACE]) && | 1241 if ((system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_3DFACE]) && |
1310 (system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_WINDOW])) { | 1242 (system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_WINDOW])) { |
1311 FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); | 1243 FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); |
(...skipping 26 matching lines...) Expand all Loading... | |
1338 case kHovered: | 1270 case kHovered: |
1339 state_id = extra.spin_up ? UPS_HOT : DNS_HOT; | 1271 state_id = extra.spin_up ? UPS_HOT : DNS_HOT; |
1340 break; | 1272 break; |
1341 case kNormal: | 1273 case kNormal: |
1342 state_id = extra.spin_up ? UPS_NORMAL : DNS_NORMAL; | 1274 state_id = extra.spin_up ? UPS_NORMAL : DNS_NORMAL; |
1343 break; | 1275 break; |
1344 case kPressed: | 1276 case kPressed: |
1345 state_id = extra.spin_up ? UPS_PRESSED : DNS_PRESSED; | 1277 state_id = extra.spin_up ? UPS_PRESSED : DNS_PRESSED; |
1346 break; | 1278 break; |
1347 default: | 1279 default: |
1348 NOTREACHED() << "Invalid state " << state; | 1280 NOTREACHED(); |
1349 break; | 1281 break; |
1350 } | 1282 } |
1351 | 1283 |
1352 if (handle && draw_theme_) | 1284 if (handle && draw_theme_) |
1353 return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); | 1285 return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); |
1354 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, extra.classic_state); | 1286 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, extra.classic_state); |
1355 return S_OK; | 1287 return S_OK; |
1356 } | 1288 } |
1357 | 1289 |
1358 HRESULT NativeThemeWin::PaintTrackbar( | 1290 HRESULT NativeThemeWin::PaintTrackbar( |
1359 SkCanvas* canvas, | 1291 SkCanvas* canvas, |
1360 HDC hdc, | 1292 HDC hdc, |
1361 Part part, | 1293 Part part, |
1362 State state, | 1294 State state, |
1363 const gfx::Rect& rect, | 1295 const gfx::Rect& rect, |
1364 const TrackbarExtraParams& extra) const { | 1296 const TrackbarExtraParams& extra) const { |
1365 int part_id = part == kTrackbarTrack ? TKP_TRACK : TKP_THUMBBOTTOM; | 1297 const int part_id = extra.vertical ? |
1366 if (extra.vertical) | 1298 ((part == kTrackbarTrack) ? TKP_TRACKVERT : TKP_THUMBVERT) : |
1367 part_id = part == kTrackbarTrack ? TKP_TRACKVERT : TKP_THUMBVERT; | 1299 ((part == kTrackbarTrack) ? TKP_TRACK : TKP_THUMBBOTTOM); |
1368 | 1300 |
1369 int state_id = 0; | 1301 int state_id = 0; |
1370 switch (state) { | 1302 switch (state) { |
1371 case kDisabled: | 1303 case kDisabled: |
1372 state_id = TUS_DISABLED; | 1304 state_id = TUS_DISABLED; |
1373 break; | 1305 break; |
1374 case kHovered: | 1306 case kHovered: |
1375 state_id = TUS_HOT; | 1307 state_id = TUS_HOT; |
1376 break; | 1308 break; |
1377 case kNormal: | 1309 case kNormal: |
1378 state_id = TUS_NORMAL; | 1310 state_id = TUS_NORMAL; |
1379 break; | 1311 break; |
1380 case kPressed: | 1312 case kPressed: |
1381 state_id = TUS_PRESSED; | 1313 state_id = TUS_PRESSED; |
1382 break; | 1314 break; |
1383 default: | 1315 default: |
1384 NOTREACHED() << "Invalid state " << state; | 1316 NOTREACHED(); |
1385 break; | 1317 break; |
1386 } | 1318 } |
1387 | 1319 |
1388 // Make the channel be 4 px thick in the center of the supplied rect. (4 px | 1320 // Make the channel be 4 px thick in the center of the supplied rect. (4 px |
1389 // matches what XP does in various menus; GetThemePartSize() doesn't seem to | 1321 // matches what XP does in various menus; GetThemePartSize() doesn't seem to |
1390 // return good values here.) | 1322 // return good values here.) |
1391 RECT rect_win = rect.ToRECT(); | 1323 RECT rect_win = rect.ToRECT(); |
1392 RECT channel_rect = rect.ToRECT(); | 1324 RECT channel_rect = rect.ToRECT(); |
1393 const int channel_thickness = 4; | 1325 const int channel_thickness = 4; |
1394 if (part_id == TKP_TRACK) { | 1326 if (part_id == TKP_TRACK) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1462 return S_OK; | 1394 return S_OK; |
1463 } | 1395 } |
1464 | 1396 |
1465 HRESULT NativeThemeWin::PaintProgressBar( | 1397 HRESULT NativeThemeWin::PaintProgressBar( |
1466 HDC hdc, | 1398 HDC hdc, |
1467 const gfx::Rect& rect, | 1399 const gfx::Rect& rect, |
1468 const ProgressBarExtraParams& extra) const { | 1400 const ProgressBarExtraParams& extra) const { |
1469 // There is no documentation about the animation speed, frame-rate, nor | 1401 // There is no documentation about the animation speed, frame-rate, nor |
1470 // size of moving overlay of the indeterminate progress bar. | 1402 // size of moving overlay of the indeterminate progress bar. |
1471 // So we just observed real-world programs and guessed following parameters. | 1403 // So we just observed real-world programs and guessed following parameters. |
1472 const int kDeteminateOverlayPixelsPerSecond = 300; | 1404 const int kDeterminateOverlayPixelsPerSecond = 300; |
1473 const int kDeteminateOverlayWidth = 120; | 1405 const int kDeterminateOverlayWidth = 120; |
1474 const int kIndeterminateOverlayPixelsPerSecond = 175; | 1406 const int kIndeterminateOverlayPixelsPerSecond = 175; |
1475 const int kVistaIndeterminateOverlayWidth = 120; | 1407 const int kVistaIndeterminateOverlayWidth = 120; |
1476 const int kXPIndeterminateOverlayWidth = 55; | 1408 const int kXPIndeterminateOverlayWidth = 55; |
1477 // The thickness of the bar frame inside |value_rect| | 1409 // The thickness of the bar frame inside |value_rect| |
1478 const int kXPBarPadding = 3; | 1410 const int kXPBarPadding = 3; |
1479 | 1411 |
1480 RECT bar_rect = rect.ToRECT(); | 1412 RECT bar_rect = rect.ToRECT(); |
1481 RECT value_rect = gfx::Rect(extra.value_rect_x, | 1413 RECT value_rect = gfx::Rect(extra.value_rect_x, |
1482 extra.value_rect_y, | 1414 extra.value_rect_y, |
1483 extra.value_rect_width, | 1415 extra.value_rect_width, |
1484 extra.value_rect_height).ToRECT(); | 1416 extra.value_rect_height).ToRECT(); |
1485 | 1417 |
1486 bool pre_vista = base::win::GetVersion() < base::win::VERSION_VISTA; | |
1487 HANDLE handle = GetThemeHandle(PROGRESS); | 1418 HANDLE handle = GetThemeHandle(PROGRESS); |
1488 if (handle && draw_theme_ && draw_theme_ex_) { | 1419 if (!handle || !draw_theme_ || !draw_theme_ex_) { |
1489 draw_theme_(handle, hdc, PP_BAR, 0, &bar_rect, NULL); | 1420 FillRect(hdc, &bar_rect, GetSysColorBrush(COLOR_BTNFACE)); |
1490 | 1421 FillRect(hdc, &value_rect, GetSysColorBrush(COLOR_BTNSHADOW)); |
1491 int bar_width = bar_rect.right - bar_rect.left; | 1422 DrawEdge(hdc, &bar_rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); |
1492 if (extra.determinate) { | |
1493 // TODO(morrita): this RTL guess can be wrong. | |
1494 // We should pass the direction from WebKit side. | |
1495 bool is_rtl = (bar_rect.right == value_rect.right && | |
1496 bar_rect.left != value_rect.left); | |
1497 // We should care the direction here because PP_CNUNK painting | |
1498 // is asymmetric. | |
1499 DTBGOPTS value_draw_options; | |
1500 value_draw_options.dwSize = sizeof(DTBGOPTS); | |
1501 value_draw_options.dwFlags = is_rtl ? DTBG_MIRRORDC : 0; | |
1502 value_draw_options.rcClip = bar_rect; | |
1503 | |
1504 if (pre_vista) { | |
1505 // On XP, progress bar is chunk-style and has no glossy effect. | |
1506 // We need to shrink destination rect to fit the part inside the bar | |
1507 // with an appropriate margin. | |
1508 RECT shrunk_value_rect = InsetRect(&value_rect, kXPBarPadding); | |
1509 draw_theme_ex_(handle, hdc, PP_CHUNK, 0, | |
1510 &shrunk_value_rect, &value_draw_options); | |
1511 } else { | |
1512 // On Vista or later, the progress bar part has a | |
1513 // single-block value part. It also has glossy effect. | |
1514 // And the value part has exactly same height as the bar part | |
1515 // so we don't need to shrink the rect. | |
1516 draw_theme_ex_(handle, hdc, PP_FILL, 0, | |
1517 &value_rect, &value_draw_options); | |
1518 | |
1519 int dx = ComputeAnimationProgress(bar_width, | |
1520 kDeteminateOverlayWidth, | |
1521 kDeteminateOverlayPixelsPerSecond, | |
1522 extra.animated_seconds); | |
1523 RECT overlay_rect = value_rect; | |
1524 overlay_rect.left += dx; | |
1525 overlay_rect.right = overlay_rect.left + kDeteminateOverlayWidth; | |
1526 draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &value_rect); | |
1527 } | |
1528 } else { | |
1529 // A glossy overlay for indeterminate progress bar has small pause | |
1530 // after each animation. We emulate this by adding an invisible margin | |
1531 // the animation has to traverse. | |
1532 int width_with_margin = bar_width + kIndeterminateOverlayPixelsPerSecond; | |
1533 int overlay_width = pre_vista ? | |
1534 kXPIndeterminateOverlayWidth : kVistaIndeterminateOverlayWidth; | |
1535 int dx = ComputeAnimationProgress(width_with_margin, | |
1536 overlay_width, | |
1537 kIndeterminateOverlayPixelsPerSecond, | |
1538 extra.animated_seconds); | |
1539 RECT overlay_rect = bar_rect; | |
1540 overlay_rect.left += dx; | |
1541 overlay_rect.right = overlay_rect.left + overlay_width; | |
1542 if (pre_vista) { | |
1543 RECT shrunk_rect = InsetRect(&overlay_rect, kXPBarPadding); | |
1544 RECT shrunk_bar_rect = InsetRect(&bar_rect, kXPBarPadding); | |
1545 draw_theme_(handle, hdc, PP_CHUNK, 0, &shrunk_rect, &shrunk_bar_rect); | |
1546 } else { | |
1547 draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &bar_rect); | |
1548 } | |
1549 } | |
1550 | |
1551 return S_OK; | 1423 return S_OK; |
1552 } | 1424 } |
1553 | 1425 |
1554 HBRUSH bg_brush = GetSysColorBrush(COLOR_BTNFACE); | 1426 draw_theme_(handle, hdc, PP_BAR, 0, &bar_rect, NULL); |
1555 HBRUSH fg_brush = GetSysColorBrush(COLOR_BTNSHADOW); | 1427 |
1556 FillRect(hdc, &bar_rect, bg_brush); | 1428 bool pre_vista = base::win::GetVersion() < base::win::VERSION_VISTA; |
1557 FillRect(hdc, &value_rect, fg_brush); | 1429 int bar_width = bar_rect.right - bar_rect.left; |
1558 DrawEdge(hdc, &bar_rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); | 1430 if (!extra.determinate) { |
1431 // The glossy overlay for the indeterminate progress bar has a small pause | |
1432 // after each animation. We emulate this by adding an invisible margin the | |
1433 // animation has to traverse. | |
1434 int width_with_margin = bar_width + kIndeterminateOverlayPixelsPerSecond; | |
1435 int overlay_width = pre_vista ? | |
1436 kXPIndeterminateOverlayWidth : kVistaIndeterminateOverlayWidth; | |
1437 RECT overlay_rect = bar_rect; | |
1438 overlay_rect.left += ComputeAnimationProgress( | |
1439 width_with_margin, overlay_width, kIndeterminateOverlayPixelsPerSecond, | |
1440 extra.animated_seconds); | |
1441 overlay_rect.right = overlay_rect.left + overlay_width; | |
1442 if (pre_vista) { | |
1443 RECT shrunk_rect = InsetRect(&overlay_rect, kXPBarPadding); | |
1444 RECT shrunk_bar_rect = InsetRect(&bar_rect, kXPBarPadding); | |
1445 draw_theme_(handle, hdc, PP_CHUNK, 0, &shrunk_rect, &shrunk_bar_rect); | |
1446 } else { | |
1447 draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &bar_rect); | |
1448 } | |
1449 return S_OK; | |
1450 } | |
1451 | |
1452 // We care about the direction here because PP_CHUNK painting is asymmetric. | |
1453 // TODO(morrita): This RTL guess can be wrong. We should pass in the | |
1454 // direction from WebKit. | |
1455 const DTBGOPTS value_draw_options = { | |
1456 sizeof(DTBGOPTS), | |
1457 (bar_rect.right == value_rect.right && bar_rect.left != value_rect.left) ? | |
1458 DTBG_MIRRORDC : 0, | |
1459 bar_rect | |
1460 }; | |
1461 if (pre_vista) { | |
1462 // On XP, the progress bar is chunk-style and has no glossy effect. We need | |
1463 // to shrink the destination rect to fit the part inside the bar with an | |
1464 // appropriate margin. | |
1465 RECT shrunk_value_rect = InsetRect(&value_rect, kXPBarPadding); | |
1466 draw_theme_ex_(handle, hdc, PP_CHUNK, 0, &shrunk_value_rect, | |
1467 &value_draw_options); | |
1468 } else { | |
1469 // On Vista or later, the progress bar part has a single-block value part | |
1470 // and a glossy effect. The value part has exactly same height as the bar | |
1471 // part, so we don't need to shrink the rect. | |
1472 draw_theme_ex_(handle, hdc, PP_FILL, 0, &value_rect, &value_draw_options); | |
1473 | |
1474 RECT overlay_rect = value_rect; | |
1475 overlay_rect.left += ComputeAnimationProgress( | |
1476 bar_width, kDeterminateOverlayWidth, kDeterminateOverlayPixelsPerSecond, | |
1477 extra.animated_seconds); | |
1478 overlay_rect.right = overlay_rect.left + kDeterminateOverlayWidth; | |
1479 draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &value_rect); | |
1480 } | |
1559 return S_OK; | 1481 return S_OK; |
1560 } | 1482 } |
1561 | 1483 |
1562 HRESULT NativeThemeWin::PaintWindowResizeGripper(HDC hdc, | 1484 HRESULT NativeThemeWin::PaintWindowResizeGripper(HDC hdc, |
1563 const gfx::Rect& rect) const { | 1485 const gfx::Rect& rect) const { |
1564 HANDLE handle = GetThemeHandle(STATUS); | 1486 HANDLE handle = GetThemeHandle(STATUS); |
1565 RECT rect_win = rect.ToRECT(); | 1487 RECT rect_win = rect.ToRECT(); |
1566 if (handle && draw_theme_) { | 1488 if (handle && draw_theme_) { |
1567 // Paint the status bar gripper. There doesn't seem to be a | 1489 // Paint the status bar gripper. There doesn't seem to be a standard |
1568 // standard gripper in Windows for the space between | 1490 // gripper in Windows for the space between scrollbars. This is pretty |
1569 // scrollbars. This is pretty close, but it's supposed to be | 1491 // close, but it's supposed to be painted over a status bar. |
1570 // painted over a status bar. | |
1571 return draw_theme_(handle, hdc, SP_GRIPPER, 0, &rect_win, NULL); | 1492 return draw_theme_(handle, hdc, SP_GRIPPER, 0, &rect_win, NULL); |
1572 } | 1493 } |
1573 | 1494 |
1574 // Draw a windows classic scrollbar gripper. | 1495 // Draw a windows classic scrollbar gripper. |
1575 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); | 1496 DrawFrameControl(hdc, &rect_win, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); |
1576 return S_OK; | 1497 return S_OK; |
1577 } | 1498 } |
1578 | 1499 |
1579 HRESULT NativeThemeWin::PaintTabPanelBackground(HDC hdc, | 1500 HRESULT NativeThemeWin::PaintTabPanelBackground(HDC hdc, |
1580 const gfx::Rect& rect) const { | 1501 const gfx::Rect& rect) const { |
1581 HANDLE handle = GetThemeHandle(TAB); | 1502 HANDLE handle = GetThemeHandle(TAB); |
1582 RECT rect_win = rect.ToRECT(); | 1503 RECT rect_win = rect.ToRECT(); |
1583 if (handle && draw_theme_) | 1504 if (handle && draw_theme_) |
1584 return draw_theme_(handle, hdc, TABP_BODY, 0, &rect_win, NULL); | 1505 return draw_theme_(handle, hdc, TABP_BODY, 0, &rect_win, NULL); |
1585 | 1506 |
1586 // Classic just renders a flat color background. | 1507 // Classic just renders a flat color background. |
1587 FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1)); | 1508 FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1)); |
1588 return S_OK; | 1509 return S_OK; |
1589 } | 1510 } |
1590 | 1511 |
1591 HRESULT NativeThemeWin::PaintTextField( | 1512 HRESULT NativeThemeWin::PaintTextField( |
1592 HDC hdc, | 1513 HDC hdc, |
1593 Part part, | 1514 Part part, |
1594 State state, | 1515 State state, |
1595 const gfx::Rect& rect, | 1516 const gfx::Rect& rect, |
1596 const TextFieldExtraParams& extra) const { | 1517 const TextFieldExtraParams& extra) const { |
1597 int part_id = EP_EDITTEXT; | |
1598 int state_id = ETS_NORMAL; | 1518 int state_id = ETS_NORMAL; |
1599 switch (state) { | 1519 switch (state) { |
1600 case kNormal: | 1520 case kDisabled: |
1601 if (extra.is_read_only) { | 1521 state_id = ETS_DISABLED; |
1602 state_id = ETS_READONLY; | |
1603 } else if (extra.is_focused) { | |
1604 state_id = ETS_FOCUSED; | |
1605 } else { | |
1606 state_id = ETS_NORMAL; | |
1607 } | |
1608 break; | 1522 break; |
1609 case kHovered: | 1523 case kHovered: |
1610 state_id = ETS_HOT; | 1524 state_id = ETS_HOT; |
1611 break; | 1525 break; |
1526 case kNormal: | |
1527 if (extra.is_read_only) | |
1528 state_id = ETS_READONLY; | |
1529 else if (extra.is_focused) | |
1530 state_id = ETS_FOCUSED; | |
1531 else | |
1532 state_id = ETS_NORMAL; | |
1533 break; | |
1612 case kPressed: | 1534 case kPressed: |
1613 state_id = ETS_SELECTED; | 1535 state_id = ETS_SELECTED; |
1614 break; | 1536 break; |
1615 case kDisabled: | |
1616 state_id = ETS_DISABLED; | |
1617 break; | |
1618 default: | 1537 default: |
1619 NOTREACHED() << "Invalid state: " << state; | 1538 NOTREACHED(); |
1620 break; | 1539 break; |
1621 } | 1540 } |
1622 | 1541 |
1623 RECT rect_win = rect.ToRECT(); | 1542 RECT rect_win = rect.ToRECT(); |
1624 return PaintTextField(hdc, part_id, state_id, extra.classic_state, | 1543 return PaintTextField(hdc, EP_EDITTEXT, state_id, extra.classic_state, |
1625 &rect_win, | 1544 &rect_win, |
1626 skia::SkColorToCOLORREF(extra.background_color), | 1545 skia::SkColorToCOLORREF(extra.background_color), |
1627 extra.fill_content_area, extra.draw_edges); | 1546 extra.fill_content_area, extra.draw_edges); |
1628 } | 1547 } |
1629 | 1548 |
1630 HRESULT NativeThemeWin::PaintTextField(HDC hdc, | 1549 HRESULT NativeThemeWin::PaintTextField(HDC hdc, |
1631 int part_id, | 1550 int part_id, |
1632 int state_id, | 1551 int state_id, |
1633 int classic_state, | 1552 int classic_state, |
1634 RECT* rect, | 1553 RECT* rect, |
1635 COLORREF color, | 1554 COLORREF color, |
1636 bool fill_content_area, | 1555 bool fill_content_area, |
1637 bool draw_edges) const { | 1556 bool draw_edges) const { |
1638 // TODO(ojan): http://b/1210017 Figure out how to give the ability to | 1557 // TODO(ojan): http://b/1210017 Figure out how to give the ability to |
1639 // exclude individual edges from being drawn. | 1558 // exclude individual edges from being drawn. |
1640 | 1559 |
1641 HANDLE handle = GetThemeHandle(TEXTFIELD); | 1560 HANDLE handle = GetThemeHandle(TEXTFIELD); |
1642 // TODO(mpcomplete): can we detect if the color is specified by the user, | 1561 // TODO(mpcomplete): can we detect if the color is specified by the user, |
1643 // and if not, just use the system color? | 1562 // and if not, just use the system color? |
1644 // CreateSolidBrush() accepts a RGB value but alpha must be 0. | 1563 // CreateSolidBrush() accepts a RGB value but alpha must be 0. |
1645 HBRUSH bg_brush = CreateSolidBrush(color); | 1564 base::win::ScopedGDIObject<HBRUSH> bg_brush(CreateSolidBrush(color)); |
1646 HRESULT hr; | |
1647 // DrawThemeBackgroundEx was introduced in XP SP2, so that it's possible | 1565 // DrawThemeBackgroundEx was introduced in XP SP2, so that it's possible |
1648 // draw_theme_ex_ is NULL and draw_theme_ is non-null. | 1566 // draw_theme_ex_ is NULL and draw_theme_ is non-null. |
1649 if (handle && (draw_theme_ex_ || (draw_theme_ && draw_edges))) { | 1567 if (!handle || (!draw_theme_ex_ && (!draw_theme_ || !draw_edges))) { |
1650 if (draw_theme_ex_) { | |
1651 static const DTBGOPTS omit_border_options = { | |
1652 sizeof(DTBGOPTS), | |
1653 DTBG_OMITBORDER, | |
1654 { 0, 0, 0, 0 } | |
1655 }; | |
1656 const DTBGOPTS* draw_opts = draw_edges ? NULL : &omit_border_options; | |
1657 hr = draw_theme_ex_(handle, hdc, part_id, state_id, rect, draw_opts); | |
1658 } else { | |
1659 hr = draw_theme_(handle, hdc, part_id, state_id, rect, NULL); | |
1660 } | |
1661 | |
1662 // TODO(maruel): Need to be fixed if get_theme_content_rect_ is NULL. | |
1663 if (fill_content_area && get_theme_content_rect_) { | |
1664 RECT content_rect; | |
1665 hr = get_theme_content_rect_(handle, hdc, part_id, state_id, rect, | |
1666 &content_rect); | |
1667 FillRect(hdc, &content_rect, bg_brush); | |
1668 } | |
1669 } else { | |
1670 // Draw it manually. | 1568 // Draw it manually. |
1671 if (draw_edges) | 1569 if (draw_edges) |
1672 DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); | 1570 DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); |
1673 | 1571 |
1674 if (fill_content_area) { | 1572 if (fill_content_area) { |
1675 FillRect(hdc, rect, (classic_state & DFCS_INACTIVE) ? | 1573 FillRect(hdc, rect, (classic_state & DFCS_INACTIVE) ? |
1676 reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1) : bg_brush); | 1574 reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1) : bg_brush); |
1677 } | 1575 } |
1678 hr = S_OK; | 1576 return S_OK; |
1679 } | 1577 } |
1680 DeleteObject(bg_brush); | 1578 |
1579 static const DTBGOPTS omit_border_options = { | |
1580 sizeof(DTBGOPTS), | |
1581 DTBG_OMITBORDER, | |
1582 { 0, 0, 0, 0 } | |
1583 }; | |
1584 HRESULT hr = draw_theme_ex_ ? | |
1585 draw_theme_ex_(handle, hdc, part_id, state_id, rect, | |
1586 draw_edges ? NULL : &omit_border_options) : | |
1587 draw_theme_(handle, hdc, part_id, state_id, rect, NULL); | |
1588 | |
1589 // TODO(maruel): Need to be fixed if get_theme_content_rect_ is NULL. | |
1590 if (fill_content_area && get_theme_content_rect_) { | |
1591 RECT content_rect; | |
1592 hr = get_theme_content_rect_(handle, hdc, part_id, state_id, rect, | |
1593 &content_rect); | |
1594 FillRect(hdc, &content_rect, bg_brush); | |
1595 } | |
1681 return hr; | 1596 return hr; |
1682 } | 1597 } |
1683 | 1598 |
1684 HRESULT NativeThemeWin::PaintScaledTheme(HANDLE theme, | 1599 HRESULT NativeThemeWin::PaintScaledTheme(HANDLE theme, |
1685 HDC hdc, | 1600 HDC hdc, |
1686 int part_id, | 1601 int part_id, |
1687 int state_id, | 1602 int state_id, |
1688 const gfx::Rect& rect) const { | 1603 const gfx::Rect& rect) const { |
1689 // Correct the scaling and positioning of sub-components such as scrollbar | 1604 // Correct the scaling and positioning of sub-components such as scrollbar |
1690 // arrows and thumb grippers in the event that the world transform applies | 1605 // arrows and thumb grippers in the event that the world transform applies |
1691 // scaling (e.g. in high-DPI mode). | 1606 // scaling (e.g. in high-DPI mode). |
1692 XFORM save_transform; | 1607 XFORM save_transform; |
1693 if (GetWorldTransform(hdc, &save_transform)) { | 1608 if (GetWorldTransform(hdc, &save_transform)) { |
1694 float scale = save_transform.eM11; | 1609 float scale = save_transform.eM11; |
1695 if (scale != 1 && save_transform.eM12 == 0) { | 1610 if (scale != 1 && save_transform.eM12 == 0) { |
1696 ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); | 1611 ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); |
1697 gfx::Rect scaled_rect = gfx::ToEnclosedRect( | 1612 gfx::Rect scaled_rect(gfx::ToEnclosedRect(gfx::ScaleRect(rect, scale))); |
1698 gfx::ScaleRect(rect, scale)); | 1613 scaled_rect.Offset(save_transform.eDx, save_transform.eDy); |
1699 RECT bounds = gfx::Rect(scaled_rect.x() + save_transform.eDx, | 1614 RECT bounds = scaled_rect.ToRECT(); |
1700 scaled_rect.y() + save_transform.eDy, | |
1701 scaled_rect.width(), | |
1702 scaled_rect.height()).ToRECT(); | |
1703 HRESULT result = draw_theme_(theme, hdc, part_id, state_id, &bounds, | 1615 HRESULT result = draw_theme_(theme, hdc, part_id, state_id, &bounds, |
1704 NULL); | 1616 NULL); |
1705 SetWorldTransform(hdc, &save_transform); | 1617 SetWorldTransform(hdc, &save_transform); |
1706 return result; | 1618 return result; |
1707 } | 1619 } |
1708 } | 1620 } |
1709 RECT bounds = rect.ToRECT(); | 1621 RECT bounds = rect.ToRECT(); |
1710 return draw_theme_(theme, hdc, part_id, state_id, &bounds, NULL); | 1622 return draw_theme_(theme, hdc, part_id, state_id, &bounds, NULL); |
1711 } | 1623 } |
1712 | 1624 |
1713 // static | 1625 // static |
1714 NativeThemeWin::ThemeName NativeThemeWin::GetThemeName(Part part) { | 1626 NativeThemeWin::ThemeName NativeThemeWin::GetThemeName(Part part) { |
1715 ThemeName name; | |
1716 switch (part) { | 1627 switch (part) { |
1717 case kCheckbox: | 1628 case kCheckbox: |
1718 case kRadio: | 1629 case kRadio: |
1719 case kPushButton: | 1630 case kPushButton: |
1720 name = BUTTON; | 1631 return BUTTON; |
1721 break; | |
1722 case kInnerSpinButton: | 1632 case kInnerSpinButton: |
1723 name = SPIN; | 1633 return SPIN; |
1724 break; | |
1725 case kMenuCheck: | 1634 case kMenuCheck: |
1726 case kMenuPopupGutter: | 1635 case kMenuPopupGutter: |
1727 case kMenuList: | 1636 case kMenuList: |
1728 case kMenuPopupArrow: | 1637 case kMenuPopupArrow: |
1729 case kMenuPopupSeparator: | 1638 case kMenuPopupSeparator: |
1730 name = MENU; | 1639 return MENU; |
1731 break; | |
1732 case kProgressBar: | 1640 case kProgressBar: |
1733 name = PROGRESS; | 1641 return PROGRESS; |
1734 break; | |
1735 case kScrollbarDownArrow: | 1642 case kScrollbarDownArrow: |
1736 case kScrollbarLeftArrow: | 1643 case kScrollbarLeftArrow: |
1737 case kScrollbarRightArrow: | 1644 case kScrollbarRightArrow: |
1738 case kScrollbarUpArrow: | 1645 case kScrollbarUpArrow: |
1739 case kScrollbarHorizontalThumb: | 1646 case kScrollbarHorizontalThumb: |
1740 case kScrollbarVerticalThumb: | 1647 case kScrollbarVerticalThumb: |
1741 case kScrollbarHorizontalTrack: | 1648 case kScrollbarHorizontalTrack: |
1742 case kScrollbarVerticalTrack: | 1649 case kScrollbarVerticalTrack: |
1743 name = SCROLLBAR; | 1650 return SCROLLBAR; |
1744 break; | |
1745 case kSliderTrack: | 1651 case kSliderTrack: |
1746 case kSliderThumb: | 1652 case kSliderThumb: |
1747 name = TRACKBAR; | 1653 return TRACKBAR; |
1748 break; | |
1749 case kTextField: | 1654 case kTextField: |
1750 name = TEXTFIELD; | 1655 return TEXTFIELD; |
1751 break; | |
1752 case kWindowResizeGripper: | 1656 case kWindowResizeGripper: |
1753 name = STATUS; | 1657 return STATUS; |
1754 break; | |
1755 default: | 1658 default: |
1756 NOTREACHED() << "Invalid part: " << part; | 1659 NOTREACHED(); |
1757 break; | 1660 return LAST; |
1758 } | 1661 } |
1759 return name; | |
1760 } | 1662 } |
1761 | 1663 |
1762 // static | 1664 // static |
1763 int NativeThemeWin::GetWindowsPart(Part part, | 1665 int NativeThemeWin::GetWindowsPart(Part part, |
1764 State state, | 1666 State state, |
1765 const ExtraParams& extra) { | 1667 const ExtraParams& extra) { |
1766 int part_id; | |
1767 switch (part) { | 1668 switch (part) { |
1768 case kCheckbox: | 1669 case kCheckbox: |
1769 part_id = BP_CHECKBOX; | 1670 return BP_CHECKBOX; |
1770 break; | |
1771 case kMenuCheck: | 1671 case kMenuCheck: |
1772 part_id = MENU_POPUPCHECK; | 1672 return MENU_POPUPCHECK; |
1773 break; | |
1774 case kMenuPopupArrow: | 1673 case kMenuPopupArrow: |
1775 part_id = MENU_POPUPSUBMENU; | 1674 return MENU_POPUPSUBMENU; |
1776 break; | |
1777 case kMenuPopupGutter: | 1675 case kMenuPopupGutter: |
1778 part_id = MENU_POPUPGUTTER; | 1676 return MENU_POPUPGUTTER; |
1779 break; | |
1780 case kMenuPopupSeparator: | 1677 case kMenuPopupSeparator: |
1781 part_id = MENU_POPUPSEPARATOR; | 1678 return MENU_POPUPSEPARATOR; |
1782 break; | |
1783 case kPushButton: | 1679 case kPushButton: |
1784 part_id = BP_PUSHBUTTON; | 1680 return BP_PUSHBUTTON; |
1785 break; | |
1786 case kRadio: | 1681 case kRadio: |
1787 part_id = BP_RADIOBUTTON; | 1682 return BP_RADIOBUTTON; |
1788 break; | |
1789 case kWindowResizeGripper: | 1683 case kWindowResizeGripper: |
1790 part_id = SP_GRIPPER; | 1684 return SP_GRIPPER; |
1791 break; | |
1792 case kScrollbarDownArrow: | 1685 case kScrollbarDownArrow: |
1793 case kScrollbarLeftArrow: | 1686 case kScrollbarLeftArrow: |
1794 case kScrollbarRightArrow: | 1687 case kScrollbarRightArrow: |
1795 case kScrollbarUpArrow: | 1688 case kScrollbarUpArrow: |
1796 part_id = SBP_ARROWBTN; | 1689 return SBP_ARROWBTN; |
1797 break; | |
1798 case kScrollbarHorizontalThumb: | 1690 case kScrollbarHorizontalThumb: |
1799 part_id = SBP_THUMBBTNHORZ; | 1691 return SBP_THUMBBTNHORZ; |
1800 break; | |
1801 case kScrollbarVerticalThumb: | 1692 case kScrollbarVerticalThumb: |
1802 part_id = SBP_THUMBBTNVERT; | 1693 return SBP_THUMBBTNVERT; |
1803 break; | |
1804 default: | 1694 default: |
1805 NOTREACHED() << "Invalid part: " << part; | 1695 NOTREACHED(); |
1806 break; | 1696 return 0; |
1807 } | 1697 } |
1808 return part_id; | |
1809 } | 1698 } |
1810 | 1699 |
1811 int NativeThemeWin::GetWindowsState(Part part, | 1700 int NativeThemeWin::GetWindowsState(Part part, |
1812 State state, | 1701 State state, |
1813 const ExtraParams& extra) { | 1702 const ExtraParams& extra) { |
1814 int state_id; | |
1815 switch (part) { | 1703 switch (part) { |
1816 case kCheckbox: | 1704 case kCheckbox: |
1817 switch (state) { | 1705 switch (state) { |
1818 case kNormal: | 1706 case kDisabled: |
1819 state_id = CBS_UNCHECKEDNORMAL; | 1707 return CBS_UNCHECKEDDISABLED; |
1820 break; | 1708 case kHovered: |
1821 case kHovered: | 1709 return CBS_UNCHECKEDHOT; |
1822 state_id = CBS_UNCHECKEDHOT; | 1710 case kNormal: |
1823 break; | 1711 return CBS_UNCHECKEDNORMAL; |
1824 case kPressed: | 1712 case kPressed: |
1825 state_id = CBS_UNCHECKEDPRESSED; | 1713 return CBS_UNCHECKEDPRESSED; |
1826 break; | 1714 default: |
1827 case kDisabled: | 1715 NOTREACHED(); |
1828 state_id = CBS_UNCHECKEDDISABLED; | 1716 return 0; |
1829 break; | 1717 } |
1830 default: | |
1831 NOTREACHED() << "Invalid state: " << state; | |
1832 break; | |
1833 } | |
1834 break; | |
1835 case kMenuCheck: | 1718 case kMenuCheck: |
1836 switch (state) { | 1719 switch (state) { |
1837 case kNormal: | 1720 case kDisabled: |
1838 case kHovered: | 1721 return extra.menu_check.is_radio ? |
1839 case kPressed: | 1722 MC_BULLETDISABLED : MC_CHECKMARKDISABLED; |
1840 state_id = extra.menu_check.is_radio ? MC_BULLETNORMAL | 1723 case kHovered: |
1841 : MC_CHECKMARKNORMAL; | 1724 case kNormal: |
1842 break; | 1725 case kPressed: |
1843 case kDisabled: | 1726 return extra.menu_check.is_radio ? |
1844 state_id = extra.menu_check.is_radio ? MC_BULLETDISABLED | 1727 MC_BULLETNORMAL : MC_CHECKMARKNORMAL; |
1845 : MC_CHECKMARKDISABLED; | 1728 default: |
1846 break; | 1729 NOTREACHED(); |
1847 default: | 1730 return 0; |
1848 NOTREACHED() << "Invalid state: " << state; | 1731 } |
1849 break; | |
1850 } | |
1851 break; | |
1852 case kMenuPopupArrow: | 1732 case kMenuPopupArrow: |
1853 case kMenuPopupGutter: | 1733 case kMenuPopupGutter: |
1854 case kMenuPopupSeparator: | 1734 case kMenuPopupSeparator: |
1855 switch (state) { | 1735 switch (state) { |
1856 case kNormal: | 1736 case kDisabled: |
1857 state_id = MBI_NORMAL; | 1737 return MBI_DISABLED; |
1858 break; | 1738 case kHovered: |
1859 case kHovered: | 1739 return MBI_HOT; |
1860 state_id = MBI_HOT; | 1740 case kNormal: |
1861 break; | 1741 return MBI_NORMAL; |
1862 case kPressed: | 1742 case kPressed: |
1863 state_id = MBI_PUSHED; | 1743 return MBI_PUSHED; |
1864 break; | 1744 default: |
1865 case kDisabled: | 1745 NOTREACHED(); |
1866 state_id = MBI_DISABLED; | 1746 return 0; |
1867 break; | 1747 } |
1868 default: | |
1869 NOTREACHED() << "Invalid state: " << state; | |
1870 break; | |
1871 } | |
1872 break; | |
1873 case kPushButton: | 1748 case kPushButton: |
1874 switch (state) { | 1749 switch (state) { |
1875 case kNormal: | 1750 case kDisabled: |
1876 state_id = PBS_NORMAL; | 1751 return PBS_DISABLED; |
1877 break; | 1752 case kHovered: |
1878 case kHovered: | 1753 return PBS_HOT; |
1879 state_id = PBS_HOT; | 1754 case kNormal: |
1880 break; | 1755 return PBS_NORMAL; |
1881 case kPressed: | 1756 case kPressed: |
1882 state_id = PBS_PRESSED; | 1757 return PBS_PRESSED; |
1883 break; | 1758 default: |
1884 case kDisabled: | 1759 NOTREACHED(); |
1885 state_id = PBS_DISABLED; | 1760 return 0; |
1886 break; | 1761 } |
1887 default: | |
1888 NOTREACHED() << "Invalid state: " << state; | |
1889 break; | |
1890 } | |
1891 break; | |
1892 case kRadio: | 1762 case kRadio: |
1893 switch (state) { | 1763 switch (state) { |
1894 case kNormal: | 1764 case kDisabled: |
1895 state_id = RBS_UNCHECKEDNORMAL; | 1765 return RBS_UNCHECKEDDISABLED; |
1896 break; | 1766 case kHovered: |
1897 case kHovered: | 1767 return RBS_UNCHECKEDHOT; |
1898 state_id = RBS_UNCHECKEDHOT; | 1768 case kNormal: |
1899 break; | 1769 return RBS_UNCHECKEDNORMAL; |
1900 case kPressed: | 1770 case kPressed: |
1901 state_id = RBS_UNCHECKEDPRESSED; | 1771 return RBS_UNCHECKEDPRESSED; |
1902 break; | 1772 default: |
1903 case kDisabled: | 1773 NOTREACHED(); |
1904 state_id = RBS_UNCHECKEDDISABLED; | 1774 return 0; |
1905 break; | 1775 } |
1906 default: | |
1907 NOTREACHED() << "Invalid state: " << state; | |
1908 break; | |
1909 } | |
1910 break; | |
1911 case kWindowResizeGripper: | 1776 case kWindowResizeGripper: |
1912 switch (state) { | 1777 switch (state) { |
1913 case kNormal: | 1778 case kDisabled: |
1914 case kHovered: | 1779 case kHovered: |
1915 case kPressed: | 1780 case kNormal: |
1916 case kDisabled: | 1781 case kPressed: |
1917 state_id = 1; // gripper has no windows state | 1782 return 1; // gripper has no windows state |
1918 break; | 1783 default: |
1919 default: | 1784 NOTREACHED(); |
1920 NOTREACHED() << "Invalid state: " << state; | 1785 return 0; |
1921 break; | 1786 } |
1922 } | |
1923 break; | |
1924 case kScrollbarDownArrow: | 1787 case kScrollbarDownArrow: |
1925 switch (state) { | 1788 switch (state) { |
1926 case kNormal: | 1789 case kDisabled: |
1927 state_id = ABS_DOWNNORMAL; | 1790 return ABS_DOWNDISABLED; |
1928 break; | 1791 case kHovered: |
1929 case kHovered: | 1792 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. |
1930 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. | 1793 return base::win::GetVersion() < base::win::VERSION_VISTA ? |
1931 state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? | |
1932 ABS_DOWNHOT : ABS_DOWNHOVER; | 1794 ABS_DOWNHOT : ABS_DOWNHOVER; |
1933 break; | 1795 case kNormal: |
1934 case kPressed: | 1796 return ABS_DOWNNORMAL; |
1935 state_id = ABS_DOWNPRESSED; | 1797 case kPressed: |
1936 break; | 1798 return ABS_DOWNPRESSED; |
1937 case kDisabled: | 1799 default: |
1938 state_id = ABS_DOWNDISABLED; | 1800 NOTREACHED(); |
1939 break; | 1801 return 0; |
1940 default: | 1802 } |
1941 NOTREACHED() << "Invalid state: " << state; | |
1942 break; | |
1943 } | |
1944 break; | |
1945 case kScrollbarLeftArrow: | 1803 case kScrollbarLeftArrow: |
1946 switch (state) { | 1804 switch (state) { |
1947 case kNormal: | 1805 case kDisabled: |
1948 state_id = ABS_LEFTNORMAL; | 1806 return ABS_LEFTDISABLED; |
1949 break; | 1807 case kHovered: |
1950 case kHovered: | 1808 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. |
1951 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. | 1809 return base::win::GetVersion() < base::win::VERSION_VISTA ? |
1952 state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? | |
1953 ABS_LEFTHOT : ABS_LEFTHOVER; | 1810 ABS_LEFTHOT : ABS_LEFTHOVER; |
1954 break; | 1811 case kNormal: |
1955 case kPressed: | 1812 return ABS_LEFTNORMAL; |
1956 state_id = ABS_LEFTPRESSED; | 1813 case kPressed: |
1957 break; | 1814 return ABS_LEFTPRESSED; |
1958 case kDisabled: | 1815 default: |
1959 state_id = ABS_LEFTDISABLED; | 1816 NOTREACHED(); |
1960 break; | 1817 return 0; |
1961 default: | 1818 } |
1962 NOTREACHED() << "Invalid state: " << state; | |
1963 break; | |
1964 } | |
1965 break; | |
1966 case kScrollbarRightArrow: | 1819 case kScrollbarRightArrow: |
1967 switch (state) { | 1820 switch (state) { |
1968 case kNormal: | 1821 case kDisabled: |
1969 state_id = ABS_RIGHTNORMAL; | 1822 return ABS_RIGHTDISABLED; |
1970 break; | 1823 case kHovered: |
1971 case kHovered: | 1824 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. |
1972 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. | 1825 return base::win::GetVersion() < base::win::VERSION_VISTA ? |
1973 state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? | |
1974 ABS_RIGHTHOT : ABS_RIGHTHOVER; | 1826 ABS_RIGHTHOT : ABS_RIGHTHOVER; |
1975 break; | 1827 case kNormal: |
1976 case kPressed: | 1828 return ABS_RIGHTNORMAL; |
1977 state_id = ABS_RIGHTPRESSED; | 1829 case kPressed: |
1978 break; | 1830 return ABS_RIGHTPRESSED; |
1979 case kDisabled: | 1831 default: |
1980 state_id = ABS_RIGHTDISABLED; | 1832 NOTREACHED(); |
1981 break; | 1833 return 0; |
1982 default: | |
1983 NOTREACHED() << "Invalid state: " << state; | |
1984 break; | |
1985 } | 1834 } |
1986 break; | 1835 break; |
1987 case kScrollbarUpArrow: | 1836 case kScrollbarUpArrow: |
1988 switch (state) { | 1837 switch (state) { |
1989 case kNormal: | 1838 case kDisabled: |
1990 state_id = ABS_UPNORMAL; | 1839 return ABS_UPDISABLED; |
1991 break; | 1840 case kHovered: |
1992 case kHovered: | 1841 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. |
1993 // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. | 1842 return base::win::GetVersion() < base::win::VERSION_VISTA ? |
1994 state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? | |
1995 ABS_UPHOT : ABS_UPHOVER; | 1843 ABS_UPHOT : ABS_UPHOVER; |
1996 break; | 1844 case kNormal: |
1997 case kPressed: | 1845 return ABS_UPNORMAL; |
1998 state_id = ABS_UPPRESSED; | 1846 case kPressed: |
1999 break; | 1847 return ABS_UPPRESSED; |
2000 case kDisabled: | 1848 default: |
2001 state_id = ABS_UPDISABLED; | 1849 NOTREACHED(); |
2002 break; | 1850 return 0; |
2003 default: | |
2004 NOTREACHED() << "Invalid state: " << state; | |
2005 break; | |
2006 } | 1851 } |
2007 break; | 1852 break; |
2008 case kScrollbarHorizontalThumb: | 1853 case kScrollbarHorizontalThumb: |
2009 case kScrollbarVerticalThumb: | 1854 case kScrollbarVerticalThumb: |
2010 switch (state) { | 1855 switch (state) { |
2011 case kNormal: | 1856 case kDisabled: |
2012 state_id = SCRBS_NORMAL; | 1857 return SCRBS_DISABLED; |
2013 break; | |
2014 case kHovered: | 1858 case kHovered: |
2015 // Mimic WebKit's behaviour in ScrollbarThemeChromiumWin.cpp. | 1859 // Mimic WebKit's behaviour in ScrollbarThemeChromiumWin.cpp. |
2016 state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? | 1860 return base::win::GetVersion() < base::win::VERSION_VISTA ? |
2017 SCRBS_HOT : SCRBS_HOVER; | 1861 SCRBS_HOT : SCRBS_HOVER; |
2018 break; | 1862 case kNormal: |
2019 case kPressed: | 1863 return SCRBS_NORMAL; |
2020 state_id = SCRBS_PRESSED; | 1864 case kPressed: |
2021 break; | 1865 return SCRBS_PRESSED; |
2022 case kDisabled: | 1866 default: |
2023 state_id = SCRBS_DISABLED; | 1867 NOTREACHED(); |
2024 break; | 1868 return 0; |
2025 default: | 1869 } |
2026 NOTREACHED() << "Invalid state: " << state; | |
2027 break; | |
2028 } | |
2029 break; | |
2030 default: | 1870 default: |
2031 NOTREACHED() << "Invalid part: " << part; | 1871 NOTREACHED(); |
2032 break; | 1872 return 0; |
2033 } | 1873 } |
2034 return state_id; | |
2035 } | 1874 } |
2036 | 1875 |
2037 HRESULT NativeThemeWin::GetThemeInt(ThemeName theme, | 1876 HRESULT NativeThemeWin::GetThemeInt(ThemeName theme, |
2038 int part_id, | 1877 int part_id, |
2039 int state_id, | 1878 int state_id, |
2040 int prop_id, | 1879 int prop_id, |
2041 int *value) const { | 1880 int *value) const { |
2042 HANDLE handle = GetThemeHandle(theme); | 1881 HANDLE handle = GetThemeHandle(theme); |
2043 if (handle && get_theme_int_) | 1882 return (handle && get_theme_int_) ? |
2044 return get_theme_int_(handle, part_id, state_id, prop_id, value); | 1883 get_theme_int_(handle, part_id, state_id, prop_id, value) : E_NOTIMPL; |
2045 return E_NOTIMPL; | |
2046 } | 1884 } |
2047 | 1885 |
2048 HRESULT NativeThemeWin::PaintFrameControl(HDC hdc, | 1886 HRESULT NativeThemeWin::PaintFrameControl(HDC hdc, |
2049 const gfx::Rect& rect, | 1887 const gfx::Rect& rect, |
2050 UINT type, | 1888 UINT type, |
2051 UINT state, | 1889 UINT state, |
2052 bool is_selected, | 1890 bool is_selected, |
2053 State control_state) const { | 1891 State control_state) const { |
2054 const int width = rect.width(); | 1892 const int width = rect.width(); |
2055 const int height = rect.height(); | 1893 const int height = rect.height(); |
2056 | 1894 |
2057 // DrawFrameControl for menu arrow/check wants a monochrome bitmap. | 1895 // DrawFrameControl for menu arrow/check wants a monochrome bitmap. |
2058 base::win::ScopedBitmap mask_bitmap(CreateBitmap(width, height, 1, 1, NULL)); | 1896 base::win::ScopedBitmap mask_bitmap(CreateBitmap(width, height, 1, 1, NULL)); |
2059 | 1897 |
2060 if (mask_bitmap == NULL) | 1898 if (mask_bitmap == NULL) |
2061 return E_OUTOFMEMORY; | 1899 return E_OUTOFMEMORY; |
2062 | 1900 |
2063 base::win::ScopedCreateDC bitmap_dc(CreateCompatibleDC(NULL)); | 1901 base::win::ScopedCreateDC bitmap_dc(CreateCompatibleDC(NULL)); |
2064 base::win::ScopedSelectObject select_bitmap(bitmap_dc, mask_bitmap); | 1902 base::win::ScopedSelectObject select_bitmap(bitmap_dc, mask_bitmap); |
2065 RECT local_rect = { 0, 0, width, height }; | 1903 RECT local_rect = { 0, 0, width, height }; |
2066 DrawFrameControl(bitmap_dc, &local_rect, type, state); | 1904 DrawFrameControl(bitmap_dc, &local_rect, type, state); |
2067 | 1905 |
2068 // We're going to use BitBlt with a b&w mask. This results in using the dest | 1906 // We're going to use BitBlt with a b&w mask. This results in using the dest |
2069 // dc's text color for the black bits in the mask, and the dest dc's | 1907 // dc's text color for the black bits in the mask, and the dest dc's |
2070 // background color for the white bits in the mask. DrawFrameControl draws the | 1908 // background color for the white bits in the mask. DrawFrameControl draws the |
2071 // check in black, and the background in white. | 1909 // check in black, and the background in white. |
2072 int bg_color_key; | 1910 int bg_color_key; |
2073 int text_color_key; | 1911 int text_color_key; |
2074 switch (control_state) { | 1912 switch (control_state) { |
1913 case NativeTheme::kDisabled: | |
1914 bg_color_key = is_selected ? COLOR_HIGHLIGHT : COLOR_MENU; | |
1915 text_color_key = COLOR_GRAYTEXT; | |
1916 break; | |
2075 case NativeTheme::kHovered: | 1917 case NativeTheme::kHovered: |
2076 bg_color_key = COLOR_HIGHLIGHT; | 1918 bg_color_key = COLOR_HIGHLIGHT; |
2077 text_color_key = COLOR_HIGHLIGHTTEXT; | 1919 text_color_key = COLOR_HIGHLIGHTTEXT; |
2078 break; | 1920 break; |
2079 case NativeTheme::kNormal: | 1921 case NativeTheme::kNormal: |
2080 bg_color_key = COLOR_MENU; | 1922 bg_color_key = COLOR_MENU; |
2081 text_color_key = COLOR_MENUTEXT; | 1923 text_color_key = COLOR_MENUTEXT; |
2082 break; | 1924 break; |
2083 case NativeTheme::kDisabled: | |
2084 bg_color_key = is_selected ? COLOR_HIGHLIGHT : COLOR_MENU; | |
2085 text_color_key = COLOR_GRAYTEXT; | |
2086 break; | |
2087 default: | 1925 default: |
2088 NOTREACHED(); | 1926 NOTREACHED(); |
2089 bg_color_key = COLOR_MENU; | 1927 bg_color_key = COLOR_MENU; |
2090 text_color_key = COLOR_MENUTEXT; | 1928 text_color_key = COLOR_MENUTEXT; |
2091 break; | 1929 break; |
2092 } | 1930 } |
2093 COLORREF old_bg_color = SetBkColor(hdc, GetSysColor(bg_color_key)); | 1931 COLORREF old_bg_color = SetBkColor(hdc, GetSysColor(bg_color_key)); |
2094 COLORREF old_text_color = SetTextColor(hdc, GetSysColor(text_color_key)); | 1932 COLORREF old_text_color = SetTextColor(hdc, GetSysColor(text_color_key)); |
2095 BitBlt(hdc, rect.x(), rect.y(), width, height, bitmap_dc, 0, 0, SRCCOPY); | 1933 BitBlt(hdc, rect.x(), rect.y(), width, height, bitmap_dc, 0, 0, SRCCOPY); |
2096 SetBkColor(hdc, old_bg_color); | 1934 SetBkColor(hdc, old_bg_color); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2140 handle = open_theme_(NULL, L"Window"); | 1978 handle = open_theme_(NULL, L"Window"); |
2141 break; | 1979 break; |
2142 case PROGRESS: | 1980 case PROGRESS: |
2143 handle = open_theme_(NULL, L"Progress"); | 1981 handle = open_theme_(NULL, L"Progress"); |
2144 break; | 1982 break; |
2145 case SPIN: | 1983 case SPIN: |
2146 handle = open_theme_(NULL, L"Spin"); | 1984 handle = open_theme_(NULL, L"Spin"); |
2147 break; | 1985 break; |
2148 default: | 1986 default: |
2149 NOTREACHED(); | 1987 NOTREACHED(); |
1988 break; | |
2150 } | 1989 } |
2151 theme_handles_[theme_name] = handle; | 1990 theme_handles_[theme_name] = handle; |
2152 return handle; | 1991 return handle; |
2153 } | 1992 } |
2154 | 1993 |
2155 } // namespace ui | 1994 } // namespace ui |
OLD | NEW |