xref: /aosp_15_r20/external/pdfium/xfa/fwl/cfwl_pushbutton.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_pushbutton.h"
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fde/cfde_textout.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_event.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_eventmouse.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_messagekey.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_messagemouse.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_notedriver.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_themebackground.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_themetext.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/fwl_widgetdef.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/ifwl_themeprovider.h"
19*3ac0a46fSAndroid Build Coastguard Worker 
CFWL_PushButton(CFWL_App * app)20*3ac0a46fSAndroid Build Coastguard Worker CFWL_PushButton::CFWL_PushButton(CFWL_App* app)
21*3ac0a46fSAndroid Build Coastguard Worker     : CFWL_Widget(app, Properties(), nullptr) {}
22*3ac0a46fSAndroid Build Coastguard Worker 
23*3ac0a46fSAndroid Build Coastguard Worker CFWL_PushButton::~CFWL_PushButton() = default;
24*3ac0a46fSAndroid Build Coastguard Worker 
GetClassID() const25*3ac0a46fSAndroid Build Coastguard Worker FWL_Type CFWL_PushButton::GetClassID() const {
26*3ac0a46fSAndroid Build Coastguard Worker   return FWL_Type::PushButton;
27*3ac0a46fSAndroid Build Coastguard Worker }
28*3ac0a46fSAndroid Build Coastguard Worker 
SetStates(uint32_t dwStates)29*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::SetStates(uint32_t dwStates) {
30*3ac0a46fSAndroid Build Coastguard Worker   if (dwStates & FWL_STATE_WGT_Disabled) {
31*3ac0a46fSAndroid Build Coastguard Worker     m_Properties.m_dwStates = FWL_STATE_WGT_Disabled;
32*3ac0a46fSAndroid Build Coastguard Worker     return;
33*3ac0a46fSAndroid Build Coastguard Worker   }
34*3ac0a46fSAndroid Build Coastguard Worker   CFWL_Widget::SetStates(dwStates);
35*3ac0a46fSAndroid Build Coastguard Worker }
36*3ac0a46fSAndroid Build Coastguard Worker 
Update()37*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::Update() {
38*3ac0a46fSAndroid Build Coastguard Worker   if (IsLocked())
39*3ac0a46fSAndroid Build Coastguard Worker     return;
40*3ac0a46fSAndroid Build Coastguard Worker 
41*3ac0a46fSAndroid Build Coastguard Worker   m_ClientRect = GetClientRect();
42*3ac0a46fSAndroid Build Coastguard Worker   m_CaptionRect = m_ClientRect;
43*3ac0a46fSAndroid Build Coastguard Worker }
44*3ac0a46fSAndroid Build Coastguard Worker 
DrawWidget(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & matrix)45*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::DrawWidget(CFGAS_GEGraphics* pGraphics,
46*3ac0a46fSAndroid Build Coastguard Worker                                  const CFX_Matrix& matrix) {
47*3ac0a46fSAndroid Build Coastguard Worker   if (!pGraphics)
48*3ac0a46fSAndroid Build Coastguard Worker     return;
49*3ac0a46fSAndroid Build Coastguard Worker 
50*3ac0a46fSAndroid Build Coastguard Worker   if (HasBorder())
51*3ac0a46fSAndroid Build Coastguard Worker     DrawBorder(pGraphics, CFWL_ThemePart::Part::kBorder, matrix);
52*3ac0a46fSAndroid Build Coastguard Worker 
53*3ac0a46fSAndroid Build Coastguard Worker   DrawBkground(pGraphics, matrix);
54*3ac0a46fSAndroid Build Coastguard Worker }
55*3ac0a46fSAndroid Build Coastguard Worker 
DrawBkground(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & matrix)56*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::DrawBkground(CFGAS_GEGraphics* pGraphics,
57*3ac0a46fSAndroid Build Coastguard Worker                                    const CFX_Matrix& matrix) {
58*3ac0a46fSAndroid Build Coastguard Worker   CFWL_ThemeBackground param(CFWL_ThemePart::Part::kBackground, this,
59*3ac0a46fSAndroid Build Coastguard Worker                              pGraphics);
60*3ac0a46fSAndroid Build Coastguard Worker   param.m_dwStates = GetPartStates();
61*3ac0a46fSAndroid Build Coastguard Worker   param.m_matrix = matrix;
62*3ac0a46fSAndroid Build Coastguard Worker   param.m_PartRect = m_ClientRect;
63*3ac0a46fSAndroid Build Coastguard Worker   if (m_Properties.m_dwStates & FWL_STATE_WGT_Focused)
64*3ac0a46fSAndroid Build Coastguard Worker     param.m_pRtData = &m_CaptionRect;
65*3ac0a46fSAndroid Build Coastguard Worker   GetThemeProvider()->DrawBackground(param);
66*3ac0a46fSAndroid Build Coastguard Worker }
67*3ac0a46fSAndroid Build Coastguard Worker 
GetPartStates()68*3ac0a46fSAndroid Build Coastguard Worker Mask<CFWL_PartState> CFWL_PushButton::GetPartStates() {
69*3ac0a46fSAndroid Build Coastguard Worker   Mask<CFWL_PartState> dwStates = CFWL_PartState::kNormal;
70*3ac0a46fSAndroid Build Coastguard Worker   if (m_Properties.m_dwStates & FWL_STATE_WGT_Focused)
71*3ac0a46fSAndroid Build Coastguard Worker     dwStates |= CFWL_PartState::kFocused;
72*3ac0a46fSAndroid Build Coastguard Worker   if (m_Properties.m_dwStates & FWL_STATE_WGT_Disabled)
73*3ac0a46fSAndroid Build Coastguard Worker     dwStates = CFWL_PartState::kDisabled;
74*3ac0a46fSAndroid Build Coastguard Worker   else if (m_Properties.m_dwStates & FWL_STATE_PSB_Pressed)
75*3ac0a46fSAndroid Build Coastguard Worker     dwStates |= CFWL_PartState::kPressed;
76*3ac0a46fSAndroid Build Coastguard Worker   else if (m_Properties.m_dwStates & FWL_STATE_PSB_Hovered)
77*3ac0a46fSAndroid Build Coastguard Worker     dwStates |= CFWL_PartState::kHovered;
78*3ac0a46fSAndroid Build Coastguard Worker   return dwStates;
79*3ac0a46fSAndroid Build Coastguard Worker }
80*3ac0a46fSAndroid Build Coastguard Worker 
OnProcessMessage(CFWL_Message * pMessage)81*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnProcessMessage(CFWL_Message* pMessage) {
82*3ac0a46fSAndroid Build Coastguard Worker   if (!IsEnabled())
83*3ac0a46fSAndroid Build Coastguard Worker     return;
84*3ac0a46fSAndroid Build Coastguard Worker 
85*3ac0a46fSAndroid Build Coastguard Worker   switch (pMessage->GetType()) {
86*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kSetFocus:
87*3ac0a46fSAndroid Build Coastguard Worker       OnFocusGained();
88*3ac0a46fSAndroid Build Coastguard Worker       break;
89*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kKillFocus:
90*3ac0a46fSAndroid Build Coastguard Worker       OnFocusLost();
91*3ac0a46fSAndroid Build Coastguard Worker       break;
92*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kMouse: {
93*3ac0a46fSAndroid Build Coastguard Worker       CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
94*3ac0a46fSAndroid Build Coastguard Worker       switch (pMsg->m_dwCmd) {
95*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kLeftButtonDown:
96*3ac0a46fSAndroid Build Coastguard Worker           OnLButtonDown(pMsg);
97*3ac0a46fSAndroid Build Coastguard Worker           break;
98*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kLeftButtonUp:
99*3ac0a46fSAndroid Build Coastguard Worker           OnLButtonUp(pMsg);
100*3ac0a46fSAndroid Build Coastguard Worker           break;
101*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kMove:
102*3ac0a46fSAndroid Build Coastguard Worker           OnMouseMove(pMsg);
103*3ac0a46fSAndroid Build Coastguard Worker           break;
104*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kLeave:
105*3ac0a46fSAndroid Build Coastguard Worker           OnMouseLeave(pMsg);
106*3ac0a46fSAndroid Build Coastguard Worker           break;
107*3ac0a46fSAndroid Build Coastguard Worker         default:
108*3ac0a46fSAndroid Build Coastguard Worker           break;
109*3ac0a46fSAndroid Build Coastguard Worker       }
110*3ac0a46fSAndroid Build Coastguard Worker       break;
111*3ac0a46fSAndroid Build Coastguard Worker     }
112*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kKey: {
113*3ac0a46fSAndroid Build Coastguard Worker       CFWL_MessageKey* pKey = static_cast<CFWL_MessageKey*>(pMessage);
114*3ac0a46fSAndroid Build Coastguard Worker       if (pKey->m_dwCmd == CFWL_MessageKey::KeyCommand::kKeyDown)
115*3ac0a46fSAndroid Build Coastguard Worker         OnKeyDown(pKey);
116*3ac0a46fSAndroid Build Coastguard Worker       break;
117*3ac0a46fSAndroid Build Coastguard Worker     }
118*3ac0a46fSAndroid Build Coastguard Worker     default:
119*3ac0a46fSAndroid Build Coastguard Worker       break;
120*3ac0a46fSAndroid Build Coastguard Worker   }
121*3ac0a46fSAndroid Build Coastguard Worker   // Dst target could be |this|, continue only if not destroyed by above.
122*3ac0a46fSAndroid Build Coastguard Worker   if (pMessage->GetDstTarget())
123*3ac0a46fSAndroid Build Coastguard Worker     CFWL_Widget::OnProcessMessage(pMessage);
124*3ac0a46fSAndroid Build Coastguard Worker }
125*3ac0a46fSAndroid Build Coastguard Worker 
OnDrawWidget(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & matrix)126*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnDrawWidget(CFGAS_GEGraphics* pGraphics,
127*3ac0a46fSAndroid Build Coastguard Worker                                    const CFX_Matrix& matrix) {
128*3ac0a46fSAndroid Build Coastguard Worker   DrawWidget(pGraphics, matrix);
129*3ac0a46fSAndroid Build Coastguard Worker }
130*3ac0a46fSAndroid Build Coastguard Worker 
OnFocusGained()131*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnFocusGained() {
132*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates |= FWL_STATE_WGT_Focused;
133*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
134*3ac0a46fSAndroid Build Coastguard Worker }
135*3ac0a46fSAndroid Build Coastguard Worker 
OnFocusLost()136*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnFocusLost() {
137*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates &= ~FWL_STATE_WGT_Focused;
138*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
139*3ac0a46fSAndroid Build Coastguard Worker }
140*3ac0a46fSAndroid Build Coastguard Worker 
OnLButtonDown(CFWL_MessageMouse * pMsg)141*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnLButtonDown(CFWL_MessageMouse* pMsg) {
142*3ac0a46fSAndroid Build Coastguard Worker   m_bBtnDown = true;
143*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates |= FWL_STATE_PSB_Hovered;
144*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates |= FWL_STATE_PSB_Pressed;
145*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
146*3ac0a46fSAndroid Build Coastguard Worker }
147*3ac0a46fSAndroid Build Coastguard Worker 
OnLButtonUp(CFWL_MessageMouse * pMsg)148*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnLButtonUp(CFWL_MessageMouse* pMsg) {
149*3ac0a46fSAndroid Build Coastguard Worker   m_bBtnDown = false;
150*3ac0a46fSAndroid Build Coastguard Worker   if (m_ClientRect.Contains(pMsg->m_pos)) {
151*3ac0a46fSAndroid Build Coastguard Worker     m_Properties.m_dwStates &= ~FWL_STATE_PSB_Pressed;
152*3ac0a46fSAndroid Build Coastguard Worker     m_Properties.m_dwStates |= FWL_STATE_PSB_Hovered;
153*3ac0a46fSAndroid Build Coastguard Worker   } else {
154*3ac0a46fSAndroid Build Coastguard Worker     m_Properties.m_dwStates &= ~FWL_STATE_PSB_Hovered;
155*3ac0a46fSAndroid Build Coastguard Worker     m_Properties.m_dwStates &= ~FWL_STATE_PSB_Pressed;
156*3ac0a46fSAndroid Build Coastguard Worker   }
157*3ac0a46fSAndroid Build Coastguard Worker   if (m_ClientRect.Contains(pMsg->m_pos)) {
158*3ac0a46fSAndroid Build Coastguard Worker     CFWL_Event wmClick(CFWL_Event::Type::Click, this);
159*3ac0a46fSAndroid Build Coastguard Worker     DispatchEvent(&wmClick);
160*3ac0a46fSAndroid Build Coastguard Worker   }
161*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
162*3ac0a46fSAndroid Build Coastguard Worker }
163*3ac0a46fSAndroid Build Coastguard Worker 
OnMouseMove(CFWL_MessageMouse * pMsg)164*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnMouseMove(CFWL_MessageMouse* pMsg) {
165*3ac0a46fSAndroid Build Coastguard Worker   bool bRepaint = false;
166*3ac0a46fSAndroid Build Coastguard Worker   if (m_bBtnDown) {
167*3ac0a46fSAndroid Build Coastguard Worker     if (m_ClientRect.Contains(pMsg->m_pos)) {
168*3ac0a46fSAndroid Build Coastguard Worker       if ((m_Properties.m_dwStates & FWL_STATE_PSB_Pressed) == 0) {
169*3ac0a46fSAndroid Build Coastguard Worker         m_Properties.m_dwStates |= FWL_STATE_PSB_Pressed;
170*3ac0a46fSAndroid Build Coastguard Worker         bRepaint = true;
171*3ac0a46fSAndroid Build Coastguard Worker       }
172*3ac0a46fSAndroid Build Coastguard Worker       if (m_Properties.m_dwStates & FWL_STATE_PSB_Hovered) {
173*3ac0a46fSAndroid Build Coastguard Worker         m_Properties.m_dwStates &= ~FWL_STATE_PSB_Hovered;
174*3ac0a46fSAndroid Build Coastguard Worker         bRepaint = true;
175*3ac0a46fSAndroid Build Coastguard Worker       }
176*3ac0a46fSAndroid Build Coastguard Worker     } else {
177*3ac0a46fSAndroid Build Coastguard Worker       if (m_Properties.m_dwStates & FWL_STATE_PSB_Pressed) {
178*3ac0a46fSAndroid Build Coastguard Worker         m_Properties.m_dwStates &= ~FWL_STATE_PSB_Pressed;
179*3ac0a46fSAndroid Build Coastguard Worker         bRepaint = true;
180*3ac0a46fSAndroid Build Coastguard Worker       }
181*3ac0a46fSAndroid Build Coastguard Worker       if ((m_Properties.m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
182*3ac0a46fSAndroid Build Coastguard Worker         m_Properties.m_dwStates |= FWL_STATE_PSB_Hovered;
183*3ac0a46fSAndroid Build Coastguard Worker         bRepaint = true;
184*3ac0a46fSAndroid Build Coastguard Worker       }
185*3ac0a46fSAndroid Build Coastguard Worker     }
186*3ac0a46fSAndroid Build Coastguard Worker   } else {
187*3ac0a46fSAndroid Build Coastguard Worker     if (!m_ClientRect.Contains(pMsg->m_pos))
188*3ac0a46fSAndroid Build Coastguard Worker       return;
189*3ac0a46fSAndroid Build Coastguard Worker     if ((m_Properties.m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
190*3ac0a46fSAndroid Build Coastguard Worker       m_Properties.m_dwStates |= FWL_STATE_PSB_Hovered;
191*3ac0a46fSAndroid Build Coastguard Worker       bRepaint = true;
192*3ac0a46fSAndroid Build Coastguard Worker     }
193*3ac0a46fSAndroid Build Coastguard Worker   }
194*3ac0a46fSAndroid Build Coastguard Worker   if (bRepaint)
195*3ac0a46fSAndroid Build Coastguard Worker     RepaintRect(m_ClientRect);
196*3ac0a46fSAndroid Build Coastguard Worker }
197*3ac0a46fSAndroid Build Coastguard Worker 
OnMouseLeave(CFWL_MessageMouse * pMsg)198*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnMouseLeave(CFWL_MessageMouse* pMsg) {
199*3ac0a46fSAndroid Build Coastguard Worker   m_bBtnDown = false;
200*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates &= ~FWL_STATE_PSB_Hovered;
201*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates &= ~FWL_STATE_PSB_Pressed;
202*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
203*3ac0a46fSAndroid Build Coastguard Worker }
204*3ac0a46fSAndroid Build Coastguard Worker 
OnKeyDown(CFWL_MessageKey * pMsg)205*3ac0a46fSAndroid Build Coastguard Worker void CFWL_PushButton::OnKeyDown(CFWL_MessageKey* pMsg) {
206*3ac0a46fSAndroid Build Coastguard Worker   if (pMsg->m_dwKeyCodeOrChar != XFA_FWL_VKEY_Return)
207*3ac0a46fSAndroid Build Coastguard Worker     return;
208*3ac0a46fSAndroid Build Coastguard Worker 
209*3ac0a46fSAndroid Build Coastguard Worker   CFWL_EventMouse wmMouse(this, nullptr,
210*3ac0a46fSAndroid Build Coastguard Worker                           CFWL_MessageMouse::MouseCommand::kLeftButtonUp);
211*3ac0a46fSAndroid Build Coastguard Worker   DispatchEvent(&wmMouse);
212*3ac0a46fSAndroid Build Coastguard Worker   if (!wmMouse.GetSrcTarget())
213*3ac0a46fSAndroid Build Coastguard Worker     return;
214*3ac0a46fSAndroid Build Coastguard Worker 
215*3ac0a46fSAndroid Build Coastguard Worker   CFWL_Event wmClick(CFWL_Event::Type::Click, this);
216*3ac0a46fSAndroid Build Coastguard Worker   DispatchEvent(&wmClick);
217*3ac0a46fSAndroid Build Coastguard Worker }
218