262 mVerticalDistance = mInactiveRectToCompare.bottom() - mMovingRect.bottom(); |
233 mVerticalDistance = mInactiveRectToCompare.bottom() - mMovingRect.bottom(); |
263 } |
234 } |
264 } |
235 } |
265 } |
236 } |
266 |
237 |
267 |
238 /*! |
268 /*! |
239 Check if the Vertical edges (Left and Right Edges) of the inactive rect being compared |
269 Check if the left edge of moving rect is snappable to the incative rect's left or right edge. |
240 is in range of the snapping distance of the vertical edge of moving rect |
270 The inactive rect's edge is only chosen if it is a better fit for horizontal snapping. |
241 \param movingRectVerticalEdgePosition Position of the Vertical edge(either left or right) of moving rect. |
271 */ |
242 */ |
272 void HsSnapToLines::compareLeftSideOfMovingRectForSnapping() |
243 void HsSnapToLines::checkInactiveRectVerticalEdgesInRange(qreal movingRectVerticalEdgePosition) |
273 { |
244 { |
274 checkInactiveRectLieAboveOrBelowOfMovingRect(); |
|
275 |
|
276 //calculate the distance of the moving rect's left edge to the inactive rect's left and right edges |
|
277 qreal leftToLeftOfInactiveRect = qAbs(mInactiveRectToCompare.left() - mMovingRect.left()); |
|
278 qreal leftToRightOfInactiveRect = qAbs(mInactiveRectToCompare.right() - mMovingRect.left()); |
|
279 mLeftInRange = false; |
245 mLeftInRange = false; |
280 mRightInRange = false; |
246 mRightInRange = false; |
281 |
247 |
282 if (leftToLeftOfInactiveRect <= mMinVerticalEdgesDistance) { |
248 //calculate the distance of the moving rect's vertical edge to the inactive rect's left and right edges |
283 if (mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForBelow |
249 mVerticalEdgeToLeftOfInactiveRect = qAbs(mInactiveRectToCompare.left() - movingRectVerticalEdgePosition); |
284 || !mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForAbove) { |
250 mVerticalEdgeToRightOfInactiveRect = qAbs(mInactiveRectToCompare.right() - movingRectVerticalEdgePosition); |
285 mLeftInRange = true; |
251 |
286 } |
252 if (mVerticalEdgeToLeftOfInactiveRect <= mMinVerticalEdgesDistance |
287 } |
253 && (mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForBelow |
288 if (leftToRightOfInactiveRect <= mMinVerticalEdgesDistance) { |
254 || !mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForAbove)) { |
289 if (mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForBelow |
255 mLeftInRange = true; |
290 || !mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForAbove) { |
256 } |
291 mRightInRange = true; |
257 if (mVerticalEdgeToRightOfInactiveRect <= mMinVerticalEdgesDistance |
292 } |
258 && (mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForBelow |
293 } |
259 || !mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForAbove)) { |
294 |
260 mRightInRange = true; |
295 //calculate the distance of inactive rect's left edge and container rect's left edge |
261 } |
296 qreal differenceContainerLeftEdgeToInactiveRectLeftEdge = mInactiveRectToCompare.left() - mContainerRect.left(); |
262 } |
297 //calculate the distance of inactive rect's right edge and container rect's right edge |
263 |
298 qreal differenceContainerRightEdgeToInactiveRectRightEdge = mContainerRect.right() - mInactiveRectToCompare.right(); |
264 /*! |
299 |
265 Check if this inactive rect is better fit for Horizontal snapping |
300 qreal minDistancePosition = 0.0; |
266 \param containerVerticalEdgeToInactiveRectVerticalEdge |
301 qreal distanceVerticalEdges = 0.0; |
267 difference between the vertical edge of the container and same vertical edge of inactive rect |
302 qreal xSnapGapAdjustment = 0.0; |
268 \param containerOtherVerticalEdgeToInactiveRectOtherVerticalEdge |
303 |
269 difference between the opposite vertical edges of continer and the inactive rect |
304 //If only one edge of inactive rect is in snappable range, save that position |
270 */ |
305 if ((mLeftInRange && !mRightInRange) |
271 void HsSnapToLines::checkInactiveRectBetterFitForHorizontalSnapping(qreal containerVerticalEdgeToInactiveRectVerticalEdge, |
306 || !mLeftInRange && mRightInRange) { |
272 qreal containerOtherVerticalEdgeToInactiveRectOtherVerticalEdge) |
307 if (mLeftInRange) { |
273 { |
308 minDistancePosition = mInactiveRectToCompare.left(); |
274 //Check if the inactive rect is better fit or if it is inline with already selected position and hence is also a better fit |
309 distanceVerticalEdges = leftToLeftOfInactiveRect; |
275 mIsBetterFitHorizontalSnap = false; |
310 xSnapGapAdjustment = 0.0; |
|
311 } |
|
312 else { |
|
313 minDistancePosition = mInactiveRectToCompare.right(); |
|
314 distanceVerticalEdges = leftToRightOfInactiveRect; |
|
315 xSnapGapAdjustment = mSnapGap; |
|
316 } |
|
317 } |
|
318 //else both edges of inactive rect are in range, check which is a better fit |
|
319 else if (mLeftInRange && mRightInRange) { |
|
320 //if left edge of moving rect to the left of the inactive rect is closer than the left edge of moving rect to the right of the inactive rect |
|
321 if (leftToLeftOfInactiveRect < leftToRightOfInactiveRect) { |
|
322 minDistancePosition = mInactiveRectToCompare.left(); |
|
323 distanceVerticalEdges = leftToLeftOfInactiveRect; |
|
324 xSnapGapAdjustment = 0.0; |
|
325 mRightInRange = false; |
|
326 } |
|
327 //if the left edge of inactive rect to left of moving rect is at the same distance as the right edge of inactive rect to the right of moving rect |
|
328 else if (leftToLeftOfInactiveRect == leftToRightOfInactiveRect) { |
|
329 //if inactive rect lies towards the left or middle of container rect, then the left edge is priortized as the selected edge for outside snapping |
|
330 if (differenceContainerLeftEdgeToInactiveRectLeftEdge <= differenceContainerRightEdgeToInactiveRectRightEdge) { |
|
331 minDistancePosition = mInactiveRectToCompare.left(); |
|
332 distanceVerticalEdges = leftToLeftOfInactiveRect; |
|
333 xSnapGapAdjustment = 0.0; |
|
334 mRightInRange = false; |
|
335 } |
|
336 //else right of the inactive rect lies more close to the right of the container rect, and hence prioritize it for snapping. |
|
337 else { |
|
338 minDistancePosition = mInactiveRectToCompare.right(); |
|
339 distanceVerticalEdges = leftToRightOfInactiveRect; |
|
340 xSnapGapAdjustment = mSnapGap; |
|
341 mLeftInRange = false; |
|
342 } |
|
343 } |
|
344 //else right edge of inactive rect to the left of the moving rect is closer than the left edge of inactive rect to the left of the moving rect |
|
345 else{ |
|
346 minDistancePosition = mInactiveRectToCompare.right(); |
|
347 distanceVerticalEdges = leftToRightOfInactiveRect; |
|
348 xSnapGapAdjustment = mSnapGap; |
|
349 mLeftInRange = false; |
|
350 } |
|
351 } |
|
352 |
|
353 //Check if this inactive rect is better fit than the previous selected rect for X - snapping |
|
354 bool horizontalSnappingBetterFit = false; |
|
355 if (mLeftInRange || mRightInRange) { |
276 if (mLeftInRange || mRightInRange) { |
356 if (distanceVerticalEdges < mMinVerticalEdgesDistance) { |
277 if (mDistanceVerticalEdges < mMinVerticalEdgesDistance) { |
357 horizontalSnappingBetterFit = true; |
278 mIsBetterFitHorizontalSnap = true; |
358 } |
279 } |
359 else if (distanceVerticalEdges == mMinVerticalEdgesDistance) { //the distance in the vertical edges is same as from the selected rectangle |
280 else if (mDistanceVerticalEdges == mMinVerticalEdgesDistance) { //the distance in the vertical edges is same as from the previously selected rect |
360 //check the position of rect with respect to Vertical line |
|
361 checkInactiveRectPositionToVerticalLine(); |
|
362 //if horizontal snap position was previously found the rect's edges are in line with Vertical line |
|
363 if (mHorizontalSnapFound && mRectVerticalEdgeLiesInLineWithVerticalLine) { |
|
364 if (mRectLieAboveVerticalLine || mRectLieBelowVerticalLine) { |
|
365 extendVerticalLineToIncludeInactiveRect(); |
|
366 } |
|
367 } |
|
368 //here the case is that moving rect lies exactly in middle of two same sides of two inactive widgets. |
|
369 else { |
|
370 //Prioritize first on the fact if the inactive rect is closer to the moving rect in Y - direction. |
|
371 if (mVerticalDistance < mVerticalDistanceFromSelectedRect) { |
|
372 horizontalSnappingBetterFit = true; |
|
373 } |
|
374 else if (mVerticalDistance == mVerticalDistanceFromSelectedRect) { |
|
375 //Prioritize next if this Inactive rect is closer to the left edge of the container rect, then the previously selected rect |
|
376 if (differenceContainerLeftEdgeToInactiveRectLeftEdge < mContainerVerticalEdgeDistance) { |
|
377 horizontalSnappingBetterFit = true; |
|
378 } |
|
379 //Prioritize next if the Inactive widget's left edge lies near to left edge of the container rect |
|
380 else if (differenceContainerLeftEdgeToInactiveRectLeftEdge < differenceContainerRightEdgeToInactiveRectRightEdge) { |
|
381 horizontalSnappingBetterFit = true; |
|
382 } |
|
383 else { |
|
384 //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping. |
|
385 //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit. |
|
386 } |
|
387 } |
|
388 } |
|
389 } |
|
390 } |
|
391 |
|
392 if (horizontalSnappingBetterFit) { |
|
393 qreal proposedRightOfActiveRect = minDistancePosition + xSnapGapAdjustment + mActiveRectWidth; |
|
394 if (qBound(mContainerRect.left(), proposedRightOfActiveRect, mContainerRect.right()) |
|
395 == proposedRightOfActiveRect) { |
|
396 mHorizontalSnapFound = true; |
|
397 mHorizontalSnapPosition = minDistancePosition + xSnapGapAdjustment; |
|
398 mMinVerticalEdgesDistance = distanceVerticalEdges; |
|
399 mVerticalDistanceFromSelectedRect = mVerticalDistance; |
|
400 //Save the new distance of the Chosen Rectangle's left edge from Container's left edge |
|
401 mContainerVerticalEdgeDistance = differenceContainerLeftEdgeToInactiveRectLeftEdge; |
|
402 |
|
403 if (mRectLieAbove) { |
|
404 mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.top())); |
|
405 mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.bottom())); |
|
406 } |
|
407 else { |
|
408 mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.bottom())); |
|
409 mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.top())); |
|
410 } |
|
411 } |
|
412 } |
|
413 } |
|
414 |
|
415 /*! |
|
416 Check if the right edge of moving rect is snappable to the incative rect's left or right edge. |
|
417 The inactive rect's edge is only chosen if it is a better fit for horizontal snapping. |
|
418 */ |
|
419 void HsSnapToLines::compareRightSideOfMovingRectForSnapping() |
|
420 { |
|
421 checkInactiveRectLieAboveOrBelowOfMovingRect(); |
|
422 |
|
423 //calculate the distance of the moving rect's right edge to the inactive rect's left and right edges |
|
424 qreal rightToLeftOfInactiveRect = qAbs(mInactiveRectToCompare.left() - mMovingRect.right()); |
|
425 qreal rightToRightOfInactiveRect = qAbs(mInactiveRectToCompare.right() - mMovingRect.right()); |
|
426 mLeftInRange = false; |
|
427 mRightInRange = false; |
|
428 |
|
429 if (rightToLeftOfInactiveRect <= mMinVerticalEdgesDistance) { |
|
430 if (mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForBelow |
|
431 || !mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForAbove) { |
|
432 mLeftInRange = true; |
|
433 } |
|
434 } |
|
435 if (rightToRightOfInactiveRect <= mMinVerticalEdgesDistance) { |
|
436 if (mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForBelow |
|
437 || !mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForAbove) { |
|
438 mRightInRange = true; |
|
439 } |
|
440 } |
|
441 |
|
442 //calculate the distance of inactive rect's left edge and container rect's left edge |
|
443 qreal differenceContainerLeftEdgeToInactiveRectLeftEdge = mInactiveRectToCompare.left() - mContainerRect.left(); |
|
444 //calculate the distance of inactive rect's right edge and container rect's right edge |
|
445 qreal differenceContainerRightEdgeToInactiveRectRightEdge = mContainerRect.right() - mInactiveRectToCompare.right(); |
|
446 qreal minDistancePosition = 0.0; |
|
447 qreal distanceVerticalEdges = 0.0; |
|
448 qreal xSnapGapAdjustment = 0.0; |
|
449 |
|
450 //If only one edge of inactive rect is in snappable range, save that position |
|
451 if ((mLeftInRange && !mRightInRange) |
|
452 || !mLeftInRange && mRightInRange) { |
|
453 if (mLeftInRange) { |
|
454 minDistancePosition = mInactiveRectToCompare.left(); |
|
455 distanceVerticalEdges = rightToLeftOfInactiveRect; |
|
456 xSnapGapAdjustment = mSnapGap; |
|
457 } |
|
458 else { |
|
459 minDistancePosition = mInactiveRectToCompare.right(); |
|
460 distanceVerticalEdges = rightToRightOfInactiveRect; |
|
461 xSnapGapAdjustment = 0.0; |
|
462 } |
|
463 } |
|
464 //else both edges of inactive rect are in range, check which is a better fit |
|
465 else if (mLeftInRange && mRightInRange) { |
|
466 //if right edge of moving rect to the right of the inactive rect is closer than the right edge of moving rect to the left of inactive rect |
|
467 if (rightToRightOfInactiveRect < rightToLeftOfInactiveRect) { |
|
468 minDistancePosition = mInactiveRectToCompare.right(); |
|
469 distanceVerticalEdges = rightToRightOfInactiveRect; |
|
470 xSnapGapAdjustment = 0.0; |
|
471 mLeftInRange = false; |
|
472 } |
|
473 //if the right edge of moving rect to right of inactive rect is at the same distance as the right edge of moving rect to the left of inactive rect |
|
474 else if (rightToRightOfInactiveRect == rightToLeftOfInactiveRect) { |
|
475 //if inactive rect lies towards the right of container rect, then the right edge is priortized as the selected edge for outside snapping |
|
476 if (differenceContainerRightEdgeToInactiveRectRightEdge < differenceContainerLeftEdgeToInactiveRectLeftEdge ) { |
|
477 minDistancePosition = mInactiveRectToCompare.right(); |
|
478 distanceVerticalEdges = rightToRightOfInactiveRect; |
|
479 xSnapGapAdjustment = 0.0; |
|
480 mLeftInRange = false; |
|
481 } |
|
482 //else left of the inactive rect lies more close to the left or middle of the container rect, and hence prioritize it |
|
483 else { |
|
484 minDistancePosition = mInactiveRectToCompare.left(); |
|
485 distanceVerticalEdges = rightToLeftOfInactiveRect; |
|
486 xSnapGapAdjustment = mSnapGap; |
|
487 mRightInRange = false; |
|
488 } |
|
489 } |
|
490 //else right edge of moving rect to the left of the inactive rect is closer than the right edge of moving rect to the right of the incoming rect |
|
491 else{ |
|
492 minDistancePosition = mInactiveRectToCompare.left(); |
|
493 distanceVerticalEdges = rightToLeftOfInactiveRect; |
|
494 xSnapGapAdjustment = mSnapGap; |
|
495 mRightInRange = false; |
|
496 } |
|
497 } |
|
498 |
|
499 //Check if this inactive rect is better fit than the previous selected rect |
|
500 bool horizontalSnappingBetterFit = false; |
|
501 if (mLeftInRange || mRightInRange) { |
|
502 if (distanceVerticalEdges < mMinVerticalEdgesDistance) { |
|
503 horizontalSnappingBetterFit = true; |
|
504 } |
|
505 else if (distanceVerticalEdges == mMinVerticalEdgesDistance) { //the distance in the vertical edge is same as from the selected rectangle |
|
506 //check the position of rect with respect to Vertical line |
281 //check the position of rect with respect to Vertical line |
507 checkInactiveRectPositionToVerticalLine(); |
282 checkInactiveRectPositionToVerticalLine(); |
508 //if horizontal snap position was previously found and the rect's edge is in line with Vertical line |
283 //if horizontal snap position was previously found and the rect's edge is in line with Vertical line |
509 if (mHorizontalSnapFound && mRectVerticalEdgeLiesInLineWithVerticalLine) { |
284 if (mHorizontalSnapFound && mRectVerticalEdgeLiesInLineWithVerticalLine) { |
510 if (mRectLieAboveVerticalLine || mRectLieBelowVerticalLine) { |
285 if (mRectLieAboveVerticalLine || mRectLieBelowVerticalLine) { |
511 extendVerticalLineToIncludeInactiveRect(); |
286 extendVerticalLineToIncludeInactiveRect(); |
512 } |
287 } |
513 } |
288 } |
514 //here the case is that moving rect lies exactly in middle of two same sides of two inactive widgets. |
289 //here the case is that moving rect lies exactly in middle of two same sides of two different inactive widgets. |
515 else { |
290 else { |
516 //Prioritize first on the fact if the inactive rect is closer to the moving rect in Y - direction. |
291 //Prioritize first on the fact if the inactive rect is closer to the moving rect in Y - direction. |
517 if (mVerticalDistance < mVerticalDistanceFromSelectedRect) { |
292 if (mVerticalDistance < mVerticalDistanceFromSelectedRect) { |
518 horizontalSnappingBetterFit = true; |
293 mIsBetterFitHorizontalSnap = true; |
519 } |
294 } |
520 else if (mVerticalDistance == mVerticalDistanceFromSelectedRect) { |
295 else if (mVerticalDistance == mVerticalDistanceFromSelectedRect) { |
521 //Prioritize next if this Inactive rect is closer to the right edge of the container rect, then the previously selected rect |
296 //Prioritize next if this Inactive rect's vertical edge is closer to the same vertical edge of the container rect, then the previously selected rect |
522 if (differenceContainerRightEdgeToInactiveRectRightEdge < mContainerVerticalEdgeDistance) { |
297 if (containerVerticalEdgeToInactiveRectVerticalEdge < mContainerVerticalEdgeDistance) { |
523 horizontalSnappingBetterFit = true; |
298 mIsBetterFitHorizontalSnap = true; |
524 } |
299 } |
525 //Prioritize next if the Inactive rect's right edge lies near to right edge of the container rect |
300 //Prioritize next if the Inactive rect's vertical edge lies near to same vertical edge of the container rect than the other pair |
526 else if (differenceContainerRightEdgeToInactiveRectRightEdge < differenceContainerLeftEdgeToInactiveRectLeftEdge) { |
301 else if (containerVerticalEdgeToInactiveRectVerticalEdge < containerOtherVerticalEdgeToInactiveRectOtherVerticalEdge) { |
527 horizontalSnappingBetterFit = true; |
302 mIsBetterFitHorizontalSnap = true; |
528 } |
303 } |
529 else { |
304 else { |
530 //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, but in opposite Y direction. |
305 //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, but in opposite Y direction. |
531 //In that case it does not matter which is the selected rectangle. Hece we leave the already selected rectangle as the better fit. |
306 //In that case it does not matter which is the selected rectangle. Hece we leave the already selected rectangle as the better fit. |
532 } |
307 } |
533 } |
308 } |
534 } |
309 } |
535 } |
310 } |
536 } |
311 } |
537 |
312 } |
538 if (horizontalSnappingBetterFit) { |
313 |
539 qreal proposedLeftOfActiveRect = minDistancePosition - mActiveRectWidth - xSnapGapAdjustment; |
314 /*! |
|
315 Check if the left edge of moving rect is snappable to the incative rect's left or right edge. |
|
316 The inactive rect's edge is only chosen if it is a better fit for horizontal snapping. |
|
317 */ |
|
318 void HsSnapToLines::compareLeftSideOfMovingRectForSnapping() |
|
319 { |
|
320 checkInactiveRectLieAboveOrBelowOfMovingRect(); |
|
321 |
|
322 checkInactiveRectVerticalEdgesInRange(mMovingRect.left()); |
|
323 |
|
324 //calculate the distance of inactive rect's left edge and container rect's left edge |
|
325 qreal differenceContainerLeftEdgeToInactiveRectLeftEdge = mInactiveRectToCompare.left() - mContainerRect.left(); |
|
326 //calculate the distance of inactive rect's right edge and container rect's right edge |
|
327 qreal differenceContainerRightEdgeToInactiveRectRightEdge = mContainerRect.right() - mInactiveRectToCompare.right(); |
|
328 qreal xSnapGapAdjustment = 0.0; |
|
329 mDistanceVerticalEdges = 0.0; |
|
330 mMinDistancePosition = 0.0; |
|
331 |
|
332 //If only one edge of inactive rect is in snappable range, save that position |
|
333 if ((mLeftInRange && !mRightInRange) |
|
334 || !mLeftInRange && mRightInRange) { |
|
335 if (mLeftInRange) { |
|
336 mMinDistancePosition = mInactiveRectToCompare.left(); |
|
337 mDistanceVerticalEdges = mVerticalEdgeToLeftOfInactiveRect; |
|
338 xSnapGapAdjustment = 0.0; |
|
339 } |
|
340 else { |
|
341 mMinDistancePosition = mInactiveRectToCompare.right(); |
|
342 mDistanceVerticalEdges = mVerticalEdgeToRightOfInactiveRect; |
|
343 xSnapGapAdjustment = mSnapGap; |
|
344 } |
|
345 } |
|
346 //else both edges of inactive rect are in range, check which is a better fit |
|
347 else if (mLeftInRange && mRightInRange) { |
|
348 //if left edge of moving rect to the left of the inactive rect is closer than the left edge of moving rect to the right of the inactive rect |
|
349 if (mVerticalEdgeToLeftOfInactiveRect < mVerticalEdgeToRightOfInactiveRect) { |
|
350 mMinDistancePosition = mInactiveRectToCompare.left(); |
|
351 mDistanceVerticalEdges = mVerticalEdgeToLeftOfInactiveRect; |
|
352 xSnapGapAdjustment = 0.0; |
|
353 mRightInRange = false; |
|
354 } |
|
355 //if the left edge of inactive rect to left of moving rect is at the same distance as the right edge of inactive rect to the right of moving rect |
|
356 else if (mVerticalEdgeToLeftOfInactiveRect == mVerticalEdgeToRightOfInactiveRect) { |
|
357 //if inactive rect lies towards the left or middle of container rect, then the left edge is priortized as the selected edge for outside snapping |
|
358 if (differenceContainerLeftEdgeToInactiveRectLeftEdge <= differenceContainerRightEdgeToInactiveRectRightEdge) { |
|
359 mMinDistancePosition = mInactiveRectToCompare.left(); |
|
360 mDistanceVerticalEdges = mVerticalEdgeToLeftOfInactiveRect; |
|
361 xSnapGapAdjustment = 0.0; |
|
362 mRightInRange = false; |
|
363 } |
|
364 //else right of the inactive rect lies more close to the right of the container rect, and hence prioritize it for snapping. |
|
365 else { |
|
366 mMinDistancePosition = mInactiveRectToCompare.right(); |
|
367 mDistanceVerticalEdges = mVerticalEdgeToRightOfInactiveRect; |
|
368 xSnapGapAdjustment = mSnapGap; |
|
369 mLeftInRange = false; |
|
370 } |
|
371 } |
|
372 //else right edge of inactive rect to the left of the moving rect is closer than the left edge of inactive rect to the left of the moving rect |
|
373 else{ |
|
374 mMinDistancePosition = mInactiveRectToCompare.right(); |
|
375 mDistanceVerticalEdges = mVerticalEdgeToRightOfInactiveRect; |
|
376 xSnapGapAdjustment = mSnapGap; |
|
377 mLeftInRange = false; |
|
378 } |
|
379 } |
|
380 |
|
381 //Check if this inactive rect is better fit than the previous selected rect for Horizontal - snapping |
|
382 checkInactiveRectBetterFitForHorizontalSnapping(differenceContainerLeftEdgeToInactiveRectLeftEdge, |
|
383 differenceContainerRightEdgeToInactiveRectRightEdge); |
|
384 |
|
385 if (mIsBetterFitHorizontalSnap) { |
|
386 qreal proposedRightOfActiveRect = mMinDistancePosition + xSnapGapAdjustment + mActiveRectWidth; |
|
387 if (qBound(mContainerRect.left(), proposedRightOfActiveRect, mContainerRect.right()) |
|
388 == proposedRightOfActiveRect) { |
|
389 mHorizontalSnapFound = true; |
|
390 mHorizontalSnapPosition = mMinDistancePosition + xSnapGapAdjustment; |
|
391 mMinVerticalEdgesDistance = mDistanceVerticalEdges; |
|
392 mVerticalDistanceFromSelectedRect = mVerticalDistance; |
|
393 //Save the new distance of the Chosen Rectangle's left edge from Container's left edge |
|
394 mContainerVerticalEdgeDistance = differenceContainerLeftEdgeToInactiveRectLeftEdge; |
|
395 createVerticalLine(); |
|
396 } |
|
397 } |
|
398 } |
|
399 |
|
400 /*! |
|
401 Check if the right edge of moving rect is snappable to the incative rect's left or right edge. |
|
402 The inactive rect's edge is only chosen if it is a better fit for horizontal snapping. |
|
403 */ |
|
404 void HsSnapToLines::compareRightSideOfMovingRectForSnapping() |
|
405 { |
|
406 checkInactiveRectLieAboveOrBelowOfMovingRect(); |
|
407 |
|
408 checkInactiveRectVerticalEdgesInRange(mMovingRect.right()); |
|
409 |
|
410 //calculate the distance of inactive rect's left edge and container rect's left edge |
|
411 qreal differenceContainerLeftEdgeToInactiveRectLeftEdge = mInactiveRectToCompare.left() - mContainerRect.left(); |
|
412 //calculate the distance of inactive rect's right edge and container rect's right edge |
|
413 qreal differenceContainerRightEdgeToInactiveRectRightEdge = mContainerRect.right() - mInactiveRectToCompare.right(); |
|
414 qreal xSnapGapAdjustment = 0.0; |
|
415 mDistanceVerticalEdges = 0.0; |
|
416 mMinDistancePosition = 0.0; |
|
417 |
|
418 //If only one edge of inactive rect is in snappable range, save that position |
|
419 if ((mLeftInRange && !mRightInRange) |
|
420 || !mLeftInRange && mRightInRange) { |
|
421 if (mLeftInRange) { |
|
422 mMinDistancePosition = mInactiveRectToCompare.left(); |
|
423 mDistanceVerticalEdges = mVerticalEdgeToLeftOfInactiveRect; |
|
424 xSnapGapAdjustment = mSnapGap; |
|
425 } |
|
426 else { |
|
427 mMinDistancePosition = mInactiveRectToCompare.right(); |
|
428 mDistanceVerticalEdges = mVerticalEdgeToRightOfInactiveRect; |
|
429 xSnapGapAdjustment = 0.0; |
|
430 } |
|
431 } |
|
432 //else both edges of inactive rect are in range, check which is a better fit |
|
433 else if (mLeftInRange && mRightInRange) { |
|
434 //if right edge of moving rect to the right of the inactive rect is closer than the right edge of moving rect to the left of inactive rect |
|
435 if (mVerticalEdgeToRightOfInactiveRect < mVerticalEdgeToLeftOfInactiveRect) { |
|
436 mMinDistancePosition = mInactiveRectToCompare.right(); |
|
437 mDistanceVerticalEdges = mVerticalEdgeToRightOfInactiveRect; |
|
438 xSnapGapAdjustment = 0.0; |
|
439 mLeftInRange = false; |
|
440 } |
|
441 //if the right edge of moving rect to right of inactive rect is at the same distance as the right edge of moving rect to the left of inactive rect |
|
442 else if (mVerticalEdgeToRightOfInactiveRect == mVerticalEdgeToLeftOfInactiveRect) { |
|
443 //if inactive rect lies towards the right of container rect, then the right edge is priortized as the selected edge for outside snapping |
|
444 if (differenceContainerRightEdgeToInactiveRectRightEdge < differenceContainerLeftEdgeToInactiveRectLeftEdge ) { |
|
445 mMinDistancePosition = mInactiveRectToCompare.right(); |
|
446 mDistanceVerticalEdges = mVerticalEdgeToRightOfInactiveRect; |
|
447 xSnapGapAdjustment = 0.0; |
|
448 mLeftInRange = false; |
|
449 } |
|
450 //else left of the inactive rect lies more close to the left or middle of the container rect, and hence prioritize it |
|
451 else { |
|
452 mMinDistancePosition = mInactiveRectToCompare.left(); |
|
453 mDistanceVerticalEdges = mVerticalEdgeToLeftOfInactiveRect; |
|
454 xSnapGapAdjustment = mSnapGap; |
|
455 mRightInRange = false; |
|
456 } |
|
457 } |
|
458 //else right edge of moving rect to the left of the inactive rect is closer than the right edge of moving rect to the right of the incoming rect |
|
459 else{ |
|
460 mMinDistancePosition = mInactiveRectToCompare.left(); |
|
461 mDistanceVerticalEdges = mVerticalEdgeToLeftOfInactiveRect; |
|
462 xSnapGapAdjustment = mSnapGap; |
|
463 mRightInRange = false; |
|
464 } |
|
465 } |
|
466 |
|
467 //Check if this inactive rect is better fit than the previous selected rect |
|
468 checkInactiveRectBetterFitForHorizontalSnapping(differenceContainerRightEdgeToInactiveRectRightEdge, |
|
469 differenceContainerLeftEdgeToInactiveRectLeftEdge); |
|
470 |
|
471 if (mIsBetterFitHorizontalSnap) { |
|
472 qreal proposedLeftOfActiveRect = mMinDistancePosition - mActiveRectWidth - xSnapGapAdjustment; |
540 if (qBound(mContainerRect.left(), proposedLeftOfActiveRect, mContainerRect.right()) |
473 if (qBound(mContainerRect.left(), proposedLeftOfActiveRect, mContainerRect.right()) |
541 == proposedLeftOfActiveRect) { |
474 == proposedLeftOfActiveRect) { |
542 mHorizontalSnapFound = true; |
475 mHorizontalSnapFound = true; |
543 mHorizontalSnapPosition = proposedLeftOfActiveRect; |
476 mHorizontalSnapPosition = proposedLeftOfActiveRect; |
544 mMinVerticalEdgesDistance = distanceVerticalEdges; |
477 mMinVerticalEdgesDistance = mDistanceVerticalEdges; |
545 mVerticalDistanceFromSelectedRect = mVerticalDistance; |
478 mVerticalDistanceFromSelectedRect = mVerticalDistance; |
546 //Save the new distance of the Chosen Rectangle's right edge from Container's right edge |
479 //Save the new distance of the Chosen Rectangle's right edge from Container's right edge |
547 mContainerVerticalEdgeDistance = differenceContainerRightEdgeToInactiveRectRightEdge; |
480 mContainerVerticalEdgeDistance = differenceContainerRightEdgeToInactiveRectRightEdge; |
548 |
481 createVerticalLine(); |
549 if (mRectLieAbove) { |
482 } |
550 //save the points for the Vertical line |
483 } |
551 mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.top())); |
484 } |
552 mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.bottom())); |
485 |
553 } |
486 /*! |
554 else { |
487 Create the vertical line for horizontal snap guidance |
555 //save the points for the Vertical line |
488 */ |
556 mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.bottom())); |
489 void HsSnapToLines::createVerticalLine() |
557 mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.top())); |
490 { |
558 } |
491 if (mRectLieAbove) { |
559 } |
492 mVerticalLine.setP1(QPointF(mMinDistancePosition, mInactiveRectToCompare.top())); |
|
493 mVerticalLine.setP2(QPointF(mMinDistancePosition, mMovingRect.bottom())); |
|
494 } |
|
495 else { |
|
496 mVerticalLine.setP1(QPointF(mMinDistancePosition, mInactiveRectToCompare.bottom())); |
|
497 mVerticalLine.setP2(QPointF(mMinDistancePosition, mMovingRect.top())); |
560 } |
498 } |
561 } |
499 } |
562 |
500 |
563 /*! |
501 /*! |
564 Check if the inactive rect being compared with moving rect lies on left or right of moving rect. |
502 Check if the inactive rect being compared with moving rect lies on left or right of moving rect. |
588 } |
526 } |
589 } |
527 } |
590 } |
528 } |
591 |
529 |
592 /*! |
530 /*! |
593 Check if the top edge of moving rect is snappable to the incative rect's top or bottom edge. |
531 Check if the Horizontal edges (Top and Bottom Edges) of the inactive rect being compared |
594 The inactive rect's edge is only chosen if it is a better fit for vertical snapping. |
532 is in range of the snapping distance of the horizontal edge of moving rect |
595 */ |
533 \param movingRectHorizontalEdgePosition Position of the Horizontal edge(either top or bottom) of moving rect. |
596 void HsSnapToLines::compareTopOfMovingRectForSnapping() |
534 */ |
597 { |
535 void HsSnapToLines::checkInactiveRectHorizontalEdgesInRange(qreal movingRectHorizontalEdgePosition) |
598 //Check if the inactive rect lies to the left or right of the moving rect |
536 { |
599 checkInactiveRectLieLeftOrRightOfMovingRect(); |
|
600 |
|
601 //calculate the distance of the moving rect's top edge to the inactive rect's top and bottom edges |
|
602 qreal topToTopOfInactiveRect = qAbs(mInactiveRectToCompare.top() - mMovingRect.top()); |
|
603 qreal topToBottomOfInactiveRect = qAbs(mInactiveRectToCompare.bottom() - mMovingRect.top()); |
|
604 mTopInRange = false; |
537 mTopInRange = false; |
605 mBottomInRange = false; |
538 mBottomInRange = false; |
606 |
539 |
607 if (topToTopOfInactiveRect <= mMinHorizontalEdgesDistance) { |
540 //calculate the distance of the moving rect's horizontal edge to the inactive rect's top and bottom edges |
|
541 mHorizontalEdgeToTopOfInactiveRect = qAbs(mInactiveRectToCompare.top() - movingRectHorizontalEdgePosition); |
|
542 mHorizontalEdgeToBottomOfInactiveRect = qAbs(mInactiveRectToCompare.bottom() - movingRectHorizontalEdgePosition); |
|
543 |
|
544 if (mHorizontalEdgeToTopOfInactiveRect <= mMinHorizontalEdgesDistance) { |
608 if (mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForRight |
545 if (mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForRight |
609 || !mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForLeft) { |
546 || !mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForLeft) { |
610 mTopInRange = true; |
547 mTopInRange = true; |
611 } |
548 } |
612 } |
549 } |
613 if (topToBottomOfInactiveRect <= mMinHorizontalEdgesDistance) { |
550 if (mHorizontalEdgeToBottomOfInactiveRect <= mMinHorizontalEdgesDistance) { |
614 if (mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForRight |
551 if (mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForRight |
615 || !mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForLeft) { |
552 || !mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForLeft) { |
616 mBottomInRange = true; |
553 mBottomInRange = true; |
617 } |
554 } |
618 } |
555 } |
619 |
556 } |
620 //calculate the distance of inactive rect's top edge and container rect's top edge |
557 |
621 qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top(); |
558 /*! |
622 //calculate the distance of inactive rect's bottom edge and container rect's bottom edge |
559 Check if this inactive rect is better fit for Vertical snapping |
623 qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom(); |
560 \param containerHorizontalEdgeToInactiveRectHorizontalEdge |
624 qreal minDistancePosition = 0.0; |
561 difference between the horizontal edge of the container and same horizontal edge of inactive rect |
625 qreal distanceHorizontalEdges = 0.0; |
562 \param containerOtherHorizontalEdgeToInactiveRectOtherHorizontalEdge |
626 qreal ySnapGapAdjustment = 0.0; |
563 difference between the opposite horizontal edges of continer and the inactive rect |
627 |
564 */ |
628 //If only one edge of inactive rect is in snappable range, save that position |
565 void HsSnapToLines::checkInactiveRectBetterFitForVerticalSnapping(qreal containerHorizontalEdgeToInactiveRectHorizontalEdge, |
629 if ((mTopInRange && !mBottomInRange) |
566 qreal containerOtherHorizontalEdgeToInactiveRectOtherHorizontalEdge) |
630 || !mTopInRange && mBottomInRange) { |
567 { |
631 if (mTopInRange) { |
568 mIsBetterFitVerticalSnap = false; |
632 minDistancePosition = mInactiveRectToCompare.top(); |
|
633 distanceHorizontalEdges = topToTopOfInactiveRect; |
|
634 ySnapGapAdjustment = 0.0; |
|
635 } |
|
636 else { |
|
637 minDistancePosition = mInactiveRectToCompare.bottom(); |
|
638 distanceHorizontalEdges = topToBottomOfInactiveRect; |
|
639 ySnapGapAdjustment = mSnapGap; |
|
640 } |
|
641 } |
|
642 //else both edges of inactive rect are in range, check which is a better fit |
|
643 else if (mTopInRange && mBottomInRange) { |
|
644 //if top edge of moving rect to the top of the inactive rect is closer than the bottom edge of moving rect to the bottom of the inactive rect |
|
645 if (topToTopOfInactiveRect < topToBottomOfInactiveRect) { |
|
646 minDistancePosition = mInactiveRectToCompare.top(); |
|
647 distanceHorizontalEdges = topToTopOfInactiveRect; |
|
648 ySnapGapAdjustment = 0.0; |
|
649 mBottomInRange = false; |
|
650 } |
|
651 //if the top edge of moving rect to top of inactive rect is at the same distance as the top edge of moving rect to the bottom of inactive rect |
|
652 else if (topToTopOfInactiveRect == topToBottomOfInactiveRect) { |
|
653 //if inactive rect lies towards the top or middle of container rect, then the top edge is priortized as the selected edge for outside snapping |
|
654 if (differenceContainerTopEdgeToInactiveRectTopEdge <= differenceContainerBottomEdgeToInactiveRectBottomEdge) { |
|
655 minDistancePosition = mInactiveRectToCompare.top(); |
|
656 distanceHorizontalEdges = topToTopOfInactiveRect; |
|
657 ySnapGapAdjustment = 0.0; |
|
658 mBottomInRange = false; |
|
659 } |
|
660 //else bottom of the inactive rect lies more close to the bottom of the container rect, and hence prioritize it for snapping. |
|
661 else { |
|
662 minDistancePosition = mInactiveRectToCompare.bottom(); |
|
663 distanceHorizontalEdges = topToBottomOfInactiveRect; |
|
664 ySnapGapAdjustment = mSnapGap; |
|
665 mTopInRange = false; |
|
666 } |
|
667 } |
|
668 //else top edge of moving rect to the bottom of the inactive rect is closer than the top edge of moving rect to the top of the inactive rect |
|
669 else{ |
|
670 minDistancePosition = mInactiveRectToCompare.bottom(); |
|
671 distanceHorizontalEdges = topToBottomOfInactiveRect; |
|
672 ySnapGapAdjustment = mSnapGap; |
|
673 mTopInRange = false; |
|
674 } |
|
675 } |
|
676 |
|
677 //Check if this inactive rect is better fit than the previous selected rect |
|
678 bool verticalSnappingBetterFit = false; |
|
679 if (mTopInRange || mBottomInRange) { |
569 if (mTopInRange || mBottomInRange) { |
680 if (distanceHorizontalEdges < mMinHorizontalEdgesDistance) { |
570 if (mDistanceHorizontalEdges < mMinHorizontalEdgesDistance) { |
681 verticalSnappingBetterFit = true; |
571 mIsBetterFitVerticalSnap = true; |
682 } |
572 } |
683 else if (distanceHorizontalEdges == mMinHorizontalEdgesDistance) { //the distance in the horizontal edge is same as from the selected rectangle |
573 else if (mDistanceHorizontalEdges == mMinHorizontalEdgesDistance) { //the distance in the horizontal edge is same as from the selected rectangle |
684 //check the position of rect with respect to horizontal line |
574 //check the position of rect with respect to horizontal line |
685 checkInactiveRectPositionToHorizontalLine(); |
575 checkInactiveRectPositionToHorizontalLine(); |
686 //if vertical snap position was already found and this rect's horizontal edges lies in line with Horizontal snap line |
576 //if vertical snap position was already found and this rect's horizontal edges lies in line with Horizontal snap line |
687 if (mVerticalSnapFound && mRectHorizontalEdgeLiesInLineWithHorizontalLine) { |
577 if (mVerticalSnapFound && mRectHorizontalEdgeLiesInLineWithHorizontalLine) { |
688 if (mRectLieLeftOfHorizontalLine || mRectLiesRightOfHorizontalLine) { |
578 if (mRectLieLeftOfHorizontalLine || mRectLiesRightOfHorizontalLine) { |
690 } |
580 } |
691 } |
581 } |
692 else { |
582 else { |
693 //Prioritize first on the fact if the inactive rect is closer to the moving rect in X - direction. |
583 //Prioritize first on the fact if the inactive rect is closer to the moving rect in X - direction. |
694 if (mHorizontalDistance < mHorizontalDistanceFromSelectedRect) { |
584 if (mHorizontalDistance < mHorizontalDistanceFromSelectedRect) { |
695 verticalSnappingBetterFit = true; |
585 mIsBetterFitVerticalSnap = true; |
696 } |
586 } |
697 else if (mHorizontalDistance == mHorizontalDistanceFromSelectedRect) { |
587 else if (mHorizontalDistance == mHorizontalDistanceFromSelectedRect) { |
698 //Prioritize next if this Inactive rect is closer to the top edge of the container rect, then the previously selected rect |
588 //Prioritize next if this Inactive rect is closer to the top edge of the container rect, then the previously selected rect |
699 if (differenceContainerTopEdgeToInactiveRectTopEdge < mContainerHorizontalEdgeDistance) { |
589 if (containerHorizontalEdgeToInactiveRectHorizontalEdge < mContainerHorizontalEdgeDistance) { |
700 verticalSnappingBetterFit = true; |
590 mIsBetterFitVerticalSnap = true; |
701 } |
591 } |
702 //Prioritize next if the Inactive widget's top edge lies near to top edge of the container rect |
592 //Prioritize next if the Inactive widget's top edge lies near to top edge of the container rect |
703 else if (differenceContainerTopEdgeToInactiveRectTopEdge < differenceContainerBottomEdgeToInactiveRectBottomEdge) { |
593 else if (containerHorizontalEdgeToInactiveRectHorizontalEdge < containerOtherHorizontalEdgeToInactiveRectOtherHorizontalEdge) { |
704 verticalSnappingBetterFit = true; |
594 mIsBetterFitVerticalSnap = true; |
705 } |
595 } |
706 else { |
596 else { |
707 //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, or in opposite X direction. |
597 //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, or in opposite X direction. |
708 //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit. |
598 //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit. |
709 } |
599 } |
710 } |
600 } |
711 } |
601 } |
712 } |
602 } |
713 } |
603 } |
714 |
604 |
715 if (verticalSnappingBetterFit) { |
605 } |
716 qreal proposedBottomOfActiveRect = minDistancePosition + mActiveRectHeight + ySnapGapAdjustment; |
606 |
717 if (qBound(mContainerRect.top(), proposedBottomOfActiveRect, mContainerRect.bottom()) |
607 /*! |
718 == proposedBottomOfActiveRect) { |
608 Check if the top edge of moving rect is snappable to the incative rect's top or bottom edge. |
719 mVerticalSnapFound = true; |
|
720 mVerticalSnapPosition = minDistancePosition + ySnapGapAdjustment; |
|
721 mMinHorizontalEdgesDistance = distanceHorizontalEdges; |
|
722 mHorizontalDistanceFromSelectedRect = mHorizontalDistance; |
|
723 //Save the new distance of the Chosen Rectangle's top edge from Container's top edge |
|
724 mContainerHorizontalEdgeDistance = differenceContainerTopEdgeToInactiveRectTopEdge; |
|
725 |
|
726 if (mRectLieLeft) { |
|
727 //save the points for the Horizontal line |
|
728 mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.left(), minDistancePosition)); |
|
729 mHorizontalLine.setP2(QPointF(mMovingRect.right(), minDistancePosition)); |
|
730 } |
|
731 else { |
|
732 //save the points for the Horizontal line |
|
733 mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.right(), minDistancePosition)); |
|
734 mHorizontalLine.setP2(QPointF(mMovingRect.left(), minDistancePosition)); |
|
735 } |
|
736 } |
|
737 } |
|
738 } |
|
739 |
|
740 /*! |
|
741 Check if the bottom edge of moving rect is snappable to the incative rect's top or bottom edge. |
|
742 The inactive rect's edge is only chosen if it is a better fit for vertical snapping. |
609 The inactive rect's edge is only chosen if it is a better fit for vertical snapping. |
743 */ |
610 */ |
744 void HsSnapToLines::compareBottomOfMovingRectForSnapping() |
611 void HsSnapToLines::compareTopOfMovingRectForSnapping() |
745 { |
612 { |
746 //Check if the inactive rect lies to the left or right of the moving rect |
613 //Check if the inactive rect lies to the left or right of the moving rect |
747 checkInactiveRectLieLeftOrRightOfMovingRect(); |
614 checkInactiveRectLieLeftOrRightOfMovingRect(); |
748 |
615 |
749 //calculate the distance of the moving rect's bottom edge to the inactive rect's top and bottom edges |
616 checkInactiveRectHorizontalEdgesInRange(mMovingRect.top()); |
750 qreal bottomToTopOfInactiveRect = qAbs(mInactiveRectToCompare.top() - mMovingRect.bottom()); |
|
751 qreal bottomToBottomOfInactiveRect = qAbs(mInactiveRectToCompare.bottom() - mMovingRect.bottom()); |
|
752 mTopInRange = false; |
|
753 mBottomInRange = false; |
|
754 |
|
755 if (bottomToTopOfInactiveRect <= mMinHorizontalEdgesDistance) { |
|
756 if (mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForRight |
|
757 || !mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForLeft) { |
|
758 mTopInRange = true; |
|
759 } |
|
760 } |
|
761 if (bottomToBottomOfInactiveRect <= mMinHorizontalEdgesDistance) { |
|
762 if (mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForRight |
|
763 || !mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForLeft) { |
|
764 mBottomInRange = true; |
|
765 } |
|
766 } |
|
767 |
617 |
768 //calculate the distance of inactive rect's top edge and container rect's top edge |
618 //calculate the distance of inactive rect's top edge and container rect's top edge |
769 qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top(); |
619 qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top(); |
770 //calculate the distance of inactive rect's bottom edge and container rect's bottom edge |
620 //calculate the distance of inactive rect's bottom edge and container rect's bottom edge |
771 qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom(); |
621 qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom(); |
772 qreal minDistancePosition = 0.0; |
|
773 qreal distanceHorizontalEdges = 0.0; |
|
774 qreal ySnapGapAdjustment = 0.0; |
622 qreal ySnapGapAdjustment = 0.0; |
|
623 mDistanceHorizontalEdges = 0.0; |
|
624 mMinDistancePosition = 0.0; |
775 |
625 |
776 //If only one edge of inactive rect is in snappable range, save that position |
626 //If only one edge of inactive rect is in snappable range, save that position |
777 if ((mTopInRange && !mBottomInRange) |
627 if ((mTopInRange && !mBottomInRange) |
778 || !mTopInRange && mBottomInRange) { |
628 || !mTopInRange && mBottomInRange) { |
779 if (mTopInRange) { |
629 if (mTopInRange) { |
780 minDistancePosition = mInactiveRectToCompare.top(); |
630 mMinDistancePosition = mInactiveRectToCompare.top(); |
781 distanceHorizontalEdges = bottomToTopOfInactiveRect; |
631 mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; |
|
632 ySnapGapAdjustment = 0.0; |
|
633 } |
|
634 else { |
|
635 mMinDistancePosition = mInactiveRectToCompare.bottom(); |
|
636 mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; |
782 ySnapGapAdjustment = mSnapGap; |
637 ySnapGapAdjustment = mSnapGap; |
783 } |
638 } |
784 else { |
639 } |
785 minDistancePosition = mInactiveRectToCompare.bottom(); |
640 //else both edges of inactive rect are in range, check which is a better fit |
786 distanceHorizontalEdges = bottomToBottomOfInactiveRect; |
641 else if (mTopInRange && mBottomInRange) { |
|
642 //if top edge of moving rect to the top of the inactive rect is closer than the bottom edge of moving rect to the bottom of the inactive rect |
|
643 if (mHorizontalEdgeToTopOfInactiveRect < mHorizontalEdgeToBottomOfInactiveRect) { |
|
644 mMinDistancePosition = mInactiveRectToCompare.top(); |
|
645 mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; |
|
646 ySnapGapAdjustment = 0.0; |
|
647 mBottomInRange = false; |
|
648 } |
|
649 //if the top edge of moving rect to top of inactive rect is at the same distance as the top edge of moving rect to the bottom of inactive rect |
|
650 else if (mHorizontalEdgeToTopOfInactiveRect == mHorizontalEdgeToBottomOfInactiveRect) { |
|
651 //if inactive rect lies towards the top or middle of container rect, then the top edge is priortized as the selected edge for outside snapping |
|
652 if (differenceContainerTopEdgeToInactiveRectTopEdge <= differenceContainerBottomEdgeToInactiveRectBottomEdge) { |
|
653 mMinDistancePosition = mInactiveRectToCompare.top(); |
|
654 mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; |
|
655 ySnapGapAdjustment = 0.0; |
|
656 mBottomInRange = false; |
|
657 } |
|
658 //else bottom of the inactive rect lies more close to the bottom of the container rect, and hence prioritize it for snapping. |
|
659 else { |
|
660 mMinDistancePosition = mInactiveRectToCompare.bottom(); |
|
661 mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; |
|
662 ySnapGapAdjustment = mSnapGap; |
|
663 mTopInRange = false; |
|
664 } |
|
665 } |
|
666 //else top edge of moving rect to the bottom of the inactive rect is closer than the top edge of moving rect to the top of the inactive rect |
|
667 else{ |
|
668 mMinDistancePosition = mInactiveRectToCompare.bottom(); |
|
669 mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; |
|
670 ySnapGapAdjustment = mSnapGap; |
|
671 mTopInRange = false; |
|
672 } |
|
673 } |
|
674 |
|
675 //Check if this inactive rect is better fit than the previous selected rect |
|
676 checkInactiveRectBetterFitForVerticalSnapping(differenceContainerTopEdgeToInactiveRectTopEdge, |
|
677 differenceContainerBottomEdgeToInactiveRectBottomEdge); |
|
678 |
|
679 if (mIsBetterFitVerticalSnap) { |
|
680 qreal proposedBottomOfActiveRect = mMinDistancePosition + mActiveRectHeight + ySnapGapAdjustment; |
|
681 if (qBound(mContainerRect.top(), proposedBottomOfActiveRect, mContainerRect.bottom()) |
|
682 == proposedBottomOfActiveRect) { |
|
683 mVerticalSnapFound = true; |
|
684 mVerticalSnapPosition = mMinDistancePosition + ySnapGapAdjustment; |
|
685 mMinHorizontalEdgesDistance = mDistanceHorizontalEdges; |
|
686 mHorizontalDistanceFromSelectedRect = mHorizontalDistance; |
|
687 //Save the new distance of the Chosen Rectangle's top edge from Container's top edge |
|
688 mContainerHorizontalEdgeDistance = differenceContainerTopEdgeToInactiveRectTopEdge; |
|
689 createHorizontalLine(); |
|
690 } |
|
691 } |
|
692 } |
|
693 |
|
694 /*! |
|
695 Check if the bottom edge of moving rect is snappable to the incative rect's top or bottom edge. |
|
696 The inactive rect's edge is only chosen if it is a better fit for vertical snapping. |
|
697 */ |
|
698 void HsSnapToLines::compareBottomOfMovingRectForSnapping() |
|
699 { |
|
700 //Check if the inactive rect lies to the left or right of the moving rect |
|
701 checkInactiveRectLieLeftOrRightOfMovingRect(); |
|
702 |
|
703 //calculate the distance of the moving rect's bottom edge to the inactive rect's top and bottom edges |
|
704 checkInactiveRectHorizontalEdgesInRange(mMovingRect.bottom()); |
|
705 |
|
706 //calculate the distance of inactive rect's top edge and container rect's top edge |
|
707 qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top(); |
|
708 //calculate the distance of inactive rect's bottom edge and container rect's bottom edge |
|
709 qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom(); |
|
710 qreal ySnapGapAdjustment = 0.0; |
|
711 mDistanceHorizontalEdges = 0.0; |
|
712 mMinDistancePosition = 0.0; |
|
713 |
|
714 //If only one edge of inactive rect is in snappable range, save that position |
|
715 if ((mTopInRange && !mBottomInRange) |
|
716 || !mTopInRange && mBottomInRange) { |
|
717 if (mTopInRange) { |
|
718 mMinDistancePosition = mInactiveRectToCompare.top(); |
|
719 mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; |
|
720 ySnapGapAdjustment = mSnapGap; |
|
721 } |
|
722 else { |
|
723 mMinDistancePosition = mInactiveRectToCompare.bottom(); |
|
724 mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; |
787 ySnapGapAdjustment = 0.0; |
725 ySnapGapAdjustment = 0.0; |
788 } |
726 } |
789 } |
727 } |
790 //else both edges of inactive rect are in range, check which is a better fit |
728 //else both edges of inactive rect are in range, check which is a better fit |
791 else if (mTopInRange && mBottomInRange) { |
729 else if (mTopInRange && mBottomInRange) { |
792 //if bottom edge of moving rect to the bottom of inactive rect is closer than the bottom edge of moving rect to the top of the inactive rect |
730 //if bottom edge of moving rect to the bottom of inactive rect is closer than the bottom edge of moving rect to the top of the inactive rect |
793 if (bottomToBottomOfInactiveRect < bottomToTopOfInactiveRect ) { |
731 if (mHorizontalEdgeToBottomOfInactiveRect < mHorizontalEdgeToTopOfInactiveRect ) { |
794 minDistancePosition = mInactiveRectToCompare.bottom(); |
732 mMinDistancePosition = mInactiveRectToCompare.bottom(); |
795 distanceHorizontalEdges = bottomToBottomOfInactiveRect; |
733 mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; |
796 ySnapGapAdjustment = 0.0; |
734 ySnapGapAdjustment = 0.0; |
797 mTopInRange = false; |
735 mTopInRange = false; |
798 } |
736 } |
799 //if bottom edge of moving rect to the bottom of inactive rect is at the same distance as the bottom edge of moving rect to the top of inactive rect |
737 //if bottom edge of moving rect to the bottom of inactive rect is at the same distance as the bottom edge of moving rect to the top of inactive rect |
800 else if (bottomToBottomOfInactiveRect == bottomToTopOfInactiveRect) { |
738 else if (mHorizontalEdgeToBottomOfInactiveRect == mHorizontalEdgeToTopOfInactiveRect) { |
801 //if inactive rect lies towards the bottom of container rect, then the bottom edge is priortized as the selected edge for snapping |
739 //if inactive rect lies towards the bottom of container rect, then the bottom edge is priortized as the selected edge for snapping |
802 //This is done for outside snapping |
740 //This is done for outside snapping |
803 if (differenceContainerBottomEdgeToInactiveRectBottomEdge < differenceContainerTopEdgeToInactiveRectTopEdge) { |
741 if (differenceContainerBottomEdgeToInactiveRectBottomEdge < differenceContainerTopEdgeToInactiveRectTopEdge) { |
804 minDistancePosition = mInactiveRectToCompare.bottom(); |
742 mMinDistancePosition = mInactiveRectToCompare.bottom(); |
805 distanceHorizontalEdges = bottomToBottomOfInactiveRect; |
743 mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; |
806 ySnapGapAdjustment = 0.0; |
744 ySnapGapAdjustment = 0.0; |
807 mTopInRange = false; |
745 mTopInRange = false; |
808 } |
746 } |
809 //else top of the inactive rect lies more close to the top of the container rect or at the same distance, and hence prioritize it |
747 //else top of the inactive rect lies more close to the top of the container rect or at the same distance, and hence prioritize it |
810 else { |
748 else { |
811 minDistancePosition = mInactiveRectToCompare.top(); |
749 mMinDistancePosition = mInactiveRectToCompare.top(); |
812 distanceHorizontalEdges = bottomToTopOfInactiveRect; |
750 mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; |
813 ySnapGapAdjustment = mSnapGap; |
751 ySnapGapAdjustment = mSnapGap; |
814 mBottomInRange = false; |
752 mBottomInRange = false; |
815 } |
753 } |
816 } |
754 } |
817 //else bottom edge of moving rect to the top of inactive rect is closer than the bottom edge of moving rect to the bottom of the inactive rect |
755 //else bottom edge of moving rect to the top of inactive rect is closer than the bottom edge of moving rect to the bottom of the inactive rect |
818 else{ |
756 else{ |
819 minDistancePosition = mInactiveRectToCompare.top(); |
757 mMinDistancePosition = mInactiveRectToCompare.top(); |
820 distanceHorizontalEdges = bottomToTopOfInactiveRect; |
758 mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; |
821 ySnapGapAdjustment = mSnapGap; |
759 ySnapGapAdjustment = mSnapGap; |
822 mBottomInRange = false; |
760 mBottomInRange = false; |
823 } |
761 } |
824 } |
762 } |
825 |
763 |
826 //Check if this inactive rect is better fit than the previous selected rect |
764 //Check if this inactive rect is better fit than the previous selected rect |
827 bool verticalSnappingBetterFit = false; |
765 checkInactiveRectBetterFitForVerticalSnapping(differenceContainerBottomEdgeToInactiveRectBottomEdge, |
828 if (mTopInRange || mBottomInRange) { |
766 differenceContainerTopEdgeToInactiveRectTopEdge); |
829 if (distanceHorizontalEdges < mMinHorizontalEdgesDistance) { |
767 |
830 verticalSnappingBetterFit = true; |
768 if (mIsBetterFitVerticalSnap) { |
831 } |
769 qreal proposedTopOfActiveRect = mMinDistancePosition - mActiveRectHeight - ySnapGapAdjustment; |
832 else if (distanceHorizontalEdges == mMinHorizontalEdgesDistance) { //the distance in the horizontal edge is same as from the selected rectangle |
|
833 //check the position of rect with respect to horizontal line |
|
834 checkInactiveRectPositionToHorizontalLine(); |
|
835 //if vertical snap was already found and the horizontal line of rect is in line with horizontal snap line |
|
836 if (mVerticalSnapFound && mRectHorizontalEdgeLiesInLineWithHorizontalLine) { |
|
837 if (mRectLieLeftOfHorizontalLine || mRectLiesRightOfHorizontalLine) { |
|
838 extendHorizontalLineToIncludeInactiveRect(); |
|
839 } |
|
840 } |
|
841 else { |
|
842 //Prioritize first on the fact if the inactive rect is closer to the moving rect in X - direction. |
|
843 if (mHorizontalDistance < mHorizontalDistanceFromSelectedRect) { |
|
844 verticalSnappingBetterFit = true; |
|
845 } |
|
846 else if (mHorizontalDistance == mHorizontalDistanceFromSelectedRect) { |
|
847 //Prioritize next if this Inactive rect is closer to the bottom edge of the container rect, then the previously selected rect |
|
848 if (differenceContainerBottomEdgeToInactiveRectBottomEdge < mContainerHorizontalEdgeDistance) { |
|
849 verticalSnappingBetterFit = true; |
|
850 } |
|
851 //Prioritize next if the Inactive widget's bottom edge lies near to bottom edge of the container rect |
|
852 else if (differenceContainerBottomEdgeToInactiveRectBottomEdge < differenceContainerTopEdgeToInactiveRectTopEdge) { |
|
853 verticalSnappingBetterFit = true; |
|
854 } |
|
855 else { |
|
856 //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, or in opposite X direction. |
|
857 //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit. |
|
858 } |
|
859 } |
|
860 } |
|
861 } |
|
862 } |
|
863 |
|
864 if (verticalSnappingBetterFit) { |
|
865 qreal proposedTopOfActiveRect = minDistancePosition - mActiveRectHeight - ySnapGapAdjustment; |
|
866 if (qBound(mContainerRect.top(), proposedTopOfActiveRect, mContainerRect.bottom()) |
770 if (qBound(mContainerRect.top(), proposedTopOfActiveRect, mContainerRect.bottom()) |
867 == proposedTopOfActiveRect) { |
771 == proposedTopOfActiveRect) { |
868 mVerticalSnapFound = true; |
772 mVerticalSnapFound = true; |
869 mVerticalSnapPosition = proposedTopOfActiveRect; |
773 mVerticalSnapPosition = proposedTopOfActiveRect; |
870 mMinHorizontalEdgesDistance = distanceHorizontalEdges; |
774 mMinHorizontalEdgesDistance = mDistanceHorizontalEdges; |
871 mHorizontalDistanceFromSelectedRect = mHorizontalDistance; |
775 mHorizontalDistanceFromSelectedRect = mHorizontalDistance; |
872 //Save the new distance of the Selected Rectangle's bottom edge from Container's bottom edge |
776 //Save the new distance of the Selected Rectangle's bottom edge from Container's bottom edge |
873 mContainerHorizontalEdgeDistance = differenceContainerBottomEdgeToInactiveRectBottomEdge; |
777 mContainerHorizontalEdgeDistance = differenceContainerBottomEdgeToInactiveRectBottomEdge; |
874 |
778 createHorizontalLine(); |
875 if (mRectLieLeft) { |
779 } |
876 //save the points for the Horizontal line |
780 } |
877 mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.left(), minDistancePosition)); |
781 } |
878 mHorizontalLine.setP2(QPointF(mMovingRect.right(), minDistancePosition)); |
782 |
879 } |
783 /*! |
880 else { |
784 Create the horizontal line for vertical snap guidance |
881 //save the points for the Horizontal line |
785 */ |
882 mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.right(), minDistancePosition)); |
786 void HsSnapToLines::createHorizontalLine() |
883 mHorizontalLine.setP2(QPointF(mMovingRect.left(), minDistancePosition)); |
787 { |
884 } |
788 if (mRectLieLeft) { |
885 } |
789 //save the points for the Horizontal line |
|
790 mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.left(), mMinDistancePosition)); |
|
791 mHorizontalLine.setP2(QPointF(mMovingRect.right(), mMinDistancePosition)); |
|
792 } |
|
793 else { |
|
794 //save the points for the Horizontal line |
|
795 mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.right(), mMinDistancePosition)); |
|
796 mHorizontalLine.setP2(QPointF(mMovingRect.left(), mMinDistancePosition)); |
886 } |
797 } |
887 } |
798 } |
888 |
799 |
889 /*! |
800 /*! |
890 Extend the Vertical line on both side of reference(snapping) rectancles. |
801 Extend the Vertical line on both side of reference(snapping) rectancles. |