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

Side by Side Diff: xfa/fwl/core/cfwl_listbox.cpp

Issue 2559173002: Move xfa/fwl/core to xfa/fwl. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fwl/core/cfwl_listbox.h ('k') | xfa/fwl/core/cfwl_listitem.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fwl/core/cfwl_listbox.h"
8
9 #include <algorithm>
10 #include <memory>
11 #include <utility>
12
13 #include "third_party/base/ptr_util.h"
14 #include "third_party/base/stl_util.h"
15 #include "xfa/fde/tto/fde_textout.h"
16 #include "xfa/fwl/core/cfwl_app.h"
17 #include "xfa/fwl/core/cfwl_msgkey.h"
18 #include "xfa/fwl/core/cfwl_msgmouse.h"
19 #include "xfa/fwl/core/cfwl_msgmousewheel.h"
20 #include "xfa/fwl/core/cfwl_themebackground.h"
21 #include "xfa/fwl/core/cfwl_themepart.h"
22 #include "xfa/fwl/core/cfwl_themetext.h"
23 #include "xfa/fwl/core/ifwl_themeprovider.h"
24
25 namespace {
26
27 const int kItemTextMargin = 2;
28
29 } // namespace
30
31 CFWL_ListBox::CFWL_ListBox(const CFWL_App* app,
32 std::unique_ptr<CFWL_WidgetProperties> properties,
33 CFWL_Widget* pOuter)
34 : CFWL_Widget(app, std::move(properties), pOuter),
35 m_dwTTOStyles(0),
36 m_iTTOAligns(0),
37 m_hAnchor(nullptr),
38 m_fScorllBarWidth(0),
39 m_bLButtonDown(false),
40 m_pScrollBarTP(nullptr) {
41 m_rtClient.Reset();
42 m_rtConent.Reset();
43 m_rtStatic.Reset();
44 }
45
46 CFWL_ListBox::~CFWL_ListBox() {}
47
48 FWL_Type CFWL_ListBox::GetClassID() const {
49 return FWL_Type::ListBox;
50 }
51
52 void CFWL_ListBox::Update() {
53 if (IsLocked())
54 return;
55 if (!m_pProperties->m_pThemeProvider)
56 m_pProperties->m_pThemeProvider = GetAvailableTheme();
57
58 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_AlignMask) {
59 case FWL_STYLEEXT_LTB_LeftAlign: {
60 m_iTTOAligns = FDE_TTOALIGNMENT_CenterLeft;
61 break;
62 }
63 case FWL_STYLEEXT_LTB_RightAlign: {
64 m_iTTOAligns = FDE_TTOALIGNMENT_CenterRight;
65 break;
66 }
67 case FWL_STYLEEXT_LTB_CenterAlign:
68 default: {
69 m_iTTOAligns = FDE_TTOALIGNMENT_Center;
70 break;
71 }
72 }
73 if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading)
74 m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
75
76 m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine;
77 m_fScorllBarWidth = GetScrollWidth();
78 CalcSize(false);
79 }
80
81 FWL_WidgetHit CFWL_ListBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
82 if (IsShowScrollBar(false)) {
83 CFX_RectF rect = m_pHorzScrollBar->GetWidgetRect();
84 if (rect.Contains(fx, fy))
85 return FWL_WidgetHit::HScrollBar;
86 }
87 if (IsShowScrollBar(true)) {
88 CFX_RectF rect = m_pVertScrollBar->GetWidgetRect();
89 if (rect.Contains(fx, fy))
90 return FWL_WidgetHit::VScrollBar;
91 }
92 if (m_rtClient.Contains(fx, fy))
93 return FWL_WidgetHit::Client;
94 return FWL_WidgetHit::Unknown;
95 }
96
97 void CFWL_ListBox::DrawWidget(CFX_Graphics* pGraphics,
98 const CFX_Matrix* pMatrix) {
99 if (!pGraphics)
100 return;
101 if (!m_pProperties->m_pThemeProvider)
102 return;
103
104 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
105 pGraphics->SaveGraphState();
106 if (HasBorder())
107 DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
108 if (HasEdge())
109 DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
110
111 CFX_RectF rtClip(m_rtConent);
112 if (IsShowScrollBar(false))
113 rtClip.height -= m_fScorllBarWidth;
114 if (IsShowScrollBar(true))
115 rtClip.width -= m_fScorllBarWidth;
116 if (pMatrix)
117 pMatrix->TransformRect(rtClip);
118
119 pGraphics->SetClipRect(rtClip);
120 if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_NoBackground) == 0)
121 DrawBkground(pGraphics, pTheme, pMatrix);
122
123 DrawItems(pGraphics, pTheme, pMatrix);
124 pGraphics->RestoreGraphState();
125 }
126
127 void CFWL_ListBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
128 if (pThemeProvider)
129 m_pProperties->m_pThemeProvider = pThemeProvider;
130 }
131
132 int32_t CFWL_ListBox::CountSelItems() {
133 int32_t iRet = 0;
134 int32_t iCount = CountItems(this);
135 for (int32_t i = 0; i < iCount; i++) {
136 CFWL_ListItem* pItem = GetItem(this, i);
137 if (!pItem)
138 continue;
139
140 uint32_t dwStyle = GetItemStyles(this, pItem);
141 if (dwStyle & FWL_ITEMSTATE_LTB_Selected)
142 iRet++;
143 }
144 return iRet;
145 }
146
147 CFWL_ListItem* CFWL_ListBox::GetSelItem(int32_t nIndexSel) {
148 int32_t idx = GetSelIndex(nIndexSel);
149 if (idx < 0)
150 return nullptr;
151 return GetItem(this, idx);
152 }
153
154 int32_t CFWL_ListBox::GetSelIndex(int32_t nIndex) {
155 int32_t index = 0;
156 int32_t iCount = CountItems(this);
157 for (int32_t i = 0; i < iCount; i++) {
158 CFWL_ListItem* pItem = GetItem(this, i);
159 if (!pItem)
160 return -1;
161
162 uint32_t dwStyle = GetItemStyles(this, pItem);
163 if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
164 if (index == nIndex)
165 return i;
166 index++;
167 }
168 }
169 return -1;
170 }
171
172 void CFWL_ListBox::SetSelItem(CFWL_ListItem* pItem, bool bSelect) {
173 if (!pItem) {
174 if (bSelect) {
175 SelectAll();
176 } else {
177 ClearSelection();
178 SetFocusItem(nullptr);
179 }
180 return;
181 }
182 if (IsMultiSelection())
183 SetSelectionDirect(pItem, bSelect);
184 else
185 SetSelection(pItem, pItem, bSelect);
186 }
187
188 CFX_WideString CFWL_ListBox::GetDataProviderItemText(CFWL_ListItem* pItem) {
189 if (!pItem)
190 return L"";
191 return GetItemText(this, pItem);
192 }
193
194 CFWL_ListItem* CFWL_ListBox::GetListItem(CFWL_ListItem* pItem,
195 uint32_t dwKeyCode) {
196 CFWL_ListItem* hRet = nullptr;
197 switch (dwKeyCode) {
198 case FWL_VKEY_Up:
199 case FWL_VKEY_Down:
200 case FWL_VKEY_Home:
201 case FWL_VKEY_End: {
202 const bool bUp = dwKeyCode == FWL_VKEY_Up;
203 const bool bDown = dwKeyCode == FWL_VKEY_Down;
204 const bool bHome = dwKeyCode == FWL_VKEY_Home;
205 int32_t iDstItem = -1;
206 if (bUp || bDown) {
207 int32_t index = GetItemIndex(this, pItem);
208 iDstItem = dwKeyCode == FWL_VKEY_Up ? index - 1 : index + 1;
209 } else if (bHome) {
210 iDstItem = 0;
211 } else {
212 int32_t iCount = CountItems(this);
213 iDstItem = iCount - 1;
214 }
215 hRet = GetItem(this, iDstItem);
216 break;
217 }
218 default:
219 break;
220 }
221 return hRet;
222 }
223
224 void CFWL_ListBox::SetSelection(CFWL_ListItem* hStart,
225 CFWL_ListItem* hEnd,
226 bool bSelected) {
227 int32_t iStart = GetItemIndex(this, hStart);
228 int32_t iEnd = GetItemIndex(this, hEnd);
229 if (iStart > iEnd) {
230 int32_t iTemp = iStart;
231 iStart = iEnd;
232 iEnd = iTemp;
233 }
234 if (bSelected) {
235 int32_t iCount = CountItems(this);
236 for (int32_t i = 0; i < iCount; i++) {
237 CFWL_ListItem* pItem = GetItem(this, i);
238 SetSelectionDirect(pItem, false);
239 }
240 }
241 for (; iStart <= iEnd; iStart++) {
242 CFWL_ListItem* pItem = GetItem(this, iStart);
243 SetSelectionDirect(pItem, bSelected);
244 }
245 }
246
247 void CFWL_ListBox::SetSelectionDirect(CFWL_ListItem* pItem, bool bSelect) {
248 uint32_t dwOldStyle = GetItemStyles(this, pItem);
249 bSelect ? dwOldStyle |= FWL_ITEMSTATE_LTB_Selected
250 : dwOldStyle &= ~FWL_ITEMSTATE_LTB_Selected;
251 SetItemStyles(this, pItem, dwOldStyle);
252 }
253
254 bool CFWL_ListBox::IsMultiSelection() const {
255 return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection;
256 }
257
258 bool CFWL_ListBox::IsItemSelected(CFWL_ListItem* pItem) {
259 uint32_t dwState = GetItemStyles(this, pItem);
260 return (dwState & FWL_ITEMSTATE_LTB_Selected) != 0;
261 }
262
263 void CFWL_ListBox::ClearSelection() {
264 bool bMulti = IsMultiSelection();
265 int32_t iCount = CountItems(this);
266 for (int32_t i = 0; i < iCount; i++) {
267 CFWL_ListItem* pItem = GetItem(this, i);
268 uint32_t dwState = GetItemStyles(this, pItem);
269 if (!(dwState & FWL_ITEMSTATE_LTB_Selected))
270 continue;
271 SetSelectionDirect(pItem, false);
272 if (!bMulti)
273 return;
274 }
275 }
276
277 void CFWL_ListBox::SelectAll() {
278 if (!IsMultiSelection())
279 return;
280
281 int32_t iCount = CountItems(this);
282 if (iCount <= 0)
283 return;
284
285 CFWL_ListItem* pItemStart = GetItem(this, 0);
286 CFWL_ListItem* pItemEnd = GetItem(this, iCount - 1);
287 SetSelection(pItemStart, pItemEnd, false);
288 }
289
290 CFWL_ListItem* CFWL_ListBox::GetFocusedItem() {
291 int32_t iCount = CountItems(this);
292 for (int32_t i = 0; i < iCount; i++) {
293 CFWL_ListItem* pItem = GetItem(this, i);
294 if (!pItem)
295 return nullptr;
296 if (GetItemStyles(this, pItem) & FWL_ITEMSTATE_LTB_Focused)
297 return pItem;
298 }
299 return nullptr;
300 }
301
302 void CFWL_ListBox::SetFocusItem(CFWL_ListItem* pItem) {
303 CFWL_ListItem* hFocus = GetFocusedItem();
304 if (pItem == hFocus)
305 return;
306
307 if (hFocus) {
308 uint32_t dwStyle = GetItemStyles(this, hFocus);
309 dwStyle &= ~FWL_ITEMSTATE_LTB_Focused;
310 SetItemStyles(this, hFocus, dwStyle);
311 }
312 if (pItem) {
313 uint32_t dwStyle = GetItemStyles(this, pItem);
314 dwStyle |= FWL_ITEMSTATE_LTB_Focused;
315 SetItemStyles(this, pItem, dwStyle);
316 }
317 }
318
319 CFWL_ListItem* CFWL_ListBox::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
320 fx -= m_rtConent.left, fy -= m_rtConent.top;
321 FX_FLOAT fPosX = 0.0f;
322 if (m_pHorzScrollBar)
323 fPosX = m_pHorzScrollBar->GetPos();
324
325 FX_FLOAT fPosY = 0.0;
326 if (m_pVertScrollBar)
327 fPosY = m_pVertScrollBar->GetPos();
328
329 int32_t nCount = CountItems(this);
330 for (int32_t i = 0; i < nCount; i++) {
331 CFWL_ListItem* pItem = GetItem(this, i);
332 if (!pItem)
333 continue;
334
335 CFX_RectF rtItem;
336 GetItemRect(this, pItem, rtItem);
337 rtItem.Offset(-fPosX, -fPosY);
338 if (rtItem.Contains(fx, fy))
339 return pItem;
340 }
341 return nullptr;
342 }
343
344 bool CFWL_ListBox::GetItemCheckRectInternal(CFWL_ListItem* pItem,
345 CFX_RectF& rtCheck) {
346 if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check))
347 return false;
348 GetItemCheckRect(this, pItem, rtCheck);
349 return true;
350 }
351
352 bool CFWL_ListBox::GetItemChecked(CFWL_ListItem* pItem) {
353 if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check))
354 return false;
355 return !!(GetItemCheckState(this, pItem) & FWL_ITEMSTATE_LTB_Checked);
356 }
357
358 bool CFWL_ListBox::SetItemChecked(CFWL_ListItem* pItem, bool bChecked) {
359 if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check))
360 return false;
361
362 SetItemCheckState(this, pItem, bChecked ? FWL_ITEMSTATE_LTB_Checked : 0);
363 return true;
364 }
365
366 bool CFWL_ListBox::ScrollToVisible(CFWL_ListItem* pItem) {
367 if (!m_pVertScrollBar)
368 return false;
369
370 CFX_RectF rtItem;
371 GetItemRect(this, pItem, rtItem);
372
373 bool bScroll = false;
374 FX_FLOAT fPosY = m_pVertScrollBar->GetPos();
375 rtItem.Offset(0, -fPosY + m_rtConent.top);
376 if (rtItem.top < m_rtConent.top) {
377 fPosY += rtItem.top - m_rtConent.top;
378 bScroll = true;
379 } else if (rtItem.bottom() > m_rtConent.bottom()) {
380 fPosY += rtItem.bottom() - m_rtConent.bottom();
381 bScroll = true;
382 }
383 if (!bScroll)
384 return false;
385
386 m_pVertScrollBar->SetPos(fPosY);
387 m_pVertScrollBar->SetTrackPos(fPosY);
388 Repaint(&m_rtClient);
389 return true;
390 }
391
392 void CFWL_ListBox::DrawBkground(CFX_Graphics* pGraphics,
393 IFWL_ThemeProvider* pTheme,
394 const CFX_Matrix* pMatrix) {
395 if (!pGraphics)
396 return;
397 if (!pTheme)
398 return;
399
400 CFWL_ThemeBackground param;
401 param.m_pWidget = this;
402 param.m_iPart = CFWL_Part::Background;
403 param.m_dwStates = 0;
404 param.m_pGraphics = pGraphics;
405 param.m_matrix.Concat(*pMatrix);
406 param.m_rtPart = m_rtClient;
407 if (IsShowScrollBar(false) && IsShowScrollBar(true))
408 param.m_pData = &m_rtStatic;
409 if (!IsEnabled())
410 param.m_dwStates = CFWL_PartState_Disabled;
411
412 pTheme->DrawBackground(&param);
413 }
414
415 void CFWL_ListBox::DrawItems(CFX_Graphics* pGraphics,
416 IFWL_ThemeProvider* pTheme,
417 const CFX_Matrix* pMatrix) {
418 FX_FLOAT fPosX = 0.0f;
419 if (m_pHorzScrollBar)
420 fPosX = m_pHorzScrollBar->GetPos();
421
422 FX_FLOAT fPosY = 0.0f;
423 if (m_pVertScrollBar)
424 fPosY = m_pVertScrollBar->GetPos();
425
426 CFX_RectF rtView(m_rtConent);
427 if (m_pHorzScrollBar)
428 rtView.height -= m_fScorllBarWidth;
429 if (m_pVertScrollBar)
430 rtView.width -= m_fScorllBarWidth;
431
432 bool bMultiCol =
433 !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn);
434 int32_t iCount = CountItems(this);
435 for (int32_t i = 0; i < iCount; i++) {
436 CFWL_ListItem* pItem = GetItem(this, i);
437 if (!pItem)
438 continue;
439
440 CFX_RectF rtItem;
441 GetItemRect(this, pItem, rtItem);
442 rtItem.Offset(m_rtConent.left - fPosX, m_rtConent.top - fPosY);
443 if (rtItem.bottom() < m_rtConent.top)
444 continue;
445 if (rtItem.top >= m_rtConent.bottom())
446 break;
447 if (bMultiCol && rtItem.left > m_rtConent.right())
448 break;
449
450 if (!(GetStylesEx() & FWL_STYLEEXT_LTB_OwnerDraw))
451 DrawItem(pGraphics, pTheme, pItem, i, rtItem, pMatrix);
452 }
453 }
454
455 void CFWL_ListBox::DrawItem(CFX_Graphics* pGraphics,
456 IFWL_ThemeProvider* pTheme,
457 CFWL_ListItem* pItem,
458 int32_t Index,
459 const CFX_RectF& rtItem,
460 const CFX_Matrix* pMatrix) {
461 uint32_t dwItemStyles = GetItemStyles(this, pItem);
462 uint32_t dwPartStates = CFWL_PartState_Normal;
463 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
464 dwPartStates = CFWL_PartState_Disabled;
465 else if (dwItemStyles & FWL_ITEMSTATE_LTB_Selected)
466 dwPartStates = CFWL_PartState_Selected;
467
468 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused &&
469 dwItemStyles & FWL_ITEMSTATE_LTB_Focused) {
470 dwPartStates |= CFWL_PartState_Focused;
471 }
472
473 CFWL_ThemeBackground bg_param;
474 bg_param.m_pWidget = this;
475 bg_param.m_iPart = CFWL_Part::ListItem;
476 bg_param.m_dwStates = dwPartStates;
477 bg_param.m_pGraphics = pGraphics;
478 bg_param.m_matrix.Concat(*pMatrix);
479 bg_param.m_rtPart = rtItem;
480 bg_param.m_bMaximize = true;
481 CFX_RectF rtFocus(rtItem);
482 bg_param.m_pData = &rtFocus;
483 if (m_pVertScrollBar && !m_pHorzScrollBar &&
484 (dwPartStates & CFWL_PartState_Focused)) {
485 bg_param.m_rtPart.left += 1;
486 bg_param.m_rtPart.width -= (m_fScorllBarWidth + 1);
487 rtFocus.Deflate(0.5, 0.5, 1 + m_fScorllBarWidth, 1);
488 }
489 pTheme->DrawBackground(&bg_param);
490
491 bool bHasIcon = !!(GetStylesEx() & FWL_STYLEEXT_LTB_Icon);
492 if (bHasIcon) {
493 CFX_RectF rtDIB;
494 CFX_DIBitmap* pDib = GetItemIcon(this, pItem);
495 rtDIB.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height);
496 if (pDib) {
497 CFWL_ThemeBackground param;
498 param.m_pWidget = this;
499 param.m_iPart = CFWL_Part::Icon;
500 param.m_pGraphics = pGraphics;
501 param.m_matrix.Concat(*pMatrix);
502 param.m_rtPart = rtDIB;
503 param.m_bMaximize = true;
504 param.m_pImage = pDib;
505 pTheme->DrawBackground(&param);
506 }
507 }
508
509 bool bHasCheck = !!(GetStylesEx() & FWL_STYLEEXT_LTB_Check);
510 if (bHasCheck) {
511 CFX_RectF rtCheck;
512 rtCheck.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height);
513 rtCheck.Deflate(2, 2, 2, 2);
514 SetItemCheckRect(this, pItem, rtCheck);
515 CFWL_ThemeBackground param;
516 param.m_pWidget = this;
517 param.m_iPart = CFWL_Part::Check;
518 param.m_pGraphics = pGraphics;
519 if (GetItemChecked(pItem))
520 param.m_dwStates = CFWL_PartState_Checked;
521 else
522 param.m_dwStates = CFWL_PartState_Normal;
523 param.m_matrix.Concat(*pMatrix);
524 param.m_rtPart = rtCheck;
525 param.m_bMaximize = true;
526 pTheme->DrawBackground(&param);
527 }
528
529 CFX_WideString wsText = GetItemText(this, pItem);
530 if (wsText.GetLength() <= 0)
531 return;
532
533 CFX_RectF rtText(rtItem);
534 rtText.Deflate(kItemTextMargin, kItemTextMargin);
535 if (bHasIcon || bHasCheck)
536 rtText.Deflate(rtItem.height, 0, 0, 0);
537
538 CFWL_ThemeText textParam;
539 textParam.m_pWidget = this;
540 textParam.m_iPart = CFWL_Part::ListItem;
541 textParam.m_dwStates = dwPartStates;
542 textParam.m_pGraphics = pGraphics;
543 textParam.m_matrix.Concat(*pMatrix);
544 textParam.m_rtPart = rtText;
545 textParam.m_wsText = wsText;
546 textParam.m_dwTTOStyles = m_dwTTOStyles;
547 textParam.m_iTTOAlign = m_iTTOAligns;
548 textParam.m_bMaximize = true;
549 pTheme->DrawText(&textParam);
550 }
551
552 CFX_SizeF CFWL_ListBox::CalcSize(bool bAutoSize) {
553 CFX_SizeF fs;
554 if (!m_pProperties->m_pThemeProvider)
555 return fs;
556
557 GetClientRect(m_rtClient);
558 m_rtConent = m_rtClient;
559 CFX_RectF rtUIMargin;
560 rtUIMargin.Set(0, 0, 0, 0);
561 if (!m_pOuter) {
562 CFX_RectF* pUIMargin = static_cast<CFX_RectF*>(
563 GetThemeCapacity(CFWL_WidgetCapacity::UIMargin));
564 if (pUIMargin) {
565 m_rtConent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
566 pUIMargin->height);
567 }
568 }
569
570 FX_FLOAT fWidth = GetMaxTextWidth();
571 fWidth += 2 * kItemTextMargin;
572 if (!bAutoSize) {
573 FX_FLOAT fActualWidth =
574 m_rtClient.width - rtUIMargin.left - rtUIMargin.width;
575 fWidth = std::max(fWidth, fActualWidth);
576 }
577
578 m_fItemHeight = CalcItemHeight();
579 if ((GetStylesEx() & FWL_STYLEEXT_LTB_Icon))
580 fWidth += m_fItemHeight;
581
582 int32_t iCount = CountItems(this);
583 for (int32_t i = 0; i < iCount; i++) {
584 CFWL_ListItem* htem = GetItem(this, i);
585 GetItemSize(fs, htem, fWidth, m_fItemHeight, bAutoSize);
586 }
587 if (bAutoSize)
588 return fs;
589
590 FX_FLOAT iWidth = m_rtClient.width - rtUIMargin.left - rtUIMargin.width;
591 FX_FLOAT iHeight = m_rtClient.height;
592 bool bShowVertScr =
593 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) &&
594 (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll);
595 bool bShowHorzScr =
596 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) &&
597 (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll);
598 if (!bShowVertScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll &&
599 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) == 0) {
600 bShowVertScr = (fs.y > iHeight);
601 }
602 if (!bShowHorzScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll)
603 bShowHorzScr = (fs.x > iWidth);
604
605 CFX_SizeF szRange;
606 if (bShowVertScr) {
607 if (!m_pVertScrollBar)
608 InitVerticalScrollBar();
609
610 CFX_RectF rtScrollBar;
611 rtScrollBar.Set(m_rtClient.right() - m_fScorllBarWidth, m_rtClient.top,
612 m_fScorllBarWidth, m_rtClient.height - 1);
613 if (bShowHorzScr)
614 rtScrollBar.height -= m_fScorllBarWidth;
615
616 m_pVertScrollBar->SetWidgetRect(rtScrollBar);
617 szRange.x = 0, szRange.y = fs.y - m_rtConent.height;
618 szRange.y = std::max(szRange.y, m_fItemHeight);
619
620 m_pVertScrollBar->SetRange(szRange.x, szRange.y);
621 m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10);
622 m_pVertScrollBar->SetStepSize(m_fItemHeight);
623
624 FX_FLOAT fPos =
625 std::min(std::max(m_pVertScrollBar->GetPos(), 0.f), szRange.y);
626 m_pVertScrollBar->SetPos(fPos);
627 m_pVertScrollBar->SetTrackPos(fPos);
628 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) ==
629 0 ||
630 (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) {
631 m_pVertScrollBar->RemoveStates(FWL_WGTSTATE_Invisible);
632 }
633 m_pVertScrollBar->Update();
634 } else if (m_pVertScrollBar) {
635 m_pVertScrollBar->SetPos(0);
636 m_pVertScrollBar->SetTrackPos(0);
637 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible);
638 }
639 if (bShowHorzScr) {
640 if (!m_pHorzScrollBar)
641 InitHorizontalScrollBar();
642
643 CFX_RectF rtScrollBar;
644 rtScrollBar.Set(m_rtClient.left, m_rtClient.bottom() - m_fScorllBarWidth,
645 m_rtClient.width, m_fScorllBarWidth);
646 if (bShowVertScr)
647 rtScrollBar.width -= m_fScorllBarWidth;
648
649 m_pHorzScrollBar->SetWidgetRect(rtScrollBar);
650 szRange.x = 0, szRange.y = fs.x - rtScrollBar.width;
651 m_pHorzScrollBar->SetRange(szRange.x, szRange.y);
652 m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10);
653 m_pHorzScrollBar->SetStepSize(fWidth / 10);
654
655 FX_FLOAT fPos =
656 std::min(std::max(m_pHorzScrollBar->GetPos(), 0.f), szRange.y);
657 m_pHorzScrollBar->SetPos(fPos);
658 m_pHorzScrollBar->SetTrackPos(fPos);
659 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) ==
660 0 ||
661 (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) {
662 m_pHorzScrollBar->RemoveStates(FWL_WGTSTATE_Invisible);
663 }
664 m_pHorzScrollBar->Update();
665 } else if (m_pHorzScrollBar) {
666 m_pHorzScrollBar->SetPos(0);
667 m_pHorzScrollBar->SetTrackPos(0);
668 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible);
669 }
670 if (bShowVertScr && bShowHorzScr) {
671 m_rtStatic.Set(m_rtClient.right() - m_fScorllBarWidth,
672 m_rtClient.bottom() - m_fScorllBarWidth, m_fScorllBarWidth,
673 m_fScorllBarWidth);
674 }
675 return fs;
676 }
677
678 void CFWL_ListBox::GetItemSize(CFX_SizeF& size,
679 CFWL_ListItem* pItem,
680 FX_FLOAT fWidth,
681 FX_FLOAT fItemHeight,
682 bool bAutoSize) {
683 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn)
684 return;
685
686 if (!bAutoSize) {
687 CFX_RectF rtItem;
688 rtItem.Set(0, size.y, fWidth, fItemHeight);
689 SetItemRect(this, pItem, rtItem);
690 }
691 size.x = fWidth;
692 size.y += fItemHeight;
693 }
694
695 FX_FLOAT CFWL_ListBox::GetMaxTextWidth() {
696 FX_FLOAT fRet = 0.0f;
697 int32_t iCount = CountItems(this);
698 for (int32_t i = 0; i < iCount; i++) {
699 CFWL_ListItem* pItem = GetItem(this, i);
700 if (!pItem)
701 continue;
702
703 CFX_WideString wsText = GetItemText(this, pItem);
704 CFX_SizeF sz = CalcTextSize(wsText, m_pProperties->m_pThemeProvider, false);
705 fRet = std::max(fRet, sz.x);
706 }
707 return fRet;
708 }
709
710 FX_FLOAT CFWL_ListBox::GetScrollWidth() {
711 FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
712 GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth));
713 if (!pfWidth)
714 return 0;
715 return *pfWidth;
716 }
717
718 FX_FLOAT CFWL_ListBox::CalcItemHeight() {
719 FX_FLOAT* pfFont =
720 static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::FontSize));
721 if (!pfFont)
722 return 20;
723 return *pfFont + 2 * kItemTextMargin;
724 }
725
726 void CFWL_ListBox::InitVerticalScrollBar() {
727 if (m_pVertScrollBar)
728 return;
729
730 auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>();
731 prop->m_dwStyleExes = FWL_STYLEEXT_SCB_Vert;
732 prop->m_dwStates = FWL_WGTSTATE_Invisible;
733 prop->m_pParent = this;
734 prop->m_pThemeProvider = m_pScrollBarTP;
735 m_pVertScrollBar =
736 pdfium::MakeUnique<CFWL_ScrollBar>(m_pOwnerApp, std::move(prop), this);
737 }
738
739 void CFWL_ListBox::InitHorizontalScrollBar() {
740 if (m_pHorzScrollBar)
741 return;
742
743 auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>();
744 prop->m_dwStyleExes = FWL_STYLEEXT_SCB_Horz;
745 prop->m_dwStates = FWL_WGTSTATE_Invisible;
746 prop->m_pParent = this;
747 prop->m_pThemeProvider = m_pScrollBarTP;
748 m_pHorzScrollBar =
749 pdfium::MakeUnique<CFWL_ScrollBar>(m_pOwnerApp, std::move(prop), this);
750 }
751
752 bool CFWL_ListBox::IsShowScrollBar(bool bVert) {
753 CFWL_ScrollBar* pScrollbar =
754 bVert ? m_pVertScrollBar.get() : m_pHorzScrollBar.get();
755 if (!pScrollbar || (pScrollbar->GetStates() & FWL_WGTSTATE_Invisible))
756 return false;
757 return !(m_pProperties->m_dwStyleExes &
758 FWL_STYLEEXT_LTB_ShowScrollBarFocus) ||
759 (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);
760 }
761
762 void CFWL_ListBox::OnProcessMessage(CFWL_Message* pMessage) {
763 if (!pMessage)
764 return;
765 if (!IsEnabled())
766 return;
767
768 switch (pMessage->GetType()) {
769 case CFWL_Message::Type::SetFocus:
770 OnFocusChanged(pMessage, true);
771 break;
772 case CFWL_Message::Type::KillFocus:
773 OnFocusChanged(pMessage, false);
774 break;
775 case CFWL_Message::Type::Mouse: {
776 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
777 switch (pMsg->m_dwCmd) {
778 case FWL_MouseCommand::LeftButtonDown:
779 OnLButtonDown(pMsg);
780 break;
781 case FWL_MouseCommand::LeftButtonUp:
782 OnLButtonUp(pMsg);
783 break;
784 default:
785 break;
786 }
787 break;
788 }
789 case CFWL_Message::Type::MouseWheel:
790 OnMouseWheel(static_cast<CFWL_MsgMouseWheel*>(pMessage));
791 break;
792 case CFWL_Message::Type::Key: {
793 CFWL_MsgKey* pMsg = static_cast<CFWL_MsgKey*>(pMessage);
794 if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown)
795 OnKeyDown(pMsg);
796 break;
797 }
798 default:
799 break;
800 }
801 CFWL_Widget::OnProcessMessage(pMessage);
802 }
803
804 void CFWL_ListBox::OnProcessEvent(CFWL_Event* pEvent) {
805 if (!pEvent)
806 return;
807 if (pEvent->GetType() != CFWL_Event::Type::Scroll)
808 return;
809
810 CFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget;
811 if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) ||
812 (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) {
813 CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
814 OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget),
815 pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
816 }
817 }
818
819 void CFWL_ListBox::OnDrawWidget(CFX_Graphics* pGraphics,
820 const CFX_Matrix* pMatrix) {
821 DrawWidget(pGraphics, pMatrix);
822 }
823
824 void CFWL_ListBox::OnFocusChanged(CFWL_Message* pMsg, bool bSet) {
825 if (GetStylesEx() & FWL_STYLEEXT_LTB_ShowScrollBarFocus) {
826 if (m_pVertScrollBar) {
827 if (bSet)
828 m_pVertScrollBar->RemoveStates(FWL_WGTSTATE_Invisible);
829 else
830 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible);
831 }
832 if (m_pHorzScrollBar) {
833 if (bSet)
834 m_pHorzScrollBar->RemoveStates(FWL_WGTSTATE_Invisible);
835 else
836 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible);
837 }
838 }
839 if (bSet)
840 m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
841 else
842 m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
843
844 Repaint(&m_rtClient);
845 }
846
847 void CFWL_ListBox::OnLButtonDown(CFWL_MsgMouse* pMsg) {
848 m_bLButtonDown = true;
849 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)
850 SetFocus(true);
851
852 CFWL_ListItem* pItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
853 if (!pItem)
854 return;
855
856 if (IsMultiSelection()) {
857 if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) {
858 bool bSelected = IsItemSelected(pItem);
859 SetSelectionDirect(pItem, !bSelected);
860 m_hAnchor = pItem;
861 } else if (pMsg->m_dwFlags & FWL_KEYFLAG_Shift) {
862 if (m_hAnchor)
863 SetSelection(m_hAnchor, pItem, true);
864 else
865 SetSelectionDirect(pItem, true);
866 } else {
867 SetSelection(pItem, pItem, true);
868 m_hAnchor = pItem;
869 }
870 } else {
871 SetSelection(pItem, pItem, true);
872 }
873 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check) {
874 CFWL_ListItem* hSelectedItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
875 CFX_RectF rtCheck;
876 GetItemCheckRectInternal(hSelectedItem, rtCheck);
877 bool bChecked = GetItemChecked(pItem);
878 if (rtCheck.Contains(pMsg->m_fx, pMsg->m_fy)) {
879 SetItemChecked(pItem, !bChecked);
880 Update();
881 }
882 }
883 SetFocusItem(pItem);
884 ScrollToVisible(pItem);
885 SetGrab(true);
886 Repaint(&m_rtClient);
887 }
888
889 void CFWL_ListBox::OnLButtonUp(CFWL_MsgMouse* pMsg) {
890 if (!m_bLButtonDown)
891 return;
892
893 m_bLButtonDown = false;
894 SetGrab(false);
895 }
896
897 void CFWL_ListBox::OnMouseWheel(CFWL_MsgMouseWheel* pMsg) {
898 if (IsShowScrollBar(true))
899 m_pVertScrollBar->GetDelegate()->OnProcessMessage(pMsg);
900 }
901
902 void CFWL_ListBox::OnKeyDown(CFWL_MsgKey* pMsg) {
903 uint32_t dwKeyCode = pMsg->m_dwKeyCode;
904 switch (dwKeyCode) {
905 case FWL_VKEY_Tab:
906 case FWL_VKEY_Up:
907 case FWL_VKEY_Down:
908 case FWL_VKEY_Home:
909 case FWL_VKEY_End: {
910 CFWL_ListItem* pItem = GetFocusedItem();
911 pItem = GetListItem(pItem, dwKeyCode);
912 bool bShift = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Shift);
913 bool bCtrl = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl);
914 OnVK(pItem, bShift, bCtrl);
915 break;
916 }
917 default:
918 break;
919 }
920 }
921
922 void CFWL_ListBox::OnVK(CFWL_ListItem* pItem, bool bShift, bool bCtrl) {
923 if (!pItem)
924 return;
925
926 if (IsMultiSelection()) {
927 if (bCtrl) {
928 // Do nothing.
929 } else if (bShift) {
930 if (m_hAnchor)
931 SetSelection(m_hAnchor, pItem, true);
932 else
933 SetSelectionDirect(pItem, true);
934 } else {
935 SetSelection(pItem, pItem, true);
936 m_hAnchor = pItem;
937 }
938 } else {
939 SetSelection(pItem, pItem, true);
940 }
941
942 SetFocusItem(pItem);
943 ScrollToVisible(pItem);
944
945 CFX_RectF rtInvalidate;
946 rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width,
947 m_pProperties->m_rtWidget.height);
948 Repaint(&rtInvalidate);
949 }
950
951 bool CFWL_ListBox::OnScroll(CFWL_ScrollBar* pScrollBar,
952 CFWL_EvtScroll::Code dwCode,
953 FX_FLOAT fPos) {
954 CFX_SizeF fs;
955 pScrollBar->GetRange(&fs.x, &fs.y);
956 FX_FLOAT iCurPos = pScrollBar->GetPos();
957 FX_FLOAT fStep = pScrollBar->GetStepSize();
958 switch (dwCode) {
959 case CFWL_EvtScroll::Code::Min: {
960 fPos = fs.x;
961 break;
962 }
963 case CFWL_EvtScroll::Code::Max: {
964 fPos = fs.y;
965 break;
966 }
967 case CFWL_EvtScroll::Code::StepBackward: {
968 fPos -= fStep;
969 if (fPos < fs.x + fStep / 2)
970 fPos = fs.x;
971 break;
972 }
973 case CFWL_EvtScroll::Code::StepForward: {
974 fPos += fStep;
975 if (fPos > fs.y - fStep / 2)
976 fPos = fs.y;
977 break;
978 }
979 case CFWL_EvtScroll::Code::PageBackward: {
980 fPos -= pScrollBar->GetPageSize();
981 if (fPos < fs.x)
982 fPos = fs.x;
983 break;
984 }
985 case CFWL_EvtScroll::Code::PageForward: {
986 fPos += pScrollBar->GetPageSize();
987 if (fPos > fs.y)
988 fPos = fs.y;
989 break;
990 }
991 case CFWL_EvtScroll::Code::Pos:
992 case CFWL_EvtScroll::Code::TrackPos:
993 case CFWL_EvtScroll::Code::None:
994 break;
995 case CFWL_EvtScroll::Code::EndScroll:
996 return false;
997 }
998 if (iCurPos != fPos) {
999 pScrollBar->SetPos(fPos);
1000 pScrollBar->SetTrackPos(fPos);
1001 Repaint(&m_rtClient);
1002 }
1003 return true;
1004 }
1005
1006 CFX_WideString CFWL_ListBox::GetItemText(CFWL_Widget* pWidget,
1007 CFWL_ListItem* pItem) {
1008 return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_wsText : L"";
1009 }
1010
1011 int32_t CFWL_ListBox::CountItems(const CFWL_Widget* pWidget) const {
1012 return pdfium::CollectionSize<int32_t>(m_ItemArray);
1013 }
1014
1015 CFWL_ListItem* CFWL_ListBox::GetItem(const CFWL_Widget* pWidget,
1016 int32_t nIndex) const {
1017 if (nIndex < 0 || nIndex >= CountItems(pWidget))
1018 return nullptr;
1019 return m_ItemArray[nIndex].get();
1020 }
1021
1022 int32_t CFWL_ListBox::GetItemIndex(CFWL_Widget* pWidget, CFWL_ListItem* pItem) {
1023 auto it = std::find_if(
1024 m_ItemArray.begin(), m_ItemArray.end(),
1025 [pItem](const std::unique_ptr<CFWL_ListItem>& candidate) {
1026 return candidate.get() == static_cast<CFWL_ListItem*>(pItem);
1027 });
1028 return it != m_ItemArray.end() ? it - m_ItemArray.begin() : -1;
1029 }
1030
1031 uint32_t CFWL_ListBox::GetItemStyles(CFWL_Widget* pWidget,
1032 CFWL_ListItem* pItem) {
1033 return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_dwStates : 0;
1034 }
1035
1036 void CFWL_ListBox::GetItemRect(CFWL_Widget* pWidget,
1037 CFWL_ListItem* pItem,
1038 CFX_RectF& rtItem) {
1039 if (pItem)
1040 rtItem = static_cast<CFWL_ListItem*>(pItem)->m_rtItem;
1041 }
1042
1043 void* CFWL_ListBox::GetItemData(CFWL_Widget* pWidget, CFWL_ListItem* pItem) {
1044 return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_pData : nullptr;
1045 }
1046
1047 void CFWL_ListBox::SetItemStyles(CFWL_Widget* pWidget,
1048 CFWL_ListItem* pItem,
1049 uint32_t dwStyle) {
1050 if (pItem)
1051 static_cast<CFWL_ListItem*>(pItem)->m_dwStates = dwStyle;
1052 }
1053
1054 void CFWL_ListBox::SetItemRect(CFWL_Widget* pWidget,
1055 CFWL_ListItem* pItem,
1056 const CFX_RectF& rtItem) {
1057 if (pItem)
1058 static_cast<CFWL_ListItem*>(pItem)->m_rtItem = rtItem;
1059 }
1060
1061 CFX_DIBitmap* CFWL_ListBox::GetItemIcon(CFWL_Widget* pWidget,
1062 CFWL_ListItem* pItem) {
1063 return static_cast<CFWL_ListItem*>(pItem)->m_pDIB;
1064 }
1065
1066 void CFWL_ListBox::GetItemCheckRect(CFWL_Widget* pWidget,
1067 CFWL_ListItem* pItem,
1068 CFX_RectF& rtCheck) {
1069 rtCheck = static_cast<CFWL_ListItem*>(pItem)->m_rtCheckBox;
1070 }
1071
1072 void CFWL_ListBox::SetItemCheckRect(CFWL_Widget* pWidget,
1073 CFWL_ListItem* pItem,
1074 const CFX_RectF& rtCheck) {
1075 static_cast<CFWL_ListItem*>(pItem)->m_rtCheckBox = rtCheck;
1076 }
1077
1078 uint32_t CFWL_ListBox::GetItemCheckState(CFWL_Widget* pWidget,
1079 CFWL_ListItem* pItem) {
1080 return static_cast<CFWL_ListItem*>(pItem)->m_dwCheckState;
1081 }
1082
1083 void CFWL_ListBox::SetItemCheckState(CFWL_Widget* pWidget,
1084 CFWL_ListItem* pItem,
1085 uint32_t dwCheckState) {
1086 static_cast<CFWL_ListItem*>(pItem)->m_dwCheckState = dwCheckState;
1087 }
1088
1089 CFWL_ListItem* CFWL_ListBox::AddString(const CFX_WideStringC& wsAdd) {
1090 auto pItem = pdfium::MakeUnique<CFWL_ListItem>();
1091 pItem->m_dwStates = 0;
1092 pItem->m_wsText = wsAdd;
1093 pItem->m_dwStates = 0;
1094 m_ItemArray.push_back(std::move(pItem));
1095 return m_ItemArray.back().get();
1096 }
1097
1098 bool CFWL_ListBox::RemoveAt(int32_t iIndex) {
1099 if (iIndex < 0 || static_cast<size_t>(iIndex) >= m_ItemArray.size())
1100 return false;
1101
1102 m_ItemArray.erase(m_ItemArray.begin() + iIndex);
1103 return true;
1104 }
1105
1106 bool CFWL_ListBox::DeleteString(CFWL_ListItem* pItem) {
1107 int32_t nIndex = GetItemIndex(this, pItem);
1108 if (nIndex < 0 || static_cast<size_t>(nIndex) >= m_ItemArray.size())
1109 return false;
1110
1111 int32_t iSel = nIndex + 1;
1112 if (iSel >= CountItems(this))
1113 iSel = nIndex - 1;
1114 if (iSel >= 0) {
1115 CFWL_ListItem* pSel = static_cast<CFWL_ListItem*>(GetItem(this, iSel));
1116 pSel->m_dwStates |= FWL_ITEMSTATE_LTB_Selected;
1117 }
1118 m_ItemArray.erase(m_ItemArray.begin() + nIndex);
1119 return true;
1120 }
1121
1122 void CFWL_ListBox::DeleteAll() {
1123 m_ItemArray.clear();
1124 }
1125
1126 uint32_t CFWL_ListBox::GetItemStates(CFWL_ListItem* pItem) {
1127 if (!pItem)
1128 return 0;
1129 return pItem->m_dwStates | pItem->m_dwCheckState;
1130 }
1131
OLDNEW
« no previous file with comments | « xfa/fwl/core/cfwl_listbox.h ('k') | xfa/fwl/core/cfwl_listitem.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698