| // 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 "../../include/fxedit/fxet_stub.h" |
| #include "../../include/fxedit/fxet_edit.h" |
| #include "../../include/fxedit/fxet_list.h" |
| |
| /* ------------------------------- CFX_ListItem ---------------------------------- */ |
| |
| 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(); |
| ASSERT(m_pEdit != NULL); |
| |
| 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(FX_LPCWSTR 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::CFX_List() : m_fFontSize(0.0f), m_pFontMap(NULL), m_bMultiple(FALSE) |
| { |
| } |
| |
| CFX_List::~CFX_List() |
| { |
| Empty(); |
| } |
| |
| void CFX_List::Empty() |
| { |
| for (FX_INT32 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(FX_LPCWSTR str) |
| { |
| if (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(FX_INT32 nItemIndex) |
| { |
| FX_FLOAT fPosY = 0.0f; |
| |
| if (CFX_ListItem * pPrevItem = m_aListItems.GetAt(nItemIndex - 1)) |
| fPosY = pPrevItem->GetRect().bottom; |
| |
| for (FX_INT32 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(FX_INT32 nIndex) const |
| { |
| if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex)) |
| { |
| return pListItem->GetEdit(); |
| } |
| |
| return NULL; |
| } |
| |
| FX_INT32 CFX_List::GetCount() const |
| { |
| return m_aListItems.GetSize(); |
| } |
| |
| CPDF_Rect CFX_List::GetPlateRect() const |
| { |
| return CFX_ListContainer::GetPlateRect(); |
| } |
| |
| CPDF_Rect CFX_List::GetContentRect() const |
| { |
| return InnerToOuter(CFX_ListContainer::GetContentRect()); |
| } |
| |
| FX_FLOAT CFX_List::GetFontSize() const |
| { |
| return m_fFontSize; |
| } |
| |
| FX_INT32 CFX_List::GetItemIndex(const CPDF_Point & point) const |
| { |
| CPDF_Point pt = OuterToInner(point); |
| |
| FX_BOOL bFirst = TRUE; |
| FX_BOOL bLast = TRUE; |
| |
| for (FX_INT32 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; |
| } |
| |
| FX_INT32 CFX_List::GetFirstSelected() const |
| { |
| for (FX_INT32 i=0,sz=m_aListItems.GetSize(); i<sz; i++) |
| { |
| if (CFX_ListItem * pListItem = m_aListItems.GetAt(i)) |
| { |
| if (pListItem->IsSelected()) |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| FX_INT32 CFX_List::GetLastSelected() const |
| { |
| for (FX_INT32 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; |
| } |
| |
| FX_INT32 CFX_List::FindNext(FX_INT32 nIndex,FX_WCHAR nChar) const |
| { |
| FX_INT32 nCircleIndex = nIndex; |
| |
| for (FX_INT32 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; |
| } |
| |
| CPDF_Rect CFX_List::GetItemRect(FX_INT32 nIndex) const |
| { |
| if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex)) |
| { |
| CPDF_Rect rcItem = pListItem->GetRect(); |
| rcItem.left = 0.0f; |
| rcItem.right = GetPlateRect().Width(); |
| return InnerToOuter(rcItem); |
| } |
| |
| return CPDF_Rect(); |
| } |
| |
| FX_BOOL CFX_List::IsItemSelected(FX_INT32 nIndex) const |
| { |
| if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex)) |
| { |
| return pListItem->IsSelected(); |
| } |
| |
| return FALSE; |
| } |
| |
| void CFX_List::SetItemSelect(FX_INT32 nItemIndex, FX_BOOL bSelected) |
| { |
| if (CFX_ListItem * pListItem = m_aListItems.GetAt(nItemIndex)) |
| { |
| pListItem->SetSelect(bSelected); |
| } |
| } |
| |
| void CFX_List::SetItemCaret(FX_INT32 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(FX_INT32 nItemIndex) const |
| { |
| return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize(); |
| } |
| |
| CFX_WideString CFX_List::GetItemText(FX_INT32 nIndex) const |
| { |
| if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex)) |
| { |
| return pListItem->GetText(); |
| } |
| |
| return L""; |
| } |
| |
| /* ------------------------------------ CPLST_Select ---------------------------------- */ |
| |
| CPLST_Select::CPLST_Select() |
| { |
| } |
| |
| CPLST_Select::~CPLST_Select() |
| { |
| for (FX_INT32 i=0,sz=m_aItems.GetSize(); i<sz; i++) |
| delete m_aItems.GetAt(i); |
| |
| m_aItems.RemoveAll(); |
| } |
| |
| void CPLST_Select::Add(FX_INT32 nItemIndex) |
| { |
| FX_INT32 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(FX_INT32 nBeginIndex, FX_INT32 nEndIndex) |
| { |
| if (nBeginIndex > nEndIndex) |
| { |
| FX_INT32 nTemp = nEndIndex; |
| nEndIndex = nBeginIndex; |
| nBeginIndex = nTemp; |
| } |
| |
| for (FX_INT32 i=nBeginIndex; i<=nEndIndex; i++) Add(i); |
| } |
| |
| void CPLST_Select::Sub(FX_INT32 nItemIndex) |
| { |
| for (FX_INT32 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(FX_INT32 nBeginIndex, FX_INT32 nEndIndex) |
| { |
| if (nBeginIndex > nEndIndex) |
| { |
| FX_INT32 nTemp = nEndIndex; |
| nEndIndex = nBeginIndex; |
| nBeginIndex = nTemp; |
| } |
| |
| for (FX_INT32 i=nBeginIndex; i<=nEndIndex; i++) Sub(i); |
| } |
| |
| FX_INT32 CPLST_Select::Find(FX_INT32 nItemIndex) const |
| { |
| for (FX_INT32 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(FX_INT32 nItemIndex) const |
| { |
| return Find(nItemIndex) >= 0; |
| } |
| |
| FX_INT32 CPLST_Select::GetCount() const |
| { |
| return m_aItems.GetSize(); |
| } |
| |
| FX_INT32 CPLST_Select::GetItemIndex(FX_INT32 nIndex) const |
| { |
| if (nIndex >= 0 && nIndex < m_aItems.GetSize()) |
| if (CPLST_Select_Item * pItem = m_aItems.GetAt(nIndex)) |
| return pItem->nItemIndex; |
| |
| return -1; |
| } |
| |
| FX_INT32 CPLST_Select::GetState(FX_INT32 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 (FX_INT32 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 (FX_INT32 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::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; |
| } |
| |
| CPDF_Point CFX_ListCtrl::InToOut(const CPDF_Point & point) const |
| { |
| CPDF_Rect rcPlate = GetPlateRect(); |
| |
| return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left), |
| point.y - (m_ptScrollPos.y - rcPlate.top)); |
| } |
| |
| CPDF_Point CFX_ListCtrl::OutToIn(const CPDF_Point & point) const |
| { |
| CPDF_Rect rcPlate = GetPlateRect(); |
| |
| return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left), |
| point.y + (m_ptScrollPos.y - rcPlate.top)); |
| } |
| |
| CPDF_Rect CFX_ListCtrl::InToOut(const CPDF_Rect & rect) const |
| { |
| CPDF_Point ptLeftBottom = InToOut(CPDF_Point(rect.left,rect.bottom)); |
| CPDF_Point ptRightTop = InToOut(CPDF_Point(rect.right,rect.top)); |
| |
| return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y); |
| } |
| |
| CPDF_Rect CFX_ListCtrl::OutToIn(const CPDF_Rect & rect) const |
| { |
| CPDF_Point ptLeftBottom = OutToIn(CPDF_Point(rect.left,rect.bottom)); |
| CPDF_Point ptRightTop = OutToIn(CPDF_Point(rect.right,rect.top)); |
| |
| return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y); |
| } |
| |
| void CFX_ListCtrl::OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl) |
| { |
| FX_INT32 nHitIndex = this->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 (!this->IsItemVisible(nHitIndex)) |
| this->ScrollToListItem(nHitIndex); |
| } |
| |
| void CFX_ListCtrl::OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl) |
| { |
| FX_INT32 nHitIndex = this->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 (!this->IsItemVisible(nHitIndex)) |
| this->ScrollToListItem(nHitIndex); |
| } |
| |
| void CFX_ListCtrl::OnVK(FX_INT32 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 (!this->IsItemVisible(nItemIndex)) |
| this->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) |
| { |
| FX_INT32 nIndex = GetLastSelected(); |
| FX_INT32 nFindIndex = FindNext(nIndex,nChar); |
| |
| if (nFindIndex != nIndex) |
| { |
| OnVK(nFindIndex, bShift, bCtrl); |
| return TRUE; |
| } |
| return FALSE; |
| } |
| |
| /* -------- inner methods ------- */ |
| |
| void CFX_ListCtrl::SetPlateRect(const CPDF_Rect & rect) |
| { |
| CFX_ListContainer::SetPlateRect(rect); |
| m_ptScrollPos.x = rect.left; |
| SetScrollPos(CPDF_Point(rect.left,rect.top)); |
| ReArrange(0); |
| InvalidateItem(-1); |
| } |
| |
| CPDF_Rect CFX_ListCtrl::GetItemRect(FX_INT32 nIndex) const |
| { |
| return InToOut(CFX_List::GetItemRect(nIndex)); |
| } |
| |
| void CFX_ListCtrl::AddString(FX_LPCWSTR string) |
| { |
| AddItem(string); |
| ReArrange(GetCount() - 1); |
| } |
| |
| void CFX_ListCtrl::SetMultipleSelect(FX_INT32 nItemIndex, FX_BOOL bSelected) |
| { |
| if (!IsValid(nItemIndex)) return; |
| |
| if (bSelected != this->IsItemSelected(nItemIndex)) |
| { |
| if (bSelected) |
| { |
| SetItemSelect(nItemIndex,TRUE); |
| InvalidateItem(nItemIndex); |
| } |
| else |
| { |
| SetItemSelect(nItemIndex,FALSE); |
| InvalidateItem(nItemIndex); |
| } |
| } |
| } |
| |
| void CFX_ListCtrl::SetSingleSelect(FX_INT32 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(FX_INT32 nItemIndex) |
| { |
| if (!IsValid(nItemIndex)) return; |
| |
| if (this->IsMultipleSel()) |
| { |
| FX_INT32 nOldIndex = m_nCaretIndex; |
| |
| if (nOldIndex != nItemIndex) |
| { |
| m_nCaretIndex = nItemIndex; |
| |
| SetItemCaret(nOldIndex, FALSE); |
| SetItemCaret(nItemIndex,TRUE); |
| |
| InvalidateItem(nOldIndex); |
| InvalidateItem(nItemIndex); |
| } |
| } |
| } |
| |
| void CFX_ListCtrl::InvalidateItem(FX_INT32 nItemIndex) |
| { |
| if (m_pNotify) |
| { |
| if (nItemIndex == -1) |
| { |
| if (!m_bNotifyFlag) |
| { |
| m_bNotifyFlag = TRUE; |
| CPDF_Rect rcRefresh = GetPlateRect(); |
| m_pNotify->IOnInvalidateRect(&rcRefresh); |
| m_bNotifyFlag = FALSE; |
| } |
| } |
| else |
| { |
| if (!m_bNotifyFlag) |
| { |
| m_bNotifyFlag = TRUE; |
| CPDF_Rect 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 (FX_INT32 i=0,sz=m_aSelItems.GetCount(); i<sz; i++) |
| { |
| FX_INT32 nItemIndex = m_aSelItems.GetItemIndex(i); |
| FX_INT32 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(FX_INT32 nItemIndex) |
| { |
| if (!IsValid(nItemIndex)) return; |
| |
| if (this->IsMultipleSel()) |
| { |
| m_aSelItems.Add(nItemIndex); |
| SelectItems(); |
| } |
| else |
| SetSingleSelect(nItemIndex); |
| } |
| |
| FX_BOOL CFX_ListCtrl::IsItemVisible(FX_INT32 nItemIndex) const |
| { |
| CPDF_Rect rcPlate = this->GetPlateRect(); |
| CPDF_Rect rcItem = this->GetItemRect(nItemIndex); |
| |
| return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top; |
| } |
| |
| void CFX_ListCtrl::ScrollToListItem(FX_INT32 nItemIndex) |
| { |
| if (!IsValid(nItemIndex)) return; |
| |
| CPDF_Rect rcPlate = this->GetPlateRect(); |
| CPDF_Rect rcItem = CFX_List::GetItemRect(nItemIndex); |
| CPDF_Rect 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) |
| { |
| CPDF_Rect rcPlate = GetPlateRect(); |
| CPDF_Rect 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 CPDF_Point & point) |
| { |
| SetScrollPosY(point.y); |
| } |
| |
| void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) |
| { |
| if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy)) |
| { |
| CPDF_Rect rcPlate = this->GetPlateRect(); |
| CPDF_Rect 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; |
| } |
| } |
| } |
| } |
| |
| CPDF_Rect CFX_ListCtrl::GetContentRect() const |
| { |
| return InToOut(CFX_List::GetContentRect()); |
| } |
| |
| void CFX_ListCtrl::ReArrange(FX_INT32 nItemIndex) |
| { |
| CFX_List::ReArrange(nItemIndex); |
| SetScrollInfo(); |
| } |
| |
| void CFX_ListCtrl::SetTopItem(FX_INT32 nIndex) |
| { |
| if (IsValid(nIndex)) |
| { |
| this->GetPlateRect(); |
| CPDF_Rect rcItem = CFX_List::GetItemRect(nIndex); |
| SetScrollPosY(rcItem.top); |
| } |
| } |
| |
| FX_INT32 CFX_ListCtrl::GetTopItem() const |
| { |
| FX_INT32 nItemIndex = this->GetItemIndex(this->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(); |
| } |
| |
| FX_INT32 CFX_ListCtrl::GetItemIndex(const CPDF_Point & point) const |
| { |
| return CFX_List::GetItemIndex(OutToIn(point)); |
| } |
| |
| CFX_WideString CFX_ListCtrl::GetText() const |
| { |
| if (this->IsMultipleSel()) |
| return this->GetItemText(this->m_nCaretIndex); |
| else |
| return this->GetItemText(this->m_nSelItem); |
| } |
| |