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_targetimp.h"
9 #include "xfa/src/fwl/src/core/include/fwl_threadimp.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_panelimp.h"
13 #include "xfa/src/fwl/src/core/include/fwl_formimp.h"
14 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
15 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
16 #include "xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h"
17 
18 #define FWL_SYSBTNSIZE 21
19 #define FWL_SYSBTNMARGIN 5
20 #define FWL_SYSBTNSPAN 2
21 #define FWL_CornerEnlarge 10
22 
23 // static
CreateFormProxy(CFWL_WidgetImpProperties & properties,CFX_WideString * classname,IFWL_Widget * pOuter)24 IFWL_Form* IFWL_Form::CreateFormProxy(CFWL_WidgetImpProperties& properties,
25                                       CFX_WideString* classname,
26                                       IFWL_Widget* pOuter) {
27   IFWL_Form* pForm = new IFWL_Form;
28   CFWL_FormProxyImp* pFormProxyImpl = new CFWL_FormProxyImp(properties, pOuter);
29   pForm->SetImpl(pFormProxyImpl);
30   pFormProxyImpl->SetInterface(pForm);
31   return pForm;
32 }
IFWL_Form()33 IFWL_Form::IFWL_Form() {}
GetFormSize()34 FWL_FORMSIZE IFWL_Form::GetFormSize() {
35   return static_cast<CFWL_FormImp*>(GetImpl())->GetFormSize();
36 }
SetFormSize(FWL_FORMSIZE eFormSize)37 FWL_ERR IFWL_Form::SetFormSize(FWL_FORMSIZE eFormSize) {
38   return static_cast<CFWL_FormImp*>(GetImpl())->SetFormSize(eFormSize);
39 }
DoModal()40 IFWL_Widget* IFWL_Form::DoModal() {
41   return static_cast<CFWL_FormImp*>(GetImpl())->DoModal();
42 }
DoModal(FX_DWORD & dwCommandID)43 IFWL_Widget* IFWL_Form::DoModal(FX_DWORD& dwCommandID) {
44   return static_cast<CFWL_FormImp*>(GetImpl())->DoModal(dwCommandID);
45 }
EndDoModal()46 FWL_ERR IFWL_Form::EndDoModal() {
47   return static_cast<CFWL_FormImp*>(GetImpl())->EndDoModal();
48 }
SetBorderRegion(CFX_Path * pPath)49 FWL_ERR IFWL_Form::SetBorderRegion(CFX_Path* pPath) {
50   return static_cast<CFWL_FormImp*>(GetImpl())->SetBorderRegion(pPath);
51 }
52 
CFWL_FormImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)53 CFWL_FormImp::CFWL_FormImp(const CFWL_WidgetImpProperties& properties,
54                            IFWL_Widget* pOuter)
55     : CFWL_PanelImp(properties, pOuter),
56       m_pCloseBox(NULL),
57       m_pMinBox(NULL),
58       m_pMaxBox(NULL),
59       m_pCaptionBox(NULL),
60       m_pNoteLoop(NULL),
61       m_pSubFocus(NULL),
62       m_fCXBorder(0),
63       m_fCYBorder(0),
64       m_iCaptureBtn(-1),
65       m_iSysBox(0),
66       m_eResizeType(FORM_RESIZETYPE_None),
67       m_bLButtonDown(FALSE),
68       m_bMaximized(FALSE),
69       m_bSetMaximize(FALSE),
70       m_bCustomizeLayout(FALSE),
71       m_eFormSize(FWL_FORMSIZE_Manual),
72       m_bDoModalFlag(FALSE),
73       m_pBigIcon(NULL),
74       m_pSmallIcon(NULL),
75       m_bMouseIn(FALSE) {
76   m_rtRelative.Reset();
77   m_rtCaption.Reset();
78   m_rtRestore.Reset();
79   m_rtCaptionText.Reset();
80   m_rtIcon.Reset();
81   m_InfoStart.m_ptStart.Reset();
82   m_InfoStart.m_szStart.Reset();
83 }
~CFWL_FormImp()84 CFWL_FormImp::~CFWL_FormImp() {
85   RemoveSysButtons();
86   if (m_pNoteLoop) {
87     delete m_pNoteLoop;
88     m_pNoteLoop = NULL;
89   }
90 }
GetClassName(CFX_WideString & wsClass) const91 FWL_ERR CFWL_FormImp::GetClassName(CFX_WideString& wsClass) const {
92   wsClass = FWL_CLASS_Form;
93   return FWL_ERR_Succeeded;
94 }
GetClassID() const95 FX_DWORD CFWL_FormImp::GetClassID() const {
96   return FWL_CLASSHASH_Form;
97 }
IsInstance(const CFX_WideStringC & wsClass) const98 FX_BOOL CFWL_FormImp::IsInstance(const CFX_WideStringC& wsClass) const {
99   if (wsClass == CFX_WideStringC(FWL_CLASS_Form)) {
100     return TRUE;
101   }
102   return CFWL_PanelImp::IsInstance(wsClass);
103 }
Initialize()104 FWL_ERR CFWL_FormImp::Initialize() {
105   if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
106     return FWL_ERR_Indefinite;
107   RegisterForm();
108   RegisterEventTarget();
109   m_pDelegate = new CFWL_FormImpDelegate(this);
110   return FWL_ERR_Succeeded;
111 }
Finalize()112 FWL_ERR CFWL_FormImp::Finalize() {
113   delete m_pDelegate;
114   m_pDelegate = nullptr;
115   UnregisterEventTarget();
116   UnRegisterForm();
117   return CFWL_WidgetImp::Finalize();
118 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)119 FWL_ERR CFWL_FormImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
120   if (bAutoSize) {
121     rect.Reset();
122     FX_FLOAT fCapHeight = GetCaptionHeight();
123     FX_FLOAT fCXBorder = GetBorderSize(TRUE);
124     FX_FLOAT fCYBorder = GetBorderSize(FALSE);
125     FX_FLOAT fEdge = GetEdgeWidth();
126     if (m_pContent) {
127       m_pContent->GetWidgetRect(rect, TRUE);
128     }
129     rect.height += fCapHeight + fCYBorder + fEdge + fEdge;
130     rect.width += fCXBorder + fCXBorder + fEdge + fEdge;
131   } else {
132     rect = m_pProperties->m_rtWidget;
133   }
134   return FWL_ERR_Succeeded;
135 }
GetClientRect(CFX_RectF & rect)136 FWL_ERR CFWL_FormImp::GetClientRect(CFX_RectF& rect) {
137   if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) == 0) {
138     rect = m_pProperties->m_rtWidget;
139     rect.Offset(-rect.left, -rect.top);
140     return FWL_ERR_Succeeded;
141   }
142 #ifdef FWL_UseMacSystemBorder
143   rect = m_rtRelative;
144   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
145   if (!pWidgetMgr)
146     return FWL_ERR_Indefinite;
147   IFWL_AdapterWidgetMgr* adapterWidgetMgr = pWidgetMgr->GetAdapterWidgetMgr();
148   FX_FLOAT l, t, r, b;
149   l = t = r = b = 0;
150   adapterWidgetMgr->GetSystemBorder(l, t, r, b);
151   rect.Deflate(l, t, r, b);
152   rect.left = rect.top = 0;
153   return FWL_ERR_Succeeded;
154 #else
155   FX_FLOAT x = 0;
156   FX_FLOAT y = 0;
157   FX_FLOAT t = 0;
158   IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
159   if (pTheme) {
160     CFWL_ThemePart part;
161     part.m_pWidget = m_pInterface;
162     x = *static_cast<FX_FLOAT*>(
163         pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CXBorder));
164     y = *static_cast<FX_FLOAT*>(
165         pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CYBorder));
166     t = *static_cast<FX_FLOAT*>(
167         pTheme->GetCapacity(&part, FWL_WGTCAPACITY_FRM_CYCaption));
168   }
169   rect = m_pProperties->m_rtWidget;
170   rect.Offset(-rect.left, -rect.top);
171   rect.Deflate(x, t, x, y);
172   return FWL_ERR_Succeeded;
173 #endif
174 }
Update()175 FWL_ERR CFWL_FormImp::Update() {
176   if (m_iLock > 0) {
177     return FWL_ERR_Succeeded;
178   }
179   if (!m_pProperties->m_pThemeProvider) {
180     m_pProperties->m_pThemeProvider = GetAvailableTheme();
181   }
182 #ifdef FWL_UseMacSystemBorder
183 #else
184   SetThemeData();
185   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon) {
186     UpdateIcon();
187   }
188 #endif
189   UpdateCaption();
190   Layout();
191   return FWL_ERR_Succeeded;
192 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)193 FX_DWORD CFWL_FormImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
194   (void)GetAvailableTheme();
195   if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) {
196     return FWL_WGTHITTEST_CloseBox;
197   }
198   if (m_pMaxBox && m_pMaxBox->m_rtBtn.Contains(fx, fy)) {
199     return FWL_WGTHITTEST_MaxBox;
200   }
201   if (m_pMinBox && m_pMinBox->m_rtBtn.Contains(fx, fy)) {
202     return FWL_WGTHITTEST_MinBox;
203   }
204   CFX_RectF rtCap;
205   rtCap.Set(m_rtCaption.left + m_fCYBorder, m_rtCaption.top + m_fCXBorder,
206             m_rtCaption.width - FWL_SYSBTNSIZE * m_iSysBox - 2 * m_fCYBorder,
207             m_rtCaption.height - m_fCXBorder);
208   if (rtCap.Contains(fx, fy)) {
209     return FWL_WGTHITTEST_Titlebar;
210   }
211   if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) &&
212       (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize)) {
213     FX_FLOAT fWidth =
214         m_rtRelative.width - 2 * (m_fCYBorder + FWL_CornerEnlarge);
215     FX_FLOAT fHeight =
216         m_rtRelative.height - 2 * (m_fCXBorder + FWL_CornerEnlarge);
217     CFX_RectF rt;
218     rt.Set(0, m_fCXBorder + FWL_CornerEnlarge, m_fCYBorder, fHeight);
219     if (rt.Contains(fx, fy)) {
220       return FWL_WGTHITTEST_Left;
221     }
222     rt.Set(m_rtRelative.width - m_fCYBorder, m_fCXBorder + FWL_CornerEnlarge,
223            m_fCYBorder, fHeight);
224     if (rt.Contains(fx, fy)) {
225       return FWL_WGTHITTEST_Right;
226     }
227     rt.Set(m_fCYBorder + FWL_CornerEnlarge, 0, fWidth, m_fCXBorder);
228     if (rt.Contains(fx, fy)) {
229       return FWL_WGTHITTEST_Top;
230     }
231     rt.Set(m_fCYBorder + FWL_CornerEnlarge, m_rtRelative.height - m_fCXBorder,
232            fWidth, m_fCXBorder);
233     if (rt.Contains(fx, fy)) {
234       return FWL_WGTHITTEST_Bottom;
235     }
236     rt.Set(0, 0, m_fCYBorder + FWL_CornerEnlarge,
237            m_fCXBorder + FWL_CornerEnlarge);
238     if (rt.Contains(fx, fy)) {
239       return FWL_WGTHITTEST_LeftTop;
240     }
241     rt.Set(0, m_rtRelative.height - m_fCXBorder - FWL_CornerEnlarge,
242            m_fCYBorder + FWL_CornerEnlarge, m_fCXBorder + FWL_CornerEnlarge);
243     if (rt.Contains(fx, fy)) {
244       return FWL_WGTHITTEST_LeftBottom;
245     }
246     rt.Set(m_rtRelative.width - m_fCYBorder - FWL_CornerEnlarge, 0,
247            m_fCYBorder + FWL_CornerEnlarge, m_fCXBorder + FWL_CornerEnlarge);
248     if (rt.Contains(fx, fy)) {
249       return FWL_WGTHITTEST_RightTop;
250     }
251     rt.Set(m_rtRelative.width - m_fCYBorder - FWL_CornerEnlarge,
252            m_rtRelative.height - m_fCXBorder - FWL_CornerEnlarge,
253            m_fCYBorder + FWL_CornerEnlarge, m_fCXBorder + FWL_CornerEnlarge);
254     if (rt.Contains(fx, fy)) {
255       return FWL_WGTHITTEST_RightBottom;
256     }
257   }
258   return FWL_WGTHITTEST_Client;
259 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)260 FWL_ERR CFWL_FormImp::DrawWidget(CFX_Graphics* pGraphics,
261                                  const CFX_Matrix* pMatrix) {
262   if (!pGraphics)
263     return FWL_ERR_Indefinite;
264   if (!m_pProperties->m_pThemeProvider)
265     return FWL_ERR_Indefinite;
266   IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
267   FX_BOOL bInactive = !IsActive();
268   int32_t iState =
269       bInactive ? FWL_PARTSTATE_FRM_Inactive : FWL_PARTSTATE_FRM_Normal;
270   if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_NoDrawClient) == 0) {
271     DrawBackground(pGraphics, pTheme);
272   }
273 #ifdef FWL_UseMacSystemBorder
274   return FWL_ERR_Succeeded;
275 #endif
276   CFWL_ThemeBackground param;
277   param.m_pWidget = m_pInterface;
278   param.m_dwStates = iState;
279   param.m_pGraphics = pGraphics;
280   param.m_rtPart = m_rtRelative;
281   if (pMatrix) {
282     param.m_matrix.Concat(*pMatrix);
283   }
284   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) {
285     param.m_iPart = FWL_PART_FRM_Border;
286     pTheme->DrawBackground(&param);
287   }
288   if ((m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_EdgeMask) !=
289       FWL_WGTSTYLE_EdgeNone) {
290     CFX_RectF rtEdge;
291     GetEdgeRect(rtEdge);
292     param.m_iPart = FWL_PART_FRM_Edge;
293     param.m_rtPart = rtEdge;
294     param.m_dwStates = iState;
295     pTheme->DrawBackground(&param);
296   }
297   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) {
298     param.m_iPart = FWL_PART_FRM_Caption;
299     param.m_dwStates = iState;
300     param.m_rtPart = m_rtCaption;
301     pTheme->DrawBackground(&param);
302     DrawCaptionText(pGraphics, pTheme, pMatrix);
303   } else if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_NarrowCaption) {
304     param.m_iPart = FWL_PART_FRM_NarrowCaption;
305     param.m_dwStates = iState;
306     param.m_rtPart = m_rtCaption;
307     pTheme->DrawBackground(&param);
308     DrawCaptionText(pGraphics, pTheme, pMatrix);
309   }
310   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon) {
311     param.m_iPart = FWL_PART_FRM_Icon;
312     if (HasIcon()) {
313       DrawIconImage(pGraphics, pTheme, pMatrix);
314     }
315   }
316 #if (_FX_OS_ == _FX_MACOSX_)
317   {
318     if (m_pCloseBox) {
319       param.m_iPart = FWL_PART_FRM_CloseBox;
320       param.m_dwStates = m_pCloseBox->GetPartState();
321       if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) {
322         param.m_dwStates = FWL_PARTSTATE_FRM_Disabled;
323       } else if (FWL_PARTSTATE_FRM_Normal == param.m_dwStates && m_bMouseIn) {
324         param.m_dwStates = FWL_PARTSTATE_FRM_Hover;
325       }
326       param.m_rtPart = m_pCloseBox->m_rtBtn;
327       pTheme->DrawBackground(&param);
328     }
329     if (m_pMaxBox) {
330       param.m_iPart = FWL_PART_FRM_MaximizeBox;
331       param.m_dwStates = m_pMaxBox->GetPartState();
332       if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) {
333         param.m_dwStates = FWL_PARTSTATE_FRM_Disabled;
334       } else if (FWL_PARTSTATE_FRM_Normal == param.m_dwStates && m_bMouseIn) {
335         param.m_dwStates = FWL_PARTSTATE_FRM_Hover;
336       }
337       param.m_rtPart = m_pMaxBox->m_rtBtn;
338       param.m_dwData = m_bMaximized;
339       pTheme->DrawBackground(&param);
340     }
341     if (m_pMinBox) {
342       param.m_iPart = FWL_PART_FRM_MinimizeBox;
343       param.m_dwStates = m_pMinBox->GetPartState();
344       if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) {
345         param.m_dwStates = FWL_PARTSTATE_FRM_Disabled;
346       } else if (FWL_PARTSTATE_FRM_Normal == param.m_dwStates && m_bMouseIn) {
347         param.m_dwStates = FWL_PARTSTATE_FRM_Hover;
348       }
349       param.m_rtPart = m_pMinBox->m_rtBtn;
350       pTheme->DrawBackground(&param);
351     }
352     m_bMouseIn = FALSE;
353   }
354 #else
355   {
356     if (m_pCloseBox) {
357       param.m_iPart = FWL_PART_FRM_CloseBox;
358       param.m_dwStates = m_pCloseBox->GetPartState();
359       param.m_rtPart = m_pCloseBox->m_rtBtn;
360       pTheme->DrawBackground(&param);
361     }
362     if (m_pMaxBox) {
363       param.m_iPart = FWL_PART_FRM_MaximizeBox;
364       param.m_dwStates = m_pMaxBox->GetPartState();
365       param.m_rtPart = m_pMaxBox->m_rtBtn;
366       param.m_dwData = m_bMaximized;
367       pTheme->DrawBackground(&param);
368     }
369     if (m_pMinBox) {
370       param.m_iPart = FWL_PART_FRM_MinimizeBox;
371       param.m_dwStates = m_pMinBox->GetPartState();
372       param.m_rtPart = m_pMinBox->m_rtBtn;
373       pTheme->DrawBackground(&param);
374     }
375   }
376 #endif
377   return FWL_ERR_Succeeded;
378 }
GetFormSize()379 FWL_FORMSIZE CFWL_FormImp::GetFormSize() {
380   return m_eFormSize;
381 }
SetFormSize(FWL_FORMSIZE eFormSize)382 FWL_ERR CFWL_FormImp::SetFormSize(FWL_FORMSIZE eFormSize) {
383   m_eFormSize = eFormSize;
384   return FWL_ERR_Succeeded;
385 }
DoModal()386 IFWL_Widget* CFWL_FormImp::DoModal() {
387   IFWL_NoteThread* pThread = GetOwnerThread();
388   if (!pThread)
389     return NULL;
390   IFWL_NoteDriver* pDriver = pThread->GetNoteDriver();
391   if (!pDriver)
392     return NULL;
393   m_pNoteLoop = new CFWL_NoteLoop(this);
394   pDriver->PushNoteLoop(m_pNoteLoop);
395   m_bDoModalFlag = TRUE;
396   SetStates(FWL_WGTSTATE_Invisible, FALSE);
397   pDriver->Run();
398 #if (_FX_OS_ == _FX_MACOSX_)
399 #else
400   pDriver->PopNoteLoop();
401 #endif
402   delete m_pNoteLoop;
403   m_pNoteLoop = NULL;
404   return NULL;
405 }
DoModal(FX_DWORD & dwCommandID)406 IFWL_Widget* CFWL_FormImp::DoModal(FX_DWORD& dwCommandID) {
407   return DoModal();
408 }
EndDoModal()409 FWL_ERR CFWL_FormImp::EndDoModal() {
410   if (!m_pNoteLoop)
411     return FWL_ERR_Indefinite;
412   m_bDoModalFlag = FALSE;
413 #if (_FX_OS_ == _FX_MACOSX_)
414   m_pNoteLoop->EndModalLoop();
415   IFWL_NoteThread* pThread = GetOwnerThread();
416   if (!pThread)
417     return NULL;
418   CFWL_NoteDriver* pDriver =
419       static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
420   if (!pDriver)
421     return NULL;
422   pDriver->PopNoteLoop();
423   SetStates(FWL_WGTSTATE_Invisible, TRUE);
424   return FWL_ERR_Succeeded;
425 #else
426   SetStates(FWL_WGTSTATE_Invisible, TRUE);
427   return m_pNoteLoop->EndModalLoop();
428 #endif
429 }
SetBorderRegion(CFX_Path * pPath)430 FWL_ERR CFWL_FormImp::SetBorderRegion(CFX_Path* pPath) {
431   return FWL_ERR_Succeeded;
432 }
DrawBackground(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme)433 void CFWL_FormImp::DrawBackground(CFX_Graphics* pGraphics,
434                                   IFWL_ThemeProvider* pTheme) {
435   CFWL_ThemeBackground param;
436   param.m_pWidget = m_pInterface;
437   param.m_iPart = FWL_PART_FRM_Background;
438   param.m_pGraphics = pGraphics;
439   param.m_rtPart = m_rtRelative;
440   param.m_rtPart.Deflate(m_fCYBorder, m_rtCaption.height, m_fCYBorder,
441                          m_fCXBorder);
442   pTheme->DrawBackground(&param);
443 }
GetSubFocus()444 CFWL_WidgetImp* CFWL_FormImp::GetSubFocus() {
445   return m_pSubFocus;
446 }
SetSubFocus(CFWL_WidgetImp * pWidget)447 void CFWL_FormImp::SetSubFocus(CFWL_WidgetImp* pWidget) {
448   m_pSubFocus = pWidget;
449 }
GetAccelerator()450 CFX_MapAccelerators& CFWL_FormImp::GetAccelerator() {
451   return m_mapAccelerators;
452 }
SetAccelerator(CFX_MapAccelerators * pAccelerators)453 void CFWL_FormImp::SetAccelerator(CFX_MapAccelerators* pAccelerators) {
454   if (!pAccelerators)
455     return;
456   m_mapAccelerators.RemoveAll();
457   FX_DWORD vrKey, rValue;
458   FX_POSITION pos = pAccelerators->GetStartPosition();
459   while (pos) {
460     pAccelerators->GetNextAssoc(pos, vrKey, rValue);
461     m_mapAccelerators.SetAt(vrKey, rValue);
462   }
463 }
ShowChildWidget(IFWL_Widget * pParent)464 void CFWL_FormImp::ShowChildWidget(IFWL_Widget* pParent) {
465   IFWL_App* pApp = FWL_GetApp();
466   if (!pApp)
467     return;
468   CFWL_WidgetMgr* pWidgetMgr =
469       static_cast<CFWL_WidgetMgr*>(pApp->GetWidgetMgr());
470   if (!pWidgetMgr)
471     return;
472   IFWL_Widget* pChild =
473       pWidgetMgr->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
474   while (pChild) {
475     pWidgetMgr->ShowWidget_Native(pChild);
476     ShowChildWidget(pChild);
477     pChild = pWidgetMgr->GetWidget(pChild, FWL_WGTRELATION_NextSibling);
478   }
479 }
RemoveSysButtons()480 void CFWL_FormImp::RemoveSysButtons() {
481   m_rtCaption.Reset();
482   if (m_pCloseBox) {
483     delete m_pCloseBox;
484     m_pCloseBox = NULL;
485   }
486   if (m_pMinBox) {
487     delete m_pMinBox;
488     m_pMinBox = NULL;
489   }
490   if (m_pMaxBox) {
491     delete m_pMaxBox;
492     m_pMaxBox = NULL;
493   }
494   if (m_pCaptionBox) {
495     delete m_pCaptionBox;
496     m_pCaptionBox = NULL;
497   }
498 }
CalcContentRect(CFX_RectF & rtContent)499 void CFWL_FormImp::CalcContentRect(CFX_RectF& rtContent) {
500 #ifdef FWL_UseMacSystemBorder
501   rtContent = m_rtRelative;
502 #else
503   GetEdgeRect(rtContent);
504   if (HasEdge()) {
505     FX_FLOAT fEdge = GetEdgeWidth();
506     rtContent.Deflate(fEdge, fEdge);
507   }
508 #endif
509 }
GetSysBtnAtPoint(FX_FLOAT fx,FX_FLOAT fy)510 CFWL_SysBtn* CFWL_FormImp::GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
511   if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) {
512     return m_pCloseBox;
513   }
514   if (m_pMaxBox && m_pMaxBox->m_rtBtn.Contains(fx, fy)) {
515     return m_pMaxBox;
516   }
517   if (m_pMinBox && m_pMinBox->m_rtBtn.Contains(fx, fy)) {
518     return m_pMinBox;
519   }
520   if (m_pCaptionBox && m_pCaptionBox->m_rtBtn.Contains(fx, fy)) {
521     return m_pCaptionBox;
522   }
523   return NULL;
524 }
GetSysBtnByState(FX_DWORD dwState)525 CFWL_SysBtn* CFWL_FormImp::GetSysBtnByState(FX_DWORD dwState) {
526   if (m_pCloseBox && (m_pCloseBox->m_dwState & dwState)) {
527     return m_pCloseBox;
528   }
529   if (m_pMaxBox && (m_pMaxBox->m_dwState & dwState)) {
530     return m_pMaxBox;
531   }
532   if (m_pMinBox && (m_pMinBox->m_dwState & dwState)) {
533     return m_pMinBox;
534   }
535   if (m_pCaptionBox && (m_pCaptionBox->m_dwState & dwState)) {
536     return m_pCaptionBox;
537   }
538   return NULL;
539 }
GetSysBtnByIndex(int32_t nIndex)540 CFWL_SysBtn* CFWL_FormImp::GetSysBtnByIndex(int32_t nIndex) {
541   if (nIndex < 0) {
542     return NULL;
543   }
544   CFX_PtrArray arrBtn;
545   if (m_pMinBox) {
546     arrBtn.Add(m_pMinBox);
547   }
548   if (m_pMaxBox) {
549     arrBtn.Add(m_pMaxBox);
550   }
551   if (m_pCloseBox) {
552     arrBtn.Add(m_pCloseBox);
553   }
554   return static_cast<CFWL_SysBtn*>(arrBtn[nIndex]);
555 }
GetSysBtnIndex(CFWL_SysBtn * pBtn)556 int32_t CFWL_FormImp::GetSysBtnIndex(CFWL_SysBtn* pBtn) {
557   CFX_PtrArray arrBtn;
558   if (m_pMinBox) {
559     arrBtn.Add(m_pMinBox);
560   }
561   if (m_pMaxBox) {
562     arrBtn.Add(m_pMaxBox);
563   }
564   if (m_pCloseBox) {
565     arrBtn.Add(m_pCloseBox);
566   }
567   return arrBtn.Find(pBtn);
568 }
GetCaptionHeight()569 FX_FLOAT CFWL_FormImp::GetCaptionHeight() {
570   FX_DWORD dwCapacity = 0;
571   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) {
572     dwCapacity = FWL_WGTCAPACITY_FRM_CYCaption;
573   } else if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_NarrowCaption) {
574     dwCapacity = FWL_WGTCAPACITY_FRM_CYNarrowCaption;
575   }
576   if (dwCapacity > 0) {
577     FX_FLOAT* pfCapHeight =
578         static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity));
579     return pfCapHeight ? *pfCapHeight : 0;
580   }
581   return 0;
582 }
DrawCaptionText(CFX_Graphics * pGs,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)583 void CFWL_FormImp::DrawCaptionText(CFX_Graphics* pGs,
584                                    IFWL_ThemeProvider* pTheme,
585                                    const CFX_Matrix* pMatrix) {
586   CFX_WideString wsText;
587   IFWL_DataProvider* pData = m_pProperties->m_pDataProvider;
588   pData->GetCaption(m_pInterface, wsText);
589   if (wsText.IsEmpty()) {
590     return;
591   }
592   CFWL_ThemeText textParam;
593   textParam.m_pWidget = m_pInterface;
594   textParam.m_iPart = FWL_PART_FRM_Caption;
595   textParam.m_dwStates = FWL_PARTSTATE_FRM_Normal;
596   textParam.m_pGraphics = pGs;
597   if (pMatrix) {
598     textParam.m_matrix.Concat(*pMatrix);
599   }
600   CFX_RectF rtText;
601   if (m_bCustomizeLayout) {
602     rtText = m_rtCaptionText;
603     rtText.top -= 5;
604   } else {
605     rtText = m_rtCaption;
606     FX_FLOAT fpos;
607     fpos = HasIcon() ? 29.0f : 13.0f;
608     rtText.left += fpos;
609   }
610   textParam.m_rtPart = rtText;
611   textParam.m_wsText = wsText;
612   textParam.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine | FDE_TTOSTYLE_Ellipsis;
613   textParam.m_iTTOAlign = m_bCustomizeLayout ? FDE_TTOALIGNMENT_Center
614                                              : FDE_TTOALIGNMENT_CenterLeft;
615   pTheme->DrawText(&textParam);
616 }
DrawIconImage(CFX_Graphics * pGs,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)617 void CFWL_FormImp::DrawIconImage(CFX_Graphics* pGs,
618                                  IFWL_ThemeProvider* pTheme,
619                                  const CFX_Matrix* pMatrix) {
620   IFWL_FormDP* pData =
621       static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
622   CFWL_ThemeBackground param;
623   param.m_pWidget = m_pInterface;
624   param.m_iPart = FWL_PART_FRM_Icon;
625   param.m_pGraphics = pGs;
626   param.m_pImage = pData->GetIcon(m_pInterface, FALSE);
627   param.m_rtPart = m_rtIcon;
628   if (pMatrix) {
629     param.m_matrix.Concat(*pMatrix);
630   }
631   pTheme->DrawBackground(&param);
632 }
GetEdgeRect(CFX_RectF & rtEdge)633 void CFWL_FormImp::GetEdgeRect(CFX_RectF& rtEdge) {
634   rtEdge = m_rtRelative;
635   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) {
636     FX_FLOAT fCX = GetBorderSize();
637     FX_FLOAT fCY = GetBorderSize(FALSE);
638     rtEdge.Deflate(fCX, m_rtCaption.Height(), fCX, fCY);
639   }
640 }
SetWorkAreaRect()641 void CFWL_FormImp::SetWorkAreaRect() {
642   m_rtRestore = m_pProperties->m_rtWidget;
643   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
644   if (!pWidgetMgr)
645     return;
646   m_bSetMaximize = TRUE;
647   pWidgetMgr->SetMaximize_Native(m_pInterface);
648   Repaint(&m_rtRelative);
649 }
SetCursor(FX_FLOAT fx,FX_FLOAT fy)650 void CFWL_FormImp::SetCursor(FX_FLOAT fx, FX_FLOAT fy) {
651   IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
652   IFWL_AdapterCursorMgr* pCursorMgr = pNative->GetCursorMgr();
653   if (!pCursorMgr)
654     return;
655   FX_DWORD dwHitTest = HitTest(fx, fy);
656   switch (dwHitTest) {
657     case FWL_WGTHITTEST_Right: {
658       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
659       pCursorMgr->SetCursor(hCursor);
660       pCursorMgr->ShowCursor(TRUE);
661       m_eResizeType = FORM_RESIZETYPE_Right;
662       break;
663     }
664     case FWL_WGTHITTEST_Bottom: {
665       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
666       pCursorMgr->SetCursor(hCursor);
667       pCursorMgr->ShowCursor(TRUE);
668       m_eResizeType = FORM_RESIZETYPE_Bottom;
669       break;
670     }
671     case FWL_WGTHITTEST_Left: {
672       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
673       pCursorMgr->SetCursor(hCursor);
674       pCursorMgr->ShowCursor(TRUE);
675       m_eResizeType = FORM_RESIZETYPE_Left;
676       break;
677     }
678     case FWL_WGTHITTEST_Top: {
679       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
680       pCursorMgr->SetCursor(hCursor);
681       pCursorMgr->ShowCursor(TRUE);
682       m_eResizeType = FORM_RESIZETYPE_Top;
683       break;
684     }
685     case FWL_WGTHITTEST_LeftTop: {
686       FWL_HCURSOR hCursor =
687           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
688       pCursorMgr->SetCursor(hCursor);
689       pCursorMgr->ShowCursor(TRUE);
690       m_eResizeType = FORM_RESIZETYPE_LeftTop;
691       break;
692     }
693     case FWL_WGTHITTEST_LeftBottom: {
694       FWL_HCURSOR hCursor =
695           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
696       pCursorMgr->SetCursor(hCursor);
697       pCursorMgr->ShowCursor(TRUE);
698       m_eResizeType = FORM_RESIZETYPE_LeftBottom;
699       break;
700     }
701     case FWL_WGTHITTEST_RightTop: {
702       FWL_HCURSOR hCursor =
703           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
704       pCursorMgr->SetCursor(hCursor);
705       pCursorMgr->ShowCursor(TRUE);
706       m_eResizeType = FORM_RESIZETYPE_RightTop;
707       break;
708     }
709     case FWL_WGTHITTEST_RightBottom: {
710       FWL_HCURSOR hCursor =
711           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
712       pCursorMgr->SetCursor(hCursor);
713       pCursorMgr->ShowCursor(TRUE);
714       m_eResizeType = FORM_RESIZETYPE_RightBottom;
715       break;
716     }
717     default: {
718       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_Arrow);
719       pCursorMgr->SetCursor(hCursor);
720       pCursorMgr->ShowCursor(TRUE);
721     }
722   }
723 }
Layout()724 void CFWL_FormImp::Layout() {
725   GetRelativeRect(m_rtRelative);
726 #ifndef FWL_UseMacSystemBorder
727   ReSetSysBtn();
728 #endif
729   if (m_pContent) {
730     CFX_RectF rtClient;
731     GetClientRect(rtClient);
732     m_pContent->SetWidgetRect(rtClient);
733     m_pContent->Update();
734   }
735 }
ReSetSysBtn()736 void CFWL_FormImp::ReSetSysBtn() {
737   m_fCXBorder =
738       *static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_CXBorder));
739   m_fCYBorder =
740       *static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_CYBorder));
741   RemoveSysButtons();
742   IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
743   m_bCustomizeLayout = pTheme->IsCustomizedLayout(m_pInterface);
744   FX_FLOAT fCapHeight = GetCaptionHeight();
745   if (fCapHeight > 0) {
746     m_rtCaption = m_rtRelative;
747     m_rtCaption.height = fCapHeight;
748   }
749   m_iSysBox = 0;
750   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_CloseBox) {
751     m_pCloseBox = new CFWL_SysBtn;
752     if (m_bCustomizeLayout) {
753       CFWL_ThemeBackground param;
754       param.m_pWidget = m_pInterface;
755       param.m_iPart = FWL_PART_FRM_CloseBox;
756       pTheme->GetPartRect(&param, m_pCloseBox->m_rtBtn);
757     } else {
758       m_pCloseBox->m_rtBtn.Set(
759           m_rtRelative.right() - FWL_SYSBTNMARGIN - FWL_SYSBTNSIZE,
760           FWL_SYSBTNMARGIN, FWL_SYSBTNSIZE, FWL_SYSBTNSIZE);
761     }
762     m_iSysBox++;
763   }
764   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_MaximizeBox) {
765     m_pMaxBox = new CFWL_SysBtn;
766     if (m_bCustomizeLayout) {
767       CFWL_ThemeBackground param;
768       param.m_pWidget = m_pInterface;
769       param.m_iPart = FWL_PART_FRM_MaximizeBox;
770       pTheme->GetPartRect(&param, m_pMaxBox->m_rtBtn);
771     } else {
772       if (m_pCloseBox) {
773         m_pMaxBox->m_rtBtn.Set(
774             m_pCloseBox->m_rtBtn.left - FWL_SYSBTNSPAN - FWL_SYSBTNSIZE,
775             m_pCloseBox->m_rtBtn.top, FWL_SYSBTNSIZE, FWL_SYSBTNSIZE);
776       } else {
777         m_pMaxBox->m_rtBtn.Set(
778             m_rtRelative.right() - FWL_SYSBTNMARGIN - FWL_SYSBTNSIZE,
779             FWL_SYSBTNMARGIN, FWL_SYSBTNSIZE, FWL_SYSBTNSIZE);
780       }
781     }
782     m_iSysBox++;
783   }
784   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_MinimizeBox) {
785     m_pMinBox = new CFWL_SysBtn;
786     if (m_bCustomizeLayout) {
787       CFWL_ThemeBackground param;
788       param.m_pWidget = m_pInterface;
789       param.m_iPart = FWL_PART_FRM_MinimizeBox;
790       pTheme->GetPartRect(&param, m_pMinBox->m_rtBtn);
791     } else {
792       if (m_pMaxBox) {
793         m_pMinBox->m_rtBtn.Set(
794             m_pMaxBox->m_rtBtn.left - FWL_SYSBTNSPAN - FWL_SYSBTNSIZE,
795             m_pMaxBox->m_rtBtn.top, FWL_SYSBTNSIZE, FWL_SYSBTNSIZE);
796       } else if (m_pCloseBox) {
797         m_pMinBox->m_rtBtn.Set(
798             m_pCloseBox->m_rtBtn.left - FWL_SYSBTNSPAN - FWL_SYSBTNSIZE,
799             m_pCloseBox->m_rtBtn.top, FWL_SYSBTNSIZE, FWL_SYSBTNSIZE);
800       } else {
801         m_pMinBox->m_rtBtn.Set(
802             m_rtRelative.right() - FWL_SYSBTNMARGIN - FWL_SYSBTNSIZE,
803             FWL_SYSBTNMARGIN, FWL_SYSBTNSIZE, FWL_SYSBTNSIZE);
804       }
805     }
806     m_iSysBox++;
807   }
808   IFWL_FormDP* pData =
809       static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
810   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon &&
811       pData->GetIcon(m_pInterface, FALSE)) {
812     if (m_bCustomizeLayout) {
813       CFWL_ThemeBackground param;
814       param.m_pWidget = m_pInterface;
815       param.m_iPart = FWL_PART_FRM_Icon;
816       CFX_WideString wsText;
817       m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsText);
818       param.m_pData = &wsText;
819       pTheme->GetPartRect(&param, m_rtIcon);
820     } else {
821       m_rtIcon.Set(5, (m_rtCaption.height - m_fSmallIconSz) / 2, m_fSmallIconSz,
822                    m_fSmallIconSz);
823     }
824   }
825   if (m_bCustomizeLayout) {
826     CFWL_ThemeText parma;
827     parma.m_pWidget = m_pInterface;
828     parma.m_iPart = FWL_PART_FRM_HeadText;
829     m_pProperties->m_pDataProvider->GetCaption(m_pInterface, parma.m_wsText);
830     pTheme->GetPartRect(&parma, m_rtCaptionText);
831   }
832 }
RegisterForm()833 void CFWL_FormImp::RegisterForm() {
834   IFWL_NoteThread* pThread = GetOwnerThread();
835   if (!pThread)
836     return;
837   CFWL_NoteDriver* pDriver =
838       static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
839   if (!pDriver)
840     return;
841   pDriver->RegisterForm(this);
842 }
UnRegisterForm()843 void CFWL_FormImp::UnRegisterForm() {
844   IFWL_NoteThread* pThread = GetOwnerThread();
845   if (!pThread)
846     return;
847   CFWL_NoteDriver* pDriver =
848       static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
849   if (!pDriver)
850     return;
851   pDriver->UnRegisterForm(this);
852 }
IsDoModal()853 FX_BOOL CFWL_FormImp::IsDoModal() {
854   return m_bDoModalFlag;
855 }
SetThemeData()856 void CFWL_FormImp::SetThemeData() {
857   m_fSmallIconSz =
858       *static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_FRM_SmallIcon));
859   m_fBigIconSz =
860       *static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_FRM_BigIcon));
861 }
HasIcon()862 FX_BOOL CFWL_FormImp::HasIcon() {
863   IFWL_FormDP* pData =
864       static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
865   return !!pData->GetIcon(m_pInterface, FALSE);
866 }
UpdateIcon()867 void CFWL_FormImp::UpdateIcon() {
868   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
869   if (!pWidgetMgr)
870     return;
871   IFWL_FormDP* pData =
872       static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
873   CFX_DIBitmap* pBigIcon = pData->GetIcon(m_pInterface, TRUE);
874   CFX_DIBitmap* pSmallIcon = pData->GetIcon(m_pInterface, FALSE);
875   if (pBigIcon && pBigIcon != m_pBigIcon) {
876     m_pBigIcon = pBigIcon;
877     pWidgetMgr->SetWidgetIcon_Native(m_pInterface, m_pBigIcon, TRUE);
878   }
879   if (pSmallIcon && pSmallIcon != m_pSmallIcon) {
880     m_pSmallIcon = pSmallIcon;
881     pWidgetMgr->SetWidgetIcon_Native(m_pInterface, m_pBigIcon, FALSE);
882   }
883 }
UpdateCaption()884 void CFWL_FormImp::UpdateCaption() {
885   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
886   if (!pWidgetMgr)
887     return;
888   IFWL_FormDP* pData =
889       static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
890   if (!pData)
891     return;
892   CFX_WideString text;
893   pData->GetCaption(m_pInterface, text);
894   pWidgetMgr->SetWidgetCaption_Native(m_pInterface, text);
895 }
DoWidthLimit(FX_FLOAT & fLeft,FX_FLOAT & fWidth,FX_FLOAT fCurX,FX_FLOAT fSpace,FX_FLOAT fLimitMin,FX_FLOAT fLimitMax,FX_BOOL bLeft)896 void CFWL_FormImp::DoWidthLimit(FX_FLOAT& fLeft,
897                                 FX_FLOAT& fWidth,
898                                 FX_FLOAT fCurX,
899                                 FX_FLOAT fSpace,
900                                 FX_FLOAT fLimitMin,
901                                 FX_FLOAT fLimitMax,
902                                 FX_BOOL bLeft) {
903   FX_FLOAT fx = fCurX;
904   FX_FLOAT fy = 0;
905   TransformTo(NULL, fx, fy);
906   FX_FLOAT fTemp =
907       bLeft ? (fWidth - fx + fLeft + fSpace) : (fx - fLeft + fSpace);
908   if (fTemp >= fLimitMin && fTemp <= fLimitMax) {
909     fWidth = fTemp;
910     fLeft += bLeft ? (fx - fLeft - fSpace) : 0;
911   } else {
912     if (fTemp < fLimitMin && fWidth > fLimitMin) {
913       fLeft += bLeft ? (fWidth - fLimitMin) : 0;
914       fWidth = fLimitMin;
915     } else if (fTemp > fLimitMax && fWidth < fLimitMax) {
916       fLeft -= bLeft ? (fLimitMax - fWidth) : 0;
917       fWidth = fLimitMax;
918     }
919   }
920 }
DoHeightLimit(FX_FLOAT & fTop,FX_FLOAT & fHeight,FX_FLOAT fCurY,FX_FLOAT fSpace,FX_FLOAT fLimitMin,FX_FLOAT fLimitMax,FX_BOOL bTop)921 void CFWL_FormImp::DoHeightLimit(FX_FLOAT& fTop,
922                                  FX_FLOAT& fHeight,
923                                  FX_FLOAT fCurY,
924                                  FX_FLOAT fSpace,
925                                  FX_FLOAT fLimitMin,
926                                  FX_FLOAT fLimitMax,
927                                  FX_BOOL bTop) {
928   FX_FLOAT fx = 0;
929   FX_FLOAT fy = fCurY;
930   TransformTo(NULL, fx, fy);
931   FX_FLOAT fTemp = bTop ? (fHeight - fy + fTop + fSpace) : (fy - fTop + fSpace);
932   if (fTemp >= fLimitMin && fTemp <= fLimitMax) {
933     fHeight = fTemp;
934     fTop += bTop ? (fy - fTop - fSpace) : 0;
935   } else {
936     if (fTemp < fLimitMin && fHeight > fLimitMin) {
937       fTop += bTop ? (fHeight - fLimitMin) : 0;
938       fHeight = fLimitMin;
939     } else if (fTemp > fLimitMax && fHeight < fLimitMax) {
940       fTop -= bTop ? (fLimitMax - fHeight) : 0;
941       fHeight = fLimitMax;
942     }
943   }
944 }
CFWL_FormImpDelegate(CFWL_FormImp * pOwner)945 CFWL_FormImpDelegate::CFWL_FormImpDelegate(CFWL_FormImp* pOwner)
946     : m_pOwner(pOwner) {
947 }
OnProcessMessage(CFWL_Message * pMessage)948 int32_t CFWL_FormImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
949 #ifdef FWL_UseMacSystemBorder
950   if (!pMessage)
951     return 0;
952   FX_DWORD dwMsgCode = pMessage->GetClassID();
953   int32_t iRet = 1;
954   switch (dwMsgCode) {
955     case FWL_MSGHASH_Activate: {
956       m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Deactivated;
957       m_pOwner->Repaint(&m_pOwner->m_rtRelative);
958       break;
959     }
960     case FWL_MSGHASH_Deactivate: {
961       m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Deactivated;
962       m_pOwner->Repaint(&m_pOwner->m_rtRelative);
963       break;
964     }
965   }
966   return FWL_ERR_Succeeded;
967 #else
968   if (!pMessage)
969     return 0;
970   FX_DWORD dwMsgCode = pMessage->GetClassID();
971   int32_t iRet = 1;
972   switch (dwMsgCode) {
973     case FWL_MSGHASH_Activate: {
974       m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Deactivated;
975       IFWL_NoteThread* pThread = m_pOwner->GetOwnerThread();
976       CFWL_NoteDriver* pDriver =
977           static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
978       CFWL_WidgetImp* pSubFocusImp = m_pOwner->GetSubFocus();
979       IFWL_Widget* pSubFocus =
980           pSubFocusImp ? pSubFocusImp->GetInterface() : NULL;
981       if (pSubFocus && pSubFocus != pDriver->GetFocus()) {
982         pDriver->SetFocus(pSubFocus);
983       }
984       m_pOwner->Repaint(&m_pOwner->m_rtRelative);
985       break;
986     }
987     case FWL_MSGHASH_Deactivate: {
988       m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Deactivated;
989       IFWL_NoteThread* pThread = m_pOwner->GetOwnerThread();
990       CFWL_NoteDriver* pDriver =
991           static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
992       CFWL_WidgetImp* pSubFocusImp = m_pOwner->GetSubFocus();
993       IFWL_Widget* pSubFocus =
994           pSubFocusImp ? pSubFocusImp->GetInterface() : NULL;
995       if (pSubFocus) {
996         if (pSubFocus == pDriver->GetFocus()) {
997           pDriver->SetFocus(NULL);
998         } else if (pSubFocus->GetStates() & FWL_WGTSTATE_Focused) {
999           CFWL_MsgKillFocus ms;
1000           IFWL_WidgetDelegate* pDelegate = pSubFocus->SetDelegate(NULL);
1001           if (pDelegate) {
1002             pDelegate->OnProcessMessage(&ms);
1003           }
1004         }
1005       }
1006       m_pOwner->Repaint(&m_pOwner->m_rtRelative);
1007       break;
1008     }
1009     case FWL_MSGHASH_Mouse: {
1010       CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
1011       switch (pMsg->m_dwCmd) {
1012         case FWL_MSGMOUSECMD_LButtonDown: {
1013           OnLButtonDown(pMsg);
1014           break;
1015         }
1016         case FWL_MSGMOUSECMD_LButtonUp: {
1017           OnLButtonUp(pMsg);
1018           break;
1019         }
1020         case FWL_MSGMOUSECMD_MouseMove: {
1021           OnMouseMove(pMsg);
1022           break;
1023         }
1024         case FWL_MSGMOUSECMD_MouseHover: {
1025           OnMouseHover(pMsg);
1026           break;
1027         }
1028         case FWL_MSGMOUSECMD_MouseLeave: {
1029           OnMouseLeave(pMsg);
1030           break;
1031         }
1032         case FWL_MSGMOUSECMD_LButtonDblClk: {
1033           OnLButtonDblClk(pMsg);
1034           break;
1035         }
1036       }
1037       break;
1038     }
1039     case FWL_MSGHASH_Size: {
1040       CFWL_WidgetMgr* pWidgetMgr =
1041           static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
1042       if (!pWidgetMgr)
1043         return 0;
1044       pWidgetMgr->AddRedrawCounts(m_pOwner->m_pInterface);
1045       if (!m_pOwner->m_bSetMaximize) {
1046         break;
1047       }
1048       m_pOwner->m_bSetMaximize = FALSE;
1049       CFWL_MsgSize* pMsg = static_cast<CFWL_MsgSize*>(pMessage);
1050       CFX_RectF rt;
1051       pWidgetMgr->GetWidgetRect_Native(m_pOwner->m_pInterface, rt);
1052       m_pOwner->m_pProperties->m_rtWidget.left = rt.left;
1053       m_pOwner->m_pProperties->m_rtWidget.top = rt.top;
1054       m_pOwner->m_pProperties->m_rtWidget.width = (FX_FLOAT)pMsg->m_iWidth;
1055       m_pOwner->m_pProperties->m_rtWidget.height = (FX_FLOAT)pMsg->m_iHeight;
1056       m_pOwner->Update();
1057       break;
1058     }
1059     case FWL_MSGHASH_WindowMove: {
1060       OnWindowMove(static_cast<CFWL_MsgWindowMove*>(pMessage));
1061       break;
1062     }
1063     case FWL_MSGHASH_Close: {
1064       OnClose(static_cast<CFWL_MsgClose*>(pMessage));
1065       break;
1066     }
1067     default: { iRet = 0; }
1068   }
1069   return iRet;
1070 #endif
1071 }
OnProcessEvent(CFWL_Event * pEvent)1072 FWL_ERR CFWL_FormImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
1073   if (!pEvent)
1074     return FWL_ERR_Indefinite;
1075   if (pEvent->GetClassID() == FWL_EVTHASH_Close &&
1076       pEvent->m_pSrcTarget == m_pOwner->m_pInterface) {
1077   }
1078   return FWL_ERR_Succeeded;
1079 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1080 FWL_ERR CFWL_FormImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1081                                            const CFX_Matrix* pMatrix) {
1082   return m_pOwner->DrawWidget(pGraphics, pMatrix);
1083 }
OnLButtonDown(CFWL_MsgMouse * pMsg)1084 void CFWL_FormImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
1085   m_pOwner->SetGrab(TRUE);
1086   m_pOwner->m_bLButtonDown = TRUE;
1087   m_pOwner->m_eResizeType = FORM_RESIZETYPE_None;
1088   CFWL_SysBtn* pPressBtn = m_pOwner->GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy);
1089   m_pOwner->m_iCaptureBtn = m_pOwner->GetSysBtnIndex(pPressBtn);
1090   CFX_RectF rtCap;
1091   rtCap.Set(m_pOwner->m_rtCaption.left + m_pOwner->m_fCYBorder,
1092             m_pOwner->m_rtCaption.top + m_pOwner->m_fCXBorder,
1093             m_pOwner->m_rtCaption.width - FWL_SYSBTNSIZE * m_pOwner->m_iSysBox -
1094                 2 * m_pOwner->m_fCYBorder,
1095             m_pOwner->m_rtCaption.height - m_pOwner->m_fCXBorder);
1096   if (pPressBtn) {
1097     pPressBtn->SetPressed();
1098     m_pOwner->Repaint(&pPressBtn->m_rtBtn);
1099   } else if (rtCap.Contains(pMsg->m_fx, pMsg->m_fy)) {
1100     m_pOwner->m_eResizeType = FORM_RESIZETYPE_Cap;
1101   } else if ((m_pOwner->m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) &&
1102              (m_pOwner->m_pProperties->m_dwStyleExes &
1103               FWL_STYLEEXT_FRM_Resize) &&
1104              !m_pOwner->m_bMaximized) {
1105     m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
1106   }
1107   m_pOwner->m_InfoStart.m_ptStart.Set(pMsg->m_fx, pMsg->m_fy);
1108   m_pOwner->m_InfoStart.m_szStart.Set(
1109       m_pOwner->m_pProperties->m_rtWidget.width,
1110       m_pOwner->m_pProperties->m_rtWidget.height);
1111 }
OnLButtonUp(CFWL_MsgMouse * pMsg)1112 void CFWL_FormImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1113   m_pOwner->SetGrab(FALSE);
1114   m_pOwner->m_bLButtonDown = FALSE;
1115   CFWL_SysBtn* pPointBtn = m_pOwner->GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy);
1116   CFWL_SysBtn* pPressedBtn =
1117       m_pOwner->GetSysBtnByIndex(m_pOwner->m_iCaptureBtn);
1118   if (!pPressedBtn || pPointBtn != pPressedBtn) {
1119     return;
1120   }
1121   if (pPressedBtn == m_pOwner->GetSysBtnByState(FWL_SYSBUTTONSTATE_Pressed)) {
1122     pPressedBtn->SetNormal();
1123   }
1124   if (pPressedBtn == m_pOwner->m_pMaxBox) {
1125     if (m_pOwner->m_bMaximized) {
1126       m_pOwner->SetWidgetRect(m_pOwner->m_rtRestore);
1127       m_pOwner->Update();
1128       m_pOwner->Repaint();
1129     } else {
1130       m_pOwner->SetWorkAreaRect();
1131       m_pOwner->Update();
1132     }
1133     m_pOwner->m_bMaximized = !m_pOwner->m_bMaximized;
1134   } else if (pPressedBtn == m_pOwner->m_pMinBox) {
1135     CFWL_WidgetMgr* pWidgetMgr =
1136         static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
1137     if (!pWidgetMgr)
1138       return;
1139     pWidgetMgr->SetMinimize_Native(m_pOwner->m_pInterface);
1140   } else {
1141     CFWL_EvtClose eClose;
1142     eClose.m_pSrcTarget = m_pOwner->m_pInterface;
1143     m_pOwner->DispatchEvent(&eClose);
1144   }
1145 }
OnMouseMove(CFWL_MsgMouse * pMsg)1146 void CFWL_FormImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
1147   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
1148   if (m_pOwner->m_bLButtonDown) {
1149     IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
1150     IFWL_AdapterCursorMgr* pCursorMgr = pNative->GetCursorMgr();
1151     if (!pCursorMgr)
1152       return;
1153     CFWL_SysBtn* pPressedBtn =
1154         m_pOwner->GetSysBtnByIndex(m_pOwner->m_iCaptureBtn);
1155     FX_FLOAT fTop, fLeft, fWidth, fHeight;
1156     fTop = m_pOwner->m_pProperties->m_rtWidget.top;
1157     fLeft = m_pOwner->m_pProperties->m_rtWidget.left;
1158     fWidth = m_pOwner->m_pProperties->m_rtWidget.width;
1159     fHeight = m_pOwner->m_pProperties->m_rtWidget.height;
1160     FX_FLOAT fWidthMax, fWidthMin, fHeightMax, fHeightMin;
1161     if (m_pOwner->m_pContent) {
1162       m_pOwner->GetContent()->GetMaxSize(fWidthMax, fHeightMax);
1163       m_pOwner->GetContent()->GetMinSize(fWidthMin, fHeightMin);
1164     } else {
1165       fWidthMax = fHeightMax = 1024 * 4;
1166       fWidthMin = fHeightMin = 0;
1167     }
1168     FX_BOOL bWidthlimit = (fWidthMin != 0 || fWidthMax != 0);
1169     FX_BOOL bHeightlimit = (fHeightMin != 0 || fHeightMax != 0);
1170     FX_BOOL bSizelimit = bWidthlimit || bHeightlimit;
1171     if (fWidthMax != 0 || fHeightMax != 0 || fWidthMin != 0 ||
1172         fHeightMin != 0) {
1173       bSizelimit = TRUE;
1174     }
1175     if (pPressedBtn) {
1176       if (!pPressedBtn->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
1177         pPressedBtn->SetNormal();
1178       } else {
1179         pPressedBtn->SetPressed();
1180       }
1181       m_pOwner->Repaint(&pPressedBtn->m_rtBtn);
1182       return;
1183     } else if (m_pOwner->m_bMaximized) {
1184       return;
1185     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Cap) {
1186       m_pOwner->m_pProperties->m_rtWidget.Offset(
1187           pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x,
1188           pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y);
1189       pWidgetMgr->SetWidgetPosition_Native(
1190           m_pOwner->m_pInterface, m_pOwner->m_pProperties->m_rtWidget.left,
1191           m_pOwner->m_pProperties->m_rtWidget.top);
1192       return;
1193     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Right) {
1194       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
1195       pCursorMgr->SetCursor(hCursor);
1196       pCursorMgr->ShowCursor(TRUE);
1197       if (!bWidthlimit) {
1198         fWidth += pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x;
1199         m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
1200       } else {
1201         m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx,
1202                                m_pOwner->m_InfoStart.m_szStart.x -
1203                                    m_pOwner->m_InfoStart.m_ptStart.x,
1204                                fWidthMin, fWidthMax, FALSE);
1205       }
1206     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Left) {
1207       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
1208       pCursorMgr->SetCursor(hCursor);
1209       pCursorMgr->ShowCursor(TRUE);
1210       if (!bWidthlimit) {
1211         fLeft -= m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
1212         fWidth += m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
1213       } else {
1214         m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx,
1215                                m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin,
1216                                fWidthMax, TRUE);
1217       }
1218     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Bottom) {
1219       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
1220       pCursorMgr->SetCursor(hCursor);
1221       pCursorMgr->ShowCursor(TRUE);
1222       if (!bHeightlimit) {
1223         fHeight += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1224         m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
1225       } else {
1226         m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy,
1227                                 m_pOwner->m_InfoStart.m_szStart.y -
1228                                     m_pOwner->m_InfoStart.m_ptStart.y,
1229                                 fHeightMin, fHeightMax, FALSE);
1230       }
1231     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Top) {
1232       FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
1233       pCursorMgr->SetCursor(hCursor);
1234       pCursorMgr->ShowCursor(TRUE);
1235       if (!bHeightlimit) {
1236         fTop += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1237         fHeight -= pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1238       } else {
1239         m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy,
1240                                 m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin,
1241                                 fHeightMax, TRUE);
1242       }
1243     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_LeftTop) {
1244       FWL_HCURSOR hCursor =
1245           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
1246       pCursorMgr->SetCursor(hCursor);
1247       pCursorMgr->ShowCursor(TRUE);
1248       if (!bSizelimit) {
1249         fLeft -= m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
1250         fTop += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1251         fWidth += m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
1252         fHeight -= pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1253         m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
1254         m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
1255       } else {
1256         m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx,
1257                                m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin,
1258                                fWidthMax, TRUE);
1259         m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy,
1260                                 m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin,
1261                                 fHeightMax, TRUE);
1262       }
1263     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_LeftBottom) {
1264       FWL_HCURSOR hCursor =
1265           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
1266       pCursorMgr->SetCursor(hCursor);
1267       pCursorMgr->ShowCursor(TRUE);
1268       if (!bSizelimit) {
1269         fLeft -= m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
1270         fWidth += m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
1271         fHeight += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1272         m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
1273         m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
1274       } else {
1275         m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx,
1276                                m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin,
1277                                fWidthMax, TRUE);
1278         m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy,
1279                                 m_pOwner->m_InfoStart.m_szStart.y -
1280                                     m_pOwner->m_InfoStart.m_ptStart.y,
1281                                 fHeightMin, fHeightMax, FALSE);
1282       }
1283     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_RightTop) {
1284       FWL_HCURSOR hCursor =
1285           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
1286       pCursorMgr->SetCursor(hCursor);
1287       pCursorMgr->ShowCursor(TRUE);
1288       if (!bSizelimit) {
1289         fTop += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1290         fWidth += pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x;
1291         fHeight -= pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1292         m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
1293         m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
1294       } else {
1295         m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx,
1296                                m_pOwner->m_InfoStart.m_szStart.x -
1297                                    m_pOwner->m_InfoStart.m_ptStart.x,
1298                                fWidthMin, fWidthMax, FALSE);
1299         m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy,
1300                                 m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin,
1301                                 fHeightMax, TRUE);
1302       }
1303     } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_RightBottom) {
1304       FWL_HCURSOR hCursor =
1305           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
1306       pCursorMgr->SetCursor(hCursor);
1307       pCursorMgr->ShowCursor(TRUE);
1308       if (!bSizelimit) {
1309         fWidth += pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x;
1310         fHeight += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
1311         m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
1312         m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
1313       } else {
1314         m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx,
1315                                m_pOwner->m_InfoStart.m_szStart.x -
1316                                    m_pOwner->m_InfoStart.m_ptStart.x,
1317                                fWidthMin, fWidthMax, FALSE);
1318         m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy,
1319                                 m_pOwner->m_InfoStart.m_szStart.y -
1320                                     m_pOwner->m_InfoStart.m_ptStart.y,
1321                                 fHeightMin, fHeightMax, FALSE);
1322       }
1323     }
1324     if (m_pOwner->m_pContent) {
1325     }
1326     CFX_RectF rtForm;
1327     rtForm.Set(fLeft, fTop, fWidth, fHeight);
1328 #if (_FX_OS_ == _FX_MACOSX_)
1329     m_pOwner->m_pProperties->m_rtWidget = rtForm;
1330     m_pOwner->Update();
1331     m_pOwner->SetWidgetRect(rtForm);
1332 #else
1333     m_pOwner->SetWidgetRect(rtForm);
1334     m_pOwner->Update();
1335 #endif
1336     return;
1337   }
1338   if ((m_pOwner->m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) &&
1339       (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize) &&
1340       !m_pOwner->m_bMaximized) {
1341     m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
1342   }
1343   CFX_RectF rtInvalidate;
1344   rtInvalidate.Reset();
1345   CFWL_SysBtn* pPointBtn = m_pOwner->GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy);
1346   CFWL_SysBtn* pOldHover = m_pOwner->GetSysBtnByState(FWL_SYSBUTTONSTATE_Hover);
1347 #if (_FX_OS_ == _FX_MACOSX_)
1348   {
1349     if (pOldHover && pPointBtn != pOldHover) {
1350       pOldHover->SetNormal();
1351     }
1352     if (pPointBtn && pPointBtn != pOldHover) {
1353       pPointBtn->SetHover();
1354     }
1355     if (m_pOwner->m_pCloseBox) {
1356       rtInvalidate = m_pOwner->m_pCloseBox->m_rtBtn;
1357     }
1358     if (m_pOwner->m_pMaxBox) {
1359       if (rtInvalidate.IsEmpty()) {
1360         rtInvalidate = m_pOwner->m_pMaxBox->m_rtBtn;
1361       } else {
1362         rtInvalidate.Union(m_pOwner->m_pMaxBox->m_rtBtn);
1363       }
1364     }
1365     if (m_pOwner->m_pMinBox) {
1366       if (rtInvalidate.IsEmpty()) {
1367         rtInvalidate = m_pOwner->m_pMinBox->m_rtBtn;
1368       } else {
1369         rtInvalidate.Union(m_pOwner->m_pMinBox->m_rtBtn);
1370       }
1371     }
1372     if (!rtInvalidate.IsEmpty() &&
1373         rtInvalidate.Contains(pMsg->m_fx, pMsg->m_fy)) {
1374       m_pOwner->m_bMouseIn = TRUE;
1375     }
1376   }
1377 #else
1378   {
1379     if (pOldHover && pPointBtn != pOldHover) {
1380       pOldHover->SetNormal();
1381       rtInvalidate = pOldHover->m_rtBtn;
1382     }
1383     if (pPointBtn && pPointBtn != pOldHover) {
1384       pPointBtn->SetHover();
1385       if (rtInvalidate.IsEmpty()) {
1386         rtInvalidate = pPointBtn->m_rtBtn;
1387       } else {
1388         rtInvalidate.Union(pPointBtn->m_rtBtn);
1389       }
1390     }
1391   }
1392 #endif
1393   if (!rtInvalidate.IsEmpty()) {
1394     m_pOwner->Repaint(&rtInvalidate);
1395   }
1396 }
OnMouseHover(CFWL_MsgMouse * pMsg)1397 void CFWL_FormImpDelegate::OnMouseHover(CFWL_MsgMouse* pMsg) {
1398   m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
1399 }
OnMouseLeave(CFWL_MsgMouse * pMsg)1400 void CFWL_FormImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
1401   CFWL_SysBtn* pHover = m_pOwner->GetSysBtnByState(FWL_SYSBUTTONSTATE_Hover);
1402   if (pHover) {
1403     pHover->SetNormal();
1404     m_pOwner->Repaint(&pHover->m_rtBtn);
1405   }
1406   if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave &&
1407       !m_pOwner->m_bLButtonDown) {
1408     m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
1409   }
1410 }
OnLButtonDblClk(CFWL_MsgMouse * pMsg)1411 void CFWL_FormImpDelegate::OnLButtonDblClk(CFWL_MsgMouse* pMsg) {
1412   if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize) &&
1413       m_pOwner->HitTest(pMsg->m_fx, pMsg->m_fy) == FWL_WGTHITTEST_Titlebar) {
1414     if (m_pOwner->m_bMaximized) {
1415       m_pOwner->SetWidgetRect(m_pOwner->m_rtRestore);
1416     } else {
1417       m_pOwner->SetWorkAreaRect();
1418     }
1419     m_pOwner->Update();
1420     m_pOwner->m_bMaximized = !m_pOwner->m_bMaximized;
1421   }
1422 }
OnWindowMove(CFWL_MsgWindowMove * pMsg)1423 void CFWL_FormImpDelegate::OnWindowMove(CFWL_MsgWindowMove* pMsg) {
1424   m_pOwner->m_pProperties->m_rtWidget.left = pMsg->m_fx;
1425   m_pOwner->m_pProperties->m_rtWidget.top = pMsg->m_fy;
1426 }
OnClose(CFWL_MsgClose * pMsg)1427 void CFWL_FormImpDelegate::OnClose(CFWL_MsgClose* pMsg) {
1428   CFWL_EvtClose eClose;
1429   eClose.m_pSrcTarget = m_pOwner->m_pInterface;
1430   m_pOwner->DispatchEvent(&eClose);
1431 }
FWL_Accelerator_SetForm(IFWL_Form * pFrom,CFX_MapAccelerators * pMapAccel)1432 FWL_ERR FWL_Accelerator_SetForm(IFWL_Form* pFrom,
1433                                 CFX_MapAccelerators* pMapAccel) {
1434   CFWL_FormImp* pImp = static_cast<CFWL_FormImp*>(pFrom->GetImpl());
1435   if (!pImp)
1436     return FWL_ERR_Indefinite;
1437   return FWL_ERR_Succeeded;
1438 }
1439