|
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: Window to a list of objects |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #ifndef C_GLXLISTWINDOW_H |
|
22 #define C_GLXLISTWINDOW_H |
|
23 |
|
24 #include <e32base.h> |
|
25 |
|
26 |
|
27 /** |
|
28 * Interface to get, setup and cleanup objects that go into a list window |
|
29 * Not strictly a factory, as also handles cleanup |
|
30 */ |
|
31 class MGlxWindowObjectFactory |
|
32 { |
|
33 public: |
|
34 /** |
|
35 * Creates an object that the list window will contain |
|
36 * (not called NewObjectL since signature would be too similar to CGlxListWindowBase::NewObjectL) |
|
37 * @return an object to be put into the window |
|
38 */ |
|
39 virtual CBase* CreateObjectL() const = 0; |
|
40 |
|
41 /** |
|
42 * Makes the object at the index ready for use |
|
43 * This is called when the object is added to the window |
|
44 */ |
|
45 virtual void SetupObject( TInt aListIndex, CBase& aObject ) = 0; |
|
46 |
|
47 /** |
|
48 * Makes the object at the index ready for removal |
|
49 * If your object builds links from other objects to it, use this |
|
50 * function to remove those links. The object will be removed from |
|
51 * the window after this function returns, and may be deleted or reused. |
|
52 */ |
|
53 virtual void CleanupObject( TInt aListIndex, CBase& aObject ) = 0; |
|
54 }; |
|
55 |
|
56 class CGlxDataWindow; |
|
57 |
|
58 /** |
|
59 * Iterator that iterates through the items in a window |
|
60 */ |
|
61 class TGlxWindowIterator |
|
62 { |
|
63 public: |
|
64 /** Constructor. Not exported since CGlxDataWindow is internal. */ |
|
65 TGlxWindowIterator( const CGlxDataWindow& aWindow ); |
|
66 /** Copy constructor */ |
|
67 IMPORT_C TGlxWindowIterator( const TGlxWindowIterator& aIterator ); |
|
68 /** |
|
69 * @return the current item index in the list and move to next |
|
70 * or KErrNotFound if has reached the end of the list |
|
71 */ |
|
72 IMPORT_C TInt operator++( TInt ); |
|
73 |
|
74 private: |
|
75 /// window being iterated |
|
76 const CGlxDataWindow* iWindow; |
|
77 /// current position of iteration |
|
78 TInt iWindowIndex; |
|
79 }; |
|
80 |
|
81 /** |
|
82 * CGlxListWindowBase |
|
83 */ |
|
84 class CGlxListWindow : public CBase |
|
85 { |
|
86 public: |
|
87 /** Constructor */ |
|
88 IMPORT_C CGlxListWindow( MGlxWindowObjectFactory& aObjectFactory ); |
|
89 /** Second-phase constructor */ |
|
90 IMPORT_C void ConstructL(); |
|
91 /** Destructor */ |
|
92 IMPORT_C ~CGlxListWindow(); |
|
93 |
|
94 /** |
|
95 * Cleans up the objects, so that the list window can be deleted |
|
96 * If the objects contained in the window do not build any links |
|
97 * from other objects to them, this function does not have to be called. |
|
98 * In this case also your implementation of CleanupObject can be empty. |
|
99 * |
|
100 * Depending on usage, may not be necessary to call on destruction |
|
101 * of the window's owner (e.g., when the whole app is being closed, |
|
102 * removing links to other objects is usually unnecessary. However, |
|
103 * if you are removing one list window but leaving others, then |
|
104 * the list window should be cleaned up, assuming your implementation |
|
105 * of CleanupObject has some code in it.) |
|
106 * |
|
107 * Cannot be called by the destructor of this class, as long as deriving |
|
108 * classes implement MGlxWindowObjectFactory, since vtable would not |
|
109 * be valid in the destructor |
|
110 */ |
|
111 IMPORT_C void Cleanup(); |
|
112 |
|
113 /** |
|
114 * Updates range offset. The range is the span of indexes that defined |
|
115 * which objects should exists as actual objects in the window (and which |
|
116 * should be abstract in the form of indexes). The range is calculated |
|
117 * as a number (aFrontOffset) of objects in the front of the focus index |
|
118 * and as a number (aRearOffset) of objects after the focus index. |
|
119 */ |
|
120 IMPORT_C void SetRangeOffsetsL( TInt aFrontOffset, TInt aRearOffset ); /// @todo depricated |
|
121 IMPORT_C void SetRangeOffsetsL( TInt aFocusIndex, TInt aTotalSize, |
|
122 TInt aFrontOffset, TInt aRearOffset ); |
|
123 |
|
124 /** @return an iterator that allows going through the items in the window */ |
|
125 IMPORT_C TGlxWindowIterator Iterator() const; |
|
126 |
|
127 /** |
|
128 * Sets the focus. |
|
129 * @param aFocusIndex index of the object to be focused in the list |
|
130 */ |
|
131 /* @todo depricated */ IMPORT_C void SetFocusIndex( TInt aFocusIndex ); |
|
132 IMPORT_C void SetFocusIndex( TInt aFocusIndex, TInt aTotalSize ); |
|
133 |
|
134 /** |
|
135 * Adds objects to the list. Updates window if necessary. |
|
136 * The function assumes that the underlying data structure has |
|
137 * already changed. |
|
138 */ |
|
139 /* @todo depricated */ IMPORT_C void AddObjects( TInt aFirstNewIndex, TInt aLastNewIndex ); |
|
140 IMPORT_C void AddObjects( TInt aFocusIndex, TInt aTotalSize, |
|
141 TInt aFirstNewIndex, TInt aLastNewIndex ); |
|
142 |
|
143 /** |
|
144 * Removes objects from the list. Updates window if necessary. |
|
145 * The function assumes that the underlying data structure has |
|
146 * already changed. |
|
147 */ |
|
148 /* @todo depricated */ IMPORT_C void RemoveObjects( TInt aFirstRemovedIndex, TInt aLastRemovedIndex ); |
|
149 IMPORT_C void RemoveObjects( TInt aFocusIndex, TInt aTotalSize, |
|
150 TInt aFirstRemovedIndex, TInt aLastRemovedIndex ); |
|
151 |
|
152 /** |
|
153 * Access to objects in window |
|
154 * For iteration through items in the window use Iterator() |
|
155 * @return a pointer to an object or NULL if not found |
|
156 */ |
|
157 IMPORT_C CBase* At( TInt aIndex ); |
|
158 IMPORT_C const CBase* At( TInt aIndex ) const; |
|
159 |
|
160 public: |
|
161 /** Range of the window in the list */ |
|
162 struct TRange |
|
163 { |
|
164 TInt iStartIndex; |
|
165 TInt iLength; |
|
166 }; |
|
167 |
|
168 private: |
|
169 /** Type of chance that happened to the full list */ |
|
170 enum TChangeType |
|
171 { |
|
172 EChangeNone, |
|
173 EChangeObjectsAdded, |
|
174 EChangeObjectsRemoved |
|
175 }; |
|
176 |
|
177 /** Class to describe a change to the full list */ |
|
178 class TChange // declare struct as class to avoid CodeScanner warning... |
|
179 { |
|
180 public: |
|
181 /** Constructor */ |
|
182 TChange( TInt aNewFocusIndex, TInt aNewTotalSize, TChangeType aChangeType, |
|
183 TInt aFirstChangedIndex, TInt aLastChangedIndex ); |
|
184 |
|
185 TInt iNewFocusIndex; |
|
186 TInt iNewTotalSize; |
|
187 TChangeType iChangeType; |
|
188 /// first index added or removed, depending on iChangeType |
|
189 TInt iFirstChangedIndex; |
|
190 /// last index added or removed, depending on iChangeType |
|
191 TInt iLastChangedIndex; |
|
192 }; |
|
193 |
|
194 /** Update the window based on the change */ |
|
195 void Update( const TChange& aChange ); |
|
196 /** Move objects from main window to working window, or object pool if not needed */ |
|
197 void PopulateExistingAndUnuseOld( const TChange& aChange ); |
|
198 /** Populate main window with items from object pool */ |
|
199 void PopulateNew(); |
|
200 /** Make working window the main window and vice versa */ |
|
201 void SwapWindows(); |
|
202 /** @return an object from the object pool */ |
|
203 CBase* UnusedObject(); |
|
204 /** |
|
205 * @return the index of the item at aIndex, when adjusted by the change, so |
|
206 * that index keeps pointing to the same logical item. |
|
207 */ |
|
208 TInt IndexAfterChange( TInt aIndex, const TChange& aChange ) const; |
|
209 |
|
210 /** @return the first and last index of the range range */ |
|
211 TRange Range( const TChange& aChange ) const; |
|
212 |
|
213 private: |
|
214 /** |
|
215 * Position of the focus |
|
216 * If not defined (=list empty) value is -1 |
|
217 */ |
|
218 /// @todo remove as soon as possible, this is causing the focus change logic on remove/addition |
|
219 /// to be specified in media list AND here |
|
220 TInt iFocusIndex; |
|
221 |
|
222 /** |
|
223 * Front offset to focus for where window will start |
|
224 * The window will start at position iFocusIndex + iFrontOffset |
|
225 * (Although it may loop around the start and end of the list) |
|
226 * Hence, iFrontOffset must be negative or zero |
|
227 */ |
|
228 TInt iFrontOffset; |
|
229 |
|
230 /** |
|
231 * Front offset to focus for where window will end |
|
232 * The window will end at position iFocusIndex + iRearOffset |
|
233 * (Although it may loop around the start and end of the list) |
|
234 * Hence, iRearOffset must be positive or zero |
|
235 */ |
|
236 TInt iRearOffset; |
|
237 |
|
238 /// Main window |
|
239 CGlxDataWindow* iWindow; |
|
240 /// Working window, used when the list is being updates |
|
241 CGlxDataWindow* iWorkingWindow; |
|
242 /// Unused objects pool |
|
243 RPointerArray< CBase > iUnusedObjects; |
|
244 |
|
245 /// Factory that creates, sets up and cleans up objects that are stored in the window |
|
246 MGlxWindowObjectFactory& iObjectFactory; |
|
247 |
|
248 __DECLARE_TEST; |
|
249 }; |
|
250 |
|
251 #endif // C_GLXLISTWINDOW_H |
|
252 |