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