Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: Source/WebCore/platform/chromium/PopupContainer.cpp

Issue 10267006: Merge 113418 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1084/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/WebCore/platform/chromium/PopupContainer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 // Lay everything out to figure out our preferred size, then tell the view's 127 // Lay everything out to figure out our preferred size, then tell the view's
128 // WidgetClient about it. It should assign us a client. 128 // WidgetClient about it. It should assign us a client.
129 int rtlOffset = layoutAndGetRTLOffset(); 129 int rtlOffset = layoutAndGetRTLOffset();
130 bool isRTL = this->isRTL(); 130 bool isRTL = this->isRTL();
131 int rightOffset = isRTL ? rtlOffset : 0; 131 int rightOffset = isRTL ? rtlOffset : 0;
132 132
133 // Assume m_listBox size is already calculated. 133 // Assume m_listBox size is already calculated.
134 IntSize targetSize(m_listBox->width() + kBorderSize * 2, 134 IntSize targetSize(m_listBox->width() + kBorderSize * 2,
135 m_listBox->height() + kBorderSize * 2); 135 m_listBox->height() + kBorderSize * 2);
136 136
137 IntRect widgetRect; 137 IntRect widgetRectInScreen;
138 ChromeClientChromium* chromeClient = chromeClientChromium(); 138 ChromeClientChromium* chromeClient = chromeClientChromium();
139 if (chromeClient) { 139 if (chromeClient) {
140 // If the popup would extend past the bottom of the screen, open upwards 140 // If the popup would extend past the bottom of the screen, open upwards
141 // instead. 141 // instead.
142 FloatRect screen = screenAvailableRect(m_frameView.get()); 142 FloatRect screen = screenAvailableRect(m_frameView.get());
143 // Use popupInitialCoordinate.x() + rightOffset because RTL position 143 // Use popupInitialCoordinate.x() + rightOffset because RTL position
144 // needs to be considered. 144 // needs to be considered.
145 widgetRect = chromeClient->rootViewToScreen(IntRect(popupInitialCoordina te.x() + rightOffset, popupInitialCoordinate.y(), targetSize.width(), targetSize .height())); 145 widgetRectInScreen = chromeClient->rootViewToScreen(IntRect(popupInitial Coordinate.x() + rightOffset, popupInitialCoordinate.y(), targetSize.width(), ta rgetSize.height()));
146 146
147 // If we have multiple screens and the browser rect is in one screen, we have 147 // If we have multiple screens and the browser rect is in one screen, we have
148 // to clip the window width to the screen width. 148 // to clip the window width to the screen width.
149 // When clipping, we also need to set a maximum width for the list box. 149 // When clipping, we also need to set a maximum width for the list box.
150 FloatRect windowRect = chromeClient->windowRect(); 150 FloatRect windowRect = chromeClient->windowRect();
151 if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() & & (widgetRect.x() < screen.x() || widgetRect.maxX() > screen.maxX())) { 151 if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() & & (widgetRectInScreen.x() < screen.x() || widgetRectInScreen.maxX() > screen.max X())) {
152 // First, inverse the popup alignment if it does not fit the screen - this might fix things (or make them better). 152 // First, inverse the popup alignment if it does not fit the screen - this might fix things (or make them better).
153 IntRect inverseWidgetRect = chromeClient->rootViewToScreen(IntRect(p opupInitialCoordinate.x() + (isRTL ? 0 : rtlOffset), popupInitialCoordinate.y(), targetSize.width(), targetSize.height())); 153 IntRect inverseWidgetRectInScreen = chromeClient->rootViewToScreen(I ntRect(popupInitialCoordinate.x() + (isRTL ? 0 : rtlOffset), popupInitialCoordin ate.y(), targetSize.width(), targetSize.height()));
154 IntRect enclosingScreen = enclosingIntRect(screen); 154 IntRect enclosingScreen = enclosingIntRect(screen);
155 unsigned originalCutoff = max(enclosingScreen.x() - widgetRect.x(), 0) + max(widgetRect.maxX() - enclosingScreen.maxX(), 0); 155 unsigned originalCutoff = max(enclosingScreen.x() - widgetRectInScre en.x(), 0) + max(widgetRectInScreen.maxX() - enclosingScreen.maxX(), 0);
156 unsigned inverseCutoff = max(enclosingScreen.x() - inverseWidgetRect .x(), 0) + max(inverseWidgetRect.maxX() - enclosingScreen.maxX(), 0); 156 unsigned inverseCutoff = max(enclosingScreen.x() - inverseWidgetRect InScreen.x(), 0) + max(inverseWidgetRectInScreen.maxX() - enclosingScreen.maxX() , 0);
157 157
158 // Accept the inverse popup alignment if the trimmed content gets sh orter than that in the original alignment case. 158 // Accept the inverse popup alignment if the trimmed content gets sh orter than that in the original alignment case.
159 if (inverseCutoff < originalCutoff) 159 if (inverseCutoff < originalCutoff)
160 widgetRect = inverseWidgetRect; 160 widgetRectInScreen = inverseWidgetRectInScreen;
161 161
162 if (widgetRect.x() < screen.x()) { 162 if (widgetRectInScreen.x() < screen.x()) {
163 unsigned widgetRight = widgetRect.maxX(); 163 unsigned widgetRight = widgetRectInScreen.maxX();
164 widgetRect.setWidth(widgetRect.maxX() - screen.x()); 164 widgetRectInScreen.setWidth(widgetRectInScreen.maxX() - screen.x ());
165 widgetRect.setX(widgetRight - widgetRect.width()); 165 widgetRectInScreen.setX(widgetRight - widgetRectInScreen.width() );
166 listBox()->setMaxWidthAndLayout(max(widgetRect.width() - kBorder Size * 2, 0)); 166 listBox()->setMaxWidthAndLayout(max(widgetRectInScreen.width() - kBorderSize * 2, 0));
167 } else if (widgetRect.maxX() > screen.maxX()) { 167 } else if (widgetRectInScreen.maxX() > screen.maxX()) {
168 widgetRect.setWidth(screen.maxX() - widgetRect.x()); 168 widgetRectInScreen.setWidth(screen.maxX() - widgetRectInScreen.x ());
169 listBox()->setMaxWidthAndLayout(max(widgetRect.width() - kBorder Size * 2, 0)); 169 listBox()->setMaxWidthAndLayout(max(widgetRectInScreen.width() - kBorderSize * 2, 0));
170 } 170 }
171 } 171 }
172 172
173 // Calculate Y axis size. 173 // Calculate Y axis size.
174 if (widgetRect.maxY() > static_cast<int>(screen.maxY())) { 174 if (widgetRectInScreen.maxY() > static_cast<int>(screen.maxY())) {
175 if (widgetRect.y() - widgetRect.height() - targetControlHeight > 0) { 175 if (widgetRectInScreen.y() - widgetRectInScreen.height() - targetCon trolHeight > 0) {
176 // There is enough room to open upwards. 176 // There is enough room to open upwards.
177 widgetRect.move(0, -(widgetRect.height() + targetControlHeight)) ; 177 widgetRectInScreen.move(0, -(widgetRectInScreen.height() + targe tControlHeight));
178 } else { 178 } else {
179 // Figure whether upwards or downwards has more room and set the 179 // Figure whether upwards or downwards has more room and set the
180 // maximum number of items. 180 // maximum number of items.
181 int spaceAbove = widgetRect.y() - targetControlHeight; 181 int spaceAbove = widgetRectInScreen.y() - targetControlHeight;
182 int spaceBelow = screen.maxY() - widgetRect.y(); 182 int spaceBelow = screen.maxY() - widgetRectInScreen.y();
183 if (spaceAbove > spaceBelow) 183 if (spaceAbove > spaceBelow)
184 m_listBox->setMaxHeight(spaceAbove); 184 m_listBox->setMaxHeight(spaceAbove);
185 else 185 else
186 m_listBox->setMaxHeight(spaceBelow); 186 m_listBox->setMaxHeight(spaceBelow);
187 layoutAndGetRTLOffset(); 187 layoutAndGetRTLOffset();
188 // Our height has changed, so recompute only Y axis of widgetRec t. 188 // Our height has changed, so recompute only Y axis of widgetRec t.
189 // We don't have to recompute X axis, so we only replace Y axis 189 // We don't have to recompute X axis, so we only replace Y axis
190 // in widgetRect. 190 // in widgetRect.
191 IntRect frameInScreen = chromeClient->rootViewToScreen(frameRect ()); 191 IntRect frameInScreen = chromeClient->rootViewToScreen(frameRect ());
192 widgetRect.setY(frameInScreen.y()); 192 widgetRectInScreen.setY(frameInScreen.y());
193 widgetRect.setHeight(frameInScreen.height()); 193 widgetRectInScreen.setHeight(frameInScreen.height());
194 // And move upwards if necessary. 194 // And move upwards if necessary.
195 if (spaceAbove > spaceBelow) 195 if (spaceAbove > spaceBelow)
196 widgetRect.move(0, -(widgetRect.height() + targetControlHeig ht)); 196 widgetRectInScreen.move(0, -(widgetRectInScreen.height() + t argetControlHeight));
197 } 197 }
198 } 198 }
199 } 199 }
200 return widgetRect; 200
201 return widgetRectInScreen;
201 } 202 }
202 203
203 void PopupContainer::showPopup(FrameView* view) 204 void PopupContainer::showPopup(FrameView* view)
204 { 205 {
205 m_frameView = view; 206 m_frameView = view;
206 listBox()->m_focusedNode = m_frameView->frame()->document()->focusedNode(); 207 listBox()->m_focusedNode = m_frameView->frame()->document()->focusedNode();
207 208
208 ChromeClientChromium* chromeClient = chromeClientChromium(); 209 ChromeClientChromium* chromeClient = chromeClientChromium();
209 if (chromeClient) { 210 if (chromeClient) {
210 IntRect popupRect = frameRect(); 211 IntRect popupRect = m_originalFrameRect;
211 chromeClient->popupOpened(this, layoutAndCalculateWidgetRect(popupRect.h eight(), popupRect.location()), false); 212 chromeClient->popupOpened(this, layoutAndCalculateWidgetRect(popupRect.h eight(), popupRect.location()), false);
212 m_popupOpen = true; 213 m_popupOpen = true;
213 } 214 }
214 215
215 if (!m_listBox->parent()) 216 if (!m_listBox->parent())
216 addChild(m_listBox.get()); 217 addChild(m_listBox.get());
217 218
218 // Enable scrollbars after the listbox is inserted into the hierarchy, 219 // Enable scrollbars after the listbox is inserted into the hierarchy,
219 // so it has a proper WidgetClient. 220 // so it has a proper WidgetClient.
220 m_listBox->setVerticalScrollbarMode(ScrollbarAuto); 221 m_listBox->setVerticalScrollbarMode(ScrollbarAuto);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 // FIXME: make sure this is correct, and add an assertion. 394 // FIXME: make sure this is correct, and add an assertion.
394 // ASSERT(popupWindow(popup)->listBox()->selectedIndex() == index); 395 // ASSERT(popupWindow(popup)->listBox()->selectedIndex() == index);
395 396
396 // Convert point to main window coords. 397 // Convert point to main window coords.
397 IntPoint location = v->contentsToWindow(r.location()); 398 IntPoint location = v->contentsToWindow(r.location());
398 399
399 // Move it below the select widget. 400 // Move it below the select widget.
400 location.move(0, r.height()); 401 location.move(0, r.height());
401 402
402 m_originalFrameRect = IntRect(location, r.size()); 403 m_originalFrameRect = IntRect(location, r.size());
403 setFrameRect(m_originalFrameRect); 404
405 // Position at (0, 0) since the frameRect().location() is relative to the pa rent WebWidget.
406 setFrameRect(IntRect(IntPoint(), r.size()));
404 showPopup(v); 407 showPopup(v);
405 } 408 }
406 409
407 void PopupContainer::refresh(const IntRect& targetControlRect) 410 void PopupContainer::refresh(const IntRect& targetControlRect)
408 { 411 {
409 IntPoint location = m_frameView->contentsToWindow(targetControlRect.location ()); 412 listBox()->setBaseWidth(max(m_originalFrameRect.width() - kBorderSize * 2, 0 ));
413 listBox()->updateFromElement();
414
415 IntPoint locationInWindow = m_frameView->contentsToWindow(targetControlRect. location());
416
410 // Move it below the select widget. 417 // Move it below the select widget.
411 location.move(0, targetControlRect.height()); 418 locationInWindow.move(0, targetControlRect.height());
412 419
413 listBox()->setBaseWidth(max(m_originalFrameRect.width() - kBorderSize * 2, 0 )); 420 IntRect widgetRectInScreen = layoutAndCalculateWidgetRect(targetControlRect. height(), locationInWindow);
414 421
415 listBox()->updateFromElement(); 422 // Reset the size (which can be set to the PopupListBox size in layoutAndGet RTLOffset(), exceeding the available widget rectangle.)
416 // Store the original size to check if we need to request the location. 423 if (size() != widgetRectInScreen.size())
417 IntSize originalSize = size(); 424 resize(widgetRectInScreen.size());
418 IntRect widgetRect = layoutAndCalculateWidgetRect(targetControlRect.height() , location); 425
419 if (originalSize != widgetRect.size()) { 426 ChromeClientChromium* chromeClient = chromeClientChromium();
420 ChromeClientChromium* chromeClient = chromeClientChromium(); 427 if (chromeClient) {
421 if (chromeClient) { 428 // Update the WebWidget location (which is relative to the screen origin ).
422 IntPoint widgetLocation = chromeClient->screenToRootView(widgetRect. location()); 429 if (widgetRectInScreen != chromeClient->windowRect())
423 widgetRect.setLocation(widgetLocation); 430 chromeClient->setWindowRect(widgetRectInScreen);
424 setFrameRect(widgetRect);
425 }
426 } 431 }
427 432
428 invalidate(); 433 invalidate();
429 } 434 }
430 435
431 inline bool PopupContainer::isRTL() const 436 inline bool PopupContainer::isRTL() const
432 { 437 {
433 return m_listBox->m_popupClient->menuStyle().textDirection() == RTL; 438 return m_listBox->m_popupClient->menuStyle().textDirection() == RTL;
434 } 439 }
435 440
(...skipping 23 matching lines...) Expand all
459 } 464 }
460 465
461 String PopupContainer::getSelectedItemToolTip() 466 String PopupContainer::getSelectedItemToolTip()
462 { 467 {
463 // We cannot use m_popupClient->selectedIndex() to choose tooltip message, 468 // We cannot use m_popupClient->selectedIndex() to choose tooltip message,
464 // because the selectedIndex() might return final selected index, not hoveri ng selection. 469 // because the selectedIndex() might return final selected index, not hoveri ng selection.
465 return listBox()->m_popupClient->itemToolTip(listBox()->m_selectedIndex); 470 return listBox()->m_popupClient->itemToolTip(listBox()->m_selectedIndex);
466 } 471 }
467 472
468 } // namespace WebCore 473 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/WebCore/platform/chromium/PopupContainer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698