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/foxitlib.h"
8 #include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
9 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
10 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
13 #include "xfa/src/fwl/src/core/include/fwl_panelimp.h"
14 #include "xfa/src/fwl/src/core/include/fwl_formimp.h"
15 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
16 #include "xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h"
17 #include "xfa/src/fwl/src/basewidget/include/fwl_editimp.h"
18 #include "xfa/src/fwl/src/basewidget/include/fwl_listboximp.h"
19 #include "xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h"
20 #include "xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h"
21
22 // static
Create(const CFWL_WidgetImpProperties & properties)23 IFWL_ComboBox* IFWL_ComboBox::Create(
24 const CFWL_WidgetImpProperties& properties) {
25 IFWL_ComboBox* pComboBox = new IFWL_ComboBox;
26 CFWL_ComboBoxImp* pComboBoxImpl = new CFWL_ComboBoxImp(properties, nullptr);
27 pComboBox->SetImpl(pComboBoxImpl);
28 pComboBoxImpl->SetInterface(pComboBox);
29 return pComboBox;
30 }
IFWL_ComboBox()31 IFWL_ComboBox::IFWL_ComboBox() {}
GetCurSel()32 int32_t IFWL_ComboBox::GetCurSel() {
33 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetCurSel();
34 }
SetCurSel(int32_t iSel)35 FWL_ERR IFWL_ComboBox::SetCurSel(int32_t iSel) {
36 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->SetCurSel(iSel);
37 }
SetEditText(const CFX_WideString & wsText)38 FWL_ERR IFWL_ComboBox::SetEditText(const CFX_WideString& wsText) {
39 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->SetEditText(wsText);
40 }
GetEditTextLength() const41 int32_t IFWL_ComboBox::GetEditTextLength() const {
42 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetEditTextLength();
43 }
GetEditText(CFX_WideString & wsText,int32_t nStart,int32_t nCount) const44 FWL_ERR IFWL_ComboBox::GetEditText(CFX_WideString& wsText,
45 int32_t nStart,
46 int32_t nCount) const {
47 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
48 ->GetEditText(wsText, nStart, nCount);
49 }
SetEditSelRange(int32_t nStart,int32_t nCount)50 FWL_ERR IFWL_ComboBox::SetEditSelRange(int32_t nStart, int32_t nCount) {
51 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
52 ->SetEditSelRange(nStart, nCount);
53 }
GetEditSelRange(int32_t nIndex,int32_t & nStart)54 int32_t IFWL_ComboBox::GetEditSelRange(int32_t nIndex, int32_t& nStart) {
55 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
56 ->GetEditSelRange(nIndex, nStart);
57 }
GetEditLimit()58 int32_t IFWL_ComboBox::GetEditLimit() {
59 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetEditLimit();
60 }
SetEditLimit(int32_t nLimit)61 FWL_ERR IFWL_ComboBox::SetEditLimit(int32_t nLimit) {
62 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->SetEditLimit(nLimit);
63 }
EditDoClipboard(int32_t iCmd)64 FWL_ERR IFWL_ComboBox::EditDoClipboard(int32_t iCmd) {
65 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditDoClipboard(iCmd);
66 }
EditRedo(const CFX_ByteStringC & bsRecord)67 FX_BOOL IFWL_ComboBox::EditRedo(const CFX_ByteStringC& bsRecord) {
68 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditRedo(bsRecord);
69 }
EditUndo(const CFX_ByteStringC & bsRecord)70 FX_BOOL IFWL_ComboBox::EditUndo(const CFX_ByteStringC& bsRecord) {
71 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditUndo(bsRecord);
72 }
GetListBoxt()73 IFWL_ListBox* IFWL_ComboBox::GetListBoxt() {
74 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetListBoxt();
75 }
AfterFocusShowDropList()76 FX_BOOL IFWL_ComboBox::AfterFocusShowDropList() {
77 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->AfterFocusShowDropList();
78 }
OpenDropDownList(FX_BOOL bActivate)79 FX_ERR IFWL_ComboBox::OpenDropDownList(FX_BOOL bActivate) {
80 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->OpenDropDownList(bActivate);
81 }
EditCanUndo()82 FX_BOOL IFWL_ComboBox::EditCanUndo() {
83 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanUndo();
84 }
EditCanRedo()85 FX_BOOL IFWL_ComboBox::EditCanRedo() {
86 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanRedo();
87 }
EditUndo()88 FX_BOOL IFWL_ComboBox::EditUndo() {
89 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditUndo();
90 }
EditRedo()91 FX_BOOL IFWL_ComboBox::EditRedo() {
92 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditRedo();
93 }
EditCanCopy()94 FX_BOOL IFWL_ComboBox::EditCanCopy() {
95 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanCopy();
96 }
EditCanCut()97 FX_BOOL IFWL_ComboBox::EditCanCut() {
98 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanCut();
99 }
EditCanSelectAll()100 FX_BOOL IFWL_ComboBox::EditCanSelectAll() {
101 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCanSelectAll();
102 }
EditCopy(CFX_WideString & wsCopy)103 FX_BOOL IFWL_ComboBox::EditCopy(CFX_WideString& wsCopy) {
104 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCopy(wsCopy);
105 }
EditCut(CFX_WideString & wsCut)106 FX_BOOL IFWL_ComboBox::EditCut(CFX_WideString& wsCut) {
107 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditCut(wsCut);
108 }
EditPaste(const CFX_WideString & wsPaste)109 FX_BOOL IFWL_ComboBox::EditPaste(const CFX_WideString& wsPaste) {
110 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditPaste(wsPaste);
111 }
EditSelectAll()112 FX_BOOL IFWL_ComboBox::EditSelectAll() {
113 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditSelectAll();
114 }
EditDelete()115 FX_BOOL IFWL_ComboBox::EditDelete() {
116 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditDelete();
117 }
EditDeSelect()118 FX_BOOL IFWL_ComboBox::EditDeSelect() {
119 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->EditDeSelect();
120 }
GetBBox(CFX_RectF & rect)121 FWL_ERR IFWL_ComboBox::GetBBox(CFX_RectF& rect) {
122 return static_cast<CFWL_ComboBoxImp*>(GetImpl())->GetBBox(rect);
123 }
EditModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)124 FWL_ERR IFWL_ComboBox::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
125 FX_DWORD dwStylesExRemoved) {
126 return static_cast<CFWL_ComboBoxImp*>(GetImpl())
127 ->EditModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
128 }
129
CFWL_ComboEditImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)130 CFWL_ComboEditImp::CFWL_ComboEditImp(const CFWL_WidgetImpProperties& properties,
131 IFWL_Widget* pOuter)
132 : CFWL_EditImp(properties, pOuter) {
133 m_pOuter = static_cast<CFWL_ComboBoxImp*>(pOuter->GetImpl());
134 }
135
CFWL_ComboEditImpDelegate(CFWL_ComboEditImp * pOwner)136 CFWL_ComboEditImpDelegate::CFWL_ComboEditImpDelegate(CFWL_ComboEditImp* pOwner)
137 : CFWL_EditImpDelegate(pOwner), m_pOwner(pOwner) {
138 }
OnProcessMessage(CFWL_Message * pMessage)139 int32_t CFWL_ComboEditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
140 if (!pMessage)
141 return 0;
142 FX_DWORD dwMsgCode = pMessage->GetClassID();
143 FX_BOOL backDefault = TRUE;
144 switch (dwMsgCode) {
145 case FWL_MSGHASH_SetFocus:
146 case FWL_MSGHASH_KillFocus: {
147 if (dwMsgCode == FWL_MSGHASH_SetFocus) {
148 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
149 } else {
150 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
151 }
152 backDefault = FALSE;
153 break;
154 }
155 case FWL_MSGHASH_Mouse: {
156 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
157 if ((pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) &&
158 ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)) {
159 m_pOwner->SetSelected();
160 m_pOwner->SetComboBoxFocus(TRUE);
161 }
162 break;
163 }
164 default: {}
165 }
166 if (!backDefault) {
167 return 1;
168 }
169 return CFWL_EditImpDelegate::OnProcessMessage(pMessage);
170 }
ClearSelected()171 void CFWL_ComboEditImp::ClearSelected() {
172 ClearSelections();
173 Repaint(&m_rtClient);
174 }
SetSelected()175 void CFWL_ComboEditImp::SetSelected() {
176 FlagFocus(TRUE);
177 EndCaret();
178 AddSelRange(0);
179 }
EndCaret()180 void CFWL_ComboEditImp::EndCaret() {
181 m_pEdtEngine->MoveCaretPos(MC_End);
182 }
FlagFocus(FX_BOOL bSet)183 void CFWL_ComboEditImp::FlagFocus(FX_BOOL bSet) {
184 if (bSet) {
185 m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
186 } else {
187 m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
188 ShowCaret(FALSE);
189 }
190 };
SetComboBoxFocus(FX_BOOL bSet)191 void CFWL_ComboEditImp::SetComboBoxFocus(FX_BOOL bSet) {
192 m_pOuter->SetFocus(bSet);
193 }
CFWL_ComboListImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)194 CFWL_ComboListImp::CFWL_ComboListImp(const CFWL_WidgetImpProperties& properties,
195 IFWL_Widget* pOuter)
196 : CFWL_ListBoxImp(properties, pOuter), m_bNotifyOwner(TRUE) {
197 FXSYS_assert(pOuter != NULL);
198 }
Initialize()199 FWL_ERR CFWL_ComboListImp::Initialize() {
200 if (CFWL_ListBoxImp::Initialize() != FWL_ERR_Succeeded)
201 return FWL_ERR_Indefinite;
202 delete m_pDelegate;
203 m_pDelegate = new CFWL_ComboListImpDelegate(this);
204 return FWL_ERR_Succeeded;
205 }
Finalize()206 FWL_ERR CFWL_ComboListImp::Finalize() {
207 delete m_pDelegate;
208 m_pDelegate = nullptr;
209 return CFWL_ListBoxImp::Finalize();
210 }
MatchItem(const CFX_WideString & wsMatch)211 int32_t CFWL_ComboListImp::MatchItem(const CFX_WideString& wsMatch) {
212 if (wsMatch.IsEmpty()) {
213 return -1;
214 }
215 if (!m_pProperties->m_pDataProvider)
216 return -1;
217 IFWL_ListBoxDP* pData =
218 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
219 int32_t iCount = pData->CountItems(m_pInterface);
220 for (int32_t i = 0; i < iCount; i++) {
221 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
222 CFX_WideString wsText;
223 pData->GetItemText(m_pInterface, hItem, wsText);
224 FX_STRSIZE pos = wsText.Find(wsMatch.c_str());
225 if (!pos) {
226 return i;
227 }
228 }
229 return -1;
230 }
ChangeSelected(int32_t iSel)231 void CFWL_ComboListImp::ChangeSelected(int32_t iSel) {
232 if (!m_pProperties->m_pDataProvider)
233 return;
234 IFWL_ListBoxDP* pData =
235 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
236 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iSel);
237 CFX_RectF rtInvalidate;
238 rtInvalidate.Reset();
239 FWL_HLISTITEM hOld = GetSelItem(0);
240 int32_t iOld = pData->GetItemIndex(m_pInterface, hOld);
241 if (iOld == iSel) {
242 return;
243 } else if (iOld > -1) {
244 GetItemRect(iOld, rtInvalidate);
245 SetSelItem(hOld, FALSE);
246 }
247 if (hItem) {
248 CFX_RectF rect;
249 GetItemRect(iSel, rect);
250 rtInvalidate.Union(rect);
251 FWL_HLISTITEM hSel = pData->GetItem(m_pInterface, iSel);
252 SetSelItem(hSel, TRUE);
253 }
254 if (!rtInvalidate.IsEmpty()) {
255 Repaint(&rtInvalidate);
256 }
257 }
CountItems()258 int32_t CFWL_ComboListImp::CountItems() {
259 IFWL_ListBoxDP* pData =
260 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
261 return pData ? pData->CountItems(m_pInterface) : 0;
262 }
GetItemRect(int32_t nIndex,CFX_RectF & rtItem)263 void CFWL_ComboListImp::GetItemRect(int32_t nIndex, CFX_RectF& rtItem) {
264 IFWL_ListBoxDP* pData =
265 static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
266 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, nIndex);
267 pData->GetItemRect(m_pInterface, hItem, rtItem);
268 }
ClientToOuter(FX_FLOAT & fx,FX_FLOAT & fy)269 void CFWL_ComboListImp::ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy) {
270 fx += m_pProperties->m_rtWidget.left, fy += m_pProperties->m_rtWidget.top;
271 IFWL_Widget* pOwner = GetOwner();
272 if (!pOwner)
273 return;
274 pOwner->TransformTo(m_pOuter, fx, fy);
275 }
SetFocus(FX_BOOL bSet)276 void CFWL_ComboListImp::SetFocus(FX_BOOL bSet) {
277 CFWL_WidgetImp::SetFocus(bSet);
278 }
CFWL_ComboListImpDelegate(CFWL_ComboListImp * pOwner)279 CFWL_ComboListImpDelegate::CFWL_ComboListImpDelegate(CFWL_ComboListImp* pOwner)
280 : CFWL_ListBoxImpDelegate(pOwner), m_pOwner(pOwner) {
281 }
OnProcessMessage(CFWL_Message * pMessage)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 }
OnDropListFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)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 }
OnDropListMouseMove(CFWL_MsgMouse * pMsg)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 }
OnDropListLButtonDown(CFWL_MsgMouse * pMsg)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 }
OnDropListLButtonUp(CFWL_MsgMouse * pMsg)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 }
OnDropListKey(CFWL_MsgKey * pKey)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 }
OnDropListKeyDown(CFWL_MsgKey * pKey)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 }
CFWL_ComboBoxImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)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 }
~CFWL_ComboBoxImp()478 CFWL_ComboBoxImp::~CFWL_ComboBoxImp() {
479 }
GetClassName(CFX_WideString & wsClass) const480 FWL_ERR CFWL_ComboBoxImp::GetClassName(CFX_WideString& wsClass) const {
481 wsClass = FWL_CLASS_ComboBox;
482 return FWL_ERR_Succeeded;
483 }
GetClassID() const484 FX_DWORD CFWL_ComboBoxImp::GetClassID() const {
485 return FWL_CLASSHASH_ComboBox;
486 }
Initialize()487 FWL_ERR CFWL_ComboBoxImp::Initialize() {
488 if (m_pWidgetMgr->IsFormDisabled()) {
489 return DisForm_Initialize();
490 }
491 if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
492 return FWL_WGTSTATE_Invisible; // Probably a bug; not a FWL_ERR_ value.
493 m_pDelegate = new CFWL_ComboBoxImpDelegate(this);
494 CFWL_WidgetImpProperties prop;
495 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
496 prop.m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
497 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) {
498 prop.m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon;
499 }
500 prop.m_pDataProvider = m_pProperties->m_pDataProvider;
501 m_pListBox.reset(IFWL_ListBox::CreateComboList(prop, m_pInterface));
502 m_pListBox->Initialize();
503 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) {
504 CFWL_WidgetImpProperties prop2;
505 m_pEdit.reset(IFWL_Edit::CreateComboEdit(prop2, m_pInterface));
506 m_pEdit->Initialize();
507 static_cast<CFWL_EditImp*>(m_pEdit->GetImpl())->SetOuter(m_pInterface);
508 }
509 if (m_pEdit) {
510 m_pEdit->SetParent(m_pInterface);
511 }
512 SetStates(m_pProperties->m_dwStates);
513 return FWL_ERR_Succeeded;
514 }
Finalize()515 FWL_ERR CFWL_ComboBoxImp::Finalize() {
516 if (m_pEdit) {
517 m_pEdit->Finalize();
518 }
519 m_pListBox->Finalize();
520 delete m_pDelegate;
521 m_pDelegate = nullptr;
522 return CFWL_WidgetImp::Finalize();
523 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)524 FWL_ERR CFWL_ComboBoxImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
525 if (bAutoSize) {
526 rect.Reset();
527 FX_BOOL bIsDropDown = IsDropDownStyle();
528 if (bIsDropDown && m_pEdit) {
529 m_pEdit->GetWidgetRect(rect, TRUE);
530 } else {
531 rect.width = 100;
532 rect.height = 16;
533 }
534 if (!m_pProperties->m_pThemeProvider) {
535 ReSetTheme();
536 }
537 FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>(
538 GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
539 if (!pFWidth)
540 return FWL_ERR_Indefinite;
541 rect.Inflate(0, 0, *pFWidth, 0);
542 CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
543 } else {
544 rect = m_pProperties->m_rtWidget;
545 }
546 return FWL_ERR_Succeeded;
547 }
ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)548 FWL_ERR CFWL_ComboBoxImp::ModifyStylesEx(FX_DWORD dwStylesExAdded,
549 FX_DWORD dwStylesExRemoved) {
550 if (m_pWidgetMgr->IsFormDisabled()) {
551 return DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
552 }
553 FX_BOOL bAddDropDown = dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown;
554 FX_BOOL bRemoveDropDown = dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown;
555 if (bAddDropDown && !m_pEdit) {
556 CFWL_WidgetImpProperties prop;
557 m_pEdit.reset(IFWL_Edit::CreateComboEdit(prop, nullptr));
558 m_pEdit->Initialize();
559 static_cast<CFWL_EditImp*>(m_pEdit->GetImpl())->SetOuter(m_pInterface);
560 m_pEdit->SetParent(m_pInterface);
561 } else if (bRemoveDropDown && m_pEdit) {
562 m_pEdit->SetStates(FWL_WGTSTATE_Invisible, TRUE);
563 }
564 return CFWL_WidgetImp::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
565 }
Update()566 FWL_ERR CFWL_ComboBoxImp::Update() {
567 if (m_pWidgetMgr->IsFormDisabled()) {
568 return DisForm_Update();
569 }
570 if (IsLocked()) {
571 return FWL_ERR_Indefinite;
572 }
573 ReSetTheme();
574 FX_BOOL bDropDown = IsDropDownStyle();
575 if (bDropDown && m_pEdit) {
576 ReSetEditAlignment();
577 }
578 if (m_pProperties->m_pThemeProvider == NULL) {
579 m_pProperties->m_pThemeProvider = GetAvailableTheme();
580 }
581 Layout();
582 CFWL_ThemePart part;
583 part.m_pWidget = m_pInterface;
584 m_fComboFormHandler =
585 *static_cast<FX_FLOAT*>(m_pProperties->m_pThemeProvider->GetCapacity(
586 &part, FWL_WGTCAPACITY_CMB_ComboFormHandler));
587 return FWL_ERR_Succeeded;
588 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)589 FX_DWORD CFWL_ComboBoxImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
590 if (m_pWidgetMgr->IsFormDisabled()) {
591 return DisForm_HitTest(fx, fy);
592 }
593 return CFWL_WidgetImp::HitTest(fx, fy);
594 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)595 FWL_ERR CFWL_ComboBoxImp::DrawWidget(CFX_Graphics* pGraphics,
596 const CFX_Matrix* pMatrix) {
597 if (m_pWidgetMgr->IsFormDisabled()) {
598 return DisForm_DrawWidget(pGraphics, pMatrix);
599 }
600 if (!pGraphics)
601 return FWL_ERR_Indefinite;
602 if (!m_pProperties->m_pThemeProvider)
603 return FWL_ERR_Indefinite;
604 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
605 FX_BOOL bIsDropDown = IsDropDownStyle();
606 if (HasBorder()) {
607 DrawBorder(pGraphics, FWL_PART_CMB_Border, pTheme, pMatrix);
608 }
609 if (HasEdge()) {
610 DrawEdge(pGraphics, FWL_PART_CMB_Edge, pTheme, pMatrix);
611 }
612 if (!bIsDropDown) {
613 CFX_RectF rtTextBk(m_rtClient);
614 rtTextBk.width -= m_rtBtn.width;
615 CFWL_ThemeBackground param;
616 param.m_pWidget = m_pInterface;
617 param.m_iPart = FWL_PART_CMB_Background;
618 param.m_pGraphics = pGraphics;
619 if (pMatrix) {
620 param.m_matrix.Concat(*pMatrix);
621 }
622 param.m_rtPart = rtTextBk;
623 if (m_iCurSel >= 0) {
624 IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
625 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
626 ->m_pProperties->m_pDataProvider);
627 void* p = pData->GetItemData(m_pListBox.get(),
628 pData->GetItem(m_pListBox.get(), m_iCurSel));
629 if (p != NULL) {
630 param.m_pData = p;
631 }
632 }
633 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
634 param.m_dwStates = FWL_PARTSTATE_CMB_Disabled;
635 } else if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) &&
636 (m_iCurSel >= 0)) {
637 param.m_dwStates = FWL_PARTSTATE_CMB_Selected;
638 } else {
639 param.m_dwStates = FWL_PARTSTATE_CMB_Normal;
640 }
641 pTheme->DrawBackground(¶m);
642 if (m_iCurSel >= 0) {
643 if (!m_pListBox)
644 return FWL_ERR_Indefinite;
645 CFX_WideString wsText;
646 IFWL_ComboBoxDP* pData =
647 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
648 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
649 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
650 ->GetItemText(hItem, wsText);
651 CFWL_ThemeText param;
652 param.m_pWidget = m_pInterface;
653 param.m_iPart = FWL_PART_CMB_Caption;
654 param.m_dwStates = m_iBtnState;
655 param.m_pGraphics = pGraphics;
656 param.m_matrix.Concat(*pMatrix);
657 param.m_rtPart = rtTextBk;
658 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)
659 ? FWL_PARTSTATE_CMB_Selected
660 : FWL_PARTSTATE_CMB_Normal;
661 param.m_wsText = wsText;
662 param.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
663 param.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
664 pTheme->DrawText(¶m);
665 }
666 }
667 {
668 CFWL_ThemeBackground param;
669 param.m_pWidget = m_pInterface;
670 param.m_iPart = FWL_PART_CMB_DropDownButton;
671 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
672 ? FWL_PARTSTATE_CMB_Disabled
673 : m_iBtnState;
674 param.m_pGraphics = pGraphics;
675 param.m_matrix.Concat(*pMatrix);
676 param.m_rtPart = m_rtBtn;
677 pTheme->DrawBackground(¶m);
678 }
679 return FWL_ERR_Succeeded;
680 }
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)681 FWL_ERR CFWL_ComboBoxImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
682 if (!pThemeProvider)
683 return FWL_ERR_Indefinite;
684 m_pProperties->m_pThemeProvider = pThemeProvider;
685 if (m_pListBox && pThemeProvider->IsValidWidget(m_pListBox.get())) {
686 m_pListBox->SetThemeProvider(pThemeProvider);
687 }
688 if (m_pEdit && pThemeProvider->IsValidWidget(m_pEdit.get())) {
689 m_pEdit->SetThemeProvider(pThemeProvider);
690 }
691 return FWL_ERR_Succeeded;
692 }
GetCurSel()693 int32_t CFWL_ComboBoxImp::GetCurSel() {
694 return m_iCurSel;
695 }
SetCurSel(int32_t iSel)696 FWL_ERR CFWL_ComboBoxImp::SetCurSel(int32_t iSel) {
697 int32_t iCount =
698 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->CountItems();
699 FX_BOOL bClearSel = iSel < 0 || iSel >= iCount;
700 FX_BOOL bDropDown = IsDropDownStyle();
701 if (bDropDown && m_pEdit) {
702 if (bClearSel) {
703 m_pEdit->SetText(CFX_WideString());
704 } else {
705 CFX_WideString wsText;
706 IFWL_ComboBoxDP* pData =
707 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
708 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iSel);
709 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
710 ->GetItemText(hItem, wsText);
711 m_pEdit->SetText(wsText);
712 }
713 m_pEdit->Update();
714 }
715 m_iCurSel = bClearSel ? -1 : iSel;
716 return FWL_ERR_Succeeded;
717 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)718 FWL_ERR CFWL_ComboBoxImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
719 FX_BOOL bIsDropDown = IsDropDownStyle();
720 if (bIsDropDown && m_pEdit) {
721 m_pEdit->SetStates(dwStates, bSet);
722 }
723 if (m_pListBox) {
724 m_pListBox->SetStates(dwStates, bSet);
725 }
726 return CFWL_WidgetImp::SetStates(dwStates, bSet);
727 }
SetEditText(const CFX_WideString & wsText)728 FWL_ERR CFWL_ComboBoxImp::SetEditText(const CFX_WideString& wsText) {
729 if (!m_pEdit)
730 return FWL_ERR_Indefinite;
731 m_pEdit->SetText(wsText);
732 return m_pEdit->Update();
733 }
GetEditTextLength() const734 int32_t CFWL_ComboBoxImp::GetEditTextLength() const {
735 if (!m_pEdit)
736 return -1;
737 return m_pEdit->GetTextLength();
738 }
GetEditText(CFX_WideString & wsText,int32_t nStart,int32_t nCount) const739 FWL_ERR CFWL_ComboBoxImp::GetEditText(CFX_WideString& wsText,
740 int32_t nStart,
741 int32_t nCount) const {
742 if (m_pEdit) {
743 return m_pEdit->GetText(wsText, nStart, nCount);
744 } else if (m_pListBox) {
745 IFWL_ComboBoxDP* pData =
746 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
747 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
748 return m_pListBox->GetItemText(hItem, wsText);
749 }
750 return FWL_ERR_Indefinite;
751 }
SetEditSelRange(int32_t nStart,int32_t nCount)752 FWL_ERR CFWL_ComboBoxImp::SetEditSelRange(int32_t nStart, int32_t nCount) {
753 if (!m_pEdit)
754 return FWL_ERR_Indefinite;
755 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->ClearSelected();
756 m_pEdit->AddSelRange(nStart, nCount);
757 return FWL_ERR_Succeeded;
758 }
GetEditSelRange(int32_t nIndex,int32_t & nStart)759 int32_t CFWL_ComboBoxImp::GetEditSelRange(int32_t nIndex, int32_t& nStart) {
760 if (!m_pEdit)
761 return -1;
762 return m_pEdit->GetSelRange(nIndex, nStart);
763 }
GetEditLimit()764 int32_t CFWL_ComboBoxImp::GetEditLimit() {
765 if (!m_pEdit)
766 return -1;
767 return m_pEdit->GetLimit();
768 }
SetEditLimit(int32_t nLimit)769 FWL_ERR CFWL_ComboBoxImp::SetEditLimit(int32_t nLimit) {
770 if (!m_pEdit)
771 return FWL_ERR_Indefinite;
772 return m_pEdit->SetLimit(nLimit);
773 }
EditDoClipboard(int32_t iCmd)774 FWL_ERR CFWL_ComboBoxImp::EditDoClipboard(int32_t iCmd) {
775 if (!m_pEdit)
776 return FWL_ERR_Indefinite;
777 return m_pEdit->DoClipboard(iCmd);
778 }
EditRedo(const CFX_ByteStringC & bsRecord)779 FX_BOOL CFWL_ComboBoxImp::EditRedo(const CFX_ByteStringC& bsRecord) {
780 if (!m_pEdit)
781 return FALSE;
782 return m_pEdit->Redo(bsRecord);
783 }
EditUndo(const CFX_ByteStringC & bsRecord)784 FX_BOOL CFWL_ComboBoxImp::EditUndo(const CFX_ByteStringC& bsRecord) {
785 if (!m_pEdit)
786 return FALSE;
787 return m_pEdit->Undo(bsRecord);
788 }
GetListBoxt()789 IFWL_ListBox* CFWL_ComboBoxImp::GetListBoxt() {
790 return m_pListBox.get();
791 }
AfterFocusShowDropList()792 FX_BOOL CFWL_ComboBoxImp::AfterFocusShowDropList() {
793 if (!m_bNeedShowList) {
794 return FALSE;
795 }
796 if (m_pEdit) {
797 MatchEditText();
798 }
799 ShowDropList(TRUE);
800 m_bNeedShowList = FALSE;
801 return TRUE;
802 }
OpenDropDownList(FX_BOOL bActivate)803 FX_ERR CFWL_ComboBoxImp::OpenDropDownList(FX_BOOL bActivate) {
804 ShowDropList(bActivate);
805 return FWL_ERR_Succeeded;
806 }
EditCanUndo()807 FX_BOOL CFWL_ComboBoxImp::EditCanUndo() {
808 return m_pEdit->CanUndo();
809 }
EditCanRedo()810 FX_BOOL CFWL_ComboBoxImp::EditCanRedo() {
811 return m_pEdit->CanRedo();
812 }
EditUndo()813 FX_BOOL CFWL_ComboBoxImp::EditUndo() {
814 return m_pEdit->Undo();
815 }
EditRedo()816 FX_BOOL CFWL_ComboBoxImp::EditRedo() {
817 return m_pEdit->Redo();
818 }
EditCanCopy()819 FX_BOOL CFWL_ComboBoxImp::EditCanCopy() {
820 return m_pEdit->CountSelRanges() > 0;
821 }
EditCanCut()822 FX_BOOL CFWL_ComboBoxImp::EditCanCut() {
823 if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
824 return FALSE;
825 }
826 return m_pEdit->CountSelRanges() > 0;
827 }
EditCanSelectAll()828 FX_BOOL CFWL_ComboBoxImp::EditCanSelectAll() {
829 return m_pEdit->GetTextLength() > 0;
830 }
EditCopy(CFX_WideString & wsCopy)831 FX_BOOL CFWL_ComboBoxImp::EditCopy(CFX_WideString& wsCopy) {
832 return m_pEdit->Copy(wsCopy);
833 }
EditCut(CFX_WideString & wsCut)834 FX_BOOL CFWL_ComboBoxImp::EditCut(CFX_WideString& wsCut) {
835 return m_pEdit->Cut(wsCut);
836 }
EditPaste(const CFX_WideString & wsPaste)837 FX_BOOL CFWL_ComboBoxImp::EditPaste(const CFX_WideString& wsPaste) {
838 return m_pEdit->Paste(wsPaste);
839 }
EditSelectAll()840 FX_BOOL CFWL_ComboBoxImp::EditSelectAll() {
841 return m_pEdit->AddSelRange(0) == FWL_ERR_Succeeded;
842 }
EditDelete()843 FX_BOOL CFWL_ComboBoxImp::EditDelete() {
844 return m_pEdit->ClearText() == FWL_ERR_Succeeded;
845 }
EditDeSelect()846 FX_BOOL CFWL_ComboBoxImp::EditDeSelect() {
847 return m_pEdit->ClearSelections() == FWL_ERR_Succeeded;
848 }
GetBBox(CFX_RectF & rect)849 FWL_ERR CFWL_ComboBoxImp::GetBBox(CFX_RectF& rect) {
850 if (m_pWidgetMgr->IsFormDisabled()) {
851 return DisForm_GetBBox(rect);
852 }
853 rect = m_pProperties->m_rtWidget;
854 if (m_pListBox && IsDropListShowed()) {
855 CFX_RectF rtList;
856 m_pListBox->GetWidgetRect(rtList);
857 rtList.Offset(rect.left, rect.top);
858 rect.Union(rtList);
859 }
860 return FWL_ERR_Succeeded;
861 }
EditModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)862 FWL_ERR CFWL_ComboBoxImp::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
863 FX_DWORD dwStylesExRemoved) {
864 if (m_pEdit != NULL) {
865 return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
866 } else {
867 return FWL_ERR_Parameter_Invalid;
868 }
869 }
GetListHeight()870 FX_FLOAT CFWL_ComboBoxImp::GetListHeight() {
871 return static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider)
872 ->GetListHeight(m_pInterface);
873 }
DrawStretchHandler(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)874 void CFWL_ComboBoxImp::DrawStretchHandler(CFX_Graphics* pGraphics,
875 const CFX_Matrix* pMatrix) {
876 CFWL_ThemeBackground param;
877 param.m_pGraphics = pGraphics;
878 param.m_iPart = FWL_PART_CMB_StretcgHandler;
879 param.m_dwStates = FWL_PARTSTATE_CMB_Normal;
880 param.m_pWidget = m_pInterface;
881 if (pMatrix) {
882 param.m_matrix.Concat(*pMatrix);
883 }
884 param.m_rtPart = m_rtHandler;
885 m_pProperties->m_pThemeProvider->DrawBackground(¶m);
886 }
ShowDropList(FX_BOOL bActivate)887 void CFWL_ComboBoxImp::ShowDropList(FX_BOOL bActivate) {
888 if (m_pWidgetMgr->IsFormDisabled()) {
889 return DisForm_ShowDropList(bActivate);
890 }
891 FX_BOOL bDropList = IsDropListShowed();
892 if (bDropList == bActivate) {
893 return;
894 }
895 if (!m_pForm) {
896 InitProxyForm();
897 }
898 m_pListProxyDelegate->Reset();
899 if (bActivate) {
900 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
901 ->ChangeSelected(m_iCurSel);
902 ReSetListItemAlignment();
903 FX_DWORD dwStyleAdd = m_pProperties->m_dwStyleExes &
904 (FWL_STYLEEXT_CMB_Sort | FWL_STYLEEXT_CMB_OwnerDraw);
905 m_pListBox->ModifyStylesEx(dwStyleAdd, 0);
906 m_pListBox->GetWidgetRect(m_rtList, TRUE);
907 FX_FLOAT fHeight = GetListHeight();
908 if (fHeight > 0) {
909 if (m_rtList.height > GetListHeight()) {
910 m_rtList.height = GetListHeight();
911 m_pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll, 0);
912 }
913 }
914 CFX_RectF rtAnchor;
915 rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width,
916 m_pProperties->m_rtWidget.height);
917 FX_FLOAT fMinHeight = 0;
918 if (m_rtList.width < m_rtClient.width) {
919 m_rtList.width = m_rtClient.width;
920 }
921 m_rtProxy = m_rtList;
922 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) {
923 m_rtProxy.height += m_fComboFormHandler;
924 }
925 GetPopupPos(fMinHeight, m_rtProxy.height, rtAnchor, m_rtProxy);
926 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) {
927 FX_FLOAT fx = 0;
928 FX_FLOAT fy = m_rtClient.top + m_rtClient.height / 2;
929 TransformTo(NULL, fx, fy);
930 m_bUpFormHandler = fy > m_rtProxy.top;
931 if (m_bUpFormHandler) {
932 m_rtHandler.Set(0, 0, m_rtList.width, m_fComboFormHandler);
933 m_rtList.top = m_fComboFormHandler;
934 } else {
935 m_rtHandler.Set(0, m_rtList.height, m_rtList.width,
936 m_fComboFormHandler);
937 }
938 }
939 m_pForm->SetWidgetRect(m_rtProxy);
940 m_pForm->Update();
941 m_pListBox->SetWidgetRect(m_rtList);
942 m_pListBox->Update();
943 CFWL_EvtCmbPreDropDown ev;
944 ev.m_pSrcTarget = m_pInterface;
945 DispatchEvent(&ev);
946 m_fItemHeight =
947 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->m_fItemHeight;
948 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->SetFocus(TRUE);
949 m_pForm->DoModal();
950 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->SetFocus(FALSE);
951 } else {
952 m_pForm->EndDoModal();
953 CFWL_EvtCmbCloseUp ev;
954 ev.m_pSrcTarget = m_pInterface;
955 DispatchEvent(&ev);
956 m_bLButtonDown = FALSE;
957 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->m_bNotifyOwner =
958 TRUE;
959 SetFocus(TRUE);
960 }
961 }
IsDropListShowed()962 FX_BOOL CFWL_ComboBoxImp::IsDropListShowed() {
963 return m_pForm && !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
964 }
IsDropDownStyle() const965 FX_BOOL CFWL_ComboBoxImp::IsDropDownStyle() const {
966 return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown;
967 }
MatchEditText()968 void CFWL_ComboBoxImp::MatchEditText() {
969 CFX_WideString wsText;
970 m_pEdit->GetText(wsText);
971 int32_t iMatch =
972 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())->MatchItem(wsText);
973 if (iMatch != m_iCurSel) {
974 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
975 ->ChangeSelected(iMatch);
976 if (iMatch >= 0) {
977 SynchrEditText(iMatch);
978 }
979 } else if (iMatch >= 0) {
980 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetSelected();
981 }
982 m_iCurSel = iMatch;
983 }
SynchrEditText(int32_t iListItem)984 void CFWL_ComboBoxImp::SynchrEditText(int32_t iListItem) {
985 CFX_WideString wsText;
986 IFWL_ComboBoxDP* pData =
987 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
988 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iListItem);
989 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
990 ->GetItemText(hItem, wsText);
991 m_pEdit->SetText(wsText);
992 m_pEdit->Update();
993 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetSelected();
994 }
Layout()995 void CFWL_ComboBoxImp::Layout() {
996 if (m_pWidgetMgr->IsFormDisabled()) {
997 return DisForm_Layout();
998 }
999 GetClientRect(m_rtClient);
1000 FX_FLOAT* pFWidth =
1001 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1002 if (!pFWidth)
1003 return;
1004 FX_FLOAT fBtn = *pFWidth;
1005 m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn,
1006 m_rtClient.height);
1007 FX_BOOL bIsDropDown = IsDropDownStyle();
1008 if (bIsDropDown && m_pEdit) {
1009 CFX_RectF rtEdit;
1010 rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn,
1011 m_rtClient.height);
1012 m_pEdit->SetWidgetRect(rtEdit);
1013 if (m_iCurSel >= 0) {
1014 CFX_WideString wsText;
1015 IFWL_ComboBoxDP* pData =
1016 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1017 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
1018 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
1019 ->GetItemText(hItem, wsText);
1020 m_pEdit->LockUpdate();
1021 m_pEdit->SetText(wsText);
1022 m_pEdit->UnlockUpdate();
1023 }
1024 m_pEdit->Update();
1025 }
1026 }
ReSetTheme()1027 void CFWL_ComboBoxImp::ReSetTheme() {
1028 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
1029 if (!pTheme) {
1030 pTheme = GetAvailableTheme();
1031 m_pProperties->m_pThemeProvider = pTheme;
1032 }
1033 if (m_pListBox) {
1034 if (!m_pListBox->GetThemeProvider() &&
1035 pTheme->IsValidWidget(m_pListBox.get())) {
1036 m_pListBox->SetThemeProvider(pTheme);
1037 }
1038 }
1039 if (m_pEdit) {
1040 if (!m_pEdit->GetThemeProvider() && pTheme->IsValidWidget(m_pEdit.get())) {
1041 m_pEdit->SetThemeProvider(pTheme);
1042 }
1043 }
1044 }
ReSetEditAlignment()1045 void CFWL_ComboBoxImp::ReSetEditAlignment() {
1046 if (!m_pEdit)
1047 return;
1048 FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
1049 FX_DWORD dwAdd = 0;
1050 switch (dwStylExes & FWL_STYLEEXT_CMB_EditHAlignMask) {
1051 case FWL_STYLEEXT_CMB_EditHCenter: {
1052 dwAdd |= FWL_STYLEEXT_EDT_HCenter;
1053 break;
1054 }
1055 case FWL_STYLEEXT_CMB_EditHFar: {
1056 dwAdd |= FWL_STYLEEXT_EDT_HFar;
1057 break;
1058 }
1059 default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; }
1060 }
1061 switch (dwStylExes & FWL_STYLEEXT_CMB_EditVAlignMask) {
1062 case FWL_STYLEEXT_CMB_EditVCenter: {
1063 dwAdd |= FWL_STYLEEXT_EDT_VCenter;
1064 break;
1065 }
1066 case FWL_STYLEEXT_CMB_EditVFar: {
1067 dwAdd |= FWL_STYLEEXT_EDT_VFar;
1068 break;
1069 }
1070 default: { dwAdd |= FWL_STYLEEXT_EDT_VNear; }
1071 }
1072 if (dwStylExes & FWL_STYLEEXT_CMB_EditJustified) {
1073 dwAdd |= FWL_STYLEEXT_EDT_Justified;
1074 }
1075 if (dwStylExes & FWL_STYLEEXT_CMB_EditDistributed) {
1076 dwAdd |= FWL_STYLEEXT_EDT_Distributed;
1077 }
1078 m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
1079 FWL_STYLEEXT_EDT_HAlignModeMask |
1080 FWL_STYLEEXT_EDT_VAlignMask);
1081 }
ReSetListItemAlignment()1082 void CFWL_ComboBoxImp::ReSetListItemAlignment() {
1083 if (!m_pListBox)
1084 return;
1085 FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
1086 FX_DWORD dwAdd = 0;
1087 switch (dwStylExes & FWL_STYLEEXT_CMB_ListItemAlignMask) {
1088 case FWL_STYLEEXT_CMB_ListItemCenterAlign: {
1089 dwAdd |= FWL_STYLEEXT_LTB_CenterAlign;
1090 }
1091 case FWL_STYLEEXT_CMB_ListItemRightAlign: {
1092 dwAdd |= FWL_STYLEEXT_LTB_RightAlign;
1093 }
1094 default: { dwAdd |= FWL_STYLEEXT_LTB_LeftAlign; }
1095 }
1096 m_pListBox->ModifyStylesEx(dwAdd, FWL_STYLEEXT_CMB_ListItemAlignMask);
1097 }
ProcessSelChanged(FX_BOOL bLButtonUp)1098 void CFWL_ComboBoxImp::ProcessSelChanged(FX_BOOL bLButtonUp) {
1099 IFWL_ComboBoxDP* pDatas =
1100 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1101 m_iCurSel = pDatas->GetItemIndex(m_pInterface, m_pListBox->GetSelItem(0));
1102 FX_BOOL bDropDown = IsDropDownStyle();
1103 if (bDropDown) {
1104 IFWL_ComboBoxDP* pData =
1105 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1106 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
1107 if (hItem) {
1108 CFX_WideString wsText;
1109 pData->GetItemText(m_pInterface, hItem, wsText);
1110 if (m_pEdit) {
1111 m_pEdit->SetText(wsText);
1112 m_pEdit->Update();
1113 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetSelected();
1114 }
1115 CFWL_EvtCmbSelChanged ev;
1116 ev.bLButtonUp = bLButtonUp;
1117 ev.m_pSrcTarget = m_pInterface;
1118 ev.iArraySels.Add(m_iCurSel);
1119 DispatchEvent(&ev);
1120 }
1121 } else {
1122 Repaint(&m_rtClient);
1123 }
1124 }
InitProxyForm()1125 void CFWL_ComboBoxImp::InitProxyForm() {
1126 if (m_pForm)
1127 return;
1128 if (!m_pListBox)
1129 return;
1130 CFWL_WidgetImpProperties propForm;
1131 propForm.m_pOwner = m_pInterface;
1132 propForm.m_dwStyles = FWL_WGTSTYLE_Popup;
1133 propForm.m_dwStates = FWL_WGTSTATE_Invisible;
1134 CFX_WideString className;
1135 m_pForm = IFWL_Form::CreateFormProxy(propForm, &className, m_pListBox.get());
1136 m_pForm->Initialize();
1137 m_pProxy = static_cast<CFWL_FormProxyImp*>(m_pForm->GetImpl());
1138 m_pListBox->SetParent(m_pForm);
1139 m_pListProxyDelegate = new CFWL_ComboProxyImpDelegate(m_pForm, this);
1140 m_pProxy->SetDelegate(m_pListProxyDelegate);
1141 }
DisForm_Initialize()1142 FWL_ERR CFWL_ComboBoxImp::DisForm_Initialize() {
1143 if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
1144 return FWL_WGTSTATE_Invisible; // Ditto.
1145 m_pDelegate = new CFWL_ComboBoxImpDelegate(this);
1146 DisForm_InitComboList();
1147 DisForm_InitComboEdit();
1148 return FWL_ERR_Succeeded;
1149 }
DisForm_InitComboList()1150 void CFWL_ComboBoxImp::DisForm_InitComboList() {
1151 if (m_pListBox) {
1152 return;
1153 }
1154 CFWL_WidgetImpProperties prop;
1155 prop.m_pParent = m_pInterface;
1156 prop.m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
1157 prop.m_dwStates = FWL_WGTSTATE_Invisible;
1158 prop.m_pDataProvider = m_pProperties->m_pDataProvider;
1159 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
1160 m_pListBox.reset(IFWL_ListBox::CreateComboList(prop, m_pInterface));
1161 m_pListBox->Initialize();
1162 }
DisForm_InitComboEdit()1163 void CFWL_ComboBoxImp::DisForm_InitComboEdit() {
1164 if (m_pEdit) {
1165 return;
1166 }
1167 CFWL_WidgetImpProperties prop;
1168 prop.m_pParent = m_pInterface;
1169 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
1170 m_pEdit.reset(IFWL_Edit::CreateComboEdit(prop, m_pInterface));
1171 m_pEdit->Initialize();
1172 static_cast<CFWL_ComboEditImp*>(m_pEdit->GetImpl())->SetOuter(m_pInterface);
1173 }
DisForm_ShowDropList(FX_BOOL bActivate)1174 void CFWL_ComboBoxImp::DisForm_ShowDropList(FX_BOOL bActivate) {
1175 FX_BOOL bDropList = DisForm_IsDropListShowed();
1176 if (bDropList == bActivate) {
1177 return;
1178 }
1179 if (bActivate) {
1180 CFWL_EvtCmbPreDropDown preEvent;
1181 preEvent.m_pSrcTarget = m_pInterface;
1182 DispatchEvent(&preEvent);
1183 CFWL_ComboListImp* pComboList =
1184 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl());
1185 int32_t iItems = pComboList->CountItems();
1186 if (iItems < 1) {
1187 return;
1188 }
1189 ReSetListItemAlignment();
1190 pComboList->ChangeSelected(m_iCurSel);
1191 FX_FLOAT fItemHeight = pComboList->GetItemHeigt();
1192 FX_FLOAT fBorder = GetBorderSize();
1193 FX_FLOAT fPopupMin = 0.0f;
1194 if (iItems > 3) {
1195 fPopupMin = fItemHeight * 3 + fBorder * 2;
1196 }
1197 FX_FLOAT fPopupMax = fItemHeight * iItems + fBorder * 2;
1198 CFX_RectF rtList;
1199 rtList.left = m_rtClient.left;
1200 rtList.width = m_pProperties->m_rtWidget.width;
1201 rtList.top = 0;
1202 rtList.height = 0;
1203 GetPopupPos(fPopupMin, fPopupMax, m_pProperties->m_rtWidget, rtList);
1204 m_pListBox->SetWidgetRect(rtList);
1205 m_pListBox->Update();
1206 } else {
1207 SetFocus(TRUE);
1208 }
1209 m_pListBox->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
1210 if (bActivate) {
1211 CFWL_EvtCmbPostDropDown postEvent;
1212 postEvent.m_pSrcTarget = m_pInterface;
1213 DispatchEvent(&postEvent);
1214 }
1215 CFX_RectF rect;
1216 m_pListBox->GetWidgetRect(rect);
1217 rect.Inflate(2, 2);
1218 Repaint(&rect);
1219 }
DisForm_IsDropListShowed()1220 FX_BOOL CFWL_ComboBoxImp::DisForm_IsDropListShowed() {
1221 return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible);
1222 }
DisForm_ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)1223 FWL_ERR CFWL_ComboBoxImp::DisForm_ModifyStylesEx(FX_DWORD dwStylesExAdded,
1224 FX_DWORD dwStylesExRemoved) {
1225 if (!m_pEdit) {
1226 DisForm_InitComboEdit();
1227 }
1228 FX_BOOL bAddDropDown = dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown;
1229 FX_BOOL bDelDropDown = dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown;
1230 dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown;
1231 m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown;
1232 if (bAddDropDown) {
1233 m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly);
1234 } else if (bDelDropDown) {
1235 m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0);
1236 }
1237 return CFWL_WidgetImp::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
1238 }
DisForm_Update()1239 FWL_ERR CFWL_ComboBoxImp::DisForm_Update() {
1240 if (m_iLock) {
1241 return FWL_ERR_Indefinite;
1242 }
1243 if (m_pEdit) {
1244 ReSetEditAlignment();
1245 }
1246 ReSetTheme();
1247 Layout();
1248 return FWL_ERR_Succeeded;
1249 }
DisForm_HitTest(FX_FLOAT fx,FX_FLOAT fy)1250 FX_DWORD CFWL_ComboBoxImp::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) {
1251 CFX_RectF rect;
1252 rect.Set(0, 0, m_pProperties->m_rtWidget.width - m_rtBtn.width,
1253 m_pProperties->m_rtWidget.height);
1254 if (rect.Contains(fx, fy)) {
1255 return FWL_WGTHITTEST_Edit;
1256 }
1257 if (m_rtBtn.Contains(fx, fy)) {
1258 return FWL_WGTHITTEST_Client;
1259 }
1260 if (DisForm_IsDropListShowed()) {
1261 m_pListBox->GetWidgetRect(rect);
1262 if (rect.Contains(fx, fy)) {
1263 return FWL_WGTHITTEST_Client;
1264 }
1265 }
1266 return FWL_WGTHITTEST_Unknown;
1267 }
DisForm_DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1268 FWL_ERR CFWL_ComboBoxImp::DisForm_DrawWidget(CFX_Graphics* pGraphics,
1269 const CFX_Matrix* pMatrix) {
1270 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
1271 CFX_Matrix mtOrg;
1272 mtOrg.Set(1, 0, 0, 1, 0, 0);
1273 if (pMatrix) {
1274 mtOrg = *pMatrix;
1275 }
1276 FX_BOOL bListShowed = m_pListBox && DisForm_IsDropListShowed();
1277 pGraphics->SaveGraphState();
1278 pGraphics->ConcatMatrix(&mtOrg);
1279 if (!m_rtBtn.IsEmpty(0.1f)) {
1280 CFWL_ThemeBackground param;
1281 param.m_pWidget = m_pInterface;
1282 param.m_iPart = FWL_PART_CMB_DropDownButton;
1283 param.m_dwStates = m_iBtnState;
1284 param.m_pGraphics = pGraphics;
1285 param.m_rtPart = m_rtBtn;
1286 pTheme->DrawBackground(¶m);
1287 }
1288 pGraphics->RestoreGraphState();
1289 if (m_pEdit) {
1290 CFX_RectF rtEdit;
1291 m_pEdit->GetWidgetRect(rtEdit);
1292 CFX_Matrix mt;
1293 mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top);
1294 mt.Concat(mtOrg);
1295 m_pEdit->DrawWidget(pGraphics, &mt);
1296 }
1297 if (bListShowed) {
1298 CFX_RectF rtList;
1299 m_pListBox->GetWidgetRect(rtList);
1300 CFX_Matrix mt;
1301 mt.Set(1, 0, 0, 1, rtList.left, rtList.top);
1302 mt.Concat(mtOrg);
1303 m_pListBox->DrawWidget(pGraphics, &mt);
1304 }
1305 return FWL_ERR_Succeeded;
1306 }
DisForm_GetBBox(CFX_RectF & rect)1307 FWL_ERR CFWL_ComboBoxImp::DisForm_GetBBox(CFX_RectF& rect) {
1308 rect = m_pProperties->m_rtWidget;
1309 if (m_pListBox && DisForm_IsDropListShowed()) {
1310 CFX_RectF rtList;
1311 m_pListBox->GetWidgetRect(rtList);
1312 rtList.Offset(rect.left, rect.top);
1313 rect.Union(rtList);
1314 }
1315 return FWL_ERR_Succeeded;
1316 }
DisForm_Layout()1317 void CFWL_ComboBoxImp::DisForm_Layout() {
1318 GetClientRect(m_rtClient);
1319 m_rtContent = m_rtClient;
1320 FX_FLOAT* pFWidth =
1321 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1322 if (!pFWidth)
1323 return;
1324 FX_FLOAT borderWidth = 0;
1325 { borderWidth = FWL_PART_CMB_Border; }
1326 FX_FLOAT fBtn = *pFWidth;
1327 if (!(this->GetStylesEx() & FWL_STYLEEXT_CMB_ReadOnly)) {
1328 m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth,
1329 fBtn - borderWidth, m_rtClient.height - 2 * borderWidth);
1330 }
1331 CFX_RectF* pUIMargin =
1332 static_cast<CFX_RectF*>(GetThemeCapacity(FWL_WGTCAPACITY_UIMargin));
1333 if (pUIMargin) {
1334 m_rtContent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
1335 pUIMargin->height);
1336 }
1337 FX_BOOL bIsDropDown = IsDropDownStyle();
1338 if (bIsDropDown && m_pEdit) {
1339 CFX_RectF rtEdit;
1340 rtEdit.Set(m_rtContent.left, m_rtContent.top, m_rtContent.width - fBtn,
1341 m_rtContent.height);
1342 m_pEdit->SetWidgetRect(rtEdit);
1343 if (m_iCurSel >= 0) {
1344 CFX_WideString wsText;
1345 IFWL_ComboBoxDP* pData =
1346 static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
1347 FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
1348 static_cast<CFWL_ComboListImp*>(m_pListBox->GetImpl())
1349 ->GetItemText(hItem, wsText);
1350 m_pEdit->LockUpdate();
1351 m_pEdit->SetText(wsText);
1352 m_pEdit->UnlockUpdate();
1353 }
1354 m_pEdit->Update();
1355 }
1356 }
CFWL_ComboBoxImpDelegate(CFWL_ComboBoxImp * pOwner)1357 CFWL_ComboBoxImpDelegate::CFWL_ComboBoxImpDelegate(CFWL_ComboBoxImp* pOwner)
1358 : m_pOwner(pOwner) {}
OnProcessMessage(CFWL_Message * pMessage)1359 int32_t CFWL_ComboBoxImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
1360 if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
1361 return DisForm_OnProcessMessage(pMessage);
1362 }
1363 if (!pMessage)
1364 return 0;
1365 FX_DWORD dwMsgCode = pMessage->GetClassID();
1366 FX_BOOL iRet = 1;
1367 switch (dwMsgCode) {
1368 case FWL_MSGHASH_SetFocus:
1369 case FWL_MSGHASH_KillFocus: {
1370 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
1371 break;
1372 }
1373 case FWL_MSGHASH_Mouse: {
1374 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
1375 FX_DWORD dwCmd = pMsg->m_dwCmd;
1376 switch (dwCmd) {
1377 case FWL_MSGMOUSECMD_LButtonDown: {
1378 OnLButtonDown(pMsg);
1379 break;
1380 }
1381 case FWL_MSGMOUSECMD_LButtonUp: {
1382 OnLButtonUp(pMsg);
1383 break;
1384 }
1385 case FWL_MSGMOUSECMD_MouseMove: {
1386 OnMouseMove(pMsg);
1387 break;
1388 }
1389 case FWL_MSGMOUSECMD_MouseLeave: {
1390 OnMouseLeave(pMsg);
1391 break;
1392 }
1393 default: {}
1394 }
1395 break;
1396 }
1397 case FWL_MSGHASH_Key: {
1398 OnKey(static_cast<CFWL_MsgKey*>(pMessage));
1399 break;
1400 }
1401 default: { iRet = 0; }
1402 }
1403 CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
1404 return iRet;
1405 }
OnProcessEvent(CFWL_Event * pEvent)1406 FWL_ERR CFWL_ComboBoxImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
1407 FX_DWORD dwFlag = pEvent->GetClassID();
1408 if (dwFlag == FWL_EVTHASH_LTB_DrawItem) {
1409 CFWL_EvtLtbDrawItem* pDrawItemEvent =
1410 static_cast<CFWL_EvtLtbDrawItem*>(pEvent);
1411 CFWL_EvtCmbDrawItem pTemp;
1412 pTemp.m_pSrcTarget = m_pOwner->m_pInterface;
1413 pTemp.m_pGraphics = pDrawItemEvent->m_pGraphics;
1414 pTemp.m_index = pDrawItemEvent->m_index;
1415 pTemp.m_rtItem = pDrawItemEvent->m_rect;
1416 m_pOwner->DispatchEvent(&pTemp);
1417 } else if (dwFlag == FWL_EVTHASH_Scroll) {
1418 CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
1419 CFWL_EvtScroll pScrollEv;
1420 pScrollEv.m_pSrcTarget = m_pOwner->m_pInterface;
1421 pScrollEv.m_iScrollCode = pScrollEvent->m_iScrollCode;
1422 pScrollEv.m_fPos = pScrollEvent->m_fPos;
1423 m_pOwner->DispatchEvent(&pScrollEv);
1424 } else if (dwFlag == FWL_EVTHASH_EDT_TextChanged) {
1425 CFWL_EvtEdtTextChanged* pTextChangedEvent =
1426 static_cast<CFWL_EvtEdtTextChanged*>(pEvent);
1427 CFWL_EvtCmbEditChanged pTemp;
1428 pTemp.m_pSrcTarget = m_pOwner->m_pInterface;
1429 pTemp.wsInsert = pTextChangedEvent->wsInsert;
1430 pTemp.wsDelete = pTextChangedEvent->wsDelete;
1431 pTemp.nChangeType = pTextChangedEvent->nChangeType;
1432 m_pOwner->DispatchEvent(&pTemp);
1433 }
1434 return FWL_ERR_Succeeded;
1435 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1436 FWL_ERR CFWL_ComboBoxImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1437 const CFX_Matrix* pMatrix) {
1438 return m_pOwner->DrawWidget(pGraphics, pMatrix);
1439 }
OnFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)1440 void CFWL_ComboBoxImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
1441 FX_BOOL bSet) {
1442 IFWL_Target* pDstTarget = pMsg->m_pDstTarget;
1443 IFWL_Target* pSrcTarget = pMsg->m_pSrcTarget;
1444 FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
1445 if (bSet) {
1446 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
1447 if (bDropDown && pSrcTarget != m_pOwner->m_pListBox.get()) {
1448 if (!m_pOwner->m_pEdit)
1449 return;
1450 static_cast<CFWL_ComboEditImp*>(m_pOwner->m_pEdit->GetImpl())
1451 ->SetSelected();
1452 } else {
1453 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1454 }
1455 } else {
1456 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
1457 if (bDropDown && pDstTarget != m_pOwner->m_pListBox.get()) {
1458 if (!m_pOwner->m_pEdit)
1459 return;
1460 static_cast<CFWL_ComboEditImp*>(m_pOwner->m_pEdit->GetImpl())
1461 ->FlagFocus(FALSE);
1462 static_cast<CFWL_ComboEditImp*>(m_pOwner->m_pEdit->GetImpl())
1463 ->ClearSelected();
1464 } else {
1465 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1466 }
1467 }
1468 }
OnLButtonDown(CFWL_MsgMouse * pMsg)1469 void CFWL_ComboBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
1470 if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
1471 return;
1472 }
1473 FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
1474 CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
1475 FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
1476 if (bClickBtn) {
1477 if (bDropDown && m_pOwner->m_pEdit) {
1478 m_pOwner->MatchEditText();
1479 }
1480 m_pOwner->m_bLButtonDown = TRUE;
1481 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Pressed;
1482 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1483 m_pOwner->ShowDropList(TRUE);
1484 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1485 m_pOwner->Repaint(&m_pOwner->m_rtClient);
1486 }
1487 }
OnLButtonUp(CFWL_MsgMouse * pMsg)1488 void CFWL_ComboBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1489 m_pOwner->m_bLButtonDown = FALSE;
1490 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
1491 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Hovered;
1492 } else {
1493 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1494 }
1495 m_pOwner->Repaint(&m_pOwner->m_rtBtn);
1496 }
OnMouseMove(CFWL_MsgMouse * pMsg)1497 void CFWL_ComboBoxImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
1498 int32_t iOldState = m_pOwner->m_iBtnState;
1499 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
1500 m_pOwner->m_iBtnState = m_pOwner->m_bLButtonDown
1501 ? FWL_PARTSTATE_CMB_Pressed
1502 : FWL_PARTSTATE_CMB_Hovered;
1503 } else {
1504 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1505 }
1506 if ((iOldState != m_pOwner->m_iBtnState) &&
1507 !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ==
1508 FWL_WGTSTATE_Disabled)) {
1509 m_pOwner->Repaint(&m_pOwner->m_rtBtn);
1510 }
1511 }
OnMouseLeave(CFWL_MsgMouse * pMsg)1512 void CFWL_ComboBoxImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
1513 if (!m_pOwner->IsDropListShowed() &&
1514 !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ==
1515 FWL_WGTSTATE_Disabled)) {
1516 m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
1517 m_pOwner->Repaint(&m_pOwner->m_rtBtn);
1518 }
1519 }
OnKey(CFWL_MsgKey * pMsg)1520 void CFWL_ComboBoxImpDelegate::OnKey(CFWL_MsgKey* pMsg) {
1521 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
1522 if (dwKeyCode == FWL_VKEY_Tab) {
1523 m_pOwner->DispatchKeyEvent(pMsg);
1524 return;
1525 }
1526 FX_BOOL bSubCtrlKey = pMsg->m_pDstTarget == m_pOwner->m_pInterface;
1527 if (bSubCtrlKey) {
1528 DoSubCtrlKey(pMsg);
1529 }
1530 }
DoSubCtrlKey(CFWL_MsgKey * pMsg)1531 void CFWL_ComboBoxImpDelegate::DoSubCtrlKey(CFWL_MsgKey* pMsg) {
1532 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
1533 FX_BOOL bUp = dwKeyCode == FWL_VKEY_Up;
1534 FX_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 }
DisForm_OnProcessMessage(CFWL_Message * pMessage)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 }
DisForm_OnLButtonDown(CFWL_MsgMouse * pMsg)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 }
DisForm_OnFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)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 }
DisForm_OnKey(CFWL_MsgKey * pMsg)1682 void CFWL_ComboBoxImpDelegate::DisForm_OnKey(CFWL_MsgKey* pMsg) {
1683 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
1684 FX_BOOL bUp = dwKeyCode == FWL_VKEY_Up;
1685 FX_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 }
CFWL_ComboProxyImpDelegate(IFWL_Form * pForm,CFWL_ComboBoxImp * pComboBox)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 }
OnProcessMessage(CFWL_Message * pMessage)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 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)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 }
OnLButtonDown(CFWL_MsgMouse * pMsg)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 return;
1790 }
1791 IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
1792 IFWL_AdapterCursorMgr* pCursorMgr = pNative->GetCursorMgr();
1793 FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
1794 pCursorMgr->SetCursor(hCursor);
1795 pCursorMgr->ShowCursor(TRUE);
1796 m_pForm->TransformTo(NULL, pMsg->m_fx, pMsg->m_fy);
1797 m_fStartPos = pMsg->m_fy;
1798 }
OnLButtonUp(CFWL_MsgMouse * pMsg)1799 void CFWL_ComboProxyImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1800 m_bLButtonDown = FALSE;
1801 IFWL_NoteThread* pThread = m_pForm->GetOwnerThread();
1802 if (!pThread)
1803 return;
1804 CFWL_NoteDriver* pDriver =
1805 static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
1806 pDriver->SetGrab(m_pForm, FALSE);
1807 if (m_bLButtonUpSelf) {
1808 CFX_RectF rect;
1809 m_pForm->GetWidgetRect(rect);
1810 rect.left = rect.top = 0;
1811 if (!rect.Contains(pMsg->m_fx, pMsg->m_fy) &&
1812 m_pComboBox->IsDropListShowed()) {
1813 m_pComboBox->ShowDropList(FALSE);
1814 }
1815 } else {
1816 m_bLButtonUpSelf = TRUE;
1817 }
1818 }
OnMouseMove(CFWL_MsgMouse * pMsg)1819 void CFWL_ComboProxyImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
1820 IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
1821 IFWL_AdapterCursorMgr* pCursorMgr = pNative->GetCursorMgr();
1822 FWL_CURSORTYPE cursorType = FWL_CURSORTYPE_Arrow;
1823 if (m_pComboBox->m_rtHandler.Contains(pMsg->m_fx, pMsg->m_fy)) {
1824 cursorType = FWL_CURSORTYPE_SizeNS;
1825 }
1826 FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(cursorType);
1827 pCursorMgr->SetCursor(hCursor);
1828 pCursorMgr->ShowCursor(TRUE);
1829 if (!m_bLButtonDown) {
1830 return;
1831 }
1832 m_pForm->TransformTo(NULL, pMsg->m_fx, pMsg->m_fy);
1833 FX_FLOAT fChanged = pMsg->m_fy - m_fStartPos;
1834 if (m_pComboBox->m_bUpFormHandler) {
1835 fChanged = m_fStartPos - pMsg->m_fy;
1836 }
1837 if (m_pComboBox->m_rtList.height + fChanged < m_pComboBox->m_fItemHeight) {
1838 return;
1839 }
1840 m_pComboBox->m_rtList.height += fChanged;
1841 m_pComboBox->m_rtProxy.height += fChanged;
1842 if (m_pComboBox->m_bUpFormHandler) {
1843 m_pComboBox->m_rtProxy.top -= fChanged;
1844 m_pComboBox->m_rtHandler.Set(0, 0, m_pComboBox->m_rtList.width,
1845 m_pComboBox->m_fComboFormHandler);
1846 } else {
1847 m_pComboBox->m_rtHandler.Set(0, m_pComboBox->m_rtList.height,
1848 m_pComboBox->m_rtList.width,
1849 m_pComboBox->m_fComboFormHandler);
1850 }
1851 m_pForm->SetWidgetRect(m_pComboBox->m_rtProxy);
1852 m_pComboBox->m_pListBox->SetWidgetRect(m_pComboBox->m_rtList);
1853 m_pComboBox->m_pListBox->Update();
1854 m_fStartPos = pMsg->m_fy;
1855 }
OnDeactive(CFWL_MsgDeactivate * pMsg)1856 void CFWL_ComboProxyImpDelegate::OnDeactive(CFWL_MsgDeactivate* pMsg) {
1857 m_pComboBox->ShowDropList(FALSE);
1858 }
OnFocusChanged(CFWL_MsgKillFocus * pMsg,FX_BOOL bSet)1859 void CFWL_ComboProxyImpDelegate::OnFocusChanged(CFWL_MsgKillFocus* pMsg,
1860 FX_BOOL bSet) {
1861 if (!bSet) {
1862 if (pMsg->m_pSetFocus == NULL) {
1863 m_pComboBox->ShowDropList(FALSE);
1864 }
1865 }
1866 }
1867