blob: b10a0854a7047eff5f92dd277598af33c007c264 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhang60f507b2015-06-13 00:41:00 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhang606346f2015-06-19 18:11:07 -07007#include <map>
tsepez0d164f82017-01-09 07:28:13 -08008#include <vector>
Lei Zhang606346f2015-06-19 18:11:07 -07009
dan sinclair89e904b2016-03-23 19:29:15 -040010#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
11#include "fpdfsdk/pdfwindow/PWL_Utils.h"
12#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
tsepez36eb4bd2016-10-03 15:24:27 -070013#include "third_party/base/ptr_util.h"
tsepez0d164f82017-01-09 07:28:13 -080014#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070015
Nico Weber9d8ec5a2015-08-04 13:00:21 -070016static std::map<int32_t, CPWL_Timer*>& GetPWLTimeMap() {
Bruce Dawson26d96ff2015-01-05 15:31:49 -080017 // Leak the object at shutdown.
Lei Zhang606346f2015-06-19 18:11:07 -070018 static auto timeMap = new std::map<int32_t, CPWL_Timer*>;
Bruce Dawson26d96ff2015-01-05 15:31:49 -080019 return *timeMap;
20}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070021
weili625ad662016-06-15 11:21:33 -070022PWL_CREATEPARAM::PWL_CREATEPARAM()
23 : rcRectWnd(0, 0, 0, 0),
24 pSystemHandler(nullptr),
25 pFontMap(nullptr),
26 pProvider(nullptr),
27 pFocusHandler(nullptr),
28 dwFlags(0),
29 sBackgroundColor(),
dsinclair8faac622016-09-15 12:41:50 -070030 pAttachedWidget(nullptr),
weili625ad662016-06-15 11:21:33 -070031 nBorderStyle(BorderStyle::SOLID),
32 dwBorderWidth(1),
33 sBorderColor(),
34 sTextColor(),
weili625ad662016-06-15 11:21:33 -070035 nTransparency(255),
36 fFontSize(PWL_DEFAULT_FONTSIZE),
37 sDash(3, 0, 0),
38 pAttachedData(nullptr),
39 pParentWnd(nullptr),
40 pMsgControl(nullptr),
41 eCursorType(FXCT_ARROW),
42 mtChild(1, 0, 0, 1, 0, 0) {}
43
44PWL_CREATEPARAM::PWL_CREATEPARAM(const PWL_CREATEPARAM& other) = default;
45
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached,
dsinclairb9590102016-04-27 06:38:59 -070047 CFX_SystemHandler* pSystemHandler)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 : m_nTimerID(0), m_pAttached(pAttached), m_pSystemHandler(pSystemHandler) {
Lei Zhang96660d62015-12-14 18:27:25 -080049 ASSERT(m_pAttached);
50 ASSERT(m_pSystemHandler);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051}
52
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053CPWL_Timer::~CPWL_Timer() {
54 KillPWLTimer();
55}
56
57int32_t CPWL_Timer::SetPWLTimer(int32_t nElapse) {
58 if (m_nTimerID != 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -070059 KillPWLTimer();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc);
61
62 GetPWLTimeMap()[m_nTimerID] = this;
63 return m_nTimerID;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064}
65
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066void CPWL_Timer::KillPWLTimer() {
67 if (m_nTimerID == 0)
68 return;
Lei Zhang606346f2015-06-19 18:11:07 -070069
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 m_pSystemHandler->KillTimer(m_nTimerID);
71 GetPWLTimeMap().erase(m_nTimerID);
72 m_nTimerID = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070073}
74
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075void CPWL_Timer::TimerProc(int32_t idEvent) {
76 auto it = GetPWLTimeMap().find(idEvent);
77 if (it == GetPWLTimeMap().end())
78 return;
Lei Zhang606346f2015-06-19 18:11:07 -070079
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 CPWL_Timer* pTimer = it->second;
81 if (pTimer->m_pAttached)
82 pTimer->m_pAttached->TimerProc();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070083}
84
weili2d5b0202016-08-03 11:06:49 -070085CPWL_TimerHandler::CPWL_TimerHandler() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086
weili2d5b0202016-08-03 11:06:49 -070087CPWL_TimerHandler::~CPWL_TimerHandler() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089void CPWL_TimerHandler::BeginTimer(int32_t nElapse) {
90 if (!m_pTimer)
tsepez36eb4bd2016-10-03 15:24:27 -070091 m_pTimer = pdfium::MakeUnique<CPWL_Timer>(this, GetSystemHandler());
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092
tsepez36eb4bd2016-10-03 15:24:27 -070093 m_pTimer->SetPWLTimer(nElapse);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070094}
95
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096void CPWL_TimerHandler::EndTimer() {
97 if (m_pTimer)
98 m_pTimer->KillPWLTimer();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099}
100
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101void CPWL_TimerHandler::TimerProc() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103class CPWL_MsgControl {
104 friend class CPWL_Wnd;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700105
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106 public:
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800107 explicit CPWL_MsgControl(CPWL_Wnd* pWnd) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108 m_pCreatedWnd = pWnd;
109 Default();
110 }
111
Dan Sinclairf766ad22016-03-14 13:51:24 -0400112 ~CPWL_MsgControl() { Default(); }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113
114 void Default() {
tsepez0d164f82017-01-09 07:28:13 -0800115 m_aMousePath.clear();
116 m_aKeyboardPath.clear();
thestig1cd352e2016-06-07 17:53:06 -0700117 m_pMainMouseWnd = nullptr;
118 m_pMainKeyboardWnd = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 }
120
tsepez4cf55152016-11-02 14:37:54 -0700121 bool IsWndCreated(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122 return m_pCreatedWnd == pWnd;
123 }
124
tsepez4cf55152016-11-02 14:37:54 -0700125 bool IsMainCaptureMouse(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 return pWnd == m_pMainMouseWnd;
127 }
128
tsepez4cf55152016-11-02 14:37:54 -0700129 bool IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
tsepez0d164f82017-01-09 07:28:13 -0800130 return pWnd && pdfium::ContainsValue(m_aMousePath, pWnd);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 }
132
tsepez4cf55152016-11-02 14:37:54 -0700133 bool IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 return pWnd == m_pMainKeyboardWnd;
135 }
136
tsepez4cf55152016-11-02 14:37:54 -0700137 bool IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
tsepez0d164f82017-01-09 07:28:13 -0800138 return pWnd && pdfium::ContainsValue(m_aKeyboardPath, pWnd);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 }
140
141 void SetFocus(CPWL_Wnd* pWnd) {
tsepez0d164f82017-01-09 07:28:13 -0800142 m_aKeyboardPath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 if (pWnd) {
144 m_pMainKeyboardWnd = pWnd;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145 CPWL_Wnd* pParent = pWnd;
146 while (pParent) {
tsepez0d164f82017-01-09 07:28:13 -0800147 m_aKeyboardPath.push_back(pParent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148 pParent = pParent->GetParentWindow();
149 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150 pWnd->OnSetFocus();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700151 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154 void KillFocus() {
tsepez0d164f82017-01-09 07:28:13 -0800155 if (!m_aKeyboardPath.empty())
156 if (CPWL_Wnd* pWnd = m_aKeyboardPath[0])
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 pWnd->OnKillFocus();
158
thestig1cd352e2016-06-07 17:53:06 -0700159 m_pMainKeyboardWnd = nullptr;
tsepez0d164f82017-01-09 07:28:13 -0800160 m_aKeyboardPath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 }
162
163 void SetCapture(CPWL_Wnd* pWnd) {
tsepez0d164f82017-01-09 07:28:13 -0800164 m_aMousePath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 if (pWnd) {
166 m_pMainMouseWnd = pWnd;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 CPWL_Wnd* pParent = pWnd;
168 while (pParent) {
tsepez0d164f82017-01-09 07:28:13 -0800169 m_aMousePath.push_back(pParent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 pParent = pParent->GetParentWindow();
171 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700172 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 void ReleaseCapture() {
thestig1cd352e2016-06-07 17:53:06 -0700176 m_pMainMouseWnd = nullptr;
tsepez0d164f82017-01-09 07:28:13 -0800177 m_aMousePath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700179
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 private:
tsepez0d164f82017-01-09 07:28:13 -0800181 std::vector<CPWL_Wnd*> m_aMousePath;
182 std::vector<CPWL_Wnd*> m_aKeyboardPath;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 CPWL_Wnd* m_pCreatedWnd;
184 CPWL_Wnd* m_pMainMouseWnd;
185 CPWL_Wnd* m_pMainKeyboardWnd;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186};
187
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188CPWL_Wnd::CPWL_Wnd()
thestig1cd352e2016-06-07 17:53:06 -0700189 : m_pVScrollBar(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 m_rcWindow(),
191 m_rcClip(),
tsepez4cf55152016-11-02 14:37:54 -0700192 m_bCreated(false),
193 m_bVisible(false),
194 m_bNotifying(false),
195 m_bEnabled(true) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196
197CPWL_Wnd::~CPWL_Wnd() {
tsepez4cf55152016-11-02 14:37:54 -0700198 ASSERT(m_bCreated == false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700199}
200
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201CFX_ByteString CPWL_Wnd::GetClassName() const {
202 return "CPWL_Wnd";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700203}
204
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) {
206 if (!IsValid()) {
207 m_sPrivateParam = cp;
208
209 OnCreate(m_sPrivateParam);
210
211 m_sPrivateParam.rcRectWnd.Normalize();
212 m_rcWindow = m_sPrivateParam.rcRectWnd;
213 m_rcClip = CPWL_Utils::InflateRect(m_rcWindow, 1.0f);
214
215 CreateMsgControl();
216
217 if (m_sPrivateParam.pParentWnd)
218 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD);
219
220 PWL_CREATEPARAM ccp = m_sPrivateParam;
221
222 ccp.dwFlags &= 0xFFFF0000L; // remove sub styles
Tom Sepez60d909e2015-12-10 15:34:55 -0800223 ccp.mtChild = CFX_Matrix(1, 0, 0, 1, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224
225 CreateScrollBar(ccp);
226 CreateChildWnd(ccp);
227
228 m_bVisible = HasFlag(PWS_VISIBLE);
229
230 OnCreated();
231
232 RePosChildWnd();
tsepez4cf55152016-11-02 14:37:54 -0700233 m_bCreated = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239void CPWL_Wnd::OnCreated() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241void CPWL_Wnd::OnDestroy() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242
Lei Zhangab5537d2016-01-06 14:58:14 -0800243void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) {
244 if (m_sPrivateParam.pFocusHandler == handler)
245 m_sPrivateParam.pFocusHandler = nullptr;
246}
247
248void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) {
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500249 if (m_sPrivateParam.pProvider.Get() == provider)
250 m_sPrivateParam.pProvider.Reset();
Lei Zhangab5537d2016-01-06 14:58:14 -0800251}
252
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253void CPWL_Wnd::Destroy() {
254 KillFocus();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 OnDestroy();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256 if (m_bCreated) {
tsepez6745f962017-01-04 10:09:45 -0800257 for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
258 if (CPWL_Wnd* pChild = *it) {
259 *it = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 pChild->Destroy();
261 delete pChild;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 }
263 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 if (m_sPrivateParam.pParentWnd)
265 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
tsepez6745f962017-01-04 10:09:45 -0800266
tsepez4cf55152016-11-02 14:37:54 -0700267 m_bCreated = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 DestroyMsgControl();
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500270 m_sPrivateParam.Reset();
tsepez6745f962017-01-04 10:09:45 -0800271 m_Children.clear();
thestig1cd352e2016-06-07 17:53:06 -0700272 m_pVScrollBar = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700274
tsepez4cf55152016-11-02 14:37:54 -0700275void CPWL_Wnd::Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 if (IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800277 CFX_FloatRect rcOld = GetWindowRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700278
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700279 m_rcWindow = rcNew;
280 m_rcWindow.Normalize();
281
282 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
283 rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) {
284 if (bReset) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700285 RePosChildWnd();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700287 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 if (bRefresh) {
289 InvalidateRectMove(rcOld, rcNew);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700290 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 m_sPrivateParam.rcRectWnd = m_rcWindow;
293 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700294}
295
Tom Sepez281a9ea2016-02-26 14:24:28 -0800296void CPWL_Wnd::InvalidateRectMove(const CFX_FloatRect& rcOld,
297 const CFX_FloatRect& rcNew) {
298 CFX_FloatRect rcUnion = rcOld;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299 rcUnion.Union(rcNew);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700300
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 InvalidateRect(&rcUnion);
302}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700303
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) {
305 if (IsValid() && IsVisible()) {
306 GetThisAppearanceStream(sAppStream);
307 GetChildAppearanceStream(sAppStream);
308 }
309}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700310
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311// if don't set,Get default apperance stream
312void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800313 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 if (!rectWnd.IsEmpty()) {
315 CFX_ByteTextBuf sThis;
316
317 if (HasFlag(PWS_BACKGROUND))
318 sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor());
319
320 if (HasFlag(PWS_BORDER)) {
321 sThis << CPWL_Utils::GetBorderAppStream(
322 rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
323 GetBorderLeftTopColor(GetBorderStyle()),
324 GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(),
325 GetBorderDash());
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700326 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327
328 sAppStream << sThis;
329 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
331
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) {
tsepez6745f962017-01-04 10:09:45 -0800333 for (CPWL_Wnd* pChild : m_Children) {
334 if (pChild)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335 pChild->GetAppearanceStream(sAppStream);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700337}
338
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800340 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341 if (IsValid() && IsVisible()) {
342 DrawThisAppearance(pDevice, pUser2Device);
343 DrawChildAppearance(pDevice, pUser2Device);
344 }
345}
346
347void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800348 CFX_Matrix* pUser2Device) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800349 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350 if (!rectWnd.IsEmpty()) {
351 if (HasFlag(PWS_BACKGROUND)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800352 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353 rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
354 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
355 GetBackgroundColor(), GetTransparency());
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700356 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700357
358 if (HasFlag(PWS_BORDER))
Lei Zhang7457e382016-01-06 23:00:34 -0800359 CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd,
360 (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
361 GetBorderLeftTopColor(GetBorderStyle()),
362 GetBorderRightBottomColor(GetBorderStyle()),
363 GetBorderStyle(), GetTransparency());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700365}
366
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700367void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800368 CFX_Matrix* pUser2Device) {
tsepez6745f962017-01-04 10:09:45 -0800369 for (CPWL_Wnd* pChild : m_Children) {
370 if (!pChild)
371 continue;
372
373 CFX_Matrix mt = pChild->GetChildMatrix();
374 if (mt.IsIdentity()) {
375 pChild->DrawAppearance(pDevice, pUser2Device);
376 } else {
377 mt.Concat(*pUser2Device);
378 pChild->DrawAppearance(pDevice, &mt);
Lei Zhang60f507b2015-06-13 00:41:00 -0700379 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700380 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700381}
382
Tom Sepez281a9ea2016-02-26 14:24:28 -0800383void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 if (IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800385 CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700386
387 if (!HasFlag(PWS_NOREFRESHCLIP)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800388 CFX_FloatRect rcClip = GetClipRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 if (!rcClip.IsEmpty()) {
390 rcRefresh.Intersect(rcClip);
391 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700392 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700393
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394 FX_RECT rcWin = PWLtoWnd(rcRefresh);
395 rcWin.left -= PWL_INVALIDATE_INFLATE;
396 rcWin.top -= PWL_INVALIDATE_INFLATE;
397 rcWin.right += PWL_INVALIDATE_INFLATE;
398 rcWin.bottom += PWL_INVALIDATE_INFLATE;
399
dsinclairb9590102016-04-27 06:38:59 -0700400 if (CFX_SystemHandler* pSH = GetSystemHandler()) {
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500401 if (CPDFSDK_Widget* widget = static_cast<CPDFSDK_Widget*>(
402 m_sPrivateParam.pAttachedWidget.Get())) {
dsinclair8faac622016-09-15 12:41:50 -0700403 pSH->InvalidateRect(widget, rcWin);
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500404 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700405 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700406 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
tsepez6745f962017-01-04 10:09:45 -0800409#define PWL_IMPLEMENT_KEY_METHOD(key_method_name) \
410 bool CPWL_Wnd::key_method_name(uint16_t nChar, uint32_t nFlag) { \
411 if (!IsValid() || !IsVisible() || !IsEnabled()) \
412 return false; \
413 if (!IsWndCaptureKeyboard(this)) \
414 return false; \
415 for (const auto& pChild : m_Children) { \
416 if (pChild && IsWndCaptureKeyboard(pChild)) \
417 return pChild->key_method_name(nChar, nFlag); \
418 } \
419 return false; \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700421
422PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
423PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
424PWL_IMPLEMENT_KEY_METHOD(OnChar)
tsepez6745f962017-01-04 10:09:45 -0800425#undef PWL_IMPLEMENT_KEY_METHOD
426
427#define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name) \
Dan Sinclairf528eee2017-02-14 11:52:07 -0500428 bool CPWL_Wnd::mouse_method_name(const CFX_PointF& point, uint32_t nFlag) { \
tsepez6745f962017-01-04 10:09:45 -0800429 if (!IsValid() || !IsVisible() || !IsEnabled()) \
430 return false; \
431 if (IsWndCaptureMouse(this)) { \
432 for (const auto& pChild : m_Children) { \
433 if (pChild && IsWndCaptureMouse(pChild)) { \
434 return pChild->mouse_method_name(pChild->ParentToChild(point), \
435 nFlag); \
436 } \
437 } \
438 SetCursor(); \
439 return false; \
440 } \
441 for (const auto& pChild : m_Children) { \
442 if (pChild && pChild->WndHitTest(pChild->ParentToChild(point))) { \
443 return pChild->mouse_method_name(pChild->ParentToChild(point), nFlag); \
444 } \
445 } \
446 if (WndHitTest(point)) \
447 SetCursor(); \
448 return false; \
449 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700450
451PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
452PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
453PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
454PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
455PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
456PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700457PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
458PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
459PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
tsepez6745f962017-01-04 10:09:45 -0800460#undef PWL_IMPLEMENT_MOUSE_METHOD
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700461
tsepez4cf55152016-11-02 14:37:54 -0700462bool CPWL_Wnd::OnMouseWheel(short zDelta,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500463 const CFX_PointF& point,
tsepez4cf55152016-11-02 14:37:54 -0700464 uint32_t nFlag) {
tsepez6745f962017-01-04 10:09:45 -0800465 if (!IsValid() || !IsVisible() || !IsEnabled())
466 return false;
467
468 SetCursor();
469 if (!IsWndCaptureKeyboard(this))
470 return false;
471
472 for (const auto& pChild : m_Children) {
473 if (pChild && IsWndCaptureKeyboard(pChild))
474 return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point), nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700475 }
tsepez4cf55152016-11-02 14:37:54 -0700476 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700477}
478
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700479void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) {
tsepez6745f962017-01-04 10:09:45 -0800480 m_Children.push_back(pWnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700481}
482
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700483void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) {
tsepez6745f962017-01-04 10:09:45 -0800484 for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
485 if (*it && *it == pWnd) {
486 m_Children.erase(std::next(it).base());
487 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700488 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700489 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700490}
491
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700492void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd,
tsepezc3255f52016-03-25 14:52:27 -0700493 uint32_t msg,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494 intptr_t wParam,
495 intptr_t lParam) {
496 switch (msg) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700497 case PNM_ADDCHILD:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498 AddChild(pWnd);
499 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700500 case PNM_REMOVECHILD:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700501 RemoveChild(pWnd);
502 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700503 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700504 break;
505 }
506}
507
tsepez4cf55152016-11-02 14:37:54 -0700508bool CPWL_Wnd::IsValid() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509 return m_bCreated;
510}
511
Lei Zhang7457e382016-01-06 23:00:34 -0800512const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700513 return m_sPrivateParam;
514}
515
516CPWL_Wnd* CPWL_Wnd::GetParentWindow() const {
517 return m_sPrivateParam.pParentWnd;
518}
519
Tom Sepez281a9ea2016-02-26 14:24:28 -0800520CFX_FloatRect CPWL_Wnd::GetWindowRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700521 return m_rcWindow;
522}
523
Tom Sepez281a9ea2016-02-26 14:24:28 -0800524CFX_FloatRect CPWL_Wnd::GetClientRect() const {
525 CFX_FloatRect rcWindow = GetWindowRect();
526 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700527 rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
528 if (CPWL_ScrollBar* pVSB = GetVScrollBar())
529 rcClient.right -= pVSB->GetScrollBarWidth();
530
531 rcClient.Normalize();
Tom Sepez281a9ea2016-02-26 14:24:28 -0800532 return rcWindow.Contains(rcClient) ? rcClient : CFX_FloatRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700533}
534
Dan Sinclairf528eee2017-02-14 11:52:07 -0500535CFX_PointF CPWL_Wnd::GetCenterPoint() const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800536 CFX_FloatRect rcClient = GetClientRect();
Dan Sinclairf528eee2017-02-14 11:52:07 -0500537 return CFX_PointF((rcClient.left + rcClient.right) * 0.5f,
538 (rcClient.top + rcClient.bottom) * 0.5f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700539}
540
tsepez4cf55152016-11-02 14:37:54 -0700541bool CPWL_Wnd::HasFlag(uint32_t dwFlags) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542 return (m_sPrivateParam.dwFlags & dwFlags) != 0;
543}
544
tsepezc3255f52016-03-25 14:52:27 -0700545void CPWL_Wnd::RemoveFlag(uint32_t dwFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546 m_sPrivateParam.dwFlags &= ~dwFlags;
547}
548
tsepezc3255f52016-03-25 14:52:27 -0700549void CPWL_Wnd::AddFlag(uint32_t dwFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550 m_sPrivateParam.dwFlags |= dwFlags;
551}
552
553CPWL_Color CPWL_Wnd::GetBackgroundColor() const {
554 return m_sPrivateParam.sBackgroundColor;
555}
556
557void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) {
558 m_sPrivateParam.sBackgroundColor = color;
559}
560
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700561CPWL_Color CPWL_Wnd::GetTextColor() const {
562 return m_sPrivateParam.sTextColor;
563}
564
dsinclair92cb5e52016-05-16 11:38:28 -0700565BorderStyle CPWL_Wnd::GetBorderStyle() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700566 return m_sPrivateParam.nBorderStyle;
567}
568
dsinclair92cb5e52016-05-16 11:38:28 -0700569void CPWL_Wnd::SetBorderStyle(BorderStyle nBorderStyle) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570 if (HasFlag(PWS_BORDER))
571 m_sPrivateParam.nBorderStyle = nBorderStyle;
572}
573
574int32_t CPWL_Wnd::GetBorderWidth() const {
575 if (HasFlag(PWS_BORDER))
576 return m_sPrivateParam.dwBorderWidth;
577
578 return 0;
579}
580
581int32_t CPWL_Wnd::GetInnerBorderWidth() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582 return 0;
583}
584
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700585CPWL_Color CPWL_Wnd::GetBorderColor() const {
586 if (HasFlag(PWS_BORDER))
587 return m_sPrivateParam.sBorderColor;
588
589 return CPWL_Color();
590}
591
Lei Zhang7457e382016-01-06 23:00:34 -0800592const CPWL_Dash& CPWL_Wnd::GetBorderDash() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700593 return m_sPrivateParam.sDash;
594}
595
596void* CPWL_Wnd::GetAttachedData() const {
597 return m_sPrivateParam.pAttachedData;
598}
599
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700600CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const {
601 if (HasFlag(PWS_VSCROLL))
602 return m_pVScrollBar;
603
thestig1cd352e2016-06-07 17:53:06 -0700604 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700605}
606
607void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) {
608 CreateVScrollBar(cp);
609}
610
611void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) {
612 if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) {
613 PWL_CREATEPARAM scp = cp;
614
615 // flags
616 scp.dwFlags =
617 PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
618
619 scp.pParentWnd = this;
620 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
621 scp.eCursorType = FXCT_ARROW;
Dan Sinclairfc54e052017-02-23 09:59:05 -0500622 scp.nTransparency = PWL_SCROLLBAR_TRANSPARENCY;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700623
Lei Zhange00660b2015-08-13 15:40:18 -0700624 m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL);
625 m_pVScrollBar->Create(scp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 }
627}
628
629void CPWL_Wnd::SetCapture() {
630 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
631 pMsgCtrl->SetCapture(this);
632}
633
634void CPWL_Wnd::ReleaseCapture() {
tsepez6745f962017-01-04 10:09:45 -0800635 for (const auto& pChild : m_Children) {
636 if (pChild)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700637 pChild->ReleaseCapture();
tsepez6745f962017-01-04 10:09:45 -0800638 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700639 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
640 pMsgCtrl->ReleaseCapture();
641}
642
643void CPWL_Wnd::SetFocus() {
644 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
645 if (!pMsgCtrl->IsMainCaptureKeyboard(this))
646 pMsgCtrl->KillFocus();
647 pMsgCtrl->SetFocus(this);
648 }
649}
650
651void CPWL_Wnd::KillFocus() {
652 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
653 if (pMsgCtrl->IsWndCaptureKeyboard(this))
654 pMsgCtrl->KillFocus();
655 }
656}
657
658void CPWL_Wnd::OnSetFocus() {}
659
660void CPWL_Wnd::OnKillFocus() {}
661
Dan Sinclairf528eee2017-02-14 11:52:07 -0500662bool CPWL_Wnd::WndHitTest(const CFX_PointF& point) const {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500663 return IsValid() && IsVisible() && GetWindowRect().Contains(point);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664}
665
Dan Sinclairf528eee2017-02-14 11:52:07 -0500666bool CPWL_Wnd::ClientHitTest(const CFX_PointF& point) const {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500667 return IsValid() && IsVisible() && GetClientRect().Contains(point);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700668}
669
670const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const {
671 if (m_sPrivateParam.pParentWnd)
672 return m_sPrivateParam.pParentWnd->GetRootWnd();
673
674 return this;
675}
676
tsepez4cf55152016-11-02 14:37:54 -0700677void CPWL_Wnd::SetVisible(bool bVisible) {
tsepez6745f962017-01-04 10:09:45 -0800678 if (!IsValid())
679 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700680
tsepez6745f962017-01-04 10:09:45 -0800681 for (const auto& pChild : m_Children) {
682 if (pChild)
683 pChild->SetVisible(bVisible);
684 }
685 if (bVisible != m_bVisible) {
686 m_bVisible = bVisible;
687 RePosChildWnd();
688 InvalidateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700689 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700690}
691
Tom Sepez281a9ea2016-02-26 14:24:28 -0800692void CPWL_Wnd::SetClipRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 m_rcClip = rect;
694 m_rcClip.Normalize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700695}
696
Tom Sepez281a9ea2016-02-26 14:24:28 -0800697const CFX_FloatRect& CPWL_Wnd::GetClipRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700698 return m_rcClip;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700699}
700
tsepez4cf55152016-11-02 14:37:54 -0700701bool CPWL_Wnd::IsReadOnly() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700702 return HasFlag(PWS_READONLY);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700703}
704
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705void CPWL_Wnd::RePosChildWnd() {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800706 CFX_FloatRect rcContent = CPWL_Utils::DeflateRect(
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700707 GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
708
709 CPWL_ScrollBar* pVSB = GetVScrollBar();
710
Tom Sepez281a9ea2016-02-26 14:24:28 -0800711 CFX_FloatRect rcVScroll =
712 CFX_FloatRect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom,
713 rcContent.right - 1.0f, rcContent.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700714
715 if (pVSB)
tsepez4cf55152016-11-02 14:37:54 -0700716 pVSB->Move(rcVScroll, true, false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700717}
718
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700719void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {}
720
721void CPWL_Wnd::SetCursor() {
722 if (IsValid()) {
dsinclairb9590102016-04-27 06:38:59 -0700723 if (CFX_SystemHandler* pSH = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700724 int32_t nCursorType = GetCreationParam().eCursorType;
725 pSH->SetCursor(nCursorType);
726 }
727 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700728}
729
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700730void CPWL_Wnd::CreateMsgControl() {
731 if (!m_sPrivateParam.pMsgControl)
732 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700733}
734
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700735void CPWL_Wnd::DestroyMsgControl() {
736 if (CPWL_MsgControl* pMsgControl = GetMsgControl())
737 if (pMsgControl->IsWndCreated(this))
738 delete pMsgControl;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700739}
740
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700741CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const {
742 return m_sPrivateParam.pMsgControl;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700743}
744
tsepez4cf55152016-11-02 14:37:54 -0700745bool CPWL_Wnd::IsCaptureMouse() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700746 return IsWndCaptureMouse(this);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700747}
748
tsepez4cf55152016-11-02 14:37:54 -0700749bool CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700750 if (CPWL_MsgControl* pCtrl = GetMsgControl())
751 return pCtrl->IsWndCaptureMouse(pWnd);
752
tsepez4cf55152016-11-02 14:37:54 -0700753 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700754}
755
tsepez4cf55152016-11-02 14:37:54 -0700756bool CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700757 if (CPWL_MsgControl* pCtrl = GetMsgControl())
758 return pCtrl->IsWndCaptureKeyboard(pWnd);
759
tsepez4cf55152016-11-02 14:37:54 -0700760 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700761}
762
tsepez4cf55152016-11-02 14:37:54 -0700763bool CPWL_Wnd::IsFocused() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700764 if (CPWL_MsgControl* pCtrl = GetMsgControl())
765 return pCtrl->IsMainCaptureKeyboard(this);
766
tsepez4cf55152016-11-02 14:37:54 -0700767 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700768}
769
Tom Sepez281a9ea2016-02-26 14:24:28 -0800770CFX_FloatRect CPWL_Wnd::GetFocusRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700771 return CPWL_Utils::InflateRect(GetWindowRect(), 1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700772}
773
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700774FX_FLOAT CPWL_Wnd::GetFontSize() const {
775 return m_sPrivateParam.fFontSize;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700776}
777
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700778void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) {
779 m_sPrivateParam.fFontSize = fFontSize;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700780}
781
dsinclairb9590102016-04-27 06:38:59 -0700782CFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700783 return m_sPrivateParam.pSystemHandler;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700784}
785
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700786IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const {
787 return m_sPrivateParam.pFocusHandler;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700788}
789
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700790IPWL_Provider* CPWL_Wnd::GetProvider() const {
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500791 return m_sPrivateParam.pProvider.Get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700792}
793
dsinclairc7a73492016-04-05 12:01:42 -0700794IPVT_FontMap* CPWL_Wnd::GetFontMap() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700795 return m_sPrivateParam.pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700796}
797
dsinclair92cb5e52016-05-16 11:38:28 -0700798CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(BorderStyle nBorderStyle) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700799 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -0700800 case BorderStyle::BEVELED:
801 return CPWL_Color(COLORTYPE_GRAY, 1);
802 case BorderStyle::INSET:
803 return CPWL_Color(COLORTYPE_GRAY, 0.5f);
804 default:
805 return CPWL_Color();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700807}
808
dsinclair92cb5e52016-05-16 11:38:28 -0700809CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(BorderStyle nBorderStyle) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700810 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -0700811 case BorderStyle::BEVELED:
Dan Sinclairfc54e052017-02-23 09:59:05 -0500812 return GetBackgroundColor() / 2.0f;
dsinclair92cb5e52016-05-16 11:38:28 -0700813 case BorderStyle::INSET:
814 return CPWL_Color(COLORTYPE_GRAY, 0.75f);
815 default:
816 return CPWL_Color();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700817 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700818}
819
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700820int32_t CPWL_Wnd::GetTransparency() {
821 return m_sPrivateParam.nTransparency;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700822}
823
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700824void CPWL_Wnd::SetTransparency(int32_t nTransparency) {
tsepez6745f962017-01-04 10:09:45 -0800825 for (const auto& pChild : m_Children) {
826 if (pChild)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700827 pChild->SetTransparency(nTransparency);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700828 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700829 m_sPrivateParam.nTransparency = nTransparency;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700830}
831
Tom Sepez60d909e2015-12-10 15:34:55 -0800832CFX_Matrix CPWL_Wnd::GetWindowMatrix() const {
833 CFX_Matrix mt = GetChildToRoot();
tsepez6745f962017-01-04 10:09:45 -0800834 if (IPWL_Provider* pProvider = GetProvider())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700835 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700836 return mt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700837}
838
Tom Sepez281a9ea2016-02-26 14:24:28 -0800839FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const {
840 CFX_FloatRect rcTemp = rect;
Tom Sepez60d909e2015-12-10 15:34:55 -0800841 CFX_Matrix mt = GetWindowMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700842 mt.TransformRect(rcTemp);
843 return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5),
844 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700845}
846
Dan Sinclairf528eee2017-02-14 11:52:07 -0500847CFX_PointF CPWL_Wnd::ChildToParent(const CFX_PointF& point) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800848 CFX_Matrix mt = GetChildMatrix();
Dan Sinclair1f403ce2017-02-21 12:56:24 -0500849 return mt.IsIdentity() ? point : mt.Transform(point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700850}
851
Tom Sepez281a9ea2016-02-26 14:24:28 -0800852CFX_FloatRect CPWL_Wnd::ChildToParent(const CFX_FloatRect& rect) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800853 CFX_Matrix mt = GetChildMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700854 if (mt.IsIdentity())
855 return rect;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700856
Tom Sepez281a9ea2016-02-26 14:24:28 -0800857 CFX_FloatRect rc = rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700858 mt.TransformRect(rc);
859 return rc;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700860}
861
Dan Sinclairf528eee2017-02-14 11:52:07 -0500862CFX_PointF CPWL_Wnd::ParentToChild(const CFX_PointF& point) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800863 CFX_Matrix mt = GetChildMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700864 if (mt.IsIdentity())
865 return point;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700866
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700867 mt.SetReverse(mt);
Dan Sinclair1f403ce2017-02-21 12:56:24 -0500868 return mt.Transform(point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700869}
870
Tom Sepez281a9ea2016-02-26 14:24:28 -0800871CFX_FloatRect CPWL_Wnd::ParentToChild(const CFX_FloatRect& rect) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800872 CFX_Matrix mt = GetChildMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700873 if (mt.IsIdentity())
874 return rect;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700875
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700876 mt.SetReverse(mt);
Tom Sepez281a9ea2016-02-26 14:24:28 -0800877 CFX_FloatRect rc = rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700878 mt.TransformRect(rc);
879 return rc;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700880}
881
weili625ad662016-06-15 11:21:33 -0700882FX_FLOAT CPWL_Wnd::GetItemHeight(FX_FLOAT fLimitWidth) {
883 return 0;
884}
885
886FX_FLOAT CPWL_Wnd::GetItemLeftMargin() {
887 return 0;
888}
889
890FX_FLOAT CPWL_Wnd::GetItemRightMargin() {
891 return 0;
892}
893
Tom Sepez60d909e2015-12-10 15:34:55 -0800894CFX_Matrix CPWL_Wnd::GetChildToRoot() const {
895 CFX_Matrix mt(1, 0, 0, 1, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700896 if (HasFlag(PWS_CHILD)) {
897 const CPWL_Wnd* pParent = this;
898 while (pParent) {
899 mt.Concat(pParent->GetChildMatrix());
900 pParent = pParent->GetParentWindow();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700901 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700902 }
903 return mt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700904}
905
Tom Sepez60d909e2015-12-10 15:34:55 -0800906CFX_Matrix CPWL_Wnd::GetChildMatrix() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700907 if (HasFlag(PWS_CHILD))
908 return m_sPrivateParam.mtChild;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700909
Tom Sepez60d909e2015-12-10 15:34:55 -0800910 return CFX_Matrix(1, 0, 0, 1, 0, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700911}
912
Tom Sepez60d909e2015-12-10 15:34:55 -0800913void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700914 m_sPrivateParam.mtChild = mt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700915}
916
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700917const CPWL_Wnd* CPWL_Wnd::GetFocused() const {
tsepez6745f962017-01-04 10:09:45 -0800918 CPWL_MsgControl* pMsgCtrl = GetMsgControl();
919 return pMsgCtrl ? pMsgCtrl->m_pMainKeyboardWnd : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920}
921
tsepez4cf55152016-11-02 14:37:54 -0700922void CPWL_Wnd::EnableWindow(bool bEnable) {
tsepez6745f962017-01-04 10:09:45 -0800923 if (m_bEnabled == bEnable)
924 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700925
tsepez6745f962017-01-04 10:09:45 -0800926 for (const auto& pChild : m_Children) {
927 if (pChild)
928 pChild->EnableWindow(bEnable);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700929 }
tsepez6745f962017-01-04 10:09:45 -0800930 m_bEnabled = bEnable;
931 if (bEnable)
932 OnEnabled();
933 else
934 OnDisabled();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700935}
936
tsepez4cf55152016-11-02 14:37:54 -0700937bool CPWL_Wnd::IsEnabled() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700938 return m_bEnabled;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700939}
940
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700941void CPWL_Wnd::OnEnabled() {}
942
943void CPWL_Wnd::OnDisabled() {}
944
tsepez4cf55152016-11-02 14:37:54 -0700945bool CPWL_Wnd::IsCTRLpressed(uint32_t nFlag) const {
dsinclairb9590102016-04-27 06:38:59 -0700946 if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700947 return pSystemHandler->IsCTRLKeyDown(nFlag);
948 }
949
tsepez4cf55152016-11-02 14:37:54 -0700950 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700951}
952
tsepez4cf55152016-11-02 14:37:54 -0700953bool CPWL_Wnd::IsSHIFTpressed(uint32_t nFlag) const {
dsinclairb9590102016-04-27 06:38:59 -0700954 if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700955 return pSystemHandler->IsSHIFTKeyDown(nFlag);
956 }
957
tsepez4cf55152016-11-02 14:37:54 -0700958 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700959}
960
tsepez4cf55152016-11-02 14:37:54 -0700961bool CPWL_Wnd::IsALTpressed(uint32_t nFlag) const {
dsinclairb9590102016-04-27 06:38:59 -0700962 if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700963 return pSystemHandler->IsALTKeyDown(nFlag);
964 }
965
tsepez4cf55152016-11-02 14:37:54 -0700966 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700967}