| Index: Source/web/PopupContainer.cpp
|
| diff --git a/Source/web/PopupContainer.cpp b/Source/web/PopupContainer.cpp
|
| deleted file mode 100644
|
| index 7ed2a44d56ce6847702d06d02278e4fdec7491f8..0000000000000000000000000000000000000000
|
| --- a/Source/web/PopupContainer.cpp
|
| +++ /dev/null
|
| @@ -1,567 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2011, Google Inc. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions are
|
| - * met:
|
| - *
|
| - * * Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * * Redistributions in binary form must reproduce the above
|
| - * copyright notice, this list of conditions and the following disclaimer
|
| - * in the documentation and/or other materials provided with the
|
| - * distribution.
|
| - * * Neither the name of Google Inc. nor the names of its
|
| - * contributors may be used to endorse or promote products derived from
|
| - * this software without specific prior written permission.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "config.h"
|
| -#include "web/PopupContainer.h"
|
| -
|
| -#include "core/dom/Document.h"
|
| -#include "core/frame/FrameView.h"
|
| -#include "core/frame/LocalFrame.h"
|
| -#include "core/html/forms/PopupMenuClient.h"
|
| -#include "core/page/Chrome.h"
|
| -#include "core/page/ChromeClient.h"
|
| -#include "core/page/Page.h"
|
| -#include "platform/PlatformGestureEvent.h"
|
| -#include "platform/PlatformKeyboardEvent.h"
|
| -#include "platform/PlatformMouseEvent.h"
|
| -#include "platform/PlatformScreen.h"
|
| -#include "platform/PlatformTouchEvent.h"
|
| -#include "platform/PlatformWheelEvent.h"
|
| -#include "platform/UserGestureIndicator.h"
|
| -#include "platform/geometry/IntRect.h"
|
| -#include "platform/graphics/GraphicsContext.h"
|
| -#include "public/web/WebPopupMenuInfo.h"
|
| -#include "public/web/WebPopupType.h"
|
| -#include "public/web/WebViewClient.h"
|
| -#include "web/PopupContainerClient.h"
|
| -#include "web/WebPopupMenuImpl.h"
|
| -#include "web/WebViewImpl.h"
|
| -#include <algorithm>
|
| -#include <limits>
|
| -
|
| -namespace blink {
|
| -
|
| -static const int borderSize = 1;
|
| -
|
| -static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent& e, PopupContainer* parent, PopupListBox* child)
|
| -{
|
| - IntPoint pos = parent->convertSelfToChild(child, e.position());
|
| -
|
| - // FIXME: This is a horrible hack since PlatformMouseEvent has no setters for x/y.
|
| - PlatformMouseEvent relativeEvent = e;
|
| - IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.position());
|
| - relativePos.setX(pos.x());
|
| - relativePos.setY(pos.y());
|
| - return relativeEvent;
|
| -}
|
| -
|
| -static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent& e, PopupContainer* parent, PopupListBox* child)
|
| -{
|
| - IntPoint pos = parent->convertSelfToChild(child, e.position());
|
| -
|
| - // FIXME: This is a horrible hack since PlatformWheelEvent has no setters for x/y.
|
| - PlatformWheelEvent relativeEvent = e;
|
| - IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.position());
|
| - relativePos.setX(pos.x());
|
| - relativePos.setY(pos.y());
|
| - return relativeEvent;
|
| -}
|
| -
|
| -// static
|
| -PassRefPtrWillBeRawPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, bool deviceSupportsTouch)
|
| -{
|
| - return adoptRefWillBeNoop(new PopupContainer(client, deviceSupportsTouch));
|
| -}
|
| -
|
| -PopupContainer::PopupContainer(PopupMenuClient* client, bool deviceSupportsTouch)
|
| - : m_listBox(PopupListBox::create(client, deviceSupportsTouch, this))
|
| - , m_popupOpen(false)
|
| - , m_client(0)
|
| -{
|
| -}
|
| -
|
| -PopupContainer::~PopupContainer()
|
| -{
|
| -#if !ENABLE(OILPAN)
|
| - if (m_listBox->parent())
|
| - m_listBox->setParent(0);
|
| -#endif
|
| -}
|
| -
|
| -void PopupContainer::trace(Visitor* visitor)
|
| -{
|
| - visitor->trace(m_frameView);
|
| - visitor->trace(m_listBox);
|
| - Widget::trace(visitor);
|
| -}
|
| -
|
| -IntRect PopupContainer::layoutAndCalculateWidgetRectInternal(IntRect widgetRectInScreen, int targetControlHeight, const FloatRect& windowRect, const FloatRect& screen, bool isRTL, const int rtlOffset, const int verticalOffset, const IntSize& transformOffset, PopupContent* listBox, bool& needToResizeView)
|
| -{
|
| - ASSERT(listBox);
|
| - if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() && (widgetRectInScreen.x() < screen.x() || widgetRectInScreen.maxX() > screen.maxX())) {
|
| - // First, inverse the popup alignment if it does not fit the screen -
|
| - // this might fix things (or make them better).
|
| - IntRect inverseWidgetRectInScreen = widgetRectInScreen;
|
| - inverseWidgetRectInScreen.setX(inverseWidgetRectInScreen.x() + (isRTL ? -rtlOffset : rtlOffset));
|
| - inverseWidgetRectInScreen.setY(inverseWidgetRectInScreen.y() + (isRTL ? -verticalOffset : verticalOffset));
|
| - IntRect enclosingScreen = enclosingIntRect(screen);
|
| - unsigned originalCutoff = std::max(enclosingScreen.x() - widgetRectInScreen.x(), 0) + std::max(widgetRectInScreen.maxX() - enclosingScreen.maxX(), 0);
|
| - unsigned inverseCutoff = std::max(enclosingScreen.x() - inverseWidgetRectInScreen.x(), 0) + std::max(inverseWidgetRectInScreen.maxX() - enclosingScreen.maxX(), 0);
|
| -
|
| - // Accept the inverse popup alignment if the trimmed content gets
|
| - // shorter than that in the original alignment case.
|
| - if (inverseCutoff < originalCutoff)
|
| - widgetRectInScreen = inverseWidgetRectInScreen;
|
| -
|
| - if (widgetRectInScreen.x() < screen.x()) {
|
| - widgetRectInScreen.setWidth(widgetRectInScreen.maxX() - screen.x());
|
| - widgetRectInScreen.setX(screen.x());
|
| - listBox->setMaxWidthAndLayout(std::max(widgetRectInScreen.width() - borderSize * 2, 0));
|
| - } else if (widgetRectInScreen.maxX() > screen.maxX()) {
|
| - widgetRectInScreen.setWidth(screen.maxX() - widgetRectInScreen.x());
|
| - listBox->setMaxWidthAndLayout(std::max(widgetRectInScreen.width() - borderSize * 2, 0));
|
| - }
|
| - }
|
| -
|
| - // Calculate Y axis size.
|
| - if (widgetRectInScreen.maxY() > static_cast<int>(screen.maxY())) {
|
| - if (widgetRectInScreen.y() - widgetRectInScreen.height() - targetControlHeight - transformOffset.height() > 0) {
|
| - // There is enough room to open upwards.
|
| - widgetRectInScreen.move(-transformOffset.width(), -(widgetRectInScreen.height() + targetControlHeight + transformOffset.height()));
|
| - } else {
|
| - // Figure whether upwards or downwards has more room and set the
|
| - // maximum number of items.
|
| - int spaceAbove = widgetRectInScreen.y() - targetControlHeight + transformOffset.height();
|
| - int spaceBelow = screen.maxY() - widgetRectInScreen.y();
|
| - if (spaceAbove > spaceBelow)
|
| - listBox->setMaxHeight(spaceAbove);
|
| - else
|
| - listBox->setMaxHeight(spaceBelow);
|
| - listBox->layout();
|
| - needToResizeView = true;
|
| - widgetRectInScreen.setHeight(listBox->popupContentHeight() + borderSize * 2);
|
| - // Move WebWidget upwards if necessary.
|
| - if (spaceAbove > spaceBelow)
|
| - widgetRectInScreen.move(-transformOffset.width(), -(widgetRectInScreen.height() + targetControlHeight + transformOffset.height()));
|
| - }
|
| - }
|
| - return widgetRectInScreen;
|
| -}
|
| -
|
| -IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, const IntSize& transformOffset, const IntPoint& popupInitialCoordinate)
|
| -{
|
| - // Reset the max width and height to their default values, they will be
|
| - // recomputed below if necessary.
|
| - m_listBox->setMaxHeight(PopupListBox::defaultMaxHeight);
|
| - m_listBox->setMaxWidth(std::numeric_limits<int>::max());
|
| -
|
| - // Lay everything out to figure out our preferred size, then tell the view's
|
| - // WidgetClient about it. It should assign us a client.
|
| - m_listBox->layout();
|
| - fitToListBox();
|
| - bool isRTL = this->isRTL();
|
| -
|
| - // Compute the starting x-axis for a normal RTL or right-aligned LTR
|
| - // dropdown. For those, the right edge of dropdown box should be aligned
|
| - // with the right edge of <select>/<input> element box, and the dropdown box
|
| - // should be expanded to the left if more space is needed.
|
| - // m_originalFrameRect.width() is the width of the target <select>/<input>
|
| - // element.
|
| - int rtlOffset = m_controlPosition.p2().x() - m_controlPosition.p1().x() - (m_listBox->width() + borderSize * 2);
|
| - int rightOffset = isRTL ? rtlOffset : 0;
|
| -
|
| - // Compute the y-axis offset between the bottom left and bottom right
|
| - // points. If the <select>/<input> is transformed, they are not the same.
|
| - int verticalOffset = - m_controlPosition.p4().y() + m_controlPosition.p3().y();
|
| - int verticalForRTLOffset = isRTL ? verticalOffset : 0;
|
| -
|
| - // Assume m_listBox size is already calculated.
|
| - IntSize targetSize(m_listBox->width() + borderSize * 2, m_listBox->height() + borderSize * 2);
|
| -
|
| - IntRect widgetRectInScreen;
|
| - // If the popup would extend past the bottom of the screen, open upwards
|
| - // instead.
|
| - FloatRect screen = screenAvailableRect(m_frameView.get());
|
| - // Use popupInitialCoordinate.x() + rightOffset because RTL position
|
| - // needs to be considered.
|
| - float pageScaleFactor = m_frameView->frame().page()->pageScaleFactor();
|
| - int popupX = round((popupInitialCoordinate.x() + rightOffset) * pageScaleFactor);
|
| - int popupY = round((popupInitialCoordinate.y() + verticalForRTLOffset) * pageScaleFactor);
|
| - widgetRectInScreen = chromeClient().rootViewToScreen(IntRect(popupX, popupY, targetSize.width(), targetSize.height()));
|
| -
|
| - // If we have multiple screens and the browser rect is in one screen, we
|
| - // have to clip the window width to the screen width.
|
| - // When clipping, we also need to set a maximum width for the list box.
|
| - FloatRect windowRect = chromeClient().windowRect();
|
| -
|
| - bool needToResizeView = false;
|
| - widgetRectInScreen = layoutAndCalculateWidgetRectInternal(widgetRectInScreen, targetControlHeight, windowRect, screen, isRTL, rtlOffset, verticalOffset, transformOffset, m_listBox.get(), needToResizeView);
|
| - if (needToResizeView)
|
| - fitToListBox();
|
| -
|
| - return widgetRectInScreen;
|
| -}
|
| -
|
| -void PopupContainer::showPopup(FrameView* view)
|
| -{
|
| - m_frameView = view;
|
| - m_listBox->m_focusedElement = m_frameView->frame().document()->focusedElement();
|
| -
|
| - IntSize transformOffset(m_controlPosition.p4().x() - m_controlPosition.p1().x(), m_controlPosition.p4().y() - m_controlPosition.p1().y() - m_controlSize.height());
|
| - popupOpened(layoutAndCalculateWidgetRect(m_controlSize.height(), transformOffset, roundedIntPoint(m_controlPosition.p4())));
|
| - m_popupOpen = true;
|
| -
|
| - if (!m_listBox->parent())
|
| - m_listBox->setParent(this);
|
| -
|
| - m_listBox->scrollToRevealSelection();
|
| -
|
| - invalidate();
|
| -}
|
| -
|
| -void PopupContainer::hidePopup()
|
| -{
|
| - m_listBox->abandon();
|
| -}
|
| -
|
| -void PopupContainer::notifyPopupHidden()
|
| -{
|
| - if (!m_popupOpen)
|
| - return;
|
| - m_popupOpen = false;
|
| -
|
| - // With Oilpan, we cannot assume that the FrameView's LocalFrame's
|
| - // page is still available, as the LocalFrame itself may have been
|
| - // detached from its FrameHost by now.
|
| - //
|
| - // So, if a popup menu is left in an open/shown state when
|
| - // finalized, the PopupMenu implementation of this container's
|
| - // listbox will hide itself when destructed, delivering the
|
| - // notifyPopupHidden() notification in the process & ending up here.
|
| - // If the LocalFrame has been detached already -- done when its
|
| - // HTMLFrameOwnerElement frame owner is detached as part of being
|
| - // torn down -- the connection to the FrameHost has been snipped &
|
| - // there's no page. Hence the null check.
|
| - //
|
| - // In a non-Oilpan setting, the RenderMenuList that controls/owns
|
| - // the PopupMenuChromium object and this PopupContainer is torn
|
| - // down and destructed before the frame and frame owner, hence the
|
| - // page will always be available in that setting and this will
|
| - // not be an issue.
|
| - if (WebViewImpl* webView = WebViewImpl::fromPage(m_frameView->frame().page()))
|
| - webView->popupClosed(this);
|
| -}
|
| -
|
| -void PopupContainer::fitToListBox()
|
| -{
|
| - // Place the listbox within our border.
|
| - m_listBox->move(borderSize, borderSize);
|
| -
|
| - // Size ourselves to contain listbox + border.
|
| - resize(m_listBox->width() + borderSize * 2, m_listBox->height() + borderSize * 2);
|
| - invalidate();
|
| -}
|
| -
|
| -bool PopupContainer::handleMouseDownEvent(const PlatformMouseEvent& event)
|
| -{
|
| - UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
|
| - return m_listBox->handleMouseDownEvent(
|
| - constructRelativeMouseEvent(event, this, m_listBox.get()));
|
| -}
|
| -
|
| -bool PopupContainer::handleMouseMoveEvent(const PlatformMouseEvent& event)
|
| -{
|
| - UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
|
| - return m_listBox->handleMouseMoveEvent(
|
| - constructRelativeMouseEvent(event, this, m_listBox.get()));
|
| -}
|
| -
|
| -bool PopupContainer::handleMouseReleaseEvent(const PlatformMouseEvent& event)
|
| -{
|
| - RefPtrWillBeRawPtr<PopupContainer> protect(this);
|
| - UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
|
| - return m_listBox->handleMouseReleaseEvent(
|
| - constructRelativeMouseEvent(event, this, m_listBox.get()));
|
| -}
|
| -
|
| -bool PopupContainer::handleWheelEvent(const PlatformWheelEvent& event)
|
| -{
|
| - UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
|
| - return m_listBox->handleWheelEvent(
|
| - constructRelativeWheelEvent(event, this, m_listBox.get()));
|
| -}
|
| -
|
| -bool PopupContainer::handleTouchEvent(const PlatformTouchEvent&)
|
| -{
|
| - return false;
|
| -}
|
| -
|
| -// FIXME: Refactor this code to share functionality with
|
| -// EventHandler::handleGestureEvent.
|
| -bool PopupContainer::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
|
| -{
|
| - switch (gestureEvent.type()) {
|
| - case PlatformEvent::GestureTap: {
|
| - PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.globalPosition(), NoButton, PlatformEvent::MouseMoved, /* clickCount */ 1, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
|
| - PlatformMouseEvent fakeMouseDown(gestureEvent.position(), gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, /* clickCount */ 1, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
|
| - PlatformMouseEvent fakeMouseUp(gestureEvent.position(), gestureEvent.globalPosition(), LeftButton, PlatformEvent::MouseReleased, /* clickCount */ 1, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
|
| - // handleMouseMoveEvent(fakeMouseMove);
|
| - handleMouseDownEvent(fakeMouseDown);
|
| - handleMouseReleaseEvent(fakeMouseUp);
|
| - return true;
|
| - }
|
| - case PlatformEvent::GestureScrollUpdate: {
|
| - PlatformWheelEvent syntheticWheelEvent(gestureEvent.position(), gestureEvent.globalPosition(), gestureEvent.deltaX(), gestureEvent.deltaY(), gestureEvent.deltaX() / 120.0f, gestureEvent.deltaY() / 120.0f, ScrollByPixelWheelEvent, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
|
| - handleWheelEvent(syntheticWheelEvent);
|
| - return true;
|
| - }
|
| - case PlatformEvent::GestureScrollBegin:
|
| - case PlatformEvent::GestureScrollEnd:
|
| - case PlatformEvent::GestureTapDown:
|
| - case PlatformEvent::GestureShowPress:
|
| - break;
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool PopupContainer::handleKeyEvent(const PlatformKeyboardEvent& event)
|
| -{
|
| - UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
|
| - return m_listBox->handleKeyEvent(event);
|
| -}
|
| -
|
| -void PopupContainer::hide()
|
| -{
|
| - m_listBox->abandon();
|
| -}
|
| -
|
| -void PopupContainer::paint(GraphicsContext* gc, const IntRect& rect)
|
| -{
|
| - // Adjust coords for scrolled frame.
|
| - IntRect r = intersection(rect, frameRect());
|
| - int tx = x();
|
| - int ty = y();
|
| -
|
| - r.move(-tx, -ty);
|
| -
|
| - gc->translate(static_cast<float>(tx), static_cast<float>(ty));
|
| - m_listBox->paint(gc, r);
|
| - gc->translate(-static_cast<float>(tx), -static_cast<float>(ty));
|
| -
|
| - paintBorder(gc, rect);
|
| -}
|
| -
|
| -void PopupContainer::paintBorder(GraphicsContext* gc, const IntRect& rect)
|
| -{
|
| - // FIXME: Where do we get the border color from?
|
| - Color borderColor(127, 157, 185);
|
| -
|
| - gc->setStrokeStyle(NoStroke);
|
| - gc->setFillColor(borderColor);
|
| -
|
| - int tx = x();
|
| - int ty = y();
|
| -
|
| - // top, left, bottom, right
|
| - gc->drawRect(IntRect(tx, ty, width(), borderSize));
|
| - gc->drawRect(IntRect(tx, ty, borderSize, height()));
|
| - gc->drawRect(IntRect(tx, ty + height() - borderSize, width(), borderSize));
|
| - gc->drawRect(IntRect(tx + width() - borderSize, ty, borderSize, height()));
|
| -}
|
| -
|
| -bool PopupContainer::isInterestedInEventForKey(int keyCode)
|
| -{
|
| - return m_listBox->isInterestedInEventForKey(keyCode);
|
| -}
|
| -
|
| -ChromeClient& PopupContainer::chromeClient()
|
| -{
|
| - return m_frameView->frame().page()->chrome().client();
|
| -}
|
| -
|
| -void PopupContainer::showInRect(const FloatQuad& controlPosition, const IntSize& controlSize, FrameView* v, int index)
|
| -{
|
| - // The controlSize is the size of the select box. It's usually larger than
|
| - // we need. Subtract border size so that usually the container will be
|
| - // displayed exactly the same width as the select box.
|
| - m_listBox->setBaseWidth(std::max(controlSize.width() - borderSize * 2, 0));
|
| -
|
| - m_listBox->updateFromElement();
|
| -
|
| - // We set the selected item in updateFromElement(), and disregard the
|
| - // index passed into this function (same as Webkit's PopupMenuWin.cpp)
|
| - // FIXME: make sure this is correct, and add an assertion.
|
| - // ASSERT(popupWindow(popup)->listBox()->selectedIndex() == index);
|
| -
|
| - // Save and convert the controlPosition to main window coords. Each point is converted separately
|
| - // to window coordinates because the control could be in a transformed webview and then each point
|
| - // would be transformed by a different delta.
|
| - m_controlPosition.setP1(v->contentsToWindow(IntPoint(controlPosition.p1().x(), controlPosition.p1().y())));
|
| - m_controlPosition.setP2(v->contentsToWindow(IntPoint(controlPosition.p2().x(), controlPosition.p2().y())));
|
| - m_controlPosition.setP3(v->contentsToWindow(IntPoint(controlPosition.p3().x(), controlPosition.p3().y())));
|
| - m_controlPosition.setP4(v->contentsToWindow(IntPoint(controlPosition.p4().x(), controlPosition.p4().y())));
|
| -
|
| - m_controlSize = controlSize;
|
| -
|
| - // Position at (0, 0) since the frameRect().location() is relative to the
|
| - // parent WebWidget.
|
| - setFrameRect(IntRect(IntPoint(), controlSize));
|
| - showPopup(v);
|
| -}
|
| -
|
| -IntRect PopupContainer::refresh(const IntRect& targetControlRect)
|
| -{
|
| - m_listBox->setBaseWidth(std::max(m_controlSize.width() - borderSize * 2, 0));
|
| - m_listBox->updateFromElement();
|
| -
|
| - IntPoint locationInWindow = m_frameView->contentsToWindow(targetControlRect.location());
|
| -
|
| - // Move it below the select widget.
|
| - locationInWindow.move(0, targetControlRect.height());
|
| -
|
| - IntRect widgetRectInScreen = layoutAndCalculateWidgetRect(targetControlRect.height(), IntSize(), locationInWindow);
|
| -
|
| - // Reset the size (which can be set to the PopupListBox size in
|
| - // layoutAndGetRTLOffset(), exceeding the available widget rectangle.)
|
| - if (size() != widgetRectInScreen.size())
|
| - resize(widgetRectInScreen.size());
|
| -
|
| - invalidate();
|
| -
|
| - return widgetRectInScreen;
|
| -}
|
| -
|
| -inline bool PopupContainer::isRTL() const
|
| -{
|
| - return m_listBox->m_popupClient->menuStyle().textDirection() == RTL;
|
| -}
|
| -
|
| -int PopupContainer::selectedIndex() const
|
| -{
|
| - return m_listBox->selectedIndex();
|
| -}
|
| -
|
| -int PopupContainer::menuItemHeight() const
|
| -{
|
| - return m_listBox->getRowHeight(0);
|
| -}
|
| -
|
| -int PopupContainer::menuItemFontSize() const
|
| -{
|
| - return m_listBox->getRowFont(0).fontDescription().computedSize();
|
| -}
|
| -
|
| -PopupMenuStyle PopupContainer::menuStyle() const
|
| -{
|
| - return m_listBox->m_popupClient->menuStyle();
|
| -}
|
| -
|
| -const WTF::Vector<PopupItem*>& PopupContainer:: popupData() const
|
| -{
|
| - return m_listBox->items();
|
| -}
|
| -
|
| -String PopupContainer::getSelectedItemToolTip()
|
| -{
|
| - // We cannot use m_popupClient->selectedIndex() to choose tooltip message,
|
| - // because the selectedIndex() might return final selected index, not
|
| - // hovering selection.
|
| - return m_listBox->m_popupClient->itemToolTip(m_listBox->m_selectedIndex);
|
| -}
|
| -
|
| -void PopupContainer::popupOpened(const IntRect& bounds)
|
| -{
|
| - WebViewImpl* webView = WebViewImpl::fromPage(m_frameView->frame().page());
|
| - if (!webView->client())
|
| - return;
|
| -
|
| - WebWidget* webwidget = webView->client()->createPopupMenu(WebPopupTypeSelect);
|
| - if (!webwidget)
|
| - return;
|
| - // We only notify when the WebView has to handle the popup, as when
|
| - // the popup is handled externally, the fact that a popup is showing is
|
| - // transparent to the WebView.
|
| - webView->popupOpened(this);
|
| - toWebPopupMenuImpl(webwidget)->initialize(this, bounds);
|
| -}
|
| -
|
| -void PopupContainer::getPopupMenuInfo(WebPopupMenuInfo* info)
|
| -{
|
| - const Vector<PopupItem*>& inputItems = popupData();
|
| -
|
| - WebVector<WebMenuItemInfo> outputItems(inputItems.size());
|
| -
|
| - for (size_t i = 0; i < inputItems.size(); ++i) {
|
| - const PopupItem& inputItem = *inputItems[i];
|
| - WebMenuItemInfo& outputItem = outputItems[i];
|
| -
|
| - outputItem.label = inputItem.label;
|
| - outputItem.enabled = inputItem.enabled;
|
| - outputItem.textDirection = toWebTextDirection(inputItem.textDirection);
|
| - outputItem.hasTextDirectionOverride = inputItem.hasTextDirectionOverride;
|
| -
|
| - switch (inputItem.type) {
|
| - case PopupItem::TypeOption:
|
| - outputItem.type = WebMenuItemInfo::Option;
|
| - break;
|
| - case PopupItem::TypeGroup:
|
| - outputItem.type = WebMenuItemInfo::Group;
|
| - break;
|
| - case PopupItem::TypeSeparator:
|
| - outputItem.type = WebMenuItemInfo::Separator;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - info->itemHeight = menuItemHeight();
|
| - info->itemFontSize = menuItemFontSize();
|
| - info->selectedIndex = selectedIndex();
|
| - info->items.swap(outputItems);
|
| - info->rightAligned = menuStyle().textDirection() == RTL;
|
| -}
|
| -
|
| -void PopupContainer::invalidateRect(const IntRect& rect)
|
| -{
|
| - if (HostWindow* h = hostWindow())
|
| - h->invalidateContentsAndRootView(rect);
|
| -}
|
| -
|
| -HostWindow* PopupContainer::hostWindow() const
|
| -{
|
| - return const_cast<PopupContainerClient*>(m_client);
|
| -}
|
| -
|
| -IntPoint PopupContainer::convertChildToSelf(const Widget* child, const IntPoint& point) const
|
| -{
|
| - IntPoint newPoint = point;
|
| - newPoint.moveBy(child->location());
|
| - return newPoint;
|
| -}
|
| -
|
| -IntPoint PopupContainer::convertSelfToChild(const Widget* child, const IntPoint& point) const
|
| -{
|
| - IntPoint newPoint = point;
|
| - newPoint.moveBy(-child->location());
|
| - return newPoint;
|
| -}
|
| -
|
| -} // namespace blink
|
|
|