1 // Copyright 2014 PDFium 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fwl/theme/cfwl_scrollbartp.h"
8
9 #include "core/fxge/render_defines.h"
10 #include "xfa/fwl/cfwl_scrollbar.h"
11 #include "xfa/fwl/cfwl_themebackground.h"
12 #include "xfa/fwl/cfwl_widget.h"
13 #include "xfa/fwl/ifwl_themeprovider.h"
14 #include "xfa/fxgraphics/cxfa_gecolor.h"
15 #include "xfa/fxgraphics/cxfa_gepath.h"
16
17 namespace {
18
19 const float kPawLength = 12.5f;
20
21 } // namespace
22
CFWL_ScrollBarTP()23 CFWL_ScrollBarTP::CFWL_ScrollBarTP() : m_pThemeData(new SBThemeData) {
24 SetThemeData();
25 }
26
~CFWL_ScrollBarTP()27 CFWL_ScrollBarTP::~CFWL_ScrollBarTP() {}
28
DrawBackground(const CFWL_ThemeBackground & pParams)29 void CFWL_ScrollBarTP::DrawBackground(const CFWL_ThemeBackground& pParams) {
30 CFWL_Widget* pWidget = pParams.m_pWidget;
31 FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
32 if (pParams.m_dwStates & CFWL_PartState_Hovered)
33 eState = FWLTHEME_STATE_Hover;
34 else if (pParams.m_dwStates & CFWL_PartState_Pressed)
35 eState = FWLTHEME_STATE_Pressed;
36 else if (pParams.m_dwStates & CFWL_PartState_Disabled)
37 eState = FWLTHEME_STATE_Disable;
38
39 CXFA_Graphics* pGraphics = pParams.m_pGraphics.Get();
40 bool bVert = !!pWidget->GetStylesEx();
41 switch (pParams.m_iPart) {
42 case CFWL_Part::ForeArrow: {
43 DrawMaxMinBtn(pGraphics, pParams.m_rtPart,
44 bVert ? FWLTHEME_DIRECTION_Up : FWLTHEME_DIRECTION_Left,
45 eState, pParams.m_matrix);
46 break;
47 }
48 case CFWL_Part::BackArrow: {
49 DrawMaxMinBtn(pGraphics, pParams.m_rtPart,
50 bVert ? FWLTHEME_DIRECTION_Down : FWLTHEME_DIRECTION_Right,
51 eState, pParams.m_matrix);
52 break;
53 }
54 case CFWL_Part::Thumb: {
55 DrawThumbBtn(pGraphics, pParams.m_rtPart, bVert, eState, true,
56 pParams.m_matrix);
57 break;
58 }
59 case CFWL_Part::LowerTrack: {
60 DrawTrack(pGraphics, pParams.m_rtPart, bVert, eState, true,
61 pParams.m_matrix);
62 break;
63 }
64 case CFWL_Part::UpperTrack: {
65 DrawTrack(pGraphics, pParams.m_rtPart, bVert, eState, false,
66 pParams.m_matrix);
67 break;
68 }
69 default:
70 break;
71 }
72 }
73
DrawThumbBtn(CXFA_Graphics * pGraphics,const CFX_RectF & input_rect,bool bVert,FWLTHEME_STATE eState,bool bPawButton,const CFX_Matrix & matrix)74 void CFWL_ScrollBarTP::DrawThumbBtn(CXFA_Graphics* pGraphics,
75 const CFX_RectF& input_rect,
76 bool bVert,
77 FWLTHEME_STATE eState,
78 bool bPawButton,
79 const CFX_Matrix& matrix) {
80 if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disable)
81 return;
82
83 CFX_RectF rect = input_rect;
84 if (bVert)
85 rect.Deflate(1, 0);
86 else
87 rect.Deflate(0, 1);
88
89 if (rect.IsEmpty(0.1f))
90 return;
91
92 FillSolidRect(pGraphics, m_pThemeData->clrBtnBK[eState - 1][1], rect, matrix);
93
94 pGraphics->SaveGraphState();
95
96 CXFA_GEPath path;
97 path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
98 pGraphics->SetStrokeColor(
99 CXFA_GEColor(m_pThemeData->clrBtnBorder[eState - 1]));
100 pGraphics->StrokePath(&path, &matrix);
101 pGraphics->RestoreGraphState();
102 }
103
DrawPaw(CXFA_Graphics * pGraphics,const CFX_RectF & rect,bool bVert,FWLTHEME_STATE eState,const CFX_Matrix & matrix)104 void CFWL_ScrollBarTP::DrawPaw(CXFA_Graphics* pGraphics,
105 const CFX_RectF& rect,
106 bool bVert,
107 FWLTHEME_STATE eState,
108 const CFX_Matrix& matrix) {
109 CXFA_GEPath path;
110 if (bVert) {
111 float fPawLen = kPawLength;
112 if (rect.width / 2 <= fPawLen) {
113 fPawLen = (rect.width - 6) / 2;
114 }
115
116 float fX = rect.left + rect.width / 4;
117 float fY = rect.top + rect.height / 2;
118 path.MoveTo(CFX_PointF(fX, fY - 4));
119 path.LineTo(CFX_PointF(fX + fPawLen, fY - 4));
120 path.MoveTo(CFX_PointF(fX, fY - 2));
121 path.LineTo(CFX_PointF(fX + fPawLen, fY - 2));
122 path.MoveTo(CFX_PointF(fX, fY));
123 path.LineTo(CFX_PointF(fX + fPawLen, fY));
124 path.MoveTo(CFX_PointF(fX, fY + 2));
125 path.LineTo(CFX_PointF(fX + fPawLen, fY + 2));
126
127 pGraphics->SetLineWidth(1);
128 pGraphics->SetStrokeColor(
129 CXFA_GEColor(m_pThemeData->clrPawColorLight[eState - 1]));
130 pGraphics->StrokePath(&path, nullptr);
131 fX++;
132
133 path.Clear();
134 path.MoveTo(CFX_PointF(fX, fY - 3));
135 path.LineTo(CFX_PointF(fX + fPawLen, fY - 3));
136 path.MoveTo(CFX_PointF(fX, fY - 1));
137 path.LineTo(CFX_PointF(fX + fPawLen, fY - 1));
138 path.MoveTo(CFX_PointF(fX, fY + 1));
139 path.LineTo(CFX_PointF(fX + fPawLen, fY + 1));
140 path.MoveTo(CFX_PointF(fX, fY + 3));
141 path.LineTo(CFX_PointF(fX + fPawLen, fY + 3));
142
143 pGraphics->SetLineWidth(1);
144 pGraphics->SetStrokeColor(
145 CXFA_GEColor(m_pThemeData->clrPawColorDark[eState - 1]));
146 pGraphics->StrokePath(&path, &matrix);
147 } else {
148 float fPawLen = kPawLength;
149 if (rect.height / 2 <= fPawLen) {
150 fPawLen = (rect.height - 6) / 2;
151 }
152
153 float fX = rect.left + rect.width / 2;
154 float fY = rect.top + rect.height / 4;
155 path.MoveTo(CFX_PointF(fX - 4, fY));
156 path.LineTo(CFX_PointF(fX - 4, fY + fPawLen));
157 path.MoveTo(CFX_PointF(fX - 2, fY));
158 path.LineTo(CFX_PointF(fX - 2, fY + fPawLen));
159 path.MoveTo(CFX_PointF(fX, fY));
160 path.LineTo(CFX_PointF(fX, fY + fPawLen));
161 path.MoveTo(CFX_PointF(fX + 2, fY));
162 path.LineTo(CFX_PointF(fX + 2, fY + fPawLen));
163
164 pGraphics->SetLineWidth(1);
165 pGraphics->SetStrokeColor(
166 CXFA_GEColor(m_pThemeData->clrPawColorLight[eState - 1]));
167 pGraphics->StrokePath(&path, &matrix);
168 fY++;
169
170 path.Clear();
171 path.MoveTo(CFX_PointF(fX - 3, fY));
172 path.LineTo(CFX_PointF(fX - 3, fY + fPawLen));
173 path.MoveTo(CFX_PointF(fX - 1, fY));
174 path.LineTo(CFX_PointF(fX - 1, fY + fPawLen));
175 path.MoveTo(CFX_PointF(fX + 1, fY));
176 path.LineTo(CFX_PointF(fX + 1, fY + fPawLen));
177 path.MoveTo(CFX_PointF(fX + 3, fY));
178 path.LineTo(CFX_PointF(fX + 3, fY + fPawLen));
179
180 pGraphics->SetLineWidth(1);
181 pGraphics->SetStrokeColor(
182 CXFA_GEColor(m_pThemeData->clrPawColorDark[eState - 1]));
183 pGraphics->StrokePath(&path, &matrix);
184 }
185 }
186
DrawTrack(CXFA_Graphics * pGraphics,const CFX_RectF & rect,bool bVert,FWLTHEME_STATE eState,bool bLowerTrack,const CFX_Matrix & matrix)187 void CFWL_ScrollBarTP::DrawTrack(CXFA_Graphics* pGraphics,
188 const CFX_RectF& rect,
189 bool bVert,
190 FWLTHEME_STATE eState,
191 bool bLowerTrack,
192 const CFX_Matrix& matrix) {
193 if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disable)
194 return;
195
196 pGraphics->SaveGraphState();
197 CXFA_GEPath path;
198 float fRight = rect.right();
199 float fBottom = rect.bottom();
200 if (bVert) {
201 path.AddRectangle(rect.left, rect.top, 1, rect.height);
202 path.AddRectangle(fRight - 1, rect.top, 1, rect.height);
203 } else {
204 path.AddRectangle(rect.left, rect.top, rect.width, 1);
205 path.AddRectangle(rect.left, fBottom - 1, rect.width, 1);
206 }
207 pGraphics->SetFillColor(CXFA_GEColor(ArgbEncode(255, 238, 237, 229)));
208 pGraphics->FillPath(&path, FXFILL_WINDING, &matrix);
209 path.Clear();
210 path.AddRectangle(rect.left + 1, rect.top, rect.width - 2, rect.height);
211 pGraphics->RestoreGraphState();
212 FillSolidRect(pGraphics, m_pThemeData->clrTrackBKEnd, rect, matrix);
213 }
214
DrawMaxMinBtn(CXFA_Graphics * pGraphics,const CFX_RectF & rect,FWLTHEME_DIRECTION eDict,FWLTHEME_STATE eState,const CFX_Matrix & matrix)215 void CFWL_ScrollBarTP::DrawMaxMinBtn(CXFA_Graphics* pGraphics,
216 const CFX_RectF& rect,
217 FWLTHEME_DIRECTION eDict,
218 FWLTHEME_STATE eState,
219 const CFX_Matrix& matrix) {
220 DrawTrack(pGraphics, rect,
221 eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down,
222 eState, true, matrix);
223 CFX_RectF rtArrowBtn = rect;
224 rtArrowBtn.Deflate(1, 1, 1, 1);
225 DrawArrowBtn(pGraphics, rtArrowBtn, eDict, eState, matrix);
226 }
227
SetThemeData()228 void CFWL_ScrollBarTP::SetThemeData() {
229 m_pThemeData->clrPawColorLight[3] = ArgbEncode(0xff, 208, 223, 172);
230 m_pThemeData->clrPawColorDark[3] = ArgbEncode(0xff, 140, 157, 115);
231 m_pThemeData->clrBtnBK[3][0] = ArgbEncode(0xff, 164, 180, 139);
232 m_pThemeData->clrBtnBK[3][1] = ArgbEncode(0xff, 141, 157, 115);
233 m_pThemeData->clrBtnBorder[3] = ArgbEncode(0xff, 236, 233, 216);
234 m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 238, 244, 254);
235 m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 176, 248);
236 m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 197, 213, 252);
237 m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 182, 205, 251);
238 m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 148, 176, 221);
239 m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 252, 253, 255);
240 m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 156, 197, 255);
241 m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 216, 232, 255);
242 m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 204, 225, 255);
243 m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 218, 230, 254);
244 m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 207, 221, 253);
245 m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 131, 158, 216);
246 m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 167, 190, 245);
247 m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 146, 179, 249);
248 m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 124, 159, 211);
249 m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
250 m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
251 }
252