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