|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: List of media items, which has focus |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #ifndef __C_GLXNAVIGABLELIST_H__ |
|
22 #define __C_GLXNAVIGABLELIST_H__ |
|
23 |
|
24 #include <e32base.h> |
|
25 #include <glxlistdefs.h> |
|
26 |
|
27 |
|
28 #include "glxmediaid.h" |
|
29 #include "mglxitemlistobserver.h" |
|
30 |
|
31 /** @todo |
|
32 Other required changes: |
|
33 -Media list must not media for static items to be requested: Remove static item indexes from the list attribute context returned |
|
34 -Thumbnail context needs to give a low score (very low) to static items, so that it does not stop requesting thumbnails |
|
35 */ |
|
36 |
|
37 // Forward declarations |
|
38 class TGlxMedia; |
|
39 class CGlxMedia; |
|
40 class CGlxStaticItemList; |
|
41 class CMPXCollectionPath; |
|
42 class MGlxMediaPool; |
|
43 class MGlxMediaUser; |
|
44 class MGlxNavigableListObserver; |
|
45 |
|
46 /** |
|
47 * Namespace for CGlxNavigableList class' helpers |
|
48 */ |
|
49 namespace NGlxNavigableList |
|
50 { |
|
51 class MSelectionIndexStrategy; |
|
52 } |
|
53 |
|
54 /** |
|
55 * CGlxNavigableList |
|
56 * |
|
57 * List that has |
|
58 * - non-static items |
|
59 * - static items |
|
60 * - focus |
|
61 * - selection |
|
62 * |
|
63 * @author Aki Vanhatalo |
|
64 * |
|
65 * @internal reviewed 16/07/2007 by Kimmo Hoikka |
|
66 * |
|
67 * @ingroup mlm_media_list_manager_design |
|
68 */ |
|
69 NONSHARABLE_CLASS( CGlxNavigableList ) : public CBase, public MGlxItemListObserver |
|
70 { |
|
71 public: |
|
72 /** |
|
73 * Two-phase constructor |
|
74 * @param aIdSpaceId id of the "space" in which all item ids are unique |
|
75 * @param aObserver Observer to be notified |
|
76 * @param aMediaUser User of media objects - media objects that |
|
77 * this list links to will be linked to the user, so that |
|
78 * cache manager is able to quickly access the media lists |
|
79 * that use particular media objects |
|
80 */ |
|
81 static CGlxNavigableList* NewL( const TGlxIdSpaceId& aIdSpaceId, |
|
82 MGlxNavigableListObserver& aObserver, MGlxMediaUser& aMediaUser ); |
|
83 |
|
84 /** |
|
85 * Destructor |
|
86 */ |
|
87 ~CGlxNavigableList(); |
|
88 |
|
89 /** |
|
90 * @return id space id |
|
91 */ |
|
92 const TGlxIdSpaceId& IdSpaceId() const; |
|
93 |
|
94 /** |
|
95 * Synchronises the list with new path |
|
96 * Sends added/removed notifications as necessary |
|
97 * Note: Does not copy the selected items or focus |
|
98 * |
|
99 * @param aSource path with item ids |
|
100 * @param aMediaPool interface from which to ask for media items |
|
101 */ |
|
102 void SetContentsL( const CMPXCollectionPath& aSource, |
|
103 const MGlxMediaPool& aMediaPool ); |
|
104 |
|
105 /** |
|
106 * Re-orders the list with new path |
|
107 * Sends all items removed followed by all items added (from new path) notifications |
|
108 * Maintains the selected items and focus |
|
109 * |
|
110 * @param aSource path with item ids |
|
111 * @param aMediaPool interface from which to ask for media items |
|
112 */ |
|
113 void ReorderContentsL( const CMPXCollectionPath& aSource, |
|
114 const MGlxMediaPool& aMediaPool ); |
|
115 |
|
116 /** |
|
117 * Remove an item form the list |
|
118 * Sends removed notification |
|
119 * |
|
120 * @param aIdSpaceId Id space of the item. Use KGlxStaticItemIdSpaceId |
|
121 * if you want to permanently remove a static item. |
|
122 * @param aItemId Id of item to remove |
|
123 */ |
|
124 void Remove( const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aItemId ); |
|
125 |
|
126 /** |
|
127 * Remove any pointers to the media object at the specified index |
|
128 * @param aIndex index of media object from which to remove a reference |
|
129 */ |
|
130 void RemoveReference( TInt aIndex ); |
|
131 |
|
132 /** |
|
133 * Adds a static item and takes ownership |
|
134 * Note: In case of a leave, aStaticItem may have been modified. |
|
135 * It is assumed that since ownership of the static item is passed, |
|
136 * the object is free to be modified. |
|
137 * @param aStaticItem Static item to be added |
|
138 * @param aTargetPosition Whether to be added at beginning or end |
|
139 */ |
|
140 void AddStaticItemL( CGlxMedia* aStaticItem, |
|
141 NGlxListDefs::TInsertionPosition aTargetPosition ); |
|
142 |
|
143 /** |
|
144 * Enables or disables static items |
|
145 * @param aEnabled true if static items should be enabled |
|
146 * false if static items should be disabled |
|
147 */ |
|
148 void SetStaticItemsEnabled( TBool aEnabled ); |
|
149 |
|
150 /** |
|
151 * @return ETrue if static items are enabled |
|
152 */ |
|
153 TBool IsStaticItemsEnabled() const; |
|
154 |
|
155 /** |
|
156 * @param aType type of count wanted |
|
157 * @return count of items, as specified in aType |
|
158 */ |
|
159 TInt Count( NGlxListDefs::TCountType aType = NGlxListDefs::ECountAll ) const; |
|
160 |
|
161 /** |
|
162 * @return item at index |
|
163 */ |
|
164 TGlxMedia& Item( TInt aIndex ); |
|
165 |
|
166 /** |
|
167 * @param aId Id of item for which index is needed |
|
168 * @return item with id aId or KErrNotFound |
|
169 */ |
|
170 TInt Index(const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aId ) const; |
|
171 |
|
172 /** |
|
173 * Sets the initial focus position, first or last item |
|
174 * @param aFocusInitialPosition initial focus on first or last item |
|
175 */ |
|
176 void SetFocusInitialPosition(NGlxListDefs::TFocusInitialPosition aFocusInitialPosition); |
|
177 |
|
178 /** |
|
179 * @return index of focused item |
|
180 */ |
|
181 TInt FocusIndex() const; |
|
182 |
|
183 /** |
|
184 * Sets focus to item at index |
|
185 * Notifies observer via HandleFocusChangedL |
|
186 * @param aType EAbsolute or ERelative |
|
187 * @param aValue If aType is EAbsolute, the new index value |
|
188 * If aType is ERelative, the amount of indexes to move focus |
|
189 */ |
|
190 void SetFocus( NGlxListDefs::TFocusSetType aType, TInt aValue ); |
|
191 |
|
192 /** |
|
193 * Resets the focus to the initial position |
|
194 */ |
|
195 void ResetFocus(); |
|
196 |
|
197 /** |
|
198 * @return ETrue if item is selected, EFalse if not |
|
199 */ |
|
200 TBool IsSelected( TInt aIndex ) const; |
|
201 |
|
202 /** |
|
203 * Selects or deselects an item. |
|
204 * If item is already at desired selection state, does nothing. |
|
205 * Otherwise, calls back via HandleItemSelected. |
|
206 * |
|
207 * @param aIndex index of item to be selected/deselected |
|
208 * @param aSelected true if item should be selected |
|
209 * false if item should be deselected |
|
210 */ |
|
211 void SetSelectedL( TInt aIndex, TBool aSelected ); |
|
212 |
|
213 /** |
|
214 * @return Array of indexes of items that are selected |
|
215 */ |
|
216 const TArray< TInt > SelectedItemIndices() const; |
|
217 |
|
218 // From MGlxItemListObserver |
|
219 void HandleItemsAdded( TInt aFirstInsertedIndex, TInt aCount ); |
|
220 void HandleItemsRemoved( TInt aRemovedFromIndex, TInt aCount ); |
|
221 |
|
222 private: |
|
223 /** |
|
224 * Constructor |
|
225 * @param aObserver Observer to be notified |
|
226 */ |
|
227 CGlxNavigableList( MGlxNavigableListObserver& aObserver ); |
|
228 |
|
229 /** |
|
230 * Second-phase constructor |
|
231 * @param aIdSpaceId id of the "space" in which all item ids are unique |
|
232 * @param aMediaUser User of media objects |
|
233 */ |
|
234 void ConstructL( const TGlxIdSpaceId& aIdSpaceId, |
|
235 MGlxMediaUser& aMediaUser ); |
|
236 |
|
237 /** @return id of focused item or KGlxIdNone if nothing focused */ |
|
238 TGlxMediaId FocusId() const; |
|
239 |
|
240 /** |
|
241 * Populates provided array with currently selected item ids |
|
242 * @param aItemIds array to contain selected item ids |
|
243 */ |
|
244 void SelectionL( RArray< TGlxMediaId >& aItemIds ) const; |
|
245 |
|
246 /** |
|
247 * Sets list contents to nothing, but leaves static items |
|
248 * @param aMediaPool interface from which to ask for media items |
|
249 */ |
|
250 void ClearContentsL( const MGlxMediaPool& aMediaPool ); |
|
251 |
|
252 /** |
|
253 * Selects items by id |
|
254 * Ok to call if item does not exist in list |
|
255 * @param aItemIds List of ids of items to select |
|
256 */ |
|
257 void SelectL( const RArray< TGlxMediaId >& aItemIds ); |
|
258 |
|
259 /** |
|
260 * Select item at index |
|
261 * @param aIndex index to be selected |
|
262 */ |
|
263 void SelectL( TInt aIndex ); |
|
264 |
|
265 /** |
|
266 * Select item at index |
|
267 * Must call ReserveFreeSpaceInSelectionL first |
|
268 * @param aIndex index to be selected |
|
269 */ |
|
270 void Select( TInt aIndex ); |
|
271 |
|
272 /** |
|
273 * Reserve free space in selection, so that Select |
|
274 * can be safely called |
|
275 * @param aCount Number of times Select will be called (or larger) |
|
276 */ |
|
277 void ReserveFreeSpaceInSelectionL( TInt aCount ); |
|
278 |
|
279 /** |
|
280 * Deselect item at index |
|
281 * @param aIndex index to be deselected |
|
282 */ |
|
283 void Deselect( TInt aIndex ); |
|
284 |
|
285 /** |
|
286 * Sets the initial focus |
|
287 */ |
|
288 void SetInitialFocus(); |
|
289 |
|
290 /** |
|
291 * Set focus by id. Notifies observer |
|
292 * Does nothing if id does not exist in list |
|
293 * @param aItemId Id of the item to be focused |
|
294 */ |
|
295 void SetFocus( const TGlxMediaId& aItemId ); |
|
296 |
|
297 /** |
|
298 * Set focus index |
|
299 * @param aIndex New focus index |
|
300 * @return Focus change type |
|
301 */ |
|
302 NGlxListDefs::TFocusChangeType SetFocus( TInt aIndex ); |
|
303 |
|
304 /** |
|
305 * Move focus index |
|
306 * @param aDelta amount of indexes to move focus by |
|
307 * @return Focus change type |
|
308 */ |
|
309 NGlxListDefs::TFocusChangeType MoveFocus( TInt aDelta ); |
|
310 |
|
311 /** |
|
312 * Optionally, notify observer of focus change |
|
313 * @param aType Focus change type |
|
314 * @param aOldFocusIndex Focus index before focus being moved |
|
315 * @param aNotify if ETrue, notifies observer |
|
316 * if EFalse, does nothing |
|
317 */ |
|
318 void NotifyFocusChange( NGlxListDefs::TFocusChangeType aType, |
|
319 TInt aNewIndex, TBool aNotify ); |
|
320 |
|
321 /** |
|
322 * Update focus after items have been inserted to the list |
|
323 * @param aInsertionIndex Insertion point |
|
324 * @param aInsertionCount Number of items inserted |
|
325 * @return ETrue if observer should be notified of focus change |
|
326 * EFalse if not |
|
327 */ |
|
328 TInt UpdateFocusAfterInsertion( TInt aInsertionIndex, TInt aInsertionCount ); |
|
329 |
|
330 /** |
|
331 * Update selection item indexes after removal of items |
|
332 * @param aRemovedFromIndex First removed item index |
|
333 * @param aRemovedCount Number of items removed |
|
334 */ |
|
335 void UpdateSelectionAfterRemove( TInt aRemovedFromIndex, TInt aRemovedCount ); |
|
336 |
|
337 /** |
|
338 * Update focus after items have been removed from the list |
|
339 * @param aRemovedFromIndex index of first removed item |
|
340 * @param aRemovedCount Number of items removed |
|
341 * @return ETrue if observer should be notified of focus change |
|
342 * EFalse if not |
|
343 */ |
|
344 TBool UpdateFocusAfterRemoval( TInt aRemovedFromIndex, TInt aRemovedCount ); |
|
345 |
|
346 /** |
|
347 * Move focus if index changed. |
|
348 * @param aChangedIndex Only move focus if index changed. |
|
349 * @param aMoveBy Amount to move by |
|
350 * @return ETrue if observer should be notified of focus change |
|
351 * EFalse if not |
|
352 */ |
|
353 TBool MoveFocusIfIndexChanged( TInt aChangedIndex, TInt aMoveBy ); |
|
354 |
|
355 |
|
356 /** |
|
357 * Run selection index strategy for all selection item indexes that point |
|
358 * to items between aFromIndex and aToIndex (inclusive) |
|
359 * @param aFromIndex First item index to be processed (not selection item index, |
|
360 * but item index) |
|
361 * @param aToIndex Last item index to be processed (not selection item index, |
|
362 * but item index) |
|
363 * @param aStrategy Strategy object that contains the logic of what to do |
|
364 * with the selection index |
|
365 */ |
|
366 void ProcessSelectionItemIndicesBetweenIndexes( TInt aFromIndex, |
|
367 TInt aToIndex, NGlxNavigableList::MSelectionIndexStrategy& aStrategy ); |
|
368 |
|
369 /** |
|
370 * Find the first selected item index that points to an item index |
|
371 * smaller aMaxIndex |
|
372 * @aMaxIndex The item index pointed to by the returned selection index has |
|
373 * to be smaller than this parameter |
|
374 * @return selected item index (in iSelectedItemIndices) |
|
375 */ |
|
376 TInt FindFirstSelectedItemIndexBefore( TInt aMaxIndex ); |
|
377 |
|
378 private: |
|
379 /// list of items |
|
380 CGlxStaticItemList* iItemList; // own |
|
381 |
|
382 |
|
383 /// Focus initial position, first or last item |
|
384 NGlxListDefs::TFocusInitialPosition iFocusInitialPosition; |
|
385 |
|
386 /// Focus index or KErrNotFound |
|
387 TInt iFocusIndex; |
|
388 |
|
389 /// Indexes of selected items |
|
390 RArray<TInt> iSelectedItemIndices; |
|
391 |
|
392 /// Observer for changes |
|
393 MGlxNavigableListObserver& iObserver; |
|
394 |
|
395 /// Free space in iSelectedItemIndices. Used to make sure Select(...) is not |
|
396 /// called without calling ReserveFreeSpaceInSelectionL first |
|
397 __DEBUG_ONLY( TInt _iSelectionReserveCount ); |
|
398 |
|
399 __DECLARE_TEST; |
|
400 }; |
|
401 |
|
402 #endif // __C_GLXNAVIGABLELIST_H__ |
|
403 |