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

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

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

Powered by Google App Engine
This is Rietveld 408576698