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 PUSHBUTTON_SIZE_Corner 2
9CFWL_PushButtonTP::CFWL_PushButtonTP() {
10  m_pThemeData = new PBThemeData;
11  SetThemeData(0);
12}
13CFWL_PushButtonTP::~CFWL_PushButtonTP() {
14  if (m_pThemeData) {
15    delete m_pThemeData;
16  }
17}
18FX_BOOL CFWL_PushButtonTP::IsValidWidget(IFWL_Widget* pWidget) {
19  return pWidget->GetClassID() == FWL_CLASSHASH_PushButton;
20}
21FX_DWORD CFWL_PushButtonTP::SetThemeID(IFWL_Widget* pWidget,
22                                       FX_DWORD dwThemeID,
23                                       FX_BOOL bChildren) {
24  SetThemeData(FWL_GetThemeColor(dwThemeID));
25  return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
26}
27FX_BOOL CFWL_PushButtonTP::DrawBackground(CFWL_ThemeBackground* pParams) {
28  switch (pParams->m_iPart) {
29    case FWL_PART_PSB_Border: {
30      DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
31      break;
32    }
33    case FWL_PART_PSB_Edge: {
34      DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(),
35               &pParams->m_rtPart, &pParams->m_matrix);
36      break;
37    }
38    case FWL_PART_PSB_Background: {
39      CFX_RectF& rect = pParams->m_rtPart;
40      FX_FLOAT fRight = rect.right();
41      FX_FLOAT fBottom = rect.bottom();
42      CFX_Path strokePath;
43      strokePath.Create();
44      strokePath.MoveTo(rect.left + PUSHBUTTON_SIZE_Corner, rect.top);
45      strokePath.LineTo(fRight - PUSHBUTTON_SIZE_Corner, rect.top);
46      strokePath.LineTo(fRight, rect.top + PUSHBUTTON_SIZE_Corner);
47      strokePath.LineTo(fRight, fBottom - PUSHBUTTON_SIZE_Corner);
48      strokePath.LineTo(fRight - PUSHBUTTON_SIZE_Corner, fBottom);
49      strokePath.LineTo(rect.left + PUSHBUTTON_SIZE_Corner, fBottom);
50      strokePath.LineTo(rect.left, fBottom - PUSHBUTTON_SIZE_Corner);
51      strokePath.LineTo(rect.left, rect.top + PUSHBUTTON_SIZE_Corner);
52      strokePath.LineTo(rect.left + PUSHBUTTON_SIZE_Corner, rect.top);
53      CFX_Path fillPath;
54      fillPath.Create();
55      fillPath.AddSubpath(&strokePath);
56      CFX_Graphics* pGraphics = pParams->m_pGraphics;
57      pGraphics->SaveGraphState();
58      CFX_RectF rtInner(rect);
59      rtInner.Deflate(PUSHBUTTON_SIZE_Corner + 1, PUSHBUTTON_SIZE_Corner + 1,
60                      PUSHBUTTON_SIZE_Corner, PUSHBUTTON_SIZE_Corner);
61      fillPath.AddRectangle(rtInner.left, rtInner.top, rtInner.width,
62                            rtInner.height);
63      int32_t iColor = GetColorID(pParams->m_dwStates);
64      DrawAxialShading(pGraphics, rect.left + PUSHBUTTON_SIZE_Corner, rect.top,
65                       rect.left + PUSHBUTTON_SIZE_Corner, rect.bottom(),
66                       m_pThemeData->clrStart[iColor],
67                       m_pThemeData->clrEnd[iColor], &fillPath,
68                       FXFILL_ALTERNATE, &pParams->m_matrix);
69      CFX_Color crStroke(m_pThemeData->clrBorder[iColor]);
70      pGraphics->SetStrokeColor(&crStroke);
71      pGraphics->StrokePath(&strokePath, &pParams->m_matrix);
72      fillPath.Clear();
73      fillPath.AddRectangle(rtInner.left, rtInner.top, rtInner.width,
74                            rtInner.height);
75      CFX_Color crFill(m_pThemeData->clrFill[iColor]);
76      pGraphics->SetFillColor(&crFill);
77      pGraphics->FillPath(&fillPath, FXFILL_WINDING, &pParams->m_matrix);
78      if (pParams->m_dwStates & FWL_PARTSTATE_PSB_Focused) {
79        rtInner.Inflate(1, 1, 0, 0);
80        DrawFocus(pGraphics, &rtInner, &pParams->m_matrix);
81      }
82      pGraphics->RestoreGraphState();
83      break;
84    }
85    default: {}
86  }
87  return TRUE;
88}
89void* CFWL_PushButtonTP::GetCapacity(CFWL_ThemePart* pThemePart,
90                                     FX_DWORD dwCapacity) {
91  if (dwCapacity == FWL_WGTCAPACITY_PSB_Margin) {
92    m_fValue = 0;
93    return &m_fValue;
94  }
95  return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
96}
97FWL_ERR CFWL_PushButtonTP::Initialize() {
98  InitTTO();
99  return CFWL_WidgetTP::Initialize();
100}
101FWL_ERR CFWL_PushButtonTP::Finalize() {
102  FinalizeTTO();
103  return CFWL_WidgetTP::Finalize();
104}
105void CFWL_PushButtonTP::SetThemeData(FX_DWORD dwID) {
106  if (dwID) {
107    m_pThemeData->clrBorder[0] = ArgbEncode(255, 55, 98, 6);
108    m_pThemeData->clrBorder[1] = ArgbEncode(255, 55, 98, 6);
109    m_pThemeData->clrBorder[2] = ArgbEncode(255, 55, 98, 6);
110    m_pThemeData->clrBorder[3] = ArgbEncode(255, 55, 98, 6);
111    m_pThemeData->clrBorder[4] = ArgbEncode(255, 172, 168, 153);
112    m_pThemeData->clrStart[0] = ArgbEncode(255, 255, 255, 246);
113    m_pThemeData->clrStart[1] = ArgbEncode(255, 223, 205, 180);
114    m_pThemeData->clrStart[2] = ArgbEncode(255, 252, 197, 149);
115    m_pThemeData->clrStart[3] = ArgbEncode(255, 194, 209, 143);
116    m_pThemeData->clrStart[4] = ArgbEncode(255, 216, 216, 216);
117    m_pThemeData->clrEnd[0] = ArgbEncode(255, 227, 209, 184);
118    m_pThemeData->clrEnd[1] = ArgbEncode(255, 248, 244, 228);
119    m_pThemeData->clrEnd[2] = ArgbEncode(255, 207, 114, 37);
120    m_pThemeData->clrEnd[3] = ArgbEncode(255, 144, 193, 84);
121    m_pThemeData->clrEnd[4] = ArgbEncode(255, 172, 168, 153);
122    m_pThemeData->clrFill[0] = ArgbEncode(255, 255, 255, 255);
123    m_pThemeData->clrFill[1] = ArgbEncode(255, 226, 225, 218);
124    m_pThemeData->clrFill[2] = ArgbEncode(255, 255, 255, 255);
125    m_pThemeData->clrFill[3] = ArgbEncode(255, 255, 255, 255);
126    m_pThemeData->clrFill[4] = ArgbEncode(255, 245, 244, 234);
127  } else {
128    m_pThemeData->clrBorder[0] = ArgbEncode(255, 0, 60, 116);
129    m_pThemeData->clrBorder[1] = ArgbEncode(255, 0, 60, 116);
130    m_pThemeData->clrBorder[2] = ArgbEncode(255, 0, 60, 116);
131    m_pThemeData->clrBorder[3] = ArgbEncode(255, 0, 60, 116);
132    m_pThemeData->clrBorder[4] = ArgbEncode(255, 201, 199, 186);
133    m_pThemeData->clrStart[0] = ArgbEncode(255, 255, 255, 255);
134    m_pThemeData->clrStart[1] = ArgbEncode(255, 209, 204, 193);
135    m_pThemeData->clrStart[2] = ArgbEncode(255, 255, 240, 207);
136    m_pThemeData->clrStart[3] = ArgbEncode(255, 206, 231, 255);
137    m_pThemeData->clrStart[4] = ArgbEncode(255, 245, 244, 234);
138    m_pThemeData->clrEnd[0] = ArgbEncode(255, 214, 208, 197);
139    m_pThemeData->clrEnd[1] = ArgbEncode(255, 242, 241, 238);
140    m_pThemeData->clrEnd[2] = ArgbEncode(255, 229, 151, 0);
141    m_pThemeData->clrEnd[3] = ArgbEncode(255, 105, 130, 238);
142    m_pThemeData->clrEnd[4] = ArgbEncode(255, 245, 244, 234);
143    m_pThemeData->clrFill[0] = ArgbEncode(255, 255, 255, 255);
144    m_pThemeData->clrFill[1] = ArgbEncode(255, 226, 225, 218);
145    m_pThemeData->clrFill[2] = ArgbEncode(255, 255, 255, 255);
146    m_pThemeData->clrFill[3] = ArgbEncode(255, 255, 255, 255);
147    m_pThemeData->clrFill[4] = ArgbEncode(255, 245, 244, 234);
148  }
149}
150int32_t CFWL_PushButtonTP::GetColorID(FX_DWORD dwStates) {
151  return dwStates &= FWL_PARTSTATE_PSB_Mask;
152}
153