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