blob: 6edd6bdd8570f0aa4f6a09c7a3610ca9741669a3 [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 Zhangbde53d22015-11-12 22:21:30 -08007#include "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
Lei Zhangbde53d22015-11-12 22:21:30 -08009#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
10#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
11#include "fpdfsdk/include/pdfwindow/PWL_ListBox.h"
12#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
13#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080014#include "public/fpdf_fwlevent.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070015
Nico Weber9d8ec5a2015-08-04 13:00:21 -070016#define PWLCB_DEFAULTFONTSIZE 12.0f
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
Nico Weber9d8ec5a2015-08-04 13:00:21 -070018#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
19#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
20#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
21#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070022
Tom Sepez281a9ea2016-02-26 14:24:28 -080023FX_BOOL CPWL_CBListBox::OnLButtonUp(const CFX_FloatPoint& point,
24 FX_DWORD nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 if (m_bMouseDown) {
28 ReleaseCapture();
29 m_bMouseDown = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070030
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031 if (ClientHitTest(point)) {
32 if (CPWL_Wnd* pParent = GetParentWindow()) {
33 pParent->OnNotify(this, PNM_LBUTTONUP, 0,
34 PWL_MAKEDWORD(point.x, point.y));
35 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070036
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 FX_BOOL bExit = FALSE;
38 OnNotifySelChanged(FALSE, bExit, nFlag);
39 if (bExit)
Tom Sepez2f2ffec2015-07-23 14:42:09 -070040 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070041 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070042 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070045}
46
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047FX_BOOL CPWL_CBListBox::OnKeyDownWithExit(FX_WORD nChar,
48 FX_BOOL& bExit,
49 FX_DWORD nFlag) {
50 if (!m_pList)
51 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 switch (nChar) {
54 default:
55 return FALSE;
56 case FWL_VKEY_Up:
57 case FWL_VKEY_Down:
58 case FWL_VKEY_Home:
59 case FWL_VKEY_Left:
60 case FWL_VKEY_End:
61 case FWL_VKEY_Right:
62 break;
63 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065 switch (nChar) {
66 case FWL_VKEY_Up:
67 m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
68 break;
69 case FWL_VKEY_Down:
70 m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
71 break;
72 case FWL_VKEY_Home:
73 m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
74 break;
75 case FWL_VKEY_Left:
76 m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
77 break;
78 case FWL_VKEY_End:
79 m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
80 break;
81 case FWL_VKEY_Right:
82 m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
83 break;
84 case FWL_VKEY_Delete:
85 break;
86 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 OnNotifySelChanged(TRUE, bExit, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 return TRUE;
91}
92
93FX_BOOL CPWL_CBListBox::OnCharWithExit(FX_WORD nChar,
94 FX_BOOL& bExit,
95 FX_DWORD nFlag) {
96 if (!m_pList)
97 return FALSE;
98
99 if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
100 return FALSE;
101
102 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow()) {
103 pComboBox->SetSelectText();
104 }
105
106 OnNotifySelChanged(TRUE, bExit, nFlag);
107
108 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109}
110
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
112 CPWL_Wnd::GetThisAppearanceStream(sAppStream);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700113
Tom Sepez281a9ea2016-02-26 14:24:28 -0800114 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700115
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 if (IsVisible() && !rectWnd.IsEmpty()) {
117 CFX_ByteTextBuf sButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700118
Tom Sepez281a9ea2016-02-26 14:24:28 -0800119 CFX_FloatPoint ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120
Tom Sepez281a9ea2016-02-26 14:24:28 -0800121 CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
122 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
123 CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
124 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
125 CFX_FloatPoint pt3(ptCenter.x,
126 ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700127
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 if (IsFloatBigger(rectWnd.right - rectWnd.left,
129 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
130 IsFloatBigger(rectWnd.top - rectWnd.bottom,
131 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
132 sButton << "0 g\n";
133 sButton << pt1.x << " " << pt1.y << " m\n";
134 sButton << pt2.x << " " << pt2.y << " l\n";
135 sButton << pt3.x << " " << pt3.y << " l\n";
136 sButton << pt1.x << " " << pt1.y << " l f\n";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 sAppStream << "q\n" << sButton << "Q\n";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700139 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700141}
142
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800144 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700146
Tom Sepez281a9ea2016-02-26 14:24:28 -0800147 CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700148
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 if (IsVisible() && !rectWnd.IsEmpty()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800150 CFX_FloatPoint ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700151
Tom Sepez281a9ea2016-02-26 14:24:28 -0800152 CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
153 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
154 CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
155 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
156 CFX_FloatPoint pt3(ptCenter.x,
157 ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 if (IsFloatBigger(rectWnd.right - rectWnd.left,
160 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
161 IsFloatBigger(rectWnd.top - rectWnd.bottom,
162 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
163 CFX_PathData path;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700164
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 path.SetPointCount(4);
166 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
167 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
168 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
169 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700170
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 pDevice->DrawPath(&path, pUser2Device, NULL,
172 CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,
173 GetTransparency()),
174 0, FXFILL_ALTERNATE);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700175 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700177}
178
Tom Sepez281a9ea2016-02-26 14:24:28 -0800179FX_BOOL CPWL_CBButton::OnLButtonDown(const CFX_FloatPoint& point,
180 FX_DWORD nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700182
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 if (CPWL_Wnd* pParent = GetParentWindow()) {
186 pParent->OnNotify(this, PNM_LBUTTONDOWN, 0,
187 PWL_MAKEDWORD(point.x, point.y));
188 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700189
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700191}
192
Tom Sepez281a9ea2016-02-26 14:24:28 -0800193FX_BOOL CPWL_CBButton::OnLButtonUp(const CFX_FloatPoint& point,
194 FX_DWORD nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700196
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 ReleaseCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700198
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200}
201
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202CPWL_ComboBox::CPWL_ComboBox()
203 : m_pEdit(NULL),
204 m_pButton(NULL),
205 m_pList(NULL),
206 m_bPopup(FALSE),
207 m_nPopupWhere(0),
208 m_nSelectItem(-1),
209 m_pFillerNotify(NULL) {}
210
211CFX_ByteString CPWL_ComboBox::GetClassName() const {
212 return "CPWL_ComboBox";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700213}
214
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
216 cp.dwFlags &= ~PWS_HSCROLL;
217 cp.dwFlags &= ~PWS_VSCROLL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218}
219
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220void CPWL_ComboBox::SetFocus() {
221 if (m_pEdit)
222 m_pEdit->SetFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}
224
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225void CPWL_ComboBox::KillFocus() {
226 SetPopup(FALSE);
227 CPWL_Wnd::KillFocus();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230CFX_WideString CPWL_ComboBox::GetText() const {
231 if (m_pEdit) {
232 return m_pEdit->GetText();
233 }
234 return CFX_WideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237void CPWL_ComboBox::SetText(const FX_WCHAR* text) {
238 if (m_pEdit)
239 m_pEdit->SetText(text);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240}
241
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500242void CPWL_ComboBox::AddString(const FX_WCHAR* str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 if (m_pList)
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500244 m_pList->AddString(str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245}
246
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247int32_t CPWL_ComboBox::GetSelect() const {
248 return m_nSelectItem;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700249}
250
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
252 if (m_pList)
253 m_pList->Select(nItemIndex);
254
255 m_pEdit->SetText(m_pList->GetText().c_str());
256
257 m_nSelectItem = nItemIndex;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700258}
259
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
261 if (m_pEdit) {
262 m_pEdit->SetSel(nStartChar, nEndChar);
263 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700264}
265
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
267 nStartChar = -1;
268 nEndChar = -1;
269
270 if (m_pEdit) {
271 m_pEdit->GetSel(nStartChar, nEndChar);
272 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273}
274
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275void CPWL_ComboBox::Clear() {
276 if (m_pEdit) {
277 m_pEdit->Clear();
278 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279}
280
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
282 CreateEdit(cp);
283 CreateButton(cp);
284 CreateListBox(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700285}
286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
288 if (!m_pEdit) {
289 m_pEdit = new CPWL_CBEdit;
290 m_pEdit->AttachFFLData(m_pFormFiller);
291
292 PWL_CREATEPARAM ecp = cp;
293 ecp.pParentWnd = this;
294 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
295 PES_AUTOSCROLL | PES_UNDO;
296
297 if (HasFlag(PWS_AUTOFONTSIZE))
298 ecp.dwFlags |= PWS_AUTOFONTSIZE;
299
300 if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
301 ecp.dwFlags |= PWS_READONLY;
302
Tom Sepez281a9ea2016-02-26 14:24:28 -0800303 ecp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 ecp.dwBorderWidth = 0;
305 ecp.nBorderStyle = PBS_SOLID;
306
307 m_pEdit->Create(ecp);
308 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700309}
310
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
312 if (!m_pButton) {
313 m_pButton = new CPWL_CBButton;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700314
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 PWL_CREATEPARAM bcp = cp;
316 bcp.pParentWnd = this;
317 bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
318 bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
319 bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
320 bcp.dwBorderWidth = 2;
321 bcp.nBorderStyle = PBS_BEVELED;
322 bcp.eCursorType = FXCT_ARROW;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700323
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 m_pButton->Create(bcp);
325 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700326}
327
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
329 if (!m_pList) {
330 m_pList = new CPWL_CBListBox;
331 m_pList->AttachFFLData(m_pFormFiller);
332 PWL_CREATEPARAM lcp = cp;
333 lcp.pParentWnd = this;
334 lcp.dwFlags =
335 PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
336 lcp.nBorderStyle = PBS_SOLID;
337 lcp.dwBorderWidth = 1;
338 lcp.eCursorType = FXCT_ARROW;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800339 lcp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700340
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341 if (cp.dwFlags & PWS_AUTOFONTSIZE)
342 lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700343 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700344 lcp.fFontSize = cp.fFontSize;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700345
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346 if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
347 lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
348
349 if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
350 lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
351
352 m_pList->Create(lcp);
353 }
354}
355
356void CPWL_ComboBox::RePosChildWnd() {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800357 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358
359 if (m_bPopup) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800360 CFX_FloatRect rclient = GetClientRect();
361 CFX_FloatRect rcButton = rclient;
362 CFX_FloatRect rcEdit = rcClient;
363 CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364
365 FX_FLOAT fOldWindowHeight = m_rcOldWindow.Height();
366 FX_FLOAT fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
367
368 switch (m_nPopupWhere) {
369 case 0:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700370 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700371
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 if (rcButton.left < rclient.left)
373 rcButton.left = rclient.left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700374
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700375 rcButton.bottom = rcButton.top - fOldClientHeight;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700376
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700377 rcEdit.right = rcButton.left - 1.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700378
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379 if (rcEdit.left < rclient.left)
380 rcEdit.left = rclient.left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700381
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700382 if (rcEdit.right < rcEdit.left)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700383 rcEdit.right = rcEdit.left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700384
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 rcEdit.bottom = rcEdit.top - fOldClientHeight;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 rcList.top -= fOldWindowHeight;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700388
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700389 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 case 1:
391 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
392
393 if (rcButton.left < rclient.left)
394 rcButton.left = rclient.left;
395
396 rcButton.top = rcButton.bottom + fOldClientHeight;
397
398 rcEdit.right = rcButton.left - 1.0f;
399
400 if (rcEdit.left < rclient.left)
401 rcEdit.left = rclient.left;
402
403 if (rcEdit.right < rcEdit.left)
404 rcEdit.right = rcEdit.left;
405
406 rcEdit.top = rcEdit.bottom + fOldClientHeight;
407
408 rcList.bottom += fOldWindowHeight;
409
410 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700411 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700412
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700413 if (m_pButton)
414 m_pButton->Move(rcButton, TRUE, FALSE);
415
416 if (m_pEdit)
417 m_pEdit->Move(rcEdit, TRUE, FALSE);
418
419 if (m_pList) {
420 m_pList->SetVisible(TRUE);
421 m_pList->Move(rcList, TRUE, FALSE);
422 m_pList->ScrollToListItem(m_nSelectItem);
423 }
424 } else {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800425 CFX_FloatRect rcButton = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426
427 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
428
429 if (rcButton.left < rcClient.left)
430 rcButton.left = rcClient.left;
431
432 if (m_pButton)
433 m_pButton->Move(rcButton, TRUE, FALSE);
434
Tom Sepez281a9ea2016-02-26 14:24:28 -0800435 CFX_FloatRect rcEdit = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700436 rcEdit.right = rcButton.left - 1.0f;
437
438 if (rcEdit.left < rcClient.left)
439 rcEdit.left = rcClient.left;
440
441 if (rcEdit.right < rcEdit.left)
442 rcEdit.right = rcEdit.left;
443
444 if (m_pEdit)
445 m_pEdit->Move(rcEdit, TRUE, FALSE);
446
447 if (m_pList)
448 m_pList->SetVisible(FALSE);
449 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700450}
451
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700452void CPWL_ComboBox::SelectAll() {
453 if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700454 m_pEdit->SelectAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700455}
456
Tom Sepez281a9ea2016-02-26 14:24:28 -0800457CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
458 return CFX_FloatRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700459}
460
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461void CPWL_ComboBox::SetPopup(FX_BOOL bPopup) {
462 if (!m_pList)
463 return;
464 if (bPopup == m_bPopup)
465 return;
466 FX_FLOAT fListHeight = m_pList->GetContentRect().Height();
467 if (!IsFloatBigger(fListHeight, 0.0f))
468 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700469
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700470 if (bPopup) {
471 if (m_pFillerNotify) {
Tom Sepez51da0932015-11-25 16:05:49 -0800472#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 FX_BOOL bExit = FALSE;
474 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
475 if (bExit)
476 return;
Tom Sepez40e9ff32015-11-30 12:39:54 -0800477#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700478 int32_t nWhere = 0;
479 FX_FLOAT fPopupRet = 0.0f;
480 FX_FLOAT fPopupMin = 0.0f;
481 if (m_pList->GetCount() > 3)
482 fPopupMin =
483 m_pList->GetFirstHeight() * 3 + m_pList->GetBorderWidth() * 2;
484 FX_FLOAT fPopupMax = fListHeight + m_pList->GetBorderWidth() * 2;
485 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
486 nWhere, fPopupRet);
487
488 if (IsFloatBigger(fPopupRet, 0.0f)) {
489 m_bPopup = bPopup;
490
Tom Sepez281a9ea2016-02-26 14:24:28 -0800491 CFX_FloatRect rcWindow = CPWL_Wnd::GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700492 m_rcOldWindow = rcWindow;
493 switch (nWhere) {
494 default:
495 case 0:
496 rcWindow.bottom -= fPopupRet;
497 break;
498 case 1:
499 rcWindow.top += fPopupRet;
500 break;
501 }
502
503 m_nPopupWhere = nWhere;
504 Move(rcWindow, TRUE, TRUE);
Tom Sepez51da0932015-11-25 16:05:49 -0800505#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506 bExit = FALSE;
507 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
508 if (bExit)
509 return;
Tom Sepez40e9ff32015-11-30 12:39:54 -0800510#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511 }
512 }
513 } else {
514 m_bPopup = bPopup;
515 Move(m_rcOldWindow, TRUE, TRUE);
516 }
517}
518
519FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
520 if (!m_pList)
521 return FALSE;
522 if (!m_pEdit)
523 return FALSE;
524
525 m_nSelectItem = -1;
526
527 switch (nChar) {
528 case FWL_VKEY_Up:
529 if (m_pList->GetCurSel() > 0) {
530 FX_BOOL bExit = FALSE;
Tom Sepez51da0932015-11-25 16:05:49 -0800531#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700532 if (m_pFillerNotify) {
533 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
534 if (bExit)
535 return FALSE;
536 bExit = FALSE;
537 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
538 if (bExit)
539 return FALSE;
540 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800541#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
543 if (bExit)
544 return FALSE;
545 SetSelectText();
546 }
547 }
548 return TRUE;
549 case FWL_VKEY_Down:
550 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
551 FX_BOOL bExit = FALSE;
Tom Sepez51da0932015-11-25 16:05:49 -0800552#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700553 if (m_pFillerNotify) {
554 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
555 if (bExit)
556 return FALSE;
557 bExit = FALSE;
558 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
559 if (bExit)
560 return FALSE;
561 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800562#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700563 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
564 if (bExit)
565 return FALSE;
566 SetSelectText();
567 }
568 }
569 return TRUE;
570 }
571
572 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
573 return m_pEdit->OnKeyDown(nChar, nFlag);
574
575 return FALSE;
576}
577
578FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
579 if (!m_pList)
580 return FALSE;
581
582 if (!m_pEdit)
583 return FALSE;
584
585 m_nSelectItem = -1;
586 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
587 return m_pEdit->OnChar(nChar, nFlag);
588
589 FX_BOOL bExit = FALSE;
Tom Sepez51da0932015-11-25 16:05:49 -0800590#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700591 if (m_pFillerNotify) {
592 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
593 if (bExit)
594 return FALSE;
595
596 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
597 if (bExit)
598 return FALSE;
599 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800600#endif // PDF_ENABLE_XFA
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700601 return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700602}
603
604void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd,
605 FX_DWORD msg,
606 intptr_t wParam,
607 intptr_t lParam) {
608 switch (msg) {
609 case PNM_LBUTTONDOWN:
610 if (pWnd == m_pButton) {
611 SetPopup(!m_bPopup);
612 return;
613 }
614 break;
615 case PNM_LBUTTONUP:
616 if (m_pEdit && m_pList) {
617 if (pWnd == m_pList) {
618 SetSelectText();
619 SelectAll();
620 m_pEdit->SetFocus();
621 SetPopup(FALSE);
622 return;
623 }
624 }
625 }
626
627 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
628}
629
630FX_BOOL CPWL_ComboBox::IsPopup() const {
631 return m_bPopup;
632}
633
634void CPWL_ComboBox::SetSelectText() {
635 CFX_WideString swText = m_pList->GetText();
636 m_pEdit->SelectAll();
637 m_pEdit->ReplaceSel(m_pList->GetText().c_str());
638 m_pEdit->SelectAll();
639
640 m_nSelectItem = m_pList->GetCurSel();
641}
642
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700643void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
644 m_pFillerNotify = pNotify;
645
646 if (m_pEdit)
647 m_pEdit->SetFillerNotify(pNotify);
648
649 if (m_pList)
650 m_pList->SetFillerNotify(pNotify);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700651}