Chromium Code Reviews| 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 |