]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/selstore.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/selstore.cpp
3 // Purpose: wxSelectionStore implementation
4 // Author: Vadim Zeitlin
6 // Created: 08.06.03 (extracted from src/generic/listctrl.cpp)
7 // Copyright: (c) 2000-2003 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
25 #include "wx/selstore.h"
27 // ============================================================================
29 // ============================================================================
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 bool wxSelectionStore::IsSelected(unsigned item
) const
37 bool isSel
= m_itemsSel
.Index(item
) != wxNOT_FOUND
;
39 // if the default state is to be selected, being in m_itemsSel means that
40 // the item is not selected, so we have to inverse the logic
41 return m_defaultState
? !isSel
: isSel
;
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 bool wxSelectionStore::SelectItem(unsigned item
, bool select
)
50 // search for the item ourselves as like this we get the index where to
51 // insert it later if needed, so we do only one search in the array instead
52 // of two (adding item to a sorted array requires a search)
53 size_t index
= m_itemsSel
.IndexForInsert(item
);
54 bool isSel
= index
< m_itemsSel
.GetCount() && m_itemsSel
[index
] == item
;
56 if ( select
!= m_defaultState
)
60 m_itemsSel
.AddAt(item
, index
);
65 else // reset to default state
69 m_itemsSel
.RemoveAt(index
);
77 bool wxSelectionStore::SelectRange(unsigned itemFrom
, unsigned itemTo
,
79 wxArrayInt
*itemsChanged
)
81 // 100 is hardcoded but it shouldn't matter much: the important thing is
82 // that we don't refresh everything when really few (e.g. 1 or 2) items
84 static const unsigned MANY_ITEMS
= 100;
86 wxASSERT_MSG( itemFrom
<= itemTo
, wxT("should be in order") );
88 // are we going to have more [un]selected items than the other ones?
89 if ( itemTo
- itemFrom
> m_count
/2 )
91 if ( select
!= m_defaultState
)
93 // the default state now becomes the same as 'select'
94 m_defaultState
= select
;
96 // so all the old selections (which had state select) shouldn't be
97 // selected any more, but all the other ones should
98 wxSelectedIndices selOld
= m_itemsSel
;
101 // TODO: it should be possible to optimize the searches a bit
102 // knowing the possible range
105 for ( item
= 0; item
< itemFrom
; item
++ )
107 if ( selOld
.Index(item
) == wxNOT_FOUND
)
108 m_itemsSel
.Add(item
);
111 for ( item
= itemTo
+ 1; item
< m_count
; item
++ )
113 if ( selOld
.Index(item
) == wxNOT_FOUND
)
114 m_itemsSel
.Add(item
);
117 // many items (> half) changed state
120 else // select == m_defaultState
122 // get the inclusive range of items between itemFrom and itemTo
123 size_t count
= m_itemsSel
.GetCount(),
124 start
= m_itemsSel
.IndexForInsert(itemFrom
),
125 end
= m_itemsSel
.IndexForInsert(itemTo
);
127 if ( start
== count
|| m_itemsSel
[start
] < itemFrom
)
132 if ( end
== count
|| m_itemsSel
[end
] > itemTo
)
139 // delete all of them (from end to avoid changing indices)
140 for ( int i
= end
; i
>= (int)start
; i
-- )
144 if ( itemsChanged
->GetCount() > MANY_ITEMS
)
146 // stop counting (see comment below)
151 itemsChanged
->Add(m_itemsSel
[i
]);
155 m_itemsSel
.RemoveAt(i
);
160 else // "few" items change state
164 itemsChanged
->Empty();
167 // just add the items to the selection
168 for ( unsigned item
= itemFrom
; item
<= itemTo
; item
++ )
170 if ( SelectItem(item
, select
) && itemsChanged
)
172 itemsChanged
->Add(item
);
174 if ( itemsChanged
->GetCount() > MANY_ITEMS
)
176 // stop counting them, we'll just eat gobs of memory
177 // for nothing at all - faster to refresh everything in
185 // we set it to NULL if there are many items changing state
186 return itemsChanged
!= NULL
;
189 // ----------------------------------------------------------------------------
191 // ----------------------------------------------------------------------------
193 void wxSelectionStore::OnItemDelete(unsigned item
)
195 size_t count
= m_itemsSel
.GetCount(),
196 i
= m_itemsSel
.IndexForInsert(item
);
198 if ( i
< count
&& m_itemsSel
[i
] == item
)
200 // this item itself was in m_itemsSel, remove it from there
201 m_itemsSel
.RemoveAt(i
);
206 // and adjust the index of all which follow it
209 // all following elements must be greater than the one we deleted
210 wxASSERT_MSG( m_itemsSel
[i
] > item
, wxT("logic error") );
216 void wxSelectionStore::SetItemCount(unsigned count
)
218 // forget about all items whose indices are now invalid if the size
220 if ( count
< m_count
)
222 for ( size_t i
= m_itemsSel
.GetCount(); i
> 0; i
-- )
224 if ( m_itemsSel
[i
- 1] >= count
)
225 m_itemsSel
.RemoveAt(i
- 1);
229 // remember the new number of items