|
1 /* |
|
2 * Copyright (c) 2010 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QLineF> |
|
19 #include <QtGlobal> |
|
20 #include <QPointF> |
|
21 #include <math.h> |
|
22 |
|
23 #include "hswidgetpositioningonwidgetadd.h" |
|
24 #include "hsconfiguration.h" |
|
25 #include "hsgui.h" |
|
26 |
|
27 const qreal offset = 20; //TODO: Implement this as configurable parameter |
|
28 |
|
29 |
|
30 /*! |
|
31 \class HsWidgetPositioningOnWidgetAdd |
|
32 \ingroup group_hsutils |
|
33 \brief |
|
34 */ |
|
35 |
|
36 /*! |
|
37 \class HsWidgetPositioningOnWidgetAdd |
|
38 \brief Defines widget positioning on widget add. |
|
39 |
|
40 Widget positioning on widget add sets positions for |
|
41 a set of home screen widgets added from application library. |
|
42 */ |
|
43 |
|
44 /*! |
|
45 Sets the positioning \a instance as the current one. |
|
46 Deletes the existing instance if present. |
|
47 */ |
|
48 void HsWidgetPositioningOnWidgetAdd::setInstance( |
|
49 HsWidgetPositioningOnWidgetAdd *instance) |
|
50 { |
|
51 if (mInstance) |
|
52 delete mInstance; |
|
53 mInstance = instance; |
|
54 } |
|
55 |
|
56 /*! |
|
57 Returns the current positioning instance. |
|
58 */ |
|
59 HsWidgetPositioningOnWidgetAdd *HsWidgetPositioningOnWidgetAdd::instance() |
|
60 { |
|
61 return mInstance; |
|
62 } |
|
63 |
|
64 /*! |
|
65 Stores the current positioning instance. |
|
66 */ |
|
67 HsWidgetPositioningOnWidgetAdd *HsWidgetPositioningOnWidgetAdd::mInstance = 0; |
|
68 |
|
69 /*! |
|
70 \class HsAnchorPointInBottomRight |
|
71 \brief Diagonal widget positioning algorithm. |
|
72 |
|
73 Sets widget's lower right corner to follow content area's diagonal. |
|
74 Widgets are positioned to certain offset to each other. |
|
75 */ |
|
76 QList<QRectF> HsAnchorPointInBottomRight::convert( |
|
77 const QRectF &contentArea, |
|
78 const QList<QRectF> &existingRects, |
|
79 const QList<QRectF> &newRects, |
|
80 const QPointF &startPoint) |
|
81 { |
|
82 Q_UNUSED(existingRects); |
|
83 |
|
84 QList<QRectF> toGeometries; |
|
85 |
|
86 //Offset for widgets' bottom right position to each other |
|
87 qreal k = contentArea.height()/contentArea.width(); //slope of the diagonal |
|
88 qreal offset_x = offset/(sqrt(k + 1)); |
|
89 qreal offset_y = k*offset_x; |
|
90 QPointF offsetPoint(offset_x, offset_y); |
|
91 |
|
92 QPointF anchorPoint; |
|
93 |
|
94 if(startPoint.isNull()){ |
|
95 |
|
96 QLineF diagonal(contentArea.topLeft(), contentArea.bottomRight()); |
|
97 QLineF widgetRightSide(contentArea.center().x()+ newRects.at(0).width()/2, |
|
98 contentArea.top(), |
|
99 contentArea.center().x()+ newRects.at(0).width()/2, |
|
100 contentArea.bottom()); |
|
101 |
|
102 // right side line intersection with diagonal will be bottom right position |
|
103 // for the first rect |
|
104 if(QLineF::BoundedIntersection != |
|
105 diagonal.intersect(widgetRightSide, &anchorPoint)) { |
|
106 return newRects; //Return original since undefined error. |
|
107 //In this case widget's must be wider than the content area. |
|
108 } |
|
109 }else{ |
|
110 anchorPoint = startPoint - offsetPoint; |
|
111 } |
|
112 |
|
113 QRectF widgetRect; |
|
114 for(int i=0;i<newRects.count();++i) { |
|
115 widgetRect = newRects.at(i); |
|
116 widgetRect.moveBottomRight(anchorPoint); |
|
117 //if widget rect doesn't fit, try to move it |
|
118 if(!contentArea.contains(widgetRect)) { |
|
119 /*! precondition is that |
|
120 widget's max height < content area height |
|
121 widget's max widht < content area width |
|
122 */ |
|
123 widgetRect.moveBottomRight(contentArea.bottomRight()); |
|
124 // anchorPoin is always previous bottom right |
|
125 anchorPoint = widgetRect.bottomRight(); |
|
126 } |
|
127 toGeometries << widgetRect; |
|
128 anchorPoint -= offsetPoint; |
|
129 |
|
130 } |
|
131 return toGeometries; |
|
132 } |
|
133 |
|
134 /*! |
|
135 \class HsAnchorPointInCenter |
|
136 \brief Diagonal widget positioning algorithm. |
|
137 |
|
138 Sets widget's center point to follow content area's diagonal. |
|
139 Widgets are positioned to certain offset to each other. |
|
140 */ |
|
141 #ifdef COVERAGE_MEASUREMENT |
|
142 #pragma CTC SKIP |
|
143 #endif //COVERAGE_MEASUREMENT |
|
144 QList<QRectF> HsAnchorPointInCenter::convert( |
|
145 const QRectF &contentArea, |
|
146 const QList<QRectF> &existingRects, |
|
147 const QList<QRectF> &newRects, |
|
148 const QPointF &startPoint ) |
|
149 { |
|
150 Q_UNUSED(existingRects); |
|
151 Q_UNUSED(startPoint) |
|
152 |
|
153 QList<QRectF> toGeometries; |
|
154 |
|
155 //Offset for widgets' centers position to each other |
|
156 qreal k = contentArea.height()/contentArea.width(); //slope of the diagonal |
|
157 qreal offset_x = offset/(sqrt(k + 1)); |
|
158 qreal offset_y = k*offset_x; |
|
159 QPointF offsetPoint(offset_x, offset_y); |
|
160 |
|
161 //First widget to the center of the content area |
|
162 QPointF anchorPoint = contentArea.center(); |
|
163 foreach (QRectF g, newRects) { |
|
164 g.moveCenter(anchorPoint); |
|
165 toGeometries << g; |
|
166 anchorPoint -= offsetPoint; |
|
167 if(!contentArea.contains(anchorPoint)) { |
|
168 anchorPoint = contentArea.bottomRight(); |
|
169 } |
|
170 } |
|
171 return toGeometries; |
|
172 } |
|
173 |
|
174 HsWidgetOrganizer::HsWidgetOrganizer(int anchorDistance, |
|
175 HsConfiguration::WidgetOrganizerSearchSequence sequence) |
|
176 : mAnchorDistance(anchorDistance), mSequence(sequence), mAnchorColumns(0), mAnchorRows(0), |
|
177 mCenterAlgorithm(new HsAnchorPointInCenter()) |
|
178 { |
|
179 |
|
180 } |
|
181 |
|
182 HsWidgetOrganizer::~HsWidgetOrganizer() |
|
183 { |
|
184 delete mCenterAlgorithm; |
|
185 } |
|
186 |
|
187 /*! |
|
188 \class HsWidgetOrganizer |
|
189 \brief Advanced widget positioning algorithm. |
|
190 |
|
191 Organizes widget's starting from upper left corner towards right, |
|
192 and then continues the on the next line. |
|
193 */ |
|
194 QList<QRectF> HsWidgetOrganizer::convert( |
|
195 const QRectF &contentArea, |
|
196 const QList<QRectF> &existingRects, |
|
197 const QList<QRectF> &newRects, |
|
198 const QPointF &startPoint) |
|
199 { |
|
200 Q_UNUSED(startPoint) |
|
201 |
|
202 // mandatory check ups |
|
203 if (mAnchorDistance <= 0 || contentArea == QRectF() || |
|
204 newRects == QList<QRectF>()) { |
|
205 return QList<QRectF>(); |
|
206 } |
|
207 |
|
208 // calculate anchor limits based on anchor distance |
|
209 mAnchorColumns = convertToAnchors(contentArea.width()); |
|
210 mAnchorRows = convertToAnchors(contentArea.height()); |
|
211 mContentArea = contentArea; |
|
212 |
|
213 // map rects so that we can later return them in original order |
|
214 QMap<int, QRectF> newRectsMap; |
|
215 for (int id = 0; id < newRects.count(); id++) { |
|
216 newRectsMap.insert(id, newRects.at(id)); |
|
217 } |
|
218 |
|
219 // get orientation |
|
220 Qt::Orientation orientation(HsGui::instance()->orientation()); |
|
221 |
|
222 SortMode mode; |
|
223 // select sorting mode based on orientation and search sequence |
|
224 if((orientation == Qt::Vertical && mSequence == HsConfiguration::SearchRowByRow) || |
|
225 (orientation == Qt::Horizontal && mSequence == HsConfiguration::SearchColumnByColumn)) { |
|
226 mode = SortByHeight; |
|
227 } else { |
|
228 mode = SortByWidth; |
|
229 } |
|
230 |
|
231 // sort rects into order |
|
232 QList<int> newRectsSorted = sortRects(mode, newRectsMap); |
|
233 |
|
234 // initialize anchor points |
|
235 initAnchors(); |
|
236 |
|
237 // go through existing rects |
|
238 bool ok = checkExistingRects(existingRects); |
|
239 if (!ok) { |
|
240 return QList<QRectF>(); |
|
241 } |
|
242 |
|
243 QList<int> newRectsNotCalculated; |
|
244 QList<QRectF> newExistingRects; |
|
245 newExistingRects += existingRects; |
|
246 |
|
247 // get positions for all new rects |
|
248 for (int i = 0; i < newRectsMap.count(); i++) { |
|
249 // proceed in sorted order with the rects |
|
250 QRectF newRect = newRectsMap.value(newRectsSorted.at(i)); |
|
251 // find first free anchor point for rect |
|
252 QPointF position = getPosition(newRect.size()); |
|
253 if (position != QPointF(-1,-1)) { |
|
254 QRectF calculatedGeometry = QRectF(position.x() + mContentArea.x(), |
|
255 position.y() + mContentArea.y(), |
|
256 newRect.width(), newRect.height()); |
|
257 // update new rect instead of old one based on id map |
|
258 newRectsMap.insert(newRectsSorted.at(i), calculatedGeometry); |
|
259 // update existing rects |
|
260 newExistingRects << calculatedGeometry; |
|
261 // mark new rect reserved |
|
262 bool marked = markAnchors(QRectF(position, newRect.size())); |
|
263 if (!marked) { |
|
264 return QList<QRectF>(); |
|
265 } |
|
266 |
|
267 } else { |
|
268 // collect rect that do not fit |
|
269 newRectsNotCalculated << newRectsSorted.at(i); |
|
270 } |
|
271 } |
|
272 |
|
273 // use center algorithm with offset for the rest rects that did not fit to content area |
|
274 if (newRectsNotCalculated.count() > 0 ) { |
|
275 // collect not organized rects |
|
276 QList<QRectF> undoneRects; |
|
277 for (int i = 0; i < newRectsNotCalculated.count(); i++) { |
|
278 undoneRects << newRectsMap.value(newRectsNotCalculated.at(i)); |
|
279 } |
|
280 QList<QRectF> calculatedRects = |
|
281 mCenterAlgorithm->convert(mContentArea, newExistingRects, undoneRects, QPointF()); |
|
282 // update the rest rects instead of old ones |
|
283 for (int i = 0; i < calculatedRects.count(); i++) { |
|
284 newRectsMap.insert(newRectsNotCalculated.at(i), calculatedRects.at(i)); |
|
285 /* take rect out of list and add it to the end of the list |
|
286 rect that do not fit are added in the end in users add order */ |
|
287 // we need to map z values to correct widgets to enable this |
|
288 /* |
|
289 newRectsMap.take(newRectsNotCalculated.at(i)); |
|
290 newRectsMap.insert(newRectsMap.count() + i + 1, calculatedRects.at(i)); |
|
291 */ |
|
292 } |
|
293 } |
|
294 |
|
295 return newRectsMap.values(); |
|
296 } |
|
297 |
|
298 /*! |
|
299 Initializes anchor point network for area size |
|
300 */ |
|
301 void HsWidgetOrganizer::initAnchors() |
|
302 { |
|
303 // need to zero just in case (if algorithm is called twice) |
|
304 mAnchors = QList<bool>(); |
|
305 // create anchor point network |
|
306 for (int i = 0; i < (mAnchorColumns * mAnchorRows); i++) { |
|
307 mAnchors.append(false); |
|
308 } |
|
309 } |
|
310 |
|
311 /*! |
|
312 Check existing rects and marks them reserved |
|
313 */ |
|
314 bool HsWidgetOrganizer::checkExistingRects(const QList<QRectF> &existingRects) |
|
315 { |
|
316 foreach (QRectF rect, existingRects) { |
|
317 /* if existing rect is on the edges of content area |
|
318 need to drop one pixels because there is no anchors on the edge */ |
|
319 int rightmostPoint = rect.x() + rect.width(); |
|
320 if (rightmostPoint == mContentArea.width()) { |
|
321 rect.setWidth(rect.width() - 1); |
|
322 } |
|
323 int undermostPoint = rect.y() + rect.height(); |
|
324 if (undermostPoint == mContentArea.height()) { |
|
325 rect.setHeight(rect.height() - 1); |
|
326 } |
|
327 // decrease content area size in case it does not start from (0,0) |
|
328 rect = QRectF( |
|
329 QPointF(rect.x() - mContentArea.x(), rect.y() - mContentArea.y()), |
|
330 rect.size()); |
|
331 bool marked = markAnchors(rect); |
|
332 if (!marked) { |
|
333 return false; |
|
334 } |
|
335 } |
|
336 return true; |
|
337 } |
|
338 |
|
339 /*! |
|
340 Calculates pixel length as anchor points |
|
341 */ |
|
342 int HsWidgetOrganizer::convertToAnchors(int length) |
|
343 { |
|
344 // calculate remainder |
|
345 int remainder = length % mAnchorDistance; |
|
346 // calculate anchor points (only pixel integrals are counted, decimals are cut away) |
|
347 int anchorPoints = (length - remainder) / mAnchorDistance; |
|
348 return anchorPoints; |
|
349 } |
|
350 |
|
351 /*! |
|
352 Marks reserved anchor points based on given rects |
|
353 */ |
|
354 bool HsWidgetOrganizer::markAnchors(const QRectF &rect) |
|
355 { |
|
356 // in case content does not start from zero, need take contentArea into calculations |
|
357 int startWidth = convertToAnchors(rect.x()); |
|
358 int endWidth = convertToAnchors(rect.x() + rect.width()); |
|
359 int startHeight = convertToAnchors(rect.y()); |
|
360 int endHeight = convertToAnchors(rect.y() + rect.height()); |
|
361 |
|
362 // mark reserved anchors row by row from left to right |
|
363 for (int i = startWidth; i <= endWidth; i++) { |
|
364 for (int j = startHeight; j <= endHeight; j++) { |
|
365 int index = getAnchorListIndex(QPointF(i,j)); |
|
366 if (index < 0) { |
|
367 return false; |
|
368 } |
|
369 mAnchors[index] = true; |
|
370 } |
|
371 } |
|
372 return true; |
|
373 } |
|
374 |
|
375 /*! |
|
376 Returns anchor's list index based on given position |
|
377 */ |
|
378 int HsWidgetOrganizer::getAnchorListIndex(const QPointF &position) |
|
379 { |
|
380 int index = (position.y() * mAnchorColumns) + position.x(); |
|
381 if (index < mAnchors.count()) { |
|
382 return index; |
|
383 } else { |
|
384 return -1; |
|
385 } |
|
386 } |
|
387 |
|
388 /*! |
|
389 Finds anchor points for content size |
|
390 */ |
|
391 QPointF HsWidgetOrganizer::getPosition(const QSizeF &size) |
|
392 { |
|
393 QPointF startPoint(0,0); |
|
394 // convert units from pixels to anchors |
|
395 int width = convertToAnchors(size.width()); |
|
396 int height = convertToAnchors(size.height()); |
|
397 |
|
398 // based on search sequence, select position searching method |
|
399 if (mSequence == HsConfiguration::SearchRowByRow) { |
|
400 startPoint = searchPositionRowByRow(startPoint, width, height); |
|
401 } else { |
|
402 startPoint = searchPositionColumnByColumn(startPoint, width, height); |
|
403 } |
|
404 |
|
405 if (startPoint == QPointF(-1,-1)) { |
|
406 return startPoint; |
|
407 } else { |
|
408 // return the actual pixel coordinate |
|
409 return QPointF(startPoint.x() * mAnchorDistance, startPoint.y() * mAnchorDistance); |
|
410 } |
|
411 } |
|
412 |
|
413 /*! |
|
414 Search sequence that finds anchor position by looking first for width on x-axis and |
|
415 then secondarily on height from y-axis |
|
416 */ |
|
417 QPointF HsWidgetOrganizer::searchPositionRowByRow(QPointF startPoint, int width, int height) |
|
418 { |
|
419 bool anchorFound = false; |
|
420 QPointF candidatePoint(0,0); |
|
421 // loop until anchor point is found |
|
422 while (anchorFound == false) { |
|
423 // search for width on specified row |
|
424 candidatePoint = searchSpace(SearchRow, startPoint, width); |
|
425 if (candidatePoint != QPointF(-1,-1)) { |
|
426 // update start point to where found width starts |
|
427 startPoint.setX(candidatePoint.x()); |
|
428 // check all anchor height points corresponding the found free width points |
|
429 for(int i = startPoint.x(); i <= startPoint.x() + width; i++) { |
|
430 // save current start point to be checked |
|
431 QPointF point = QPointF(i, startPoint.y()); |
|
432 // search for height on specified column |
|
433 candidatePoint = searchSpace(SearchColumn, point, height); |
|
434 if (candidatePoint == QPointF(-1,-1)) { |
|
435 // update x anchor index |
|
436 startPoint.setX(startPoint.x() + 1); |
|
437 // set i to max to stop searching |
|
438 i = startPoint.x() + width; |
|
439 } |
|
440 } |
|
441 // if all height searches were successfull |
|
442 if (candidatePoint != QPointF(-1,-1)) { |
|
443 anchorFound = true; |
|
444 } |
|
445 } else { |
|
446 // update x and y start positions when row has been checked |
|
447 startPoint.setX(0); |
|
448 startPoint.setY(startPoint.y() + 1); |
|
449 // check that enough height left |
|
450 if (startPoint.y() >= mAnchorRows) { |
|
451 return QPointF(-1,-1); |
|
452 } |
|
453 } |
|
454 } |
|
455 |
|
456 return startPoint; |
|
457 } |
|
458 |
|
459 /*! |
|
460 Search sequence that finds anchor position by looking first for height on y-axis and |
|
461 then secondarily on width from x-axis |
|
462 */ |
|
463 QPointF HsWidgetOrganizer::searchPositionColumnByColumn(QPointF startPoint, |
|
464 int width, int height) |
|
465 { |
|
466 bool anchorFound = false; |
|
467 QPointF candidatePoint(0,0); |
|
468 |
|
469 while (anchorFound == false) { |
|
470 candidatePoint = searchSpace(SearchColumn, startPoint, height); |
|
471 if (candidatePoint != QPointF(-1,-1)) { |
|
472 startPoint.setY(candidatePoint.y()); |
|
473 for(int i = startPoint.y(); i <= startPoint.y() + height; i++) { |
|
474 QPointF point = QPointF(startPoint.x(), i); |
|
475 candidatePoint = searchSpace(SearchRow, point, width); |
|
476 if (candidatePoint == QPointF(-1,-1)) { |
|
477 startPoint.setY(startPoint.y() + 1); |
|
478 i = startPoint.y() + height; |
|
479 } |
|
480 } |
|
481 if (candidatePoint != QPointF(-1,-1)) { |
|
482 anchorFound = true; |
|
483 } |
|
484 } else { |
|
485 startPoint.setY(0); |
|
486 startPoint.setX(startPoint.x() + 1); |
|
487 if (startPoint.x() >= mAnchorColumns) { |
|
488 return QPointF(-1,-1); |
|
489 } |
|
490 } |
|
491 } |
|
492 |
|
493 return startPoint; |
|
494 } |
|
495 |
|
496 /*! |
|
497 Searches anchor point space for given length |
|
498 */ |
|
499 QPointF HsWidgetOrganizer::searchSpace(SearchMode mode, QPointF startPoint, int length) |
|
500 { |
|
501 int availableLength = 0; |
|
502 // convert start point to an index in anchor list |
|
503 int startIndex = getAnchorListIndex(startPoint); |
|
504 int increment = 0; |
|
505 int endIndex = 0; |
|
506 |
|
507 // set end anchor index depending on checked axis |
|
508 if (mode == SearchRow) { |
|
509 // save the last index of the checked row |
|
510 endIndex = getAnchorListIndex(QPointF((mAnchorColumns - 1), startPoint.y())); |
|
511 |
|
512 } else { |
|
513 // save the last index of the checked column |
|
514 endIndex = getAnchorListIndex(QPointF(startPoint.x(), (mAnchorRows - 1))); |
|
515 // we need to add increment due to anchors are listed row by row |
|
516 increment = mAnchorColumns - 1; |
|
517 } |
|
518 |
|
519 // safety checks |
|
520 if (startIndex == -1 || endIndex == -1) { |
|
521 return QPointF(-1,-1); |
|
522 } |
|
523 |
|
524 // loop through anchor indexes, increment is added only when going through height |
|
525 for (int i = startIndex; i <= endIndex; i = i + 1 + increment) { |
|
526 // if anchor reserved |
|
527 if (mAnchors.at(i) == true) { |
|
528 availableLength = 0; |
|
529 // if going through the first part of sequence (width/height) |
|
530 if ((mSequence == HsConfiguration::SearchRowByRow && mode == SearchRow) || |
|
531 (mSequence == HsConfiguration::SearchColumnByColumn && mode == SearchColumn)) { |
|
532 // update start index |
|
533 startIndex = i + 1 + increment; |
|
534 } else { |
|
535 // exit immediately if second part of sequence fails |
|
536 return QPointF(-1,-1); |
|
537 } |
|
538 } else { |
|
539 // if enough space found |
|
540 if (availableLength == length) { |
|
541 // return the actual anchor position |
|
542 return getAnchorCoordinates(startIndex); |
|
543 } |
|
544 // update available length |
|
545 availableLength++; |
|
546 } |
|
547 } |
|
548 |
|
549 return QPointF(-1,-1); |
|
550 } |
|
551 |
|
552 /*! |
|
553 Returns pixel coordinate based on anchor coordinate |
|
554 */ |
|
555 QPointF HsWidgetOrganizer::getAnchorCoordinates(int index) |
|
556 { |
|
557 if (index < mAnchors.count()) { |
|
558 int x = index % mAnchorColumns; |
|
559 int y = (index - x) / mAnchorColumns; |
|
560 return QPointF(x,y); |
|
561 } else { |
|
562 return QPointF(); |
|
563 } |
|
564 } |
|
565 |
|
566 /*! |
|
567 Sorts rects based on sort mode and given map of rects |
|
568 */ |
|
569 QList<int> HsWidgetOrganizer::sortRects(SortMode mode, const QMap<int, QRectF> &rects) |
|
570 { |
|
571 QList<int> sortedRects; |
|
572 int i = 0; |
|
573 // loop through all rects |
|
574 QMapIterator<int, QRectF> id(rects); |
|
575 while (id.hasNext()) { |
|
576 id.next(); |
|
577 int index = 0; |
|
578 // add first rect id to sorted list |
|
579 if (i == 0) { |
|
580 sortedRects << id.key(); |
|
581 } else { |
|
582 // go through existing rects in the sorted list |
|
583 for ( int j = 0; j < sortedRects.count(); j++) { |
|
584 // calculations for sortByArea |
|
585 qreal existingArea = rects.value(sortedRects.at(j)).width() * |
|
586 rects.value(sortedRects.at(j)).height(); |
|
587 qreal newArea = id.value().width() * id.value().height(); |
|
588 // sort rects in height order |
|
589 switch (mode) { |
|
590 case SortByHeight: |
|
591 /* if rect heigth is smaller on already |
|
592 existing ones in the list -> increment index |
|
593 */ |
|
594 if (id.value().height() <= rects.value(sortedRects.at(j)).height()) { |
|
595 index++; |
|
596 } |
|
597 break; |
|
598 // sort rects in width order |
|
599 case SortByWidth: |
|
600 // if rect width is smaller -> increment index |
|
601 if (id.value().width() <= rects.value(sortedRects.at(j)).width()) { |
|
602 index++; |
|
603 } |
|
604 break; |
|
605 case SortByArea: |
|
606 // if rect area is smaller -> increment index |
|
607 if (newArea <= existingArea) { |
|
608 index++; |
|
609 } |
|
610 // otherwise return in original order |
|
611 default: |
|
612 index++; |
|
613 break; |
|
614 } |
|
615 } |
|
616 // add rect id in the sorted list |
|
617 sortedRects.insert(index, id.key()); |
|
618 } |
|
619 i++; |
|
620 } |
|
621 return sortedRects; |
|
622 } |
|
623 |
|
624 #ifdef COVERAGE_MEASUREMENT |
|
625 #pragma CTC ENDSKIP |
|
626 #endif //COVERAGE_MEASUREMENT |
|
627 |