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