blob: 5184cfe70a5c4fd0c2fc36ddc02172859e2ca9fb [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
dan sinclair89e904b2016-03-23 19:29:15 -04007#include "fpdfsdk/pdfwindow/PWL_ComboBox.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
dsinclair48baa5f2016-04-06 10:00:40 -07009#include "core/fxge/include/fx_ge.h"
dsinclaire35af1e2016-07-13 11:26:20 -070010#include "fpdfsdk/fxedit/include/fxet_list.h"
dan sinclair89e904b2016-03-23 19:29:15 -040011#include "fpdfsdk/pdfwindow/PWL_Edit.h"
12#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
13#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
14#include "fpdfsdk/pdfwindow/PWL_Utils.h"
15#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080016#include "public/fpdf_fwlevent.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
Nico Weber9d8ec5a2015-08-04 13:00:21 -070018#define PWLCB_DEFAULTFONTSIZE 12.0f
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070019
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
21#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
22#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
23#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
Tom Sepez281a9ea2016-02-26 14:24:28 -080025FX_BOOL CPWL_CBListBox::OnLButtonUp(const CFX_FloatPoint& point,
tsepezc3255f52016-03-25 14:52:27 -070026 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029 if (m_bMouseDown) {
30 ReleaseCapture();
31 m_bMouseDown = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070032
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 if (ClientHitTest(point)) {
34 if (CPWL_Wnd* pParent = GetParentWindow()) {
35 pParent->OnNotify(this, PNM_LBUTTONUP, 0,
36 PWL_MAKEDWORD(point.x, point.y));
37 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070038
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039 FX_BOOL bExit = FALSE;
40 OnNotifySelChanged(FALSE, bExit, nFlag);
41 if (bExit)
Tom Sepez2f2ffec2015-07-23 14:42:09 -070042 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070043 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070045
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070047}
48
Tom Sepez62a70f92016-03-21 15:00:20 -070049FX_BOOL CPWL_CBListBox::OnKeyDownWithExit(uint16_t nChar,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050 FX_BOOL& bExit,
tsepezc3255f52016-03-25 14:52:27 -070051 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052 if (!m_pList)
53 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 switch (nChar) {
56 default:
57 return FALSE;
58 case FWL_VKEY_Up:
59 case FWL_VKEY_Down:
60 case FWL_VKEY_Home:
61 case FWL_VKEY_Left:
62 case FWL_VKEY_End:
63 case FWL_VKEY_Right:
64 break;
65 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070066
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 switch (nChar) {
68 case FWL_VKEY_Up:
69 m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
70 break;
71 case FWL_VKEY_Down:
72 m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
73 break;
74 case FWL_VKEY_Home:
75 m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
76 break;
77 case FWL_VKEY_Left:
78 m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
79 break;
80 case FWL_VKEY_End:
81 m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
82 break;
83 case FWL_VKEY_Right:
84 m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
85 break;
86 case FWL_VKEY_Delete:
87 break;
88 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 OnNotifySelChanged(TRUE, bExit, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070091
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 return TRUE;
93}
94
Tom Sepez62a70f92016-03-21 15:00:20 -070095FX_BOOL CPWL_CBListBox::OnCharWithExit(uint16_t nChar,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096 FX_BOOL& bExit,
tsepezc3255f52016-03-25 14:52:27 -070097 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 if (!m_pList)
99 return FALSE;
100
101 if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
102 return FALSE;
103
104 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow()) {
105 pComboBox->SetSelectText();
106 }
107
108 OnNotifySelChanged(TRUE, bExit, nFlag);
109
110 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700111}
112
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
114 CPWL_Wnd::GetThisAppearanceStream(sAppStream);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700115
Tom Sepez281a9ea2016-02-26 14:24:28 -0800116 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700117
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118 if (IsVisible() && !rectWnd.IsEmpty()) {
119 CFX_ByteTextBuf sButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120
Tom Sepez281a9ea2016-02-26 14:24:28 -0800121 CFX_FloatPoint ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122
Tom Sepez281a9ea2016-02-26 14:24:28 -0800123 CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
124 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
125 CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
126 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
127 CFX_FloatPoint pt3(ptCenter.x,
128 ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 if (IsFloatBigger(rectWnd.right - rectWnd.left,
131 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
132 IsFloatBigger(rectWnd.top - rectWnd.bottom,
133 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
134 sButton << "0 g\n";
135 sButton << pt1.x << " " << pt1.y << " m\n";
136 sButton << pt2.x << " " << pt2.y << " l\n";
137 sButton << pt3.x << " " << pt3.y << " l\n";
138 sButton << pt1.x << " " << pt1.y << " l f\n";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 sAppStream << "q\n" << sButton << "Q\n";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700141 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143}
144
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800146 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148
Tom Sepez281a9ea2016-02-26 14:24:28 -0800149 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700150
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 if (IsVisible() && !rectWnd.IsEmpty()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800152 CFX_FloatPoint ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153
Tom Sepez281a9ea2016-02-26 14:24:28 -0800154 CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
155 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
156 CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
157 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
158 CFX_FloatPoint pt3(ptCenter.x,
159 ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700160
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 if (IsFloatBigger(rectWnd.right - rectWnd.left,
162 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
163 IsFloatBigger(rectWnd.top - rectWnd.bottom,
164 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
165 CFX_PathData path;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 path.SetPointCount(4);
168 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
169 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
170 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
171 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700172
thestig1cd352e2016-06-07 17:53:06 -0700173 pDevice->DrawPath(&path, pUser2Device, nullptr,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,
175 GetTransparency()),
176 0, FXFILL_ALTERNATE);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700177 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700179}
180
Tom Sepez281a9ea2016-02-26 14:24:28 -0800181FX_BOOL CPWL_CBButton::OnLButtonDown(const CFX_FloatPoint& point,
tsepezc3255f52016-03-25 14:52:27 -0700182 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 if (CPWL_Wnd* pParent = GetParentWindow()) {
188 pParent->OnNotify(this, PNM_LBUTTONDOWN, 0,
189 PWL_MAKEDWORD(point.x, point.y));
190 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700191
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700193}
194
Tom Sepez281a9ea2016-02-26 14:24:28 -0800195FX_BOOL CPWL_CBButton::OnLButtonUp(const CFX_FloatPoint& point,
tsepezc3255f52016-03-25 14:52:27 -0700196 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700198
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199 ReleaseCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202}
203
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204CPWL_ComboBox::CPWL_ComboBox()
thestig1cd352e2016-06-07 17:53:06 -0700205 : m_pEdit(nullptr),
206 m_pButton(nullptr),
207 m_pList(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 m_bPopup(FALSE),
209 m_nPopupWhere(0),
210 m_nSelectItem(-1),
thestig1cd352e2016-06-07 17:53:06 -0700211 m_pFillerNotify(nullptr) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212
213CFX_ByteString CPWL_ComboBox::GetClassName() const {
214 return "CPWL_ComboBox";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215}
216
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
218 cp.dwFlags &= ~PWS_HSCROLL;
219 cp.dwFlags &= ~PWS_VSCROLL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700220}
221
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222void CPWL_ComboBox::SetFocus() {
223 if (m_pEdit)
224 m_pEdit->SetFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225}
226
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227void CPWL_ComboBox::KillFocus() {
228 SetPopup(FALSE);
229 CPWL_Wnd::KillFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230}
231
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232CFX_WideString CPWL_ComboBox::GetText() const {
233 if (m_pEdit) {
234 return m_pEdit->GetText();
235 }
236 return CFX_WideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237}
238
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239void CPWL_ComboBox::SetText(const FX_WCHAR* text) {
240 if (m_pEdit)
241 m_pEdit->SetText(text);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242}
243
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500244void CPWL_ComboBox::AddString(const FX_WCHAR* str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245 if (m_pList)
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500246 m_pList->AddString(str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247}
248
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249int32_t CPWL_ComboBox::GetSelect() const {
250 return m_nSelectItem;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700251}
252
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
254 if (m_pList)
255 m_pList->Select(nItemIndex);
256
257 m_pEdit->SetText(m_pList->GetText().c_str());
258
259 m_nSelectItem = nItemIndex;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260}
261
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
263 if (m_pEdit) {
264 m_pEdit->SetSel(nStartChar, nEndChar);
265 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700266}
267
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
269 nStartChar = -1;
270 nEndChar = -1;
271
272 if (m_pEdit) {
273 m_pEdit->GetSel(nStartChar, nEndChar);
274 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700275}
276
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277void CPWL_ComboBox::Clear() {
278 if (m_pEdit) {
279 m_pEdit->Clear();
280 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700281}
282
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700283void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
284 CreateEdit(cp);
285 CreateButton(cp);
286 CreateListBox(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700287}
288
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
290 if (!m_pEdit) {
291 m_pEdit = new CPWL_CBEdit;
292 m_pEdit->AttachFFLData(m_pFormFiller);
293
294 PWL_CREATEPARAM ecp = cp;
295 ecp.pParentWnd = this;
296 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
297 PES_AUTOSCROLL | PES_UNDO;
298
299 if (HasFlag(PWS_AUTOFONTSIZE))
300 ecp.dwFlags |= PWS_AUTOFONTSIZE;
301
302 if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
303 ecp.dwFlags |= PWS_READONLY;
304
Tom Sepez281a9ea2016-02-26 14:24:28 -0800305 ecp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 ecp.dwBorderWidth = 0;
dsinclair92cb5e52016-05-16 11:38:28 -0700307 ecp.nBorderStyle = BorderStyle::SOLID;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308
309 m_pEdit->Create(ecp);
310 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700311}
312
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700313void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
314 if (!m_pButton) {
315 m_pButton = new CPWL_CBButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 PWL_CREATEPARAM bcp = cp;
318 bcp.pParentWnd = this;
319 bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
320 bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
321 bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
322 bcp.dwBorderWidth = 2;
dsinclair92cb5e52016-05-16 11:38:28 -0700323 bcp.nBorderStyle = BorderStyle::BEVELED;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 bcp.eCursorType = FXCT_ARROW;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700325
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326 m_pButton->Create(bcp);
327 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700328}
329
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
331 if (!m_pList) {
332 m_pList = new CPWL_CBListBox;
333 m_pList->AttachFFLData(m_pFormFiller);
334 PWL_CREATEPARAM lcp = cp;
335 lcp.pParentWnd = this;
336 lcp.dwFlags =
337 PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
dsinclair92cb5e52016-05-16 11:38:28 -0700338 lcp.nBorderStyle = BorderStyle::SOLID;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 lcp.dwBorderWidth = 1;
340 lcp.eCursorType = FXCT_ARROW;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800341 lcp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700342
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700343 if (cp.dwFlags & PWS_AUTOFONTSIZE)
344 lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700345 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346 lcp.fFontSize = cp.fFontSize;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700347
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700348 if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
349 lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
350
351 if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
352 lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
353
354 m_pList->Create(lcp);
355 }
356}
357
358void CPWL_ComboBox::RePosChildWnd() {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800359 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700360
361 if (m_bPopup) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800362 CFX_FloatRect rclient = GetClientRect();
363 CFX_FloatRect rcButton = rclient;
364 CFX_FloatRect rcEdit = rcClient;
365 CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366
367 FX_FLOAT fOldWindowHeight = m_rcOldWindow.Height();
368 FX_FLOAT fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
369
370 switch (m_nPopupWhere) {
371 case 0:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700372 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700373
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374 if (rcButton.left < rclient.left)
375 rcButton.left = rclient.left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700376
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700377 rcButton.bottom = rcButton.top - fOldClientHeight;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700378
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700379 rcEdit.right = rcButton.left - 1.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700380
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 if (rcEdit.left < rclient.left)
382 rcEdit.left = rclient.left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700384 if (rcEdit.right < rcEdit.left)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 rcEdit.right = rcEdit.left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 rcEdit.bottom = rcEdit.top - fOldClientHeight;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700388
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 rcList.top -= fOldWindowHeight;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700390
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700391 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392 case 1:
393 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
394
395 if (rcButton.left < rclient.left)
396 rcButton.left = rclient.left;
397
398 rcButton.top = rcButton.bottom + fOldClientHeight;
399
400 rcEdit.right = rcButton.left - 1.0f;
401
402 if (rcEdit.left < rclient.left)
403 rcEdit.left = rclient.left;
404
405 if (rcEdit.right < rcEdit.left)
406 rcEdit.right = rcEdit.left;
407
408 rcEdit.top = rcEdit.bottom + fOldClientHeight;
409
410 rcList.bottom += fOldWindowHeight;
411
412 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700413 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700414
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415 if (m_pButton)
416 m_pButton->Move(rcButton, TRUE, FALSE);
417
418 if (m_pEdit)
419 m_pEdit->Move(rcEdit, TRUE, FALSE);
420
421 if (m_pList) {
422 m_pList->SetVisible(TRUE);
423 m_pList->Move(rcList, TRUE, FALSE);
424 m_pList->ScrollToListItem(m_nSelectItem);
425 }
426 } else {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800427 CFX_FloatRect rcButton = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700428
429 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
430
431 if (rcButton.left < rcClient.left)
432 rcButton.left = rcClient.left;
433
434 if (m_pButton)
435 m_pButton->Move(rcButton, TRUE, FALSE);
436
Tom Sepez281a9ea2016-02-26 14:24:28 -0800437 CFX_FloatRect rcEdit = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700438 rcEdit.right = rcButton.left - 1.0f;
439
440 if (rcEdit.left < rcClient.left)
441 rcEdit.left = rcClient.left;
442
443 if (rcEdit.right < rcEdit.left)
444 rcEdit.right = rcEdit.left;
445
446 if (m_pEdit)
447 m_pEdit->Move(rcEdit, TRUE, FALSE);
448
449 if (m_pList)
450 m_pList->SetVisible(FALSE);
451 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700452}
453
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454void CPWL_ComboBox::SelectAll() {
455 if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700456 m_pEdit->SelectAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700457}
458
Tom Sepez281a9ea2016-02-26 14:24:28 -0800459CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
460 return CFX_FloatRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700461}
462
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463void CPWL_ComboBox::SetPopup(FX_BOOL bPopup) {
464 if (!m_pList)
465 return;
466 if (bPopup == m_bPopup)
467 return;
468 FX_FLOAT fListHeight = m_pList->GetContentRect().Height();
469 if (!IsFloatBigger(fListHeight, 0.0f))
470 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700471
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700472 if (bPopup) {
473 if (m_pFillerNotify) {
Tom Sepez51da0932015-11-25 16:05:49 -0800474#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700475 FX_BOOL bExit = FALSE;
476 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
477 if (bExit)
478 return;
Tom Sepez40e9ff32015-11-30 12:39:54 -0800479#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700480 int32_t nWhere = 0;
481 FX_FLOAT fPopupRet = 0.0f;
482 FX_FLOAT fPopupMin = 0.0f;
483 if (m_pList->GetCount() > 3)
484 fPopupMin =
485 m_pList->GetFirstHeight() * 3 + m_pList->GetBorderWidth() * 2;
486 FX_FLOAT fPopupMax = fListHeight + m_pList->GetBorderWidth() * 2;
487 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
488 nWhere, fPopupRet);
489
490 if (IsFloatBigger(fPopupRet, 0.0f)) {
491 m_bPopup = bPopup;
492
Tom Sepez281a9ea2016-02-26 14:24:28 -0800493 CFX_FloatRect rcWindow = CPWL_Wnd::GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494 m_rcOldWindow = rcWindow;
495 switch (nWhere) {
496 default:
497 case 0:
498 rcWindow.bottom -= fPopupRet;
499 break;
500 case 1:
501 rcWindow.top += fPopupRet;
502 break;
503 }
504
505 m_nPopupWhere = nWhere;
506 Move(rcWindow, TRUE, TRUE);
Tom Sepez51da0932015-11-25 16:05:49 -0800507#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508 bExit = FALSE;
509 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
510 if (bExit)
511 return;
Tom Sepez40e9ff32015-11-30 12:39:54 -0800512#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700513 }
514 }
515 } else {
516 m_bPopup = bPopup;
517 Move(m_rcOldWindow, TRUE, TRUE);
518 }
519}
520
tsepezc3255f52016-03-25 14:52:27 -0700521FX_BOOL CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522 if (!m_pList)
523 return FALSE;
524 if (!m_pEdit)
525 return FALSE;
526
527 m_nSelectItem = -1;
528
529 switch (nChar) {
530 case FWL_VKEY_Up:
531 if (m_pList->GetCurSel() > 0) {
532 FX_BOOL bExit = FALSE;
Tom Sepez51da0932015-11-25 16:05:49 -0800533#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700534 if (m_pFillerNotify) {
535 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
536 if (bExit)
537 return FALSE;
538 bExit = FALSE;
539 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
540 if (bExit)
541 return FALSE;
542 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800543#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
545 if (bExit)
546 return FALSE;
547 SetSelectText();
548 }
549 }
550 return TRUE;
551 case FWL_VKEY_Down:
552 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
553 FX_BOOL bExit = FALSE;
Tom Sepez51da0932015-11-25 16:05:49 -0800554#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700555 if (m_pFillerNotify) {
556 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
557 if (bExit)
558 return FALSE;
559 bExit = FALSE;
560 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
561 if (bExit)
562 return FALSE;
563 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800564#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
566 if (bExit)
567 return FALSE;
568 SetSelectText();
569 }
570 }
571 return TRUE;
572 }
573
574 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
575 return m_pEdit->OnKeyDown(nChar, nFlag);
576
577 return FALSE;
578}
579
tsepezc3255f52016-03-25 14:52:27 -0700580FX_BOOL CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581 if (!m_pList)
582 return FALSE;
583
584 if (!m_pEdit)
585 return FALSE;
586
587 m_nSelectItem = -1;
588 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
589 return m_pEdit->OnChar(nChar, nFlag);
590
591 FX_BOOL bExit = FALSE;
Tom Sepez51da0932015-11-25 16:05:49 -0800592#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700593 if (m_pFillerNotify) {
594 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
595 if (bExit)
596 return FALSE;
597
598 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
599 if (bExit)
600 return FALSE;
601 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800602#endif // PDF_ENABLE_XFA
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700603 return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700604}
605
606void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd,
tsepezc3255f52016-03-25 14:52:27 -0700607 uint32_t msg,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608 intptr_t wParam,
609 intptr_t lParam) {
610 switch (msg) {
611 case PNM_LBUTTONDOWN:
612 if (pWnd == m_pButton) {
613 SetPopup(!m_bPopup);
614 return;
615 }
616 break;
617 case PNM_LBUTTONUP:
618 if (m_pEdit && m_pList) {
619 if (pWnd == m_pList) {
620 SetSelectText();
621 SelectAll();
622 m_pEdit->SetFocus();
623 SetPopup(FALSE);
624 return;
625 }
626 }
627 }
628
629 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
630}
631
632FX_BOOL CPWL_ComboBox::IsPopup() const {
633 return m_bPopup;
634}
635
636void CPWL_ComboBox::SetSelectText() {
637 CFX_WideString swText = m_pList->GetText();
638 m_pEdit->SelectAll();
639 m_pEdit->ReplaceSel(m_pList->GetText().c_str());
640 m_pEdit->SelectAll();
641
642 m_nSelectItem = m_pList->GetCurSel();
643}
644
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700645void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
646 m_pFillerNotify = pNotify;
647
648 if (m_pEdit)
649 m_pEdit->SetFillerNotify(pNotify);
650
651 if (m_pList)
652 m_pList->SetFillerNotify(pNotify);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700653}