From a5574d24bc8c0e94c8880c75f0fd27d08d30b98b Mon Sep 17 00:00:00 2001 From: Rozhuk Ivan Date: Sat, 29 Nov 2014 20:36:41 +0000 Subject: MirandaG15: code cleanup. git-svn-id: http://svn.miranda-ng.org/main/trunk@11162 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirandaG15/src/LCDFramework/CLCDList.h | 1886 ++++++++++++------------ 1 file changed, 944 insertions(+), 942 deletions(-) (limited to 'plugins/MirandaG15/src/LCDFramework/CLCDList.h') diff --git a/plugins/MirandaG15/src/LCDFramework/CLCDList.h b/plugins/MirandaG15/src/LCDFramework/CLCDList.h index ae019fe914..80a6b246cf 100644 --- a/plugins/MirandaG15/src/LCDFramework/CLCDList.h +++ b/plugins/MirandaG15/src/LCDFramework/CLCDList.h @@ -1,943 +1,945 @@ -#ifndef _CLCDLIST_H_ -#define _CLCDLIST_H_ - -#include "CLCDTextObject.h" -#include "CLCDBar.h" -#include - - -enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2}; - -template class CListEntry -{ -public: - CListEntry(CListEntry *pParent) - { - m_iIndex = -1; - m_iEntryCount = 0; - m_Position = NULL; - m_pParent = pParent; - if(pParent == NULL) - { - m_iLevel = 0; - m_eType = ROOT; - m_pRoot = this; - } - else - m_iLevel = m_pParent->GetLevel()+1; - } - - virtual ~CListEntry() - { - - } - - int GetLevel() - { - return m_iLevel; - } - - virtual CListEntry *GetNextEntry() - { - if(m_pParent == NULL) - return NULL; - - return m_pParent->GetNextEntry(this); - } - - virtual CListEntry *GetPreviousEntry() - { - if(m_pParent == NULL) - return NULL; - - return m_pParent->GetPreviousEntry(this); - } - - virtual CListEntry *GetNextEntry(CListEntry *pEntry) - { - return NULL; - } - - virtual CListEntry *GetPreviousEntry(CListEntry *pEntry) - { - return NULL; - } - - EListEntryType GetType() - { - return m_eType; - } - - int GetEntryCount() - { - return m_iEntryCount; - } - - virtual void UpdateEntryCount() - { - m_iEntryCount = 0; - } - - void SetRoot(CListEntry* pRoot) - { - m_pRoot = pRoot; - } - - virtual void DeleteItem(T Entry) - { - } - - virtual void DeleteGroup(G Group) - { - } - - CListEntry *GetPosition() - { - return m_Position; - } - - virtual void SetPosition(CListEntry *pPosition) - { - m_Position = pPosition; - } - - CListEntry *GetParent() - { - return m_pParent; - } - - int GetIndex() - { - return m_iIndex; - } - - void SetIndex(int iIndex) - { - m_iIndex = iIndex; - } - -protected: - int m_iIndex; - int m_iEntryCount; - int m_iLevel; - EListEntryType m_eType; - CListEntry *m_pParent; - CListEntry *m_pRoot; - CListEntry *m_Position; -}; - -template class CListItem : public CListEntry -{ -public: - CListItem(CListEntry *pParent,T Entry) : CListEntry(pParent) - { - m_Item = Entry; - m_eType = ITEM; - } - - ~CListItem() - { - m_pRoot->DeleteItem(GetItemData()); - } - - T GetItemData() - { - return m_Item; - } -private: - T m_Item; -}; - -template class CListContainer : public CListEntry -{ -public: - typedef typename list* >::iterator iterator; - - typename list* >::iterator end() - { - return m_Entrys.end(); - } - - typename list* >::iterator begin() - { - return m_Entrys.begin(); - } - - typename list* >::size_type size() - { - return m_Entrys.size(); - } - - bool empty() - { - bool b = m_Entrys.empty(); - return m_Entrys.empty(); - } - - CListContainer(CListEntry *pParent) : CListEntry(pParent) - { - if(m_pParent != NULL) - { - m_eType = CONTAINER; - m_bOpen = false; - } - else - m_bOpen = true; - } - - ~CListContainer() - { - if(m_pRoot != NULL) { - m_pRoot->DeleteGroup(GetGroupData()); - } - Clear(); - } - - void Clear() - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListItem *pItem = NULL; - CListContainer *pContainer = NULL; - - while(iter != m_Entrys.end()) - { - delete *iter; - if(m_pRoot && m_pRoot->GetPosition() == *iter) - { - if(GetType() == ROOT) - m_pRoot->SetPosition(NULL); - else - m_pRoot->SetPosition(this); - } - - iter++; - } - m_Entrys.clear(); - } - - void SetGroupData(G GroupData) - { - m_GroupData = GroupData; - } - - bool IsEmpty() - { - return m_Entrys.empty(); - } - - CListEntry *GetLastOwnEntry() - { - if(m_Entrys.empty()) - return NULL; - - return *(--m_Entrys.end()); - } - - CListEntry *GetLastEntry() - { - if(!m_Entrys.empty()) - { - - CListEntry *pEntry = *(--m_Entrys.end()); - if(pEntry->GetType() == ITEM || !((CListContainer*)pEntry)->IsOpen() || ((CListContainer*)pEntry)->IsEmpty()) - return pEntry; - return ((CListContainer*)pEntry)->GetLastEntry(); - } - return NULL; - } - - CListEntry *GetFirstEntry() - { - if(!m_Entrys.empty()) - return *(m_Entrys.begin()); - return NULL; - } - - CListEntry *GetNextEntry() - { - if(!IsOpen() || m_Entrys.empty()) - { - if(!m_pParent) - return NULL; - return m_pParent->GetNextEntry(this); - } - - return *m_Entrys.begin(); - } - - CListEntry *GetNextEntry(CListEntry *pEntry) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - while(iter != m_Entrys.end()) - { - if((CListEntry*)(*iter) == pEntry) - { - if(++iter == m_Entrys.end()) - { - if(m_pParent == NULL) - return NULL; - return m_pParent->GetNextEntry(this); - } - else - return *iter; - } - iter++; - } - return NULL; - } - - CListEntry *GetPreviousEntry(CListEntry *pEntry) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - - while(iter != m_Entrys.end()) - { - if((CListEntry*)(*iter) == pEntry) - { - if(iter == m_Entrys.begin()) - { - if(m_pParent == NULL) - return NULL; - return this; - } - else - { - iter--; - if((*iter)->GetType() == CONTAINER) - { - CListContainer* pContainer = (CListContainer*)*iter; - if(pContainer->IsOpen() && !pContainer->IsEmpty()) - return pContainer->GetLastEntry(); - } - return *iter; - } - } - iter++; - } - return NULL; - } - - virtual CListItem *InsertItem(iterator _Where,T Entry) - { - CListItem *pItem = new CListItem(this,Entry); - pItem->SetRoot(m_pRoot); - m_Entrys.insert(_Where,pItem); - - m_pRoot->UpdateEntryCount(); - - return pItem; - } - - virtual CListContainer *InsertGroup(iterator _Where,G Group) - { - CListContainer *pGroup = new CListContainer(this); - pGroup->SetGroupData(Group); - pGroup->SetRoot(m_pRoot); - m_Entrys.insert(_Where,(CListEntry*)pGroup); - - m_pRoot->UpdateEntryCount(); - - return pGroup; - } - - virtual CListItem * AddItem(T Entry) - { - return InsertItem(end(),Entry); - } - - virtual CListContainer * AddGroup(G Group) - { - return InsertGroup(end(),Group); - } - - - - virtual void RemoveGroup(G Group) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer *pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - if(pContainer->GetGroupData() == Group) - { - pContainer->Clear(); - if(m_pRoot && m_pRoot->GetPosition() == *iter) - { - CListEntry *pPosition = (*iter)->GetPreviousEntry(); - if(!pPosition) - pPosition = (*iter)->GetNextEntry(); - m_pRoot->SetPosition(pPosition); - } - delete *iter; - m_Entrys.erase(iter); - m_pRoot->UpdateEntryCount(); - return; - } - } - iter++; - } - } - - virtual void RemoveItem(T Entry) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListItem *pItem = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == ITEM) - { - pItem = (CListItem*)(*iter); - if(pItem->GetItemData() == Entry) - { - if(m_pRoot && m_pRoot->GetPosition() == *iter) - { - CListEntry *pPosition = (*iter)->GetPreviousEntry(); - if(!pPosition) - pPosition = (*iter)->GetNextEntry(); - m_pRoot->SetPosition(pPosition); - } - delete *iter; - - m_Entrys.erase(iter); - m_pRoot->UpdateEntryCount(); - return; - } - } - iter++; - } - } - - CListContainer *GetGroup(G Group) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer *pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - if(pContainer->GetGroupData() == Group) - return pContainer; - } - iter++; - } - return NULL; - } - - G GetGroupData() - { - return m_GroupData; - } - - bool IsOpen() - { - return m_bOpen; - } - - void ToggleOpen() - { - m_bOpen = !m_bOpen; - - m_pRoot->UpdateEntryCount(); - if(m_pRoot) - m_pRoot->SetPosition(this); - } - - void SetOpen(bool bOpen = true) - { - if(bOpen == m_bOpen) - return; - - m_bOpen = bOpen; - - m_pRoot->UpdateEntryCount(); - if(m_pRoot) - m_pRoot->SetPosition(this); - } - - void CollapseAll() - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer* pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - pContainer->CollapseAll(); - pContainer->SetOpen(false); - } - iter++; - } - } - - void ExpandAll() - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer* pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - pContainer->ExpandAll(); - pContainer->SetOpen(true); - } - iter++; - } - } - - void UpdateEntryCount() - { - m_iEntryCount = 0; - - int iIndex = GetIndex()+1; - - if(!IsOpen()) - return; - - list< CListEntry* >::iterator iter = m_Entrys.begin(); - while(iter != m_Entrys.end()) - { - (*iter)->SetIndex(iIndex+m_iEntryCount); - (*iter)->UpdateEntryCount(); - m_iEntryCount += 1+(*iter)->GetEntryCount(); - - iter++; - } - - if(GetType() == ROOT) - { - if(GetPosition() == NULL && !m_Entrys.empty()) - SetPosition(*m_Entrys.begin()); - else - SetPosition(GetPosition()); - } - } - - template - void sort(_Pr3 _Pred) { - m_Entrys.sort(_Pred); - UpdateEntryCount(); - m_pRoot->SetPosition(m_pRoot->GetPosition()); - } - -private: - typename list< CListEntry* > m_Entrys; - G m_GroupData; - bool m_bOpen; -}; - - -template class CLCDList : public CLCDTextObject, public CListContainer -{ -friend CListContainer; -friend CListItem; -public: - //************************************************************************ - // Constructor - //************************************************************************ - CLCDList() : CListContainer(NULL) - { - m_pScrollbar = NULL; - m_iIndention = 10; - m_iColumns = 1; - m_bDrawTreeLines = true; - m_iEntryHeight = 10; - } - - //************************************************************************ - // Destructor - //************************************************************************ - ~CLCDList() - { - } - - //************************************************************************ - // Initializes the list - //************************************************************************ - bool Initialize() - { - if(!CLCDTextObject::Initialize()) - return false; - - return true; - } - - //************************************************************************ - // Deinitializes the list - //************************************************************************ - bool Shutdown() - { - if(!CLCDTextObject::Shutdown()) - return false; - - Clear(); - - return true; - } - - //************************************************************************ - // updates the list - //************************************************************************ - bool Update() - { - if(!CLCDTextObject::Update()) - return false; - - return true; - } - - //************************************************************************ - // draws the list - //************************************************************************ - bool Draw(CLCDGfx *pGfx) - { - if(!CLCDTextObject::Draw(pGfx)) - return false; - - SelectObject(pGfx->GetHDC(),m_hFont); - - POINT ptPrevViewportOrg = { 0, 0 }; - HRGN hRgn = NULL; - int iHeight = 0,iLimit=0; - int iYOffset = 0, iXOffset=0; - int iColWidth = (GetWidth()- (m_iColumns-1)*3)/m_iColumns; - int iSpace = GetHeight() - (GetHeight()/m_iEntryHeight)*m_iEntryHeight; - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - - int iEntriesDrawn = 0; - CListEntry *pPosition = m_Position; - - // if nothing is selected, skip drawing - if(pPosition == NULL) - return true; - - bool bDrawGroup = false; - bool bSelected = false; - - // calculate the start offset - - if(m_iStartIndex < pPosition->GetIndex()) - { - while(pPosition && pPosition->GetIndex() != m_iStartIndex) - pPosition = pPosition->GetPreviousEntry(); - } - - if(m_iStartIndex > 0 && pPosition->GetIndex() > 0) - pPosition = pPosition->GetPreviousEntry(); - - for(int iCol = 0;iColGetIndex() < m_iStartIndex) - iHeight -= m_iEntryHeight-iSpace; - else if(GetEntryCount() >= (iPerPage/m_iColumns) +1) - iHeight = iSpace; - } - - // bottom selection - while(pPosition != NULL ) - { - iYOffset = iHeight; - - bSelected = m_Position == pPosition; - bDrawGroup = pPosition->GetType() == CONTAINER; - - // ~~~~~~~~~~~~~~~~~~~~~~ - // Draw tree lines - // ~~~~~~~~~~~~~~~~~~~~~~ - - // set the clip region for the entry - int iClipHeight = m_iEntryHeight; - if(GetOrigin().y+iYOffset+iClipHeight > GetOrigin().y + GetHeight()) - iClipHeight = GetHeight() - iYOffset; - - pGfx->SetClipRegion(GetOrigin().x+iXOffset,GetOrigin().y+iYOffset, - iColWidth, iClipHeight); - - // offset the control at its origin so entry use (0,0) - SetViewportOrgEx(pGfx->GetHDC(), - GetOrigin().x+iXOffset, - GetOrigin().y+iYOffset, - &ptPrevViewportOrg); - - if(m_bDrawTreeLines) - { - for(int i=1;iGetLevel();i++) - { - if(i == pPosition->GetLevel()-1) - { - // - - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2,i*m_iIndention,m_iEntryHeight/2); - // | - if(pPosition == ((CListContainer*)pPosition->GetParent())->GetLastOwnEntry()) - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2); - // | - // | - else - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); - } - else - { - CListEntry *pPosition2 = pPosition; - for(int j = pPosition->GetLevel();j>i+1;j--) - pPosition2 = pPosition2->GetParent(); - // | - // | - if(pPosition2 != ((CListContainer*)pPosition2->GetParent())->GetLastOwnEntry()) - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); - } - } - } - - // ~~~~~~~~~~~~~~~~~~~~~~ - // Draw the entry - // ~~~~~~~~~~~~~~~~~~~~~~ - pGfx->SetClipRegion(GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, - GetOrigin().y+iYOffset, - iColWidth-(pPosition->GetLevel()-1)*m_iIndention, - iClipHeight); - // set the offset - SetViewportOrgEx(pGfx->GetHDC(), - GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, - GetOrigin().y+iYOffset, - &ptPrevViewportOrg); - - // draw the entry - if(!bDrawGroup) - DrawEntry(pGfx,((CListItem*)pPosition)->GetItemData(),bSelected); - else - // draw the group - DrawGroup(pGfx,((CListContainer*)pPosition)->GetGroupData(),((CListContainer*)pPosition)->IsOpen(),bSelected); - - // ~~~~~~~~~~~~~~~~~~~~~~ - - if(pPosition->GetIndex() >= m_iStartIndex && iHeight + m_iEntryHeight <= GetHeight()) - iEntriesDrawn++; - - iHeight += m_iEntryHeight; - pPosition = pPosition->GetNextEntry(); - - if(iHeight >= GetHeight()) - break; - } - if(iCol != m_iColumns-1) - { - pGfx->SetClipRegion(GetOrigin().x, - GetOrigin().y, - GetWidth(), - GetHeight()); - // set the offset - SetViewportOrgEx(pGfx->GetHDC(), - GetOrigin().x, - GetOrigin().y, - &ptPrevViewportOrg); - - pGfx->DrawLine(iCol*3 + iColWidth + 1,0,iCol*3 + iColWidth + 1,GetHeight()); - } - iXOffset += 3 + iColWidth; - } - - if(m_pScrollbar) - { - m_pScrollbar->ScrollTo(m_iStartIndex); - m_pScrollbar->SetSliderSize(iEntriesDrawn); - } - return true; - } - - - void SetPosition(CListEntry *pEntry) - { - CListContainer::SetPosition(pEntry); - - if(pEntry == NULL) - return; - - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - m_iStartIndex = pEntry->GetIndex(); - if(m_iStartIndex + (iPerPage-1) > GetEntryCount()-1) - m_iStartIndex = (GetEntryCount()-1)-(iPerPage-1); - if(m_iStartIndex < 0) - m_iStartIndex = 0; - } - - //************************************************************************ - // scrolls up - //************************************************************************ - bool ScrollUp() - { - if(m_Position != NULL) - { - CListEntry *pEntry = m_Position->GetPreviousEntry(); - if(pEntry != NULL) - { - m_Position = pEntry; - - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - if(m_Position->GetIndex() < m_iStartIndex) - m_iStartIndex--; - return true; - } - } - return false; - } - - //************************************************************************ - // scrolls down - //************************************************************************ - bool ScrollDown() - { - if(m_Position != NULL) - { - CListEntry *pEntry = m_Position->GetNextEntry(); - if(pEntry != NULL) - { - m_Position = pEntry; - - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - if(m_Position->GetIndex() >= m_iStartIndex + iPerPage) - m_iStartIndex++; - return true; - } - } - return false; - } - - //************************************************************************ - // returns the selected list entry - //************************************************************************ - CListEntry *GetSelectedEntry() - { - return m_Position; - } - - //************************************************************************ - // associates a scrollbar with the list - //************************************************************************ - void SetScrollbar(CLCDBar *pScrollbar) - { - m_pScrollbar = pScrollbar; - if(m_pScrollbar) - { - m_pScrollbar->SetRange(0,m_iEntryCount-1); - m_pScrollbar->ScrollTo(m_Position != NULL?m_Position->GetIndex():0); - - m_pScrollbar->SetAlignment(TOP); - } - } - - //************************************************************************ - // sets the group indention in pixels - //************************************************************************ - void SetIndention(int iIndention) - { - m_iIndention = iIndention; - } - - //************************************************************************ - // sets the lists entry height - //************************************************************************ - void SetEntryHeight(int iEntryHeight) - { - m_iEntryHeight = iEntryHeight; - } - - //************************************************************************ - // returns the lists entry height - //************************************************************************ - int GetEntryHeight() - { - return m_iEntryHeight; - } - - //************************************************************************ - // enables/disables drawing of treelines - //************************************************************************ - void SetDrawTreeLines(bool bDraw) - { - m_bDrawTreeLines = bDraw; - } - - //************************************************************************ - // sets the amount of columns the list uses - //************************************************************************ - void SetColumns(int iColumns) - { - if(m_iColumns == iColumns) - return; - m_iColumns = iColumns; - SetPosition(GetPosition()); - } -protected: - //************************************************************************ - // called when the lists size has changed - //************************************************************************ - void OnSizeChanged() - { - SetPosition(GetPosition()); - } - - //************************************************************************ - // updates the list's entry count - //************************************************************************ - void UpdateEntryCount() - { - CListContainer::UpdateEntryCount(); - if(m_pScrollbar) - { - m_pScrollbar->SetRange(0,m_iEntryCount-1); - if(GetPosition() != NULL) - m_pScrollbar->ScrollTo(GetPosition()->GetIndex()); - } - } - - //************************************************************************ - // Called to delete the specified entry - //************************************************************************ - virtual void DeleteEntry(T Entry) - { - - } - - //************************************************************************ - // Called to delete the specified group - //************************************************************************ - virtual void DeleteGroup(G Group) - { - - } - - //************************************************************************ - // Called to draw the specified entry - //************************************************************************ - virtual void DrawEntry(CLCDGfx *pGfx,T Entry, bool bSelected) - { - } - - //************************************************************************ - // Called to draw the specified entry - //************************************************************************ - virtual void DrawGroup(CLCDGfx *pGfx,G Group, bool bOpen, bool bSelected) - { - } - - - -protected: - int m_iStartIndex; - int m_iColumns; - - bool m_bDrawTreeLines; - int m_iIndention; - int m_iEntryHeight; - CLCDBar *m_pScrollbar; -}; - +#ifndef _CLCDLIST_H_ +#define _CLCDLIST_H_ + +#include "CLCDTextObject.h" +#include "CLCDBar.h" +#include + + +enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2}; + +template class CListEntry +{ +public: + CListEntry(CListEntry *pParent) + { + m_iIndex = -1; + m_iEntryCount = 0; + m_Position = NULL; + m_pParent = pParent; + if(pParent == NULL) + { + m_iLevel = 0; + m_eType = ROOT; + m_pRoot = this; + } + else + m_iLevel = m_pParent->GetLevel()+1; + } + + virtual ~CListEntry() + { + + } + + int GetLevel() + { + return m_iLevel; + } + + virtual CListEntry *GetNextEntry() + { + if(m_pParent == NULL) + return NULL; + + return m_pParent->GetNextEntry(this); + } + + virtual CListEntry *GetPreviousEntry() + { + if(m_pParent == NULL) + return NULL; + + return m_pParent->GetPreviousEntry(this); + } + + virtual CListEntry *GetNextEntry(CListEntry *pEntry) + { + return NULL; + } + + virtual CListEntry *GetPreviousEntry(CListEntry *pEntry) + { + return NULL; + } + + EListEntryType GetType() + { + return m_eType; + } + + int GetEntryCount() + { + return m_iEntryCount; + } + + virtual void UpdateEntryCount() + { + m_iEntryCount = 0; + } + + void SetRoot(CListEntry* pRoot) + { + m_pRoot = pRoot; + } + + virtual void DeleteItem(T Entry) + { + } + + virtual void DeleteGroup(G Group) + { + } + + CListEntry *GetPosition() + { + return m_Position; + } + + virtual void SetPosition(CListEntry *pPosition) + { + m_Position = pPosition; + } + + CListEntry *GetParent() + { + return m_pParent; + } + + int GetIndex() + { + return m_iIndex; + } + + void SetIndex(int iIndex) + { + m_iIndex = iIndex; + } + +protected: + int m_iIndex; + int m_iEntryCount; + int m_iLevel; + EListEntryType m_eType; + CListEntry *m_pParent; + CListEntry *m_pRoot; + CListEntry *m_Position; +}; + +template class CListItem : public CListEntry +{ +public: + CListItem(CListEntry *pParent,T Entry) : CListEntry(pParent) + { + m_Item = Entry; + m_eType = ITEM; + } + + ~CListItem() + { + m_pRoot->DeleteItem(GetItemData()); + } + + T GetItemData() + { + return m_Item; + } +private: + T m_Item; +}; + +template class CListContainer : public CListEntry +{ +public: + typedef typename list* >::iterator iterator; + + typename list* >::iterator end() + { + return m_Entrys.end(); + } + + typename list* >::iterator begin() + { + return m_Entrys.begin(); + } + + typename list* >::size_type size() + { + return m_Entrys.size(); + } + + bool empty() + { + bool b = m_Entrys.empty(); + return m_Entrys.empty(); + } + + CListContainer(CListEntry *pParent) : CListEntry(pParent) + { + if(m_pParent != NULL) + { + m_eType = CONTAINER; + m_bOpen = false; + } + else + m_bOpen = true; + } + + ~CListContainer() + { + if(m_pRoot != NULL) { + m_pRoot->DeleteGroup(GetGroupData()); + } + Clear(); + } + + void Clear() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListItem *pItem = NULL; + CListContainer *pContainer = NULL; + + while(iter != m_Entrys.end()) + { + delete *iter; + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + if(GetType() == ROOT) + m_pRoot->SetPosition(NULL); + else + m_pRoot->SetPosition(this); + } + + iter++; + } + m_Entrys.clear(); + } + + void SetGroupData(G GroupData) + { + m_GroupData = GroupData; + } + + bool IsEmpty() + { + return m_Entrys.empty(); + } + + CListEntry *GetLastOwnEntry() + { + if(m_Entrys.empty()) + return NULL; + + return *(--m_Entrys.end()); + } + + CListEntry *GetLastEntry() + { + if(!m_Entrys.empty()) + { + + CListEntry *pEntry = *(--m_Entrys.end()); + if(pEntry->GetType() == ITEM || !((CListContainer*)pEntry)->IsOpen() || ((CListContainer*)pEntry)->IsEmpty()) + return pEntry; + return ((CListContainer*)pEntry)->GetLastEntry(); + } + return NULL; + } + + CListEntry *GetFirstEntry() + { + if(!m_Entrys.empty()) + return *(m_Entrys.begin()); + return NULL; + } + + CListEntry *GetNextEntry() + { + if(!IsOpen() || m_Entrys.empty()) + { + if(!m_pParent) + return NULL; + return m_pParent->GetNextEntry(this); + } + + return *m_Entrys.begin(); + } + + CListEntry *GetNextEntry(CListEntry *pEntry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + if((CListEntry*)(*iter) == pEntry) + { + if(++iter == m_Entrys.end()) + { + if(m_pParent == NULL) + return NULL; + return m_pParent->GetNextEntry(this); + } + else + return *iter; + } + iter++; + } + return NULL; + } + + CListEntry *GetPreviousEntry(CListEntry *pEntry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + + while(iter != m_Entrys.end()) + { + if((CListEntry*)(*iter) == pEntry) + { + if(iter == m_Entrys.begin()) + { + if(m_pParent == NULL) + return NULL; + return this; + } + else + { + iter--; + if((*iter)->GetType() == CONTAINER) + { + CListContainer* pContainer = (CListContainer*)*iter; + if(pContainer->IsOpen() && !pContainer->IsEmpty()) + return pContainer->GetLastEntry(); + } + return *iter; + } + } + iter++; + } + return NULL; + } + + virtual CListItem *InsertItem(iterator _Where,T Entry) + { + CListItem *pItem = new CListItem(this,Entry); + pItem->SetRoot(m_pRoot); + m_Entrys.insert(_Where,pItem); + + m_pRoot->UpdateEntryCount(); + + return pItem; + } + + virtual CListContainer *InsertGroup(iterator _Where,G Group) + { + CListContainer *pGroup = new CListContainer(this); + pGroup->SetGroupData(Group); + pGroup->SetRoot(m_pRoot); + m_Entrys.insert(_Where,(CListEntry*)pGroup); + + m_pRoot->UpdateEntryCount(); + + return pGroup; + } + + virtual CListItem * AddItem(T Entry) + { + return InsertItem(end(),Entry); + } + + virtual CListContainer * AddGroup(G Group) + { + return InsertGroup(end(),Group); + } + + + + virtual void RemoveGroup(G Group) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer *pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + if(pContainer->GetGroupData() == Group) + { + pContainer->Clear(); + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + CListEntry *pPosition = (*iter)->GetPreviousEntry(); + if(!pPosition) + pPosition = (*iter)->GetNextEntry(); + m_pRoot->SetPosition(pPosition); + } + delete *iter; + m_Entrys.erase(iter); + m_pRoot->UpdateEntryCount(); + return; + } + } + iter++; + } + } + + virtual void RemoveItem(T Entry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListItem *pItem = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == ITEM) + { + pItem = (CListItem*)(*iter); + if(pItem->GetItemData() == Entry) + { + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + CListEntry *pPosition = (*iter)->GetPreviousEntry(); + if(!pPosition) + pPosition = (*iter)->GetNextEntry(); + m_pRoot->SetPosition(pPosition); + } + delete *iter; + + m_Entrys.erase(iter); + m_pRoot->UpdateEntryCount(); + return; + } + } + iter++; + } + } + + CListContainer *GetGroup(G Group) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer *pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + if(pContainer->GetGroupData() == Group) + return pContainer; + } + iter++; + } + return NULL; + } + + G GetGroupData() + { + return m_GroupData; + } + + bool IsOpen() + { + return m_bOpen; + } + + void ToggleOpen() + { + m_bOpen = !m_bOpen; + + if (m_pRoot) { + m_pRoot->UpdateEntryCount(); + m_pRoot->SetPosition(this); + } + } + + void SetOpen(bool bOpen = true) + { + if(bOpen == m_bOpen) + return; + + m_bOpen = bOpen; + + if (m_pRoot) { + m_pRoot->UpdateEntryCount(); + m_pRoot->SetPosition(this); + } + } + + void CollapseAll() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer* pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + pContainer->CollapseAll(); + pContainer->SetOpen(false); + } + iter++; + } + } + + void ExpandAll() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer* pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + pContainer->ExpandAll(); + pContainer->SetOpen(true); + } + iter++; + } + } + + void UpdateEntryCount() + { + m_iEntryCount = 0; + + int iIndex = GetIndex()+1; + + if(!IsOpen()) + return; + + list< CListEntry* >::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + (*iter)->SetIndex(iIndex+m_iEntryCount); + (*iter)->UpdateEntryCount(); + m_iEntryCount += 1+(*iter)->GetEntryCount(); + + iter++; + } + + if(GetType() == ROOT) + { + if(GetPosition() == NULL && !m_Entrys.empty()) + SetPosition(*m_Entrys.begin()); + else + SetPosition(GetPosition()); + } + } + + template + void sort(_Pr3 _Pred) { + m_Entrys.sort(_Pred); + UpdateEntryCount(); + m_pRoot->SetPosition(m_pRoot->GetPosition()); + } + +private: + typename list< CListEntry* > m_Entrys; + G m_GroupData; + bool m_bOpen; +}; + + +template class CLCDList : public CLCDTextObject, public CListContainer +{ +friend CListContainer; +friend CListItem; +public: + //************************************************************************ + // Constructor + //************************************************************************ + CLCDList() : CListContainer(NULL) + { + m_pScrollbar = NULL; + m_iIndention = 10; + m_iColumns = 1; + m_bDrawTreeLines = true; + m_iEntryHeight = 10; + } + + //************************************************************************ + // Destructor + //************************************************************************ + ~CLCDList() + { + } + + //************************************************************************ + // Initializes the list + //************************************************************************ + bool Initialize() + { + if(!CLCDTextObject::Initialize()) + return false; + + return true; + } + + //************************************************************************ + // Deinitializes the list + //************************************************************************ + bool Shutdown() + { + if(!CLCDTextObject::Shutdown()) + return false; + + Clear(); + + return true; + } + + //************************************************************************ + // updates the list + //************************************************************************ + bool Update() + { + if(!CLCDTextObject::Update()) + return false; + + return true; + } + + //************************************************************************ + // draws the list + //************************************************************************ + bool Draw(CLCDGfx *pGfx) + { + if(!CLCDTextObject::Draw(pGfx)) + return false; + + SelectObject(pGfx->GetHDC(),m_hFont); + + POINT ptPrevViewportOrg = { 0, 0 }; + HRGN hRgn = NULL; + int iHeight = 0,iLimit=0; + int iYOffset = 0, iXOffset=0; + int iColWidth = (GetWidth()- (m_iColumns-1)*3)/m_iColumns; + int iSpace = GetHeight() - (GetHeight()/m_iEntryHeight)*m_iEntryHeight; + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + + int iEntriesDrawn = 0; + CListEntry *pPosition = m_Position; + + // if nothing is selected, skip drawing + if(pPosition == NULL) + return true; + + bool bDrawGroup = false; + bool bSelected = false; + + // calculate the start offset + + if(m_iStartIndex < pPosition->GetIndex()) + { + while(pPosition && pPosition->GetIndex() != m_iStartIndex) + pPosition = pPosition->GetPreviousEntry(); + } + + if(m_iStartIndex > 0 && pPosition->GetIndex() > 0) + pPosition = pPosition->GetPreviousEntry(); + + for(int iCol = 0;iColGetIndex() < m_iStartIndex) + iHeight -= m_iEntryHeight-iSpace; + else if(GetEntryCount() >= (iPerPage/m_iColumns) +1) + iHeight = iSpace; + } + + // bottom selection + while(pPosition != NULL ) + { + iYOffset = iHeight; + + bSelected = m_Position == pPosition; + bDrawGroup = pPosition->GetType() == CONTAINER; + + // ~~~~~~~~~~~~~~~~~~~~~~ + // Draw tree lines + // ~~~~~~~~~~~~~~~~~~~~~~ + + // set the clip region for the entry + int iClipHeight = m_iEntryHeight; + if(GetOrigin().y+iYOffset+iClipHeight > GetOrigin().y + GetHeight()) + iClipHeight = GetHeight() - iYOffset; + + pGfx->SetClipRegion(GetOrigin().x+iXOffset,GetOrigin().y+iYOffset, + iColWidth, iClipHeight); + + // offset the control at its origin so entry use (0,0) + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x+iXOffset, + GetOrigin().y+iYOffset, + &ptPrevViewportOrg); + + if(m_bDrawTreeLines) + { + for(int i=1;iGetLevel();i++) + { + if(i == pPosition->GetLevel()-1) + { + // - + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2,i*m_iIndention,m_iEntryHeight/2); + // | + if(pPosition == ((CListContainer*)pPosition->GetParent())->GetLastOwnEntry()) + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2); + // | + // | + else + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); + } + else + { + CListEntry *pPosition2 = pPosition; + for(int j = pPosition->GetLevel();j>i+1;j--) + pPosition2 = pPosition2->GetParent(); + // | + // | + if(pPosition2 != ((CListContainer*)pPosition2->GetParent())->GetLastOwnEntry()) + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); + } + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~ + // Draw the entry + // ~~~~~~~~~~~~~~~~~~~~~~ + pGfx->SetClipRegion(GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, + GetOrigin().y+iYOffset, + iColWidth-(pPosition->GetLevel()-1)*m_iIndention, + iClipHeight); + // set the offset + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, + GetOrigin().y+iYOffset, + &ptPrevViewportOrg); + + // draw the entry + if(!bDrawGroup) + DrawEntry(pGfx,((CListItem*)pPosition)->GetItemData(),bSelected); + else + // draw the group + DrawGroup(pGfx,((CListContainer*)pPosition)->GetGroupData(),((CListContainer*)pPosition)->IsOpen(),bSelected); + + // ~~~~~~~~~~~~~~~~~~~~~~ + + if(pPosition->GetIndex() >= m_iStartIndex && iHeight + m_iEntryHeight <= GetHeight()) + iEntriesDrawn++; + + iHeight += m_iEntryHeight; + pPosition = pPosition->GetNextEntry(); + + if(iHeight >= GetHeight()) + break; + } + if(iCol != m_iColumns-1) + { + pGfx->SetClipRegion(GetOrigin().x, + GetOrigin().y, + GetWidth(), + GetHeight()); + // set the offset + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x, + GetOrigin().y, + &ptPrevViewportOrg); + + pGfx->DrawLine(iCol*3 + iColWidth + 1,0,iCol*3 + iColWidth + 1,GetHeight()); + } + iXOffset += 3 + iColWidth; + } + + if(m_pScrollbar) + { + m_pScrollbar->ScrollTo(m_iStartIndex); + m_pScrollbar->SetSliderSize(iEntriesDrawn); + } + return true; + } + + + void SetPosition(CListEntry *pEntry) + { + CListContainer::SetPosition(pEntry); + + if(pEntry == NULL) + return; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + m_iStartIndex = pEntry->GetIndex(); + if(m_iStartIndex + (iPerPage-1) > GetEntryCount()-1) + m_iStartIndex = (GetEntryCount()-1)-(iPerPage-1); + if(m_iStartIndex < 0) + m_iStartIndex = 0; + } + + //************************************************************************ + // scrolls up + //************************************************************************ + bool ScrollUp() + { + if(m_Position != NULL) + { + CListEntry *pEntry = m_Position->GetPreviousEntry(); + if(pEntry != NULL) + { + m_Position = pEntry; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + if(m_Position->GetIndex() < m_iStartIndex) + m_iStartIndex--; + return true; + } + } + return false; + } + + //************************************************************************ + // scrolls down + //************************************************************************ + bool ScrollDown() + { + if(m_Position != NULL) + { + CListEntry *pEntry = m_Position->GetNextEntry(); + if(pEntry != NULL) + { + m_Position = pEntry; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + if(m_Position->GetIndex() >= m_iStartIndex + iPerPage) + m_iStartIndex++; + return true; + } + } + return false; + } + + //************************************************************************ + // returns the selected list entry + //************************************************************************ + CListEntry *GetSelectedEntry() + { + return m_Position; + } + + //************************************************************************ + // associates a scrollbar with the list + //************************************************************************ + void SetScrollbar(CLCDBar *pScrollbar) + { + m_pScrollbar = pScrollbar; + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iEntryCount-1); + m_pScrollbar->ScrollTo(m_Position != NULL?m_Position->GetIndex():0); + + m_pScrollbar->SetAlignment(TOP); + } + } + + //************************************************************************ + // sets the group indention in pixels + //************************************************************************ + void SetIndention(int iIndention) + { + m_iIndention = iIndention; + } + + //************************************************************************ + // sets the lists entry height + //************************************************************************ + void SetEntryHeight(int iEntryHeight) + { + m_iEntryHeight = iEntryHeight; + } + + //************************************************************************ + // returns the lists entry height + //************************************************************************ + int GetEntryHeight() + { + return m_iEntryHeight; + } + + //************************************************************************ + // enables/disables drawing of treelines + //************************************************************************ + void SetDrawTreeLines(bool bDraw) + { + m_bDrawTreeLines = bDraw; + } + + //************************************************************************ + // sets the amount of columns the list uses + //************************************************************************ + void SetColumns(int iColumns) + { + if(m_iColumns == iColumns) + return; + m_iColumns = iColumns; + SetPosition(GetPosition()); + } +protected: + //************************************************************************ + // called when the lists size has changed + //************************************************************************ + void OnSizeChanged() + { + SetPosition(GetPosition()); + } + + //************************************************************************ + // updates the list's entry count + //************************************************************************ + void UpdateEntryCount() + { + CListContainer::UpdateEntryCount(); + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iEntryCount-1); + if(GetPosition() != NULL) + m_pScrollbar->ScrollTo(GetPosition()->GetIndex()); + } + } + + //************************************************************************ + // Called to delete the specified entry + //************************************************************************ + virtual void DeleteEntry(T Entry) + { + + } + + //************************************************************************ + // Called to delete the specified group + //************************************************************************ + virtual void DeleteGroup(G Group) + { + + } + + //************************************************************************ + // Called to draw the specified entry + //************************************************************************ + virtual void DrawEntry(CLCDGfx *pGfx,T Entry, bool bSelected) + { + } + + //************************************************************************ + // Called to draw the specified entry + //************************************************************************ + virtual void DrawGroup(CLCDGfx *pGfx,G Group, bool bOpen, bool bSelected) + { + } + + + +protected: + int m_iStartIndex; + int m_iColumns; + + bool m_bDrawTreeLines; + int m_iIndention; + int m_iEntryHeight; + CLCDBar *m_pScrollbar; +}; + #endif \ No newline at end of file -- cgit v1.2.3