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 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
9 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
10 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
13 
MakeWidgetImpProperties(IFWL_DataProvider * pDataProvider) const14 CFWL_WidgetImpProperties CFWL_WidgetProperties::MakeWidgetImpProperties(
15     IFWL_DataProvider* pDataProvider) const {
16   CFWL_WidgetImpProperties result;
17   result.m_ctmOnParent = m_ctmOnParent;
18   result.m_rtWidget = m_rtWidget;
19   result.m_dwStyles = m_dwStyles;
20   result.m_dwStyleExes = m_dwStyleExes;
21   result.m_dwStates = m_dwStates;
22   if (m_pParent)
23     result.m_pParent = m_pParent->GetWidget();
24   if (m_pOwner)
25     result.m_pOwner = m_pOwner->GetWidget();
26   result.m_pDataProvider = pDataProvider;
27   return result;
28 }
GetWidget()29 IFWL_Widget* CFWL_Widget::GetWidget() {
30   return m_pIface;
31 }
GetClassName(CFX_WideString & wsClass) const32 FWL_ERR CFWL_Widget::GetClassName(CFX_WideString& wsClass) const {
33   if (!m_pIface)
34     return FWL_ERR_Indefinite;
35   return m_pIface->GetClassName(wsClass);
36 }
GetClassID() const37 FX_DWORD CFWL_Widget::GetClassID() const {
38   if (!m_pIface)
39     return 0;
40   return m_pIface->GetClassID();
41 }
IsInstance(const CFX_WideStringC & wsClass) const42 FX_BOOL CFWL_Widget::IsInstance(const CFX_WideStringC& wsClass) const {
43   if (!m_pIface)
44     return FALSE;
45   return m_pIface->IsInstance(wsClass);
46 }
47 static void* gs_pFWLWidget = (void*)FXBSTR_ID('l', 'i', 'g', 't');
Initialize(const CFWL_WidgetProperties * pProperties)48 FWL_ERR CFWL_Widget::Initialize(const CFWL_WidgetProperties* pProperties) {
49   if (!m_pIface)
50     return FWL_ERR_Indefinite;
51   return m_pIface->SetPrivateData(gs_pFWLWidget, this, NULL);
52 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)53 FWL_ERR CFWL_Widget::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
54   if (!m_pIface)
55     return FWL_ERR_Indefinite;
56   return m_pIface->GetWidgetRect(rect, bAutoSize);
57 }
GetGlobalRect(CFX_RectF & rect)58 FWL_ERR CFWL_Widget::GetGlobalRect(CFX_RectF& rect) {
59   if (!m_pIface)
60     return FWL_ERR_Indefinite;
61   return m_pIface->GetGlobalRect(rect);
62 }
SetWidgetRect(const CFX_RectF & rect)63 FWL_ERR CFWL_Widget::SetWidgetRect(const CFX_RectF& rect) {
64   if (!m_pIface)
65     return FWL_ERR_Indefinite;
66   return m_pIface->SetWidgetRect(rect);
67 }
GetClientRect(CFX_RectF & rect)68 FWL_ERR CFWL_Widget::GetClientRect(CFX_RectF& rect) {
69   if (!m_pIface)
70     return FWL_ERR_Indefinite;
71   return m_pIface->GetClientRect(rect);
72 }
GetParent()73 CFWL_Widget* CFWL_Widget::GetParent() {
74   if (!m_pIface)
75     return NULL;
76   IFWL_Widget* parent = m_pIface->GetParent();
77   if (parent) {
78     return static_cast<CFWL_Widget*>(parent->GetPrivateData(gs_pFWLWidget));
79   }
80   return NULL;
81 }
SetParent(CFWL_Widget * pParent)82 FWL_ERR CFWL_Widget::SetParent(CFWL_Widget* pParent) {
83   if (!m_pIface)
84     return FWL_ERR_Indefinite;
85   return m_pIface->SetParent(pParent ? pParent->GetWidget() : NULL);
86 }
GetOwner()87 CFWL_Widget* CFWL_Widget::GetOwner() {
88   if (!m_pIface)
89     return NULL;
90   return NULL;
91 }
SetOwner(CFWL_Widget * pOwner)92 FWL_ERR CFWL_Widget::SetOwner(CFWL_Widget* pOwner) {
93   if (!m_pIface)
94     return FWL_ERR_Indefinite;
95   return FWL_ERR_Succeeded;
96 }
GetStyles()97 FX_DWORD CFWL_Widget::GetStyles() {
98   if (!m_pIface)
99     return 0;
100   return m_pIface->GetStyles();
101 }
ModifyStyles(FX_DWORD dwStylesAdded,FX_DWORD dwStylesRemoved)102 FWL_ERR CFWL_Widget::ModifyStyles(FX_DWORD dwStylesAdded,
103                                   FX_DWORD dwStylesRemoved) {
104   if (!m_pIface)
105     return FWL_ERR_Indefinite;
106   return m_pIface->ModifyStyles(dwStylesAdded, dwStylesRemoved);
107 }
GetStylesEx()108 FX_DWORD CFWL_Widget::GetStylesEx() {
109   if (!m_pIface)
110     return 0;
111   return m_pIface->GetStylesEx();
112 }
ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)113 FWL_ERR CFWL_Widget::ModifyStylesEx(FX_DWORD dwStylesExAdded,
114                                     FX_DWORD dwStylesExRemoved) {
115   return m_pIface->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
116 }
GetStates()117 FX_DWORD CFWL_Widget::GetStates() {
118   if (!m_pIface)
119     return FWL_ERR_Indefinite;
120   return m_pIface->GetStates();
121 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)122 FWL_ERR CFWL_Widget::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
123   if (!m_pIface)
124     return FWL_ERR_Indefinite;
125   return m_pIface->SetStates(dwStates, bSet);
126 }
SetPrivateData(void * module_id,void * pData,PD_CALLBACK_FREEDATA callback)127 FWL_ERR CFWL_Widget::SetPrivateData(void* module_id,
128                                     void* pData,
129                                     PD_CALLBACK_FREEDATA callback) {
130   if (!m_pIface)
131     return FWL_ERR_Indefinite;
132   return m_pIface->SetPrivateData(module_id, pData, callback);
133 }
GetPrivateData(void * module_id)134 void* CFWL_Widget::GetPrivateData(void* module_id) {
135   if (!m_pIface)
136     return NULL;
137   return m_pIface->GetPrivateData(module_id);
138 }
Update()139 FWL_ERR CFWL_Widget::Update() {
140   if (!m_pIface)
141     return FWL_ERR_Indefinite;
142   return m_pIface->Update();
143 }
LockUpdate()144 FWL_ERR CFWL_Widget::LockUpdate() {
145   if (!m_pIface)
146     return FWL_ERR_Indefinite;
147   return m_pIface->LockUpdate();
148 }
UnlockUpdate()149 FWL_ERR CFWL_Widget::UnlockUpdate() {
150   if (!m_pIface)
151     return FWL_ERR_Indefinite;
152   return m_pIface->UnlockUpdate();
153 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)154 FX_DWORD CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
155   if (!m_pIface)
156     return 0;
157   return m_pIface->HitTest(fx, fy);
158 }
TransformTo(CFWL_Widget * pWidget,FX_FLOAT & fx,FX_FLOAT & fy)159 FWL_ERR CFWL_Widget::TransformTo(CFWL_Widget* pWidget,
160                                  FX_FLOAT& fx,
161                                  FX_FLOAT& fy) {
162   if (!m_pIface)
163     return FWL_ERR_Indefinite;
164   return m_pIface->TransformTo(pWidget ? pWidget->GetWidget() : NULL, fx, fy);
165 }
TransformTo(CFWL_Widget * pWidget,CFX_RectF & rt)166 FWL_ERR CFWL_Widget::TransformTo(CFWL_Widget* pWidget, CFX_RectF& rt) {
167   if (!m_pIface)
168     return FWL_ERR_Indefinite;
169   return m_pIface->TransformTo(pWidget ? pWidget->GetWidget() : NULL, rt);
170 }
GetMatrix(CFX_Matrix & matrix,FX_BOOL bGlobal)171 FWL_ERR CFWL_Widget::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
172   if (!m_pIface)
173     return FWL_ERR_Indefinite;
174   return m_pIface->GetMatrix(matrix, bGlobal);
175 }
SetMatrix(const CFX_Matrix & matrix)176 FWL_ERR CFWL_Widget::SetMatrix(const CFX_Matrix& matrix) {
177   if (!m_pIface)
178     return FWL_ERR_Indefinite;
179   return m_pIface->SetMatrix(matrix);
180 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)181 FWL_ERR CFWL_Widget::DrawWidget(CFX_Graphics* pGraphics,
182                                 const CFX_Matrix* pMatrix) {
183   if (!m_pIface)
184     return FWL_ERR_Indefinite;
185   return m_pIface->DrawWidget(pGraphics, pMatrix);
186 }
SetDelegate(IFWL_WidgetDelegate * pDelegate)187 IFWL_WidgetDelegate* CFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) {
188   if (!m_pIface)
189     return NULL;
190   m_pDelegate = m_pIface->SetDelegate(pDelegate);
191   return m_pDelegate;
192 }
CFWL_Widget()193 CFWL_Widget::CFWL_Widget()
194     : m_pIface(NULL), m_pDelegate(NULL), m_pProperties(NULL) {
195   m_pProperties = new CFWL_WidgetProperties;
196   m_pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
197   FXSYS_assert(m_pWidgetMgr != NULL);
198 }
~CFWL_Widget()199 CFWL_Widget::~CFWL_Widget() {
200   delete m_pProperties;
201   if (m_pIface) {
202     m_pIface->Finalize();
203     delete m_pIface;
204   }
205 }
Repaint(const CFX_RectF * pRect)206 FWL_ERR CFWL_Widget::Repaint(const CFX_RectF* pRect) {
207   if (!m_pIface)
208     return FWL_ERR_Indefinite;
209   CFX_RectF rect;
210   if (pRect) {
211     rect = *pRect;
212   } else {
213     m_pIface->GetWidgetRect(rect);
214     rect.left = rect.top = 0;
215   }
216   return m_pWidgetMgr->RepaintWidget(m_pIface, &rect);
217 }
SetFocus(FX_BOOL bFocus)218 FWL_ERR CFWL_Widget::SetFocus(FX_BOOL bFocus) {
219   if (!m_pIface)
220     return FWL_ERR_Indefinite;
221   IFWL_NoteThread* pThread = m_pIface->GetOwnerThread();
222   if (!pThread)
223     return FWL_ERR_Indefinite;
224   IFWL_NoteDriver* pDriver = pThread->GetNoteDriver();
225   if (!pDriver)
226     return FWL_ERR_Indefinite;
227   if (bFocus) {
228     pDriver->SetFocus(m_pIface);
229   } else {
230     if (pDriver->GetFocus() == m_pIface) {
231       pDriver->SetFocus(NULL);
232     }
233   }
234   return FWL_ERR_Succeeded;
235 }
SetGrab(FX_BOOL bSet)236 FWL_ERR CFWL_Widget::SetGrab(FX_BOOL bSet) {
237   if (!m_pIface)
238     return FWL_ERR_Indefinite;
239   IFWL_NoteThread* pThread = m_pIface->GetOwnerThread();
240   if (!pThread)
241     return FWL_ERR_Indefinite;
242   IFWL_NoteDriver* pDriver = pThread->GetNoteDriver();
243   if (!pDriver)
244     return FWL_ERR_Indefinite;
245   pDriver->SetGrab(m_pIface, bSet);
246   return FWL_ERR_Succeeded;
247 }
RegisterEventTarget(CFWL_Widget * pEventSource,FX_DWORD dwFilter)248 void CFWL_Widget::RegisterEventTarget(CFWL_Widget* pEventSource,
249                                       FX_DWORD dwFilter) {
250   if (!m_pIface)
251     return;
252   IFWL_NoteThread* pThread = m_pIface->GetOwnerThread();
253   if (!pThread)
254     return;
255   IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
256   if (!pNoteDriver)
257     return;
258   IFWL_Widget* pEventSourceImp =
259       !pEventSource ? NULL : pEventSource->GetWidget();
260   pNoteDriver->RegisterEventTarget(GetWidget(), pEventSourceImp, dwFilter);
261 }
DispatchEvent(CFWL_Event * pEvent)262 void CFWL_Widget::DispatchEvent(CFWL_Event* pEvent) {
263   if (!m_pIface)
264     return;
265   if (m_pIface->GetOuter()) {
266     return;
267   }
268   IFWL_NoteThread* pThread = m_pIface->GetOwnerThread();
269   if (!pThread)
270     return;
271   IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
272   if (!pNoteDriver)
273     return;
274   pNoteDriver->SendNote(pEvent);
275 }
276 #define FWL_WGT_CalcHeight 2048
277 #define FWL_WGT_CalcWidth 2048
278 #define FWL_WGT_CalcMultiLineDefWidth 120.0f
CalcTextSize(const CFX_WideString & wsText,FX_BOOL bMultiLine,int32_t iLineWidth)279 CFX_SizeF CFWL_Widget::CalcTextSize(const CFX_WideString& wsText,
280                                     FX_BOOL bMultiLine,
281                                     int32_t iLineWidth) {
282   CFX_SizeF sz;
283   sz.Set(0, 0);
284   if (!m_pIface)
285     return sz;
286   IFWL_ThemeProvider* pTheme = m_pIface->GetThemeProvider();
287   if (!pTheme)
288     return sz;
289   CFWL_ThemeText calPart;
290   calPart.m_pWidget = m_pIface;
291   calPart.m_wsText = wsText;
292   calPart.m_dwTTOStyles =
293       bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
294   calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
295   CFX_RectF rect;
296   FX_FLOAT fWidth = bMultiLine
297                         ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth
298                                           : FWL_WGT_CalcMultiLineDefWidth)
299                         : FWL_WGT_CalcWidth;
300   rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight);
301   pTheme->CalcTextRect(&calPart, rect);
302   sz.x = rect.width;
303   sz.y = rect.height;
304   return sz;
305 }
CFWL_WidgetDelegate()306 CFWL_WidgetDelegate::CFWL_WidgetDelegate() {}
~CFWL_WidgetDelegate()307 CFWL_WidgetDelegate::~CFWL_WidgetDelegate() {}
OnProcessMessage(CFWL_Message * pMessage)308 int32_t CFWL_WidgetDelegate::OnProcessMessage(CFWL_Message* pMessage) {
309   return 1;
310 }
OnProcessEvent(CFWL_Event * pEvent)311 FWL_ERR CFWL_WidgetDelegate::OnProcessEvent(CFWL_Event* pEvent) {
312   return FWL_ERR_Succeeded;
313 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)314 FWL_ERR CFWL_WidgetDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
315                                           const CFX_Matrix* pMatrix) {
316   return FWL_ERR_Succeeded;
317 }
318