|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions are met: |
|
7 * |
|
8 * - Redistributions of source code must retain the above copyright notice, |
|
9 * this list of conditions and the following disclaimer. |
|
10 * - Redistributions in binary form must reproduce the above copyright notice, |
|
11 * this list of conditions and the following disclaimer in the documentation |
|
12 * and/or other materials provided with the distribution. |
|
13 * - Neither the name of Nokia Corporation nor the names of its contributors |
|
14 * may be used to endorse or promote products derived from this software |
|
15 * without specific prior written permission. |
|
16 * |
|
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 * POSSIBILITY OF SUCH DAMAGE. |
|
28 * |
|
29 * Initial Contributors: |
|
30 * Nokia Corporation - initial contribution. |
|
31 * |
|
32 * Contributors: |
|
33 * |
|
34 * Description: |
|
35 * |
|
36 */ |
|
37 |
|
38 using System; |
|
39 using System.Drawing; |
|
40 using HeapLib.Cells; |
|
41 using SymbianUtils.RawItems; |
|
42 |
|
43 namespace HeapCtrlLib.Utilities |
|
44 { |
|
45 public class HeapCellMetaData |
|
46 { |
|
47 #region Constructors & destructor |
|
48 public HeapCellMetaData( HeapRenderingNavigator aNavigator ) |
|
49 { |
|
50 aNavigator.iNavBegin += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavBegin( Navigator_NavBegin ); |
|
51 aNavigator.iNavEnd += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavEnd( Navigator_NavEnd ); |
|
52 aNavigator.iNavHeapCellBegin += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavHeapCellBegin( Navigator_NavHeapCellBegin ); |
|
53 aNavigator.iNavHeapCellEnd += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavHeapCellEnd( Navigator_NavHeapCellEnd ); |
|
54 aNavigator.iNavNewColumn += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavNewColumn( Navigator_NavNewColumn ); |
|
55 aNavigator.iNavNewRowBody += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavNewRowBody( Navigator_NavNewRowBody ); |
|
56 } |
|
57 #endregion |
|
58 |
|
59 #region Properties |
|
60 public Point BoxCoordinates |
|
61 { |
|
62 get { return iBoxCoordinates; } |
|
63 set { iBoxCoordinates = value; } |
|
64 } |
|
65 |
|
66 public int RemainingBoxes |
|
67 { |
|
68 get { return iRemainingBoxes; } |
|
69 set { iRemainingBoxes = value; } |
|
70 } |
|
71 |
|
72 public int RemainingBoxesAfterThisRow |
|
73 { |
|
74 get { return iRemainingBoxesAfterThisRow; } |
|
75 set { iRemainingBoxesAfterThisRow = value; } |
|
76 } |
|
77 |
|
78 public int RemainingRows |
|
79 { |
|
80 get { return iRemainingRows; } |
|
81 set { iRemainingRows = value; } |
|
82 } |
|
83 |
|
84 public long RemainingBytes |
|
85 { |
|
86 get { return iRemainingBytes; } |
|
87 set { iRemainingBytes = value; } |
|
88 } |
|
89 |
|
90 public int CellBoxIndex |
|
91 { |
|
92 get { return iCellBoxIndex; } |
|
93 set { iCellBoxIndex = value; } |
|
94 } |
|
95 |
|
96 public int CellRowIndex |
|
97 { |
|
98 get { return iCellRowIndex; } |
|
99 set { iCellRowIndex = value; } |
|
100 } |
|
101 |
|
102 public int CellBoxCount |
|
103 { |
|
104 get { return iCellBoxCount; } |
|
105 set { iCellBoxCount = value; } |
|
106 } |
|
107 |
|
108 public RawItem RawItem |
|
109 { |
|
110 get { return iRawItem; } |
|
111 } |
|
112 |
|
113 public HeapCell.TRegion Region |
|
114 { |
|
115 get |
|
116 { |
|
117 System.Diagnostics.Debug.Assert( iCell != null, "Not rendering a heap cell" ); |
|
118 System.Diagnostics.Debug.Assert( iAddress > 0, "Invalid current address" ); |
|
119 // |
|
120 HeapCell.TRegion region = iCell.RegionForAddress( iAddress ); |
|
121 return region; |
|
122 } |
|
123 } |
|
124 |
|
125 public HeapCellBorderInfo Borders |
|
126 { |
|
127 get { return iBorders; } |
|
128 set { iBorders = value; } |
|
129 } |
|
130 |
|
131 // Set by the content renderer, read by the border renderer |
|
132 public Color CellBoxColor |
|
133 { |
|
134 get { return iCellBoxColor; } |
|
135 set { iCellBoxColor = value; } |
|
136 } |
|
137 #endregion |
|
138 |
|
139 #region Internal methods |
|
140 private void CalculateBorders( HeapCell aCell, long aAddress, Size aDimensions ) |
|
141 { |
|
142 long remainingBoxes = ( aCell.EndAddress - aAddress ) / SymbianUtils.RawItems.RawItem.KSizeOfOneRawItemInBytes; |
|
143 |
|
144 // Start with no borders |
|
145 Borders.Reset(); |
|
146 |
|
147 // How many boxes are left to render on this row |
|
148 int remainingBoxesForThisLine = ( aDimensions.Width - BoxCoordinates.X ); |
|
149 |
|
150 // Its the first line if we are drawing the first row, or if we're drawing the |
|
151 // second row and there weren't any boxes from this heap cell directly above us |
|
152 // in the grid. |
|
153 bool firstLine = ( CellRowIndex == 0 ); |
|
154 if ( CellRowIndex == 1 ) |
|
155 { |
|
156 int numberOfBoxesDrawnOnPreviousLine = ( CellBoxIndex - BoxCoordinates.X ); |
|
157 int xPosOfFirstBox = aDimensions.Width - numberOfBoxesDrawnOnPreviousLine; |
|
158 firstLine = ( BoxCoordinates.X < xPosOfFirstBox ); |
|
159 } |
|
160 Borders.SetBorder( THeapCellBorderType.ETop, firstLine ); |
|
161 |
|
162 // Its the last line if we are drawing the last row, or then if we're drawing |
|
163 // the last-but-one row and there weren't any boxes from this heap cell directly |
|
164 // below us in the grid. |
|
165 bool lastLine = ( RemainingBoxes <= remainingBoxesForThisLine ); |
|
166 if ( RemainingRows > 0 && BoxCoordinates.Y == aDimensions.Height - 1 ) |
|
167 { |
|
168 lastLine = true; |
|
169 } |
|
170 else if ( RemainingRows == 1 ) |
|
171 { |
|
172 // Now we need to work out how many boxes of the next row will be |
|
173 // required to finish rendering it fully. |
|
174 lastLine = ( BoxCoordinates.X >= RemainingBoxesAfterThisRow ); |
|
175 } |
|
176 Borders.SetBorder( THeapCellBorderType.EBottom, lastLine ); |
|
177 |
|
178 // Its the first box if it is the absolute first box we have rendered for a given |
|
179 // cell, or then it is the first box in a new row. |
|
180 bool firstBox = ( CellBoxIndex == 0 ) || ( BoxCoordinates.X == 0 ); |
|
181 Borders.SetBorder( THeapCellBorderType.ELeft, firstBox ); |
|
182 |
|
183 // Its the last box if it is the absolute last box we have rendered for a given |
|
184 // cell, or then it is the last box in a new row. |
|
185 bool lastBox = ( CellBoxIndex == CellBoxCount - 1 ) || ( remainingBoxes == 0 ) || ( BoxCoordinates.X == aDimensions.Width - 1 ); |
|
186 Borders.SetBorder( THeapCellBorderType.ERight, lastBox ); |
|
187 } |
|
188 #endregion |
|
189 |
|
190 #region Navigator call backs |
|
191 private void Navigator_NavBegin() |
|
192 { |
|
193 } |
|
194 |
|
195 private void Navigator_NavEnd() |
|
196 { |
|
197 iCell = null; |
|
198 } |
|
199 |
|
200 private void Navigator_NavHeapCellBegin( HeapCell aCell, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding ) |
|
201 { |
|
202 // Starting a new cell |
|
203 iCell = aCell; |
|
204 iAddress = aAddress; |
|
205 |
|
206 // This contains the absolute number of boxes required to render a given |
|
207 // heap cell. |
|
208 CellBoxCount = (int) ( aCell.Length / SymbianUtils.RawItems.RawItem.KSizeOfOneRawItemInBytes ); |
|
209 BoxCoordinates = new Point(); |
|
210 RemainingBoxes = 0; |
|
211 RemainingBoxesAfterThisRow = 0; |
|
212 RemainingRows = 0; |
|
213 RemainingBytes = 0; |
|
214 CellRowIndex = 0; |
|
215 Borders.Reset(); |
|
216 |
|
217 // Reset current raw item - we won't have a new one until we hit the payload section |
|
218 iRawItem = null; |
|
219 |
|
220 // This starts at -1 since the first act of |
|
221 // preparing the meta data is to increment the index by one. |
|
222 CellBoxIndex = -1; |
|
223 } |
|
224 |
|
225 private void Navigator_NavHeapCellEnd( HeapCell aCell, HeapCellMetaData aMetaData, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding ) |
|
226 { |
|
227 // Finished with the cell... |
|
228 iCell = null; |
|
229 } |
|
230 |
|
231 private void Navigator_NavNewColumn( HeapCell aCell, HeapCellMetaData aMetaData, uint aAddress, Point aPixelPos, Point aBoxPos, Size aDimensions, Size aBoxSize, Size aPadding ) |
|
232 { |
|
233 System.Diagnostics.Debug.Assert( iCell != null && iCell.Address == aCell.Address ); |
|
234 |
|
235 // Indicate that we're processing a new box |
|
236 ++CellBoxIndex; |
|
237 iAddress = aAddress; |
|
238 |
|
239 // Set our box coordinates |
|
240 iBoxCoordinates = aBoxPos; |
|
241 |
|
242 // Get current raw item if we're in the payload section |
|
243 iRawItem = null; |
|
244 try |
|
245 { |
|
246 HeapCell.TRegion region = Region; |
|
247 if ( region == HeapCell.TRegion.EPayload ) |
|
248 { |
|
249 iRawItem = iCell[ aAddress ]; |
|
250 } |
|
251 } |
|
252 catch( ArgumentException ) |
|
253 { |
|
254 } |
|
255 |
|
256 |
|
257 // Some up front calculations that we'll need below... |
|
258 RemainingBytes = aCell.Remainder( aAddress ); |
|
259 int remainingBoxesForThisLine = ( aDimensions.Width - BoxCoordinates.X ); |
|
260 RemainingBoxes = (int) ( RemainingBytes / SymbianUtils.RawItems.RawItem.KSizeOfOneRawItemInBytes ); |
|
261 RemainingBoxesAfterThisRow = Math.Max( 0, RemainingBoxes - remainingBoxesForThisLine ); |
|
262 |
|
263 // If we can render all the remaining boxes in the not-yet-drawn |
|
264 // boxes from this row, we don't need anymore rows. |
|
265 RemainingRows = 0; |
|
266 if ( RemainingBoxesAfterThisRow > 0 ) |
|
267 { |
|
268 // Otherwise, we need to identify how many more rows we will need |
|
269 // in order to complete the remaining boxes that are left over |
|
270 // after this row's boxes. |
|
271 RemainingRows = ( RemainingBoxesAfterThisRow / aDimensions.Width ) + 1; |
|
272 } |
|
273 |
|
274 // Work out the borders that should be enabled for the cell |
|
275 CalculateBorders( aCell, aAddress, aDimensions ); |
|
276 } |
|
277 |
|
278 private void Navigator_NavNewRowBody( HeapCellMetaData aMetaData, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding ) |
|
279 { |
|
280 ++CellRowIndex; |
|
281 } |
|
282 #endregion |
|
283 |
|
284 #region Data members |
|
285 private Point iBoxCoordinates = new Point( 0, 0 ); |
|
286 private int iRemainingBoxes = 0; |
|
287 private int iRemainingBoxesAfterThisRow = 0; |
|
288 private int iRemainingRows = 0; |
|
289 private long iRemainingBytes = 0; |
|
290 private int iCellBoxIndex = 0; |
|
291 private int iCellRowIndex = 0; |
|
292 private int iCellBoxCount = 0; |
|
293 private uint iAddress = 0; |
|
294 private HeapCell iCell = null; |
|
295 private RawItem iRawItem = null; |
|
296 private HeapCellBorderInfo iBorders = new HeapCellBorderInfo(); |
|
297 private Color iCellBoxColor = Color.HotPink; |
|
298 #endregion |
|
299 } |
|
300 } |