7#include "xfa/fwl/cfwl_listbox.h"
13#include "core/fxcrt/numerics/safe_conversions.h"
14#include "core/fxcrt/stl_util.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"
32const int kItemTextMargin = 2;
44 CFWL_Widget::Trace(visitor);
45 visitor->Trace(m_pHorzScrollBar);
46 visitor->Trace(m_pVertScrollBar);
70 m_fScorllBarWidth = GetScrollWidth();
76 CFX_RectF rect = m_pHorzScrollBar->GetWidgetRect();
81 CFX_RectF rect = m_pVertScrollBar->GetWidgetRect();
101 rtClip
.height -= m_fScorllBarWidth;
103 rtClip
.width -= m_fScorllBarWidth;
107 DrawBkground(pGraphics, matrix);
109 DrawItems(pGraphics, matrix);
115 for (int32_t i = 0; i < iCount; i++) {
133 for (int32_t i = 0; i < iCount; i++) {
152 SetFocusItem(
nullptr);
156 if (IsMultiSelection())
164 Item* hRet =
nullptr;
173 int32_t iDstItem = -1;
181 iDstItem = iCount - 1;
183 hRet =
GetItem(
this, iDstItem);
196 std::swap(iStart, iEnd);
199 for (int32_t i = 0; i < iCount; i++) {
205 while (iStart <= iEnd) {
218 bool bMulti = IsMultiSelection();
220 for (int32_t i = 0; i < iCount; i++) {
233 if (!IsMultiSelection())
247 for (int32_t i = 0; i < iCount; i++) {
258 Item* hFocus = GetFocusedItem();
269 CFX_PointF pos = point - m_ContentRect.TopLeft();
271 if (m_pHorzScrollBar)
272 fPosX = m_pHorzScrollBar->GetPos();
275 if (m_pVertScrollBar)
276 fPosY = m_pVertScrollBar->GetPos();
279 for (int32_t i = 0; i < nCount; i++) {
286 if (rtItem.Contains(pos))
293 if (!m_pVertScrollBar)
297 bool bScroll =
false;
298 float fPosY = m_pVertScrollBar->GetPos();
300 if (rtItem
.top < m_ContentRect
.top) {
301 fPosY += rtItem
.top - m_ContentRect
.top;
310 m_pVertScrollBar->SetPos(fPosY);
311 m_pVertScrollBar->SetTrackPos(fPosY);
326 param.m_pRtData = &m_StaticRect;
335 if (m_pHorzScrollBar)
336 fPosX = m_pHorzScrollBar->GetPos();
339 if (m_pVertScrollBar)
340 fPosY = m_pVertScrollBar->GetPos();
343 if (m_pHorzScrollBar)
344 rtView
.height -= m_fScorllBarWidth;
345 if (m_pVertScrollBar)
346 rtView
.width -= m_fScorllBarWidth;
349 for (int32_t i = 0; i < iCount; i++) {
360 DrawItem(pGraphics, pItem, i, rtItem, mtMatrix);
383 bg_param.m_dwStates = dwPartStates;
387 bg_param.m_pRtData = &rtFocus;
388 if (m_pVertScrollBar && !m_pHorzScrollBar &&
389 (dwPartStates & CFWL_PartState::kFocused)) {
401 if (wsText.GetLength() <= 0)
408 textParam.m_dwStates = dwPartStates;
411 textParam.m_wsText =
std::move(wsText);
420 m_ContentRect
= m_ClientRect;
429 float fWidth = GetMaxTextWidth();
430 fWidth += 2 * kItemTextMargin;
433 fWidth =
std::max(fWidth, fActualWidth);
438 for (int32_t i = 0; i < iCount; i++) {
440 UpdateItemSize(htem, fs, fWidth, m_fItemHeight);
443 float iHeight = m_ClientRect
.height;
444 bool bShowVertScr =
false;
445 bool bShowHorzScr =
false;
447 bShowVertScr = (fs.height > iHeight);
451 if (!m_pVertScrollBar)
455 m_ClientRect
.top, m_fScorllBarWidth
,
458 rtScrollBar
.height -= m_fScorllBarWidth;
460 m_pVertScrollBar->SetWidgetRect(rtScrollBar);
461 fMax =
std::max(fs.height - m_ContentRect
.height, m_fItemHeight);
463 m_pVertScrollBar->SetRange(0.0f, fMax);
464 m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10);
465 m_pVertScrollBar->SetStepSize(m_fItemHeight);
467 float fPos = std::clamp(m_pVertScrollBar->GetPos(), 0.0f, fMax);
468 m_pVertScrollBar->SetPos(fPos);
469 m_pVertScrollBar->SetTrackPos(fPos);
475 m_pVertScrollBar->Update();
476 }
else if (m_pVertScrollBar) {
477 m_pVertScrollBar->SetPos(0);
478 m_pVertScrollBar->SetTrackPos(0);
482 if (!m_pHorzScrollBar)
487 m_ClientRect
.width, m_fScorllBarWidth
);
489 rtScrollBar
.width -= m_fScorllBarWidth;
491 m_pHorzScrollBar->SetWidgetRect(rtScrollBar);
492 fMax = fs.width - rtScrollBar
.width;
493 m_pHorzScrollBar->SetRange(0.0f, fMax);
494 m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10);
495 m_pHorzScrollBar->SetStepSize(fWidth / 10);
497 float fPos = std::clamp(m_pHorzScrollBar->GetPos(), 0.0f, fMax);
498 m_pHorzScrollBar->SetPos(fPos);
499 m_pHorzScrollBar->SetTrackPos(fPos);
505 m_pHorzScrollBar->Update();
506 }
else if (m_pHorzScrollBar) {
507 m_pHorzScrollBar->SetPos(0);
508 m_pHorzScrollBar->SetTrackPos(0);
511 if (bShowVertScr && bShowHorzScr) {
514 m_fScorllBarWidth
, m_fScorllBarWidth
);
522 float fItemHeight)
const {
524 CFX_RectF rtItem(0, size.height, fWidth, fItemHeight);
528 size.height += fItemHeight;
534 for (int32_t i = 0; i < iCount; i++) {
539 CFX_SizeF sz = CalcTextSize(pItem->GetText(),
false);
540 fRet =
std::max(fRet, sz.width);
555 if (m_pVertScrollBar)
558 m_pVertScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
559 GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
564 if (m_pHorzScrollBar)
567 m_pHorzScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
568 GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
573 return m_pVertScrollBar && m_pVertScrollBar->IsVisible() &&
574 ScrollBarPropertiesPresent();
578 return m_pHorzScrollBar && m_pHorzScrollBar->IsVisible() &&
579 ScrollBarPropertiesPresent();
599 CFWL_MessageMouse* pMsg =
static_cast<CFWL_MessageMouse*>(pMessage);
613 OnMouseWheel(
static_cast<CFWL_MessageMouseWheel*>(pMessage));
616 CFWL_MessageKey* pMsg =
static_cast<CFWL_MessageKey*>(pMessage);
634 if ((pSrcTarget == m_pVertScrollBar && m_pVertScrollBar) ||
635 (pSrcTarget == m_pHorzScrollBar && m_pHorzScrollBar)) {
636 CFWL_EventScroll* pScrollEvent =
static_cast<CFWL_EventScroll*>(pEvent);
637 OnScroll(
static_cast<CFWL_ScrollBar*>(pSrcTarget),
649 if (m_pVertScrollBar)
651 if (m_pHorzScrollBar)
660 if (m_pVertScrollBar)
662 if (m_pHorzScrollBar)
669void CFWL_ListBox::OnLButtonDown(CFWL_MessageMouse* pMsg) {
670 m_bLButtonDown =
true;
676 if (IsMultiSelection()) {
682 SetSelection(m_hAnchor, pItem,
true);
699void CFWL_ListBox::OnLButtonUp(CFWL_MessageMouse* pMsg) {
703 m_bLButtonDown =
false;
707void CFWL_ListBox::OnMouseWheel(CFWL_MessageMouseWheel* pMsg) {
708 if (IsShowVertScrollBar())
709 m_pVertScrollBar->GetDelegate()->OnProcessMessage(pMsg);
723 OnVK(pItem, bShift, bCtrl);
735 if (IsMultiSelection()) {
740 SetSelection(m_hAnchor, pItem,
true);
757 CFWL_EventScroll::
Code dwCode,
775 if (fPos < fMin + fStep / 2)
781 if (fPos > fMax - fStep / 2)
804 if (iCurPos != fPos) {
813 return fxcrt::CollectionSize<int32_t>(m_ItemArray);
817 int32_t nIndex)
const {
820 return m_ItemArray[nIndex].get();
824 auto it = std::find_if(m_ItemArray.begin(), m_ItemArray.end(),
825 [pItem](
const std::unique_ptr<Item>& candidate) {
826 return candidate.get() == pItem;
828 return it != m_ItemArray.end()
829 ? checked_cast<int32_t>(it - m_ItemArray.begin())
834 m_ItemArray.push_back(std::make_unique<Item>(wsAdd));
835 return m_ItemArray.back().get();
839 if (iIndex < 0 ||
static_cast<size_t>(iIndex) >= m_ItemArray.size())
841 m_ItemArray.erase(m_ItemArray.begin() + iIndex);
846 if (nIndex < 0 ||
static_cast<size_t>(nIndex) >= m_ItemArray.size())
849 int32_t iSel = nIndex + 1;
857 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)
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)
CFWL_Widget * GetSrcTarget() const
Item(const WideString &text)
WideString GetText() const
CFX_RectF GetRect() const
void SetSelected(bool enable)
void SetRect(const CFX_RectF &rect)
void SetFocused(bool enable)
void OnDrawWidget(CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix) override
bool ScrollBarPropertiesPresent() const
bool IsShowHorzScrollBar() const
void InitVerticalScrollBar()
int32_t GetSelIndex(int32_t nIndex)
Item * GetItemAtPoint(const CFX_PointF &point)
Item * GetItem(const CFWL_Widget *pWidget, int32_t nIndex) const
void DeleteString(Item *pItem)
FWL_Type GetClassID() const override
bool ScrollToVisible(Item *hItem)
void SetSelItem(Item *hItem, bool bSelect)
void RemoveAt(int32_t iIndex)
Item * GetListItem(Item *hItem, XFA_FWL_VKEYCODE dwKeyCode)
CFWL_ListBox(CFWL_App *pApp, const Properties &properties, CFWL_Widget *pOuter)
void InitHorizontalScrollBar()
FWL_WidgetHit HitTest(const CFX_PointF &point) override
Item * GetSelItem(int32_t nIndexSel)
void OnProcessMessage(CFWL_Message *pMessage) override
void DrawWidget(CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix) override
int32_t CountItems(const CFWL_Widget *pWidget) const
void SetSelection(Item *hStart, Item *hEnd, bool bSelected)
Item * AddString(const WideString &wsAdd)
void Trace(cppgc::Visitor *visitor) const override
bool IsShowVertScrollBar() const
void OnProcessEvent(CFWL_Event *pEvent) override
int32_t GetItemIndex(CFWL_Widget *pWidget, Item *pItem)
const uint32_t m_dwKeyCodeOrChar
const MouseCommand m_dwCmd
CFWL_Widget * GetDstTarget() const
FDE_TextStyle m_dwTTOStyles
FDE_TextAlignment m_iTTOAlign
virtual void DrawText(const CFWL_ThemeText &pParams)=0
virtual void DrawBackground(const CFWL_ThemeBackground &pParams)=0
CFX_PTemplate< float > CFX_PointF
CFX_STemplate< float > CFX_SizeF
fxcrt::WideString WideString