Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: xfa/src/fwl/basewidget/fwl_comboboximp.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // 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.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/src/fwl/basewidget/fwl_comboboximp.h"
8
9 #include "xfa/include/fwl/core/fwl_theme.h"
10 #include "xfa/src/fde/tto/fde_textout.h"
11 #include "xfa/src/fwl/basewidget/fwl_editimp.h"
12 #include "xfa/src/fwl/basewidget/fwl_formproxyimp.h"
13 #include "xfa/src/fwl/basewidget/fwl_listboximp.h"
14 #include "xfa/src/fwl/basewidget/fwl_scrollbarimp.h"
15 #include "xfa/src/fwl/core/fwl_appimp.h"
16 #include "xfa/src/fwl/core/fwl_formimp.h"
17 #include "xfa/src/fwl/core/fwl_noteimp.h"
18 #include "xfa/src/fwl/core/fwl_panelimp.h"
19 #include "xfa/src/fwl/core/fwl_targetimp.h"
20 #include "xfa/src/fwl/core/fwl_threadimp.h"
21 #include "xfa/src/fwl/core/fwl_widgetimp.h"
22 #include "xfa/src/fwl/core/fwl_widgetmgrimp.h"
23
24 // static
25 IFWL_ComboBox* IFWL_ComboBox::Create(
26 const CFWL_WidgetImpProperties& properties) {
27 IFWL_ComboBox* pComboBox = new IFWL_ComboBox;
28 CFWL_ComboBoxImp* pComboBoxImpl = new CFWL_ComboBoxImp(properties, nullptr);
29 pComboBox->SetImpl(pComboBoxImpl);
30 pComboBoxImpl->SetInterface(pComboBox);
31 return pComboBox;
32 }
33 IFWL_ComboBox::IFWL_ComboBox() {}
34 int32_t IFWL_ComboBox::GetCurSel() {
35 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetCurSel();
36 }
37 FWL_ERR IFWL_ComboBox::SetCurSel(int32_t iSel) {
38 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->SetCurSel(iSel);
39 }
40 FWL_ERR IFWL_ComboBox::SetEditText(const CFX_WideString& wsText) {
41 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->SetEditText(wsText);
42 }
43 int32_t IFWL_ComboBox::GetEditTextLength() const {
44 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetEditTextLength();
45 }
46 FWL_ERR IFWL_ComboBox::GetEditText(CFX_WideString& wsText,
47 int32_t nStart,
48 int32_t nCount) const {
49 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
50 ->GetEditText(wsText, nStart, nCount);
51 }
52 FWL_ERR IFWL_ComboBox::SetEditSelRange(int32_t nStart, int32_t nCount) {
53 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
54 ->SetEditSelRange(nStart, nCount);
55 }
56 int32_t IFWL_ComboBox::GetEditSelRange(int32_t nIndex, int32_t& nStart) {
57 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
58 ->GetEditSelRange(nIndex, nStart);
59 }
60 int32_t IFWL_ComboBox::GetEditLimit() {
61 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetEditLimit();
62 }
63 FWL_ERR IFWL_ComboBox::SetEditLimit(int32_t nLimit) {
64 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->SetEditLimit(nLimit);
65 }
66 FWL_ERR IFWL_ComboBox::EditDoClipboard(int32_t iCmd) {
67 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditDoClipboard(iCmd);
68 }
69 FX_BOOL IFWL_ComboBox::EditRedo(const CFX_ByteStringC& bsRecord) {
70 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditRedo(bsRecord);
71 }
72 FX_BOOL IFWL_ComboBox::EditUndo(const CFX_ByteStringC& bsRecord) {
73 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditUndo(bsRecord);
74 }
75 IFWL_ListBox* IFWL_ComboBox::GetListBoxt() {
76 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetListBoxt();
77 }
78 FX_BOOL IFWL_ComboBox::AfterFocusShowDropList() {
79 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->AfterFocusShowDropList();
80 }
81 FX_ERR IFWL_ComboBox::OpenDropDownList(FX_BOOL bActivate) {
82 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->OpenDropDownList(bActivate);
83 }
84 FX_BOOL IFWL_ComboBox::EditCanUndo() {
85 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanUndo();
86 }
87 FX_BOOL IFWL_ComboBox::EditCanRedo() {
88 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanRedo();
89 }
90 FX_BOOL IFWL_ComboBox::EditUndo() {
91 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditUndo();
92 }
93 FX_BOOL IFWL_ComboBox::EditRedo() {
94 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditRedo();
95 }
96 FX_BOOL IFWL_ComboBox::EditCanCopy() {
97 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanCopy();
98 }
99 FX_BOOL IFWL_ComboBox::EditCanCut() {
100 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanCut();
101 }
102 FX_BOOL IFWL_ComboBox::EditCanSelectAll() {
103 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanSelectAll();
104 }
105 FX_BOOL IFWL_ComboBox::EditCopy(CFX_WideString& wsCopy) {
106 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCopy(wsCopy);
107 }
108 FX_BOOL IFWL_ComboBox::EditCut(CFX_WideString& wsCut) {
109 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCut(wsCut);
110 }
111 FX_BOOL IFWL_ComboBox::EditPaste(const CFX_WideString& wsPaste) {
112 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditPaste(wsPaste);
113 }
114 FX_BOOL IFWL_ComboBox::EditSelectAll() {
115 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditSelectAll();
116 }
117 FX_BOOL IFWL_ComboBox::EditDelete() {
118 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditDelete();
119 }
120 FX_BOOL IFWL_ComboBox::EditDeSelect() {
121 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditDeSelect();
122 }
123 FWL_ERR IFWL_ComboBox::GetBBox(CFX_RectF& rect) {
124 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetBBox(rect);
125 }
126 FWL_ERR IFWL_ComboBox::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
127 FX_DWORD dwStylesExRemoved) {
128 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
129 ->EditModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
130 }
131
132 CFWL_ComboEditImp::CFWL_ComboEditImp(const CFWL_WidgetImpProperties& properties,
133 IFWL_Widget* pOuter)
134 : CFWL_EditImp(properties, pOuter) {
135 m_pOuter = static_cast<CFWL_ComboBoxImp*>(pOuter->GetImpl());
136 }
137
138 CFWL_ComboEditImpDelegate::CFWL_ComboEditImpDelegate(CFWL_ComboEditImp* pOwner)
139 : CFWL_EditImpDelegate(pOwner), m_pOwner(pOwner) {}
140 int32_t CFWL_ComboEditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
141 if (!pMessage)
142 return 0;
143 FX_DWORD dwMsgCode = pMessage->GetClassID();
144 FX_BOOL backDefault = TRUE;
145 switch (dwMsgCode) {
146 case FWL_MSGHASH_SetFocus:
147 case FWL_MSGHASH_KillFocus: {
148 if (dwMsgCode == FWL_MSGHASH_SetFocus) {
149 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
150 } else {
151 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
152 }
153 backDefault = FALSE;
154 break;
155 }
156 case FWL_MSGHASH_Mouse: {
157 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
158 if ((pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) &&
159 ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)) {
160 m_pOwner->SetSelected();
161 m_pOwner->SetComboBoxFocus(TRUE);
162 }
163 break;
164 }
165 default: {}
166 }
167 if (!backDefault) {
168 return 1;
169 }
170 return CFWL_EditImpDelegate::OnProcessMessage(pMessage);
171 }
172 void CFWL_ComboEditImp::ClearSelected() {
173 ClearSelections();
174 Repaint(&m_rtClient);
175 }
176 void CFWL_ComboEditImp::SetSelected() {
177 FlagFocus(TRUE);
178 EndCaret();
179 AddSelRange(0);
180 }
181 void CFWL_ComboEditImp::EndCaret() {
182 m_pEdtEngine->MoveCaretPos(MC_End);
183 }
184 void CFWL_ComboEditImp::FlagFocus(FX_BOOL bSet) {
185 if (bSet) {
186 m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
187 } else {
188 m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
189 ShowCaret(FALSE);
190 }
191 }
192 void CFWL_ComboEditImp::SetComboBoxFocus(FX_BOOL bSet) {
193 m_pOuter->SetFocus(bSet);
194 }
195 CFWL_ComboListImp::CFWL_ComboListImp(const CFWL_WidgetImpProperties& properties,
196 IFWL_Widget* pOuter)
197 : CFWL_ListBoxImp(properties, pOuter), m_bNotifyOwner(TRUE) {
198 FXSYS_assert(pOuter != NULL);
199 }
200 FWL_ERR CFWL_ComboListImp::Initialize() {
201 if (CFWL_ListBoxImp::Initialize() != FWL_ERR_Succeeded)
202 return FWL_ERR_Indefinite;
203 delete m_pDelegate;
204 m_pDelegate = new CFWL_ComboListImpDelegate(this);
205 return FWL_ERR_Succeeded;
206 }
207 FWL_ERR CFWL_ComboListImp::Finalize() {
208 delete m_pDelegate;
209 m_pDelegate = nullptr;
210 return CFWL_ListBoxImp::Finalize();
211 }
212 int32_t CFWL_ComboListImp::MatchItem(const CFX_WideString& wsMatch) {
213 if (wsMatch.IsEmpty()) {
214 return -1;
215 }
216 if (!m_pProperties->m_pDataProvider)
217 return -1;
218 IFWL_ListBoxDP* pData =
219 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
220 int32_t iCount = pData->CountItems(m_pInterface);
221 for (int32_t i = 0; i < iCount; i++) {
222 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
223 CFX_WideString wsText;
224 pData->GetItemText(m_pInterface, hItem, wsText);
225 FX_STRSIZE pos = wsText.Find(wsMatch.c_str());
226 if (!pos) {
227 return i;
228 }
229 }
230 return -1;
231 }
232 void CFWL_ComboListImp::ChangeSelected(int32_t iSel) {
233 if (!m_pProperties->m_pDataProvider)
234 return;
235 IFWL_ListBoxDP* pData =
236 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
237 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iSel);
238 CFX_RectF rtInvalidate;
239 rtInvalidate.Reset();
240 FWL_HLISTITEM hOld = GetSelItem(0);
241 int32_t iOld = pData->GetItemIndex(m_pInterface, hOld);
242 if (iOld == iSel) {
243 return;
244 } else if (iOld > -1) {
245 GetItemRect(iOld, rtInvalidate);
246 SetSelItem(hOld, FALSE);
247 }
248 if (hItem) {
249 CFX_RectF rect;
250 GetItemRect(iSel, rect);
251 rtInvalidate.Union(rect);
252 FWL_HLISTITEM hSel = pData->GetItem(m_pInterface, iSel);
253 SetSelItem(hSel, TRUE);
254 }
255 if (!rtInvalidate.IsEmpty()) {
256 Repaint(&rtInvalidate);
257 }
258 }
259 int32_t CFWL_ComboListImp::CountItems() {
260 IFWL_ListBoxDP* pData =
261 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
262 return pData ? pData->CountItems(m_pInterface) : 0;
263 }
264 void CFWL_ComboListImp::GetItemRect(int32_t nIndex, CFX_RectF& rtItem) {
265 IFWL_ListBoxDP* pData =
266 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
267 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, nIndex);
268 pData->GetItemRect(m_pInterface, hItem, rtItem);
269 }
270 void CFWL_ComboListImp::ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy) {
271 fx += m_pProperties->m_rtWidget.left, fy += m_pProperties->m_rtWidget.top;
272 IFWL_Widget* pOwner = GetOwner();
273 if (!pOwner)
274 return;
275 pOwner->TransformTo(m_pOuter, fx, fy);
276 }
277 void CFWL_ComboListImp::SetFocus(FX_BOOL bSet) {
278 CFWL_WidgetImp::SetFocus(bSet);
279 }
280 CFWL_ComboListImpDelegate::CFWL_ComboListImpDelegate(CFWL_ComboListImp* pOwner)
281 : CFWL_ListBoxImpDelegate(pOwner), m_pOwner(pOwner) {}
282 int32_t CFWL_ComboListImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
283 if (!pMessage)
284 return 0;
285 FX_DWORD dwHashCode = pMessage->GetClassID();
286 FX_BOOL backDefault = TRUE;
287 if (dwHashCode == FWL_MSGHASH_SetFocus ||
288 dwHashCode == FWL_MSGHASH_KillFocus) {
289 OnDropListFocusChanged(pMessage, dwHashCode == FWL_MSGHASH_SetFocus);
290 } else if (dwHashCode == FWL_MSGHASH_Mouse) {
291 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
292 if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
293 CFX_RectF rect;
294 m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
295 if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
296 pMsg->m_fx -= rect.left;
297 pMsg->m_fy -= rect.top;
298 IFWL_WidgetDelegate* pDelegate =
299 m_pOwner->m_pVertScrollBar->SetDelegate(NULL);
300 return pDelegate->OnProcessMessage(pMsg);
301 }
302 }
303 FX_DWORD dwCmd = pMsg->m_dwCmd;
304 switch (dwCmd) {
305 case FWL_MSGMOUSECMD_MouseMove: {
306 backDefault = FALSE;
307 OnDropListMouseMove(pMsg);
308 break;
309 }
310 case FWL_MSGMOUSECMD_LButtonDown: {
311 backDefault = FALSE;
312 OnDropListLButtonDown(pMsg);
313 break;
314 }
315 case FWL_MSGMOUSECMD_LButtonUp: {
316 backDefault = FALSE;
317 OnDropListLButtonUp(pMsg);
318 break;
319 }
320 default: {}
321 }
322 } else if (dwHashCode == FWL_MSGHASH_Key) {
323 backDefault = !OnDropListKey(static_cast<CFWL_MsgKey*>(pMessage));
324 }
325 if (!backDefault) {
326 return 1;
327 }
328 return CFWL_ListBoxImpDelegate::OnProcessMessage(pMessage);
329 }
330 void CFWL_ComboListImpDelegate::OnDropListFocusChanged(CFWL_Message* pMsg,
331 FX_BOOL bSet) {
332 if (!bSet) {
333 CFWL_MsgKillFocus* pKill = static_cast<CFWL_MsgKillFocus*>(pMsg);
334 CFWL_ComboBoxImp* pOuter =
335 static_cast<CFWL_ComboBoxImp*>(m_pOwner->m_pOuter->GetImpl());
336 if (pKill->m_pSetFocus == m_pOwner->m_pOuter ||
337 pKill->m_pSetFocus == pOuter->m_pEdit.get()) {
338 pOuter->ShowDropList(FALSE);
339 }
340 }
341 }
342 int32_t CFWL_ComboListImpDelegate::OnDropListMouseMove(CFWL_MsgMouse* pMsg) {
343 if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
344 if (m_pOwner->m_bNotifyOwner) {
345 m_pOwner->m_bNotifyOwner = FALSE;
346 }
347 if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
348 CFX_RectF rect;
349 m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
350 if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
351 return 1;
352 }
353 }
354 FWL_HLISTITEM hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
355 if (hItem) {
356 if (!m_pOwner->m_pProperties->m_pDataProvider)
357 return 0;
358 IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
359 m_pOwner->m_pProperties->m_pDataProvider);
360 int32_t iSel = pData->GetItemIndex(m_pOwner->m_pInterface, hItem);
361 CFWL_EvtCmbHoverChanged event;
362 event.m_pSrcTarget = m_pOwner->m_pOuter;
363 event.m_iCurHover = iSel;
364 m_pOwner->DispatchEvent(&event);
365 m_pOwner->ChangeSelected(iSel);
366 }
367 } else if (m_pOwner->m_bNotifyOwner) {
368 m_pOwner->ClientToOuter(pMsg->m_fx, pMsg->m_fy);
369 CFWL_ComboBoxImp* pOuter =
370 static_cast<CFWL_ComboBoxImp*>(m_pOwner->m_pOuter->GetImpl());
371 pOuter->m_pDelegate->OnProcessMessage(pMsg);
372 }
373 return 1;
374 }
375 int32_t CFWL_ComboListImpDelegate::OnDropListLButtonDown(CFWL_MsgMouse* pMsg) {
376 if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
377 return 0;
378 }
379 CFWL_ComboBoxImp* pOuter =
380 static_cast<CFWL_ComboBoxImp*>(m_pOwner->m_pOuter->GetImpl());
381 pOuter->ShowDropList(FALSE);
382 return 1;
383 }
384 int32_t CFWL_ComboListImpDelegate::OnDropListLButtonUp(CFWL_MsgMouse* pMsg) {
385 CFWL_ComboBoxImp* pOuter =
386 static_cast<CFWL_ComboBoxImp*>(m_pOwner->m_pOuter->GetImpl());
387 if (m_pOwner->m_bNotifyOwner) {
388 m_pOwner->ClientToOuter(pMsg->m_fx, pMsg->m_fy);
389 pOuter->m_pDelegate->OnProcessMessage(pMsg);
390 } else {
391 if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
392 CFX_RectF rect;
393 m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
394 if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
395 return 1;
396 }
397 }
398 pOuter->ShowDropList(FALSE);
399 FWL_HLISTITEM hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
400 if (hItem) {
401 pOuter->ProcessSelChanged(TRUE);
402 }
403 }
404 return 1;
405 }
406 int32_t CFWL_ComboListImpDelegate::OnDropListKey(CFWL_MsgKey* pKey) {
407 CFWL_ComboBoxImp* pOuter =
408 static_cast<CFWL_ComboBoxImp*>(m_pOwner->m_pOuter->GetImpl());
409 FX_BOOL bPropagate = FALSE;
410 if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
411 FX_DWORD dwKeyCode = pKey->m_dwKeyCode;
412 switch (dwKeyCode) {
413 case FWL_VKEY_Return:
414 case FWL_VKEY_Escape: {
415 pOuter->ShowDropList(FALSE);
416 return 1;
417 }
418 case FWL_VKEY_Up:
419 case FWL_VKEY_Down: {
420 OnDropListKeyDown(pKey);
421 pOuter->SetDelegate(nullptr);
422 pOuter->ProcessSelChanged(FALSE);
423 return 1;
424 }
425 default: { bPropagate = TRUE; }
426 }
427 } else if (pKey->m_dwCmd == FWL_MSGKEYCMD_Char) {
428 bPropagate = TRUE;
429 }
430 if (bPropagate) {
431 pKey->m_pDstTarget = m_pOwner->m_pOuter;
432 pOuter->m_pDelegate->OnProcessMessage(pKey);
433 return 1;
434 }
435 return 0;
436 }
437 void CFWL_ComboListImpDelegate::OnDropListKeyDown(CFWL_MsgKey* pKey) {
438 FX_DWORD dwKeyCode = pKey->m_dwKeyCode;
439 switch (dwKeyCode) {
440 case FWL_VKEY_Up:
441 case FWL_VKEY_Down:
442 case FWL_VKEY_Home:
443 case FWL_VKEY_End: {
444 CFWL_ComboBoxImp* pOuter =
445 static_cast<CFWL_ComboBoxImp*>(m_pOwner->m_pOuter->GetImpl());
446 IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
447 m_pOwner->m_pProperties->m_pDataProvider);
448 FWL_HLISTITEM hItem =
449 pData->GetItem(m_pOwner->m_pInterface, pOuter->m_iCurSel);
450 hItem = m_pOwner->GetItem(hItem, dwKeyCode);
451 if (!hItem) {
452 break;
453 }
454 m_pOwner->SetSelection(hItem, hItem, TRUE);
455 m_pOwner->ScrollToVisible(hItem);
456 CFX_RectF rtInvalidate;
457 rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
458 m_pOwner->m_pProperties->m_rtWidget.height);
459 m_pOwner->Repaint(&rtInvalidate);
460 break;
461 }
462 default: {}
463 }
464 }
465 CFWL_ComboBoxImp::CFWL_ComboBoxImp(const CFWL_WidgetImpProperties& properties,
466 IFWL_Widget* pOuter)
467 : CFWL_WidgetImp(properties, pOuter),
468 m_pForm(NULL),
469 m_bLButtonDown(FALSE),
470 m_iCurSel(-1),
471 m_iBtnState(FWL_PARTSTATE_CMB_Normal),
472 m_fComboFormHandler(0),
473 m_bNeedShowList(FALSE) {
474 m_rtClient.Reset();
475 m_rtBtn.Reset();
476 m_rtHandler.Reset();
477 }
478 CFWL_ComboBoxImp::~CFWL_ComboBoxImp() {}
479 FWL_ERR CFWL_ComboBoxImp::GetClassName(CFX_WideString& wsClass) const {
480 wsClass = FWL_CLASS_ComboBox;
481 return FWL_ERR_Succeeded;
482 }
483 FX_DWORD CFWL_ComboBoxImp::GetClassID() const {
484 return FWL_CLASSHASH_ComboBox;
485 }
486 FWL_ERR CFWL_ComboBoxImp::Initialize() {
487 if (m_pWidgetMgr->IsFormDisabled()) {
488 return DisForm_Initialize();
489 }
490 if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
491 return FWL_WGTSTATE_Invisible; // Probably a bug; not a FWL_ERR_ value.
492 m_pDelegate = new CFWL_ComboBoxImpDelegate(this);
493 CFWL_WidgetImpProperties prop;
494 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
495 prop.m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
496 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) {
497 prop.m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon;
498 }
499 prop.m_pDataProvider = m_pProperties->m_pDataProvider;
500 m_pListBox.reset(IFWL_ListBox::CreateComboList(prop, m_pInterface));
501 m_pListBox->Initialize();
502 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) {
503 CFWL_WidgetImpProperties prop2;
504 m_pEdit.reset(IFWL_Edit::CreateComboEdit(prop2, m_pInterface));
505 m_pEdit->Initialize();
506 static_cast<CFWL_EditImp*>(m_pEdit->GetImpl())->SetOuter(m_pInterface);
507 }
508 if (m_pEdit) {
509 m_pEdit->SetParent(m_pInterface);
510 }
511 SetStates(m_pProperties->m_dwStates);
512 return FWL_ERR_Succeeded;
513 }
514 FWL_ERR CFWL_ComboBoxImp::Finalize() {
515 if (m_pEdit) {
516 m_pEdit->Finalize();
517 }
518 m_pListBox->Finalize();
519 delete m_pDelegate;
520 m_pDelegate = nullptr;
521 return CFWL_WidgetImp::Finalize();
522 }
523 FWL_ERR CFWL_ComboBoxImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
524 if (bAutoSize) {
525 rect.Reset();
526 FX_BOOL bIsDropDown = IsDropDownStyle();
527 if (bIsDropDown && m_pEdit) {
528 m_pEdit->GetWidgetRect(rect, TRUE);
529 } else {
530 rect.width = 100;
531 rect.height = 16;
532 }
533 if (!m_pProperties->m_pThemeProvider) {
534 ReSetTheme();
535 }
536 FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>(
537 GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
538 if (!pFWidth)
539 return FWL_ERR_Indefinite;
540 rect.Inflate(0, 0, *pFWidth, 0);
541 CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
542 } else {
543 rect = m_pProperties->m_rtWidget;
544 }
545 return FWL_ERR_Succeeded;
546 }
547 FWL_ERR CFWL_ComboBoxImp::ModifyStylesEx(FX_DWORD dwStylesExAdded,
548 FX_DWORD dwStylesExRemoved) {
549 if (m_pWidgetMgr->IsFormDisabled()) {
550 return DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
551 }
552 FX_BOOL bAddDropDown = dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown;
553 FX_BOOL bRemoveDropDown = dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown;
554 if (bAddDropDown && !m_pEdit) {
555 CFWL_WidgetImpProperties prop;
556 m_pEdit.reset(IFWL_Edit::CreateComboEdit(prop, nullptr));
557 m_pEdit->Initialize();
558 static_cast<CFWL_EditImp*>(m_pEdit->GetImpl())->SetOuter(m_pInterface);
559 m_pEdit->SetParent(m_pInterface);
560 } else if (bRemoveDropDown && m_pEdit) {
561 m_pEdit->SetStates(FWL_WGTSTATE_Invisible, TRUE);
562 }
563 return CFWL_WidgetImp::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
564 }
565 FWL_ERR CFWL_ComboBoxImp::Update() {
566 if (m_pWidgetMgr->IsFormDisabled()) {
567 return DisForm_Update();
568 }
569 if (IsLocked()) {
570 return FWL_ERR_Indefinite;
571 }
572 ReSetTheme();
573 FX_BOOL bDropDown = IsDropDownStyle();
574 if (bDropDown && m_pEdit) {
575 ReSetEditAlignment();
576 }
577 if (m_pProperties->m_pThemeProvider == NULL) {
578 m_pProperties->m_pThemeProvider = GetAvailableTheme();
579 }
580 Layout();
581 CFWL_ThemePart part;
582 part.m_pWidget = m_pInterface;
583 m_fComboFormHandler =
584 *static_cast<FX_FLOAT*>(m_pProperties->m_pThemeProvider->GetCapacity(
585 &part, FWL_WGTCAPACITY_CMB_ComboFormHandler));
586 return FWL_ERR_Succeeded;
587 }
588 FX_DWORD CFWL_ComboBoxImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
589 if (m_pWidgetMgr->IsFormDisabled()) {
590 return DisForm_HitTest(fx, fy);
591 }
592 return CFWL_WidgetImp::HitTest(fx, fy);
593 }
594 FWL_ERR CFWL_ComboBoxImp::DrawWidget(CFX_Graphics* pGraphics,
595 const CFX_Matrix* pMatrix) {
596 if (m_pWidgetMgr->IsFormDisabled()) {
597 return DisForm_DrawWidget(pGraphics, pMatrix);
598 }
599 if (!pGraphics)
600 return FWL_ERR_Indefinite;
601 if (!m_pProperties->m_pThemeProvider)
602 return FWL_ERR_Indefinite;
603 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
604 FX_BOOL bIsDropDown = IsDropDownStyle();
605 if (HasBorder()) {
606 DrawBorder(pGraphics, FWL_PART_CMB_Border, pTheme, pMatrix);
607 }
608 if (HasEdge()) {
609 DrawEdge(pGraphics, FWL_PART_CMB_Edge, pTheme, pMatrix);
610 }
611 if (!bIsDropDown) {
612 CFX_RectF rtTextBk(m_rtClient);
613 rtTextBk.width -= m_rtBtn.width;
614 CFWL_ThemeBackground param;
615 param.m_pWidget = m_pInterface;
616 param.m_iPart = FWL_PART_CMB_Background;
617 param.m_pGraphics = pGraphics;
618 if (pMatrix) {
619 param.m_matrix.Concat(*pMatrix);
620 }
621 param.m_rtPart = rtTextBk;
622 if (m_iCurSel >= 0) {
623 IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
624 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
625 ->m_pProperties->m_pDataProvider);
626 void* p = pData->GetItemData(m_pListBox.get(),
627 pData->GetItem(m_pListBox.get(), m_iCurSel));
628 if (p != NULL) {
629 param.m_pData = p;
630 }
631 }
632 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
633 param.m_dwStates = FWL_PARTSTATE_CMB_Disabled;
634 } else if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) &&
635 (m_iCurSel >= 0)) {
636 param.m_dwStates = FWL_PARTSTATE_CMB_Selected;
637 } else {
638 param.m_dwStates = FWL_PARTSTATE_CMB_Normal;
639 }
640 pTheme->DrawBackground(&param);
641 if (m_iCurSel >= 0) {
642 if (!m_pListBox)
643 return FWL_ERR_Indefinite;
644 CFX_WideString wsText;
645 IFWL_ComboBoxDP* pData =
646 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
647 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
648 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
649 ->GetItemText(hItem, wsText);
650 CFWL_ThemeText param;
651 param.m_pWidget = m_pInterface;
652 param.m_iPart = FWL_PART_CMB_Caption;
653 param.m_dwStates = m_iBtnState;
654 param.m_pGraphics = pGraphics;
655 param.m_matrix.Concat(*pMatrix);
656 param.m_rtPart = rtTextBk;
657 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)
658 ? FWL_PARTSTATE_CMB_Selected
659 : FWL_PARTSTATE_CMB_Normal;
660 param.m_wsText = wsText;
661 param.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
662 param.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
663 pTheme->DrawText(&param);
664 }
665 }
666 {
667 CFWL_ThemeBackground param;
668 param.m_pWidget = m_pInterface;
669 param.m_iPart = FWL_PART_CMB_DropDownButton;
670 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
671 ? FWL_PARTSTATE_CMB_Disabled
672 : m_iBtnState;
673 param.m_pGraphics = pGraphics;
674 param.m_matrix.Concat(*pMatrix);
675 param.m_rtPart = m_rtBtn;
676 pTheme->DrawBackground(&param);
677 }
678 return FWL_ERR_Succeeded;
679 }
680 FWL_ERR CFWL_ComboBoxImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
681 if (!pThemeProvider)
682 return FWL_ERR_Indefinite;
683 m_pProperties->m_pThemeProvider = pThemeProvider;
684 if (m_pListBox && pThemeProvider->IsValidWidget(m_pListBox.get())) {
685 m_pListBox->SetThemeProvider(pThemeProvider);
686 }
687 if (m_pEdit && pThemeProvider->IsValidWidget(m_pEdit.get())) {
688 m_pEdit->SetThemeProvider(pThemeProvider);
689 }
690 return FWL_ERR_Succeeded;
691 }
692 int32_t CFWL_ComboBoxImp::GetCurSel() {
693 return m_iCurSel;
694 }
695 FWL_ERR CFWL_ComboBoxImp::SetCurSel(int32_t iSel) {
696 int32_t iCount =
697 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->CountItems();
698 FX_BOOL bClearSel = iSel < 0 || iSel >= iCount;
699 FX_BOOL bDropDown = IsDropDownStyle();
700 if (bDropDown && m_pEdit) {
701 if (bClearSel) {
702 m_pEdit->SetText(CFX_WideString());
703 } else {
704 CFX_WideString wsText;
705 IFWL_ComboBoxDP* pData =
706 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
707 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iSel);
708 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
709 ->GetItemText(hItem, wsText);
710 m_pEdit->SetText(wsText);
711 }
712 m_pEdit->Update();
713 }
714 m_iCurSel = bClearSel ? -1 : iSel;
715 return FWL_ERR_Succeeded;
716 }
717 FWL_ERR CFWL_ComboBoxImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
718 FX_BOOL bIsDropDown = IsDropDownStyle();
719 if (bIsDropDown && m_pEdit) {
720 m_pEdit->SetStates(dwStates, bSet);
721 }
722 if (m_pListBox) {
723 m_pListBox->SetStates(dwStates, bSet);
724 }
725 return CFWL_WidgetImp::SetStates(dwStates, bSet);
726 }
727 FWL_ERR CFWL_ComboBoxImp::SetEditText(const CFX_WideString& wsText) {
728 if (!m_pEdit)
729 return FWL_ERR_Indefinite;
730 m_pEdit->SetText(wsText);
731 return m_pEdit->Update();
732 }
733 int32_t CFWL_ComboBoxImp::GetEditTextLength() const {
734 if (!m_pEdit)
735 return -1;
736 return m_pEdit->GetTextLength();
737 }
738 FWL_ERR CFWL_ComboBoxImp::GetEditText(CFX_WideString& wsText,
739 int32_t nStart,
740 int32_t nCount) const {
741 if (m_pEdit) {
742 return m_pEdit->GetText(wsText, nStart, nCount);
743 } else if (m_pListBox) {
744 IFWL_ComboBoxDP* pData =
745 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
746 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
747 return m_pListBox->GetItemText(hItem, wsText);
748 }
749 return FWL_ERR_Indefinite;
750 }
751 FWL_ERR CFWL_ComboBoxImp::SetEditSelRange(int32_t nStart, int32_t nCount) {
752 if (!m_pEdit)
753 return FWL_ERR_Indefinite;
754 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->ClearSelected();
755 m_pEdit->AddSelRange(nStart, nCount);
756 return FWL_ERR_Succeeded;
757 }
758 int32_t CFWL_ComboBoxImp::GetEditSelRange(int32_t nIndex, int32_t& nStart) {
759 if (!m_pEdit)
760 return -1;
761 return m_pEdit->GetSelRange(nIndex, nStart);
762 }
763 int32_t CFWL_ComboBoxImp::GetEditLimit() {
764 if (!m_pEdit)
765 return -1;
766 return m_pEdit->GetLimit();
767 }
768 FWL_ERR CFWL_ComboBoxImp::SetEditLimit(int32_t nLimit) {
769 if (!m_pEdit)
770 return FWL_ERR_Indefinite;
771 return m_pEdit->SetLimit(nLimit);
772 }
773 FWL_ERR CFWL_ComboBoxImp::EditDoClipboard(int32_t iCmd) {
774 if (!m_pEdit)
775 return FWL_ERR_Indefinite;
776 return m_pEdit->DoClipboard(iCmd);
777 }
778 FX_BOOL CFWL_ComboBoxImp::EditRedo(const CFX_ByteStringC& bsRecord) {
779 if (!m_pEdit)
780 return FALSE;
781 return m_pEdit->Redo(bsRecord);
782 }
783 FX_BOOL CFWL_ComboBoxImp::EditUndo(const CFX_ByteStringC& bsRecord) {
784 if (!m_pEdit)
785 return FALSE;
786 return m_pEdit->Undo(bsRecord);
787 }
788 IFWL_ListBox* CFWL_ComboBoxImp::GetListBoxt() {
789 return m_pListBox.get();
790 }
791 FX_BOOL CFWL_ComboBoxImp::AfterFocusShowDropList() {
792 if (!m_bNeedShowList) {
793 return FALSE;
794 }
795 if (m_pEdit) {
796 MatchEditText();
797 }
798 ShowDropList(TRUE);
799 m_bNeedShowList = FALSE;
800 return TRUE;
801 }
802 FX_ERR CFWL_ComboBoxImp::OpenDropDownList(FX_BOOL bActivate) {
803 ShowDropList(bActivate);
804 return FWL_ERR_Succeeded;
805 }
806 FX_BOOL CFWL_ComboBoxImp::EditCanUndo() {
807 return m_pEdit->CanUndo();
808 }
809 FX_BOOL CFWL_ComboBoxImp::EditCanRedo() {
810 return m_pEdit->CanRedo();
811 }
812 FX_BOOL CFWL_ComboBoxImp::EditUndo() {
813 return m_pEdit->Undo();
814 }
815 FX_BOOL CFWL_ComboBoxImp::EditRedo() {
816 return m_pEdit->Redo();
817 }
818 FX_BOOL CFWL_ComboBoxImp::EditCanCopy() {
819 return m_pEdit->CountSelRanges() > 0;
820 }
821 FX_BOOL CFWL_ComboBoxImp::EditCanCut() {
822 if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
823 return FALSE;
824 }
825 return m_pEdit->CountSelRanges() > 0;
826 }
827 FX_BOOL CFWL_ComboBoxImp::EditCanSelectAll() {
828 return m_pEdit->GetTextLength() > 0;
829 }
830 FX_BOOL CFWL_ComboBoxImp::EditCopy(CFX_WideString& wsCopy) {
831 return m_pEdit->Copy(wsCopy);
832 }
833 FX_BOOL CFWL_ComboBoxImp::EditCut(CFX_WideString& wsCut) {
834 return m_pEdit->Cut(wsCut);
835 }
836 FX_BOOL CFWL_ComboBoxImp::EditPaste(const CFX_WideString& wsPaste) {
837 return m_pEdit->Paste(wsPaste);
838 }
839 FX_BOOL CFWL_ComboBoxImp::EditSelectAll() {
840 return m_pEdit->AddSelRange(0) == FWL_ERR_Succeeded;
841 }
842 FX_BOOL CFWL_ComboBoxImp::EditDelete() {
843 return m_pEdit->ClearText() == FWL_ERR_Succeeded;
844 }
845 FX_BOOL CFWL_ComboBoxImp::EditDeSelect() {
846 return m_pEdit->ClearSelections() == FWL_ERR_Succeeded;
847 }
848 FWL_ERR CFWL_ComboBoxImp::GetBBox(CFX_RectF& rect) {
849 if (m_pWidgetMgr->IsFormDisabled()) {
850 return DisForm_GetBBox(rect);
851 }
852 rect = m_pProperties->m_rtWidget;
853 if (m_pListBox && IsDropListShowed()) {
854 CFX_RectF rtList;
855 m_pListBox->GetWidgetRect(rtList);
856 rtList.Offset(rect.left, rect.top);
857 rect.Union(rtList);
858 }
859 return FWL_ERR_Succeeded;
860 }
861 FWL_ERR CFWL_ComboBoxImp::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
862 FX_DWORD dwStylesExRemoved) {
863 if (m_pEdit != NULL) {
864 return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
865 } else {
866 return FWL_ERR_Parameter_Invalid;
867 }
868 }
869 FX_FLOAT CFWL_ComboBoxImp::GetListHeight() {
870 return static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider)
871 ->GetListHeight(m_pInterface);
872 }
873 void CFWL_ComboBoxImp::DrawStretchHandler(CFX_Graphics* pGraphics,
874 const CFX_Matrix* pMatrix) {
875 CFWL_ThemeBackground param;
876 param.m_pGraphics = pGraphics;
877 param.m_iPart = FWL_PART_CMB_StretcgHandler;
878 param.m_dwStates = FWL_PARTSTATE_CMB_Normal;
879 param.m_pWidget = m_pInterface;
880 if (pMatrix) {
881 param.m_matrix.Concat(*pMatrix);
882 }
883 param.m_rtPart = m_rtHandler;
884 m_pProperties->m_pThemeProvider->DrawBackground(&param);
885 }
886 void CFWL_ComboBoxImp::ShowDropList(FX_BOOL bActivate) {
887 if (m_pWidgetMgr->IsFormDisabled()) {
888 return DisForm_ShowDropList(bActivate);
889 }
890 FX_BOOL bDropList = IsDropListShowed();
891 if (bDropList == bActivate) {
892 return;
893 }
894 if (!m_pForm) {
895 InitProxyForm();
896 }
897 m_pListProxyDelegate->Reset();
898 if (bActivate) {
899 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
900 ->ChangeSelected(m_iCurSel);
901 ReSetListItemAlignment();
902 FX_DWORD dwStyleAdd = m_pProperties->m_dwStyleExes &
903 (FWL_STYLEEXT_CMB_Sort | FWL_STYLEEXT_CMB_OwnerDraw);
904 m_pListBox->ModifyStylesEx(dwStyleAdd, 0);
905 m_pListBox->GetWidgetRect(m_rtList, TRUE);
906 FX_FLOAT fHeight = GetListHeight();
907 if (fHeight > 0) {
908 if (m_rtList.height > GetListHeight()) {
909 m_rtList.height = GetListHeight();
910 m_pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll, 0);
911 }
912 }
913 CFX_RectF rtAnchor;
914 rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width,
915 m_pProperties->m_rtWidget.height);
916 FX_FLOAT fMinHeight = 0;
917 if (m_rtList.width < m_rtClient.width) {
918 m_rtList.width = m_rtClient.width;
919 }
920 m_rtProxy = m_rtList;
921 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) {
922 m_rtProxy.height += m_fComboFormHandler;
923 }
924 GetPopupPos(fMinHeight, m_rtProxy.height, rtAnchor, m_rtProxy);
925 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) {
926 FX_FLOAT fx = 0;
927 FX_FLOAT fy = m_rtClient.top + m_rtClient.height / 2;
928 TransformTo(NULL, fx, fy);
929 m_bUpFormHandler = fy > m_rtProxy.top;
930 if (m_bUpFormHandler) {
931 m_rtHandler.Set(0, 0, m_rtList.width, m_fComboFormHandler);
932 m_rtList.top = m_fComboFormHandler;
933 } else {
934 m_rtHandler.Set(0, m_rtList.height, m_rtList.width,
935 m_fComboFormHandler);
936 }
937 }
938 m_pForm->SetWidgetRect(m_rtProxy);
939 m_pForm->Update();
940 m_pListBox->SetWidgetRect(m_rtList);
941 m_pListBox->Update();
942 CFWL_EvtCmbPreDropDown ev;
943 ev.m_pSrcTarget = m_pInterface;
944 DispatchEvent(&ev);
945 m_fItemHeight =
946 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->m_fItemHeight;
947 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->SetFocus(TRUE);
948 m_pForm->DoModal();
949 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->SetFocus(FALSE);
950 } else {
951 m_pForm->EndDoModal();
952 CFWL_EvtCmbCloseUp ev;
953 ev.m_pSrcTarget = m_pInterface;
954 DispatchEvent(&ev);
955 m_bLButtonDown = FALSE;
956 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->m_bNotifyOwner =
957 TRUE;
958 SetFocus(TRUE);
959 }
960 }
961 FX_BOOL CFWL_ComboBoxImp::IsDropListShowed() {
962 return m_pForm && !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
963 }
964 FX_BOOL CFWL_ComboBoxImp::IsDropDownStyle() const {
965 return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown;
966 }
967 void CFWL_ComboBoxImp::MatchEditText() {
968 CFX_WideString wsText;
969 m_pEdit->GetText(wsText);
970 int32_t iMatch =
971 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->MatchItem(wsText);
972 if (iMatch != m_iCurSel) {
973 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
974 ->ChangeSelected(iMatch);
975 if (iMatch >= 0) {
976 SynchrEditText(iMatch);
977 }
978 } else if (iMatch >= 0) {
979 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetSelected();
980 }
981 m_iCurSel = iMatch;
982 }
983 void CFWL_ComboBoxImp::SynchrEditText(int32_t iListItem) {
984 CFX_WideString wsText;
985 IFWL_ComboBoxDP* pData =
986 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
987 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iListItem);
988 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
989 ->GetItemText(hItem, wsText);
990 m_pEdit->SetText(wsText);
991 m_pEdit->Update();
992 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetSelected();
993 }
994 void CFWL_ComboBoxImp::Layout() {
995 if (m_pWidgetMgr->IsFormDisabled()) {
996 return DisForm_Layout();
997 }
998 GetClientRect(m_rtClient);
999 FX_FLOAT* pFWidth =
1000 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1001 if (!pFWidth)
1002 return;
1003 FX_FLOAT fBtn = *pFWidth;
1004 m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn,
1005 m_rtClient.height);
1006 FX_BOOL bIsDropDown = IsDropDownStyle();
1007 if (bIsDropDown && m_pEdit) {
1008 CFX_RectF rtEdit;
1009 rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn,
1010 m_rtClient.height);
1011 m_pEdit->SetWidgetRect(rtEdit);
1012 if (m_iCurSel >= 0) {
1013 CFX_WideString wsText;
1014 IFWL_ComboBoxDP* pData =
1015 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1016 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
1017 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
1018 ->GetItemText(hItem, wsText);
1019 m_pEdit->LockUpdate();
1020 m_pEdit->SetText(wsText);
1021 m_pEdit->UnlockUpdate();
1022 }
1023 m_pEdit->Update();
1024 }
1025 }
1026 void CFWL_ComboBoxImp::ReSetTheme() {
1027 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
1028 if (!pTheme) {
1029 pTheme = GetAvailableTheme();
1030 m_pProperties->m_pThemeProvider = pTheme;
1031 }
1032 if (m_pListBox) {
1033 if (!m_pListBox->GetThemeProvider() &&
1034 pTheme->IsValidWidget(m_pListBox.get())) {
1035 m_pListBox->SetThemeProvider(pTheme);
1036 }
1037 }
1038 if (m_pEdit) {
1039 if (!m_pEdit->GetThemeProvider() && pTheme->IsValidWidget(m_pEdit.get())) {
1040 m_pEdit->SetThemeProvider(pTheme);
1041 }
1042 }
1043 }
1044 void CFWL_ComboBoxImp::ReSetEditAlignment() {
1045 if (!m_pEdit)
1046 return;
1047 FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
1048 FX_DWORD dwAdd = 0;
1049 switch (dwStylExes & FWL_STYLEEXT_CMB_EditHAlignMask) {
1050 case FWL_STYLEEXT_CMB_EditHCenter: {
1051 dwAdd |= FWL_STYLEEXT_EDT_HCenter;
1052 break;
1053 }
1054 case FWL_STYLEEXT_CMB_EditHFar: {
1055 dwAdd |= FWL_STYLEEXT_EDT_HFar;
1056 break;
1057 }
1058 default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; }
1059 }
1060 switch (dwStylExes & FWL_STYLEEXT_CMB_EditVAlignMask) {
1061 case FWL_STYLEEXT_CMB_EditVCenter: {
1062 dwAdd |= FWL_STYLEEXT_EDT_VCenter;
1063 break;
1064 }
1065 case FWL_STYLEEXT_CMB_EditVFar: {
1066 dwAdd |= FWL_STYLEEXT_EDT_VFar;
1067 break;
1068 }
1069 default: { dwAdd |= FWL_STYLEEXT_EDT_VNear; }
1070 }
1071 if (dwStylExes & FWL_STYLEEXT_CMB_EditJustified) {
1072 dwAdd |= FWL_STYLEEXT_EDT_Justified;
1073 }
1074 if (dwStylExes & FWL_STYLEEXT_CMB_EditDistributed) {
1075 dwAdd |= FWL_STYLEEXT_EDT_Distributed;
1076 }
1077 m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
1078 FWL_STYLEEXT_EDT_HAlignModeMask |
1079 FWL_STYLEEXT_EDT_VAlignMask);
1080 }
1081 void CFWL_ComboBoxImp::ReSetListItemAlignment() {
1082 if (!m_pListBox)
1083 return;
1084 FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
1085 FX_DWORD dwAdd = 0;
1086 switch (dwStylExes & FWL_STYLEEXT_CMB_ListItemAlignMask) {
1087 case FWL_STYLEEXT_CMB_ListItemCenterAlign: {
1088 dwAdd |= FWL_STYLEEXT_LTB_CenterAlign;
1089 }
1090 case FWL_STYLEEXT_CMB_ListItemRightAlign: {
1091 dwAdd |= FWL_STYLEEXT_LTB_RightAlign;
1092 }
1093 default: { dwAdd |= FWL_STYLEEXT_LTB_LeftAlign; }
1094 }
1095 m_pListBox->ModifyStylesEx(dwAdd, FWL_STYLEEXT_CMB_ListItemAlignMask);
1096 }
1097 void CFWL_ComboBoxImp::ProcessSelChanged(FX_BOOL bLButtonUp) {
1098 IFWL_ComboBoxDP* pDatas =
1099 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1100 m_iCurSel = pDatas->GetItemIndex(m_pInterface, m_pListBox->GetSelItem(0));
1101 FX_BOOL bDropDown = IsDropDownStyle();
1102 if (bDropDown) {
1103 IFWL_ComboBoxDP* pData =
1104 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1105 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
1106 if (hItem) {
1107 CFX_WideString wsText;
1108 pData->GetItemText(m_pInterface, hItem, wsText);
1109 if (m_pEdit) {
1110 m_pEdit->SetText(wsText);
1111 m_pEdit->Update();
1112 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetSelected();
1113 }
1114 CFWL_EvtCmbSelChanged ev;
1115 ev.bLButtonUp = bLButtonUp;
1116 ev.m_pSrcTarget = m_pInterface;
1117 ev.iArraySels.Add(m_iCurSel);
1118 DispatchEvent(&ev);
1119 }
1120 } else {
1121 Repaint(&m_rtClient);
1122 }
1123 }
1124 void CFWL_ComboBoxImp::InitProxyForm() {
1125 if (m_pForm)
1126 return;
1127 if (!m_pListBox)
1128 return;
1129 CFWL_WidgetImpProperties propForm;
1130 propForm.m_pOwner = m_pInterface;
1131 propForm.m_dwStyles = FWL_WGTSTYLE_Popup;
1132 propForm.m_dwStates = FWL_WGTSTATE_Invisible;
1133 CFX_WideString className;
1134 m_pForm = IFWL_Form::CreateFormProxy(propForm, &className, m_pListBox.get());
1135 m_pForm->Initialize();
1136 m_pProxy = static_cast<CFWL_FormProxyImp*>(m_pForm->GetImpl());
1137 m_pListBox->SetParent(m_pForm);
1138 m_pListProxyDelegate = new CFWL_ComboProxyImpDelegate(m_pForm, this);
1139 m_pProxy->SetDelegate(m_pListProxyDelegate);
1140 }
1141 FWL_ERR CFWL_ComboBoxImp::DisForm_Initialize() {
1142 if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
1143 return FWL_WGTSTATE_Invisible; // Ditto.
1144 m_pDelegate = new CFWL_ComboBoxImpDelegate(this);
1145 DisForm_InitComboList();
1146 DisForm_InitComboEdit();
1147 return FWL_ERR_Succeeded;
1148 }
1149 void CFWL_ComboBoxImp::DisForm_InitComboList() {
1150 if (m_pListBox) {
1151 return;
1152 }
1153 CFWL_WidgetImpProperties prop;
1154 prop.m_pParent = m_pInterface;
1155 prop.m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
1156 prop.m_dwStates = FWL_WGTSTATE_Invisible;
1157 prop.m_pDataProvider = m_pProperties->m_pDataProvider;
1158 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
1159 m_pListBox.reset(IFWL_ListBox::CreateComboList(prop, m_pInterface));
1160 m_pListBox->Initialize();
1161 }
1162 void CFWL_ComboBoxImp::DisForm_InitComboEdit() {
1163 if (m_pEdit) {
1164 return;
1165 }
1166 CFWL_WidgetImpProperties prop;
1167 prop.m_pParent = m_pInterface;
1168 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
1169 m_pEdit.reset(IFWL_Edit::CreateComboEdit(prop, m_pInterface));
1170 m_pEdit->Initialize();
1171 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetOuter(m_pInterface);
1172 }
1173 void CFWL_ComboBoxImp::DisForm_ShowDropList(FX_BOOL bActivate) {
1174 FX_BOOL bDropList = DisForm_IsDropListShowed();
1175 if (bDropList == bActivate) {
1176 return;
1177 }
1178 if (bActivate) {
1179 CFWL_EvtCmbPreDropDown preEvent;
1180 preEvent.m_pSrcTarget = m_pInterface;
1181 DispatchEvent(&preEvent);
1182 CFWL_ComboListImp* pComboList =
1183 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl());
1184 int32_t iItems = pComboList->CountItems();
1185 if (iItems < 1) {
1186 return;
1187 }
1188 ReSetListItemAlignment();
1189 pComboList->ChangeSelected(m_iCurSel);
1190 FX_FLOAT fItemHeight = pComboList->GetItemHeigt();
1191 FX_FLOAT fBorder = GetBorderSize();
1192 FX_FLOAT fPopupMin = 0.0f;
1193 if (iItems > 3) {
1194 fPopupMin = fItemHeight * 3 + fBorder * 2;
1195 }
1196 FX_FLOAT fPopupMax = fItemHeight * iItems + fBorder * 2;
1197 CFX_RectF rtList;
1198 rtList.left = m_rtClient.left;
1199 rtList.width = m_pProperties->m_rtWidget.width;
1200 rtList.top = 0;
1201 rtList.height = 0;
1202 GetPopupPos(fPopupMin, fPopupMax, m_pProperties->m_rtWidget, rtList);
1203 m_pListBox->SetWidgetRect(rtList);
1204 m_pListBox->Update();
1205 } else {
1206 SetFocus(TRUE);
1207 }
1208 m_pListBox->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
1209 if (bActivate) {
1210 CFWL_EvtCmbPostDropDown postEvent;
1211 postEvent.m_pSrcTarget = m_pInterface;
1212 DispatchEvent(&postEvent);
1213 }
1214 CFX_RectF rect;
1215 m_pListBox->GetWidgetRect(rect);
1216 rect.Inflate(2, 2);
1217 Repaint(&rect);
1218 }
1219 FX_BOOL CFWL_ComboBoxImp::DisForm_IsDropListShowed() {
1220 return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible);
1221 }
1222 FWL_ERR CFWL_ComboBoxImp::DisForm_ModifyStylesEx(FX_DWORD dwStylesExAdded,
1223 FX_DWORD dwStylesExRemoved) {
1224 if (!m_pEdit) {
1225 DisForm_InitComboEdit();
1226 }
1227 FX_BOOL bAddDropDown = dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown;
1228 FX_BOOL bDelDropDown = dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown;
1229 dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown;
1230 m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown;
1231 if (bAddDropDown) {
1232 m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly);
1233 } else if (bDelDropDown) {
1234 m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0);
1235 }
1236 return CFWL_WidgetImp::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
1237 }
1238 FWL_ERR CFWL_ComboBoxImp::DisForm_Update() {
1239 if (m_iLock) {
1240 return FWL_ERR_Indefinite;
1241 }
1242 if (m_pEdit) {
1243 ReSetEditAlignment();
1244 }
1245 ReSetTheme();
1246 Layout();
1247 return FWL_ERR_Succeeded;
1248 }
1249 FX_DWORD CFWL_ComboBoxImp::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) {
1250 CFX_RectF rect;
1251 rect.Set(0, 0, m_pProperties->m_rtWidget.width - m_rtBtn.width,
1252 m_pProperties->m_rtWidget.height);
1253 if (rect.Contains(fx, fy)) {
1254 return FWL_WGTHITTEST_Edit;
1255 }
1256 if (m_rtBtn.Contains(fx, fy)) {
1257 return FWL_WGTHITTEST_Client;
1258 }
1259 if (DisForm_IsDropListShowed()) {
1260 m_pListBox->GetWidgetRect(rect);
1261 if (rect.Contains(fx, fy)) {
1262 return FWL_WGTHITTEST_Client;
1263 }
1264 }
1265 return FWL_WGTHITTEST_Unknown;
1266 }
1267 FWL_ERR CFWL_ComboBoxImp::DisForm_DrawWidget(CFX_Graphics* pGraphics,
1268 const CFX_Matrix* pMatrix) {
1269 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
1270 CFX_Matrix mtOrg;
1271 mtOrg.Set(1, 0, 0, 1, 0, 0);
1272 if (pMatrix) {
1273 mtOrg = *pMatrix;
1274 }
1275 FX_BOOL bListShowed = m_pListBox && DisForm_IsDropListShowed();
1276 pGraphics->SaveGraphState();
1277 pGraphics->ConcatMatrix(&mtOrg);
1278 if (!m_rtBtn.IsEmpty(0.1f)) {
1279 CFWL_ThemeBackground param;
1280 param.m_pWidget = m_pInterface;
1281 param.m_iPart = FWL_PART_CMB_DropDownButton;
1282 param.m_dwStates = m_iBtnState;
1283 param.m_pGraphics = pGraphics;
1284 param.m_rtPart = m_rtBtn;
1285 pTheme->DrawBackground(&param);
1286 }
1287 pGraphics->RestoreGraphState();
1288 if (m_pEdit) {
1289 CFX_RectF rtEdit;
1290 m_pEdit->GetWidgetRect(rtEdit);
1291 CFX_Matrix mt;
1292 mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top);
1293 mt.Concat(mtOrg);
1294 m_pEdit->DrawWidget(pGraphics, &mt);
1295 }
1296 if (bListShowed) {
1297 CFX_RectF rtList;
1298 m_pListBox->GetWidgetRect(rtList);
1299 CFX_Matrix mt;
1300 mt.Set(1, 0, 0, 1, rtList.left, rtList.top);
1301 mt.Concat(mtOrg);
1302 m_pListBox->DrawWidget(pGraphics, &mt);
1303 }
1304 return FWL_ERR_Succeeded;
1305 }
1306 FWL_ERR CFWL_ComboBoxImp::DisForm_GetBBox(CFX_RectF& rect) {
1307 rect = m_pProperties->m_rtWidget;
1308 if (m_pListBox && DisForm_IsDropListShowed()) {
1309 CFX_RectF rtList;
1310 m_pListBox->GetWidgetRect(rtList);
1311 rtList.Offset(rect.left, rect.top);
1312 rect.Union(rtList);
1313 }
1314 return FWL_ERR_Succeeded;
1315 }
1316 void CFWL_ComboBoxImp::DisForm_Layout() {
1317 GetClientRect(m_rtClient);
1318 m_rtContent = m_rtClient;
1319 FX_FLOAT* pFWidth =
1320 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1321 if (!pFWidth)
1322 return;
1323 FX_FLOAT borderWidth = 0;
1324 { borderWidth = FWL_PART_CMB_Border; }
1325 FX_FLOAT fBtn = *pFWidth;
1326 if (!(GetStylesEx() & FWL_STYLEEXT_CMB_ReadOnly)) {
1327 m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth,
1328 fBtn - borderWidth, m_rtClient.height - 2 * borderWidth);
1329 }
1330 CFX_RectF* pUIMargin =
1331 static_cast<CFX_RectF*>(GetThemeCapacity(FWL_WGTCAPACITY_UIMargin));
1332 if (pUIMargin) {
1333 m_rtContent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
1334 pUIMargin->height);
1335 }
1336 FX_BOOL bIsDropDown = IsDropDownStyle();
1337 if (bIsDropDown && m_pEdit) {
1338 CFX_RectF rtEdit;
1339 rtEdit.Set(m_rtContent.left, m_rtContent.top, m_rtContent.width - fBtn,
1340 m_rtContent.height);
1341 m_pEdit->SetWidgetRect(rtEdit);
1342 if (m_iCurSel >= 0) {
1343 CFX_WideString wsText;
1344 IFWL_ComboBoxDP* pData =
1345 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1346 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
1347 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
1348 ->GetItemText(hItem, wsText);
1349 m_pEdit->LockUpdate();
1350 m_pEdit->SetText(wsText);
1351 m_pEdit->UnlockUpdate();
1352 }
1353 m_pEdit->Update();
1354 }
1355 }
1356 CFWL_ComboBoxImpDelegate::CFWL_ComboBoxImpDelegate(CFWL_ComboBoxImp* pOwner)
1357 : m_pOwner(pOwner) {}
1358 int32_t CFWL_ComboBoxImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
1359 if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
1360 return DisForm_OnProcessMessage(pMessage);
1361 }
1362 if (!pMessage)
1363 return 0;
1364 FX_DWORD dwMsgCode = pMessage->GetClassID();
1365 FX_BOOL iRet = 1;
1366 switch (dwMsgCode) {
1367 case FWL_MSGHASH_SetFocus:
1368 case FWL_MSGHASH_KillFocus: {
1369 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
1370 break;
1371 }
1372 case FWL_MSGHASH_Mouse: {
1373 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
1374 FX_DWORD dwCmd = pMsg->m_dwCmd;
1375 switch (dwCmd) {
1376 case FWL_MSGMOUSECMD_LButtonDown: {
1377 OnLButtonDown(pMsg);
1378 break;
1379 }
1380 case FWL_MSGMOUSECMD_LButtonUp: {
1381 OnLButtonUp(pMsg);
1382 break;
1383 }
1384 case FWL_MSGMOUSECMD_MouseMove: {
1385 OnMouseMove(pMsg);
1386 break;
1387 }
1388 case FWL_MSGMOUSECMD_MouseLeave: {
1389 OnMouseLeave(pMsg);
1390 break;
1391 }
1392 default: {}
1393 }
1394 break;
1395 }
1396 case FWL_MSGHASH_Key: {
1397 OnKey(static_cast<CFWL_MsgKey*>(pMessage));
1398 break;
1399 }
1400 default: { iRet = 0; }
1401 }
1402 CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
1403 return iRet;
1404 }
1405 FWL_ERR CFWL_ComboBoxImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
1406 FX_DWORD dwFlag = pEvent->GetClassID();
1407 if (dwFlag == FWL_EVTHASH_LTB_DrawItem) {
1408 CFWL_EvtLtbDrawItem* pDrawItemEvent =
1409 static_cast<CFWL_EvtLtbDrawItem*>(pEvent);
1410 CFWL_EvtCmbDrawItem pTemp;
1411 pTemp.m_pSrcTarget = m_pOwner->m_pInterface;
1412 pTemp.m_pGraphics = pDrawItemEvent->m_pGraphics;
1413 pTemp.m_index = pDrawItemEvent->m_index;
1414 pTemp.m_rtItem = pDrawItemEvent->m_rect;
1415 m_pOwner->DispatchEvent(&pTemp);
1416 } else if (dwFlag == FWL_EVTHASH_Scroll) {
1417 CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
1418 CFWL_EvtScroll pScrollEv;
1419 pScrollEv.m_pSrcTarget = m_pOwner->m_pInterface;
1420 pScrollEv.m_iScrollCode = pScrollEvent->m_iScrollCode;
1421 pScrollEv.m_fPos = pScrollEvent->m_fPos;
1422 m_pOwner->DispatchEvent(&pScrollEv);
1423 } else if (dwFlag == FWL_EVTHASH_EDT_TextChanged) {
1424 CFWL_EvtEdtTextChanged* pTextChangedEvent =
1425 static_cast<CFWL_EvtEdtTextChanged*>(pEvent);
1426 CFWL_EvtCmbEditChanged pTemp;
1427 pTemp.m_pSrcTarget = m_pOwner->m_pInterface;
1428 pTemp.wsInsert = pTextChangedEvent->wsInsert;
1429 pTemp.wsDelete = pTextChangedEvent->wsDelete;
1430 pTemp.nChangeType = pTextChangedEvent->nChangeType;
1431 m_pOwner->DispatchEvent(&pTemp);
1432 }
1433 return FWL_ERR_Succeeded;
1434 }
1435 FWL_ERR CFWL_ComboBoxImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1436 const CFX_Matrix* pMatrix) {
1437 return m_pOwner->DrawWidget(pGraphics, pMatrix);
1438 }
1439 void CFWL_ComboBoxImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
1440 FX_BOOL bSet) {
1441 IFWL_Target* pDstTarget = pMsg->m_pDstTarget;
1442 IFWL_Target* pSrcTarget = pMsg->m_pSrcTarget;
1443 FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
1444 if (bSet) {
1445 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
1446 if (bDropDown && pSrcTarget != m_pOwner->m_pListBox.get()) {
1447 if (!m_pOwner->m_pEdit)
1448 return;
1449 static_cast<CFWL_ComboEditImp*>(m_pOwner->m_pEdit->GetImpl())
1450 ->SetSelected();
1451 } else {
1452 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1453 }
1454 } else {
1455 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
1456 if (bDropDown && pDstTarget != m_pOwner->m_pListBox.get()) {
1457 if (!m_pOwner->m_pEdit)
1458 return;
1459 static_cast<CFWL_ComboEditImp*>(m_pOwner->m_pEdit->GetImpl())
1460 ->FlagFocus(FALSE);
1461 static_cast<CFWL_ComboEditImp*>(m_pOwner->m_pEdit->GetImpl())
1462 ->ClearSelected();
1463 } else {
1464 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1465 }
1466 }
1467 }
1468 void CFWL_ComboBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
1469 if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
1470 return;
1471 }
1472 FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
1473 CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
1474 FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
1475 if (bClickBtn) {
1476 if (bDropDown && m_pOwner->m_pEdit) {
1477 m_pOwner->MatchEditText();
1478 }
1479 m_pOwner->m_bLButtonDown = TRUE;
1480 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Pressed;
1481 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1482 m_pOwner->ShowDropList(TRUE);
1483 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1484 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1485 }
1486 }
1487 void CFWL_ComboBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1488 m_pOwner->m_bLButtonDown = FALSE;
1489 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
1490 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Hovered;
1491 } else {
1492 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1493 }
1494 m_pOwner->Repaint(&m_pOwner->m_rtBtn);
1495 }
1496 void CFWL_ComboBoxImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
1497 int32_t iOldState = m_pOwner->m_iBtnState;
1498 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
1499 m_pOwner->m_iBtnState = m_pOwner->m_bLButtonDown
1500 ? FWL_PARTSTATE_CMB_Pressed
1501 : FWL_PARTSTATE_CMB_Hovered;
1502 } else {
1503 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1504 }
1505 if ((iOldState != m_pOwner->m_iBtnState) &&
1506 !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ==
1507 FWL_WGTSTATE_Disabled)) {
1508 m_pOwner->Repaint(&m_pOwner->m_rtBtn);
1509 }
1510 }
1511 void CFWL_ComboBoxImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
1512 if (!m_pOwner->IsDropListShowed() &&
1513 !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ==
1514 FWL_WGTSTATE_Disabled)) {
1515 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1516 m_pOwner->Repaint(&m_pOwner->m_rtBtn);
1517 }
1518 }
1519 void CFWL_ComboBoxImpDelegate::OnKey(CFWL_MsgKey* pMsg) {
1520 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
1521 if (dwKeyCode == FWL_VKEY_Tab) {
1522 m_pOwner->DispatchKeyEvent(pMsg);
1523 return;
1524 }
1525 if (pMsg->m_pDstTarget == m_pOwner->m_pInterface)
1526 DoSubCtrlKey(pMsg);
1527 }
1528 void CFWL_ComboBoxImpDelegate::DoSubCtrlKey(CFWL_MsgKey* pMsg) {
1529 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
1530 const bool bUp = dwKeyCode == FWL_VKEY_Up;
1531 const bool bDown = dwKeyCode == FWL_VKEY_Down;
1532 if (bUp || bDown) {
1533 int32_t iCount =
1534 static_cast<CFWL_ComboListImp*>(m_pOwner->m_pListBox->GetImpl())
1535 ->CountItems();
1536 if (iCount < 1) {
1537 return;
1538 }
1539 FX_BOOL bMatchEqual = FALSE;
1540 int32_t iCurSel = m_pOwner->m_iCurSel;
1541 FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
1542 if (bDropDown && m_pOwner->m_pEdit) {
1543 CFX_WideString wsText;
1544 m_pOwner->m_pEdit->GetText(wsText);
1545 iCurSel = static_cast<CFWL_ComboListImp*>(m_pOwner->m_pListBox->GetImpl())
1546 ->MatchItem(wsText);
1547 if (iCurSel >= 0) {
1548 CFX_WideString wsTemp;
1549 IFWL_ComboBoxDP* pData = static_cast<IFWL_ComboBoxDP*>(
1550 m_pOwner->m_pProperties->m_pDataProvider);
1551 FWL_HLISTITEM hItem = pData->GetItem(m_pOwner->m_pInterface, iCurSel);
1552 static_cast<CFWL_ComboListImp*>(m_pOwner->m_pListBox->GetImpl())
1553 ->GetItemText(hItem, wsTemp);
1554 bMatchEqual = wsText.Equal(wsTemp);
1555 }
1556 }
1557 if (iCurSel < 0) {
1558 iCurSel = 0;
1559 } else if (!bDropDown || bMatchEqual) {
1560 if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) {
1561 return;
1562 }
1563 if (bUp) {
1564 iCurSel--;
1565 } else {
1566 iCurSel++;
1567 }
1568 }
1569 m_pOwner->m_iCurSel = iCurSel;
1570 if (bDropDown && m_pOwner->m_pEdit) {
1571 m_pOwner->SynchrEditText(m_pOwner->m_iCurSel);
1572 } else {
1573 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1574 }
1575 return;
1576 }
1577 FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
1578 if (bDropDown) {
1579 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
1580 pDelegate->OnProcessMessage(pMsg);
1581 }
1582 }
1583 int32_t CFWL_ComboBoxImpDelegate::DisForm_OnProcessMessage(
1584 CFWL_Message* pMessage) {
1585 if (!pMessage)
1586 return 0;
1587 FX_DWORD dwMsgCode = pMessage->GetClassID();
1588 FX_BOOL backDefault = TRUE;
1589 switch (dwMsgCode) {
1590 case FWL_MSGHASH_SetFocus:
1591 case FWL_MSGHASH_KillFocus: {
1592 backDefault = FALSE;
1593 DisForm_OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
1594 break;
1595 }
1596 case FWL_MSGHASH_Mouse: {
1597 backDefault = FALSE;
1598 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
1599 FX_DWORD dwCmd = pMsg->m_dwCmd;
1600 switch (dwCmd) {
1601 case FWL_MSGMOUSECMD_LButtonDown: {
1602 DisForm_OnLButtonDown(pMsg);
1603 break;
1604 }
1605 case FWL_MSGMOUSECMD_LButtonUp: {
1606 OnLButtonUp(pMsg);
1607 break;
1608 }
1609 default: {}
1610 }
1611 break;
1612 }
1613 case FWL_MSGHASH_Key: {
1614 backDefault = FALSE;
1615 CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
1616 if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyUp) {
1617 break;
1618 }
1619 if (m_pOwner->DisForm_IsDropListShowed() &&
1620 pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
1621 FX_DWORD dwKeyCode = pKey->m_dwKeyCode;
1622 FX_BOOL bListKey =
1623 dwKeyCode == FWL_VKEY_Up || dwKeyCode == FWL_VKEY_Down ||
1624 dwKeyCode == FWL_VKEY_Return || dwKeyCode == FWL_VKEY_Escape;
1625 if (bListKey) {
1626 IFWL_WidgetDelegate* pDelegate =
1627 m_pOwner->m_pListBox->SetDelegate(NULL);
1628 pDelegate->OnProcessMessage(pMessage);
1629 break;
1630 }
1631 }
1632 DisForm_OnKey(pKey);
1633 break;
1634 }
1635 default: {}
1636 }
1637 if (!backDefault) {
1638 return 1;
1639 }
1640 return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
1641 }
1642 void CFWL_ComboBoxImpDelegate::DisForm_OnLButtonDown(CFWL_MsgMouse* pMsg) {
1643 FX_BOOL bDropDown = m_pOwner->DisForm_IsDropListShowed();
1644 CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
1645 FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
1646 if (bClickBtn) {
1647 if (m_pOwner->DisForm_IsDropListShowed()) {
1648 m_pOwner->DisForm_ShowDropList(FALSE);
1649 return;
1650 }
1651 {
1652 if (m_pOwner->m_pEdit) {
1653 m_pOwner->MatchEditText();
1654 }
1655 m_pOwner->DisForm_ShowDropList(TRUE);
1656 }
1657 }
1658 }
1659 void CFWL_ComboBoxImpDelegate::DisForm_OnFocusChanged(CFWL_Message* pMsg,
1660 FX_BOOL bSet) {
1661 if (bSet) {
1662 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
1663 if ((m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) == 0) {
1664 CFWL_MsgSetFocus msg;
1665 msg.m_pDstTarget = m_pOwner->m_pEdit.get();
1666 msg.m_pSrcTarget = NULL;
1667 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
1668 pDelegate->OnProcessMessage(&msg);
1669 }
1670 } else {
1671 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
1672 m_pOwner->DisForm_ShowDropList(FALSE);
1673 CFWL_MsgKillFocus msg;
1674 msg.m_pDstTarget = NULL;
1675 msg.m_pSrcTarget = m_pOwner->m_pEdit.get();
1676 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
1677 pDelegate->OnProcessMessage(&msg);
1678 }
1679 }
1680 void CFWL_ComboBoxImpDelegate::DisForm_OnKey(CFWL_MsgKey* pMsg) {
1681 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
1682 const bool bUp = dwKeyCode == FWL_VKEY_Up;
1683 const bool bDown = dwKeyCode == FWL_VKEY_Down;
1684 if (bUp || bDown) {
1685 CFWL_ComboListImp* pComboList =
1686 static_cast<CFWL_ComboListImp*>(m_pOwner->m_pListBox->GetImpl());
1687 int32_t iCount = pComboList->CountItems();
1688 if (iCount < 1) {
1689 return;
1690 }
1691 FX_BOOL bMatchEqual = FALSE;
1692 int32_t iCurSel = m_pOwner->m_iCurSel;
1693 if (m_pOwner->m_pEdit) {
1694 CFX_WideString wsText;
1695 m_pOwner->m_pEdit->GetText(wsText);
1696 iCurSel = pComboList->MatchItem(wsText);
1697 if (iCurSel >= 0) {
1698 CFX_WideString wsTemp;
1699 FWL_HLISTITEM item = m_pOwner->m_pListBox->GetSelItem(iCurSel);
1700 m_pOwner->m_pListBox->GetItemText(item, wsTemp);
1701 bMatchEqual = wsText.Equal(wsTemp);
1702 }
1703 }
1704 if (iCurSel < 0) {
1705 iCurSel = 0;
1706 } else if (bMatchEqual) {
1707 if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) {
1708 return;
1709 }
1710 if (bUp) {
1711 iCurSel--;
1712 } else {
1713 iCurSel++;
1714 }
1715 }
1716 m_pOwner->m_iCurSel = iCurSel;
1717 m_pOwner->SynchrEditText(m_pOwner->m_iCurSel);
1718 return;
1719 }
1720 if (m_pOwner->m_pEdit) {
1721 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
1722 pDelegate->OnProcessMessage(pMsg);
1723 }
1724 }
1725 CFWL_ComboProxyImpDelegate::CFWL_ComboProxyImpDelegate(
1726 IFWL_Form* pForm,
1727 CFWL_ComboBoxImp* pComboBox)
1728 : m_bLButtonDown(FALSE),
1729 m_bLButtonUpSelf(FALSE),
1730 m_fStartPos(0),
1731 m_pForm(pForm),
1732 m_pComboBox(pComboBox) {}
1733 int32_t CFWL_ComboProxyImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
1734 if (!pMessage)
1735 return 0;
1736 FX_DWORD dwMsgCode = pMessage->GetClassID();
1737 if (dwMsgCode == FWL_MSGHASH_Mouse) {
1738 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
1739 FX_DWORD dwCmd = pMsg->m_dwCmd;
1740 switch (dwCmd) {
1741 case FWL_MSGMOUSECMD_LButtonDown: {
1742 OnLButtonDown(pMsg);
1743 break;
1744 }
1745 case FWL_MSGMOUSECMD_LButtonUp: {
1746 OnLButtonUp(pMsg);
1747 break;
1748 }
1749 case FWL_MSGMOUSECMD_MouseMove: {
1750 OnMouseMove(pMsg);
1751 break;
1752 }
1753 default: {}
1754 }
1755 }
1756 if (dwMsgCode == FWL_MSGHASH_Deactivate) {
1757 OnDeactive(static_cast<CFWL_MsgDeactivate*>(pMessage));
1758 }
1759 if (dwMsgCode == FWL_MSGHASH_KillFocus || dwMsgCode == FWL_MSGHASH_SetFocus) {
1760 OnFocusChanged(static_cast<CFWL_MsgKillFocus*>(pMessage),
1761 dwMsgCode == FWL_MSGHASH_SetFocus);
1762 }
1763 return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
1764 }
1765 FWL_ERR CFWL_ComboProxyImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1766 const CFX_Matrix* pMatrix) {
1767 m_pComboBox->DrawStretchHandler(pGraphics, pMatrix);
1768 return FWL_ERR_Succeeded;
1769 }
1770 void CFWL_ComboProxyImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
1771 IFWL_NoteThread* pThread = m_pForm->GetOwnerThread();
1772 if (!pThread)
1773 return;
1774 CFWL_NoteDriver* pDriver =
1775 static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
1776 CFX_RectF rtWidget;
1777 m_pForm->GetWidgetRect(rtWidget);
1778 rtWidget.left = rtWidget.top = 0;
1779 if (rtWidget.Contains(pMsg->m_fx, pMsg->m_fy)) {
1780 m_bLButtonDown = TRUE;
1781 pDriver->SetGrab(m_pForm, TRUE);
1782 } else {
1783 m_bLButtonDown = FALSE;
1784 pDriver->SetGrab(m_pForm, FALSE);
1785 m_pComboBox->ShowDropList(FALSE);
1786 }
1787 }
1788 void CFWL_ComboProxyImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1789 m_bLButtonDown = FALSE;
1790 IFWL_NoteThread* pThread = m_pForm->GetOwnerThread();
1791 if (!pThread)
1792 return;
1793 CFWL_NoteDriver* pDriver =
1794 static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
1795 pDriver->SetGrab(m_pForm, FALSE);
1796 if (m_bLButtonUpSelf) {
1797 CFX_RectF rect;
1798 m_pForm->GetWidgetRect(rect);
1799 rect.left = rect.top = 0;
1800 if (!rect.Contains(pMsg->m_fx, pMsg->m_fy) &&
1801 m_pComboBox->IsDropListShowed()) {
1802 m_pComboBox->ShowDropList(FALSE);
1803 }
1804 } else {
1805 m_bLButtonUpSelf = TRUE;
1806 }
1807 }
1808 void CFWL_ComboProxyImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {}
1809 void CFWL_ComboProxyImpDelegate::OnDeactive(CFWL_MsgDeactivate* pMsg) {
1810 m_pComboBox->ShowDropList(FALSE);
1811 }
1812 void CFWL_ComboProxyImpDelegate::OnFocusChanged(CFWL_MsgKillFocus* pMsg,
1813 FX_BOOL bSet) {
1814 if (!bSet) {
1815 if (pMsg->m_pSetFocus == NULL) {
1816 m_pComboBox->ShowDropList(FALSE);
1817 }
1818 }
1819 }
OLDNEW
« no previous file with comments | « xfa/src/fwl/basewidget/fwl_comboboximp.h ('k') | xfa/src/fwl/basewidget/fwl_datetimepickerimp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698