1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "mojo/services/html_viewer/webthemeengine_impl.h"
6
7#include "skia/ext/platform_canvas.h"
8#include "third_party/WebKit/public/platform/WebRect.h"
9#include "third_party/WebKit/public/platform/WebSize.h"
10#include "ui/native_theme/native_theme.h"
11
12using blink::WebCanvas;
13using blink::WebColor;
14using blink::WebRect;
15using blink::WebThemeEngine;
16
17namespace mojo {
18
19static ui::NativeTheme::Part NativeThemePart(
20    WebThemeEngine::Part part) {
21  switch (part) {
22    case WebThemeEngine::PartScrollbarDownArrow:
23      return ui::NativeTheme::kScrollbarDownArrow;
24    case WebThemeEngine::PartScrollbarLeftArrow:
25      return ui::NativeTheme::kScrollbarLeftArrow;
26    case WebThemeEngine::PartScrollbarRightArrow:
27      return ui::NativeTheme::kScrollbarRightArrow;
28    case WebThemeEngine::PartScrollbarUpArrow:
29      return ui::NativeTheme::kScrollbarUpArrow;
30    case WebThemeEngine::PartScrollbarHorizontalThumb:
31      return ui::NativeTheme::kScrollbarHorizontalThumb;
32    case WebThemeEngine::PartScrollbarVerticalThumb:
33      return ui::NativeTheme::kScrollbarVerticalThumb;
34    case WebThemeEngine::PartScrollbarHorizontalTrack:
35      return ui::NativeTheme::kScrollbarHorizontalTrack;
36    case WebThemeEngine::PartScrollbarVerticalTrack:
37      return ui::NativeTheme::kScrollbarVerticalTrack;
38    case WebThemeEngine::PartScrollbarCorner:
39      return ui::NativeTheme::kScrollbarCorner;
40    case WebThemeEngine::PartCheckbox:
41      return ui::NativeTheme::kCheckbox;
42    case WebThemeEngine::PartRadio:
43      return ui::NativeTheme::kRadio;
44    case WebThemeEngine::PartButton:
45      return ui::NativeTheme::kPushButton;
46    case WebThemeEngine::PartTextField:
47      return ui::NativeTheme::kTextField;
48    case WebThemeEngine::PartMenuList:
49      return ui::NativeTheme::kMenuList;
50    case WebThemeEngine::PartSliderTrack:
51      return ui::NativeTheme::kSliderTrack;
52    case WebThemeEngine::PartSliderThumb:
53      return ui::NativeTheme::kSliderThumb;
54    case WebThemeEngine::PartInnerSpinButton:
55      return ui::NativeTheme::kInnerSpinButton;
56    case WebThemeEngine::PartProgressBar:
57      return ui::NativeTheme::kProgressBar;
58    default:
59      return ui::NativeTheme::kScrollbarDownArrow;
60  }
61}
62
63static ui::NativeTheme::State NativeThemeState(
64    WebThemeEngine::State state) {
65  switch (state) {
66    case WebThemeEngine::StateDisabled:
67      return ui::NativeTheme::kDisabled;
68    case WebThemeEngine::StateHover:
69      return ui::NativeTheme::kHovered;
70    case WebThemeEngine::StateNormal:
71      return ui::NativeTheme::kNormal;
72    case WebThemeEngine::StatePressed:
73      return ui::NativeTheme::kPressed;
74    default:
75      return ui::NativeTheme::kDisabled;
76  }
77}
78
79static void GetNativeThemeExtraParams(
80    WebThemeEngine::Part part,
81    WebThemeEngine::State state,
82    const WebThemeEngine::ExtraParams* extra_params,
83    ui::NativeTheme::ExtraParams* native_theme_extra_params) {
84  switch (part) {
85    case WebThemeEngine::PartScrollbarHorizontalTrack:
86    case WebThemeEngine::PartScrollbarVerticalTrack:
87      native_theme_extra_params->scrollbar_track.track_x =
88          extra_params->scrollbarTrack.trackX;
89      native_theme_extra_params->scrollbar_track.track_y =
90          extra_params->scrollbarTrack.trackY;
91      native_theme_extra_params->scrollbar_track.track_width =
92          extra_params->scrollbarTrack.trackWidth;
93      native_theme_extra_params->scrollbar_track.track_height =
94          extra_params->scrollbarTrack.trackHeight;
95      break;
96    case WebThemeEngine::PartCheckbox:
97      native_theme_extra_params->button.checked = extra_params->button.checked;
98      native_theme_extra_params->button.indeterminate =
99          extra_params->button.indeterminate;
100      break;
101    case WebThemeEngine::PartRadio:
102      native_theme_extra_params->button.checked = extra_params->button.checked;
103      break;
104    case WebThemeEngine::PartButton:
105      native_theme_extra_params->button.is_default =
106          extra_params->button.isDefault;
107      native_theme_extra_params->button.has_border =
108          extra_params->button.hasBorder;
109      // Native buttons have a different focus style.
110      native_theme_extra_params->button.is_focused = false;
111      native_theme_extra_params->button.background_color =
112          extra_params->button.backgroundColor;
113      break;
114    case WebThemeEngine::PartTextField:
115      native_theme_extra_params->text_field.is_text_area =
116          extra_params->textField.isTextArea;
117      native_theme_extra_params->text_field.is_listbox =
118          extra_params->textField.isListbox;
119      native_theme_extra_params->text_field.background_color =
120          extra_params->textField.backgroundColor;
121      break;
122    case WebThemeEngine::PartMenuList:
123      native_theme_extra_params->menu_list.has_border =
124          extra_params->menuList.hasBorder;
125      native_theme_extra_params->menu_list.has_border_radius =
126          extra_params->menuList.hasBorderRadius;
127      native_theme_extra_params->menu_list.arrow_x =
128          extra_params->menuList.arrowX;
129      native_theme_extra_params->menu_list.arrow_y =
130          extra_params->menuList.arrowY;
131      native_theme_extra_params->menu_list.background_color =
132          extra_params->menuList.backgroundColor;
133      break;
134    case WebThemeEngine::PartSliderTrack:
135    case WebThemeEngine::PartSliderThumb:
136      native_theme_extra_params->slider.vertical =
137          extra_params->slider.vertical;
138      native_theme_extra_params->slider.in_drag = extra_params->slider.inDrag;
139      break;
140    case WebThemeEngine::PartInnerSpinButton:
141      native_theme_extra_params->inner_spin.spin_up =
142          extra_params->innerSpin.spinUp;
143      native_theme_extra_params->inner_spin.read_only =
144          extra_params->innerSpin.readOnly;
145      break;
146    case WebThemeEngine::PartProgressBar:
147      native_theme_extra_params->progress_bar.determinate =
148          extra_params->progressBar.determinate;
149      native_theme_extra_params->progress_bar.value_rect_x =
150          extra_params->progressBar.valueRectX;
151      native_theme_extra_params->progress_bar.value_rect_y =
152          extra_params->progressBar.valueRectY;
153      native_theme_extra_params->progress_bar.value_rect_width =
154          extra_params->progressBar.valueRectWidth;
155      native_theme_extra_params->progress_bar.value_rect_height =
156          extra_params->progressBar.valueRectHeight;
157      break;
158    default:
159      break;  // Parts that have no extra params get here.
160  }
161}
162
163blink::WebSize WebThemeEngineImpl::getSize(WebThemeEngine::Part part) {
164  ui::NativeTheme::ExtraParams extra;
165  return ui::NativeTheme::instance()->GetPartSize(NativeThemePart(part),
166                                                   ui::NativeTheme::kNormal,
167                                                   extra);
168}
169
170void WebThemeEngineImpl::paint(
171    blink::WebCanvas* canvas,
172    WebThemeEngine::Part part,
173    WebThemeEngine::State state,
174    const blink::WebRect& rect,
175    const WebThemeEngine::ExtraParams* extra_params) {
176  ui::NativeTheme::ExtraParams native_theme_extra_params;
177  GetNativeThemeExtraParams(
178      part, state, extra_params, &native_theme_extra_params);
179  ui::NativeTheme::instance()->Paint(
180      canvas,
181      NativeThemePart(part),
182      NativeThemeState(state),
183      gfx::Rect(rect),
184      native_theme_extra_params);
185}
186
187void WebThemeEngineImpl::paintStateTransition(blink::WebCanvas* canvas,
188                                              WebThemeEngine::Part part,
189                                              WebThemeEngine::State startState,
190                                              WebThemeEngine::State endState,
191                                              double progress,
192                                              const blink::WebRect& rect) {
193  ui::NativeTheme::instance()->PaintStateTransition(
194      canvas,
195      NativeThemePart(part),
196      NativeThemeState(startState),
197      NativeThemeState(endState),
198      progress,
199      gfx::Rect(rect));
200}
201
202}  // namespace mojo
203