blob: e5076332f6b0f1e4f4ecaf883f531d1cfaff2936 [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 Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhang633a3b72017-06-02 15:27:22 -07007#include "fpdfsdk/pdfwindow/cpwl_combo_box.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
Lei Zhang7bef7c82017-05-31 23:52:00 -07009#include <algorithm>
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -040010#include <sstream>
Lei Zhang7bef7c82017-05-31 23:52:00 -070011
dsinclair74a34fc2016-09-29 16:41:42 -070012#include "core/fxge/cfx_pathdata.h"
13#include "core/fxge/cfx_renderdevice.h"
dsinclair0bb385b2016-09-29 17:03:59 -070014#include "fpdfsdk/fxedit/fxet_list.h"
Lei Zhang633a3b72017-06-02 15:27:22 -070015#include "fpdfsdk/pdfwindow/cpwl_edit.h"
16#include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h"
17#include "fpdfsdk/pdfwindow/cpwl_list_box.h"
Lei Zhang633a3b72017-06-02 15:27:22 -070018#include "fpdfsdk/pdfwindow/cpwl_wnd.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080019#include "public/fpdf_fwlevent.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070020
Dan Sinclaira9e28432017-07-05 14:18:14 -040021namespace {
22
23constexpr float kDefaultFontSize = 12.0f;
24constexpr float kTriangleHalfLength = 3.0f;
25
26} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027
Dan Sinclairf528eee2017-02-14 11:52:07 -050028bool CPWL_CBListBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070030
dsinclair36177512016-07-19 10:16:10 -070031 if (!m_bMouseDown)
tsepez4cf55152016-11-02 14:37:54 -070032 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033
dsinclair36177512016-07-19 10:16:10 -070034 ReleaseCapture();
tsepez4cf55152016-11-02 14:37:54 -070035 m_bMouseDown = false;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070036
dsinclair36177512016-07-19 10:16:10 -070037 if (!ClientHitTest(point))
tsepez4cf55152016-11-02 14:37:54 -070038 return true;
dsinclair36177512016-07-19 10:16:10 -070039 if (CPWL_Wnd* pParent = GetParentWindow())
Dan Sinclair7f6bec92017-07-05 14:13:16 -040040 pParent->NotifyLButtonUp(this, point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070041
Dan Sinclair2b444412017-07-06 13:56:35 -040042 return !OnNotifySelectionChanged(false, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043}
44
Dan Sinclair07dbf432017-07-06 11:47:26 -040045bool CPWL_CBListBox::IsMovementKey(uint16_t nChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 switch (nChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 case FWL_VKEY_Up:
48 case FWL_VKEY_Down:
49 case FWL_VKEY_Home:
50 case FWL_VKEY_Left:
51 case FWL_VKEY_End:
52 case FWL_VKEY_Right:
Dan Sinclair07dbf432017-07-06 11:47:26 -040053 return true;
dsinclair36177512016-07-19 10:16:10 -070054 default:
tsepez4cf55152016-11-02 14:37:54 -070055 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 }
Dan Sinclair07dbf432017-07-06 11:47:26 -040057}
58
59bool CPWL_CBListBox::OnMovementKeyDown(uint16_t nChar, uint32_t nFlag) {
60 ASSERT(IsMovementKey(nChar));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 switch (nChar) {
63 case FWL_VKEY_Up:
64 m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
65 break;
66 case FWL_VKEY_Down:
67 m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
68 break;
69 case FWL_VKEY_Home:
70 m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
71 break;
72 case FWL_VKEY_Left:
73 m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
74 break;
75 case FWL_VKEY_End:
76 m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
77 break;
78 case FWL_VKEY_Right:
79 m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
80 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 }
Dan Sinclair2b444412017-07-06 13:56:35 -040082 return OnNotifySelectionChanged(true, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083}
84
Dan Sinclair16fea942017-07-06 11:56:37 -040085bool CPWL_CBListBox::IsChar(uint16_t nChar, uint32_t nFlag) const {
86 return m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
87}
88
89bool CPWL_CBListBox::OnCharNotify(uint16_t nChar, uint32_t nFlag) {
dsinclair36177512016-07-19 10:16:10 -070090 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 pComboBox->SetSelectText();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092
Dan Sinclair2b444412017-07-06 13:56:35 -040093 return OnNotifySelectionChanged(true, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070094}
95
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -080097 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099
Tom Sepez281a9ea2016-02-26 14:24:28 -0800100 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700101
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400102 if (!IsVisible() || rectWnd.IsEmpty())
103 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400105 CFX_PointF ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106
Dan Sinclaira9e28432017-07-05 14:18:14 -0400107 CFX_PointF pt1(ptCenter.x - kTriangleHalfLength,
108 ptCenter.y + kTriangleHalfLength * 0.5f);
109 CFX_PointF pt2(ptCenter.x + kTriangleHalfLength,
110 ptCenter.y + kTriangleHalfLength * 0.5f);
111 CFX_PointF pt3(ptCenter.x, ptCenter.y - kTriangleHalfLength * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700112
Dan Sinclaira9e28432017-07-05 14:18:14 -0400113 if (IsFloatBigger(rectWnd.right - rectWnd.left, kTriangleHalfLength * 2) &&
114 IsFloatBigger(rectWnd.top - rectWnd.bottom, kTriangleHalfLength)) {
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400115 CFX_PathData path;
116 path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false);
117 path.AppendPoint(pt2, FXPT_TYPE::LineTo, false);
118 path.AppendPoint(pt3, FXPT_TYPE::LineTo, false);
119 path.AppendPoint(pt1, FXPT_TYPE::LineTo, false);
120
121 pDevice->DrawPath(&path, pUser2Device, nullptr,
122 PWL_DEFAULT_BLACKCOLOR.ToFXColor(GetTransparency()), 0,
123 FXFILL_ALTERNATE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125}
126
Dan Sinclairf528eee2017-02-14 11:52:07 -0500127bool CPWL_CBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400132 if (CPWL_Wnd* pParent = GetParentWindow())
133 pParent->NotifyLButtonDown(this, point);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700134
tsepez4cf55152016-11-02 14:37:54 -0700135 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136}
137
Dan Sinclairf528eee2017-02-14 11:52:07 -0500138bool CPWL_CBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700140
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 ReleaseCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700142
tsepez4cf55152016-11-02 14:37:54 -0700143 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700144}
145
Lei Zhang35162562017-06-09 01:04:52 -0700146CPWL_ComboBox::CPWL_ComboBox() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147
Tom Sepezb084c1f2017-05-12 14:04:06 -0700148CPWL_ComboBox::~CPWL_ComboBox() {}
149
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150CFX_ByteString CPWL_ComboBox::GetClassName() const {
151 return "CPWL_ComboBox";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700152}
153
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
155 cp.dwFlags &= ~PWS_HSCROLL;
156 cp.dwFlags &= ~PWS_VSCROLL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700157}
158
Lei Zhang35162562017-06-09 01:04:52 -0700159void CPWL_ComboBox::OnDestroy() {
160 // Until cleanup takes place in the virtual destructor for CPWL_Wnd
161 // subclasses, implement the virtual OnDestroy method that does the
162 // cleanup first, then invokes the superclass OnDestroy ... gee,
163 // like a dtor would.
164 m_pList.Release();
165 m_pButton.Release();
166 m_pEdit.Release();
167 CPWL_Wnd::OnDestroy();
168}
169
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170void CPWL_ComboBox::SetFocus() {
171 if (m_pEdit)
172 m_pEdit->SetFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700173}
174
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175void CPWL_ComboBox::KillFocus() {
tsepez4cf55152016-11-02 14:37:54 -0700176 SetPopup(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 CPWL_Wnd::KillFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700178}
179
Diana Gagedce2d722017-06-20 11:17:11 -0700180CFX_WideString CPWL_ComboBox::GetSelectedText() {
181 if (m_pEdit)
182 return m_pEdit->GetSelectedText();
183
184 return CFX_WideString();
185}
186
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187CFX_WideString CPWL_ComboBox::GetText() const {
188 if (m_pEdit) {
189 return m_pEdit->GetText();
190 }
191 return CFX_WideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700192}
193
tsepez067990c2016-09-13 06:46:40 -0700194void CPWL_ComboBox::SetText(const CFX_WideString& text) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195 if (m_pEdit)
196 m_pEdit->SetText(text);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700197}
198
tsepez067990c2016-09-13 06:46:40 -0700199void CPWL_ComboBox::AddString(const CFX_WideString& str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 if (m_pList)
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500201 m_pList->AddString(str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202}
203
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204int32_t CPWL_ComboBox::GetSelect() const {
205 return m_nSelectItem;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700206}
207
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
209 if (m_pList)
210 m_pList->Select(nItemIndex);
211
tsepez067990c2016-09-13 06:46:40 -0700212 m_pEdit->SetText(m_pList->GetText());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 m_nSelectItem = nItemIndex;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700214}
215
Diana Gage4d02e902017-07-20 17:20:31 -0700216void CPWL_ComboBox::SetEditSelection(int32_t nStartChar, int32_t nEndChar) {
tsepez067990c2016-09-13 06:46:40 -0700217 if (m_pEdit)
Diana Gage4d02e902017-07-20 17:20:31 -0700218 m_pEdit->SetSelection(nStartChar, nEndChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219}
220
Diana Gage4d02e902017-07-20 17:20:31 -0700221void CPWL_ComboBox::GetEditSelection(int32_t& nStartChar,
222 int32_t& nEndChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 nStartChar = -1;
224 nEndChar = -1;
225
tsepez067990c2016-09-13 06:46:40 -0700226 if (m_pEdit)
Diana Gage4d02e902017-07-20 17:20:31 -0700227 m_pEdit->GetSelection(nStartChar, nEndChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230void CPWL_ComboBox::Clear() {
tsepez067990c2016-09-13 06:46:40 -0700231 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 m_pEdit->Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
236 CreateEdit(cp);
237 CreateButton(cp);
238 CreateListBox(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239}
240
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700242 if (m_pEdit)
243 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -0400245 m_pEdit = new CPWL_Edit();
Tom Sepezcc205132017-05-16 14:01:47 -0700246 m_pEdit->AttachFFLData(m_pFormFiller.Get());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247
Tom Sepezb084c1f2017-05-12 14:04:06 -0700248 PWL_CREATEPARAM ecp = cp;
249 ecp.pParentWnd = this;
250 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
251 PES_AUTOSCROLL | PES_UNDO;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252
Tom Sepezb084c1f2017-05-12 14:04:06 -0700253 if (HasFlag(PWS_AUTOFONTSIZE))
254 ecp.dwFlags |= PWS_AUTOFONTSIZE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255
Tom Sepezb084c1f2017-05-12 14:04:06 -0700256 if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
257 ecp.dwFlags |= PWS_READONLY;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258
Lei Zhangd24236a2017-06-29 18:28:58 -0700259 ecp.rcRectWnd = CFX_FloatRect();
Tom Sepezb084c1f2017-05-12 14:04:06 -0700260 ecp.dwBorderWidth = 0;
261 ecp.nBorderStyle = BorderStyle::SOLID;
262 m_pEdit->Create(ecp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700263}
264
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700266 if (m_pButton)
267 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268
Tom Sepez45b9ae12017-05-18 08:34:03 -0700269 m_pButton = new CPWL_CBButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700270
Tom Sepezb084c1f2017-05-12 14:04:06 -0700271 PWL_CREATEPARAM bcp = cp;
272 bcp.pParentWnd = this;
273 bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
Dan Sinclair7f55a542017-07-13 14:17:10 -0400274 bcp.sBackgroundColor = CFX_Color(COLORTYPE_RGB, 220.0f / 255.0f,
275 220.0f / 255.0f, 220.0f / 255.0f);
Tom Sepezb084c1f2017-05-12 14:04:06 -0700276 bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
277 bcp.dwBorderWidth = 2;
278 bcp.nBorderStyle = BorderStyle::BEVELED;
279 bcp.eCursorType = FXCT_ARROW;
280 m_pButton->Create(bcp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700281}
282
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700283void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700284 if (m_pList)
285 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700286
Tom Sepez45b9ae12017-05-18 08:34:03 -0700287 m_pList = new CPWL_CBListBox();
Tom Sepezcc205132017-05-16 14:01:47 -0700288 m_pList->AttachFFLData(m_pFormFiller.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700289
Tom Sepezb084c1f2017-05-12 14:04:06 -0700290 PWL_CREATEPARAM lcp = cp;
291 lcp.pParentWnd = this;
292 lcp.dwFlags =
293 PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
294 lcp.nBorderStyle = BorderStyle::SOLID;
295 lcp.dwBorderWidth = 1;
296 lcp.eCursorType = FXCT_ARROW;
Lei Zhangd24236a2017-06-29 18:28:58 -0700297 lcp.rcRectWnd = CFX_FloatRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700298
Tom Sepezb084c1f2017-05-12 14:04:06 -0700299 if (cp.dwFlags & PWS_AUTOFONTSIZE)
Dan Sinclaira9e28432017-07-05 14:18:14 -0400300 lcp.fFontSize = kDefaultFontSize;
Tom Sepezb084c1f2017-05-12 14:04:06 -0700301 else
302 lcp.fFontSize = cp.fFontSize;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303
Tom Sepezb084c1f2017-05-12 14:04:06 -0700304 if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
305 lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
306
307 if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
308 lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
309
310 m_pList->Create(lcp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311}
312
313void CPWL_ComboBox::RePosChildWnd() {
Lei Zhang7bef7c82017-05-31 23:52:00 -0700314 const CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 if (m_bPopup) {
Lei Zhang7bef7c82017-05-31 23:52:00 -0700316 const float fOldWindowHeight = m_rcOldWindow.Height();
317 const float fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
318
Tom Sepez281a9ea2016-02-26 14:24:28 -0800319 CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
Lei Zhang7bef7c82017-05-31 23:52:00 -0700320 CFX_FloatRect rcButton = rcClient;
321 rcButton.left =
322 std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
323 CFX_FloatRect rcEdit = rcClient;
324 rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
325 if (m_bBottom) {
326 rcButton.bottom = rcButton.top - fOldClientHeight;
327 rcEdit.bottom = rcEdit.top - fOldClientHeight;
328 rcList.top -= fOldWindowHeight;
329 } else {
330 rcButton.top = rcButton.bottom + fOldClientHeight;
331 rcEdit.top = rcEdit.bottom + fOldClientHeight;
332 rcList.bottom += fOldWindowHeight;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700333 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700334
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335 if (m_pButton)
tsepez4cf55152016-11-02 14:37:54 -0700336 m_pButton->Move(rcButton, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337
338 if (m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700339 m_pEdit->Move(rcEdit, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340
341 if (m_pList) {
tsepez4cf55152016-11-02 14:37:54 -0700342 m_pList->SetVisible(true);
343 m_pList->Move(rcList, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700344 m_pList->ScrollToListItem(m_nSelectItem);
345 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700346 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700348
349 CFX_FloatRect rcButton = rcClient;
350 rcButton.left =
351 std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
352
353 if (m_pButton)
354 m_pButton->Move(rcButton, true, false);
355
356 CFX_FloatRect rcEdit = rcClient;
357 rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
358
359 if (m_pEdit)
360 m_pEdit->Move(rcEdit, true, false);
361
362 if (m_pList)
363 m_pList->SetVisible(false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700364}
365
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366void CPWL_ComboBox::SelectAll() {
367 if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700368 m_pEdit->SelectAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700369}
370
Tom Sepez281a9ea2016-02-26 14:24:28 -0800371CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
372 return CFX_FloatRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700373}
374
tsepez4cf55152016-11-02 14:37:54 -0700375void CPWL_ComboBox::SetPopup(bool bPopup) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376 if (!m_pList)
377 return;
378 if (bPopup == m_bPopup)
379 return;
Dan Sinclair05df0752017-03-14 14:43:42 -0400380 float fListHeight = m_pList->GetContentRect().Height();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 if (!IsFloatBigger(fListHeight, 0.0f))
382 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383
Lei Zhang7bef7c82017-05-31 23:52:00 -0700384 if (!bPopup) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 m_bPopup = bPopup;
tsepez4cf55152016-11-02 14:37:54 -0700386 Move(m_rcOldWindow, true, true);
Lei Zhang7bef7c82017-05-31 23:52:00 -0700387 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700389
390 if (!m_pFillerNotify)
391 return;
392
393#ifdef PDF_ENABLE_XFA
Dan Sinclair5fe98082017-07-06 11:13:02 -0400394 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), 0))
Lei Zhang7bef7c82017-05-31 23:52:00 -0700395 return;
396#endif // PDF_ENABLE_XFA
397
398 float fBorderWidth = m_pList->GetBorderWidth() * 2;
399 float fPopupMin = 0.0f;
400 if (m_pList->GetCount() > 3)
401 fPopupMin = m_pList->GetFirstHeight() * 3 + fBorderWidth;
402 float fPopupMax = fListHeight + fBorderWidth;
403
404 bool bBottom;
405 float fPopupRet;
406 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
407 &bBottom, &fPopupRet);
408 if (!IsFloatBigger(fPopupRet, 0.0f))
409 return;
410
411 m_rcOldWindow = CPWL_Wnd::GetWindowRect();
412 m_bPopup = bPopup;
413 m_bBottom = bBottom;
414
415 CFX_FloatRect rcWindow = m_rcOldWindow;
416 if (bBottom)
417 rcWindow.bottom -= fPopupRet;
418 else
419 rcWindow.top += fPopupRet;
420
421 Move(rcWindow, true, true);
422#ifdef PDF_ENABLE_XFA
Dan Sinclair5fe98082017-07-06 11:13:02 -0400423 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), 0);
Lei Zhang7bef7c82017-05-31 23:52:00 -0700424#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425}
426
tsepez4cf55152016-11-02 14:37:54 -0700427bool CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700428 if (!m_pList)
tsepez4cf55152016-11-02 14:37:54 -0700429 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700430 if (!m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700431 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432
433 m_nSelectItem = -1;
434
435 switch (nChar) {
436 case FWL_VKEY_Up:
437 if (m_pList->GetCurSel() > 0) {
Tom Sepez51da0932015-11-25 16:05:49 -0800438#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700439 if (m_pFillerNotify) {
Dan Sinclair5fe98082017-07-06 11:13:02 -0400440 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700441 return false;
Dan Sinclair5fe98082017-07-06 11:13:02 -0400442 if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700443 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700444 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800445#endif // PDF_ENABLE_XFA
Dan Sinclair07dbf432017-07-06 11:47:26 -0400446 if (m_pList->IsMovementKey(nChar)) {
447 if (m_pList->OnMovementKeyDown(nChar, nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700448 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700449 SetSelectText();
450 }
451 }
tsepez4cf55152016-11-02 14:37:54 -0700452 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700453 case FWL_VKEY_Down:
454 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
Tom Sepez51da0932015-11-25 16:05:49 -0800455#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456 if (m_pFillerNotify) {
Dan Sinclair5fe98082017-07-06 11:13:02 -0400457 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700458 return false;
Dan Sinclair5fe98082017-07-06 11:13:02 -0400459 if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700460 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800462#endif // PDF_ENABLE_XFA
Dan Sinclair07dbf432017-07-06 11:47:26 -0400463 if (m_pList->IsMovementKey(nChar)) {
464 if (m_pList->OnMovementKeyDown(nChar, nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700465 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700466 SetSelectText();
467 }
468 }
tsepez4cf55152016-11-02 14:37:54 -0700469 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700470 }
471
472 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
473 return m_pEdit->OnKeyDown(nChar, nFlag);
474
tsepez4cf55152016-11-02 14:37:54 -0700475 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700476}
477
tsepez4cf55152016-11-02 14:37:54 -0700478bool CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700479 if (!m_pList)
tsepez4cf55152016-11-02 14:37:54 -0700480 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700481
482 if (!m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700483 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484
485 m_nSelectItem = -1;
486 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
487 return m_pEdit->OnChar(nChar, nFlag);
488
Tom Sepez51da0932015-11-25 16:05:49 -0800489#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490 if (m_pFillerNotify) {
Dan Sinclair5fe98082017-07-06 11:13:02 -0400491 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700492 return false;
Dan Sinclair5fe98082017-07-06 11:13:02 -0400493 if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700494 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800496#endif // PDF_ENABLE_XFA
Dan Sinclair16fea942017-07-06 11:56:37 -0400497 if (!m_pList->IsChar(nChar, nFlag))
498 return false;
499 return m_pList->OnCharNotify(nChar, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700500}
501
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400502void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
503 if (child == m_pButton)
504 SetPopup(!m_bPopup);
505}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400507void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
508 if (!m_pEdit || !m_pList || child != m_pList)
509 return;
510
511 SetSelectText();
512 SelectAll();
513 m_pEdit->SetFocus();
514 SetPopup(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700515}
516
tsepez4cf55152016-11-02 14:37:54 -0700517bool CPWL_ComboBox::IsPopup() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700518 return m_bPopup;
519}
520
521void CPWL_ComboBox::SetSelectText() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522 m_pEdit->SelectAll();
tsepez067990c2016-09-13 06:46:40 -0700523 m_pEdit->ReplaceSel(m_pList->GetText());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 m_pEdit->SelectAll();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700525 m_nSelectItem = m_pList->GetCurSel();
526}
527
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
529 m_pFillerNotify = pNotify;
530
531 if (m_pEdit)
532 m_pEdit->SetFillerNotify(pNotify);
533
534 if (m_pList)
535 m_pList->SetFillerNotify(pNotify);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700536}