Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxfa / src / app / xfa_ffpushbutton.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../common/xfa_common.h"\r
9 #include "xfa_ffwidget.h"\r
10 #include "xfa_ffwidgetacc.h"\r
11 #include "xfa_fffield.h"\r
12 #include "xfa_ffpageview.h"\r
13 #include "xfa_ffpushbutton.h"\r
14 #include "xfa_textlayout.h"\r
15 #include "xfa_ffapp.h"\r
16 CXFA_FFPushButton::CXFA_FFPushButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)\r
17     : CXFA_FFField(pPageView, pDataAcc)\r
18     , m_pRolloverTextLayout(NULL)\r
19     , m_pDownTextLayout(NULL)\r
20     , m_pDownProvider(NULL)\r
21     , m_pRollProvider(NULL)\r
22     , m_pOldDelegate(NULL)\r
23 {\r
24 }\r
25 CXFA_FFPushButton::~CXFA_FFPushButton()\r
26 {\r
27     CXFA_FFPushButton::UnloadWidget();\r
28 }\r
29 void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )\r
30 {\r
31     if (!IsMatchVisibleStatus(dwStatus)) {\r
32         return;\r
33     }\r
34     CFX_Matrix mtRotate;\r
35     GetRotateMatrix(mtRotate);\r
36     if (pMatrix) {\r
37         mtRotate.Concat(*pMatrix);\r
38     }\r
39     CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);\r
40     RenderHighlightCaption(pGS, &mtRotate);\r
41     CFX_RectF rtWidget;\r
42     GetRectWithoutRotate(rtWidget);\r
43     CFX_Matrix mt;\r
44     mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);\r
45     mt.Concat(mtRotate);\r
46     GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(), pGS, &mt);\r
47 }\r
48 FX_BOOL CXFA_FFPushButton::LoadWidget()\r
49 {\r
50     FXSYS_assert(m_pNormalWidget == NULL);\r
51     CFWL_PushButton* pPushButton = CFWL_PushButton::Create();\r
52     if (pPushButton) {\r
53         pPushButton->Initialize();\r
54     }\r
55     m_pOldDelegate = pPushButton->SetDelegate(this);\r
56     m_pNormalWidget = (CFWL_Widget*)pPushButton;\r
57     IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();\r
58     m_pNormalWidget->SetPrivateData(pWidget, this, NULL);\r
59     IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();\r
60     pNoteDriver->RegisterEventTarget(pWidget, pWidget);\r
61     m_pNormalWidget->LockUpdate();\r
62     UpdateWidgetProperty();\r
63     LoadHighlightCaption();\r
64     m_pNormalWidget->UnlockUpdate();\r
65     return CXFA_FFField::LoadWidget();\r
66 }\r
67 void CXFA_FFPushButton::UpdateWidgetProperty()\r
68 {\r
69     FX_DWORD dwStyleEx = 0;\r
70     switch(m_pDataAcc->GetButtonHighlight()) {\r
71         case XFA_ATTRIBUTEENUM_Inverted:\r
72             dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteInverted;\r
73             break;\r
74         case XFA_ATTRIBUTEENUM_Outline:\r
75             dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteOutLine;\r
76             break;\r
77         case XFA_ATTRIBUTEENUM_Push:\r
78             dwStyleEx = XFA_FWL_PSBSTYLEEXT_HilitePush;\r
79             break;\r
80         default:\r
81             break;\r
82     }\r
83     m_pNormalWidget->ModifyStylesEx(dwStyleEx, 0xFFFFFFFF);\r
84 }\r
85 void CXFA_FFPushButton::UnloadWidget()\r
86 {\r
87     if (m_pRolloverTextLayout) {\r
88         delete m_pRolloverTextLayout;\r
89         m_pRolloverTextLayout = NULL;\r
90     }\r
91     if (m_pDownTextLayout) {\r
92         delete m_pDownTextLayout;\r
93         m_pDownTextLayout = NULL;\r
94     }\r
95     if (m_pDownProvider) {\r
96         delete m_pDownProvider;\r
97         m_pDownProvider = NULL;\r
98     }\r
99     if (m_pRollProvider) {\r
100         delete m_pRollProvider;\r
101         m_pRollProvider = NULL;\r
102     }\r
103     CXFA_FFField::UnloadWidget();\r
104 }\r
105 FX_BOOL CXFA_FFPushButton::LayoutWidget()\r
106 {\r
107     CXFA_FFWidget::LayoutWidget();\r
108     CFX_RectF rtWidget;\r
109     GetRectWithoutRotate(rtWidget);\r
110     m_rtUI = rtWidget;\r
111     if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {\r
112         XFA_RectWidthoutMargin(rtWidget, mgWidget);\r
113     }\r
114     CXFA_Caption caption = m_pDataAcc->GetCaption();\r
115     m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);\r
116     if (CXFA_Margin mgCap = caption.GetMargin()) {\r
117         XFA_RectWidthoutMargin(m_rtCaption, mgCap);\r
118     }\r
119     LayoutHighlightCaption();\r
120     SetFWLRect();\r
121     if (m_pNormalWidget) {\r
122         m_pNormalWidget->Update();\r
123     }\r
124     return TRUE;\r
125 }\r
126 FX_FLOAT CXFA_FFPushButton::GetLineWidth()\r
127 {\r
128     CXFA_Border border = m_pDataAcc->GetBorder();\r
129     if (border.IsExistInXML() && (border.GetPresence() == XFA_ATTRIBUTEENUM_Visible)) {\r
130         CXFA_Edge edge = border.GetEdge(0);\r
131         return edge.GetThickness();\r
132     }\r
133     return 0;\r
134 }\r
135 FX_ARGB CXFA_FFPushButton::GetLineColor()\r
136 {\r
137     return 0xFF000000;\r
138 }\r
139 FX_ARGB CXFA_FFPushButton::GetFillColor()\r
140 {\r
141     return 0xFFFFFFFF;\r
142 }\r
143 void CXFA_FFPushButton::LoadHighlightCaption()\r
144 {\r
145     CXFA_Caption caption = m_pDataAcc->GetCaption();\r
146     if (caption.IsExistInXML() && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {\r
147         {\r
148             CFX_WideString wsRollover;\r
149             FX_BOOL bRichText;\r
150             if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) {\r
151                 if (m_pRollProvider == NULL) {\r
152                     m_pRollProvider = FX_NEW CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Rollover);\r
153                 }\r
154                 m_pRolloverTextLayout = FX_NEW CXFA_TextLayout(m_pRollProvider);\r
155             }\r
156             CFX_WideString wsDown;\r
157             if (m_pDataAcc->GetButtonDown(wsDown, bRichText)) {\r
158                 if (m_pDownProvider == NULL) {\r
159                     m_pDownProvider = FX_NEW CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Down);\r
160                 }\r
161                 m_pDownTextLayout = FX_NEW CXFA_TextLayout(m_pDownProvider);\r
162             }\r
163         }\r
164     }\r
165 }\r
166 void CXFA_FFPushButton::LayoutHighlightCaption()\r
167 {\r
168     CFX_SizeF sz;\r
169     sz.Set(m_rtCaption.width, m_rtCaption.height);\r
170     LayoutCaption();\r
171     if (m_pRolloverTextLayout) {\r
172         m_pRolloverTextLayout->Layout(sz);\r
173     }\r
174     if (m_pDownTextLayout) {\r
175         m_pDownTextLayout->Layout(sz);\r
176     }\r
177 }\r
178 void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix )\r
179 {\r
180     CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();\r
181     CXFA_Caption caption = m_pDataAcc->GetCaption();\r
182     if (caption.IsExistInXML() && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {\r
183         CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();\r
184         CFX_RectF rtWidget;\r
185         GetRectWithoutRotate(rtWidget);\r
186         CFX_RectF rtClip = m_rtCaption;\r
187         rtClip.Intersect(rtWidget);\r
188         CFX_Matrix mt;\r
189         mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);\r
190         if (pMatrix) {\r
191             pMatrix->TransformRect(rtClip);\r
192             mt.Concat(*pMatrix);\r
193         }\r
194         {\r
195             FX_DWORD dwState = m_pNormalWidget->GetStates();\r
196             if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) && (dwState & FWL_STATE_PSB_Hovered)) {\r
197                 if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) {\r
198                     return;\r
199                 }\r
200             } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) {\r
201                 if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) {\r
202                     return;\r
203                 }\r
204             }\r
205         }\r
206         if (pCapTextLayout) {\r
207             pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);\r
208         }\r
209     }\r
210 }\r
211 FX_INT32 CXFA_FFPushButton::OnProcessMessage(CFWL_Message *pMessage)\r
212 {\r
213     return m_pOldDelegate->OnProcessMessage(pMessage);\r
214 }\r
215 FWL_ERR  CXFA_FFPushButton::OnProcessEvent(CFWL_Event *pEvent)\r
216 {\r
217     m_pOldDelegate->OnProcessEvent(pEvent);\r
218     return CXFA_FFField::OnProcessEvent(pEvent);\r
219 }\r
220 FWL_ERR CXFA_FFPushButton::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
221 {\r
222     if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) {\r
223         if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {\r
224             CFX_RectF rtFill;\r
225             m_pNormalWidget->GetWidgetRect(rtFill);\r
226             rtFill.left = rtFill.top = 0;\r
227             FX_FLOAT fLineWith =  GetLineWidth();\r
228             rtFill.Deflate(fLineWith, fLineWith);\r
229             CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255));\r
230             pGraphics->SetFillColor(&cr);\r
231             CFX_Path path;\r
232             path.Create();\r
233             path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height);\r
234             pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix);\r
235         }\r
236     } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteOutLine) {\r
237         if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {\r
238             FX_FLOAT fLineWidth = GetLineWidth();\r
239             CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255));\r
240             pGraphics->SetStrokeColor(&cr);\r
241             pGraphics->SetLineWidth(fLineWidth);\r
242             CFX_Path path;\r
243             path.Create();\r
244             CFX_RectF rect;\r
245             m_pNormalWidget->GetWidgetRect(rect);\r
246             path.AddRectangle(0, 0, rect.width, rect.height);\r
247             pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix);\r
248         }\r
249     } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HilitePush) {\r
250     }\r
251     return FWL_ERR_Succeeded;\r
252 }\r