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