]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/selstore.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: generic/selstore.cpp
3 // Purpose: wxSelectionStore implementation
4 // Author: Vadim Zeitlin
6 // Created: 08.06.03 (extracted from src/generic/listctrl.cpp)
8 // Copyright: (c) 2000-2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/selstore.h"
22 // ============================================================================
24 // ============================================================================
26 // ----------------------------------------------------------------------------
28 // ----------------------------------------------------------------------------
30 bool wxSelectionStore::IsSelected(size_t item
) const
32 bool isSel
= m_itemsSel
.Index(item
) != wxNOT_FOUND
;
34 // if the default state is to be selected, being in m_itemsSel means that
35 // the item is not selected, so we have to inverse the logic
36 return m_defaultState
? !isSel
: isSel
;
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 bool wxSelectionStore::SelectItem(size_t item
, bool select
)
45 // search for the item ourselves as like this we get the index where to
46 // insert it later if needed, so we do only one search in the array instead
47 // of two (adding item to a sorted array requires a search)
48 size_t index
= m_itemsSel
.IndexForInsert(item
);
49 bool isSel
= index
< m_itemsSel
.GetCount() && m_itemsSel
[index
] == item
;
51 if ( select
!= m_defaultState
)
55 m_itemsSel
.AddAt(item
, index
);
60 else // reset to default state
64 m_itemsSel
.RemoveAt(index
);
72 bool wxSelectionStore::SelectRange(size_t itemFrom
, size_t itemTo
,
74 wxArrayInt
*itemsChanged
)
76 // 100 is hardcoded but it shouldn't matter much: the important thing is
77 // that we don't refresh everything when really few (e.g. 1 or 2) items
79 static const size_t MANY_ITEMS
= 100;
81 wxASSERT_MSG( itemFrom
<= itemTo
, _T("should be in order") );
83 // are we going to have more [un]selected items than the other ones?
84 if ( itemTo
- itemFrom
> m_count
/2 )
86 if ( select
!= m_defaultState
)
88 // the default state now becomes the same as 'select'
89 m_defaultState
= select
;
91 // so all the old selections (which had state select) shouldn't be
92 // selected any more, but all the other ones should
93 wxSelectedIndices selOld
= m_itemsSel
;
96 // TODO: it should be possible to optimize the searches a bit
97 // knowing the possible range
100 for ( item
= 0; item
< itemFrom
; item
++ )
102 if ( selOld
.Index(item
) == wxNOT_FOUND
)
103 m_itemsSel
.Add(item
);
106 for ( item
= itemTo
+ 1; item
< m_count
; item
++ )
108 if ( selOld
.Index(item
) == wxNOT_FOUND
)
109 m_itemsSel
.Add(item
);
112 // many items (> half) changed state
115 else // select == m_defaultState
117 // get the inclusive range of items between itemFrom and itemTo
118 size_t count
= m_itemsSel
.GetCount(),
119 start
= m_itemsSel
.IndexForInsert(itemFrom
),
120 end
= m_itemsSel
.IndexForInsert(itemTo
);
122 if ( start
== count
|| m_itemsSel
[start
] < itemFrom
)
127 if ( end
== count
|| m_itemsSel
[end
] > itemTo
)
134 // delete all of them (from end to avoid changing indices)
135 for ( int i
= end
; i
>= (int)start
; i
-- )
139 if ( itemsChanged
->GetCount() > MANY_ITEMS
)
141 // stop counting (see comment below)
146 itemsChanged
->Add(m_itemsSel
[i
]);
150 m_itemsSel
.RemoveAt(i
);
155 else // "few" items change state
159 itemsChanged
->Empty();
162 // just add the items to the selection
163 for ( size_t item
= itemFrom
; item
<= itemTo
; item
++ )
165 if ( SelectItem(item
, select
) && itemsChanged
)
167 itemsChanged
->Add(item
);
169 if ( itemsChanged
->GetCount() > MANY_ITEMS
)
171 // stop counting them, we'll just eat gobs of memory
172 // for nothing at all - faster to refresh everything in
180 // we set it to NULL if there are many items changing state
181 return itemsChanged
!= NULL
;
184 // ----------------------------------------------------------------------------
186 // ----------------------------------------------------------------------------
188 void wxSelectionStore::OnItemDelete(size_t item
)
190 size_t count
= m_itemsSel
.GetCount(),
191 i
= m_itemsSel
.IndexForInsert(item
);
193 if ( i
< count
&& m_itemsSel
[i
] == item
)
195 // this item itself was in m_itemsSel, remove it from there
196 m_itemsSel
.RemoveAt(i
);
201 // and adjust the index of all which follow it
204 // all following elements must be greater than the one we deleted
205 wxASSERT_MSG( m_itemsSel
[i
] > item
, _T("logic error") );