| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011, Google Inc. All rights reserved. | 2 * Copyright (c) 2011, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 #include "platform/PlatformScreen.h" | 40 #include "platform/PlatformScreen.h" |
| 41 #include "platform/PlatformTouchEvent.h" | 41 #include "platform/PlatformTouchEvent.h" |
| 42 #include "platform/PlatformWheelEvent.h" | 42 #include "platform/PlatformWheelEvent.h" |
| 43 #include "platform/PopupMenuClient.h" | 43 #include "platform/PopupMenuClient.h" |
| 44 #include "platform/RuntimeEnabledFeatures.h" | 44 #include "platform/RuntimeEnabledFeatures.h" |
| 45 #include "platform/fonts/Font.h" | 45 #include "platform/fonts/Font.h" |
| 46 #include "platform/fonts/FontCache.h" | 46 #include "platform/fonts/FontCache.h" |
| 47 #include "platform/fonts/FontSelector.h" | 47 #include "platform/fonts/FontSelector.h" |
| 48 #include "platform/geometry/IntRect.h" | 48 #include "platform/geometry/IntRect.h" |
| 49 #include "platform/graphics/GraphicsContext.h" | 49 #include "platform/graphics/GraphicsContext.h" |
| 50 #include "platform/scroll/FramelessScrollViewClient.h" | |
| 51 #include "platform/scroll/ScrollbarTheme.h" | 50 #include "platform/scroll/ScrollbarTheme.h" |
| 52 #include "platform/text/StringTruncator.h" | 51 #include "platform/text/StringTruncator.h" |
| 53 #include "platform/text/TextRun.h" | 52 #include "platform/text/TextRun.h" |
| 54 #include "web/PopupContainer.h" | 53 #include "web/PopupContainer.h" |
| 54 #include "web/PopupContainerClient.h" |
| 55 #include "web/PopupMenuChromium.h" | 55 #include "web/PopupMenuChromium.h" |
| 56 #include "wtf/ASCIICType.h" | 56 #include "wtf/ASCIICType.h" |
| 57 #include "wtf/CurrentTime.h" | 57 #include "wtf/CurrentTime.h" |
| 58 #include <limits> | 58 #include <limits> |
| 59 | 59 |
| 60 namespace blink { | 60 namespace blink { |
| 61 | 61 |
| 62 using namespace WTF::Unicode; | 62 using namespace WTF::Unicode; |
| 63 | 63 |
| 64 const int PopupListBox::defaultMaxHeight = 500; | 64 const int PopupListBox::defaultMaxHeight = 500; |
| 65 static const int maxVisibleRows = 20; | 65 static const int maxVisibleRows = 20; |
| 66 static const int minEndOfLinePadding = 2; | 66 static const int minEndOfLinePadding = 2; |
| 67 static const TimeStamp typeAheadTimeoutMs = 1000; | 67 static const TimeStamp typeAheadTimeoutMs = 1000; |
| 68 | 68 |
| 69 PopupListBox::PopupListBox(PopupMenuClient* client, bool deviceSupportsTouch) | 69 PopupListBox::PopupListBox(PopupMenuClient* client, bool deviceSupportsTouch, Po
pupContainer* container) |
| 70 : m_deviceSupportsTouch(deviceSupportsTouch) | 70 : m_deviceSupportsTouch(deviceSupportsTouch) |
| 71 , m_originalIndex(0) | 71 , m_originalIndex(0) |
| 72 , m_selectedIndex(0) | 72 , m_selectedIndex(0) |
| 73 , m_acceptedIndexOnAbandon(-1) | 73 , m_acceptedIndexOnAbandon(-1) |
| 74 , m_visibleRows(0) | 74 , m_visibleRows(0) |
| 75 , m_baseWidth(0) | 75 , m_baseWidth(0) |
| 76 , m_maxHeight(defaultMaxHeight) | 76 , m_maxHeight(defaultMaxHeight) |
| 77 , m_popupClient(client) | 77 , m_popupClient(client) |
| 78 , m_repeatingChar(0) | 78 , m_repeatingChar(0) |
| 79 , m_lastCharTime(0) | 79 , m_lastCharTime(0) |
| 80 , m_maxWindowWidth(std::numeric_limits<int>::max()) | 80 , m_maxWindowWidth(std::numeric_limits<int>::max()) |
| 81 , m_container(container) |
| 81 { | 82 { |
| 82 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); | 83 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); |
| 83 } | 84 } |
| 84 | 85 |
| 86 PopupListBox::~PopupListBox() |
| 87 { |
| 88 clear(); |
| 89 |
| 90 setHasHorizontalScrollbar(false); |
| 91 setHasVerticalScrollbar(false); |
| 92 } |
| 93 |
| 85 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) | 94 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) |
| 86 { | 95 { |
| 87 Scrollbar* scrollbar = scrollbarAtPoint(event.position()); | 96 Scrollbar* scrollbar = scrollbarAtPoint(event.position()); |
| 88 if (scrollbar) { | 97 if (scrollbar) { |
| 89 m_capturingScrollbar = scrollbar; | 98 m_capturingScrollbar = scrollbar; |
| 90 m_capturingScrollbar->mouseDown(event); | 99 m_capturingScrollbar->mouseDown(event); |
| 91 return true; | 100 return true; |
| 92 } | 101 } |
| 93 | 102 |
| 94 if (!isPointInBounds(event.position())) | 103 if (!isPointInBounds(event.position())) |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 if (rightAligned) | 469 if (rightAligned) |
| 461 textX += maxWidth - itemFont.width(textRun); | 470 textX += maxWidth - itemFont.width(textRun); |
| 462 | 471 |
| 463 // Draw the item text. | 472 // Draw the item text. |
| 464 int textY = rowRect.y() + itemFont.fontMetrics().ascent() + (rowRect.height(
) - itemFont.fontMetrics().height()) / 2; | 473 int textY = rowRect.y() + itemFont.fontMetrics().ascent() + (rowRect.height(
) - itemFont.fontMetrics().height()) / 2; |
| 465 TextRunPaintInfo textRunPaintInfo(textRun); | 474 TextRunPaintInfo textRunPaintInfo(textRun); |
| 466 textRunPaintInfo.bounds = rowRect; | 475 textRunPaintInfo.bounds = rowRect; |
| 467 gc->drawBidiText(itemFont, textRunPaintInfo, IntPoint(textX, textY)); | 476 gc->drawBidiText(itemFont, textRunPaintInfo, IntPoint(textX, textY)); |
| 468 } | 477 } |
| 469 | 478 |
| 470 Font PopupListBox::getRowFont(int rowIndex) | 479 Font PopupListBox::getRowFont(int rowIndex) const |
| 471 { | 480 { |
| 472 Font itemFont = m_popupClient->itemStyle(rowIndex).font(); | 481 Font itemFont = m_popupClient->itemStyle(rowIndex).font(); |
| 473 if (m_popupClient->itemIsLabel(rowIndex)) { | 482 if (m_popupClient->itemIsLabel(rowIndex)) { |
| 474 // Bold-ify labels (ie, an <optgroup> heading). | 483 // Bold-ify labels (ie, an <optgroup> heading). |
| 475 FontDescription d = itemFont.fontDescription(); | 484 FontDescription d = itemFont.fontDescription(); |
| 476 d.setWeight(FontWeightBold); | 485 d.setWeight(FontWeightBold); |
| 477 Font font(d); | 486 Font font(d); |
| 478 font.update(nullptr); | 487 font.update(nullptr); |
| 479 return font; | 488 return font; |
| 480 } | 489 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 m_popupClient->selectionChanged(m_selectedIndex); | 570 m_popupClient->selectionChanged(m_selectedIndex); |
| 562 } else if (!isSelectable) | 571 } else if (!isSelectable) |
| 563 clearSelection(); | 572 clearSelection(); |
| 564 } | 573 } |
| 565 | 574 |
| 566 void PopupListBox::setOriginalIndex(int index) | 575 void PopupListBox::setOriginalIndex(int index) |
| 567 { | 576 { |
| 568 m_originalIndex = m_selectedIndex = index; | 577 m_originalIndex = m_selectedIndex = index; |
| 569 } | 578 } |
| 570 | 579 |
| 571 int PopupListBox::getRowHeight(int index) | 580 int PopupListBox::getRowHeight(int index) const |
| 572 { | 581 { |
| 573 int minimumHeight = m_deviceSupportsTouch ? optionRowHeightForTouch : minRow
Height; | 582 int minimumHeight = m_deviceSupportsTouch ? optionRowHeightForTouch : minRow
Height; |
| 574 | 583 |
| 575 if (index < 0 || m_popupClient->itemStyle(index).isDisplayNone()) | 584 if (index < 0 || m_popupClient->itemStyle(index).isDisplayNone()) |
| 576 return minimumHeight; | 585 return minimumHeight; |
| 577 | 586 |
| 578 // Separator row height is the same size as itself. | 587 // Separator row height is the same size as itself. |
| 579 if (m_popupClient->itemIsSeparator(index)) | 588 if (m_popupClient->itemIsSeparator(index)) |
| 580 return max(separatorHeight, minimumHeight); | 589 return max(separatorHeight, minimumHeight); |
| 581 | 590 |
| 582 int fontHeight = getRowFont(index).fontMetrics().height(); | 591 int fontHeight = getRowFont(index).fontMetrics().height(); |
| 583 return max(fontHeight, minimumHeight); | 592 return max(fontHeight, minimumHeight); |
| 584 } | 593 } |
| 585 | 594 |
| 586 IntRect PopupListBox::getRowBounds(int index) | 595 IntRect PopupListBox::getRowBounds(int index) |
| 587 { | 596 { |
| 588 if (index < 0) | 597 if (index < 0) |
| 589 return IntRect(0, 0, visibleWidth(), getRowHeight(index)); | 598 return IntRect(0, 0, visibleWidth(), getRowHeight(index)); |
| 590 | 599 |
| 591 return IntRect(0, m_items[index]->yOffset, visibleWidth(), getRowHeight(inde
x)); | 600 return IntRect(0, m_items[index]->yOffset, visibleWidth(), getRowHeight(inde
x)); |
| 592 } | 601 } |
| 593 | 602 |
| 594 void PopupListBox::invalidateRow(int index) | 603 void PopupListBox::invalidateRow(int index) |
| 595 { | 604 { |
| 596 if (index < 0) | 605 if (index < 0) |
| 597 return; | 606 return; |
| 598 | 607 |
| 599 // Invalidate in the window contents, as FramelessScrollView::invalidateRect | 608 // Invalidate in the window contents, as invalidateRect paints in the window
coordinates. |
| 600 // paints in the window coordinates. | |
| 601 IntRect clipRect = contentsToWindow(getRowBounds(index)); | 609 IntRect clipRect = contentsToWindow(getRowBounds(index)); |
| 602 if (shouldPlaceVerticalScrollbarOnLeft() && verticalScrollbar() && !vertical
Scrollbar()->isOverlayScrollbar()) | 610 if (shouldPlaceVerticalScrollbarOnLeft() && verticalScrollbar() && !vertical
Scrollbar()->isOverlayScrollbar()) |
| 603 clipRect.move(verticalScrollbar()->width(), 0); | 611 clipRect.move(verticalScrollbar()->width(), 0); |
| 604 invalidateRect(clipRect); | 612 invalidateRect(clipRect); |
| 605 } | 613 } |
| 606 | 614 |
| 607 void PopupListBox::scrollToRevealRow(int index) | 615 void PopupListBox::scrollToRevealRow(int index) |
| 608 { | 616 { |
| 609 if (index < 0) | 617 if (index < 0) |
| 610 return; | 618 return; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 // Select the new index, and ensure its visible. We do this regardless of | 684 // Select the new index, and ensure its visible. We do this regardless of |
| 677 // whether the selection changed to ensure keyboard events always bring the | 685 // whether the selection changed to ensure keyboard events always bring the |
| 678 // selection into view. | 686 // selection into view. |
| 679 selectIndex(targetIndex); | 687 selectIndex(targetIndex); |
| 680 scrollToRevealSelection(); | 688 scrollToRevealSelection(); |
| 681 } | 689 } |
| 682 | 690 |
| 683 void PopupListBox::hidePopup() | 691 void PopupListBox::hidePopup() |
| 684 { | 692 { |
| 685 if (parent()) { | 693 if (parent()) { |
| 686 PopupContainer* container = static_cast<PopupContainer*>(parent()); | 694 if (m_container->client()) |
| 687 if (container->client()) | 695 m_container->client()->popupClosed(m_container); |
| 688 container->client()->popupClosed(container); | 696 m_container->notifyPopupHidden(); |
| 689 container->notifyPopupHidden(); | |
| 690 } | 697 } |
| 691 | 698 |
| 692 if (m_popupClient) | 699 if (m_popupClient) |
| 693 m_popupClient->popupDidHide(); | 700 m_popupClient->popupDidHide(); |
| 694 } | 701 } |
| 695 | 702 |
| 696 void PopupListBox::updateFromElement() | 703 void PopupListBox::updateFromElement() |
| 697 { | 704 { |
| 698 clear(); | 705 clear(); |
| 699 | 706 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 bool PopupListBox::isPointInBounds(const IntPoint& point) | 834 bool PopupListBox::isPointInBounds(const IntPoint& point) |
| 828 { | 835 { |
| 829 return numItems() && IntRect(0, 0, width(), height()).contains(point); | 836 return numItems() && IntRect(0, 0, width(), height()).contains(point); |
| 830 } | 837 } |
| 831 | 838 |
| 832 int PopupListBox::popupContentHeight() const | 839 int PopupListBox::popupContentHeight() const |
| 833 { | 840 { |
| 834 return height(); | 841 return height(); |
| 835 } | 842 } |
| 836 | 843 |
| 844 void PopupListBox::invalidateRect(const IntRect& rect) |
| 845 { |
| 846 if (HostWindow* h = hostWindow()) |
| 847 h->invalidateContentsAndRootView(rect); |
| 848 } |
| 849 |
| 850 IntRect PopupListBox::windowClipRect(IncludeScrollbarsInRect scrollbarInclusion)
const |
| 851 { |
| 852 IntRect clipRect = visibleContentRect(scrollbarInclusion); |
| 853 if (shouldPlaceVerticalScrollbarOnLeft() && verticalScrollbar() && !vertical
Scrollbar()->isOverlayScrollbar()) |
| 854 clipRect.move(verticalScrollbar()->width(), 0); |
| 855 return contentsToWindow(clipRect); |
| 856 } |
| 857 |
| 858 void PopupListBox::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect&
rect) |
| 859 { |
| 860 // Add in our offset within the ScrollView. |
| 861 IntRect dirtyRect = rect; |
| 862 dirtyRect.move(scrollbar->x(), scrollbar->y()); |
| 863 invalidateRect(dirtyRect); |
| 864 } |
| 865 |
| 866 bool PopupListBox::isActive() const |
| 867 { |
| 868 // FIXME |
| 869 return true; |
| 870 } |
| 871 |
| 872 bool PopupListBox::scrollbarsCanBeActive() const |
| 873 { |
| 874 return isActive(); |
| 875 } |
| 876 |
| 877 IntRect PopupListBox::scrollableAreaBoundingBox() const |
| 878 { |
| 879 return windowClipRect(IncludeScrollbars); |
| 880 } |
| 881 |
| 837 } // namespace blink | 882 } // namespace blink |
| OLD | NEW |