| 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 |