blob: 11a674b41b2811d915c6ea6ab0230207215e568d [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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022#define PWLCB_DEFAULTFONTSIZE 12.0f
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023
Dan Sinclairf528eee2017-02-14 11:52:07 -050024bool CPWL_CBListBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
dsinclair36177512016-07-19 10:16:10 -070027 if (!m_bMouseDown)
tsepez4cf55152016-11-02 14:37:54 -070028 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029
dsinclair36177512016-07-19 10:16:10 -070030 ReleaseCapture();
tsepez4cf55152016-11-02 14:37:54 -070031 m_bMouseDown = false;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070032
dsinclair36177512016-07-19 10:16:10 -070033 if (!ClientHitTest(point))
tsepez4cf55152016-11-02 14:37:54 -070034 return true;
dsinclair36177512016-07-19 10:16:10 -070035 if (CPWL_Wnd* pParent = GetParentWindow())
Dan Sinclair7f6bec92017-07-05 14:13:16 -040036 pParent->NotifyLButtonUp(this, point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070037
tsepez4cf55152016-11-02 14:37:54 -070038 bool bExit = false;
39 OnNotifySelChanged(false, bExit, nFlag);
dsinclair36177512016-07-19 10:16:10 -070040
41 return !bExit;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070042}
43
tsepez4cf55152016-11-02 14:37:54 -070044bool CPWL_CBListBox::OnKeyDownWithExit(uint16_t nChar,
45 bool& bExit,
46 uint32_t nFlag) {
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:
54 break;
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 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070058
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059 switch (nChar) {
60 case FWL_VKEY_Up:
61 m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
62 break;
63 case FWL_VKEY_Down:
64 m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
65 break;
66 case FWL_VKEY_Home:
67 m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
68 break;
69 case FWL_VKEY_Left:
70 m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
71 break;
72 case FWL_VKEY_End:
73 m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
74 break;
75 case FWL_VKEY_Right:
76 m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
77 break;
78 case FWL_VKEY_Delete:
79 break;
80 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070081
tsepez4cf55152016-11-02 14:37:54 -070082 OnNotifySelChanged(true, bExit, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070083
tsepez4cf55152016-11-02 14:37:54 -070084 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085}
86
tsepez4cf55152016-11-02 14:37:54 -070087bool CPWL_CBListBox::OnCharWithExit(uint16_t nChar,
88 bool& bExit,
89 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
tsepez4cf55152016-11-02 14:37:54 -070091 return false;
dsinclair36177512016-07-19 10:16:10 -070092 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093 pComboBox->SetSelectText();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094
tsepez4cf55152016-11-02 14:37:54 -070095 OnNotifySelChanged(true, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096
tsepez4cf55152016-11-02 14:37:54 -070097 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400100void CPWL_CBButton::GetThisAppearanceStream(std::ostringstream* psAppStream) {
101 CPWL_Wnd::GetThisAppearanceStream(psAppStream);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700102
Tom Sepez281a9ea2016-02-26 14:24:28 -0800103 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700104
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400105 if (!IsVisible() || rectWnd.IsEmpty())
106 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700107
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400108 CFX_PointF ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400110 CFX_PointF pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
111 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
112 CFX_PointF pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
113 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
114 CFX_PointF pt3(ptCenter.x, ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700115
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400116 if (IsFloatBigger(rectWnd.right - rectWnd.left,
117 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
118 IsFloatBigger(rectWnd.top - rectWnd.bottom,
119 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
120 *psAppStream << "q\n"
121 << "0 g\n"
122 << pt1.x << " " << pt1.y << " m\n"
123 << pt2.x << " " << pt2.y << " l\n"
124 << pt3.x << " " << pt3.y << " l\n"
125 << pt1.x << " " << pt1.y << " l f\n"
126 << "Q\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128}
129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800131 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700133
Tom Sepez281a9ea2016-02-26 14:24:28 -0800134 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700135
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400136 if (!IsVisible() || rectWnd.IsEmpty())
137 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700138
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400139 CFX_PointF ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700140
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400141 CFX_PointF pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
142 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
143 CFX_PointF pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
144 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
145 CFX_PointF pt3(ptCenter.x, ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700146
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -0400147 if (IsFloatBigger(rectWnd.right - rectWnd.left,
148 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
149 IsFloatBigger(rectWnd.top - rectWnd.bottom,
150 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
151 CFX_PathData path;
152 path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false);
153 path.AppendPoint(pt2, FXPT_TYPE::LineTo, false);
154 path.AppendPoint(pt3, FXPT_TYPE::LineTo, false);
155 path.AppendPoint(pt1, FXPT_TYPE::LineTo, false);
156
157 pDevice->DrawPath(&path, pUser2Device, nullptr,
158 PWL_DEFAULT_BLACKCOLOR.ToFXColor(GetTransparency()), 0,
159 FXFILL_ALTERNATE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700160 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700161}
162
Dan Sinclairf528eee2017-02-14 11:52:07 -0500163bool CPWL_CBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700167
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400168 if (CPWL_Wnd* pParent = GetParentWindow())
169 pParent->NotifyLButtonDown(this, point);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700170
tsepez4cf55152016-11-02 14:37:54 -0700171 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700172}
173
Dan Sinclairf528eee2017-02-14 11:52:07 -0500174bool CPWL_CBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700176
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 ReleaseCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700178
tsepez4cf55152016-11-02 14:37:54 -0700179 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700180}
181
Lei Zhang35162562017-06-09 01:04:52 -0700182CPWL_ComboBox::CPWL_ComboBox() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183
Tom Sepezb084c1f2017-05-12 14:04:06 -0700184CPWL_ComboBox::~CPWL_ComboBox() {}
185
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186CFX_ByteString CPWL_ComboBox::GetClassName() const {
187 return "CPWL_ComboBox";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700188}
189
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
191 cp.dwFlags &= ~PWS_HSCROLL;
192 cp.dwFlags &= ~PWS_VSCROLL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700193}
194
Lei Zhang35162562017-06-09 01:04:52 -0700195void CPWL_ComboBox::OnDestroy() {
196 // Until cleanup takes place in the virtual destructor for CPWL_Wnd
197 // subclasses, implement the virtual OnDestroy method that does the
198 // cleanup first, then invokes the superclass OnDestroy ... gee,
199 // like a dtor would.
200 m_pList.Release();
201 m_pButton.Release();
202 m_pEdit.Release();
203 CPWL_Wnd::OnDestroy();
204}
205
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206void CPWL_ComboBox::SetFocus() {
207 if (m_pEdit)
208 m_pEdit->SetFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700209}
210
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211void CPWL_ComboBox::KillFocus() {
tsepez4cf55152016-11-02 14:37:54 -0700212 SetPopup(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 CPWL_Wnd::KillFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700214}
215
Diana Gagedce2d722017-06-20 11:17:11 -0700216CFX_WideString CPWL_ComboBox::GetSelectedText() {
217 if (m_pEdit)
218 return m_pEdit->GetSelectedText();
219
220 return CFX_WideString();
221}
222
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223CFX_WideString CPWL_ComboBox::GetText() const {
224 if (m_pEdit) {
225 return m_pEdit->GetText();
226 }
227 return CFX_WideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
tsepez067990c2016-09-13 06:46:40 -0700230void CPWL_ComboBox::SetText(const CFX_WideString& text) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 if (m_pEdit)
232 m_pEdit->SetText(text);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
tsepez067990c2016-09-13 06:46:40 -0700235void CPWL_ComboBox::AddString(const CFX_WideString& str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236 if (m_pList)
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500237 m_pList->AddString(str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238}
239
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240int32_t CPWL_ComboBox::GetSelect() const {
241 return m_nSelectItem;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242}
243
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
245 if (m_pList)
246 m_pList->Select(nItemIndex);
247
tsepez067990c2016-09-13 06:46:40 -0700248 m_pEdit->SetText(m_pList->GetText());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 m_nSelectItem = nItemIndex;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250}
251
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
tsepez067990c2016-09-13 06:46:40 -0700253 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 m_pEdit->SetSel(nStartChar, nEndChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700255}
256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
258 nStartChar = -1;
259 nEndChar = -1;
260
tsepez067990c2016-09-13 06:46:40 -0700261 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 m_pEdit->GetSel(nStartChar, nEndChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700263}
264
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265void CPWL_ComboBox::Clear() {
tsepez067990c2016-09-13 06:46:40 -0700266 if (m_pEdit)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267 m_pEdit->Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268}
269
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
271 CreateEdit(cp);
272 CreateButton(cp);
273 CreateListBox(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700274}
275
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700277 if (m_pEdit)
278 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700279
Tom Sepez45b9ae12017-05-18 08:34:03 -0700280 m_pEdit = new CPWL_CBEdit();
Tom Sepezcc205132017-05-16 14:01:47 -0700281 m_pEdit->AttachFFLData(m_pFormFiller.Get());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282
Tom Sepezb084c1f2017-05-12 14:04:06 -0700283 PWL_CREATEPARAM ecp = cp;
284 ecp.pParentWnd = this;
285 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
286 PES_AUTOSCROLL | PES_UNDO;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287
Tom Sepezb084c1f2017-05-12 14:04:06 -0700288 if (HasFlag(PWS_AUTOFONTSIZE))
289 ecp.dwFlags |= PWS_AUTOFONTSIZE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290
Tom Sepezb084c1f2017-05-12 14:04:06 -0700291 if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
292 ecp.dwFlags |= PWS_READONLY;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293
Lei Zhangd24236a2017-06-29 18:28:58 -0700294 ecp.rcRectWnd = CFX_FloatRect();
Tom Sepezb084c1f2017-05-12 14:04:06 -0700295 ecp.dwBorderWidth = 0;
296 ecp.nBorderStyle = BorderStyle::SOLID;
297 m_pEdit->Create(ecp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298}
299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700301 if (m_pButton)
302 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700303
Tom Sepez45b9ae12017-05-18 08:34:03 -0700304 m_pButton = new CPWL_CBButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700305
Tom Sepezb084c1f2017-05-12 14:04:06 -0700306 PWL_CREATEPARAM bcp = cp;
307 bcp.pParentWnd = this;
308 bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
309 bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
310 bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
311 bcp.dwBorderWidth = 2;
312 bcp.nBorderStyle = BorderStyle::BEVELED;
313 bcp.eCursorType = FXCT_ARROW;
314 m_pButton->Create(bcp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700315}
316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
Tom Sepezb084c1f2017-05-12 14:04:06 -0700318 if (m_pList)
319 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700320
Tom Sepez45b9ae12017-05-18 08:34:03 -0700321 m_pList = new CPWL_CBListBox();
Tom Sepezcc205132017-05-16 14:01:47 -0700322 m_pList->AttachFFLData(m_pFormFiller.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700323
Tom Sepezb084c1f2017-05-12 14:04:06 -0700324 PWL_CREATEPARAM lcp = cp;
325 lcp.pParentWnd = this;
326 lcp.dwFlags =
327 PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
328 lcp.nBorderStyle = BorderStyle::SOLID;
329 lcp.dwBorderWidth = 1;
330 lcp.eCursorType = FXCT_ARROW;
Lei Zhangd24236a2017-06-29 18:28:58 -0700331 lcp.rcRectWnd = CFX_FloatRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332
Tom Sepezb084c1f2017-05-12 14:04:06 -0700333 if (cp.dwFlags & PWS_AUTOFONTSIZE)
334 lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
335 else
336 lcp.fFontSize = cp.fFontSize;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337
Tom Sepezb084c1f2017-05-12 14:04:06 -0700338 if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
339 lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
340
341 if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
342 lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
343
344 m_pList->Create(lcp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700345}
346
347void CPWL_ComboBox::RePosChildWnd() {
Lei Zhang7bef7c82017-05-31 23:52:00 -0700348 const CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349 if (m_bPopup) {
Lei Zhang7bef7c82017-05-31 23:52:00 -0700350 const float fOldWindowHeight = m_rcOldWindow.Height();
351 const float fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
352
Tom Sepez281a9ea2016-02-26 14:24:28 -0800353 CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
Lei Zhang7bef7c82017-05-31 23:52:00 -0700354 CFX_FloatRect rcButton = rcClient;
355 rcButton.left =
356 std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
357 CFX_FloatRect rcEdit = rcClient;
358 rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
359 if (m_bBottom) {
360 rcButton.bottom = rcButton.top - fOldClientHeight;
361 rcEdit.bottom = rcEdit.top - fOldClientHeight;
362 rcList.top -= fOldWindowHeight;
363 } else {
364 rcButton.top = rcButton.bottom + fOldClientHeight;
365 rcEdit.top = rcEdit.bottom + fOldClientHeight;
366 rcList.bottom += fOldWindowHeight;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700367 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700368
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369 if (m_pButton)
tsepez4cf55152016-11-02 14:37:54 -0700370 m_pButton->Move(rcButton, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371
372 if (m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700373 m_pEdit->Move(rcEdit, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374
375 if (m_pList) {
tsepez4cf55152016-11-02 14:37:54 -0700376 m_pList->SetVisible(true);
377 m_pList->Move(rcList, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700378 m_pList->ScrollToListItem(m_nSelectItem);
379 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700380 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700382
383 CFX_FloatRect rcButton = rcClient;
384 rcButton.left =
385 std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
386
387 if (m_pButton)
388 m_pButton->Move(rcButton, true, false);
389
390 CFX_FloatRect rcEdit = rcClient;
391 rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
392
393 if (m_pEdit)
394 m_pEdit->Move(rcEdit, true, false);
395
396 if (m_pList)
397 m_pList->SetVisible(false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700398}
399
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700400void CPWL_ComboBox::SelectAll() {
401 if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700402 m_pEdit->SelectAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700403}
404
Tom Sepez281a9ea2016-02-26 14:24:28 -0800405CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
406 return CFX_FloatRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
tsepez4cf55152016-11-02 14:37:54 -0700409void CPWL_ComboBox::SetPopup(bool bPopup) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410 if (!m_pList)
411 return;
412 if (bPopup == m_bPopup)
413 return;
Dan Sinclair05df0752017-03-14 14:43:42 -0400414 float fListHeight = m_pList->GetContentRect().Height();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415 if (!IsFloatBigger(fListHeight, 0.0f))
416 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700417
Lei Zhang7bef7c82017-05-31 23:52:00 -0700418 if (!bPopup) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700419 m_bPopup = bPopup;
tsepez4cf55152016-11-02 14:37:54 -0700420 Move(m_rcOldWindow, true, true);
Lei Zhang7bef7c82017-05-31 23:52:00 -0700421 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700422 }
Lei Zhang7bef7c82017-05-31 23:52:00 -0700423
424 if (!m_pFillerNotify)
425 return;
426
427#ifdef PDF_ENABLE_XFA
428 bool bExit = false;
429 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
430 if (bExit)
431 return;
432#endif // PDF_ENABLE_XFA
433
434 float fBorderWidth = m_pList->GetBorderWidth() * 2;
435 float fPopupMin = 0.0f;
436 if (m_pList->GetCount() > 3)
437 fPopupMin = m_pList->GetFirstHeight() * 3 + fBorderWidth;
438 float fPopupMax = fListHeight + fBorderWidth;
439
440 bool bBottom;
441 float fPopupRet;
442 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
443 &bBottom, &fPopupRet);
444 if (!IsFloatBigger(fPopupRet, 0.0f))
445 return;
446
447 m_rcOldWindow = CPWL_Wnd::GetWindowRect();
448 m_bPopup = bPopup;
449 m_bBottom = bBottom;
450
451 CFX_FloatRect rcWindow = m_rcOldWindow;
452 if (bBottom)
453 rcWindow.bottom -= fPopupRet;
454 else
455 rcWindow.top += fPopupRet;
456
457 Move(rcWindow, true, true);
458#ifdef PDF_ENABLE_XFA
459 bExit = false;
460 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
461#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700462}
463
tsepez4cf55152016-11-02 14:37:54 -0700464bool CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700465 if (!m_pList)
tsepez4cf55152016-11-02 14:37:54 -0700466 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700467 if (!m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700468 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700469
470 m_nSelectItem = -1;
471
472 switch (nChar) {
473 case FWL_VKEY_Up:
474 if (m_pList->GetCurSel() > 0) {
tsepez4cf55152016-11-02 14:37:54 -0700475 bool bExit = false;
Tom Sepez51da0932015-11-25 16:05:49 -0800476#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477 if (m_pFillerNotify) {
478 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
479 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700480 return false;
481 bExit = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700482 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
483 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700484 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800486#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700487 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
488 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700489 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490 SetSelectText();
491 }
492 }
tsepez4cf55152016-11-02 14:37:54 -0700493 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494 case FWL_VKEY_Down:
495 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
tsepez4cf55152016-11-02 14:37:54 -0700496 bool bExit = false;
Tom Sepez51da0932015-11-25 16:05:49 -0800497#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498 if (m_pFillerNotify) {
499 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
500 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700501 return false;
502 bExit = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
504 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700505 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800507#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
509 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700510 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511 SetSelectText();
512 }
513 }
tsepez4cf55152016-11-02 14:37:54 -0700514 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700515 }
516
517 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
518 return m_pEdit->OnKeyDown(nChar, nFlag);
519
tsepez4cf55152016-11-02 14:37:54 -0700520 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700521}
522
tsepez4cf55152016-11-02 14:37:54 -0700523bool CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 if (!m_pList)
tsepez4cf55152016-11-02 14:37:54 -0700525 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700526
527 if (!m_pEdit)
tsepez4cf55152016-11-02 14:37:54 -0700528 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700529
530 m_nSelectItem = -1;
531 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
532 return m_pEdit->OnChar(nChar, nFlag);
533
tsepez4cf55152016-11-02 14:37:54 -0700534 bool bExit = false;
Tom Sepez51da0932015-11-25 16:05:49 -0800535#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700536 if (m_pFillerNotify) {
537 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
538 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700539 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700540
541 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
542 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700543 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800545#endif // PDF_ENABLE_XFA
tsepez4cf55152016-11-02 14:37:54 -0700546 return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700547}
548
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400549void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
550 if (child == m_pButton)
551 SetPopup(!m_bPopup);
552}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700553
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400554void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
555 if (!m_pEdit || !m_pList || child != m_pList)
556 return;
557
558 SetSelectText();
559 SelectAll();
560 m_pEdit->SetFocus();
561 SetPopup(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700562}
563
tsepez4cf55152016-11-02 14:37:54 -0700564bool CPWL_ComboBox::IsPopup() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565 return m_bPopup;
566}
567
568void CPWL_ComboBox::SetSelectText() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569 m_pEdit->SelectAll();
tsepez067990c2016-09-13 06:46:40 -0700570 m_pEdit->ReplaceSel(m_pList->GetText());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700571 m_pEdit->SelectAll();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700572 m_nSelectItem = m_pList->GetCurSel();
573}
574
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700575void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
576 m_pFillerNotify = pNotify;
577
578 if (m_pEdit)
579 m_pEdit->SetFillerNotify(pNotify);
580
581 if (m_pList)
582 m_pList->SetFillerNotify(pNotify);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700583}