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 |