summaryrefslogtreecommitdiff
path: root/fpdfsdk/fxedit/fxet_list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk/fxedit/fxet_list.cpp')
-rw-r--r--fpdfsdk/fxedit/fxet_list.cpp822
1 files changed, 822 insertions, 0 deletions
diff --git a/fpdfsdk/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp
new file mode 100644
index 0000000000..cc9696030e
--- /dev/null
+++ b/fpdfsdk/fxedit/fxet_list.cpp
@@ -0,0 +1,822 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/fxedit/fxet_list.h"
+
+#include "fpdfsdk/include/fxedit/fxet_edit.h"
+
+CFX_ListItem::CFX_ListItem()
+ : m_pEdit(NULL),
+ m_bSelected(FALSE),
+ m_bCaret(FALSE),
+ m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) {
+ m_pEdit = IFX_Edit::NewEdit();
+ m_pEdit->SetAlignmentV(1);
+ m_pEdit->Initialize();
+}
+
+CFX_ListItem::~CFX_ListItem() {
+ IFX_Edit::DelEdit(m_pEdit);
+}
+
+void CFX_ListItem::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+ if (m_pEdit)
+ m_pEdit->SetFontMap(pFontMap);
+}
+
+IFX_Edit* CFX_ListItem::GetEdit() const {
+ return m_pEdit;
+}
+
+IFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
+ if (m_pEdit)
+ return m_pEdit->GetIterator();
+
+ return NULL;
+}
+
+void CFX_ListItem::SetRect(const CLST_Rect& rect) {
+ m_rcListItem = rect;
+}
+
+CLST_Rect CFX_ListItem::GetRect() const {
+ return m_rcListItem;
+}
+
+FX_BOOL CFX_ListItem::IsSelected() const {
+ return m_bSelected;
+}
+
+void CFX_ListItem::SetSelect(FX_BOOL bSelected) {
+ m_bSelected = bSelected;
+}
+
+FX_BOOL CFX_ListItem::IsCaret() const {
+ return m_bCaret;
+}
+
+void CFX_ListItem::SetCaret(FX_BOOL bCaret) {
+ m_bCaret = bCaret;
+}
+
+void CFX_ListItem::SetText(const FX_WCHAR* text) {
+ if (m_pEdit)
+ m_pEdit->SetText(text);
+}
+
+void CFX_ListItem::SetFontSize(FX_FLOAT fFontSize) {
+ if (m_pEdit)
+ m_pEdit->SetFontSize(fFontSize);
+}
+
+FX_FLOAT CFX_ListItem::GetItemHeight() const {
+ if (m_pEdit)
+ return m_pEdit->GetContentRect().Height();
+
+ return 0.0f;
+}
+
+FX_WORD CFX_ListItem::GetFirstChar() const {
+ CPVT_Word word;
+
+ if (IFX_Edit_Iterator* pIterator = GetIterator()) {
+ pIterator->SetAt(1);
+ pIterator->GetWord(word);
+ }
+
+ return word.Word;
+}
+
+CFX_WideString CFX_ListItem::GetText() const {
+ if (m_pEdit)
+ return m_pEdit->GetText();
+
+ return L"";
+}
+
+CFX_List::CFX_List()
+ : m_fFontSize(0.0f), m_pFontMap(NULL), m_bMultiple(FALSE) {}
+
+CFX_List::~CFX_List() {
+ Empty();
+}
+
+void CFX_List::Empty() {
+ for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
+ delete m_aListItems.GetAt(i);
+
+ m_aListItems.RemoveAll();
+}
+
+void CFX_List::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+ m_pFontMap = pFontMap;
+}
+
+void CFX_List::SetFontSize(FX_FLOAT fFontSize) {
+ m_fFontSize = fFontSize;
+}
+
+void CFX_List::AddItem(const FX_WCHAR* str) {
+ CFX_ListItem* pListItem = new CFX_ListItem();
+ pListItem->SetFontMap(m_pFontMap);
+ pListItem->SetFontSize(m_fFontSize);
+ pListItem->SetText(str);
+ m_aListItems.Add(pListItem);
+}
+
+void CFX_List::ReArrange(int32_t nItemIndex) {
+ FX_FLOAT fPosY = 0.0f;
+
+ if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
+ fPosY = pPrevItem->GetRect().bottom;
+
+ for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+ FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
+ pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
+ fPosY += fListItemHeight;
+ }
+ }
+
+ SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
+}
+
+IFX_Edit* CFX_List::GetItemEdit(int32_t nIndex) const {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+ return pListItem->GetEdit();
+ }
+
+ return NULL;
+}
+
+int32_t CFX_List::GetCount() const {
+ return m_aListItems.GetSize();
+}
+
+CFX_FloatRect CFX_List::GetPlateRect() const {
+ return CFX_ListContainer::GetPlateRect();
+}
+
+CFX_FloatRect CFX_List::GetContentRect() const {
+ return InnerToOuter(CFX_ListContainer::GetContentRect());
+}
+
+FX_FLOAT CFX_List::GetFontSize() const {
+ return m_fFontSize;
+}
+
+int32_t CFX_List::GetItemIndex(const CFX_FloatPoint& point) const {
+ CFX_FloatPoint pt = OuterToInner(point);
+
+ FX_BOOL bFirst = TRUE;
+ FX_BOOL bLast = TRUE;
+
+ for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+ CLST_Rect rcListItem = pListItem->GetRect();
+
+ if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
+ bFirst = FALSE;
+ }
+
+ if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
+ bLast = FALSE;
+ }
+
+ if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
+ return i;
+ }
+ }
+ }
+
+ if (bFirst)
+ return 0;
+ if (bLast)
+ return m_aListItems.GetSize() - 1;
+
+ return -1;
+}
+
+FX_FLOAT CFX_List::GetFirstHeight() const {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
+ return pListItem->GetItemHeight();
+ }
+
+ return 1.0f;
+}
+
+int32_t CFX_List::GetFirstSelected() const {
+ for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+ if (pListItem->IsSelected())
+ return i;
+ }
+ }
+ return -1;
+}
+
+int32_t CFX_List::GetLastSelected() const {
+ for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+ if (pListItem->IsSelected())
+ return i;
+ }
+ }
+ return -1;
+}
+
+FX_WCHAR CFX_List::Toupper(FX_WCHAR c) const {
+ if ((c >= 'a') && (c <= 'z'))
+ c = c - ('a' - 'A');
+ return c;
+}
+
+int32_t CFX_List::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
+ int32_t nCircleIndex = nIndex;
+
+ for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+ nCircleIndex++;
+ if (nCircleIndex >= sz)
+ nCircleIndex = 0;
+
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
+ if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
+ return nCircleIndex;
+ }
+ }
+
+ return nCircleIndex;
+}
+
+CFX_FloatRect CFX_List::GetItemRect(int32_t nIndex) const {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+ CFX_FloatRect rcItem = pListItem->GetRect();
+ rcItem.left = 0.0f;
+ rcItem.right = GetPlateRect().Width();
+ return InnerToOuter(rcItem);
+ }
+
+ return CFX_FloatRect();
+}
+
+FX_BOOL CFX_List::IsItemSelected(int32_t nIndex) const {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+ return pListItem->IsSelected();
+ }
+
+ return FALSE;
+}
+
+void CFX_List::SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected) {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
+ pListItem->SetSelect(bSelected);
+ }
+}
+
+void CFX_List::SetItemCaret(int32_t nItemIndex, FX_BOOL bCaret) {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
+ pListItem->SetCaret(bCaret);
+ }
+}
+
+void CFX_List::SetMultipleSel(FX_BOOL bMultiple) {
+ m_bMultiple = bMultiple;
+}
+
+FX_BOOL CFX_List::IsMultipleSel() const {
+ return m_bMultiple;
+}
+
+FX_BOOL CFX_List::IsValid(int32_t nItemIndex) const {
+ return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
+}
+
+CFX_WideString CFX_List::GetItemText(int32_t nIndex) const {
+ if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+ return pListItem->GetText();
+ }
+
+ return L"";
+}
+
+CPLST_Select::CPLST_Select() {}
+
+CPLST_Select::~CPLST_Select() {
+ for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++)
+ delete m_aItems.GetAt(i);
+
+ m_aItems.RemoveAll();
+}
+
+void CPLST_Select::Add(int32_t nItemIndex) {
+ int32_t nIndex = Find(nItemIndex);
+
+ if (nIndex < 0) {
+ m_aItems.Add(new CPLST_Select_Item(nItemIndex, 1));
+ } else {
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex)) {
+ pItem->nState = 1;
+ }
+ }
+}
+
+void CPLST_Select::Add(int32_t nBeginIndex, int32_t nEndIndex) {
+ if (nBeginIndex > nEndIndex) {
+ int32_t nTemp = nEndIndex;
+ nEndIndex = nBeginIndex;
+ nBeginIndex = nTemp;
+ }
+
+ for (int32_t i = nBeginIndex; i <= nEndIndex; i++)
+ Add(i);
+}
+
+void CPLST_Select::Sub(int32_t nItemIndex) {
+ for (int32_t i = m_aItems.GetSize() - 1; i >= 0; i--) {
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(i))
+ if (pItem->nItemIndex == nItemIndex)
+ pItem->nState = -1;
+ }
+}
+
+void CPLST_Select::Sub(int32_t nBeginIndex, int32_t nEndIndex) {
+ if (nBeginIndex > nEndIndex) {
+ int32_t nTemp = nEndIndex;
+ nEndIndex = nBeginIndex;
+ nBeginIndex = nTemp;
+ }
+
+ for (int32_t i = nBeginIndex; i <= nEndIndex; i++)
+ Sub(i);
+}
+
+int32_t CPLST_Select::Find(int32_t nItemIndex) const {
+ for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++) {
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
+ if (pItem->nItemIndex == nItemIndex)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+FX_BOOL CPLST_Select::IsExist(int32_t nItemIndex) const {
+ return Find(nItemIndex) >= 0;
+}
+
+int32_t CPLST_Select::GetCount() const {
+ return m_aItems.GetSize();
+}
+
+int32_t CPLST_Select::GetItemIndex(int32_t nIndex) const {
+ if (nIndex >= 0 && nIndex < m_aItems.GetSize())
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex))
+ return pItem->nItemIndex;
+
+ return -1;
+}
+
+int32_t CPLST_Select::GetState(int32_t nIndex) const {
+ if (nIndex >= 0 && nIndex < m_aItems.GetSize())
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex))
+ return pItem->nState;
+
+ return 0;
+}
+
+void CPLST_Select::DeselectAll() {
+ for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++) {
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
+ pItem->nState = -1;
+ }
+ }
+}
+
+void CPLST_Select::Done() {
+ for (int32_t i = m_aItems.GetSize() - 1; i >= 0; i--) {
+ if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
+ if (pItem->nState == -1) {
+ delete pItem;
+ m_aItems.RemoveAt(i);
+ } else {
+ pItem->nState = 0;
+ }
+ }
+ }
+}
+
+CFX_ListCtrl::CFX_ListCtrl()
+ : m_pNotify(NULL),
+ m_bNotifyFlag(FALSE),
+ m_ptScrollPos(0.0f, 0.0f),
+ m_nSelItem(-1),
+ m_nFootIndex(-1),
+ m_bCtrlSel(FALSE),
+ m_nCaretIndex(-1) {}
+
+CFX_ListCtrl::~CFX_ListCtrl() {}
+
+void CFX_ListCtrl::SetNotify(IFX_List_Notify* pNotify) {
+ m_pNotify = pNotify;
+}
+
+CFX_FloatPoint CFX_ListCtrl::InToOut(const CFX_FloatPoint& point) const {
+ CFX_FloatRect rcPlate = GetPlateRect();
+
+ return CFX_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left),
+ point.y - (m_ptScrollPos.y - rcPlate.top));
+}
+
+CFX_FloatPoint CFX_ListCtrl::OutToIn(const CFX_FloatPoint& point) const {
+ CFX_FloatRect rcPlate = GetPlateRect();
+
+ return CFX_FloatPoint(point.x + (m_ptScrollPos.x - rcPlate.left),
+ point.y + (m_ptScrollPos.y - rcPlate.top));
+}
+
+CFX_FloatRect CFX_ListCtrl::InToOut(const CFX_FloatRect& rect) const {
+ CFX_FloatPoint ptLeftBottom = InToOut(CFX_FloatPoint(rect.left, rect.bottom));
+ CFX_FloatPoint ptRightTop = InToOut(CFX_FloatPoint(rect.right, rect.top));
+
+ return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+ ptRightTop.y);
+}
+
+CFX_FloatRect CFX_ListCtrl::OutToIn(const CFX_FloatRect& rect) const {
+ CFX_FloatPoint ptLeftBottom = OutToIn(CFX_FloatPoint(rect.left, rect.bottom));
+ CFX_FloatPoint ptRightTop = OutToIn(CFX_FloatPoint(rect.right, rect.top));
+
+ return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+ ptRightTop.y);
+}
+
+void CFX_ListCtrl::OnMouseDown(const CFX_FloatPoint& point,
+ FX_BOOL bShift,
+ FX_BOOL bCtrl) {
+ int32_t nHitIndex = GetItemIndex(point);
+
+ if (IsMultipleSel()) {
+ if (bCtrl) {
+ if (IsItemSelected(nHitIndex)) {
+ m_aSelItems.Sub(nHitIndex);
+ SelectItems();
+ m_bCtrlSel = FALSE;
+ } else {
+ m_aSelItems.Add(nHitIndex);
+ SelectItems();
+ m_bCtrlSel = TRUE;
+ }
+
+ m_nFootIndex = nHitIndex;
+ } else if (bShift) {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(m_nFootIndex, nHitIndex);
+ SelectItems();
+ } else {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(nHitIndex);
+ SelectItems();
+
+ m_nFootIndex = nHitIndex;
+ }
+
+ SetCaret(nHitIndex);
+ } else {
+ SetSingleSelect(nHitIndex);
+ }
+
+ if (!IsItemVisible(nHitIndex))
+ ScrollToListItem(nHitIndex);
+}
+
+void CFX_ListCtrl::OnMouseMove(const CFX_FloatPoint& point,
+ FX_BOOL bShift,
+ FX_BOOL bCtrl) {
+ int32_t nHitIndex = GetItemIndex(point);
+
+ if (IsMultipleSel()) {
+ if (bCtrl) {
+ if (m_bCtrlSel)
+ m_aSelItems.Add(m_nFootIndex, nHitIndex);
+ else
+ m_aSelItems.Sub(m_nFootIndex, nHitIndex);
+
+ SelectItems();
+ } else {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(m_nFootIndex, nHitIndex);
+ SelectItems();
+ }
+
+ SetCaret(nHitIndex);
+ } else {
+ SetSingleSelect(nHitIndex);
+ }
+
+ if (!IsItemVisible(nHitIndex))
+ ScrollToListItem(nHitIndex);
+}
+
+void CFX_ListCtrl::OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) {
+ if (IsMultipleSel()) {
+ if (nItemIndex >= 0 && nItemIndex < GetCount()) {
+ if (bCtrl) {
+ } else if (bShift) {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(m_nFootIndex, nItemIndex);
+ SelectItems();
+ } else {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(nItemIndex);
+ SelectItems();
+ m_nFootIndex = nItemIndex;
+ }
+
+ SetCaret(nItemIndex);
+ }
+ } else {
+ SetSingleSelect(nItemIndex);
+ }
+
+ if (!IsItemVisible(nItemIndex))
+ ScrollToListItem(nItemIndex);
+}
+
+void CFX_ListCtrl::OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) {
+ OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl);
+}
+
+void CFX_ListCtrl::OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) {
+ OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl);
+}
+
+void CFX_ListCtrl::OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) {
+ OnVK(0, bShift, bCtrl);
+}
+
+void CFX_ListCtrl::OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) {
+ OnVK(GetCount() - 1, bShift, bCtrl);
+}
+
+void CFX_ListCtrl::OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) {
+ OnVK(0, bShift, bCtrl);
+}
+
+void CFX_ListCtrl::OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) {
+ OnVK(GetCount() - 1, bShift, bCtrl);
+}
+
+FX_BOOL CFX_ListCtrl::OnChar(FX_WORD nChar, FX_BOOL bShift, FX_BOOL bCtrl) {
+ int32_t nIndex = GetLastSelected();
+ int32_t nFindIndex = FindNext(nIndex, nChar);
+
+ if (nFindIndex != nIndex) {
+ OnVK(nFindIndex, bShift, bCtrl);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CFX_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) {
+ CFX_ListContainer::SetPlateRect(rect);
+ m_ptScrollPos.x = rect.left;
+ SetScrollPos(CFX_FloatPoint(rect.left, rect.top));
+ ReArrange(0);
+ InvalidateItem(-1);
+}
+
+CFX_FloatRect CFX_ListCtrl::GetItemRect(int32_t nIndex) const {
+ return InToOut(CFX_List::GetItemRect(nIndex));
+}
+
+void CFX_ListCtrl::AddString(const FX_WCHAR* str) {
+ AddItem(str);
+ ReArrange(GetCount() - 1);
+}
+
+void CFX_ListCtrl::SetMultipleSelect(int32_t nItemIndex, FX_BOOL bSelected) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (bSelected != IsItemSelected(nItemIndex)) {
+ if (bSelected) {
+ SetItemSelect(nItemIndex, TRUE);
+ InvalidateItem(nItemIndex);
+ } else {
+ SetItemSelect(nItemIndex, FALSE);
+ InvalidateItem(nItemIndex);
+ }
+ }
+}
+
+void CFX_ListCtrl::SetSingleSelect(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (m_nSelItem != nItemIndex) {
+ if (m_nSelItem >= 0) {
+ SetItemSelect(m_nSelItem, FALSE);
+ InvalidateItem(m_nSelItem);
+ }
+
+ SetItemSelect(nItemIndex, TRUE);
+ InvalidateItem(nItemIndex);
+ m_nSelItem = nItemIndex;
+ }
+}
+
+void CFX_ListCtrl::SetCaret(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (IsMultipleSel()) {
+ int32_t nOldIndex = m_nCaretIndex;
+
+ if (nOldIndex != nItemIndex) {
+ m_nCaretIndex = nItemIndex;
+
+ SetItemCaret(nOldIndex, FALSE);
+ SetItemCaret(nItemIndex, TRUE);
+
+ InvalidateItem(nOldIndex);
+ InvalidateItem(nItemIndex);
+ }
+ }
+}
+
+void CFX_ListCtrl::InvalidateItem(int32_t nItemIndex) {
+ if (m_pNotify) {
+ if (nItemIndex == -1) {
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = TRUE;
+ CFX_FloatRect rcRefresh = GetPlateRect();
+ m_pNotify->IOnInvalidateRect(&rcRefresh);
+ m_bNotifyFlag = FALSE;
+ }
+ } else {
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = TRUE;
+ CFX_FloatRect rcRefresh = GetItemRect(nItemIndex);
+ rcRefresh.left -= 1.0f;
+ rcRefresh.right += 1.0f;
+ rcRefresh.bottom -= 1.0f;
+ rcRefresh.top += 1.0f;
+
+ m_pNotify->IOnInvalidateRect(&rcRefresh);
+ m_bNotifyFlag = FALSE;
+ }
+ }
+ }
+}
+
+void CFX_ListCtrl::SelectItems() {
+ for (int32_t i = 0, sz = m_aSelItems.GetCount(); i < sz; i++) {
+ int32_t nItemIndex = m_aSelItems.GetItemIndex(i);
+ int32_t nState = m_aSelItems.GetState(i);
+
+ switch (nState) {
+ case 1:
+ SetMultipleSelect(nItemIndex, TRUE);
+ break;
+ case -1:
+ SetMultipleSelect(nItemIndex, FALSE);
+ break;
+ }
+ }
+
+ m_aSelItems.Done();
+}
+
+void CFX_ListCtrl::Select(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (IsMultipleSel()) {
+ m_aSelItems.Add(nItemIndex);
+ SelectItems();
+ } else {
+ SetSingleSelect(nItemIndex);
+ }
+}
+
+FX_BOOL CFX_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
+ CFX_FloatRect rcPlate = GetPlateRect();
+ CFX_FloatRect rcItem = GetItemRect(nItemIndex);
+
+ return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top;
+}
+
+void CFX_ListCtrl::ScrollToListItem(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ CFX_FloatRect rcPlate = GetPlateRect();
+ CFX_FloatRect rcItem = CFX_List::GetItemRect(nItemIndex);
+ CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);
+
+ if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
+ if (FX_EDIT_IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
+ SetScrollPosY(rcItem.bottom + rcPlate.Height());
+ }
+ } else if (FX_EDIT_IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
+ if (FX_EDIT_IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
+ SetScrollPosY(rcItem.top);
+ }
+ }
+}
+
+void CFX_ListCtrl::SetScrollInfo() {
+ if (m_pNotify) {
+ CFX_FloatRect rcPlate = GetPlateRect();
+ CFX_FloatRect rcContent = CFX_List::GetContentRect();
+
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = TRUE;
+ m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
+ rcContent.bottom, rcContent.top,
+ GetFirstHeight(), rcPlate.Height());
+ m_bNotifyFlag = FALSE;
+ }
+ }
+}
+
+void CFX_ListCtrl::SetScrollPos(const CFX_FloatPoint& point) {
+ SetScrollPosY(point.y);
+}
+
+void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
+ if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
+ CFX_FloatRect rcPlate = GetPlateRect();
+ CFX_FloatRect rcContent = CFX_List::GetContentRect();
+
+ if (rcPlate.Height() > rcContent.Height()) {
+ fy = rcPlate.top;
+ } else {
+ if (FX_EDIT_IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
+ fy = rcContent.bottom + rcPlate.Height();
+ } else if (FX_EDIT_IsFloatBigger(fy, rcContent.top)) {
+ fy = rcContent.top;
+ }
+ }
+
+ m_ptScrollPos.y = fy;
+ InvalidateItem(-1);
+
+ if (m_pNotify) {
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = TRUE;
+ m_pNotify->IOnSetScrollPosY(fy);
+ m_bNotifyFlag = FALSE;
+ }
+ }
+ }
+}
+
+CFX_FloatRect CFX_ListCtrl::GetContentRect() const {
+ return InToOut(CFX_List::GetContentRect());
+}
+
+void CFX_ListCtrl::ReArrange(int32_t nItemIndex) {
+ CFX_List::ReArrange(nItemIndex);
+ SetScrollInfo();
+}
+
+void CFX_ListCtrl::SetTopItem(int32_t nIndex) {
+ if (IsValid(nIndex)) {
+ GetPlateRect();
+ CFX_FloatRect rcItem = CFX_List::GetItemRect(nIndex);
+ SetScrollPosY(rcItem.top);
+ }
+}
+
+int32_t CFX_ListCtrl::GetTopItem() const {
+ int32_t nItemIndex = GetItemIndex(GetBTPoint());
+
+ if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1))
+ nItemIndex += 1;
+
+ return nItemIndex;
+}
+
+void CFX_ListCtrl::Empty() {
+ CFX_List::Empty();
+ InvalidateItem(-1);
+}
+
+void CFX_ListCtrl::Cancel() {
+ m_aSelItems.DeselectAll();
+}
+
+int32_t CFX_ListCtrl::GetItemIndex(const CFX_FloatPoint& point) const {
+ return CFX_List::GetItemIndex(OutToIn(point));
+}
+
+CFX_WideString CFX_ListCtrl::GetText() const {
+ if (IsMultipleSel())
+ return GetItemText(m_nCaretIndex);
+ return GetItemText(m_nSelItem);
+}