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/PlatformGestureEvent.h" | 40 #include "platform/PlatformGestureEvent.h" |
41 #include "platform/PlatformKeyboardEvent.h" | 41 #include "platform/PlatformKeyboardEvent.h" |
42 #include "platform/PlatformMouseEvent.h" | 42 #include "platform/PlatformMouseEvent.h" |
43 #include "platform/PlatformScreen.h" | 43 #include "platform/PlatformScreen.h" |
44 #include "platform/PlatformTouchEvent.h" | 44 #include "platform/PlatformTouchEvent.h" |
45 #include "platform/PlatformWheelEvent.h" | 45 #include "platform/PlatformWheelEvent.h" |
46 #include "platform/PopupMenuClient.h" | 46 #include "platform/PopupMenuClient.h" |
47 #include "platform/UserGestureIndicator.h" | 47 #include "platform/UserGestureIndicator.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 "public/web/WebPopupMenuInfo.h" | 50 #include "public/web/WebPopupMenuInfo.h" |
52 #include "public/web/WebPopupType.h" | 51 #include "public/web/WebPopupType.h" |
53 #include "public/web/WebViewClient.h" | 52 #include "public/web/WebViewClient.h" |
| 53 #include "web/PopupContainerClient.h" |
54 #include "web/WebPopupMenuImpl.h" | 54 #include "web/WebPopupMenuImpl.h" |
55 #include "web/WebViewImpl.h" | 55 #include "web/WebViewImpl.h" |
56 #include <limits> | 56 #include <limits> |
57 | 57 |
58 namespace blink { | 58 namespace blink { |
59 | 59 |
60 static const int borderSize = 1; | 60 static const int borderSize = 1; |
61 | 61 |
62 static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent&
e, FramelessScrollView* parent, FramelessScrollView* child) | 62 static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent&
e, PopupContainer* parent, PopupListBox* child) |
63 { | 63 { |
64 IntPoint pos = parent->convertSelfToChild(child, e.position()); | 64 IntPoint pos = parent->convertSelfToChild(child, e.position()); |
65 | 65 |
66 // FIXME: This is a horrible hack since PlatformMouseEvent has no setters fo
r x/y. | 66 // FIXME: This is a horrible hack since PlatformMouseEvent has no setters fo
r x/y. |
67 PlatformMouseEvent relativeEvent = e; | 67 PlatformMouseEvent relativeEvent = e; |
68 IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.position()); | 68 IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.position()); |
69 relativePos.setX(pos.x()); | 69 relativePos.setX(pos.x()); |
70 relativePos.setY(pos.y()); | 70 relativePos.setY(pos.y()); |
71 return relativeEvent; | 71 return relativeEvent; |
72 } | 72 } |
73 | 73 |
74 static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent&
e, FramelessScrollView* parent, FramelessScrollView* child) | 74 static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent&
e, PopupContainer* parent, PopupListBox* child) |
75 { | 75 { |
76 IntPoint pos = parent->convertSelfToChild(child, e.position()); | 76 IntPoint pos = parent->convertSelfToChild(child, e.position()); |
77 | 77 |
78 // FIXME: This is a horrible hack since PlatformWheelEvent has no setters fo
r x/y. | 78 // FIXME: This is a horrible hack since PlatformWheelEvent has no setters fo
r x/y. |
79 PlatformWheelEvent relativeEvent = e; | 79 PlatformWheelEvent relativeEvent = e; |
80 IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.position()); | 80 IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.position()); |
81 relativePos.setX(pos.x()); | 81 relativePos.setX(pos.x()); |
82 relativePos.setY(pos.y()); | 82 relativePos.setY(pos.y()); |
83 return relativeEvent; | 83 return relativeEvent; |
84 } | 84 } |
85 | 85 |
86 // static | 86 // static |
87 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, bool
deviceSupportsTouch) | 87 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, bool
deviceSupportsTouch) |
88 { | 88 { |
89 return adoptRef(new PopupContainer(client, deviceSupportsTouch)); | 89 return adoptRef(new PopupContainer(client, deviceSupportsTouch)); |
90 } | 90 } |
91 | 91 |
92 PopupContainer::PopupContainer(PopupMenuClient* client, bool deviceSupportsTouch
) | 92 PopupContainer::PopupContainer(PopupMenuClient* client, bool deviceSupportsTouch
) |
93 : m_listBox(PopupListBox::create(client, deviceSupportsTouch)) | 93 : m_listBox(PopupListBox::create(client, deviceSupportsTouch, this)) |
94 , m_popupOpen(false) | 94 , m_popupOpen(false) |
| 95 , m_client(0) |
95 { | 96 { |
96 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); | |
97 } | 97 } |
98 | 98 |
99 PopupContainer::~PopupContainer() | 99 PopupContainer::~PopupContainer() |
100 { | 100 { |
101 if (m_listBox && m_listBox->parent()) | 101 if (m_listBox->parent()) |
102 removeChild(m_listBox.get()); | 102 m_listBox->setParent(0); |
103 } | 103 } |
104 | 104 |
105 IntRect PopupContainer::layoutAndCalculateWidgetRectInternal(IntRect widgetRectI
nScreen, int targetControlHeight, const FloatRect& windowRect, const FloatRect&
screen, bool isRTL, const int rtlOffset, const int verticalOffset, const IntSize
& transformOffset, PopupContent* listBox, bool& needToResizeView) | 105 IntRect PopupContainer::layoutAndCalculateWidgetRectInternal(IntRect widgetRectI
nScreen, int targetControlHeight, const FloatRect& windowRect, const FloatRect&
screen, bool isRTL, const int rtlOffset, const int verticalOffset, const IntSize
& transformOffset, PopupContent* listBox, bool& needToResizeView) |
106 { | 106 { |
107 ASSERT(listBox); | 107 ASSERT(listBox); |
108 if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() && (w
idgetRectInScreen.x() < screen.x() || widgetRectInScreen.maxX() > screen.maxX())
) { | 108 if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() && (w
idgetRectInScreen.x() < screen.x() || widgetRectInScreen.maxX() > screen.maxX())
) { |
109 // First, inverse the popup alignment if it does not fit the screen - | 109 // First, inverse the popup alignment if it does not fit the screen - |
110 // this might fix things (or make them better). | 110 // this might fix things (or make them better). |
111 IntRect inverseWidgetRectInScreen = widgetRectInScreen; | 111 IntRect inverseWidgetRectInScreen = widgetRectInScreen; |
112 inverseWidgetRectInScreen.setX(inverseWidgetRectInScreen.x() + (isRTL ?
-rtlOffset : rtlOffset)); | 112 inverseWidgetRectInScreen.setX(inverseWidgetRectInScreen.x() + (isRTL ?
-rtlOffset : rtlOffset)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 widgetRectInScreen = layoutAndCalculateWidgetRectInternal(widgetRectInScreen
, targetControlHeight, windowRect, screen, isRTL, rtlOffset, verticalOffset, tra
nsformOffset, m_listBox.get(), needToResizeView); | 205 widgetRectInScreen = layoutAndCalculateWidgetRectInternal(widgetRectInScreen
, targetControlHeight, windowRect, screen, isRTL, rtlOffset, verticalOffset, tra
nsformOffset, m_listBox.get(), needToResizeView); |
206 if (needToResizeView) | 206 if (needToResizeView) |
207 fitToListBox(); | 207 fitToListBox(); |
208 | 208 |
209 return widgetRectInScreen; | 209 return widgetRectInScreen; |
210 } | 210 } |
211 | 211 |
212 void PopupContainer::showPopup(FrameView* view) | 212 void PopupContainer::showPopup(FrameView* view) |
213 { | 213 { |
214 m_frameView = view; | 214 m_frameView = view; |
215 listBox()->m_focusedElement = m_frameView->frame().document()->focusedElemen
t(); | 215 m_listBox->m_focusedElement = m_frameView->frame().document()->focusedElemen
t(); |
216 | 216 |
217 IntSize transformOffset(m_controlPosition.p4().x() - m_controlPosition.p1().
x(), m_controlPosition.p4().y() - m_controlPosition.p1().y() - m_controlSize.hei
ght()); | 217 IntSize transformOffset(m_controlPosition.p4().x() - m_controlPosition.p1().
x(), m_controlPosition.p4().y() - m_controlPosition.p1().y() - m_controlSize.hei
ght()); |
218 popupOpened(layoutAndCalculateWidgetRect(m_controlSize.height(), transformOf
fset, roundedIntPoint(m_controlPosition.p4()))); | 218 popupOpened(layoutAndCalculateWidgetRect(m_controlSize.height(), transformOf
fset, roundedIntPoint(m_controlPosition.p4()))); |
219 m_popupOpen = true; | 219 m_popupOpen = true; |
220 | 220 |
221 if (!m_listBox->parent()) | 221 if (!m_listBox->parent()) |
222 addChild(m_listBox.get()); | 222 m_listBox->setParent(this); |
223 | 223 |
224 // Enable scrollbars after the listbox is inserted into the hierarchy, | 224 // Enable scrollbars after the listbox is inserted into the hierarchy, |
225 // so it has a proper WidgetClient. | 225 // so it has a proper WidgetClient. |
226 m_listBox->setVerticalScrollbarMode(ScrollbarAuto); | 226 m_listBox->setVerticalScrollbarMode(ScrollbarAuto); |
227 | 227 |
228 m_listBox->scrollToRevealSelection(); | 228 m_listBox->scrollToRevealSelection(); |
229 | 229 |
230 invalidate(); | 230 invalidate(); |
231 } | 231 } |
232 | 232 |
233 void PopupContainer::hidePopup() | 233 void PopupContainer::hidePopup() |
234 { | 234 { |
235 listBox()->abandon(); | 235 m_listBox->abandon(); |
236 } | 236 } |
237 | 237 |
238 void PopupContainer::notifyPopupHidden() | 238 void PopupContainer::notifyPopupHidden() |
239 { | 239 { |
240 if (!m_popupOpen) | 240 if (!m_popupOpen) |
241 return; | 241 return; |
242 m_popupOpen = false; | 242 m_popupOpen = false; |
243 WebViewImpl::fromPage(m_frameView->frame().page())->popupClosed(this); | 243 WebViewImpl::fromPage(m_frameView->frame().page())->popupClosed(this); |
244 } | 244 } |
245 | 245 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 ChromeClient& PopupContainer::chromeClient() | 371 ChromeClient& PopupContainer::chromeClient() |
372 { | 372 { |
373 return m_frameView->frame().page()->chrome().client(); | 373 return m_frameView->frame().page()->chrome().client(); |
374 } | 374 } |
375 | 375 |
376 void PopupContainer::showInRect(const FloatQuad& controlPosition, const IntSize&
controlSize, FrameView* v, int index) | 376 void PopupContainer::showInRect(const FloatQuad& controlPosition, const IntSize&
controlSize, FrameView* v, int index) |
377 { | 377 { |
378 // The controlSize is the size of the select box. It's usually larger than | 378 // The controlSize is the size of the select box. It's usually larger than |
379 // we need. Subtract border size so that usually the container will be | 379 // we need. Subtract border size so that usually the container will be |
380 // displayed exactly the same width as the select box. | 380 // displayed exactly the same width as the select box. |
381 listBox()->setBaseWidth(max(controlSize.width() - borderSize * 2, 0)); | 381 m_listBox->setBaseWidth(max(controlSize.width() - borderSize * 2, 0)); |
382 | 382 |
383 listBox()->updateFromElement(); | 383 m_listBox->updateFromElement(); |
384 | 384 |
385 // We set the selected item in updateFromElement(), and disregard the | 385 // We set the selected item in updateFromElement(), and disregard the |
386 // index passed into this function (same as Webkit's PopupMenuWin.cpp) | 386 // index passed into this function (same as Webkit's PopupMenuWin.cpp) |
387 // FIXME: make sure this is correct, and add an assertion. | 387 // FIXME: make sure this is correct, and add an assertion. |
388 // ASSERT(popupWindow(popup)->listBox()->selectedIndex() == index); | 388 // ASSERT(popupWindow(popup)->listBox()->selectedIndex() == index); |
389 | 389 |
390 // Save and convert the controlPosition to main window coords. Each point is
converted separately | 390 // Save and convert the controlPosition to main window coords. Each point is
converted separately |
391 // to window coordinates because the control could be in a transformed webvi
ew and then each point | 391 // to window coordinates because the control could be in a transformed webvi
ew and then each point |
392 // would be transformed by a different delta. | 392 // would be transformed by a different delta. |
393 m_controlPosition.setP1(v->contentsToWindow(IntPoint(controlPosition.p1().x(
), controlPosition.p1().y()))); | 393 m_controlPosition.setP1(v->contentsToWindow(IntPoint(controlPosition.p1().x(
), controlPosition.p1().y()))); |
394 m_controlPosition.setP2(v->contentsToWindow(IntPoint(controlPosition.p2().x(
), controlPosition.p2().y()))); | 394 m_controlPosition.setP2(v->contentsToWindow(IntPoint(controlPosition.p2().x(
), controlPosition.p2().y()))); |
395 m_controlPosition.setP3(v->contentsToWindow(IntPoint(controlPosition.p3().x(
), controlPosition.p3().y()))); | 395 m_controlPosition.setP3(v->contentsToWindow(IntPoint(controlPosition.p3().x(
), controlPosition.p3().y()))); |
396 m_controlPosition.setP4(v->contentsToWindow(IntPoint(controlPosition.p4().x(
), controlPosition.p4().y()))); | 396 m_controlPosition.setP4(v->contentsToWindow(IntPoint(controlPosition.p4().x(
), controlPosition.p4().y()))); |
397 | 397 |
398 m_controlSize = controlSize; | 398 m_controlSize = controlSize; |
399 | 399 |
400 // Position at (0, 0) since the frameRect().location() is relative to the | 400 // Position at (0, 0) since the frameRect().location() is relative to the |
401 // parent WebWidget. | 401 // parent WebWidget. |
402 setFrameRect(IntRect(IntPoint(), controlSize)); | 402 setFrameRect(IntRect(IntPoint(), controlSize)); |
403 showPopup(v); | 403 showPopup(v); |
404 } | 404 } |
405 | 405 |
406 IntRect PopupContainer::refresh(const IntRect& targetControlRect) | 406 IntRect PopupContainer::refresh(const IntRect& targetControlRect) |
407 { | 407 { |
408 listBox()->setBaseWidth(max(m_controlSize.width() - borderSize * 2, 0)); | 408 m_listBox->setBaseWidth(max(m_controlSize.width() - borderSize * 2, 0)); |
409 listBox()->updateFromElement(); | 409 m_listBox->updateFromElement(); |
410 | 410 |
411 IntPoint locationInWindow = m_frameView->contentsToWindow(targetControlRect.
location()); | 411 IntPoint locationInWindow = m_frameView->contentsToWindow(targetControlRect.
location()); |
412 | 412 |
413 // Move it below the select widget. | 413 // Move it below the select widget. |
414 locationInWindow.move(0, targetControlRect.height()); | 414 locationInWindow.move(0, targetControlRect.height()); |
415 | 415 |
416 IntRect widgetRectInScreen = layoutAndCalculateWidgetRect(targetControlRect.
height(), IntSize(), locationInWindow); | 416 IntRect widgetRectInScreen = layoutAndCalculateWidgetRect(targetControlRect.
height(), IntSize(), locationInWindow); |
417 | 417 |
418 // Reset the size (which can be set to the PopupListBox size in | 418 // Reset the size (which can be set to the PopupListBox size in |
419 // layoutAndGetRTLOffset(), exceeding the available widget rectangle.) | 419 // layoutAndGetRTLOffset(), exceeding the available widget rectangle.) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 const WTF::Vector<PopupItem*>& PopupContainer:: popupData() const | 453 const WTF::Vector<PopupItem*>& PopupContainer:: popupData() const |
454 { | 454 { |
455 return m_listBox->items(); | 455 return m_listBox->items(); |
456 } | 456 } |
457 | 457 |
458 String PopupContainer::getSelectedItemToolTip() | 458 String PopupContainer::getSelectedItemToolTip() |
459 { | 459 { |
460 // We cannot use m_popupClient->selectedIndex() to choose tooltip message, | 460 // We cannot use m_popupClient->selectedIndex() to choose tooltip message, |
461 // because the selectedIndex() might return final selected index, not | 461 // because the selectedIndex() might return final selected index, not |
462 // hovering selection. | 462 // hovering selection. |
463 return listBox()->m_popupClient->itemToolTip(listBox()->m_selectedIndex); | 463 return m_listBox->m_popupClient->itemToolTip(m_listBox->m_selectedIndex); |
464 } | 464 } |
465 | 465 |
466 void PopupContainer::popupOpened(const IntRect& bounds) | 466 void PopupContainer::popupOpened(const IntRect& bounds) |
467 { | 467 { |
468 WebViewImpl* webView = WebViewImpl::fromPage(m_frameView->frame().page()); | 468 WebViewImpl* webView = WebViewImpl::fromPage(m_frameView->frame().page()); |
469 if (!webView->client()) | 469 if (!webView->client()) |
470 return; | 470 return; |
471 | 471 |
472 WebWidget* webwidget = webView->client()->createPopupMenu(WebPopupTypeSelect
); | 472 WebWidget* webwidget = webView->client()->createPopupMenu(WebPopupTypeSelect
); |
473 if (!webwidget) | 473 if (!webwidget) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 507 } |
508 } | 508 } |
509 | 509 |
510 info->itemHeight = menuItemHeight(); | 510 info->itemHeight = menuItemHeight(); |
511 info->itemFontSize = menuItemFontSize(); | 511 info->itemFontSize = menuItemFontSize(); |
512 info->selectedIndex = selectedIndex(); | 512 info->selectedIndex = selectedIndex(); |
513 info->items.swap(outputItems); | 513 info->items.swap(outputItems); |
514 info->rightAligned = menuStyle().textDirection() == RTL; | 514 info->rightAligned = menuStyle().textDirection() == RTL; |
515 } | 515 } |
516 | 516 |
| 517 void PopupContainer::invalidateRect(const IntRect& rect) |
| 518 { |
| 519 if (HostWindow* h = hostWindow()) |
| 520 h->invalidateContentsAndRootView(rect); |
| 521 } |
| 522 |
| 523 HostWindow* PopupContainer::hostWindow() const |
| 524 { |
| 525 return const_cast<PopupContainerClient*>(m_client); |
| 526 } |
| 527 |
517 } // namespace blink | 528 } // namespace blink |
OLD | NEW |