blob: 792524b950265ddb338d493ecb3f69d6b6a5dc57 [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"
18#include "fpdfsdk/pdfwindow/cpwl_utils.h"
19#include "fpdfsdk/pdfwindow/cpwl_wnd.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080020#include "public/fpdf_fwlevent.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070021
Dan Sinclaira9e28432017-07-05 14:18:14 -040022namespace {
23
24constexpr float kDefaultFontSize = 12.0f;
25constexpr float kTriangleHalfLength = 3.0f;
26
27} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028
Dan Sinclairf528eee2017-02-14 11:52:07 -050029bool CPWL_CBListBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031
dsinclair36177512016-07-19 10:16:10 -070032 if (!m_bMouseDown)
tsepez4cf55152016-11-02 14:37:54 -070033 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034
dsinclair36177512016-07-19 10:16:10 -070035 ReleaseCapture();
tsepez4cf55152016-11-02 14:37:54 -070036 m_bMouseDown = false;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070037
dsinclair36177512016-07-19 10:16:10 -070038 if (!ClientHitTest(point))
tsepez4cf55152016-11-02 14:37:54 -070039 return true;
dsinclair36177512016-07-19 10:16:10 -070040 if (CPWL_Wnd* pParent = GetParentWindow())
Dan Sinclair7f6bec92017-07-05 14:13:16 -040041 pParent->NotifyLButtonUp(this, point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070042
Dan Sinclair1f9d2332017-07-06 12:11:33 -040043 return !OnNotifySelChanged(false, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044}
45
Dan Sinclair07dbf432017-07-06 11:47:26 -040046bool CPWL_CBListBox::IsMovementKey(uint16_t nChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 switch (nChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 case FWL_VKEY_Up:
49 case FWL_VKEY_Down:
50 case FWL_VKEY_Home:
51 case FWL_VKEY_Left:
52 case FWL_VKEY_End:
53 case FWL_VKEY_Right:
Dan Sinclair07dbf432017-07-06 11:47:26 -040054 return true;
dsinclair36177512016-07-19 10:16:10 -070055 default:
tsepez4cf55152016-11-02 14:37:54 -070056 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070057 }
Dan Sinclair07dbf432017-07-06 11:47:26 -040058}
59
60bool CPWL_CBListBox::OnMovementKeyDown(uint16_t nChar, uint32_t nFlag) {
61 ASSERT(IsMovementKey(nChar));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070062
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 switch (nChar) {
64 case FWL_VKEY_Up:
65 m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
66 break;
67 case FWL_VKEY_Down:
68 m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
69 break;
70 case FWL_VKEY_Home:
71 m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
72 break;
73 case FWL_VKEY_Left:
74 m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
75 break;
76 case FWL_VKEY_End:
77 m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
78 break;
79 case FWL_VKEY_Right:
80 m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
81 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 }
Dan Sinclair1f9d2332017-07-06 12:11:33 -040083 return OnNotifySelChanged(true, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084}
85
Dan Sinclair16fea942017-07-06 11:56:37 -040086bool CPWL_CBListBox::IsChar(uint16_t nChar, uint32_t nFlag) const {
87 return m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
88}
89
90bool CPWL_CBListBox::OnCharNotify(uint16_t nChar, uint32_t nFlag) {
dsinclair36177512016-07-19 10:16:10 -070091 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 pComboBox->SetSelectText();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093
Dan Sinclair1f9d2332017-07-06 12:11:33 -040094 return OnNotifySelChanged(true, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095}
96
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -040097void CPWL_CBButton::GetThisAppearanceStream(std::ostringstream* psAppStream) {
98 CPWL_Wnd::GetThisAppearanceStream(psAppStream);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -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 *psAppStream << "q\n"
116 << "0 g\n"
117 << pt1.x << " " << pt1.y << " m\n"
118 << pt2.x << " " << pt2.y << " l\n"
119 << pt3.x << " " << pt3.y << " l\n"
120 << pt1.x << " " << pt1.y << " l f\n"
121 << "Q\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700123}
124
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800126 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128
Tom Sepez281a9ea2016-02-26 14:24:28 -0800129 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700130
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400131 if (!IsVisible() || rectWnd.IsEmpty())
132 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700133
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400134 CFX_PointF ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135
Dan Sinclaira9e28432017-07-05 14:18:14 -0400136 CFX_PointF pt1(ptCenter.x - kTriangleHalfLength,
137 ptCenter.y + kTriangleHalfLength * 0.5f);
138 CFX_PointF pt2(ptCenter.x + kTriangleHalfLength,
139 ptCenter.y + kTriangleHalfLength * 0.5f);
140 CFX_PointF pt3(ptCenter.x, ptCenter.y - kTriangleHalfLength * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700141
Dan Sinclaira9e28432017-07-05 14:18:14 -0400142 if (IsFloatBigger(rectWnd.right - rectWnd.left, kTriangleHalfLength * 2) &&
143 IsFloatBigger(rectWnd.top - rectWnd.bottom, kTriangleHalfLength)) {
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400144 CFX_PathData path;
145 path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false);
146 path.AppendPoint(pt2, FXPT_TYPE::LineTo, false);
147 path.AppendPoint(pt3, FXPT_TYPE::LineTo, false);
148 path.AppendPoint(pt1, FXPT_TYPE::LineTo, false);
149
150 pDevice->DrawPath(&path, pUser2Device, nullptr,
151 PWL_DEFAULT_BLACKCOLOR.ToFXColor(GetTransparency()), 0,
152 FXFILL_ALTERNATE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154}
155
Dan Sinclairf528eee2017-02-14 11:52:07 -0500156bool CPWL_CBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700160
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400161 if (CPWL_Wnd* pParent = GetParentWindow())
162 pParent->NotifyLButtonDown(this, point);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700163
tsepez4cf55152016-11-02 14:37:54 -0700164 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165}
166
Dan Sinclairf528eee2017-02-14 11:52:07 -0500167bool CPWL_CBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700169
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 ReleaseCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700171
tsepez4cf55152016-11-02 14:37:54 -0700172 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700173}
174
Lei Zhang35162562017-06-09 01:04:52 -0700175CPWL_ComboBox::CPWL_ComboBox() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176
Tom Sepezb084c1f2017-05-12 14:04:06 -0700177CPWL_ComboBox::~CPWL_ComboBox() {}
178
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179CFX_ByteString CPWL_ComboBox::GetClassName() const {
180 return "CPWL_ComboBox";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700181}
182
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
184 cp.dwFlags &= ~PWS_HSCROLL;
185 cp.dwFlags &= ~PWS_VSCROLL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186}
187
Lei Zhang35162562017-06-09 01:04:52 -0700188void CPWL_ComboBox::OnDestroy() {
189 // Until cleanup takes place in the virtual destructor for CPWL_Wnd
190 // subclasses, implement the virtual OnDestroy method that does the
191 // cleanup first, then invokes the superclass OnDestroy ... gee,
192 // like a dtor would.
193 m_pList.Release();
194 m_pButton.Release();
195 m_pEdit.Release();
196 CPWL_Wnd::OnDestroy();
197}
198
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199void CPWL_ComboBox::SetFocus() {
200 if (m_pEdit)
201 m_pEdit->SetFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202}
203
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204void CPWL_ComboBox::KillFocus() {
tsepez4cf55152016-11-02 14:37:54 -0700205 SetPopup(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 CPWL_Wnd::KillFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700207}
208
Diana Gagedce2d722017-06-20 11:17:11 -0700209CFX_WideString CPWL_ComboBox::GetSelectedText() {
210 if (m_pEdit)
211 return m_pEdit->GetSelectedText();
212
213 return CFX_WideString();
214}
215
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216CFX_WideString CPWL_ComboBox::GetText() const {
217 if (m_pEdit) {
218 return m_pEdit->GetText();
219 }
220 return CFX_WideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700221}
222
tsepez067990c2016-09-13 06:46:40 -0700223void CPWL_ComboBox::SetText(const CFX_WideString& text) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224 if (m_pEdit)
225 m_pEdit->SetText(text);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226}
227
tsepez067990c2016-09-13 06:46:40 -0700228void CPWL_ComboBox::AddString(const CFX_WideString& str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 if (m_pList)
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500230 m_pList->AddString(str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700231}
232
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233int32_t CPWL_ComboBox::GetSelect() const {
234 return m_nSelectItem;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
238 if (m_pList)
239 m_pList->Select(nItemIndex);
240
tsepez067990c2016-09-13 06:46:40 -0700241 m_pEdit->SetText(m_pList->GetText());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 m_nSelectItem = nItemIndex;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243}
244
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
tsepez067990c2016-09-13 06:46:40 -0700246 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 m_pEdit->SetSel(nStartChar, nEndChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700248}
249
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
251 nStartChar = -1;
252 nEndChar = -1;
253
tsepez067990c2016-09-13 06:46:40 -0700254 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 m_pEdit->GetSel(nStartChar, nEndChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256}
257
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258void CPWL_ComboBox::Clear() {
tsepez067990c2016-09-13 06:46:40 -0700259 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 m_pEdit->Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700261}
262
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
264 CreateEdit(cp);
265 CreateButton(cp);
266 CreateListBox(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700267}
268
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700270 if (m_pEdit)
271 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -0400273 m_pEdit = new CPWL_Edit();
Tom Sepezcc205132017-05-16 14:01:47 -0700274 m_pEdit->AttachFFLData(m_pFormFiller.Get());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275
Tom Sepezb084c1f2017-05-12 14:04:06 -0700276 PWL_CREATEPARAM ecp = cp;
277 ecp.pParentWnd = this;
278 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
279 PES_AUTOSCROLL | PES_UNDO;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280
Tom Sepezb084c1f2017-05-12 14:04:06 -0700281 if (HasFlag(PWS_AUTOFONTSIZE))
282 ecp.dwFlags |= PWS_AUTOFONTSIZE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700283
Tom Sepezb084c1f2017-05-12 14:04:06 -0700284 if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
285 ecp.dwFlags |= PWS_READONLY;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286
Lei Zhangd24236a2017-06-29 18:28:58 -0700287 ecp.rcRectWnd = CFX_FloatRect();
Tom Sepezb084c1f2017-05-12 14:04:06 -0700288 ecp.dwBorderWidth = 0;
289 ecp.nBorderStyle = BorderStyle::SOLID;
290 m_pEdit->Create(ecp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291}
292
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700294 if (m_pButton)
295 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700296
Tom Sepez45b9ae12017-05-18 08:34:03 -0700297 m_pButton = new CPWL_CBButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298
Tom Sepezb084c1f2017-05-12 14:04:06 -0700299 PWL_CREATEPARAM bcp = cp;
300 bcp.pParentWnd = this;
301 bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
Dan Sinclaira9e28432017-07-05 14:18:14 -0400302 bcp.sBackgroundColor = CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f,
303 220.0f / 255.0f, 220.0f / 255.0f);
Tom Sepezb084c1f2017-05-12 14:04:06 -0700304 bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
305 bcp.dwBorderWidth = 2;
306 bcp.nBorderStyle = BorderStyle::BEVELED;
307 bcp.eCursorType = FXCT_ARROW;
308 m_pButton->Create(bcp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700309}
310
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700312 if (m_pList)
313 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700314
Tom Sepez45b9ae12017-05-18 08:34:03 -0700315 m_pList = new CPWL_CBListBox();
Tom Sepezcc205132017-05-16 14:01:47 -0700316 m_pList->AttachFFLData(m_pFormFiller.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700317
Tom Sepezb084c1f2017-05-12 14:04:06 -0700318 PWL_CREATEPARAM lcp = cp;
319 lcp.pParentWnd = this;
320 lcp.dwFlags =
321 PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
322 lcp.nBorderStyle = BorderStyle::SOLID;
323 lcp.dwBorderWidth = 1;
324 lcp.eCursorType = FXCT_ARROW;
Lei Zhangd24236a2017-06-29 18:28:58 -0700325 lcp.rcRectWnd = CFX_FloatRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326
Tom Sepezb084c1f2017-05-12 14:04:06 -0700327 if (cp.dwFlags & PWS_AUTOFONTSIZE)
Dan Sinclaira9e28432017-07-05 14:18:14 -0400328 lcp.fFontSize = kDefaultFontSize;
Tom Sepezb084c1f2017-05-12 14:04:06 -0700329 else
330 lcp.fFontSize = cp.fFontSize;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331
Tom Sepezb084c1f2017-05-12 14:04:06 -0700332 if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
333 lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
334
335 if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
336 lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
337
338 m_pList->Create(lcp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339}
340
341void CPWL_ComboBox::RePosChildWnd() {
Lei Zhang7bef7c82017-05-31 23:52:00 -0700342 const CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700343 if (m_bPopup) {
Lei Zhang7bef7c82017-05-31 23:52:00 -0700344 const float fOldWindowHeight = m_rcOldWindow.Height();
345 const float fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
346
Tom Sepez281a9ea2016-02-26 14:24:28 -0800347 CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
Lei Zhang7bef7c82017-05-31 23:52:00 -0700348 CFX_FloatRect rcButton = rcClient;
349 rcButton.left =
350 std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
351 CFX_FloatRect rcEdit = rcClient;
352 rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
353 if (m_bBottom) {
354 rcButton.bottom = rcButton.top - fOldClientHeight;
355 rcEdit.bottom = rcEdit.top - fOldClientHeight;
356 rcList.top -= fOldWindowHeight;
357 } else {
358 rcButton.top = rcButton.bottom + fOldClientHeight;
359 rcEdit.top = rcEdit.bottom + fOldClientHeight;
360 rcList.bottom += fOldWindowHeight;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700361 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700362
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 if (m_pButton)
tsepez4cf55152016-11-02 14:37:54 -0700364 m_pButton->Move(rcButton, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365
366 if (m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700367 m_pEdit->Move(rcEdit, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368
369 if (m_pList) {
tsepez4cf55152016-11-02 14:37:54 -0700370 m_pList->SetVisible(true);
371 m_pList->Move(rcList, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 m_pList->ScrollToListItem(m_nSelectItem);
373 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700374 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700375 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700376
377 CFX_FloatRect rcButton = rcClient;
378 rcButton.left =
379 std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
380
381 if (m_pButton)
382 m_pButton->Move(rcButton, true, false);
383
384 CFX_FloatRect rcEdit = rcClient;
385 rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
386
387 if (m_pEdit)
388 m_pEdit->Move(rcEdit, true, false);
389
390 if (m_pList)
391 m_pList->SetVisible(false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700392}
393
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394void CPWL_ComboBox::SelectAll() {
395 if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700396 m_pEdit->SelectAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397}
398
Tom Sepez281a9ea2016-02-26 14:24:28 -0800399CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
400 return CFX_FloatRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700401}
402
tsepez4cf55152016-11-02 14:37:54 -0700403void CPWL_ComboBox::SetPopup(bool bPopup) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700404 if (!m_pList)
405 return;
406 if (bPopup == m_bPopup)
407 return;
Dan Sinclair05df0752017-03-14 14:43:42 -0400408 float fListHeight = m_pList->GetContentRect().Height();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700409 if (!IsFloatBigger(fListHeight, 0.0f))
410 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700411
Lei Zhang7bef7c82017-05-31 23:52:00 -0700412 if (!bPopup) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700413 m_bPopup = bPopup;
tsepez4cf55152016-11-02 14:37:54 -0700414 Move(m_rcOldWindow, true, true);
Lei Zhang7bef7c82017-05-31 23:52:00 -0700415 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700416 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700417
418 if (!m_pFillerNotify)
419 return;
420
421#ifdef PDF_ENABLE_XFA
Dan Sinclair5fe98082017-07-06 11:13:02 -0400422 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), 0))
Lei Zhang7bef7c82017-05-31 23:52:00 -0700423 return;
424#endif // PDF_ENABLE_XFA
425
426 float fBorderWidth = m_pList->GetBorderWidth() * 2;
427 float fPopupMin = 0.0f;
428 if (m_pList->GetCount() > 3)
429 fPopupMin = m_pList->GetFirstHeight() * 3 + fBorderWidth;
430 float fPopupMax = fListHeight + fBorderWidth;
431
432 bool bBottom;
433 float fPopupRet;
434 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
435 &bBottom, &fPopupRet);
436 if (!IsFloatBigger(fPopupRet, 0.0f))
437 return;
438
439 m_rcOldWindow = CPWL_Wnd::GetWindowRect();
440 m_bPopup = bPopup;
441 m_bBottom = bBottom;
442
443 CFX_FloatRect rcWindow = m_rcOldWindow;
444 if (bBottom)
445 rcWindow.bottom -= fPopupRet;
446 else
447 rcWindow.top += fPopupRet;
448
449 Move(rcWindow, true, true);
450#ifdef PDF_ENABLE_XFA
Dan Sinclair5fe98082017-07-06 11:13:02 -0400451 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), 0);
Lei Zhang7bef7c82017-05-31 23:52:00 -0700452#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700453}
454
tsepez4cf55152016-11-02 14:37:54 -0700455bool CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456 if (!m_pList)
tsepez4cf55152016-11-02 14:37:54 -0700457 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700458 if (!m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700459 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700460
461 m_nSelectItem = -1;
462
463 switch (nChar) {
464 case FWL_VKEY_Up:
465 if (m_pList->GetCurSel() > 0) {
Tom Sepez51da0932015-11-25 16:05:49 -0800466#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700467 if (m_pFillerNotify) {
Dan Sinclair5fe98082017-07-06 11:13:02 -0400468 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700469 return false;
Dan Sinclair5fe98082017-07-06 11:13:02 -0400470 if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700471 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700472 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800473#endif // PDF_ENABLE_XFA
Dan Sinclair07dbf432017-07-06 11:47:26 -0400474 if (m_pList->IsMovementKey(nChar)) {
475 if (m_pList->OnMovementKeyDown(nChar, nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700476 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477 SetSelectText();
478 }
479 }
tsepez4cf55152016-11-02 14:37:54 -0700480 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700481 case FWL_VKEY_Down:
482 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
Tom Sepez51da0932015-11-25 16:05:49 -0800483#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484 if (m_pFillerNotify) {
Dan Sinclair5fe98082017-07-06 11:13:02 -0400485 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700486 return false;
Dan Sinclair5fe98082017-07-06 11:13:02 -0400487 if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700488 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700489 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800490#endif // PDF_ENABLE_XFA
Dan Sinclair07dbf432017-07-06 11:47:26 -0400491 if (m_pList->IsMovementKey(nChar)) {
492 if (m_pList->OnMovementKeyDown(nChar, nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700493 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494 SetSelectText();
495 }
496 }
tsepez4cf55152016-11-02 14:37:54 -0700497 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498 }
499
500 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
501 return m_pEdit->OnKeyDown(nChar, nFlag);
502
tsepez4cf55152016-11-02 14:37:54 -0700503 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700504}
505
tsepez4cf55152016-11-02 14:37:54 -0700506bool CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700507 if (!m_pList)
tsepez4cf55152016-11-02 14:37:54 -0700508 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509
510 if (!m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700511 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700512
513 m_nSelectItem = -1;
514 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
515 return m_pEdit->OnChar(nChar, nFlag);
516
Tom Sepez51da0932015-11-25 16:05:49 -0800517#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700518 if (m_pFillerNotify) {
Dan Sinclair5fe98082017-07-06 11:13:02 -0400519 if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700520 return false;
Dan Sinclair5fe98082017-07-06 11:13:02 -0400521 if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700522 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700523 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800524#endif // PDF_ENABLE_XFA
Dan Sinclair16fea942017-07-06 11:56:37 -0400525 if (!m_pList->IsChar(nChar, nFlag))
526 return false;
527 return m_pList->OnCharNotify(nChar, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528}
529
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400530void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
531 if (child == m_pButton)
532 SetPopup(!m_bPopup);
533}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700534
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400535void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
536 if (!m_pEdit || !m_pList || child != m_pList)
537 return;
538
539 SetSelectText();
540 SelectAll();
541 m_pEdit->SetFocus();
542 SetPopup(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700543}
544
tsepez4cf55152016-11-02 14:37:54 -0700545bool CPWL_ComboBox::IsPopup() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546 return m_bPopup;
547}
548
549void CPWL_ComboBox::SetSelectText() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550 m_pEdit->SelectAll();
tsepez067990c2016-09-13 06:46:40 -0700551 m_pEdit->ReplaceSel(m_pList->GetText());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700552 m_pEdit->SelectAll();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700553 m_nSelectItem = m_pList->GetCurSel();
554}
555
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
557 m_pFillerNotify = pNotify;
558
559 if (m_pEdit)
560 m_pEdit->SetFillerNotify(pNotify);
561
562 if (m_pList)
563 m_pList->SetFillerNotify(pNotify);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700564}