]>
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)
8 // Copyright: (c) 2000-2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
26 #include "wx/selstore.h"
28 // ============================================================================
30 // ============================================================================
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 bool wxSelectionStore::IsSelected(unsigned item
) const
38 bool isSel
= m_itemsSel
.Index(item
) != wxNOT_FOUND
;
40 // if the default state is to be selected, being in m_itemsSel means that
41 // the item is not selected, so we have to inverse the logic
42 return m_defaultState
? !isSel
: isSel
;
45 // ----------------------------------------------------------------------------
47 // ----------------------------------------------------------------------------
49 bool wxSelectionStore::SelectItem(unsigned item
, bool select
)
51 // search for the item ourselves as like this we get the index where to
52 // insert it later if needed, so we do only one search in the array instead
53 // of two (adding item to a sorted array requires a search)
54 size_t index
= m_itemsSel
.IndexForInsert(item
);
55 bool isSel
= index
< m_itemsSel
.GetCount() && m_itemsSel
[index
] == item
;
57 if ( select
!= m_defaultState
)
61 m_itemsSel
.AddAt(item
, index
);
66 else // reset to default state
70 m_itemsSel
.RemoveAt(index
);
78 bool wxSelectionStore::SelectRange(unsigned itemFrom
, unsigned itemTo
,
80 wxArrayInt
*itemsChanged
)
82 // 100 is hardcoded but it shouldn't matter much: the important thing is
83 // that we don't refresh everything when really few (e.g. 1 or 2) items
85 static const unsigned MANY_ITEMS
= 100;
87 wxASSERT_MSG( itemFrom
<= itemTo
, wxT("should be in order") );
89 // are we going to have more [un]selected items than the other ones?
90 if ( itemTo
- itemFrom
> m_count
/2 )
92 if ( select
!= m_defaultState
)
94 // the default state now becomes the same as 'select'
95 m_defaultState
= select
;
97 // so all the old selections (which had state select) shouldn't be
98 // selected any more, but all the other ones should
99 wxSelectedIndices selOld
= m_itemsSel
;
102 // TODO: it should be possible to optimize the searches a bit
103 // knowing the possible range
106 for ( item
= 0; item
< itemFrom
; item
++ )
108 if ( selOld
.Index(item
) == wxNOT_FOUND
)
109 m_itemsSel
.Add(item
);
112 for ( item
= itemTo
+ 1; item
< m_count
; item
++ )
114 if ( selOld
.Index(item
) == wxNOT_FOUND
)
115 m_itemsSel
.Add(item
);
118 // many items (> half) changed state
121 else // select == m_defaultState
123 // get the inclusive range of items between itemFrom and itemTo
124 size_t count
= m_itemsSel
.GetCount(),
125 start
= m_itemsSel
.IndexForInsert(itemFrom
),
126 end
= m_itemsSel
.IndexForInsert(itemTo
);
128 if ( start
== count
|| m_itemsSel
[start
] < itemFrom
)
133 if ( end
== count
|| m_itemsSel
[end
] > itemTo
)
140 // delete all of them (from end to avoid changing indices)
141 for ( int i
= end
; i
>= (int)start
; i
-- )
145 if ( itemsChanged
->GetCount() > MANY_ITEMS
)
147 // stop counting (see comment below)
152 itemsChanged
->Add(m_itemsSel
[i
]);
156 m_itemsSel
.RemoveAt(i
);
161 else // "few" items change state
165 itemsChanged
->Empty();
168 // just add the items to the selection
169 for ( unsigned item
= itemFrom
; item
<= itemTo
; item
++ )
171 if ( SelectItem(item
, select
) && itemsChanged
)
173 itemsChanged
->Add(item
);
175 if ( itemsChanged
->GetCount() > MANY_ITEMS
)
177 // stop counting them, we'll just eat gobs of memory
178 // for nothing at all - faster to refresh everything in
186 // we set it to NULL if there are many items changing state
187 return itemsChanged
!= NULL
;
190 // ----------------------------------------------------------------------------
192 // ----------------------------------------------------------------------------
194 void wxSelectionStore::OnItemDelete(unsigned item
)
196 size_t count
= m_itemsSel
.GetCount(),
197 i
= m_itemsSel
.IndexForInsert(item
);
199 if ( i
< count
&& m_itemsSel
[i
] == item
)
201 // this item itself was in m_itemsSel, remove it from there
202 m_itemsSel
.RemoveAt(i
);
207 // and adjust the index of all which follow it
210 // all following elements must be greater than the one we deleted
211 wxASSERT_MSG( m_itemsSel
[i
] > item
, wxT("logic error") );
217 void wxSelectionStore::SetItemCount(unsigned count
)
219 // forget about all items whose indices are now invalid if the size
221 if ( count
< m_count
)
223 for ( size_t i
= m_itemsSel
.GetCount(); i
> 0; i
-- )
225 if ( m_itemsSel
[i
- 1] >= count
)
226 m_itemsSel
.RemoveAt(i
- 1);
230 // remember the new number of items