blob: f5d97adc19b7c3b1a5d46eab490de71284d3eae5 [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(),
35 sTextStrokeColor(),
36 nTransparency(255),
37 fFontSize(PWL_DEFAULT_FONTSIZE),
38 sDash(3, 0, 0),
39 pAttachedData(nullptr),
40 pParentWnd(nullptr),
41 pMsgControl(nullptr),
42 eCursorType(FXCT_ARROW),
43 mtChild(1, 0, 0, 1, 0, 0) {}
44
45PWL_CREATEPARAM::PWL_CREATEPARAM(const PWL_CREATEPARAM& other) = default;
46
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached,
dsinclairb9590102016-04-27 06:38:59 -070048 CFX_SystemHandler* pSystemHandler)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 : m_nTimerID(0), m_pAttached(pAttached), m_pSystemHandler(pSystemHandler) {
Lei Zhang96660d62015-12-14 18:27:25 -080050 ASSERT(m_pAttached);
51 ASSERT(m_pSystemHandler);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052}
53
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054CPWL_Timer::~CPWL_Timer() {
55 KillPWLTimer();
56}
57
58int32_t CPWL_Timer::SetPWLTimer(int32_t nElapse) {
59 if (m_nTimerID != 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -070060 KillPWLTimer();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc);
62
63 GetPWLTimeMap()[m_nTimerID] = this;
64 return m_nTimerID;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070065}
66
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067void CPWL_Timer::KillPWLTimer() {
68 if (m_nTimerID == 0)
69 return;
Lei Zhang606346f2015-06-19 18:11:07 -070070
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071 m_pSystemHandler->KillTimer(m_nTimerID);
72 GetPWLTimeMap().erase(m_nTimerID);
73 m_nTimerID = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074}
75
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076void CPWL_Timer::TimerProc(int32_t idEvent) {
77 auto it = GetPWLTimeMap().find(idEvent);
78 if (it == GetPWLTimeMap().end())
79 return;
Lei Zhang606346f2015-06-19 18:11:07 -070080
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 CPWL_Timer* pTimer = it->second;
82 if (pTimer->m_pAttached)
83 pTimer->m_pAttached->TimerProc();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084}
85
weili2d5b0202016-08-03 11:06:49 -070086CPWL_TimerHandler::CPWL_TimerHandler() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087
weili2d5b0202016-08-03 11:06:49 -070088CPWL_TimerHandler::~CPWL_TimerHandler() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090void CPWL_TimerHandler::BeginTimer(int32_t nElapse) {
91 if (!m_pTimer)
tsepez36eb4bd2016-10-03 15:24:27 -070092 m_pTimer = pdfium::MakeUnique<CPWL_Timer>(this, GetSystemHandler());
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093
tsepez36eb4bd2016-10-03 15:24:27 -070094 m_pTimer->SetPWLTimer(nElapse);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095}
96
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097void CPWL_TimerHandler::EndTimer() {
98 if (m_pTimer)
99 m_pTimer->KillPWLTimer();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700100}
101
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102void CPWL_TimerHandler::TimerProc() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104class CPWL_MsgControl {
105 friend class CPWL_Wnd;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 public:
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800108 explicit CPWL_MsgControl(CPWL_Wnd* pWnd) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 m_pCreatedWnd = pWnd;
110 Default();
111 }
112
Dan Sinclairf766ad22016-03-14 13:51:24 -0400113 ~CPWL_MsgControl() { Default(); }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114
115 void Default() {
tsepez0d164f82017-01-09 07:28:13 -0800116 m_aMousePath.clear();
117 m_aKeyboardPath.clear();
thestig1cd352e2016-06-07 17:53:06 -0700118 m_pMainMouseWnd = nullptr;
119 m_pMainKeyboardWnd = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 }
121
tsepez4cf55152016-11-02 14:37:54 -0700122 bool IsWndCreated(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 return m_pCreatedWnd == pWnd;
124 }
125
tsepez4cf55152016-11-02 14:37:54 -0700126 bool IsMainCaptureMouse(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 return pWnd == m_pMainMouseWnd;
128 }
129
tsepez4cf55152016-11-02 14:37:54 -0700130 bool IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
tsepez0d164f82017-01-09 07:28:13 -0800131 return pWnd && pdfium::ContainsValue(m_aMousePath, pWnd);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 }
133
tsepez4cf55152016-11-02 14:37:54 -0700134 bool IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 return pWnd == m_pMainKeyboardWnd;
136 }
137
tsepez4cf55152016-11-02 14:37:54 -0700138 bool IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
tsepez0d164f82017-01-09 07:28:13 -0800139 return pWnd && pdfium::ContainsValue(m_aKeyboardPath, pWnd);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 }
141
142 void SetFocus(CPWL_Wnd* pWnd) {
tsepez0d164f82017-01-09 07:28:13 -0800143 m_aKeyboardPath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (pWnd) {
145 m_pMainKeyboardWnd = pWnd;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146 CPWL_Wnd* pParent = pWnd;
147 while (pParent) {
tsepez0d164f82017-01-09 07:28:13 -0800148 m_aKeyboardPath.push_back(pParent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 pParent = pParent->GetParentWindow();
150 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 pWnd->OnSetFocus();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700152 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 void KillFocus() {
tsepez0d164f82017-01-09 07:28:13 -0800156 if (!m_aKeyboardPath.empty())
157 if (CPWL_Wnd* pWnd = m_aKeyboardPath[0])
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 pWnd->OnKillFocus();
159
thestig1cd352e2016-06-07 17:53:06 -0700160 m_pMainKeyboardWnd = nullptr;
tsepez0d164f82017-01-09 07:28:13 -0800161 m_aKeyboardPath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 }
163
164 void SetCapture(CPWL_Wnd* pWnd) {
tsepez0d164f82017-01-09 07:28:13 -0800165 m_aMousePath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 if (pWnd) {
167 m_pMainMouseWnd = pWnd;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 CPWL_Wnd* pParent = pWnd;
169 while (pParent) {
tsepez0d164f82017-01-09 07:28:13 -0800170 m_aMousePath.push_back(pParent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 pParent = pParent->GetParentWindow();
172 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700173 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 void ReleaseCapture() {
thestig1cd352e2016-06-07 17:53:06 -0700177 m_pMainMouseWnd = nullptr;
tsepez0d164f82017-01-09 07:28:13 -0800178 m_aMousePath.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700180
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 private:
tsepez0d164f82017-01-09 07:28:13 -0800182 std::vector<CPWL_Wnd*> m_aMousePath;
183 std::vector<CPWL_Wnd*> m_aKeyboardPath;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 CPWL_Wnd* m_pCreatedWnd;
185 CPWL_Wnd* m_pMainMouseWnd;
186 CPWL_Wnd* m_pMainKeyboardWnd;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700187};
188
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189CPWL_Wnd::CPWL_Wnd()
thestig1cd352e2016-06-07 17:53:06 -0700190 : m_pVScrollBar(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 m_rcWindow(),
192 m_rcClip(),
tsepez4cf55152016-11-02 14:37:54 -0700193 m_bCreated(false),
194 m_bVisible(false),
195 m_bNotifying(false),
196 m_bEnabled(true) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197
198CPWL_Wnd::~CPWL_Wnd() {
tsepez4cf55152016-11-02 14:37:54 -0700199 ASSERT(m_bCreated == false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200}
201
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202CFX_ByteString CPWL_Wnd::GetClassName() const {
203 return "CPWL_Wnd";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700204}
205
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) {
207 if (!IsValid()) {
208 m_sPrivateParam = cp;
209
210 OnCreate(m_sPrivateParam);
211
212 m_sPrivateParam.rcRectWnd.Normalize();
213 m_rcWindow = m_sPrivateParam.rcRectWnd;
214 m_rcClip = CPWL_Utils::InflateRect(m_rcWindow, 1.0f);
215
216 CreateMsgControl();
217
218 if (m_sPrivateParam.pParentWnd)
219 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD);
220
221 PWL_CREATEPARAM ccp = m_sPrivateParam;
222
223 ccp.dwFlags &= 0xFFFF0000L; // remove sub styles
Tom Sepez60d909e2015-12-10 15:34:55 -0800224 ccp.mtChild = CFX_Matrix(1, 0, 0, 1, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225
226 CreateScrollBar(ccp);
227 CreateChildWnd(ccp);
228
229 m_bVisible = HasFlag(PWS_VISIBLE);
230
231 OnCreated();
232
233 RePosChildWnd();
tsepez4cf55152016-11-02 14:37:54 -0700234 m_bCreated = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700236}
237
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700238void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240void CPWL_Wnd::OnCreated() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700241
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242void CPWL_Wnd::OnDestroy() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243
Lei Zhangab5537d2016-01-06 14:58:14 -0800244void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) {
245 if (m_sPrivateParam.pFocusHandler == handler)
246 m_sPrivateParam.pFocusHandler = nullptr;
247}
248
249void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) {
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500250 if (m_sPrivateParam.pProvider.Get() == provider)
251 m_sPrivateParam.pProvider.Reset();
Lei Zhangab5537d2016-01-06 14:58:14 -0800252}
253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254void CPWL_Wnd::Destroy() {
255 KillFocus();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256 OnDestroy();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 if (m_bCreated) {
tsepez6745f962017-01-04 10:09:45 -0800258 for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
259 if (CPWL_Wnd* pChild = *it) {
260 *it = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 pChild->Destroy();
262 delete pChild;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 }
264 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265 if (m_sPrivateParam.pParentWnd)
266 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
tsepez6745f962017-01-04 10:09:45 -0800267
tsepez4cf55152016-11-02 14:37:54 -0700268 m_bCreated = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 DestroyMsgControl();
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500271 m_sPrivateParam.Reset();
tsepez6745f962017-01-04 10:09:45 -0800272 m_Children.clear();
thestig1cd352e2016-06-07 17:53:06 -0700273 m_pVScrollBar = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700275
tsepez4cf55152016-11-02 14:37:54 -0700276void CPWL_Wnd::Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 if (IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800278 CFX_FloatRect rcOld = GetWindowRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 m_rcWindow = rcNew;
281 m_rcWindow.Normalize();
282
283 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
284 rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) {
285 if (bReset) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700286 RePosChildWnd();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700288 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289 if (bRefresh) {
290 InvalidateRectMove(rcOld, rcNew);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700291 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700292
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293 m_sPrivateParam.rcRectWnd = m_rcWindow;
294 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700295}
296
Tom Sepez281a9ea2016-02-26 14:24:28 -0800297void CPWL_Wnd::InvalidateRectMove(const CFX_FloatRect& rcOld,
298 const CFX_FloatRect& rcNew) {
299 CFX_FloatRect rcUnion = rcOld;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 rcUnion.Union(rcNew);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700301
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302 InvalidateRect(&rcUnion);
303}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700304
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) {
306 if (IsValid() && IsVisible()) {
307 GetThisAppearanceStream(sAppStream);
308 GetChildAppearanceStream(sAppStream);
309 }
310}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700311
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700312// if don't set,Get default apperance stream
313void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800314 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 if (!rectWnd.IsEmpty()) {
316 CFX_ByteTextBuf sThis;
317
318 if (HasFlag(PWS_BACKGROUND))
319 sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor());
320
321 if (HasFlag(PWS_BORDER)) {
322 sThis << CPWL_Utils::GetBorderAppStream(
323 rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
324 GetBorderLeftTopColor(GetBorderStyle()),
325 GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(),
326 GetBorderDash());
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700327 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328
329 sAppStream << sThis;
330 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700331}
332
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700333void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) {
tsepez6745f962017-01-04 10:09:45 -0800334 for (CPWL_Wnd* pChild : m_Children) {
335 if (pChild)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336 pChild->GetAppearanceStream(sAppStream);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338}
339
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800341 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700342 if (IsValid() && IsVisible()) {
343 DrawThisAppearance(pDevice, pUser2Device);
344 DrawChildAppearance(pDevice, pUser2Device);
345 }
346}
347
348void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800349 CFX_Matrix* pUser2Device) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800350 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351 if (!rectWnd.IsEmpty()) {
352 if (HasFlag(PWS_BACKGROUND)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800353 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354 rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
355 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
356 GetBackgroundColor(), GetTransparency());
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700357 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358
359 if (HasFlag(PWS_BORDER))
Lei Zhang7457e382016-01-06 23:00:34 -0800360 CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd,
361 (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
362 GetBorderLeftTopColor(GetBorderStyle()),
363 GetBorderRightBottomColor(GetBorderStyle()),
364 GetBorderStyle(), GetTransparency());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700366}
367
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800369 CFX_Matrix* pUser2Device) {
tsepez6745f962017-01-04 10:09:45 -0800370 for (CPWL_Wnd* pChild : m_Children) {
371 if (!pChild)
372 continue;
373
374 CFX_Matrix mt = pChild->GetChildMatrix();
375 if (mt.IsIdentity()) {
376 pChild->DrawAppearance(pDevice, pUser2Device);
377 } else {
378 mt.Concat(*pUser2Device);
379 pChild->DrawAppearance(pDevice, &mt);
Lei Zhang60f507b2015-06-13 00:41:00 -0700380 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700382}
383
Tom Sepez281a9ea2016-02-26 14:24:28 -0800384void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 if (IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800386 CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387
388 if (!HasFlag(PWS_NOREFRESHCLIP)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800389 CFX_FloatRect rcClip = GetClipRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 if (!rcClip.IsEmpty()) {
391 rcRefresh.Intersect(rcClip);
392 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700393 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700394
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395 FX_RECT rcWin = PWLtoWnd(rcRefresh);
396 rcWin.left -= PWL_INVALIDATE_INFLATE;
397 rcWin.top -= PWL_INVALIDATE_INFLATE;
398 rcWin.right += PWL_INVALIDATE_INFLATE;
399 rcWin.bottom += PWL_INVALIDATE_INFLATE;
400
dsinclairb9590102016-04-27 06:38:59 -0700401 if (CFX_SystemHandler* pSH = GetSystemHandler()) {
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500402 if (CPDFSDK_Widget* widget = static_cast<CPDFSDK_Widget*>(
403 m_sPrivateParam.pAttachedWidget.Get())) {
dsinclair8faac622016-09-15 12:41:50 -0700404 pSH->InvalidateRect(widget, rcWin);
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500405 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700406 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700407 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700408}
409
tsepez6745f962017-01-04 10:09:45 -0800410#define PWL_IMPLEMENT_KEY_METHOD(key_method_name) \
411 bool CPWL_Wnd::key_method_name(uint16_t nChar, uint32_t nFlag) { \
412 if (!IsValid() || !IsVisible() || !IsEnabled()) \
413 return false; \
414 if (!IsWndCaptureKeyboard(this)) \
415 return false; \
416 for (const auto& pChild : m_Children) { \
417 if (pChild && IsWndCaptureKeyboard(pChild)) \
418 return pChild->key_method_name(nChar, nFlag); \
419 } \
420 return false; \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700422
423PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
424PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
425PWL_IMPLEMENT_KEY_METHOD(OnChar)
tsepez6745f962017-01-04 10:09:45 -0800426#undef PWL_IMPLEMENT_KEY_METHOD
427
428#define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name) \
Dan Sinclairf528eee2017-02-14 11:52:07 -0500429 bool CPWL_Wnd::mouse_method_name(const CFX_PointF& point, uint32_t nFlag) { \
tsepez6745f962017-01-04 10:09:45 -0800430 if (!IsValid() || !IsVisible() || !IsEnabled()) \
431 return false; \
432 if (IsWndCaptureMouse(this)) { \
433 for (const auto& pChild : m_Children) { \
434 if (pChild && IsWndCaptureMouse(pChild)) { \
435 return pChild->mouse_method_name(pChild->ParentToChild(point), \
436 nFlag); \
437 } \
438 } \
439 SetCursor(); \
440 return false; \
441 } \
442 for (const auto& pChild : m_Children) { \
443 if (pChild && pChild->WndHitTest(pChild->ParentToChild(point))) { \
444 return pChild->mouse_method_name(pChild->ParentToChild(point), nFlag); \
445 } \
446 } \
447 if (WndHitTest(point)) \
448 SetCursor(); \
449 return false; \
450 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700451
452PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
453PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
454PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
455PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
456PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
457PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700458PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
459PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
460PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
tsepez6745f962017-01-04 10:09:45 -0800461#undef PWL_IMPLEMENT_MOUSE_METHOD
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700462
tsepez4cf55152016-11-02 14:37:54 -0700463bool CPWL_Wnd::OnMouseWheel(short zDelta,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500464 const CFX_PointF& point,
tsepez4cf55152016-11-02 14:37:54 -0700465 uint32_t nFlag) {
tsepez6745f962017-01-04 10:09:45 -0800466 if (!IsValid() || !IsVisible() || !IsEnabled())
467 return false;
468
469 SetCursor();
470 if (!IsWndCaptureKeyboard(this))
471 return false;
472
473 for (const auto& pChild : m_Children) {
474 if (pChild && IsWndCaptureKeyboard(pChild))
475 return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point), nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700476 }
tsepez4cf55152016-11-02 14:37:54 -0700477 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700478}
479
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700480void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) {
tsepez6745f962017-01-04 10:09:45 -0800481 m_Children.push_back(pWnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700482}
483
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) {
tsepez6745f962017-01-04 10:09:45 -0800485 for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
486 if (*it && *it == pWnd) {
487 m_Children.erase(std::next(it).base());
488 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700489 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700491}
492
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700493void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd,
tsepezc3255f52016-03-25 14:52:27 -0700494 uint32_t msg,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 intptr_t wParam,
496 intptr_t lParam) {
497 switch (msg) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700498 case PNM_ADDCHILD:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499 AddChild(pWnd);
500 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700501 case PNM_REMOVECHILD:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700502 RemoveChild(pWnd);
503 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700504 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700505 break;
506 }
507}
508
tsepez4cf55152016-11-02 14:37:54 -0700509bool CPWL_Wnd::IsValid() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700510 return m_bCreated;
511}
512
Lei Zhang7457e382016-01-06 23:00:34 -0800513const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700514 return m_sPrivateParam;
515}
516
517CPWL_Wnd* CPWL_Wnd::GetParentWindow() const {
518 return m_sPrivateParam.pParentWnd;
519}
520
Tom Sepez281a9ea2016-02-26 14:24:28 -0800521CFX_FloatRect CPWL_Wnd::GetWindowRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522 return m_rcWindow;
523}
524
Tom Sepez281a9ea2016-02-26 14:24:28 -0800525CFX_FloatRect CPWL_Wnd::GetClientRect() const {
526 CFX_FloatRect rcWindow = GetWindowRect();
527 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528 rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
529 if (CPWL_ScrollBar* pVSB = GetVScrollBar())
530 rcClient.right -= pVSB->GetScrollBarWidth();
531
532 rcClient.Normalize();
Tom Sepez281a9ea2016-02-26 14:24:28 -0800533 return rcWindow.Contains(rcClient) ? rcClient : CFX_FloatRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700534}
535
Dan Sinclairf528eee2017-02-14 11:52:07 -0500536CFX_PointF CPWL_Wnd::GetCenterPoint() const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800537 CFX_FloatRect rcClient = GetClientRect();
Dan Sinclairf528eee2017-02-14 11:52:07 -0500538 return CFX_PointF((rcClient.left + rcClient.right) * 0.5f,
539 (rcClient.top + rcClient.bottom) * 0.5f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700540}
541
tsepez4cf55152016-11-02 14:37:54 -0700542bool CPWL_Wnd::HasFlag(uint32_t dwFlags) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700543 return (m_sPrivateParam.dwFlags & dwFlags) != 0;
544}
545
tsepezc3255f52016-03-25 14:52:27 -0700546void CPWL_Wnd::RemoveFlag(uint32_t dwFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700547 m_sPrivateParam.dwFlags &= ~dwFlags;
548}
549
tsepezc3255f52016-03-25 14:52:27 -0700550void CPWL_Wnd::AddFlag(uint32_t dwFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551 m_sPrivateParam.dwFlags |= dwFlags;
552}
553
554CPWL_Color CPWL_Wnd::GetBackgroundColor() const {
555 return m_sPrivateParam.sBackgroundColor;
556}
557
558void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) {
559 m_sPrivateParam.sBackgroundColor = color;
560}
561
562void CPWL_Wnd::SetTextColor(const CPWL_Color& color) {
563 m_sPrivateParam.sTextColor = color;
564}
565
566void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) {
567 m_sPrivateParam.sTextStrokeColor = color;
568}
569
570CPWL_Color CPWL_Wnd::GetTextColor() const {
571 return m_sPrivateParam.sTextColor;
572}
573
574CPWL_Color CPWL_Wnd::GetTextStrokeColor() const {
575 return m_sPrivateParam.sTextStrokeColor;
576}
577
dsinclair92cb5e52016-05-16 11:38:28 -0700578BorderStyle CPWL_Wnd::GetBorderStyle() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 return m_sPrivateParam.nBorderStyle;
580}
581
dsinclair92cb5e52016-05-16 11:38:28 -0700582void CPWL_Wnd::SetBorderStyle(BorderStyle nBorderStyle) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700583 if (HasFlag(PWS_BORDER))
584 m_sPrivateParam.nBorderStyle = nBorderStyle;
585}
586
587int32_t CPWL_Wnd::GetBorderWidth() const {
588 if (HasFlag(PWS_BORDER))
589 return m_sPrivateParam.dwBorderWidth;
590
591 return 0;
592}
593
594int32_t CPWL_Wnd::GetInnerBorderWidth() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700595 return 0;
596}
597
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700598CPWL_Color CPWL_Wnd::GetBorderColor() const {
599 if (HasFlag(PWS_BORDER))
600 return m_sPrivateParam.sBorderColor;
601
602 return CPWL_Color();
603}
604
Lei Zhang7457e382016-01-06 23:00:34 -0800605const CPWL_Dash& CPWL_Wnd::GetBorderDash() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700606 return m_sPrivateParam.sDash;
607}
608
609void* CPWL_Wnd::GetAttachedData() const {
610 return m_sPrivateParam.pAttachedData;
611}
612
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700613CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const {
614 if (HasFlag(PWS_VSCROLL))
615 return m_pVScrollBar;
616
thestig1cd352e2016-06-07 17:53:06 -0700617 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700618}
619
620void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) {
621 CreateVScrollBar(cp);
622}
623
624void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) {
625 if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) {
626 PWL_CREATEPARAM scp = cp;
627
628 // flags
629 scp.dwFlags =
630 PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
631
632 scp.pParentWnd = this;
633 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
634 scp.eCursorType = FXCT_ARROW;
635 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
636
Lei Zhange00660b2015-08-13 15:40:18 -0700637 m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL);
638 m_pVScrollBar->Create(scp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700639 }
640}
641
642void CPWL_Wnd::SetCapture() {
643 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
644 pMsgCtrl->SetCapture(this);
645}
646
647void CPWL_Wnd::ReleaseCapture() {
tsepez6745f962017-01-04 10:09:45 -0800648 for (const auto& pChild : m_Children) {
649 if (pChild)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700650 pChild->ReleaseCapture();
tsepez6745f962017-01-04 10:09:45 -0800651 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700652 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
653 pMsgCtrl->ReleaseCapture();
654}
655
656void CPWL_Wnd::SetFocus() {
657 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
658 if (!pMsgCtrl->IsMainCaptureKeyboard(this))
659 pMsgCtrl->KillFocus();
660 pMsgCtrl->SetFocus(this);
661 }
662}
663
664void CPWL_Wnd::KillFocus() {
665 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
666 if (pMsgCtrl->IsWndCaptureKeyboard(this))
667 pMsgCtrl->KillFocus();
668 }
669}
670
671void CPWL_Wnd::OnSetFocus() {}
672
673void CPWL_Wnd::OnKillFocus() {}
674
Dan Sinclairf528eee2017-02-14 11:52:07 -0500675bool CPWL_Wnd::WndHitTest(const CFX_PointF& point) const {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500676 return IsValid() && IsVisible() && GetWindowRect().Contains(point);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700677}
678
Dan Sinclairf528eee2017-02-14 11:52:07 -0500679bool CPWL_Wnd::ClientHitTest(const CFX_PointF& point) const {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500680 return IsValid() && IsVisible() && GetClientRect().Contains(point);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700681}
682
683const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const {
684 if (m_sPrivateParam.pParentWnd)
685 return m_sPrivateParam.pParentWnd->GetRootWnd();
686
687 return this;
688}
689
tsepez4cf55152016-11-02 14:37:54 -0700690void CPWL_Wnd::SetVisible(bool bVisible) {
tsepez6745f962017-01-04 10:09:45 -0800691 if (!IsValid())
692 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693
tsepez6745f962017-01-04 10:09:45 -0800694 for (const auto& pChild : m_Children) {
695 if (pChild)
696 pChild->SetVisible(bVisible);
697 }
698 if (bVisible != m_bVisible) {
699 m_bVisible = bVisible;
700 RePosChildWnd();
701 InvalidateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700702 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700703}
704
Tom Sepez281a9ea2016-02-26 14:24:28 -0800705void CPWL_Wnd::SetClipRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700706 m_rcClip = rect;
707 m_rcClip.Normalize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700708}
709
Tom Sepez281a9ea2016-02-26 14:24:28 -0800710const CFX_FloatRect& CPWL_Wnd::GetClipRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700711 return m_rcClip;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700712}
713
tsepez4cf55152016-11-02 14:37:54 -0700714bool CPWL_Wnd::IsReadOnly() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700715 return HasFlag(PWS_READONLY);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700716}
717
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700718void CPWL_Wnd::RePosChildWnd() {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800719 CFX_FloatRect rcContent = CPWL_Utils::DeflateRect(
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700720 GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
721
722 CPWL_ScrollBar* pVSB = GetVScrollBar();
723
Tom Sepez281a9ea2016-02-26 14:24:28 -0800724 CFX_FloatRect rcVScroll =
725 CFX_FloatRect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom,
726 rcContent.right - 1.0f, rcContent.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700727
728 if (pVSB)
tsepez4cf55152016-11-02 14:37:54 -0700729 pVSB->Move(rcVScroll, true, false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700730}
731
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700732void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {}
733
734void CPWL_Wnd::SetCursor() {
735 if (IsValid()) {
dsinclairb9590102016-04-27 06:38:59 -0700736 if (CFX_SystemHandler* pSH = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700737 int32_t nCursorType = GetCreationParam().eCursorType;
738 pSH->SetCursor(nCursorType);
739 }
740 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700741}
742
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700743void CPWL_Wnd::CreateMsgControl() {
744 if (!m_sPrivateParam.pMsgControl)
745 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700746}
747
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700748void CPWL_Wnd::DestroyMsgControl() {
749 if (CPWL_MsgControl* pMsgControl = GetMsgControl())
750 if (pMsgControl->IsWndCreated(this))
751 delete pMsgControl;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700752}
753
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700754CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const {
755 return m_sPrivateParam.pMsgControl;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700756}
757
tsepez4cf55152016-11-02 14:37:54 -0700758bool CPWL_Wnd::IsCaptureMouse() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759 return IsWndCaptureMouse(this);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700760}
761
tsepez4cf55152016-11-02 14:37:54 -0700762bool CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700763 if (CPWL_MsgControl* pCtrl = GetMsgControl())
764 return pCtrl->IsWndCaptureMouse(pWnd);
765
tsepez4cf55152016-11-02 14:37:54 -0700766 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700767}
768
tsepez4cf55152016-11-02 14:37:54 -0700769bool CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700770 if (CPWL_MsgControl* pCtrl = GetMsgControl())
771 return pCtrl->IsWndCaptureKeyboard(pWnd);
772
tsepez4cf55152016-11-02 14:37:54 -0700773 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700774}
775
tsepez4cf55152016-11-02 14:37:54 -0700776bool CPWL_Wnd::IsFocused() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700777 if (CPWL_MsgControl* pCtrl = GetMsgControl())
778 return pCtrl->IsMainCaptureKeyboard(this);
779
tsepez4cf55152016-11-02 14:37:54 -0700780 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700781}
782
Tom Sepez281a9ea2016-02-26 14:24:28 -0800783CFX_FloatRect CPWL_Wnd::GetFocusRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700784 return CPWL_Utils::InflateRect(GetWindowRect(), 1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700785}
786
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700787FX_FLOAT CPWL_Wnd::GetFontSize() const {
788 return m_sPrivateParam.fFontSize;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700789}
790
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700791void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) {
792 m_sPrivateParam.fFontSize = fFontSize;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700793}
794
dsinclairb9590102016-04-27 06:38:59 -0700795CFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700796 return m_sPrivateParam.pSystemHandler;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700797}
798
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700799IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const {
800 return m_sPrivateParam.pFocusHandler;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700801}
802
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700803IPWL_Provider* CPWL_Wnd::GetProvider() const {
Dan Sinclairbc8dcc32017-01-19 13:53:02 -0500804 return m_sPrivateParam.pProvider.Get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700805}
806
dsinclairc7a73492016-04-05 12:01:42 -0700807IPVT_FontMap* CPWL_Wnd::GetFontMap() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700808 return m_sPrivateParam.pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700809}
810
dsinclair92cb5e52016-05-16 11:38:28 -0700811CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(BorderStyle nBorderStyle) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700812 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -0700813 case BorderStyle::BEVELED:
814 return CPWL_Color(COLORTYPE_GRAY, 1);
815 case BorderStyle::INSET:
816 return CPWL_Color(COLORTYPE_GRAY, 0.5f);
817 default:
818 return CPWL_Color();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700819 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700820}
821
dsinclair92cb5e52016-05-16 11:38:28 -0700822CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(BorderStyle nBorderStyle) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700823 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -0700824 case BorderStyle::BEVELED:
825 return CPWL_Utils::DevideColor(GetBackgroundColor(), 2);
826 case BorderStyle::INSET:
827 return CPWL_Color(COLORTYPE_GRAY, 0.75f);
828 default:
829 return CPWL_Color();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700830 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700831}
832
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700833int32_t CPWL_Wnd::GetTransparency() {
834 return m_sPrivateParam.nTransparency;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700835}
836
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700837void CPWL_Wnd::SetTransparency(int32_t nTransparency) {
tsepez6745f962017-01-04 10:09:45 -0800838 for (const auto& pChild : m_Children) {
839 if (pChild)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700840 pChild->SetTransparency(nTransparency);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700841 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700842 m_sPrivateParam.nTransparency = nTransparency;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700843}
844
Tom Sepez60d909e2015-12-10 15:34:55 -0800845CFX_Matrix CPWL_Wnd::GetWindowMatrix() const {
846 CFX_Matrix mt = GetChildToRoot();
tsepez6745f962017-01-04 10:09:45 -0800847 if (IPWL_Provider* pProvider = GetProvider())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700848 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700849 return mt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700850}
851
Tom Sepez281a9ea2016-02-26 14:24:28 -0800852FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const {
853 CFX_FloatRect rcTemp = rect;
Tom Sepez60d909e2015-12-10 15:34:55 -0800854 CFX_Matrix mt = GetWindowMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 mt.TransformRect(rcTemp);
856 return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5),
857 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700858}
859
Dan Sinclairf528eee2017-02-14 11:52:07 -0500860CFX_PointF CPWL_Wnd::ChildToParent(const CFX_PointF& point) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800861 CFX_Matrix mt = GetChildMatrix();
Dan Sinclair1f403ce2017-02-21 12:56:24 -0500862 return mt.IsIdentity() ? point : mt.Transform(point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700863}
864
Tom Sepez281a9ea2016-02-26 14:24:28 -0800865CFX_FloatRect CPWL_Wnd::ChildToParent(const CFX_FloatRect& rect) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800866 CFX_Matrix mt = GetChildMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700867 if (mt.IsIdentity())
868 return rect;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700869
Tom Sepez281a9ea2016-02-26 14:24:28 -0800870 CFX_FloatRect rc = rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700871 mt.TransformRect(rc);
872 return rc;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700873}
874
Dan Sinclairf528eee2017-02-14 11:52:07 -0500875CFX_PointF CPWL_Wnd::ParentToChild(const CFX_PointF& point) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800876 CFX_Matrix mt = GetChildMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 if (mt.IsIdentity())
878 return point;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700879
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700880 mt.SetReverse(mt);
Dan Sinclair1f403ce2017-02-21 12:56:24 -0500881 return mt.Transform(point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700882}
883
Tom Sepez281a9ea2016-02-26 14:24:28 -0800884CFX_FloatRect CPWL_Wnd::ParentToChild(const CFX_FloatRect& rect) const {
Tom Sepez60d909e2015-12-10 15:34:55 -0800885 CFX_Matrix mt = GetChildMatrix();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700886 if (mt.IsIdentity())
887 return rect;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700888
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700889 mt.SetReverse(mt);
Tom Sepez281a9ea2016-02-26 14:24:28 -0800890 CFX_FloatRect rc = rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700891 mt.TransformRect(rc);
892 return rc;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700893}
894
weili625ad662016-06-15 11:21:33 -0700895FX_FLOAT CPWL_Wnd::GetItemHeight(FX_FLOAT fLimitWidth) {
896 return 0;
897}
898
899FX_FLOAT CPWL_Wnd::GetItemLeftMargin() {
900 return 0;
901}
902
903FX_FLOAT CPWL_Wnd::GetItemRightMargin() {
904 return 0;
905}
906
Tom Sepez60d909e2015-12-10 15:34:55 -0800907CFX_Matrix CPWL_Wnd::GetChildToRoot() const {
908 CFX_Matrix mt(1, 0, 0, 1, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700909 if (HasFlag(PWS_CHILD)) {
910 const CPWL_Wnd* pParent = this;
911 while (pParent) {
912 mt.Concat(pParent->GetChildMatrix());
913 pParent = pParent->GetParentWindow();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700914 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700915 }
916 return mt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700917}
918
Tom Sepez60d909e2015-12-10 15:34:55 -0800919CFX_Matrix CPWL_Wnd::GetChildMatrix() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920 if (HasFlag(PWS_CHILD))
921 return m_sPrivateParam.mtChild;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700922
Tom Sepez60d909e2015-12-10 15:34:55 -0800923 return CFX_Matrix(1, 0, 0, 1, 0, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700924}
925
Tom Sepez60d909e2015-12-10 15:34:55 -0800926void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700927 m_sPrivateParam.mtChild = mt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700928}
929
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930const CPWL_Wnd* CPWL_Wnd::GetFocused() const {
tsepez6745f962017-01-04 10:09:45 -0800931 CPWL_MsgControl* pMsgCtrl = GetMsgControl();
932 return pMsgCtrl ? pMsgCtrl->m_pMainKeyboardWnd : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700933}
934
tsepez4cf55152016-11-02 14:37:54 -0700935void CPWL_Wnd::EnableWindow(bool bEnable) {
tsepez6745f962017-01-04 10:09:45 -0800936 if (m_bEnabled == bEnable)
937 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700938
tsepez6745f962017-01-04 10:09:45 -0800939 for (const auto& pChild : m_Children) {
940 if (pChild)
941 pChild->EnableWindow(bEnable);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700942 }
tsepez6745f962017-01-04 10:09:45 -0800943 m_bEnabled = bEnable;
944 if (bEnable)
945 OnEnabled();
946 else
947 OnDisabled();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700948}
949
tsepez4cf55152016-11-02 14:37:54 -0700950bool CPWL_Wnd::IsEnabled() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700951 return m_bEnabled;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700952}
953
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700954void CPWL_Wnd::OnEnabled() {}
955
956void CPWL_Wnd::OnDisabled() {}
957
tsepez4cf55152016-11-02 14:37:54 -0700958bool CPWL_Wnd::IsCTRLpressed(uint32_t nFlag) const {
dsinclairb9590102016-04-27 06:38:59 -0700959 if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700960 return pSystemHandler->IsCTRLKeyDown(nFlag);
961 }
962
tsepez4cf55152016-11-02 14:37:54 -0700963 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700964}
965
tsepez4cf55152016-11-02 14:37:54 -0700966bool CPWL_Wnd::IsSHIFTpressed(uint32_t nFlag) const {
dsinclairb9590102016-04-27 06:38:59 -0700967 if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700968 return pSystemHandler->IsSHIFTKeyDown(nFlag);
969 }
970
tsepez4cf55152016-11-02 14:37:54 -0700971 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700972}
973
tsepez4cf55152016-11-02 14:37:54 -0700974bool CPWL_Wnd::IsALTpressed(uint32_t nFlag) const {
dsinclairb9590102016-04-27 06:38:59 -0700975 if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700976 return pSystemHandler->IsALTKeyDown(nFlag);
977 }
978
tsepez4cf55152016-11-02 14:37:54 -0700979 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700980}