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

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

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

Powered by Google App Engine
This is Rietveld 408576698