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/src/foxitlib.h"
8 #define FWL_SCROLL_PawLen 12.5f
CFWL_ScrollBarTP()9 CFWL_ScrollBarTP::CFWL_ScrollBarTP() {
10   m_pThemeData = new SBThemeData;
11   SetThemeData(0);
12 }
~CFWL_ScrollBarTP()13 CFWL_ScrollBarTP::~CFWL_ScrollBarTP() {
14   if (m_pThemeData) {
15     delete m_pThemeData;
16     m_pThemeData = NULL;
17   }
18 }
IsValidWidget(IFWL_Widget * pWidget)19 FX_BOOL CFWL_ScrollBarTP::IsValidWidget(IFWL_Widget* pWidget) {
20   if (!pWidget)
21     return FALSE;
22   return pWidget->GetClassID() == FWL_CLASSHASH_ScrollBar;
23 }
GetCapacity(CFWL_ThemePart * pThemePart,FX_DWORD dwCapacity)24 void* CFWL_ScrollBarTP::GetCapacity(CFWL_ThemePart* pThemePart,
25                                     FX_DWORD dwCapacity) {
26   if (dwCapacity == FWL_CAPACITY_SCB_Size) {
27     m_fValue = 5;
28     return &m_fValue;
29   }
30   return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
31 }
SetThemeID(IFWL_Widget * pWidget,FX_DWORD dwThemeID,FX_BOOL bChildren)32 FX_DWORD CFWL_ScrollBarTP::SetThemeID(IFWL_Widget* pWidget,
33                                       FX_DWORD dwThemeID,
34                                       FX_BOOL bChildren) {
35   if (m_pThemeData) {
36     SetThemeData(FWL_GetThemeColor(dwThemeID));
37   }
38   return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
39 }
DrawBackground(CFWL_ThemeBackground * pParams)40 FX_BOOL CFWL_ScrollBarTP::DrawBackground(CFWL_ThemeBackground* pParams) {
41   if (!pParams)
42     return FALSE;
43   IFWL_Widget* pWidget = pParams->m_pWidget;
44   FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
45   switch (pParams->m_dwStates & 0x03) {
46     case FWL_PARTSTATE_SCB_Hovered: {
47       eState = FWLTHEME_STATE_Hover;
48       break;
49     }
50     case FWL_PARTSTATE_SCB_Pressed: {
51       eState = FWLTHEME_STATE_Pressed;
52       break;
53     }
54     case FWL_PARTSTATE_SCB_Disabled: {
55       eState = FWLTHEME_STATE_Disabale;
56       break;
57     }
58   }
59   CFX_Graphics* pGraphics = pParams->m_pGraphics;
60   CFX_RectF* pRect = &pParams->m_rtPart;
61   FX_BOOL bVert = pWidget->GetStylesEx();
62   switch (pParams->m_iPart) {
63     case FWL_PART_SCB_ForeArrow: {
64       DrawMaxMinBtn(pGraphics, pRect,
65                     bVert ? FWLTHEME_DIRECTION_Up : FWLTHEME_DIRECTION_Left,
66                     eState, &pParams->m_matrix);
67       break;
68     }
69     case FWL_PART_SCB_BackArrow: {
70       DrawMaxMinBtn(pGraphics, pRect,
71                     bVert ? FWLTHEME_DIRECTION_Down : FWLTHEME_DIRECTION_Right,
72                     eState, &pParams->m_matrix);
73       break;
74     }
75     case FWL_PART_SCB_Thumb: {
76       DrawThumbBtn(pGraphics, pRect, bVert, eState, TRUE, &pParams->m_matrix);
77       break;
78     }
79     case FWL_PART_SCB_LowerTrack: {
80       DrawTrack(pGraphics, pRect, bVert, eState, TRUE, &pParams->m_matrix);
81       break;
82     }
83     case FWL_PART_SCB_UpperTrack: {
84       DrawTrack(pGraphics, pRect, bVert, eState, FALSE, &pParams->m_matrix);
85       break;
86     }
87     default: {}
88   }
89   return TRUE;
90 }
91 #ifdef THEME_XPSimilar
DrawThumbBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FX_BOOL bVert,FWLTHEME_STATE eState,FX_BOOL bPawButton,CFX_Matrix * pMatrix)92 void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics* pGraphics,
93                                     const CFX_RectF* pRect,
94                                     FX_BOOL bVert,
95                                     FWLTHEME_STATE eState,
96                                     FX_BOOL bPawButton,
97                                     CFX_Matrix* pMatrix) {
98   if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disabale) {
99     return;
100   }
101   CFX_Path path;
102   path.Create();
103   CFX_RectF rect(*pRect);
104   if (bVert) {
105     rect.Deflate(1, 0);
106     if (rect.IsEmpty(0.1f)) {
107       return;
108     }
109     path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
110     DrawAxialShading(pGraphics, rect.left, rect.top, rect.right(), rect.top,
111                      m_pThemeData->clrBtnBK[eState - 1][0],
112                      m_pThemeData->clrBtnBK[eState - 1][1], &path,
113                      FXFILL_WINDING, pMatrix);
114     CFX_Color rcStroke;
115     rcStroke.Set(m_pThemeData->clrBtnBorder[eState - 1]);
116     pGraphics->SaveGraphState();
117     pGraphics->SetStrokeColor(&rcStroke);
118     pGraphics->StrokePath(&path, pMatrix);
119     pGraphics->RestoreGraphState();
120   } else {
121     rect.Deflate(0, 1);
122     if (rect.IsEmpty(0.1f)) {
123       return;
124     }
125     path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
126     DrawAxialShading(pGraphics, rect.left, rect.top, rect.left, rect.bottom(),
127                      m_pThemeData->clrBtnBK[eState - 1][0],
128                      m_pThemeData->clrBtnBK[eState - 1][1], &path,
129                      FXFILL_WINDING, pMatrix);
130     CFX_Color rcStroke;
131     rcStroke.Set(m_pThemeData->clrBtnBorder[eState - 1]);
132     pGraphics->SaveGraphState();
133     pGraphics->SetStrokeColor(&rcStroke);
134     pGraphics->StrokePath(&path, pMatrix);
135     pGraphics->RestoreGraphState();
136   }
137 }
DrawPaw(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FX_BOOL bVert,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)138 void CFWL_ScrollBarTP::DrawPaw(CFX_Graphics* pGraphics,
139                                const CFX_RectF* pRect,
140                                FX_BOOL bVert,
141                                FWLTHEME_STATE eState,
142                                CFX_Matrix* pMatrix) {
143   CFX_Path path;
144   path.Create();
145   if (bVert) {
146     FX_FLOAT fPawLen = FWL_SCROLL_PawLen;
147     if (pRect->width / 2 <= fPawLen) {
148       fPawLen = (pRect->width - 6) / 2;
149     }
150     FX_FLOAT fX = pRect->left + pRect->width / 4;
151     FX_FLOAT fY = pRect->top + pRect->height / 2;
152     path.MoveTo(fX, fY - 4);
153     path.LineTo(fX + fPawLen, fY - 4);
154     path.MoveTo(fX, fY - 2);
155     path.LineTo(fX + fPawLen, fY - 2);
156     path.MoveTo(fX, fY);
157     path.LineTo(fX + fPawLen, fY);
158     path.MoveTo(fX, fY + 2);
159     path.LineTo(fX + fPawLen, fY + 2);
160     CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]);
161     pGraphics->SetLineWidth(1);
162     pGraphics->SetStrokeColor(&clrLight);
163     pGraphics->StrokePath(&path);
164     fX++;
165     path.Clear();
166     path.MoveTo(fX, fY - 3);
167     path.LineTo(fX + fPawLen, fY - 3);
168     path.MoveTo(fX, fY - 1);
169     path.LineTo(fX + fPawLen, fY - 1);
170     path.MoveTo(fX, fY + 1);
171     path.LineTo(fX + fPawLen, fY + 1);
172     path.MoveTo(fX, fY + 3);
173     path.LineTo(fX + fPawLen, fY + 3);
174     CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]);
175     pGraphics->SetLineWidth(1);
176     pGraphics->SetStrokeColor(&clrDark);
177     pGraphics->StrokePath(&path, pMatrix);
178   } else {
179     FX_FLOAT fPawLen = FWL_SCROLL_PawLen;
180     if (pRect->height / 2 <= fPawLen) {
181       fPawLen = (pRect->height - 6) / 2;
182     }
183     FX_FLOAT fX = pRect->left + pRect->width / 2;
184     FX_FLOAT fY = pRect->top + pRect->height / 4;
185     path.MoveTo(fX - 4, fY);
186     path.LineTo(fX - 4, fY + fPawLen);
187     path.MoveTo(fX - 2, fY);
188     path.LineTo(fX - 2, fY + fPawLen);
189     path.MoveTo(fX, fY);
190     path.LineTo(fX, fY + fPawLen);
191     path.MoveTo(fX + 2, fY);
192     path.LineTo(fX + 2, fY + fPawLen);
193     CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]);
194     pGraphics->SetLineWidth(1);
195     pGraphics->SetStrokeColor(&clrLight);
196     pGraphics->StrokePath(&path, pMatrix);
197     fY++;
198     path.Clear();
199     path.MoveTo(fX - 3, fY);
200     path.LineTo(fX - 3, fY + fPawLen);
201     path.MoveTo(fX - 1, fY);
202     path.LineTo(fX - 1, fY + fPawLen);
203     path.MoveTo(fX + 1, fY);
204     path.LineTo(fX + 1, fY + fPawLen);
205     path.MoveTo(fX + 3, fY);
206     path.LineTo(fX + 3, fY + fPawLen);
207     CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]);
208     pGraphics->SetLineWidth(1);
209     pGraphics->SetStrokeColor(&clrDark);
210     pGraphics->StrokePath(&path, pMatrix);
211   }
212 }
DrawTrack(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FX_BOOL bVert,FWLTHEME_STATE eState,FX_BOOL bLowerTrack,CFX_Matrix * pMatrix)213 void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics* pGraphics,
214                                  const CFX_RectF* pRect,
215                                  FX_BOOL bVert,
216                                  FWLTHEME_STATE eState,
217                                  FX_BOOL bLowerTrack,
218                                  CFX_Matrix* pMatrix) {
219   if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disabale) {
220     return;
221   }
222   pGraphics->SaveGraphState();
223   CFX_Color colorLine(ArgbEncode(255, 238, 237, 229));
224   CFX_Path path;
225   path.Create();
226   FX_FLOAT fRight = pRect->right();
227   FX_FLOAT fBottom = pRect->bottom();
228   if (bVert) {
229     path.AddRectangle(pRect->left, pRect->top, 1, pRect->height);
230     path.AddRectangle(fRight - 1, pRect->top, 1, pRect->height);
231   } else {
232     path.AddRectangle(pRect->left, pRect->top, pRect->width, 1);
233     path.AddRectangle(pRect->left, fBottom - 1, pRect->width, 1);
234   }
235   pGraphics->SetFillColor(&colorLine);
236   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
237   path.Clear();
238   path.AddRectangle(pRect->left + 1, pRect->top, pRect->width - 2,
239                     pRect->height);
240   FX_FLOAT x1 = bVert ? pRect->left + 1 : pRect->left;
241   FX_FLOAT y1 = bVert ? pRect->top : pRect->top + 1;
242   FX_FLOAT x2 = bVert ? fRight - 1 : pRect->left;
243   FX_FLOAT y2 = bVert ? pRect->top : fBottom - 1;
244   pGraphics->RestoreGraphState();
245   DrawAxialShading(pGraphics, x1, y1, x2, y2, m_pThemeData->clrTrackBKStart,
246                    m_pThemeData->clrTrackBKEnd, &path, FXFILL_WINDING, pMatrix);
247 }
DrawMaxMinBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)248 void CFWL_ScrollBarTP::DrawMaxMinBtn(CFX_Graphics* pGraphics,
249                                      const CFX_RectF* pRect,
250                                      FWLTHEME_DIRECTION eDict,
251                                      FWLTHEME_STATE eState,
252                                      CFX_Matrix* pMatrix) {
253   DrawTrack(pGraphics, pRect,
254             eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down,
255             eState, TRUE, pMatrix);
256   CFX_RectF rtArrowBtn(*pRect);
257   rtArrowBtn.Deflate(1, 1, 1, 1);
258   DrawArrowBtn(pGraphics, &rtArrowBtn, eDict, eState, pMatrix);
259 }
260 #else
DrawThumbBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FX_BOOL bVert,FWLTHEME_STATE eState,FX_BOOL bPawButton,CFX_Matrix * pMatrix)261 void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics* pGraphics,
262                                     const CFX_RectF* pRect,
263                                     FX_BOOL bVert,
264                                     FWLTHEME_STATE eState,
265                                     FX_BOOL bPawButton,
266                                     CFX_Matrix* pMatrix) {
267   if (pRect->IsEmpty()) {
268     return;
269   }
270   CFX_RectF rtThumb(*pRect);
271   FX_FLOAT fWidth = 2;
272   Draw3DRect(pGraphics, FWLTHEME_EDGE_Raised, fWidth, pRect,
273              FWLTHEME_COLOR_EDGELT1, FWLTHEME_COLOR_EDGELT2,
274              FWLTHEME_COLOR_EDGERB1, FWLTHEME_COLOR_EDGERB2, pMatrix);
275   CFX_Path path;
276   path.Create();
277   path.AddRectangle(pRect->left + fWidth, pRect->top + fWidth,
278                     pRect->width - 2 * fWidth, pRect->height - 2 * fWidth);
279   pGraphics->SaveGraphState();
280   CFX_Color crFill(FWLTHEME_COLOR_Background);
281   pGraphics->SetFillColor(&crFill);
282   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
283   pGraphics->RestoreGraphState();
284 }
DrawTrack(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FX_BOOL bVert,FWLTHEME_STATE eState,FX_BOOL bLowerTrack,CFX_Matrix * pMatrix)285 void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics* pGraphics,
286                                  const CFX_RectF* pRect,
287                                  FX_BOOL bVert,
288                                  FWLTHEME_STATE eState,
289                                  FX_BOOL bLowerTrack,
290                                  CFX_Matrix* pMatrix) {
291   if (pRect->IsEmpty()) {
292     return;
293   }
294   CFX_Path path;
295   path.Create();
296   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
297   pGraphics->SaveGraphState();
298   CFX_Color clrFill(0xFFF0F0F0);
299   pGraphics->SetFillColor(&clrFill);
300   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
301   pGraphics->RestoreGraphState();
302 }
DrawMaxMinBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)303 void CFWL_ScrollBarTP::DrawMaxMinBtn(CFX_Graphics* pGraphics,
304                                      const CFX_RectF* pRect,
305                                      FWLTHEME_DIRECTION eDict,
306                                      FWLTHEME_STATE eState,
307                                      CFX_Matrix* pMatrix) {
308   CFX_RectF rtThumb(*pRect);
309   FX_FLOAT fWidth = eState == FWLTHEME_STATE_Pressed ? 1.0f : 2.0f;
310   FWLTHEME_EDGE eType = eState == FWLTHEME_STATE_Pressed ? FWLTHEME_EDGE_Flat
311                                                          : FWLTHEME_EDGE_Raised;
312   Draw3DRect(pGraphics, eType, fWidth, pRect, FWLTHEME_COLOR_EDGELT1,
313              FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1,
314              FWLTHEME_COLOR_EDGERB2, pMatrix);
315   CFX_Path path;
316   path.Create();
317   path.AddRectangle(pRect->left + fWidth, pRect->top + fWidth,
318                     pRect->width - 2 * fWidth, pRect->height - 2 * fWidth);
319   pGraphics->SaveGraphState();
320   CFX_Color crFill(FWLTHEME_COLOR_Background);
321   pGraphics->SetFillColor(&crFill);
322   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
323   pGraphics->RestoreGraphState();
324   DrawArrow(pGraphics, pRect, eDict,
325             eState == FWLTHEME_STATE_Disabale ? 0xFFA0A0A0 : 0xFF000000,
326             eState == FWLTHEME_STATE_Pressed, pMatrix);
327 }
328 #endif
SetThemeData(FX_DWORD dwID)329 void CFWL_ScrollBarTP::SetThemeData(FX_DWORD dwID) {
330   m_pThemeData->clrPawColorLight[3] = ArgbEncode(0xff, 208, 223, 172);
331   m_pThemeData->clrPawColorDark[3] = ArgbEncode(0xff, 140, 157, 115);
332   m_pThemeData->clrBtnBK[3][0] = ArgbEncode(0xff, 164, 180, 139);
333   m_pThemeData->clrBtnBK[3][1] = ArgbEncode(0xff, 141, 157, 115);
334   m_pThemeData->clrBtnBorder[3] = ArgbEncode(0xff, 236, 233, 216);
335   if (dwID) {
336     m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 208, 223, 172);
337     m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 157, 115);
338     m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 162, 179, 141);
339     m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 149, 167, 117);
340     m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 142, 153, 125);
341     m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 235, 245, 212);
342     m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 182, 198, 142);
343     m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 200, 213, 170);
344     m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 195, 208, 150);
345     m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 189, 203, 150);
346     m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 208, 223, 172);
347     m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 140, 157, 115);
348     m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 164, 180, 139);
349     m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 141, 157, 115);
350     m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 128, 146, 102);
351     m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
352     m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
353   } else {
354     m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 238, 244, 254);
355     m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 176, 248);
356     m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 197, 213, 252);
357     m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 182, 205, 251);
358     m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 148, 176, 221);
359     m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 252, 253, 255);
360     m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 156, 197, 255);
361     m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 216, 232, 255);
362     m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 204, 225, 255);
363     m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 218, 230, 254);
364     m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 207, 221, 253);
365     m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 131, 158, 216);
366     m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 167, 190, 245);
367     m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 146, 179, 249);
368     m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 124, 159, 211);
369     m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
370     m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
371   }
372 }
373