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 <algorithm>
8
9 #include "xfa/src/foxitlib.h"
10 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
13 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
14 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
15 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)16 FWL_ERR IFWL_Widget::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
17 return static_cast<CFWL_WidgetImp*>(GetImpl())
18 ->GetWidgetRect(rect, bAutoSize);
19 }
GetGlobalRect(CFX_RectF & rect)20 FWL_ERR IFWL_Widget::GetGlobalRect(CFX_RectF& rect) {
21 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetGlobalRect(rect);
22 }
SetWidgetRect(const CFX_RectF & rect)23 FWL_ERR IFWL_Widget::SetWidgetRect(const CFX_RectF& rect) {
24 return static_cast<CFWL_WidgetImp*>(GetImpl())->SetWidgetRect(rect);
25 }
GetClientRect(CFX_RectF & rect)26 FWL_ERR IFWL_Widget::GetClientRect(CFX_RectF& rect) {
27 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetClientRect(rect);
28 }
GetParent()29 IFWL_Widget* IFWL_Widget::GetParent() {
30 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetParent();
31 }
SetParent(IFWL_Widget * pParent)32 FWL_ERR IFWL_Widget::SetParent(IFWL_Widget* pParent) {
33 return static_cast<CFWL_WidgetImp*>(GetImpl())->SetParent(pParent);
34 }
GetOwner()35 IFWL_Widget* IFWL_Widget::GetOwner() {
36 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOwner();
37 }
SetOwner(IFWL_Widget * pOwner)38 FWL_ERR IFWL_Widget::SetOwner(IFWL_Widget* pOwner) {
39 return static_cast<CFWL_WidgetImp*>(GetImpl())->SetOwner(pOwner);
40 }
GetOuter()41 IFWL_Widget* IFWL_Widget::GetOuter() {
42 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOuter();
43 }
GetStyles()44 FX_DWORD IFWL_Widget::GetStyles() {
45 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStyles();
46 }
ModifyStyles(FX_DWORD dwStylesAdded,FX_DWORD dwStylesRemoved)47 FWL_ERR IFWL_Widget::ModifyStyles(FX_DWORD dwStylesAdded,
48 FX_DWORD dwStylesRemoved) {
49 return static_cast<CFWL_WidgetImp*>(GetImpl())
50 ->ModifyStyles(dwStylesAdded, dwStylesRemoved);
51 }
GetStylesEx()52 FX_DWORD IFWL_Widget::GetStylesEx() {
53 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStylesEx();
54 }
ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)55 FWL_ERR IFWL_Widget::ModifyStylesEx(FX_DWORD dwStylesExAdded,
56 FX_DWORD dwStylesExRemoved) {
57 return static_cast<CFWL_WidgetImp*>(GetImpl())
58 ->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
59 }
GetStates()60 FX_DWORD IFWL_Widget::GetStates() {
61 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStates();
62 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)63 FWL_ERR IFWL_Widget::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
64 return static_cast<CFWL_WidgetImp*>(GetImpl())->SetStates(dwStates, bSet);
65 }
SetPrivateData(void * module_id,void * pData,PD_CALLBACK_FREEDATA callback)66 FWL_ERR IFWL_Widget::SetPrivateData(void* module_id,
67 void* pData,
68 PD_CALLBACK_FREEDATA callback) {
69 return static_cast<CFWL_WidgetImp*>(GetImpl())
70 ->SetPrivateData(module_id, pData, callback);
71 }
GetPrivateData(void * module_id)72 void* IFWL_Widget::GetPrivateData(void* module_id) {
73 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetPrivateData(module_id);
74 }
Update()75 FWL_ERR IFWL_Widget::Update() {
76 return static_cast<CFWL_WidgetImp*>(GetImpl())->Update();
77 }
LockUpdate()78 FWL_ERR IFWL_Widget::LockUpdate() {
79 return static_cast<CFWL_WidgetImp*>(GetImpl())->LockUpdate();
80 }
UnlockUpdate()81 FWL_ERR IFWL_Widget::UnlockUpdate() {
82 return static_cast<CFWL_WidgetImp*>(GetImpl())->UnlockUpdate();
83 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)84 FX_DWORD IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
85 return static_cast<CFWL_WidgetImp*>(GetImpl())->HitTest(fx, fy);
86 }
TransformTo(IFWL_Widget * pWidget,FX_FLOAT & fx,FX_FLOAT & fy)87 FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget* pWidget,
88 FX_FLOAT& fx,
89 FX_FLOAT& fy) {
90 return static_cast<CFWL_WidgetImp*>(GetImpl())->TransformTo(pWidget, fx, fy);
91 }
TransformTo(IFWL_Widget * pWidget,CFX_RectF & rt)92 FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
93 return static_cast<CFWL_WidgetImp*>(GetImpl())->TransformTo(pWidget, rt);
94 }
GetMatrix(CFX_Matrix & matrix,FX_BOOL bGlobal)95 FWL_ERR IFWL_Widget::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
96 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetMatrix(matrix, bGlobal);
97 }
SetMatrix(const CFX_Matrix & matrix)98 FWL_ERR IFWL_Widget::SetMatrix(const CFX_Matrix& matrix) {
99 return static_cast<CFWL_WidgetImp*>(GetImpl())->SetMatrix(matrix);
100 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)101 FWL_ERR IFWL_Widget::DrawWidget(CFX_Graphics* pGraphics,
102 const CFX_Matrix* pMatrix) {
103 return static_cast<CFWL_WidgetImp*>(GetImpl())
104 ->DrawWidget(pGraphics, pMatrix);
105 }
GetThemeProvider()106 IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider() {
107 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetThemeProvider();
108 }
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)109 FWL_ERR IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
110 return static_cast<CFWL_WidgetImp*>(GetImpl())
111 ->SetThemeProvider(pThemeProvider);
112 }
SetDataProvider(IFWL_DataProvider * pDataProvider)113 FWL_ERR IFWL_Widget::SetDataProvider(IFWL_DataProvider* pDataProvider) {
114 return static_cast<CFWL_WidgetImp*>(GetImpl())
115 ->SetDataProvider(pDataProvider);
116 }
SetDelegate(IFWL_WidgetDelegate * pDelegate)117 IFWL_WidgetDelegate* IFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) {
118 return static_cast<CFWL_WidgetImp*>(GetImpl())->SetDelegate(pDelegate);
119 }
GetOwnerThread() const120 IFWL_NoteThread* IFWL_Widget::GetOwnerThread() const {
121 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOwnerThread();
122 }
GetOffsetFromParent(IFWL_Widget * pParent)123 CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) {
124 return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOffsetFromParent(pParent);
125 }
Initialize()126 FWL_ERR CFWL_WidgetImp::Initialize() {
127 IFWL_App* pApp = FWL_GetApp();
128 if (!pApp)
129 return FWL_ERR_Indefinite;
130 IFWL_AdapterNative* pAdapter = pApp->GetAdapterNative();
131 if (!pAdapter)
132 return FWL_ERR_Indefinite;
133 IFWL_AdapterThreadMgr* pAdapterThread = pAdapter->GetThreadMgr();
134 if (!pAdapterThread)
135 return FWL_ERR_Indefinite;
136 SetOwnerThread(static_cast<CFWL_NoteThreadImp*>(
137 pAdapterThread->GetCurrentThread()->GetImpl()));
138 IFWL_Widget* pParent = m_pProperties->m_pParent;
139 m_pWidgetMgr->InsertWidget(pParent, m_pInterface);
140 if (!IsChild()) {
141 {
142 IFWL_Widget* pOwner = m_pProperties->m_pOwner;
143 if (pOwner) {
144 m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
145 }
146 }
147 m_pWidgetMgr->CreateWidget_Native(m_pInterface);
148 }
149 return FWL_ERR_Succeeded;
150 }
Finalize()151 FWL_ERR CFWL_WidgetImp::Finalize() {
152 NotifyDriver();
153 IFWL_Form* pForm = static_cast<IFWL_Form*>(
154 FWL_GetWidgetMgr()->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm));
155 if (pForm && pForm != m_pInterface) {
156 IFWL_Content* pContent = pForm->GetContent();
157 if (pContent) {
158 pContent->RemoveWidget(m_pInterface);
159 }
160 }
161 if (!IsChild()) {
162 m_pWidgetMgr->DestroyWidget_Native(m_pInterface);
163 }
164 m_pWidgetMgr->RemoveWidget(m_pInterface);
165 return FWL_ERR_Succeeded;
166 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)167 FWL_ERR CFWL_WidgetImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
168 if (bAutoSize) {
169 if (HasEdge()) {
170 FX_FLOAT fEdge = GetEdgeWidth();
171 rect.Inflate(fEdge, fEdge);
172 }
173 if (HasBorder()) {
174 FX_FLOAT fBorder = GetBorderSize();
175 rect.Inflate(fBorder, fBorder);
176 }
177 } else {
178 rect = m_pProperties->m_rtWidget;
179 }
180 return FWL_ERR_Succeeded;
181 }
GetGlobalRect(CFX_RectF & rect)182 FWL_ERR CFWL_WidgetImp::GetGlobalRect(CFX_RectF& rect) {
183 IFWL_Widget* pForm =
184 m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
185 if (!pForm)
186 return FWL_ERR_Indefinite;
187 rect.Set(0, 0, m_pProperties->m_rtWidget.width,
188 m_pProperties->m_rtWidget.height);
189 if (pForm == m_pInterface) {
190 return FWL_ERR_Succeeded;
191 }
192 return TransformTo(pForm, rect);
193 }
SetWidgetRect(const CFX_RectF & rect)194 FWL_ERR CFWL_WidgetImp::SetWidgetRect(const CFX_RectF& rect) {
195 CFX_RectF rtOld = m_pProperties->m_rtWidget;
196 m_pProperties->m_rtWidget = rect;
197 if (IsChild()) {
198 if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f ||
199 FXSYS_fabs(rtOld.height - rect.height) > 0.5f) {
200 CFWL_EvtSizeChanged ev;
201 ev.m_pSrcTarget = m_pInterface;
202 ev.m_rtOld = rtOld;
203 ev.m_rtNew = rect;
204 IFWL_WidgetDelegate* pDelegate = SetDelegate(NULL);
205 if (pDelegate) {
206 pDelegate->OnProcessEvent(&ev);
207 }
208 }
209 return FWL_ERR_Succeeded;
210 }
211 m_pWidgetMgr->SetWidgetRect_Native(m_pInterface, rect);
212 return FWL_ERR_Succeeded;
213 }
GetClientRect(CFX_RectF & rect)214 FWL_ERR CFWL_WidgetImp::GetClientRect(CFX_RectF& rect) {
215 GetEdgeRect(rect);
216 if (HasEdge()) {
217 FX_FLOAT fEdge = GetEdgeWidth();
218 rect.Deflate(fEdge, fEdge);
219 }
220 return FWL_ERR_Succeeded;
221 }
GetParent()222 IFWL_Widget* CFWL_WidgetImp::GetParent() {
223 return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Parent);
224 }
SetParent(IFWL_Widget * pParent)225 FWL_ERR CFWL_WidgetImp::SetParent(IFWL_Widget* pParent) {
226 m_pProperties->m_pParent = pParent;
227 m_pWidgetMgr->SetParent(pParent, m_pInterface);
228 return FWL_ERR_Succeeded;
229 }
GetOwner()230 IFWL_Widget* CFWL_WidgetImp::GetOwner() {
231 return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Owner);
232 }
SetOwner(IFWL_Widget * pOwner)233 FWL_ERR CFWL_WidgetImp::SetOwner(IFWL_Widget* pOwner) {
234 m_pProperties->m_pOwner = pOwner;
235 m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
236 return FWL_ERR_Succeeded;
237 }
GetOuter()238 IFWL_Widget* CFWL_WidgetImp::GetOuter() {
239 return m_pOuter;
240 }
GetStyles()241 FX_DWORD CFWL_WidgetImp::GetStyles() {
242 return m_pProperties->m_dwStyles;
243 }
ModifyStyles(FX_DWORD dwStylesAdded,FX_DWORD dwStylesRemoved)244 FWL_ERR CFWL_WidgetImp::ModifyStyles(FX_DWORD dwStylesAdded,
245 FX_DWORD dwStylesRemoved) {
246 m_pProperties->m_dwStyles =
247 (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded;
248 return FWL_ERR_Succeeded;
249 }
GetStylesEx()250 FX_DWORD CFWL_WidgetImp::GetStylesEx() {
251 return m_pProperties->m_dwStyleExes;
252 }
ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)253 FWL_ERR CFWL_WidgetImp::ModifyStylesEx(FX_DWORD dwStylesExAdded,
254 FX_DWORD dwStylesExRemoved) {
255 m_pProperties->m_dwStyleExes =
256 (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded;
257 return FWL_ERR_Succeeded;
258 }
GetStates()259 FX_DWORD CFWL_WidgetImp::GetStates() {
260 return m_pProperties->m_dwStates;
261 }
NotifyHideChildWidget(IFWL_WidgetMgr * widgetMgr,IFWL_Widget * widget,CFWL_NoteDriver * noteDriver)262 static void NotifyHideChildWidget(IFWL_WidgetMgr* widgetMgr,
263 IFWL_Widget* widget,
264 CFWL_NoteDriver* noteDriver) {
265 IFWL_Widget* child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
266 while (child) {
267 noteDriver->NotifyTargetHide(child);
268 NotifyHideChildWidget(widgetMgr, child, noteDriver);
269 child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
270 }
271 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)272 FWL_ERR CFWL_WidgetImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
273 bSet ? (m_pProperties->m_dwStates |= dwStates)
274 : (m_pProperties->m_dwStates &= ~dwStates);
275 FWL_ERR ret = FWL_ERR_Succeeded;
276 if (dwStates & FWL_WGTSTATE_Invisible) {
277 if (bSet) {
278 ret = m_pWidgetMgr->HideWidget_Native(m_pInterface);
279 CFWL_NoteDriver* noteDriver =
280 static_cast<CFWL_NoteDriver*>(GetOwnerThread()->GetNoteDriver());
281 IFWL_WidgetMgr* widgetMgr = FWL_GetWidgetMgr();
282 noteDriver->NotifyTargetHide(m_pInterface);
283 IFWL_Widget* child =
284 widgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_FirstChild);
285 while (child) {
286 noteDriver->NotifyTargetHide(child);
287 NotifyHideChildWidget(widgetMgr, child, noteDriver);
288 child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
289 }
290 } else {
291 ret = m_pWidgetMgr->ShowWidget_Native(m_pInterface);
292 }
293 }
294 return ret;
295 }
SetPrivateData(void * module_id,void * pData,PD_CALLBACK_FREEDATA callback)296 FWL_ERR CFWL_WidgetImp::SetPrivateData(void* module_id,
297 void* pData,
298 PD_CALLBACK_FREEDATA callback) {
299 if (!m_pPrivateData) {
300 m_pPrivateData = new CFX_PrivateData;
301 }
302 m_pPrivateData->SetPrivateData(module_id, pData, callback);
303 return FWL_ERR_Succeeded;
304 }
GetPrivateData(void * module_id)305 void* CFWL_WidgetImp::GetPrivateData(void* module_id) {
306 if (!m_pPrivateData)
307 return NULL;
308 return m_pPrivateData->GetPrivateData(module_id);
309 }
Update()310 FWL_ERR CFWL_WidgetImp::Update() {
311 return FWL_ERR_Succeeded;
312 }
LockUpdate()313 FWL_ERR CFWL_WidgetImp::LockUpdate() {
314 m_iLock++;
315 return FWL_ERR_Succeeded;
316 }
UnlockUpdate()317 FWL_ERR CFWL_WidgetImp::UnlockUpdate() {
318 if (IsLocked()) {
319 m_iLock--;
320 }
321 return FWL_ERR_Succeeded;
322 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)323 FX_DWORD CFWL_WidgetImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
324 CFX_RectF rtClient;
325 GetClientRect(rtClient);
326 if (rtClient.Contains(fx, fy)) {
327 return FWL_WGTHITTEST_Client;
328 }
329 if (HasEdge()) {
330 CFX_RectF rtEdge;
331 GetEdgeRect(rtEdge);
332 if (rtEdge.Contains(fx, fy)) {
333 return FWL_WGTHITTEST_Edge;
334 }
335 }
336 if (HasBorder()) {
337 CFX_RectF rtRelative;
338 GetRelativeRect(rtRelative);
339 if (rtRelative.Contains(fx, fy)) {
340 return FWL_WGTHITTEST_Border;
341 }
342 }
343 return FWL_WGTHITTEST_Unknown;
344 }
TransformTo(IFWL_Widget * pWidget,FX_FLOAT & fx,FX_FLOAT & fy)345 FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget,
346 FX_FLOAT& fx,
347 FX_FLOAT& fy) {
348 if (m_pWidgetMgr->IsFormDisabled()) {
349 CFX_SizeF szOffset;
350 if (IsParent(pWidget)) {
351 szOffset = GetOffsetFromParent(pWidget);
352 } else {
353 szOffset = pWidget->GetOffsetFromParent(m_pInterface);
354 szOffset.x = -szOffset.x;
355 szOffset.y = -szOffset.y;
356 }
357 fx += szOffset.x;
358 fy += szOffset.y;
359 return FWL_ERR_Succeeded;
360 }
361 CFX_RectF r;
362 CFX_Matrix m;
363 IFWL_Widget* parent = GetParent();
364 if (parent) {
365 GetWidgetRect(r);
366 fx += r.left;
367 fy += r.top;
368 GetMatrix(m, TRUE);
369 m.TransformPoint(fx, fy);
370 }
371 IFWL_Widget* form1 =
372 m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
373 if (!form1)
374 return FWL_ERR_Indefinite;
375 if (!pWidget) {
376 form1->GetWidgetRect(r);
377 fx += r.left;
378 fy += r.top;
379 #ifdef FWL_UseMacSystemBorder
380 if (form1->GetStyles() & FWL_WGTSTYLE_Caption) {
381 FX_FLOAT l, t, r, b;
382 l = t = r = b = 0;
383 FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
384 fy += t;
385 }
386 #endif
387 return FWL_ERR_Succeeded;
388 }
389 IFWL_Widget* form2 =
390 m_pWidgetMgr->GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
391 if (!form2)
392 return FWL_ERR_Indefinite;
393 if (form1 != form2) {
394 form1->GetWidgetRect(r);
395 fx += r.left;
396 fy += r.top;
397 form2->GetWidgetRect(r);
398 fx -= r.left;
399 fy -= r.top;
400 #ifdef FWL_UseMacSystemBorder
401 if ((form1->GetStyles() & FWL_WGTSTYLE_Caption) !=
402 (form2->GetStyles() & FWL_WGTSTYLE_Caption)) {
403 FX_FLOAT l, t, r, b;
404 l = t = r = b = 0;
405 FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
406 (form1->GetStyles() & FWL_WGTSTYLE_Caption) ? (fy += t) : (fy -= t);
407 }
408 #endif
409 }
410 parent = pWidget->GetParent();
411 if (parent) {
412 pWidget->GetMatrix(m, TRUE);
413 CFX_Matrix m1;
414 m1.SetIdentity();
415 m1.SetReverse(m);
416 m1.TransformPoint(fx, fy);
417 pWidget->GetWidgetRect(r);
418 fx -= r.left;
419 fy -= r.top;
420 }
421 return FWL_ERR_Succeeded;
422 }
TransformTo(IFWL_Widget * pWidget,CFX_RectF & rt)423 FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
424 return TransformTo(pWidget, rt.left, rt.top);
425 }
GetMatrix(CFX_Matrix & matrix,FX_BOOL bGlobal)426 FWL_ERR CFWL_WidgetImp::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
427 if (!m_pProperties)
428 return FWL_ERR_Indefinite;
429 if (bGlobal) {
430 IFWL_Widget* parent = GetParent();
431 CFX_PtrArray parents;
432 while (parent) {
433 parents.Add(parent);
434 parent = parent->GetParent();
435 }
436 matrix.SetIdentity();
437 CFX_Matrix ctmOnParent;
438 CFX_RectF rect;
439 int32_t count = parents.GetSize();
440 for (int32_t i = count - 2; i >= 0; i--) {
441 parent = static_cast<IFWL_Widget*>(parents.GetAt(i));
442 parent->GetMatrix(ctmOnParent, FALSE);
443 parent->GetWidgetRect(rect);
444 matrix.Concat(ctmOnParent, TRUE);
445 matrix.Translate(rect.left, rect.top, TRUE);
446 }
447 matrix.Concat(m_pProperties->m_ctmOnParent, TRUE);
448 parents.RemoveAll();
449 } else {
450 matrix = m_pProperties->m_ctmOnParent;
451 }
452 return FWL_ERR_Succeeded;
453 }
SetMatrix(const CFX_Matrix & matrix)454 FWL_ERR CFWL_WidgetImp::SetMatrix(const CFX_Matrix& matrix) {
455 if (!m_pProperties)
456 return FWL_ERR_Indefinite;
457 IFWL_Widget* parent = GetParent();
458 if (!parent) {
459 return FWL_ERR_Indefinite;
460 }
461 m_pProperties->m_ctmOnParent = matrix;
462 return FWL_ERR_Succeeded;
463 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)464 FWL_ERR CFWL_WidgetImp::DrawWidget(CFX_Graphics* pGraphics,
465 const CFX_Matrix* pMatrix) {
466 return FWL_ERR_Indefinite;
467 }
GetThemeProvider()468 IFWL_ThemeProvider* CFWL_WidgetImp::GetThemeProvider() {
469 return m_pProperties->m_pThemeProvider;
470 }
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)471 FWL_ERR CFWL_WidgetImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
472 m_pProperties->m_pThemeProvider = pThemeProvider;
473 return FWL_ERR_Succeeded;
474 }
SetDataProvider(IFWL_DataProvider * pDataProvider)475 FWL_ERR CFWL_WidgetImp::SetDataProvider(IFWL_DataProvider* pDataProvider) {
476 m_pProperties->m_pDataProvider = pDataProvider;
477 return FWL_ERR_Succeeded;
478 }
SetDelegate(IFWL_WidgetDelegate * pDelegate)479 IFWL_WidgetDelegate* CFWL_WidgetImp::SetDelegate(
480 IFWL_WidgetDelegate* pDelegate) {
481 if (!m_pCurDelegate) {
482 m_pCurDelegate = m_pDelegate;
483 }
484 if (!pDelegate) {
485 return m_pCurDelegate;
486 }
487 IFWL_WidgetDelegate* pOldDelegate = m_pCurDelegate;
488 m_pCurDelegate = pDelegate;
489 return pOldDelegate;
490 }
GetOwnerThread() const491 IFWL_NoteThread* CFWL_WidgetImp::GetOwnerThread() const {
492 return static_cast<IFWL_NoteThread*>(m_pOwnerThread->GetInterface());
493 }
SetOwnerThread(CFWL_NoteThreadImp * pOwnerThread)494 FWL_ERR CFWL_WidgetImp::SetOwnerThread(CFWL_NoteThreadImp* pOwnerThread) {
495 m_pOwnerThread = pOwnerThread;
496 return FWL_ERR_Succeeded;
497 }
GetInterface() const498 IFWL_Widget* CFWL_WidgetImp::GetInterface() const {
499 return m_pInterface;
500 }
SetInterface(IFWL_Widget * pInterface)501 void CFWL_WidgetImp::SetInterface(IFWL_Widget* pInterface) {
502 m_pInterface = pInterface;
503 }
CFWL_WidgetImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)504 CFWL_WidgetImp::CFWL_WidgetImp(const CFWL_WidgetImpProperties& properties,
505 IFWL_Widget* pOuter)
506 : m_pProperties(new CFWL_WidgetImpProperties),
507 m_pPrivateData(NULL),
508 m_pDelegate(NULL),
509 m_pCurDelegate(NULL),
510 m_pOuter(pOuter),
511 m_pInterface(NULL),
512 m_iLock(0) {
513 *m_pProperties = properties;
514 m_pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
515 FXSYS_assert(m_pWidgetMgr != NULL);
516 }
~CFWL_WidgetImp()517 CFWL_WidgetImp::~CFWL_WidgetImp() {
518 if (m_pPrivateData) {
519 delete m_pPrivateData;
520 m_pPrivateData = NULL;
521 }
522 if (m_pProperties) {
523 delete m_pProperties;
524 m_pProperties = NULL;
525 }
526 }
IsEnabled() const527 FX_BOOL CFWL_WidgetImp::IsEnabled() const {
528 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
529 }
IsVisible() const530 FX_BOOL CFWL_WidgetImp::IsVisible() const {
531 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
532 }
IsActive() const533 FX_BOOL CFWL_WidgetImp::IsActive() const {
534 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0;
535 }
IsOverLapper() const536 FX_BOOL CFWL_WidgetImp::IsOverLapper() const {
537 return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
538 FWL_WGTSTYLE_OverLapper;
539 }
IsPopup() const540 FX_BOOL CFWL_WidgetImp::IsPopup() const {
541 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup);
542 }
IsChild() const543 FX_BOOL CFWL_WidgetImp::IsChild() const {
544 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child);
545 }
IsLocked() const546 FX_BOOL CFWL_WidgetImp::IsLocked() const {
547 return m_iLock > 0;
548 }
IsOffscreen() const549 FX_BOOL CFWL_WidgetImp::IsOffscreen() const {
550 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen);
551 }
HasBorder() const552 FX_BOOL CFWL_WidgetImp::HasBorder() const {
553 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border);
554 }
HasEdge() const555 FX_BOOL CFWL_WidgetImp::HasEdge() const {
556 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask);
557 }
GetEdgeRect(CFX_RectF & rtEdge)558 void CFWL_WidgetImp::GetEdgeRect(CFX_RectF& rtEdge) {
559 rtEdge = m_pProperties->m_rtWidget;
560 rtEdge.left = rtEdge.top = 0;
561 if (HasBorder()) {
562 FX_FLOAT fCX = GetBorderSize();
563 FX_FLOAT fCY = GetBorderSize(FALSE);
564 rtEdge.Deflate(fCX, fCY);
565 }
566 }
GetBorderSize(FX_BOOL bCX)567 FX_FLOAT CFWL_WidgetImp::GetBorderSize(FX_BOOL bCX) {
568 FX_FLOAT* pfBorder = static_cast<FX_FLOAT*>(GetThemeCapacity(
569 bCX ? FWL_WGTCAPACITY_CXBorder : FWL_WGTCAPACITY_CYBorder));
570 if (!pfBorder)
571 return 0;
572 return *pfBorder;
573 }
GetEdgeWidth()574 FX_FLOAT CFWL_WidgetImp::GetEdgeWidth() {
575 FX_DWORD dwCapacity = 0;
576 switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) {
577 case FWL_WGTSTYLE_EdgeFlat: {
578 dwCapacity = FWL_WGTCAPACITY_EdgeFlat;
579 break;
580 }
581 case FWL_WGTSTYLE_EdgeRaised: {
582 dwCapacity = FWL_WGTCAPACITY_EdgeRaised;
583 break;
584 }
585 case FWL_WGTSTYLE_EdgeSunken: {
586 dwCapacity = FWL_WGTCAPACITY_EdgeSunken;
587 break;
588 }
589 }
590 if (dwCapacity > 0) {
591 FX_FLOAT* fRet = static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity));
592 return fRet ? *fRet : 0;
593 }
594 return 0;
595 }
GetRelativeRect(CFX_RectF & rect)596 void CFWL_WidgetImp::GetRelativeRect(CFX_RectF& rect) {
597 rect = m_pProperties->m_rtWidget;
598 rect.left = rect.top = 0;
599 }
GetThemeCapacity(FX_DWORD dwCapacity)600 void* CFWL_WidgetImp::GetThemeCapacity(FX_DWORD dwCapacity) {
601 IFWL_ThemeProvider* pTheme = GetAvailableTheme();
602 if (!pTheme)
603 return NULL;
604 CFWL_ThemePart part;
605 part.m_pWidget = m_pInterface;
606 return pTheme->GetCapacity(&part, dwCapacity);
607 }
GetAvailableTheme()608 IFWL_ThemeProvider* CFWL_WidgetImp::GetAvailableTheme() {
609 if (m_pProperties->m_pThemeProvider) {
610 return m_pProperties->m_pThemeProvider;
611 }
612 IFWL_Widget* pUp = m_pInterface;
613 do {
614 FWL_WGTRELATION relation = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
615 ? FWL_WGTRELATION_Owner
616 : FWL_WGTRELATION_Parent;
617 pUp = m_pWidgetMgr->GetWidget(pUp, relation);
618 if (pUp) {
619 IFWL_ThemeProvider* pRet = pUp->GetThemeProvider();
620 if (pRet && pRet->IsValidWidget(m_pInterface)) {
621 return pRet;
622 }
623 }
624 } while (pUp);
625 return FWL_GetApp()->GetThemeProvider();
626 }
GetRootOuter()627 CFWL_WidgetImp* CFWL_WidgetImp::GetRootOuter() {
628 IFWL_Widget* pRet = m_pOuter;
629 if (!pRet)
630 return nullptr;
631 while (IFWL_Widget* pOuter = pRet->GetOuter()) {
632 pRet = pOuter;
633 }
634 return static_cast<CFWL_WidgetImp*>(pRet->GetImpl());
635 }
636 #define FWL_WGT_CalcHeight 2048
637 #define FWL_WGT_CalcWidth 2048
638 #define FWL_WGT_CalcMultiLineDefWidth 120.0f
CalcTextSize(const CFX_WideString & wsText,IFWL_ThemeProvider * pTheme,FX_BOOL bMultiLine,int32_t iLineWidth)639 CFX_SizeF CFWL_WidgetImp::CalcTextSize(const CFX_WideString& wsText,
640 IFWL_ThemeProvider* pTheme,
641 FX_BOOL bMultiLine,
642 int32_t iLineWidth) {
643 CFX_SizeF sz;
644 sz.Set(0, 0);
645 if (!pTheme)
646 return sz;
647 CFWL_ThemeText calPart;
648 calPart.m_pWidget = m_pInterface;
649 calPart.m_wsText = wsText;
650 calPart.m_dwTTOStyles =
651 bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
652 calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
653 CFX_RectF rect;
654 FX_FLOAT fWidth = bMultiLine
655 ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth
656 : FWL_WGT_CalcMultiLineDefWidth)
657 : FWL_WGT_CalcWidth;
658 rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight);
659 pTheme->CalcTextRect(&calPart, rect);
660 sz.x = rect.width;
661 sz.y = rect.height;
662 return sz;
663 }
CalcTextRect(const CFX_WideString & wsText,IFWL_ThemeProvider * pTheme,FX_DWORD dwTTOStyles,int32_t iTTOAlign,CFX_RectF & rect)664 void CFWL_WidgetImp::CalcTextRect(const CFX_WideString& wsText,
665 IFWL_ThemeProvider* pTheme,
666 FX_DWORD dwTTOStyles,
667 int32_t iTTOAlign,
668 CFX_RectF& rect) {
669 CFWL_ThemeText calPart;
670 calPart.m_pWidget = m_pInterface;
671 calPart.m_wsText = wsText;
672 calPart.m_dwTTOStyles = dwTTOStyles;
673 calPart.m_iTTOAlign = iTTOAlign;
674 pTheme->CalcTextRect(&calPart, rect);
675 }
SetFocus(FX_BOOL bFocus)676 void CFWL_WidgetImp::SetFocus(FX_BOOL bFocus) {
677 if (m_pWidgetMgr->IsFormDisabled())
678 return;
679 IFWL_NoteThread* pThread = GetOwnerThread();
680 if (!pThread)
681 return;
682 CFWL_NoteDriver* pDriver =
683 static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
684 if (!pDriver)
685 return;
686 IFWL_Widget* curFocus = pDriver->GetFocus();
687 if (bFocus && curFocus != m_pInterface) {
688 pDriver->SetFocus(m_pInterface);
689 } else if (!bFocus && curFocus == m_pInterface) {
690 pDriver->SetFocus(NULL);
691 }
692 }
SetGrab(FX_BOOL bSet)693 void CFWL_WidgetImp::SetGrab(FX_BOOL bSet) {
694 IFWL_NoteThread* pThread = GetOwnerThread();
695 if (!pThread)
696 return;
697 CFWL_NoteDriver* pDriver =
698 static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
699 pDriver->SetGrab(m_pInterface, bSet);
700 }
GetPopupPos(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)701 FX_BOOL CFWL_WidgetImp::GetPopupPos(FX_FLOAT fMinHeight,
702 FX_FLOAT fMaxHeight,
703 const CFX_RectF& rtAnchor,
704 CFX_RectF& rtPopup) {
705 if (GetClassID() == FWL_CLASSHASH_Menu) {
706 return GetPopupPosMenu(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
707 } else {
708 if (GetClassID() == FWL_CLASSHASH_ComboBox) {
709 if (m_pWidgetMgr->IsFormDisabled()) {
710 return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
711 fMaxHeight, rtAnchor, rtPopup);
712 } else {
713 return GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
714 }
715 } else if (GetClassID() == FWL_CLASSHASH_DateTimePicker &&
716 m_pWidgetMgr->IsFormDisabled()) {
717 return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
718 fMaxHeight, rtAnchor, rtPopup);
719 } else {
720 return GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
721 }
722 }
723 return FALSE;
724 }
GetPopupPosMenu(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)725 FX_BOOL CFWL_WidgetImp::GetPopupPosMenu(FX_FLOAT fMinHeight,
726 FX_FLOAT fMaxHeight,
727 const CFX_RectF& rtAnchor,
728 CFX_RectF& rtPopup) {
729 FX_FLOAT fx = 0;
730 FX_FLOAT fy = 0;
731 FX_FLOAT fScreenWidth = 0;
732 FX_FLOAT fScreenHeight = 0;
733 GetScreenSize(fScreenWidth, fScreenHeight);
734 if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) {
735 FX_BOOL bLeft = m_pProperties->m_rtWidget.left < 0;
736 FX_FLOAT fRight = rtAnchor.right() + rtPopup.width;
737 TransformTo(NULL, fx, fy);
738 if (fRight + fx > fScreenWidth || bLeft) {
739 rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width,
740 rtPopup.height);
741 } else {
742 rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width,
743 rtPopup.height);
744 }
745 } else {
746 FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height;
747 TransformTo(NULL, fx, fy);
748 if (fBottom + fy > fScreenHeight) {
749 rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width,
750 rtPopup.height);
751 } else {
752 rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
753 rtPopup.height);
754 }
755 }
756 rtPopup.Offset(fx, fy);
757 return TRUE;
758 }
GetPopupPosComboBox(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)759 FX_BOOL CFWL_WidgetImp::GetPopupPosComboBox(FX_FLOAT fMinHeight,
760 FX_FLOAT fMaxHeight,
761 const CFX_RectF& rtAnchor,
762 CFX_RectF& rtPopup) {
763 FX_FLOAT fx = 0;
764 FX_FLOAT fy = 0;
765 FX_FLOAT fScreenWidth = 0;
766 FX_FLOAT fScreenHeight = 0;
767 GetScreenSize(fScreenWidth, fScreenHeight);
768 FX_FLOAT fPopHeight = rtPopup.height;
769 if (rtPopup.height > fMaxHeight) {
770 fPopHeight = fMaxHeight;
771 } else if (rtPopup.height < fMinHeight) {
772 fPopHeight = fMinHeight;
773 }
774 FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width);
775 FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight;
776 TransformTo(NULL, fx, fy);
777 if (fBottom + fy > fScreenHeight) {
778 rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight);
779 } else {
780 rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight);
781 }
782 rtPopup.Offset(fx, fy);
783 return TRUE;
784 }
GetPopupPosGeneral(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)785 FX_BOOL CFWL_WidgetImp::GetPopupPosGeneral(FX_FLOAT fMinHeight,
786 FX_FLOAT fMaxHeight,
787 const CFX_RectF& rtAnchor,
788 CFX_RectF& rtPopup) {
789 FX_FLOAT fx = 0;
790 FX_FLOAT fy = 0;
791 FX_FLOAT fScreenWidth = 0;
792 FX_FLOAT fScreenHeight = 0;
793 GetScreenSize(fScreenWidth, fScreenHeight);
794 TransformTo(NULL, fx, fy);
795 if (rtAnchor.bottom() + fy > fScreenHeight) {
796 rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width,
797 rtPopup.height);
798 } else {
799 rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
800 rtPopup.height);
801 }
802 rtPopup.Offset(fx, fy);
803 return TRUE;
804 }
GetScreenSize(FX_FLOAT & fx,FX_FLOAT & fy)805 FX_BOOL CFWL_WidgetImp::GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy) {
806 IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
807 IFWL_AdapterMonitorMgr* pMonitorMgr = pNative->GetMonitorMgr();
808 if (!pMonitorMgr)
809 return FALSE;
810 FWL_HMONITOR hMonitor = pMonitorMgr->GetMonitorByPoint(fx, fy);
811 pMonitorMgr->GetMonitorSize(hMonitor, fx, fy);
812 return TRUE;
813 }
RegisterEventTarget(IFWL_Widget * pEventSource,FX_DWORD dwFilter)814 void CFWL_WidgetImp::RegisterEventTarget(IFWL_Widget* pEventSource,
815 FX_DWORD dwFilter) {
816 IFWL_NoteThread* pThread = GetOwnerThread();
817 if (!pThread)
818 return;
819 IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
820 if (!pNoteDriver)
821 return;
822 pNoteDriver->RegisterEventTarget(m_pInterface, pEventSource, dwFilter);
823 }
UnregisterEventTarget()824 void CFWL_WidgetImp::UnregisterEventTarget() {
825 IFWL_NoteThread* pThread = GetOwnerThread();
826 if (!pThread)
827 return;
828 IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
829 if (!pNoteDriver)
830 return;
831 pNoteDriver->UnregisterEventTarget(m_pInterface);
832 }
DispatchKeyEvent(CFWL_MsgKey * pNote)833 void CFWL_WidgetImp::DispatchKeyEvent(CFWL_MsgKey* pNote) {
834 if (!pNote)
835 return;
836 CFWL_EvtKey* pEvent = new CFWL_EvtKey;
837 pEvent->m_pSrcTarget = m_pInterface;
838 pEvent->m_dwCmd = pNote->m_dwCmd;
839 pEvent->m_dwKeyCode = pNote->m_dwKeyCode;
840 pEvent->m_dwFlags = pNote->m_dwFlags;
841 DispatchEvent(pEvent);
842 pEvent->Release();
843 }
DispatchEvent(CFWL_Event * pEvent)844 void CFWL_WidgetImp::DispatchEvent(CFWL_Event* pEvent) {
845 if (m_pOuter) {
846 IFWL_WidgetDelegate* pDelegate = m_pOuter->SetDelegate(NULL);
847 pDelegate->OnProcessEvent(pEvent);
848 return;
849 }
850 IFWL_NoteThread* pThread = GetOwnerThread();
851 if (!pThread)
852 return;
853 IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
854 if (!pNoteDriver)
855 return;
856 pNoteDriver->SendNote(pEvent);
857 }
Repaint(const CFX_RectF * pRect)858 void CFWL_WidgetImp::Repaint(const CFX_RectF* pRect) {
859 if (pRect) {
860 m_pWidgetMgr->RepaintWidget(m_pInterface, pRect);
861 return;
862 }
863 CFX_RectF rect;
864 rect = m_pProperties->m_rtWidget;
865 rect.left = rect.top = 0;
866 m_pWidgetMgr->RepaintWidget(m_pInterface, &rect);
867 }
DrawBackground(CFX_Graphics * pGraphics,int32_t iPartBk,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)868 void CFWL_WidgetImp::DrawBackground(CFX_Graphics* pGraphics,
869 int32_t iPartBk,
870 IFWL_ThemeProvider* pTheme,
871 const CFX_Matrix* pMatrix) {
872 CFX_RectF rtRelative;
873 GetRelativeRect(rtRelative);
874 CFWL_ThemeBackground param;
875 param.m_pWidget = m_pInterface;
876 param.m_iPart = iPartBk;
877 param.m_pGraphics = pGraphics;
878 if (pMatrix) {
879 param.m_matrix.Concat(*pMatrix, TRUE);
880 }
881 param.m_rtPart = rtRelative;
882 pTheme->DrawBackground(¶m);
883 }
DrawBorder(CFX_Graphics * pGraphics,int32_t iPartBorder,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)884 void CFWL_WidgetImp::DrawBorder(CFX_Graphics* pGraphics,
885 int32_t iPartBorder,
886 IFWL_ThemeProvider* pTheme,
887 const CFX_Matrix* pMatrix) {
888 CFX_RectF rtRelative;
889 GetRelativeRect(rtRelative);
890 CFWL_ThemeBackground param;
891 param.m_pWidget = m_pInterface;
892 param.m_iPart = iPartBorder;
893 param.m_pGraphics = pGraphics;
894 if (pMatrix) {
895 param.m_matrix.Concat(*pMatrix, TRUE);
896 }
897 param.m_rtPart = rtRelative;
898 pTheme->DrawBackground(¶m);
899 }
DrawEdge(CFX_Graphics * pGraphics,int32_t iPartEdge,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)900 void CFWL_WidgetImp::DrawEdge(CFX_Graphics* pGraphics,
901 int32_t iPartEdge,
902 IFWL_ThemeProvider* pTheme,
903 const CFX_Matrix* pMatrix) {
904 CFX_RectF rtEdge;
905 GetEdgeRect(rtEdge);
906 CFWL_ThemeBackground param;
907 param.m_pWidget = m_pInterface;
908 param.m_iPart = iPartEdge;
909 param.m_pGraphics = pGraphics;
910 if (pMatrix) {
911 param.m_matrix.Concat(*pMatrix, TRUE);
912 }
913 param.m_rtPart = rtEdge;
914 pTheme->DrawBackground(¶m);
915 }
NotifyDriver()916 void CFWL_WidgetImp::NotifyDriver() {
917 IFWL_NoteThread* pThread = GetOwnerThread();
918 if (!pThread)
919 return;
920 CFWL_NoteDriver* pDriver =
921 static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
922 if (!pDriver)
923 return;
924 pDriver->NotifyTargetDestroy(m_pInterface);
925 }
GetOffsetFromParent(IFWL_Widget * pParent)926 CFX_SizeF CFWL_WidgetImp::GetOffsetFromParent(IFWL_Widget* pParent) {
927 CFX_SizeF szRet;
928 szRet.Set(0, 0);
929 if (pParent == GetInterface()) {
930 return szRet;
931 }
932 IFWL_WidgetMgr* pWidgetMgr = FWL_GetWidgetMgr();
933 if (!pWidgetMgr)
934 return szRet;
935 szRet.x += m_pProperties->m_rtWidget.left;
936 szRet.y += m_pProperties->m_rtWidget.top;
937 IFWL_Widget* pDstWidget = GetParent();
938 while (pDstWidget && pDstWidget != pParent) {
939 CFX_RectF rtDst;
940 pDstWidget->GetWidgetRect(rtDst);
941 szRet.x += rtDst.left;
942 szRet.y += rtDst.top;
943 pDstWidget = pWidgetMgr->GetWidget(pDstWidget, FWL_WGTRELATION_Parent);
944 }
945 return szRet;
946 }
IsParent(IFWL_Widget * pParent)947 FX_BOOL CFWL_WidgetImp::IsParent(IFWL_Widget* pParent) {
948 IFWL_Widget* pUpWidget = GetParent();
949 while (pUpWidget) {
950 if (pUpWidget == pParent)
951 return TRUE;
952 pUpWidget = pUpWidget->GetParent();
953 }
954 return FALSE;
955 }
CFWL_WidgetImpDelegate()956 CFWL_WidgetImpDelegate::CFWL_WidgetImpDelegate() {}
OnProcessMessage(CFWL_Message * pMessage)957 int32_t CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
958 if (!pMessage->m_pDstTarget)
959 return 0;
960 CFWL_WidgetImp* pWidget =
961 static_cast<CFWL_WidgetImp*>(pMessage->m_pDstTarget->GetImpl());
962 FX_DWORD dwMsgCode = pMessage->GetClassID();
963 switch (dwMsgCode) {
964 case FWL_MSGHASH_Mouse: {
965 CFWL_MsgMouse* pMsgMouse = static_cast<CFWL_MsgMouse*>(pMessage);
966 CFWL_EvtMouse evt;
967 evt.m_pSrcTarget = pWidget->m_pInterface;
968 evt.m_pDstTarget = pWidget->m_pInterface;
969 evt.m_dwCmd = pMsgMouse->m_dwCmd;
970 evt.m_dwFlags = pMsgMouse->m_dwFlags;
971 evt.m_fx = pMsgMouse->m_fx;
972 evt.m_fy = pMsgMouse->m_fy;
973 pWidget->DispatchEvent(&evt);
974 break;
975 }
976 case FWL_MSGHASH_MouseWheel: {
977 CFWL_MsgMouseWheel* pMsgMouseWheel =
978 static_cast<CFWL_MsgMouseWheel*>(pMessage);
979 CFWL_EvtMouseWheel evt;
980 evt.m_pSrcTarget = pWidget->m_pInterface;
981 evt.m_pDstTarget = pWidget->m_pInterface;
982 evt.m_dwFlags = pMsgMouseWheel->m_dwFlags;
983 evt.m_fDeltaX = pMsgMouseWheel->m_fDeltaX;
984 evt.m_fDeltaY = pMsgMouseWheel->m_fDeltaY;
985 evt.m_fx = pMsgMouseWheel->m_fx;
986 evt.m_fy = pMsgMouseWheel->m_fy;
987 pWidget->DispatchEvent(&evt);
988 break;
989 }
990 case FWL_MSGHASH_Key: {
991 CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage);
992 CFWL_EvtKey evt;
993 evt.m_pSrcTarget = pWidget->m_pInterface;
994 evt.m_pDstTarget = pWidget->m_pInterface;
995 evt.m_dwKeyCode = pMsgKey->m_dwKeyCode;
996 evt.m_dwFlags = pMsgKey->m_dwFlags;
997 evt.m_dwCmd = pMsgKey->m_dwCmd;
998 pWidget->DispatchEvent(&evt);
999 break;
1000 }
1001 case FWL_MSGHASH_SetFocus: {
1002 CFWL_MsgSetFocus* pMsgSetFocus = static_cast<CFWL_MsgSetFocus*>(pMessage);
1003 CFWL_EvtSetFocus evt;
1004 evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget;
1005 evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget;
1006 evt.m_pSetFocus = pWidget->m_pInterface;
1007 pWidget->DispatchEvent(&evt);
1008 break;
1009 }
1010 case FWL_MSGHASH_KillFocus: {
1011 CFWL_MsgKillFocus* pMsgKillFocus =
1012 static_cast<CFWL_MsgKillFocus*>(pMessage);
1013 CFWL_EvtKillFocus evt;
1014 evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget;
1015 evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget;
1016 evt.m_pKillFocus = pWidget->m_pInterface;
1017 pWidget->DispatchEvent(&evt);
1018 break;
1019 }
1020 default: {}
1021 }
1022 return 1;
1023 }
OnProcessEvent(CFWL_Event * pEvent)1024 FWL_ERR CFWL_WidgetImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
1025 return FWL_ERR_Succeeded;
1026 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1027 FWL_ERR CFWL_WidgetImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1028 const CFX_Matrix* pMatrix) {
1029 CFWL_EvtDraw evt;
1030 evt.m_pGraphics = pGraphics;
1031 return FWL_ERR_Succeeded;
1032 }
1033 class CFWL_CustomImp : public CFWL_WidgetImp {
1034 public:
1035 CFWL_CustomImp(const CFWL_WidgetImpProperties& properties,
1036 IFWL_Widget* pOuter);
1037 virtual FWL_ERR GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
1038 virtual FWL_ERR Update();
1039 virtual FWL_ERR SetProxy(IFWL_Proxy* pProxy);
1040
1041 protected:
1042 IFWL_Proxy* m_pProxy;
1043 };
CFWL_CustomImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)1044 CFWL_CustomImp::CFWL_CustomImp(const CFWL_WidgetImpProperties& properties,
1045 IFWL_Widget* pOuter)
1046 : CFWL_WidgetImp(properties, pOuter), m_pProxy(NULL) {}
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)1047 FWL_ERR CFWL_CustomImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
1048 if (m_pProxy &&
1049 (m_pProxy->GetWidgetRect(rect, bAutoSize) == FWL_ERR_Succeeded)) {
1050 return FWL_ERR_Succeeded;
1051 }
1052 return CFWL_WidgetImp::GetWidgetRect(rect, bAutoSize);
1053 }
Update()1054 FWL_ERR CFWL_CustomImp::Update() {
1055 if (m_pProxy) {
1056 return m_pProxy->Update();
1057 }
1058 return CFWL_WidgetImp::Update();
1059 }
SetProxy(IFWL_Proxy * pProxy)1060 FWL_ERR CFWL_CustomImp::SetProxy(IFWL_Proxy* pProxy) {
1061 m_pProxy = pProxy;
1062 return FWL_ERR_Succeeded;
1063 }
1064
1065 // static
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)1066 IFWL_Custom* IFWL_Custom::Create(const CFWL_WidgetImpProperties& properties,
1067 IFWL_Widget* pOuter) {
1068 IFWL_Custom* pCustom = new IFWL_Custom;
1069 CFWL_CustomImp* pCustomImpl = new CFWL_CustomImp(properties, pOuter);
1070 pCustom->SetImpl(pCustomImpl);
1071 pCustomImpl->SetInterface(pCustom);
1072 return pCustom;
1073 }
IFWL_Custom()1074 IFWL_Custom::IFWL_Custom() {}
SetProxy(IFWL_Proxy * pProxy)1075 FWL_ERR IFWL_Custom::SetProxy(IFWL_Proxy* pProxy) {
1076 return static_cast<CFWL_CustomImp*>(GetImpl())->SetProxy(pProxy);
1077 }
FWL_SetWidgetRect(IFWL_Widget * widget,const CFX_RectF & rect)1078 void FWL_SetWidgetRect(IFWL_Widget* widget, const CFX_RectF& rect) {
1079 static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_rtWidget =
1080 rect;
1081 }
FWL_SetWidgetStates(IFWL_Widget * widget,FX_DWORD dwStates)1082 void FWL_SetWidgetStates(IFWL_Widget* widget, FX_DWORD dwStates) {
1083 static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_dwStates =
1084 dwStates;
1085 }
FWL_SetWidgetStyles(IFWL_Widget * widget,FX_DWORD dwStyles)1086 void FWL_SetWidgetStyles(IFWL_Widget* widget, FX_DWORD dwStyles) {
1087 static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_dwStyles =
1088 dwStyles;
1089 }
FWL_EnabelWidget(IFWL_Widget * widget,FX_BOOL bEnable)1090 FWL_ERR FWL_EnabelWidget(IFWL_Widget* widget, FX_BOOL bEnable) {
1091 widget->SetStates(FWL_WGTSTATE_Disabled, !bEnable);
1092 IFWL_WidgetMgr* widgetMgr = FWL_GetWidgetMgr();
1093 IFWL_Widget* child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
1094 while (child) {
1095 FWL_EnabelWidget(child, bEnable);
1096 child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
1097 }
1098 return FWL_ERR_Succeeded;
1099 }
1100