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_noteimp.h"
10 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
11 #include "xfa/src/fwl/src/basewidget/include/fwl_pushbuttonimp.h"
12 
13 // static
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)14 IFWL_PushButton* IFWL_PushButton::Create(
15     const CFWL_WidgetImpProperties& properties,
16     IFWL_Widget* pOuter) {
17   IFWL_PushButton* pPushButton = new IFWL_PushButton;
18   CFWL_PushButtonImp* pPushButtonImpl =
19       new CFWL_PushButtonImp(properties, pOuter);
20   pPushButton->SetImpl(pPushButtonImpl);
21   pPushButtonImpl->SetInterface(pPushButton);
22   return pPushButton;
23 }
IFWL_PushButton()24 IFWL_PushButton::IFWL_PushButton() {
25 }
26 
CFWL_PushButtonImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)27 CFWL_PushButtonImp::CFWL_PushButtonImp(
28     const CFWL_WidgetImpProperties& properties,
29     IFWL_Widget* pOuter)
30     : CFWL_WidgetImp(properties, pOuter),
31       m_bBtnDown(FALSE),
32       m_dwTTOStyles(FDE_TTOSTYLE_SingleLine),
33       m_iTTOAlign(FDE_TTOALIGNMENT_Center) {
34   m_rtClient.Set(0, 0, 0, 0);
35   m_rtCaption.Set(0, 0, 0, 0);
36 }
~CFWL_PushButtonImp()37 CFWL_PushButtonImp::~CFWL_PushButtonImp() {}
GetClassName(CFX_WideString & wsClass) const38 FWL_ERR CFWL_PushButtonImp::GetClassName(CFX_WideString& wsClass) const {
39   wsClass = FWL_CLASS_PushButton;
40   return FWL_ERR_Succeeded;
41 }
GetClassID() const42 FX_DWORD CFWL_PushButtonImp::GetClassID() const {
43   return FWL_CLASSHASH_PushButton;
44 }
Initialize()45 FWL_ERR CFWL_PushButtonImp::Initialize() {
46   if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
47     return FWL_ERR_Indefinite;
48   m_pDelegate = new CFWL_PushButtonImpDelegate(this);
49   return FWL_ERR_Succeeded;
50 }
Finalize()51 FWL_ERR CFWL_PushButtonImp::Finalize() {
52   delete m_pDelegate;
53   m_pDelegate = nullptr;
54   return CFWL_WidgetImp::Finalize();
55 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)56 FWL_ERR CFWL_PushButtonImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
57   if (bAutoSize) {
58     rect.Set(0, 0, 0, 0);
59     if (m_pProperties->m_pThemeProvider == NULL) {
60       m_pProperties->m_pThemeProvider = GetAvailableTheme();
61     }
62     CFX_WideString wsCaption;
63     IFWL_PushButtonDP* pData =
64         static_cast<IFWL_PushButtonDP*>(m_pProperties->m_pDataProvider);
65     if (pData) {
66       pData->GetCaption(m_pInterface, wsCaption);
67     }
68     int32_t iLen = wsCaption.GetLength();
69     if (iLen > 0) {
70       CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider);
71       rect.Set(0, 0, sz.x, sz.y);
72     }
73     FX_FLOAT* fcaption =
74         static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_PSB_Margin));
75     rect.Inflate(*fcaption, *fcaption);
76     CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
77   } else {
78     rect = m_pProperties->m_rtWidget;
79   }
80   return FWL_ERR_Succeeded;
81 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)82 FWL_ERR CFWL_PushButtonImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
83   if ((dwStates & FWL_WGTSTATE_Disabled) && bSet) {
84     m_pProperties->m_dwStates = FWL_WGTSTATE_Disabled;
85     return FWL_ERR_Succeeded;
86   }
87   return CFWL_WidgetImp::SetStates(dwStates, bSet);
88 }
Update()89 FWL_ERR CFWL_PushButtonImp::Update() {
90   if (IsLocked()) {
91     return FWL_ERR_Indefinite;
92   }
93   if (!m_pProperties->m_pThemeProvider) {
94     m_pProperties->m_pThemeProvider = GetAvailableTheme();
95   }
96   UpdateTextOutStyles();
97   GetClientRect(m_rtClient);
98   m_rtCaption = m_rtClient;
99   FX_FLOAT* fcaption =
100       static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_PSB_Margin));
101   m_rtCaption.Inflate(-*fcaption, -*fcaption);
102   return FWL_ERR_Succeeded;
103 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)104 FWL_ERR CFWL_PushButtonImp::DrawWidget(CFX_Graphics* pGraphics,
105                                        const CFX_Matrix* pMatrix) {
106   if (!pGraphics)
107     return FWL_ERR_Indefinite;
108   if (!m_pProperties->m_pThemeProvider)
109     return FWL_ERR_Indefinite;
110   IFWL_PushButtonDP* pData =
111       static_cast<IFWL_PushButtonDP*>(m_pProperties->m_pDataProvider);
112   CFX_DIBitmap* pPicture = NULL;
113   IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
114   if (HasBorder()) {
115     DrawBorder(pGraphics, FWL_PART_PSB_Border, m_pProperties->m_pThemeProvider,
116                pMatrix);
117   }
118   if (HasEdge()) {
119     DrawEdge(pGraphics, FWL_PART_PSB_Edge, m_pProperties->m_pThemeProvider,
120              pMatrix);
121   }
122   DrawBkground(pGraphics, m_pProperties->m_pThemeProvider, pMatrix);
123   CFX_Matrix matrix;
124   matrix.Concat(*pMatrix);
125   FX_FLOAT iPicwidth = 0;
126   FX_FLOAT ipicheight = 0;
127   CFX_WideString wsCaption;
128   if (pData) {
129     pData->GetCaption(m_pInterface, wsCaption);
130   }
131   CFX_RectF rtText;
132   rtText.Set(0, 0, 0, 0);
133   if (!wsCaption.IsEmpty()) {
134     CalcTextRect(wsCaption, pTheme, 0, m_iTTOAlign, rtText);
135   }
136   switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_PSB_ModeMask) {
137     case FWL_STYLEEXT_PSB_TextOnly:
138       DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
139       break;
140     case FWL_STYLEEXT_PSB_IconOnly:
141       if (pData) {
142         pPicture = pData->GetPicture(m_pInterface);
143       }
144       if (pPicture) {
145         CFX_PointF point;
146         switch (m_iTTOAlign) {
147           case 0: {
148             point.x = m_rtClient.left;
149             point.y = m_rtClient.top;
150             break;
151           }
152           case 1: {
153             point.x = m_rtClient.left +
154                       (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
155             point.y = m_rtClient.top;
156             break;
157           }
158           case 2:
159             point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
160             point.y = m_rtClient.top;
161             break;
162           case 4:
163             point.x = m_rtClient.left;
164             point.y = m_rtClient.top + m_rtClient.height / 2 -
165                       pPicture->GetHeight() / 2;
166             break;
167           case 5:
168             point.x = m_rtClient.left +
169                       (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
170             point.y = m_rtClient.top + m_rtClient.height / 2 -
171                       pPicture->GetHeight() / 2;
172             break;
173           case 6:
174             point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
175             point.y = m_rtClient.top + m_rtClient.height / 2 -
176                       pPicture->GetHeight() / 2;
177             break;
178           case 8:
179             point.x = m_rtClient.left;
180             point.y =
181                 m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
182             break;
183           case 9:
184             point.x = m_rtClient.left +
185                       (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
186             point.y =
187                 m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
188             break;
189           case 10:
190             point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
191             point.y =
192                 m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
193             break;
194         }
195         pGraphics->DrawImage(pPicture, point, &matrix);
196       }
197       break;
198     case FWL_STYLEEXT_PSB_TextIcon:
199       if (pPicture) {
200         CFX_PointF point;
201         switch (m_iTTOAlign) {
202           case 0: {
203             point.x = m_rtClient.left;
204             point.y = m_rtClient.top;
205             iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
206             ipicheight =
207                 pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
208             break;
209           }
210           case 1: {
211             point.x =
212                 m_rtClient.left + (m_rtClient.width / 2 -
213                                    (pPicture->GetWidth() + rtText.width) / 2);
214             point.y = m_rtClient.top;
215             iPicwidth = pPicture->GetWidth() -
216                         ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
217                         rtText.width / 2 - 7;
218             ipicheight =
219                 pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
220             break;
221           }
222           case 2:
223             point.x = m_rtClient.left + m_rtClient.width -
224                       pPicture->GetWidth() - rtText.width;
225             point.y = m_rtClient.top;
226             iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
227                         pPicture->GetWidth() - rtText.width + 7;
228             ipicheight =
229                 pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
230             break;
231           case 4:
232             point.x = m_rtClient.left;
233             point.y = m_rtClient.top + m_rtClient.height / 2 -
234                       pPicture->GetHeight() / 2;
235             iPicwidth = m_rtClient.left + pPicture->GetWidth() - 7;
236             break;
237           case 5:
238             point.x =
239                 m_rtClient.left + (m_rtClient.width / 2 -
240                                    (pPicture->GetWidth() + rtText.width) / 2);
241             point.y = m_rtClient.top + m_rtClient.height / 2 -
242                       pPicture->GetHeight() / 2;
243             iPicwidth = pPicture->GetWidth() -
244                         ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
245                         rtText.width / 2 - 7;
246             break;
247           case 6:
248             point.x = m_rtClient.left + m_rtClient.width -
249                       pPicture->GetWidth() - rtText.width;
250             point.y = m_rtClient.top + m_rtClient.height / 2 -
251                       pPicture->GetHeight() / 2;
252             iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
253                         pPicture->GetWidth() - rtText.width + 7;
254             break;
255           case 8:
256             point.x = m_rtClient.left;
257             point.y =
258                 m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
259             iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
260             ipicheight -= rtText.height / 2;
261             break;
262           case 9:
263             point.x =
264                 m_rtClient.left + (m_rtClient.width / 2 -
265                                    (pPicture->GetWidth() + rtText.width) / 2);
266             point.y =
267                 m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
268             iPicwidth = pPicture->GetWidth() -
269                         ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
270                         rtText.width / 2 - 7;
271             ipicheight -= rtText.height / 2;
272             break;
273           case 10:
274             point.x = m_rtClient.left + m_rtClient.width -
275                       pPicture->GetWidth() - rtText.width;
276             point.y =
277                 m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
278             iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
279                         pPicture->GetWidth() - rtText.width + 7;
280             ipicheight -= rtText.height / 2;
281             break;
282         }
283         pGraphics->DrawImage(pPicture, point, &matrix);
284       }
285       matrix.e += m_rtClient.left + iPicwidth;
286       matrix.f += m_rtClient.top + ipicheight;
287       DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
288       break;
289   }
290   return FWL_ERR_Succeeded;
291 }
DrawBkground(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)292 void CFWL_PushButtonImp::DrawBkground(CFX_Graphics* pGraphics,
293                                       IFWL_ThemeProvider* pTheme,
294                                       const CFX_Matrix* pMatrix) {
295   CFWL_ThemeBackground param;
296   param.m_pWidget = m_pInterface;
297   param.m_iPart = FWL_PART_PSB_Background;
298   param.m_dwStates = GetPartStates();
299   param.m_pGraphics = pGraphics;
300   if (pMatrix) {
301     param.m_matrix.Concat(*pMatrix);
302   }
303   param.m_rtPart = m_rtClient;
304   if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
305     param.m_pData = &m_rtCaption;
306   }
307   pTheme->DrawBackground(&param);
308 }
DrawText(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)309 void CFWL_PushButtonImp::DrawText(CFX_Graphics* pGraphics,
310                                   IFWL_ThemeProvider* pTheme,
311                                   const CFX_Matrix* pMatrix) {
312   if (!m_pProperties->m_pDataProvider)
313     return;
314   CFX_WideString wsCaption;
315   m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
316   if (wsCaption.IsEmpty()) {
317     return;
318   }
319   CFWL_ThemeText param;
320   param.m_pWidget = m_pInterface;
321   param.m_iPart = FWL_PART_PSB_Caption;
322   param.m_dwStates = GetPartStates();
323   param.m_pGraphics = pGraphics;
324   if (pMatrix) {
325     param.m_matrix.Concat(*pMatrix);
326   }
327   param.m_rtPart = m_rtCaption;
328   param.m_wsText = wsCaption;
329   param.m_dwTTOStyles = m_dwTTOStyles;
330   param.m_iTTOAlign = m_iTTOAlign;
331   pTheme->DrawText(&param);
332 }
GetPartStates()333 FX_DWORD CFWL_PushButtonImp::GetPartStates() {
334   FX_DWORD dwStates = FWL_PARTSTATE_PSB_Normal;
335   if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
336     dwStates |= FWL_PARTSTATE_PSB_Focused;
337   }
338   if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
339     dwStates = FWL_PARTSTATE_PSB_Disabled;
340   } else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) {
341     dwStates |= FWL_PARTSTATE_PSB_Pressed;
342   } else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) {
343     dwStates |= FWL_PARTSTATE_PSB_Hovered;
344   } else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Default) {
345     dwStates |= FWL_PARTSTATE_PSB_Default;
346   }
347   return dwStates;
348 }
UpdateTextOutStyles()349 void CFWL_PushButtonImp::UpdateTextOutStyles() {
350   m_iTTOAlign = FDE_TTOALIGNMENT_Center;
351   switch (m_pProperties->m_dwStyleExes &
352           (FWL_STYLEEXT_PSB_HLayoutMask | FWL_STYLEEXT_PSB_VLayoutMask)) {
353     case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Top: {
354       m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
355       break;
356     }
357     case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Top: {
358       m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter;
359       break;
360     }
361     case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Top: {
362       m_iTTOAlign = FDE_TTOALIGNMENT_TopRight;
363       break;
364     }
365     case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_VCenter: {
366       m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
367       break;
368     }
369     case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_VCenter: {
370       m_iTTOAlign = FDE_TTOALIGNMENT_Center;
371       break;
372     }
373     case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_VCenter: {
374       m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight;
375       break;
376     }
377     case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Bottom: {
378       m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft;
379       break;
380     }
381     case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Bottom: {
382       m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter;
383       break;
384     }
385     case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Bottom: {
386       m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight;
387       break;
388     }
389     default: {}
390   }
391   m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
392   if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
393     m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
394   }
395 }
CFWL_PushButtonImpDelegate(CFWL_PushButtonImp * pOwner)396 CFWL_PushButtonImpDelegate::CFWL_PushButtonImpDelegate(
397     CFWL_PushButtonImp* pOwner)
398     : m_pOwner(pOwner) {}
OnProcessMessage(CFWL_Message * pMessage)399 int32_t CFWL_PushButtonImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
400   if (!pMessage)
401     return 0;
402   if (!m_pOwner->IsEnabled()) {
403     return 1;
404   }
405   int32_t iRet = 1;
406   FX_DWORD dwMsgCode = pMessage->GetClassID();
407   switch (dwMsgCode) {
408     case FWL_MSGHASH_SetFocus:
409     case FWL_MSGHASH_KillFocus: {
410       OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
411       break;
412     }
413     case FWL_MSGHASH_Mouse: {
414       CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
415       FX_DWORD dwCmd = pMsg->m_dwCmd;
416       switch (dwCmd) {
417         case FWL_MSGMOUSECMD_LButtonDown: {
418           OnLButtonDown(pMsg);
419           break;
420         }
421         case FWL_MSGMOUSECMD_LButtonUp: {
422           OnLButtonUp(pMsg);
423           break;
424         }
425         case FWL_MSGMOUSECMD_MouseMove: {
426           OnMouseMove(pMsg);
427           break;
428         }
429         case FWL_MSGMOUSECMD_MouseLeave: {
430           OnMouseLeave(pMsg);
431           break;
432         }
433         default: {}
434       }
435       break;
436     }
437     case FWL_MSGHASH_Key: {
438       CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
439       if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
440         OnKeyDown(pKey);
441       }
442       break;
443     }
444     default: {
445       iRet = 0;
446       break;
447     }
448   }
449   CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
450   return iRet;
451 }
OnProcessEvent(CFWL_Event * pEvent)452 FWL_ERR CFWL_PushButtonImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
453   return FWL_ERR_Succeeded;
454 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)455 FWL_ERR CFWL_PushButtonImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
456                                                  const CFX_Matrix* pMatrix) {
457   return m_pOwner->DrawWidget(pGraphics, pMatrix);
458 }
OnFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)459 void CFWL_PushButtonImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
460                                                 FX_BOOL bSet) {
461   if (bSet) {
462     m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
463   } else {
464     m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
465   }
466   m_pOwner->Repaint(&m_pOwner->m_rtClient);
467 }
OnLButtonDown(CFWL_MsgMouse * pMsg)468 void CFWL_PushButtonImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
469   if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
470     m_pOwner->SetFocus(TRUE);
471   }
472   m_pOwner->m_bBtnDown = TRUE;
473   m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
474   m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed;
475   m_pOwner->Repaint(&m_pOwner->m_rtClient);
476 }
OnLButtonUp(CFWL_MsgMouse * pMsg)477 void CFWL_PushButtonImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
478   m_pOwner->m_bBtnDown = FALSE;
479   if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
480     m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
481     m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
482   } else {
483     m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
484     m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
485   }
486   if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
487     CFWL_EvtClick wmClick;
488     wmClick.m_pSrcTarget = m_pOwner->m_pInterface;
489     m_pOwner->DispatchEvent(&wmClick);
490   }
491   m_pOwner->Repaint(&m_pOwner->m_rtClient);
492 }
OnMouseMove(CFWL_MsgMouse * pMsg)493 void CFWL_PushButtonImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
494   FX_BOOL bRepaint = FALSE;
495   if (m_pOwner->m_bBtnDown) {
496     if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
497       if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) == 0) {
498         m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed;
499         bRepaint = TRUE;
500       }
501       if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) {
502         m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
503         bRepaint = TRUE;
504       }
505     } else {
506       if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) {
507         m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
508         bRepaint = TRUE;
509       }
510       if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
511         m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
512         bRepaint = TRUE;
513       }
514     }
515   } else {
516     if (!m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
517       return;
518     }
519     if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
520       m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
521       bRepaint = TRUE;
522     }
523   }
524   if (bRepaint) {
525     m_pOwner->Repaint(&m_pOwner->m_rtClient);
526   }
527 }
OnMouseLeave(CFWL_MsgMouse * pMsg)528 void CFWL_PushButtonImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
529   m_pOwner->m_bBtnDown = FALSE;
530   m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
531   m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
532   m_pOwner->Repaint(&m_pOwner->m_rtClient);
533 }
OnKeyDown(CFWL_MsgKey * pMsg)534 void CFWL_PushButtonImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
535   if (pMsg->m_dwKeyCode == FWL_VKEY_Return) {
536     CFWL_EvtMouse wmMouse;
537     wmMouse.m_pSrcTarget = m_pOwner->m_pInterface;
538     wmMouse.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
539     m_pOwner->DispatchEvent(&wmMouse);
540     CFWL_EvtClick wmClick;
541     wmClick.m_pSrcTarget = m_pOwner->m_pInterface;
542     m_pOwner->DispatchEvent(&wmClick);
543     return;
544   }
545   if (pMsg->m_dwKeyCode != FWL_VKEY_Tab) {
546     return;
547   }
548   m_pOwner->DispatchKeyEvent(pMsg);
549 }
550