blob: 943d6acb26dab90014fc51d212f545045eb825b5 [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/PDFWindow.h"
8#include "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
9#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"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014
Nico Weber9d8ec5a2015-08-04 13:00:21 -070015#define PWLCB_DEFAULTFONTSIZE 12.0f
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
Nico Weber9d8ec5a2015-08-04 13:00:21 -070017#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
18#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
19#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
20#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070021
22/* ---------------------------- CPWL_CBListBox ---------------------------- */
23
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024FX_BOOL CPWL_CBListBox::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
25 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
111/* ---------------------------- CPWL_CBButton ---------------------------- */
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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 CPDF_Rect 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 CPDF_Point ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
124 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
125 CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
126 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
127 CPDF_Point 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,
146 CPDF_Matrix* pUser2Device) {
147 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700150
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 if (IsVisible() && !rectWnd.IsEmpty()) {
152 CPDF_Point ptCenter = GetCenterPoint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154 CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
155 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
156 CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
157 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
158 CPDF_Point 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 pDevice->DrawPath(&path, pUser2Device, NULL,
174 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181FX_BOOL CPWL_CBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
182 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700183
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700185
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186 if (CPWL_Wnd* pParent = GetParentWindow()) {
187 pParent->OnNotify(this, PNM_LBUTTONDOWN, 0,
188 PWL_MAKEDWORD(point.x, point.y));
189 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700190
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700192}
193
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194FX_BOOL CPWL_CBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
195 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
202/* ---------------------------- CPWL_ComboBox ---------------------------- */
203
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204CPWL_ComboBox::CPWL_ComboBox()
205 : m_pEdit(NULL),
206 m_pButton(NULL),
207 m_pList(NULL),
208 m_bPopup(FALSE),
209 m_nPopupWhere(0),
210 m_nSelectItem(-1),
211 m_pFillerNotify(NULL) {}
212
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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244void CPWL_ComboBox::AddString(const FX_WCHAR* string) {
245 if (m_pList)
246 m_pList->AddString(string);
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
305 ecp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
306 ecp.dwBorderWidth = 0;
307 ecp.nBorderStyle = PBS_SOLID;
308
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;
323 bcp.nBorderStyle = PBS_BEVELED;
324 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;
338 lcp.nBorderStyle = PBS_SOLID;
339 lcp.dwBorderWidth = 1;
340 lcp.eCursorType = FXCT_ARROW;
341 lcp.rcRectWnd = CPDF_Rect(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() {
359 CPDF_Rect rcClient = GetClientRect();
360
361 if (m_bPopup) {
362 CPDF_Rect rclient = GetClientRect();
363 CPDF_Rect rcButton = rclient;
364 CPDF_Rect rcEdit = rcClient;
365 CPDF_Rect rcList = CPWL_Wnd::GetWindowRect();
366
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 {
427 CPDF_Rect rcButton = rcClient;
428
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
437 CPDF_Rect rcEdit = rcClient;
438 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700459CPDF_Rect CPWL_ComboBox::GetFocusRect() const {
460 return CPDF_Rect();
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) {
474 FX_BOOL bExit = FALSE;
475 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
476 if (bExit)
477 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700478
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700479 int32_t nWhere = 0;
480 FX_FLOAT fPopupRet = 0.0f;
481 FX_FLOAT fPopupMin = 0.0f;
482 if (m_pList->GetCount() > 3)
483 fPopupMin =
484 m_pList->GetFirstHeight() * 3 + m_pList->GetBorderWidth() * 2;
485 FX_FLOAT fPopupMax = fListHeight + m_pList->GetBorderWidth() * 2;
486 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
487 nWhere, fPopupRet);
488
489 if (IsFloatBigger(fPopupRet, 0.0f)) {
490 m_bPopup = bPopup;
491
492 CPDF_Rect rcWindow = CPWL_Wnd::GetWindowRect();
493 m_rcOldWindow = rcWindow;
494 switch (nWhere) {
495 default:
496 case 0:
497 rcWindow.bottom -= fPopupRet;
498 break;
499 case 1:
500 rcWindow.top += fPopupRet;
501 break;
502 }
503
504 m_nPopupWhere = nWhere;
505 Move(rcWindow, TRUE, TRUE);
506
507 bExit = FALSE;
508 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
509 if (bExit)
510 return;
511 }
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;
531
532 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 }
541 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
542 if (bExit)
543 return FALSE;
544 SetSelectText();
545 }
546 }
547 return TRUE;
548 case FWL_VKEY_Down:
549 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
550 FX_BOOL bExit = FALSE;
551
552 if (m_pFillerNotify) {
553 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
554 if (bExit)
555 return FALSE;
556 bExit = FALSE;
557 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
558 if (bExit)
559 return FALSE;
560 }
561 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
562 if (bExit)
563 return FALSE;
564 SetSelectText();
565 }
566 }
567 return TRUE;
568 }
569
570 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
571 return m_pEdit->OnKeyDown(nChar, nFlag);
572
573 return FALSE;
574}
575
576FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
577 if (!m_pList)
578 return FALSE;
579
580 if (!m_pEdit)
581 return FALSE;
582
583 m_nSelectItem = -1;
584 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
585 return m_pEdit->OnChar(nChar, nFlag);
586
587 FX_BOOL bExit = FALSE;
588 if (m_pFillerNotify) {
589 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
590 if (bExit)
591 return FALSE;
592
593 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
594 if (bExit)
595 return FALSE;
596 }
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700597 return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700598}
599
600void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd,
601 FX_DWORD msg,
602 intptr_t wParam,
603 intptr_t lParam) {
604 switch (msg) {
605 case PNM_LBUTTONDOWN:
606 if (pWnd == m_pButton) {
607 SetPopup(!m_bPopup);
608 return;
609 }
610 break;
611 case PNM_LBUTTONUP:
612 if (m_pEdit && m_pList) {
613 if (pWnd == m_pList) {
614 SetSelectText();
615 SelectAll();
616 m_pEdit->SetFocus();
617 SetPopup(FALSE);
618 return;
619 }
620 }
621 }
622
623 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
624}
625
626FX_BOOL CPWL_ComboBox::IsPopup() const {
627 return m_bPopup;
628}
629
630void CPWL_ComboBox::SetSelectText() {
631 CFX_WideString swText = m_pList->GetText();
632 m_pEdit->SelectAll();
633 m_pEdit->ReplaceSel(m_pList->GetText().c_str());
634 m_pEdit->SelectAll();
635
636 m_nSelectItem = m_pList->GetCurSel();
637}
638
639FX_BOOL CPWL_ComboBox::IsModified() const {
640 return m_pEdit->IsModified();
641}
642
643void 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}