OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) | 2 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) |
3 * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org> | 3 * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org> |
4 * | 4 * |
5 * All rights reserved. | 5 * All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 using namespace HTMLNames; | 45 using namespace HTMLNames; |
46 | 46 |
47 static RectsAlignment alignmentForRects(FocusType, const LayoutRect&, const Layo
utRect&, const LayoutSize& viewSize); | 47 static RectsAlignment alignmentForRects(FocusType, const LayoutRect&, const Layo
utRect&, const LayoutSize& viewSize); |
48 static bool areRectsFullyAligned(FocusType, const LayoutRect&, const LayoutRect&
); | 48 static bool areRectsFullyAligned(FocusType, const LayoutRect&, const LayoutRect&
); |
49 static bool areRectsPartiallyAligned(FocusType, const LayoutRect&, const LayoutR
ect&); | 49 static bool areRectsPartiallyAligned(FocusType, const LayoutRect&, const LayoutR
ect&); |
50 static bool areRectsMoreThanFullScreenApart(FocusType, const LayoutRect& curRect
, const LayoutRect& targetRect, const LayoutSize& viewSize); | 50 static bool areRectsMoreThanFullScreenApart(FocusType, const LayoutRect& curRect
, const LayoutRect& targetRect, const LayoutSize& viewSize); |
51 static bool isRectInDirection(FocusType, const LayoutRect&, const LayoutRect&); | 51 static bool isRectInDirection(FocusType, const LayoutRect&, const LayoutRect&); |
52 static void deflateIfOverlapped(LayoutRect&, LayoutRect&); | 52 static void deflateIfOverlapped(LayoutRect&, LayoutRect&); |
53 static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const Layo
utRect&); | 53 static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const Layo
utRect&); |
54 static void entryAndExitPointsForDirection(FocusType, const LayoutRect& starting
Rect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entr
yPoint); | |
55 static bool isScrollableNode(const Node*); | 54 static bool isScrollableNode(const Node*); |
56 | 55 |
57 FocusCandidate::FocusCandidate(Node* node, FocusType type) | 56 FocusCandidate::FocusCandidate(Node* node, FocusType type) |
58 : visibleNode(0) | 57 : visibleNode(0) |
59 , focusableNode(0) | 58 , focusableNode(0) |
60 , enclosingScrollableBox(0) | 59 , enclosingScrollableBox(0) |
61 , distance(maxDistance()) | 60 , distance(maxDistance()) |
62 , parentDistance(maxDistance()) | 61 , parentDistance(maxDistance()) |
63 , alignment(None) | 62 , alignment(None) |
64 , parentAlignment(None) | 63 , parentAlignment(None) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 // operations. | 136 // operations. |
138 // * a = Current focused node's rect. | 137 // * a = Current focused node's rect. |
139 // * b = Focus candidate node's rect. | 138 // * b = Focus candidate node's rect. |
140 static bool areRectsFullyAligned(FocusType type, const LayoutRect& a, const Layo
utRect& b) | 139 static bool areRectsFullyAligned(FocusType type, const LayoutRect& a, const Layo
utRect& b) |
141 { | 140 { |
142 LayoutUnit aStart, bStart, aEnd, bEnd; | 141 LayoutUnit aStart, bStart, aEnd, bEnd; |
143 | 142 |
144 switch (type) { | 143 switch (type) { |
145 case FocusTypeLeft: | 144 case FocusTypeLeft: |
146 aStart = a.x(); | 145 aStart = a.x(); |
147 bEnd = b.maxX(); | 146 bEnd = b.x(); |
148 break; | 147 break; |
149 case FocusTypeRight: | 148 case FocusTypeRight: |
150 aStart = b.x(); | 149 aStart = b.x(); |
151 bEnd = a.maxX(); | 150 bEnd = a.x(); |
152 break; | 151 break; |
153 case FocusTypeUp: | 152 case FocusTypeUp: |
154 aStart = a.y(); | 153 aStart = a.y(); |
155 bEnd = b.y(); | 154 bEnd = b.y(); |
156 break; | 155 break; |
157 case FocusTypeDown: | 156 case FocusTypeDown: |
158 aStart = b.y(); | 157 aStart = b.y(); |
159 bEnd = a.y(); | 158 bEnd = a.y(); |
160 break; | 159 break; |
161 default: | 160 default: |
(...skipping 19 matching lines...) Expand all Loading... |
181 // **************************** ***************************** | 180 // **************************** ***************************** |
182 // * _ * _ _ _ _ * * _ * _ _ * | 181 // * _ * _ _ _ _ * * _ * _ _ * |
183 // * |_| _ * |_|_|_|_| * * _ |_| * |_|_| * | 182 // * |_| _ * |_|_|_|_| * * _ |_| * |_|_| * |
184 // * |_|....|_| * . * * |_|....|_| * . * | 183 // * |_|....|_| * . * * |_|....|_| * . * |
185 // * |_| |_| (1) . * * |_| |_| (2) . * | 184 // * |_| |_| (1) . * * |_| |_| (2) . * |
186 // * |_| * _._ * * |_| * _ _._ _ * | 185 // * |_| * _._ * * |_| * _ _._ _ * |
187 // * * |_|_| * * * |_|_|_|_| * | 186 // * * |_|_| * * * |_|_|_|_| * |
188 // * * * * * * | 187 // * * * * * * |
189 // **************************** ***************************** | 188 // **************************** ***************************** |
190 | 189 |
191 // Horizontal Vertical Horizontal Vertical | 190 return (bMiddle >= aStart && bMiddle <= aEnd) // (1) |
192 // **************************** ***************************** | 191 || (aMiddle >= bStart && aMiddle <= bEnd); // (2) |
193 // * _......_ * _ _ _ _ * * _ * _ _ _ _ * | |
194 // * |_| |_| * |_|_|_|_| * * |_| _ * |_|_|_|_| * | |
195 // * |_| |_| * . * * |_| |_| * . * | |
196 // * |_| (3) . * * |_|....|_| (4) . * | |
197 // * * ._ _ * * * _ _. * | |
198 // * * |_|_| * * * |_|_| * | |
199 // * * * * * * | |
200 // **************************** ***************************** | |
201 | |
202 return ((bMiddle >= aStart && bMiddle <= aEnd) // (1) | |
203 || (aMiddle >= bStart && aMiddle <= bEnd) // (2) | |
204 || (bStart == aStart) // (3) | |
205 || (bEnd == aEnd)); // (4) | |
206 } | 192 } |
207 | 193 |
208 // This method checks if |start| and |dest| have a partial intersection, either | 194 // This method checks if rects |a| and |b| are partially aligned either vertical
ly or |
209 // horizontally or vertically. | 195 // horizontally. In general, rects whose either of edges falls between the top o
r |
| 196 // bottom of each other are considered partially-aligned. |
| 197 // This is a separate set of conditions from "fully-aligned" and do not include
cases |
| 198 // that satisfy the former. |
210 // * a = Current focused node's rect. | 199 // * a = Current focused node's rect. |
211 // * b = Focus candidate node's rect. | 200 // * b = Focus candidate node's rect. |
212 static bool areRectsPartiallyAligned(FocusType type, const LayoutRect& a, const
LayoutRect& b) | 201 static bool areRectsPartiallyAligned(FocusType type, const LayoutRect& a, const
LayoutRect& b) |
213 { | 202 { |
214 LayoutUnit aStart = start(type, a); | 203 LayoutUnit aStart = start(type, a); |
215 LayoutUnit bStart = start(type, b); | 204 LayoutUnit bStart = start(type, b); |
216 LayoutUnit bMiddle = middle(type, b); | |
217 LayoutUnit aEnd = end(type, a); | 205 LayoutUnit aEnd = end(type, a); |
218 LayoutUnit bEnd = end(type, b); | 206 LayoutUnit bEnd = end(type, b); |
219 | 207 |
220 // Picture of the partially aligned logic: | 208 // Picture of the partially aligned logic: |
221 // | 209 // |
222 // Horizontal Vertical | 210 // Horizontal Vertical |
223 // ******************************** | 211 // ******************************** |
224 // * _ * _ _ _ * | 212 // * _ * _ _ _ * |
225 // * |_| * |_|_|_| * | 213 // * |_| * |_|_|_| * |
226 // * |_|.... _ * . . * | 214 // * |_|.... _ * . . * |
227 // * |_| |_| * . . * | 215 // * |_| |_| * . . * |
228 // * |_|....|_| * ._._ _ * | 216 // * |_|....|_| * ._._ _ * |
229 // * |_| * |_|_|_| * | 217 // * |_| * |_|_|_| * |
230 // * |_| * * | 218 // * |_| * * |
231 // * * * | 219 // * * * |
232 // ******************************** | 220 // ******************************** |
233 // | 221 // |
234 // ... and variants of the above cases. | 222 // ... and variants of the above cases. |
235 return ((bStart >= aStart && bStart <= aEnd) | 223 return (bStart >= aStart && bStart <= aEnd) |
236 || (bEnd >= aStart && bEnd <= aEnd) | 224 || (bEnd >= aStart && bEnd <= aEnd); |
237 || (bMiddle >= aStart && bMiddle <= aEnd)); | |
238 } | 225 } |
239 | 226 |
240 static bool areRectsMoreThanFullScreenApart(FocusType type, const LayoutRect& cu
rRect, const LayoutRect& targetRect, const LayoutSize& viewSize) | 227 static bool areRectsMoreThanFullScreenApart(FocusType type, const LayoutRect& cu
rRect, const LayoutRect& targetRect, const LayoutSize& viewSize) |
241 { | 228 { |
242 ASSERT(isRectInDirection(type, curRect, targetRect)); | 229 ASSERT(isRectInDirection(type, curRect, targetRect)); |
243 | 230 |
244 switch (type) { | 231 switch (type) { |
245 case FocusTypeLeft: | 232 case FocusTypeLeft: |
246 return curRect.x() - targetRect.maxX() > viewSize.width(); | 233 return curRect.x() - targetRect.maxX() > viewSize.width(); |
247 case FocusTypeRight: | 234 case FocusTypeRight: |
248 return targetRect.x() - curRect.maxX() > viewSize.width(); | 235 return targetRect.x() - curRect.maxX() > viewSize.width(); |
249 case FocusTypeUp: | 236 case FocusTypeUp: |
250 return curRect.y() - targetRect.maxY() > viewSize.height(); | 237 return curRect.y() - targetRect.maxY() > viewSize.height(); |
251 case FocusTypeDown: | 238 case FocusTypeDown: |
252 return targetRect.y() - curRect.maxY() > viewSize.height(); | 239 return targetRect.y() - curRect.maxY() > viewSize.height(); |
253 default: | 240 default: |
254 ASSERT_NOT_REACHED(); | 241 ASSERT_NOT_REACHED(); |
255 return true; | 242 return true; |
256 } | 243 } |
257 } | 244 } |
258 | 245 |
259 // Return true if rect |a| is below |b|. False otherwise. | 246 // Return true if rect |a| is below |b|. False otherwise. |
| 247 // For overlapping rects, |a| is considered to be below |b| |
| 248 // if both edges of |a| are below the respective ones of |b| |
260 static inline bool below(const LayoutRect& a, const LayoutRect& b) | 249 static inline bool below(const LayoutRect& a, const LayoutRect& b) |
261 { | 250 { |
262 return a.y() > b.maxY(); | 251 return a.y() >= b.maxY() |
| 252 || (a.y() >= b.y() && a.maxY() > b.maxY()); |
263 } | 253 } |
264 | 254 |
265 // Return true if rect |a| is on the right of |b|. False otherwise. | 255 // Return true if rect |a| is on the right of |b|. False otherwise. |
| 256 // For overlapping rects, |a| is considered to be on the right of |b| |
| 257 // if both edges of |a| are on the right of the respective ones of |b| |
266 static inline bool rightOf(const LayoutRect& a, const LayoutRect& b) | 258 static inline bool rightOf(const LayoutRect& a, const LayoutRect& b) |
267 { | 259 { |
268 return a.x() > b.maxX(); | 260 return a.x() >= b.maxX() |
| 261 || (a.x() >= b.x() && a.maxX() > b.maxX()); |
269 } | 262 } |
270 | 263 |
271 static bool isRectInDirection(FocusType type, const LayoutRect& curRect, const L
ayoutRect& targetRect) | 264 static bool isRectInDirection(FocusType type, const LayoutRect& curRect, const L
ayoutRect& targetRect) |
272 { | 265 { |
273 switch (type) { | 266 switch (type) { |
274 case FocusTypeLeft: | 267 case FocusTypeLeft: |
275 return targetRect.maxX() <= curRect.x(); | 268 return rightOf(curRect, targetRect); |
276 case FocusTypeRight: | 269 case FocusTypeRight: |
277 return targetRect.x() >= curRect.maxX(); | 270 return rightOf(targetRect, curRect); |
278 case FocusTypeUp: | 271 case FocusTypeUp: |
279 return targetRect.maxY() <= curRect.y(); | 272 return below(curRect, targetRect); |
280 case FocusTypeDown: | 273 case FocusTypeDown: |
281 return targetRect.y() >= curRect.maxY(); | 274 return below(targetRect, curRect); |
282 default: | 275 default: |
283 ASSERT_NOT_REACHED(); | 276 ASSERT_NOT_REACHED(); |
284 return false; | 277 return false; |
285 } | 278 } |
286 } | 279 } |
287 | 280 |
288 // Checks if |node| is offscreen the visible area (viewport) of its container | 281 // Checks if |node| is offscreen the visible area (viewport) of its container |
289 // document. In case it is, one can scroll in direction or take any different | 282 // document. In case it is, one can scroll in direction or take any different |
290 // desired action later on. | 283 // desired action later on. |
291 bool hasOffscreenRect(Node* node, FocusType type) | 284 bool hasOffscreenRect(Node* node, FocusType type) |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 return rect; | 525 return rect; |
533 } | 526 } |
534 | 527 |
535 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame) | 528 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame) |
536 { | 529 { |
537 return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect())
; | 530 return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect())
; |
538 } | 531 } |
539 | 532 |
540 // This method calculates the exitPoint from the startingRect and the entryPoint
into the candidate rect. | 533 // This method calculates the exitPoint from the startingRect and the entryPoint
into the candidate rect. |
541 // The line between those 2 points is the closest distance between the 2 rects. | 534 // The line between those 2 points is the closest distance between the 2 rects. |
| 535 // Takes care of overlapping rects, defining points so that the distance between
them |
| 536 // is zero where necessary |
542 void entryAndExitPointsForDirection(FocusType type, const LayoutRect& startingRe
ct, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryP
oint) | 537 void entryAndExitPointsForDirection(FocusType type, const LayoutRect& startingRe
ct, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryP
oint) |
543 { | 538 { |
544 switch (type) { | 539 switch (type) { |
545 case FocusTypeLeft: | 540 case FocusTypeLeft: |
546 exitPoint.setX(startingRect.x()); | 541 exitPoint.setX(startingRect.x()); |
547 entryPoint.setX(potentialRect.maxX()); | 542 if (potentialRect.maxX() < startingRect.x()) |
| 543 entryPoint.setX(potentialRect.maxX()); |
| 544 else |
| 545 entryPoint.setX(startingRect.x()); |
548 break; | 546 break; |
549 case FocusTypeUp: | 547 case FocusTypeUp: |
550 exitPoint.setY(startingRect.y()); | 548 exitPoint.setY(startingRect.y()); |
551 entryPoint.setY(potentialRect.maxY()); | 549 if (potentialRect.maxY() < startingRect.y()) |
| 550 entryPoint.setY(potentialRect.maxY()); |
| 551 else |
| 552 entryPoint.setY(startingRect.y()); |
552 break; | 553 break; |
553 case FocusTypeRight: | 554 case FocusTypeRight: |
554 exitPoint.setX(startingRect.maxX()); | 555 exitPoint.setX(startingRect.maxX()); |
555 entryPoint.setX(potentialRect.x()); | 556 if (potentialRect.x() > startingRect.maxX()) |
| 557 entryPoint.setX(potentialRect.x()); |
| 558 else |
| 559 entryPoint.setX(startingRect.maxX()); |
556 break; | 560 break; |
557 case FocusTypeDown: | 561 case FocusTypeDown: |
558 exitPoint.setY(startingRect.maxY()); | 562 exitPoint.setY(startingRect.maxY()); |
559 entryPoint.setY(potentialRect.y()); | 563 if (potentialRect.y() > startingRect.maxY()) |
| 564 entryPoint.setY(potentialRect.y()); |
| 565 else |
| 566 entryPoint.setY(startingRect.maxY()); |
560 break; | 567 break; |
561 default: | 568 default: |
562 ASSERT_NOT_REACHED(); | 569 ASSERT_NOT_REACHED(); |
563 } | 570 } |
564 | 571 |
565 switch (type) { | 572 switch (type) { |
566 case FocusTypeLeft: | 573 case FocusTypeLeft: |
567 case FocusTypeRight: | 574 case FocusTypeRight: |
568 if (below(startingRect, potentialRect)) { | 575 if (below(startingRect, potentialRect)) { |
569 exitPoint.setY(startingRect.y()); | 576 exitPoint.setY(startingRect.y()); |
570 entryPoint.setY(potentialRect.maxY()); | 577 if (potentialRect.maxY() < startingRect.y()) |
| 578 entryPoint.setY(potentialRect.maxY()); |
| 579 else |
| 580 entryPoint.setY(startingRect.y()); |
571 } else if (below(potentialRect, startingRect)) { | 581 } else if (below(potentialRect, startingRect)) { |
572 exitPoint.setY(startingRect.maxY()); | 582 exitPoint.setY(startingRect.maxY()); |
573 entryPoint.setY(potentialRect.y()); | 583 if (potentialRect.y() > startingRect.maxY()) |
| 584 entryPoint.setY(potentialRect.y()); |
| 585 else |
| 586 entryPoint.setY(startingRect.maxY()); |
574 } else { | 587 } else { |
575 exitPoint.setY(max(startingRect.y(), potentialRect.y())); | 588 exitPoint.setY(max(startingRect.y(), potentialRect.y())); |
576 entryPoint.setY(exitPoint.y()); | 589 entryPoint.setY(exitPoint.y()); |
577 } | 590 } |
578 break; | 591 break; |
579 case FocusTypeUp: | 592 case FocusTypeUp: |
580 case FocusTypeDown: | 593 case FocusTypeDown: |
581 if (rightOf(startingRect, potentialRect)) { | 594 if (rightOf(startingRect, potentialRect)) { |
582 exitPoint.setX(startingRect.x()); | 595 exitPoint.setX(startingRect.x()); |
583 entryPoint.setX(potentialRect.maxX()); | 596 if (potentialRect.maxX() < startingRect.x()) |
| 597 entryPoint.setX(potentialRect.maxX()); |
| 598 else |
| 599 entryPoint.setX(startingRect.x()); |
584 } else if (rightOf(potentialRect, startingRect)) { | 600 } else if (rightOf(potentialRect, startingRect)) { |
585 exitPoint.setX(startingRect.maxX()); | 601 exitPoint.setX(startingRect.maxX()); |
586 entryPoint.setX(potentialRect.x()); | 602 if (potentialRect.x() > startingRect.maxX()) |
| 603 entryPoint.setX(potentialRect.x()); |
| 604 else |
| 605 entryPoint.setX(startingRect.maxX()); |
587 } else { | 606 } else { |
588 exitPoint.setX(max(startingRect.x(), potentialRect.x())); | 607 exitPoint.setX(max(startingRect.x(), potentialRect.x())); |
589 entryPoint.setX(exitPoint.x()); | 608 entryPoint.setX(exitPoint.x()); |
590 } | 609 } |
591 break; | 610 break; |
592 default: | 611 default: |
593 ASSERT_NOT_REACHED(); | 612 ASSERT_NOT_REACHED(); |
594 } | 613 } |
595 } | 614 } |
596 | 615 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 | 648 |
630 LayoutRect nodeRect = candidate.rect; | 649 LayoutRect nodeRect = candidate.rect; |
631 LayoutRect currentRect = current.rect; | 650 LayoutRect currentRect = current.rect; |
632 deflateIfOverlapped(currentRect, nodeRect); | 651 deflateIfOverlapped(currentRect, nodeRect); |
633 | 652 |
634 if (!isRectInDirection(type, currentRect, nodeRect)) | 653 if (!isRectInDirection(type, currentRect, nodeRect)) |
635 return; | 654 return; |
636 | 655 |
637 LayoutPoint exitPoint; | 656 LayoutPoint exitPoint; |
638 LayoutPoint entryPoint; | 657 LayoutPoint entryPoint; |
639 LayoutUnit sameAxisDistance = 0; | |
640 LayoutUnit otherAxisDistance = 0; | |
641 entryAndExitPointsForDirection(type, currentRect, nodeRect, exitPoint, entry
Point); | 658 entryAndExitPointsForDirection(type, currentRect, nodeRect, exitPoint, entry
Point); |
642 | 659 |
| 660 LayoutUnit xAxis = exitPoint.x() - entryPoint.x(); |
| 661 LayoutUnit yAxis = exitPoint.y() - entryPoint.y(); |
| 662 |
| 663 LayoutUnit navigationAxisDistance; |
| 664 LayoutUnit orthogonalAxisDistance; |
| 665 |
643 switch (type) { | 666 switch (type) { |
644 case FocusTypeLeft: | 667 case FocusTypeLeft: |
645 sameAxisDistance = exitPoint.x() - entryPoint.x(); | 668 case FocusTypeRight: |
646 otherAxisDistance = absoluteValue(exitPoint.y() - entryPoint.y()); | 669 navigationAxisDistance = xAxis.abs(); |
| 670 orthogonalAxisDistance = yAxis.abs(); |
647 break; | 671 break; |
648 case FocusTypeUp: | 672 case FocusTypeUp: |
649 sameAxisDistance = exitPoint.y() - entryPoint.y(); | |
650 otherAxisDistance = absoluteValue(exitPoint.x() - entryPoint.x()); | |
651 break; | |
652 case FocusTypeRight: | |
653 sameAxisDistance = entryPoint.x() - exitPoint.x(); | |
654 otherAxisDistance = absoluteValue(entryPoint.y() - exitPoint.y()); | |
655 break; | |
656 case FocusTypeDown: | 673 case FocusTypeDown: |
657 sameAxisDistance = entryPoint.y() - exitPoint.y(); | 674 navigationAxisDistance = yAxis.abs(); |
658 otherAxisDistance = absoluteValue(entryPoint.x() - exitPoint.x()); | 675 orthogonalAxisDistance = xAxis.abs(); |
659 break; | 676 break; |
660 default: | 677 default: |
661 ASSERT_NOT_REACHED(); | 678 ASSERT_NOT_REACHED(); |
662 return; | 679 return; |
663 } | 680 } |
664 | 681 |
665 float x = ((entryPoint.x() - exitPoint.x()) * (entryPoint.x() - exitPoint.x(
))).toFloat(); | 682 double euclidianDistancePow2 = (xAxis * xAxis + yAxis * yAxis).toDouble(); |
666 float y = ((entryPoint.y() - exitPoint.y()) * (entryPoint.y() - exitPoint.y(
))).toFloat(); | 683 LayoutRect intersectionRect = intersection(currentRect, nodeRect); |
| 684 double overlap = (intersectionRect.width() * intersectionRect.height()).toDo
uble(); |
667 | 685 |
668 float euclidianDistance = sqrt(x + y); | 686 // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handlin
g |
| 687 candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance+ o
rthogonalAxisDistance * 2 - sqrt(overlap); |
669 | 688 |
670 // Loosely based on http://www.w3.org/TR/WICD/#focus-handling | |
671 // df = dotDist + dx + dy + 2 * (xdisplacement + ydisplacement) - sqrt(Overl
ap) | |
672 | |
673 float distance = euclidianDistance + sameAxisDistance + 2 * otherAxisDistanc
e; | |
674 candidate.distance = roundf(distance); | |
675 LayoutSize viewSize = candidate.visibleNode->document().page()->mainFrame()-
>view()->visibleContentRect().size(); | 689 LayoutSize viewSize = candidate.visibleNode->document().page()->mainFrame()-
>view()->visibleContentRect().size(); |
676 candidate.alignment = alignmentForRects(type, currentRect, nodeRect, viewSiz
e); | 690 candidate.alignment = alignmentForRects(type, currentRect, nodeRect, viewSiz
e); |
677 } | 691 } |
678 | 692 |
679 bool canBeScrolledIntoView(FocusType type, const FocusCandidate& candidate) | 693 bool canBeScrolledIntoView(FocusType type, const FocusCandidate& candidate) |
680 { | 694 { |
681 ASSERT(candidate.visibleNode && candidate.isOffscreen); | 695 ASSERT(candidate.visibleNode && candidate.isOffscreen); |
682 LayoutRect candidateRect = candidate.rect; | 696 LayoutRect candidateRect = candidate.rect; |
683 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { | 697 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { |
684 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); | 698 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(ar
ea.document().frame(), area.computeRect(area.imageElement()->renderer())), 1); | 744 LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(ar
ea.document().frame(), area.computeRect(area.imageElement()->renderer())), 1); |
731 return rect; | 745 return rect; |
732 } | 746 } |
733 | 747 |
734 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) | 748 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) |
735 { | 749 { |
736 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : 0; | 750 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : 0; |
737 }; | 751 }; |
738 | 752 |
739 } // namespace WebCore | 753 } // namespace WebCore |
OLD | NEW |