7#include "xfa/fwl/cfwl_listbox.h"
13#include "core/fxcrt/stl_util.h"
14#include "third_party/base/numerics/safe_conversions.h"
15#include "v8/include/cppgc/visitor.h"
16#include "xfa/fde/cfde_textout.h"
17#include "xfa/fgas/graphics/cfgas_gegraphics.h"
18#include "xfa/fwl/cfwl_app.h"
19#include "xfa/fwl/cfwl_messagekey.h"
20#include "xfa/fwl/cfwl_messagemouse.h"
21#include "xfa/fwl/cfwl_messagemousewheel.h"
22#include "xfa/fwl/cfwl_themebackground.h"
23#include "xfa/fwl/cfwl_themepart.h"
24#include "xfa/fwl/cfwl_themetext.h"
25#include "xfa/fwl/fwl_widgetdef.h"
26#include "xfa/fwl/ifwl_themeprovider.h"
30const int kItemTextMargin = 2;
42 CFWL_Widget::Trace(visitor);
43 visitor->Trace(m_pHorzScrollBar);
44 visitor->Trace(m_pVertScrollBar);
68 m_fScorllBarWidth = GetScrollWidth();
74 CFX_RectF rect = m_pHorzScrollBar->GetWidgetRect();
79 CFX_RectF rect = m_pVertScrollBar->GetWidgetRect();
99 rtClip
.height -= m_fScorllBarWidth;
101 rtClip
.width -= m_fScorllBarWidth;
105 DrawBkground(pGraphics, matrix);
107 DrawItems(pGraphics, matrix);
113 for (int32_t i = 0; i < iCount; i++) {
131 for (int32_t i = 0; i < iCount; i++) {
150 SetFocusItem(
nullptr);
154 if (IsMultiSelection())
162 Item* hRet =
nullptr;
171 int32_t iDstItem = -1;
179 iDstItem = iCount - 1;
181 hRet =
GetItem(
this, iDstItem);
194 std::swap(iStart, iEnd);
197 for (int32_t i = 0; i < iCount; i++) {
203 while (iStart <= iEnd) {
216 bool bMulti = IsMultiSelection();
218 for (int32_t i = 0; i < iCount; i++) {
231 if (!IsMultiSelection())
245 for (int32_t i = 0; i < iCount; i++) {
256 Item* hFocus = GetFocusedItem();
267 CFX_PointF pos = point - m_ContentRect.TopLeft();
269 if (m_pHorzScrollBar)
270 fPosX = m_pHorzScrollBar->GetPos();
273 if (m_pVertScrollBar)
274 fPosY = m_pVertScrollBar->GetPos();
277 for (int32_t i = 0; i < nCount; i++) {
284 if (rtItem.Contains(pos))
291 if (!m_pVertScrollBar)
295 bool bScroll =
false;
296 float fPosY = m_pVertScrollBar->GetPos();
298 if (rtItem
.top < m_ContentRect
.top) {
299 fPosY += rtItem
.top - m_ContentRect
.top;
308 m_pVertScrollBar->SetPos(fPosY);
309 m_pVertScrollBar->SetTrackPos(fPosY);
324 param.m_pRtData = &m_StaticRect;
333 if (m_pHorzScrollBar)
334 fPosX = m_pHorzScrollBar->GetPos();
337 if (m_pVertScrollBar)
338 fPosY = m_pVertScrollBar->GetPos();
341 if (m_pHorzScrollBar)
342 rtView
.height -= m_fScorllBarWidth;
343 if (m_pVertScrollBar)
344 rtView
.width -= m_fScorllBarWidth;
347 for (int32_t i = 0; i < iCount; i++) {
358 DrawItem(pGraphics, pItem, i, rtItem, mtMatrix);
381 bg_param.m_dwStates = dwPartStates;
385 bg_param.m_pRtData = &rtFocus;
386 if (m_pVertScrollBar && !m_pHorzScrollBar &&
387 (dwPartStates & CFWL_PartState::kFocused)) {
399 if (wsText.GetLength() <= 0)
406 textParam.m_dwStates = dwPartStates;
409 textParam.m_wsText =
std::move(wsText);
418 m_ContentRect
= m_ClientRect;
427 float fWidth = GetMaxTextWidth();
428 fWidth += 2 * kItemTextMargin;
431 fWidth =
std::max(fWidth, fActualWidth);
436 for (int32_t i = 0; i < iCount; i++) {
438 UpdateItemSize(htem, fs, fWidth, m_fItemHeight);
441 float iHeight = m_ClientRect
.height;
442 bool bShowVertScr =
false;
443 bool bShowHorzScr =
false;
445 bShowVertScr = (fs.height > iHeight);
449 if (!m_pVertScrollBar)
453 m_ClientRect
.top, m_fScorllBarWidth
,
456 rtScrollBar
.height -= m_fScorllBarWidth;
458 m_pVertScrollBar->SetWidgetRect(rtScrollBar);
459 fMax =
std::max(fs.height - m_ContentRect
.height, m_fItemHeight);
461 m_pVertScrollBar->SetRange(0.0f, fMax);
462 m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10);
463 m_pVertScrollBar->SetStepSize(m_fItemHeight);
465 float fPos = std::clamp(m_pVertScrollBar->GetPos(), 0.0f, fMax);
466 m_pVertScrollBar->SetPos(fPos);
467 m_pVertScrollBar->SetTrackPos(fPos);
473 m_pVertScrollBar->Update();
474 }
else if (m_pVertScrollBar) {
475 m_pVertScrollBar->SetPos(0);
476 m_pVertScrollBar->SetTrackPos(0);
480 if (!m_pHorzScrollBar)
485 m_ClientRect
.width, m_fScorllBarWidth
);
487 rtScrollBar
.width -= m_fScorllBarWidth;
489 m_pHorzScrollBar->SetWidgetRect(rtScrollBar);
490 fMax = fs.width - rtScrollBar
.width;
491 m_pHorzScrollBar->SetRange(0.0f, fMax);
492 m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10);
493 m_pHorzScrollBar->SetStepSize(fWidth / 10);
495 float fPos = std::clamp(m_pHorzScrollBar->GetPos(), 0.0f, fMax);
496 m_pHorzScrollBar->SetPos(fPos);
497 m_pHorzScrollBar->SetTrackPos(fPos);
503 m_pHorzScrollBar->Update();
504 }
else if (m_pHorzScrollBar) {
505 m_pHorzScrollBar->SetPos(0);
506 m_pHorzScrollBar->SetTrackPos(0);
509 if (bShowVertScr && bShowHorzScr) {
512 m_fScorllBarWidth
, m_fScorllBarWidth
);
520 float fItemHeight)
const {
522 CFX_RectF rtItem(0, size.height, fWidth, fItemHeight);
526 size.height += fItemHeight;
532 for (int32_t i = 0; i < iCount; i++) {
537 CFX_SizeF sz = CalcTextSize(pItem->GetText(),
false);
538 fRet =
std::max(fRet, sz.width);
553 if (m_pVertScrollBar)
556 m_pVertScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
557 GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
562 if (m_pHorzScrollBar)
565 m_pHorzScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
566 GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
571 return m_pVertScrollBar && m_pVertScrollBar->IsVisible() &&
572 ScrollBarPropertiesPresent();
576 return m_pHorzScrollBar && m_pHorzScrollBar->IsVisible() &&
577 ScrollBarPropertiesPresent();
597 CFWL_MessageMouse* pMsg =
static_cast<CFWL_MessageMouse*>(pMessage);
611 OnMouseWheel(
static_cast<CFWL_MessageMouseWheel*>(pMessage));
614 CFWL_MessageKey* pMsg =
static_cast<CFWL_MessageKey*>(pMessage);
632 if ((pSrcTarget == m_pVertScrollBar && m_pVertScrollBar) ||
633 (pSrcTarget == m_pHorzScrollBar && m_pHorzScrollBar)) {
634 CFWL_EventScroll* pScrollEvent =
static_cast<CFWL_EventScroll*>(pEvent);
635 OnScroll(
static_cast<CFWL_ScrollBar*>(pSrcTarget),
647 if (m_pVertScrollBar)
649 if (m_pHorzScrollBar)
658 if (m_pVertScrollBar)
660 if (m_pHorzScrollBar)
667void CFWL_ListBox::OnLButtonDown(CFWL_MessageMouse* pMsg) {
668 m_bLButtonDown =
true;
674 if (IsMultiSelection()) {
680 SetSelection(m_hAnchor, pItem,
true);
697void CFWL_ListBox::OnLButtonUp(CFWL_MessageMouse* pMsg) {
701 m_bLButtonDown =
false;
705void CFWL_ListBox::OnMouseWheel(CFWL_MessageMouseWheel* pMsg) {
706 if (IsShowVertScrollBar())
707 m_pVertScrollBar->GetDelegate()->OnProcessMessage(pMsg);
721 OnVK(pItem, bShift, bCtrl);
733 if (IsMultiSelection()) {
738 SetSelection(m_hAnchor, pItem,
true);
755 CFWL_EventScroll::
Code dwCode,
773 if (fPos < fMin + fStep / 2)
779 if (fPos > fMax - fStep / 2)
802 if (iCurPos != fPos) {
811 return fxcrt::CollectionSize<int32_t>(m_ItemArray);
815 int32_t nIndex)
const {
818 return m_ItemArray[nIndex].get();
822 auto it = std::find_if(m_ItemArray.begin(), m_ItemArray.end(),
823 [pItem](
const std::unique_ptr<Item>& candidate) {
824 return candidate.get() == pItem;
826 return it != m_ItemArray.end()
827 ? pdfium::base::checked_cast<int32_t>(it - m_ItemArray.begin())
832 m_ItemArray.push_back(std::make_unique<Item>(wsAdd));
833 return m_ItemArray.back().get();
837 if (iIndex < 0 ||
static_cast<size_t>(iIndex) >= m_ItemArray.size())
839 m_ItemArray.erase(m_ItemArray.begin() + iIndex);
844 if (nIndex < 0 ||
static_cast<size_t>(nIndex) >= m_ItemArray.size())
847 int32_t iSel = nIndex + 1;
855 m_ItemArray.erase(m_ItemArray.begin() + nIndex);
#define FWL_STYLEEXT_LTB_MultiSelection
#define FWL_STYLEEXT_LTB_AlignMask
#define FWL_STYLEEXT_LTB_ShowScrollBarFocus
#define FWL_STYLEEXT_LTB_CenterAlign
#define FWL_STYLEEXT_LTB_RightAlign
#define FWL_STYLEEXT_LTB_LeftAlign
StateRestorer(CFGAS_GEGraphics *graphics)
void SetClipRect(const CFX_RectF &rect)
CFWL_Widget * GetSrcTarget() const
void SetSelected(bool enable)
CFX_RectF GetRect() const
Item(const WideString &text)
void SetFocused(bool enable)
void SetRect(const CFX_RectF &rect)
WideString GetText() const
bool ScrollBarPropertiesPresent() const
void SetSelItem(Item *hItem, bool bSelect)
FWL_WidgetHit HitTest(const CFX_PointF &point) override
void Trace(cppgc::Visitor *visitor) const override
Item * GetSelItem(int32_t nIndexSel)
void OnDrawWidget(CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix) override
int32_t CountItems(const CFWL_Widget *pWidget) const
bool ScrollToVisible(Item *hItem)
int32_t GetItemIndex(CFWL_Widget *pWidget, Item *pItem)
void DrawWidget(CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix) override
void InitHorizontalScrollBar()
void SetSelection(Item *hStart, Item *hEnd, bool bSelected)
bool IsShowVertScrollBar() const
Item * GetItem(const CFWL_Widget *pWidget, int32_t nIndex) const
void RemoveAt(int32_t iIndex)
FWL_Type GetClassID() const override
bool IsShowHorzScrollBar() const
void OnProcessEvent(CFWL_Event *pEvent) override
Item * GetListItem(Item *hItem, XFA_FWL_VKEYCODE dwKeyCode)
void OnProcessMessage(CFWL_Message *pMessage) override
Item * GetItemAtPoint(const CFX_PointF &point)
CFWL_ListBox(CFWL_App *pApp, const Properties &properties, CFWL_Widget *pOuter)
void DeleteString(Item *pItem)
void InitVerticalScrollBar()
Item * AddString(const WideString &wsAdd)
int32_t GetSelIndex(int32_t nIndex)
const uint32_t m_dwKeyCodeOrChar
const MouseCommand m_dwCmd
CFWL_Widget * GetDstTarget() const
FDE_TextStyle m_dwTTOStyles
FDE_TextAlignment m_iTTOAlign
CFX_Matrix & operator=(const CFX_Matrix &other)=default
CFX_RectF TransformRect(const CFX_RectF &rect) const
CFX_RectF(const CFX_RectF &other)=default
void Offset(float dx, float dy)
constexpr CFX_RectF()=default
void Deflate(float off_left, float off_top, float off_right, float off_bottom)
CFX_RectF & operator=(const CFX_RectF &other)=default
bool Contains(const PointType &p) const
constexpr CFX_RectF(float dst_left, float dst_top, float dst_width, float dst_height)
void Deflate(float x, float y)
virtual void DrawBackground(const CFWL_ThemeBackground &pParams)=0
virtual void DrawText(const CFWL_ThemeText &pParams)=0