| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, 2009, 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 int numItems() const { return static_cast<int>(m_items.size()); } | 129 int numItems() const { return static_cast<int>(m_items.size()); } |
| 130 | 130 |
| 131 void setBaseWidth(int width) { m_baseWidth = width; } | 131 void setBaseWidth(int width) { m_baseWidth = width; } |
| 132 | 132 |
| 133 // Computes the size of widget and children. | 133 // Computes the size of widget and children. |
| 134 void layout(); | 134 void layout(); |
| 135 | 135 |
| 136 // Returns whether the popup wants to process events for the passed key. | 136 // Returns whether the popup wants to process events for the passed key. |
| 137 bool isInterestedInEventForKey(int keyCode); | 137 bool isInterestedInEventForKey(int keyCode); |
| 138 | 138 |
| 139 // Gets the height of a row. |
| 140 int getRowHeight(int index); |
| 141 |
| 142 // Returns true if the selection can be changed to index. |
| 143 // Disabled items, or labels cannot be selected. |
| 144 bool isSelectableItem(int index); |
| 145 |
| 146 const Vector<PopupItem*>& items() const { return m_items; } |
| 147 |
| 139 private: | 148 private: |
| 140 friend class PopupContainer; | 149 friend class PopupContainer; |
| 141 friend class RefCounted<PopupListBox>; | 150 friend class RefCounted<PopupListBox>; |
| 142 | 151 |
| 143 // A type of List Item | |
| 144 enum ListItemType { | |
| 145 TypeOption, | |
| 146 TypeGroup, | |
| 147 TypeSeparator | |
| 148 }; | |
| 149 | |
| 150 // A item (represented by <option> or <optgroup>) in the <select> widget. | |
| 151 struct ListItem { | |
| 152 ListItem(const String& label, ListItemType type) | |
| 153 : label(label.copy()), type(type), y(0) {} | |
| 154 String label; | |
| 155 ListItemType type; | |
| 156 int y; // y offset of this item, relative to the top of the popup. | |
| 157 }; | |
| 158 | |
| 159 PopupListBox(PopupMenuClient* client, const PopupContainerSettings& settings
) | 152 PopupListBox(PopupMenuClient* client, const PopupContainerSettings& settings
) |
| 160 : m_settings(settings) | 153 : m_settings(settings) |
| 161 , m_originalIndex(0) | 154 , m_originalIndex(0) |
| 162 , m_selectedIndex(0) | 155 , m_selectedIndex(0) |
| 163 , m_willAcceptOnAbandon(false) | 156 , m_willAcceptOnAbandon(false) |
| 164 , m_visibleRows(0) | 157 , m_visibleRows(0) |
| 165 , m_popupClient(client) | 158 , m_popupClient(client) |
| 166 , m_repeatingChar(0) | 159 , m_repeatingChar(0) |
| 167 , m_lastCharTime(0) | 160 , m_lastCharTime(0) |
| 168 { | 161 { |
| 169 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); | 162 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); |
| 170 } | 163 } |
| 171 | 164 |
| 172 ~PopupListBox() | 165 ~PopupListBox() |
| 173 { | 166 { |
| 174 clear(); | 167 clear(); |
| 175 } | 168 } |
| 176 | 169 |
| 177 void disconnectClient() { m_popupClient = 0; } | 170 void disconnectClient() { m_popupClient = 0; } |
| 178 | 171 |
| 179 // Closes the popup | 172 // Closes the popup |
| 180 void abandon(); | 173 void abandon(); |
| 181 // Select an index in the list, scrolling if necessary. | 174 // Select an index in the list, scrolling if necessary. |
| 182 void selectIndex(int index); | 175 void selectIndex(int index); |
| 183 // Accepts the selected index as the value to be displayed in the <select> w
idget on | 176 // Accepts the selected index as the value to be displayed in the <select> w
idget on |
| 184 // the web page, and closes the popup. | 177 // the web page, and closes the popup. |
| 185 void acceptIndex(int index); | 178 void acceptIndex(int index); |
| 186 | 179 |
| 187 // Returns true if the selection can be changed to index. | |
| 188 // Disabled items, or labels cannot be selected. | |
| 189 bool isSelectableItem(int index); | |
| 190 | |
| 191 // Clears the selection (so no row appears selected). | 180 // Clears the selection (so no row appears selected). |
| 192 void clearSelection(); | 181 void clearSelection(); |
| 193 | 182 |
| 194 // Scrolls to reveal the given index. | 183 // Scrolls to reveal the given index. |
| 195 void scrollToRevealRow(int index); | 184 void scrollToRevealRow(int index); |
| 196 void scrollToRevealSelection() { scrollToRevealRow(m_selectedIndex); } | 185 void scrollToRevealSelection() { scrollToRevealRow(m_selectedIndex); } |
| 197 | 186 |
| 198 // Invalidates the row at the given index. | 187 // Invalidates the row at the given index. |
| 199 void invalidateRow(int index); | 188 void invalidateRow(int index); |
| 200 | 189 |
| 201 // Gets the height of a row. | |
| 202 int getRowHeight(int index); | |
| 203 // Get the bounds of a row. | 190 // Get the bounds of a row. |
| 204 IntRect getRowBounds(int index); | 191 IntRect getRowBounds(int index); |
| 205 | 192 |
| 206 // Converts a point to an index of the row the point is over | 193 // Converts a point to an index of the row the point is over |
| 207 int pointToRowIndex(const IntPoint&); | 194 int pointToRowIndex(const IntPoint&); |
| 208 | 195 |
| 209 // Paint an individual row | 196 // Paint an individual row |
| 210 void paintRow(GraphicsContext*, const IntRect&, int rowIndex); | 197 void paintRow(GraphicsContext*, const IntRect&, int rowIndex); |
| 211 | 198 |
| 212 // Test if the given point is within the bounds of the popup window. | 199 // Test if the given point is within the bounds of the popup window. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 243 | 230 |
| 244 // This is the number of rows visible in the popup. The maximum number visib
le at a time is | 231 // This is the number of rows visible in the popup. The maximum number visib
le at a time is |
| 245 // defined as being kMaxVisibleRows. For a scrolled popup, this can be thoug
ht of as the | 232 // defined as being kMaxVisibleRows. For a scrolled popup, this can be thoug
ht of as the |
| 246 // page size in data units. | 233 // page size in data units. |
| 247 int m_visibleRows; | 234 int m_visibleRows; |
| 248 | 235 |
| 249 // Our suggested width, not including scrollbar. | 236 // Our suggested width, not including scrollbar. |
| 250 int m_baseWidth; | 237 int m_baseWidth; |
| 251 | 238 |
| 252 // A list of the options contained within the <select> | 239 // A list of the options contained within the <select> |
| 253 Vector<ListItem*> m_items; | 240 Vector<PopupItem*> m_items; |
| 254 | 241 |
| 255 // The <select> PopupMenuClient that opened us. | 242 // The <select> PopupMenuClient that opened us. |
| 256 PopupMenuClient* m_popupClient; | 243 PopupMenuClient* m_popupClient; |
| 257 | 244 |
| 258 // The scrollbar which has mouse capture. Mouse events go straight to this | 245 // The scrollbar which has mouse capture. Mouse events go straight to this |
| 259 // if non-NULL. | 246 // if non-NULL. |
| 260 RefPtr<Scrollbar> m_capturingScrollbar; | 247 RefPtr<Scrollbar> m_capturingScrollbar; |
| 261 | 248 |
| 262 // The last scrollbar that the mouse was over. Used for mouseover highlight
s. | 249 // The last scrollbar that the mouse was over. Used for mouseover highlight
s. |
| 263 RefPtr<Scrollbar> m_lastScrollbarUnderMouse; | 250 RefPtr<Scrollbar> m_lastScrollbarUnderMouse; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 /////////////////////////////////////////////////////////////////////////////// | 290 /////////////////////////////////////////////////////////////////////////////// |
| 304 // PopupContainer implementation | 291 // PopupContainer implementation |
| 305 | 292 |
| 306 // static | 293 // static |
| 307 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, | 294 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, |
| 308 const PopupContainerSettings&
settings) | 295 const PopupContainerSettings&
settings) |
| 309 { | 296 { |
| 310 return adoptRef(new PopupContainer(client, settings)); | 297 return adoptRef(new PopupContainer(client, settings)); |
| 311 } | 298 } |
| 312 | 299 |
| 313 PopupContainer::PopupContainer(PopupMenuClient* client, const PopupContainerSett
ings& settings) | 300 PopupContainer::PopupContainer(PopupMenuClient* client, |
| 301 const PopupContainerSettings& settings) |
| 314 : m_listBox(PopupListBox::create(client, settings)) | 302 : m_listBox(PopupListBox::create(client, settings)) |
| 315 , m_settings(settings) | 303 , m_settings(settings) |
| 316 { | 304 { |
| 317 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); | 305 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); |
| 318 } | 306 } |
| 319 | 307 |
| 320 PopupContainer::~PopupContainer() | 308 PopupContainer::~PopupContainer() |
| 321 { | 309 { |
| 322 if (m_listBox) | 310 if (m_listBox && m_listBox->parent()) |
| 323 removeChild(m_listBox.get()); | 311 removeChild(m_listBox.get()); |
| 324 } | 312 } |
| 325 | 313 |
| 326 void PopupContainer::showPopup(FrameView* view) | 314 void PopupContainer::showPopup(FrameView* view) |
| 327 { | 315 { |
| 328 // Pre-layout, our size matches the <select> dropdown control. | 316 // Pre-layout, our size matches the <select> dropdown control. |
| 329 int selectHeight = frameRect().height(); | 317 int selectHeight = frameRect().height(); |
| 330 | 318 |
| 331 // Lay everything out to figure out our preferred size, then tell the view's | 319 // Lay everything out to figure out our preferred size, then tell the view's |
| 332 // WidgetClient about it. It should assign us a client. | 320 // WidgetClient about it. It should assign us a client. |
| 333 layout(); | 321 layout(); |
| 334 | 322 |
| 335 ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>( | 323 ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>( |
| 336 view->frame()->page()->chrome()->client()); | 324 view->frame()->page()->chrome()->client()); |
| 337 if (chromeClient) { | 325 if (chromeClient) { |
| 338 // If the popup would extend past the bottom of the screen, open upwards | 326 // If the popup would extend past the bottom of the screen, open upwards |
| 339 // instead. | 327 // instead. |
| 340 FloatRect screen = screenAvailableRect(view); | 328 FloatRect screen = screenAvailableRect(view); |
| 341 IntRect widgetRect = chromeClient->windowToScreen(frameRect()); | 329 IntRect widgetRect = chromeClient->windowToScreen(frameRect()); |
| 342 if (widgetRect.bottom() > static_cast<int>(screen.bottom())) | 330 if (widgetRect.bottom() > static_cast<int>(screen.bottom())) |
| 343 widgetRect.move(0, -(widgetRect.height() + selectHeight)); | 331 widgetRect.move(0, -(widgetRect.height() + selectHeight)); |
| 344 | 332 |
| 345 chromeClient->popupOpened(this, widgetRect, m_settings.focusOnShow); | 333 chromeClient->popupOpened(this, widgetRect, m_settings.focusOnShow, fals
e); |
| 346 } | 334 } |
| 347 | 335 |
| 348 if (!m_listBox->parent()) | 336 if (!m_listBox->parent()) |
| 349 addChild(m_listBox.get()); | 337 addChild(m_listBox.get()); |
| 350 | 338 |
| 351 // Enable scrollbars after the listbox is inserted into the hierarchy, | 339 // Enable scrollbars after the listbox is inserted into the hierarchy, |
| 352 // so it has a proper WidgetClient. | 340 // so it has a proper WidgetClient. |
| 353 m_listBox->setVerticalScrollbarMode(ScrollbarAuto); | 341 m_listBox->setVerticalScrollbarMode(ScrollbarAuto); |
| 354 | 342 |
| 355 m_listBox->scrollToRevealSelection(); | 343 m_listBox->scrollToRevealSelection(); |
| 356 | 344 |
| 357 invalidate(); | 345 invalidate(); |
| 358 } | 346 } |
| 359 | 347 |
| 348 void PopupContainer::showExternal(const IntRect& rect, FrameView* v, int index) |
| 349 { |
| 350 if (!listBox()) |
| 351 return; |
| 352 |
| 353 listBox()->updateFromElement(); |
| 354 |
| 355 // Get the ChromeClient and pass it the popup menu's listbox data. |
| 356 ChromeClientChromium* client = static_cast<ChromeClientChromium*>( |
| 357 v->frame()->page()->chrome()->client()); |
| 358 client->popupOpened(this, rect, true, true); |
| 359 } |
| 360 |
| 360 void PopupContainer::hidePopup() | 361 void PopupContainer::hidePopup() |
| 361 { | 362 { |
| 362 if (client()) | 363 if (client()) |
| 363 client()->popupClosed(this); | 364 client()->popupClosed(this); |
| 364 } | 365 } |
| 365 | 366 |
| 366 void PopupContainer::layout() | 367 void PopupContainer::layout() |
| 367 { | 368 { |
| 368 m_listBox->layout(); | 369 m_listBox->layout(); |
| 369 | 370 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 { | 479 { |
| 479 listBox()->updateFromElement(); | 480 listBox()->updateFromElement(); |
| 480 layout(); | 481 layout(); |
| 481 } | 482 } |
| 482 | 483 |
| 483 int PopupContainer::selectedIndex() const | 484 int PopupContainer::selectedIndex() const |
| 484 { | 485 { |
| 485 return m_listBox->selectedIndex(); | 486 return m_listBox->selectedIndex(); |
| 486 } | 487 } |
| 487 | 488 |
| 489 int PopupContainer::menuItemHeight() const |
| 490 { |
| 491 return m_listBox->getRowHeight(0); |
| 492 } |
| 493 |
| 494 const WTF::Vector<PopupItem*>& PopupContainer:: popupData() const |
| 495 { |
| 496 return m_listBox->items(); |
| 497 } |
| 498 |
| 488 /////////////////////////////////////////////////////////////////////////////// | 499 /////////////////////////////////////////////////////////////////////////////// |
| 489 // PopupListBox implementation | 500 // PopupListBox implementation |
| 490 | 501 |
| 491 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) | 502 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) |
| 492 { | 503 { |
| 493 Scrollbar* scrollbar = scrollbarUnderMouse(event); | 504 Scrollbar* scrollbar = scrollbarUnderMouse(event); |
| 494 if (scrollbar) { | 505 if (scrollbar) { |
| 495 m_capturingScrollbar = scrollbar; | 506 m_capturingScrollbar = scrollbar; |
| 496 m_capturingScrollbar->mouseDown(event); | 507 m_capturingScrollbar->mouseDown(event); |
| 497 return true; | 508 return true; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 if (m_willAcceptOnAbandon) | 832 if (m_willAcceptOnAbandon) |
| 822 m_popupClient->valueChanged(m_selectedIndex); | 833 m_popupClient->valueChanged(m_selectedIndex); |
| 823 } | 834 } |
| 824 | 835 |
| 825 int PopupListBox::pointToRowIndex(const IntPoint& point) | 836 int PopupListBox::pointToRowIndex(const IntPoint& point) |
| 826 { | 837 { |
| 827 int y = scrollY() + point.y(); | 838 int y = scrollY() + point.y(); |
| 828 | 839 |
| 829 // FIXME: binary search if perf matters. | 840 // FIXME: binary search if perf matters. |
| 830 for (int i = 0; i < numItems(); ++i) { | 841 for (int i = 0; i < numItems(); ++i) { |
| 831 if (y < m_items[i]->y) | 842 if (y < m_items[i]->yOffset) |
| 832 return i-1; | 843 return i-1; |
| 833 } | 844 } |
| 834 | 845 |
| 835 // Last item? | 846 // Last item? |
| 836 if (y < contentsHeight()) | 847 if (y < contentsHeight()) |
| 837 return m_items.size()-1; | 848 return m_items.size()-1; |
| 838 | 849 |
| 839 return -1; | 850 return -1; |
| 840 } | 851 } |
| 841 | 852 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 return 0; | 894 return 0; |
| 884 | 895 |
| 885 return m_popupClient->itemStyle(index).font().height(); | 896 return m_popupClient->itemStyle(index).font().height(); |
| 886 } | 897 } |
| 887 | 898 |
| 888 IntRect PopupListBox::getRowBounds(int index) | 899 IntRect PopupListBox::getRowBounds(int index) |
| 889 { | 900 { |
| 890 if (index < 0) | 901 if (index < 0) |
| 891 return IntRect(0, 0, visibleWidth(), getRowHeight(index)); | 902 return IntRect(0, 0, visibleWidth(), getRowHeight(index)); |
| 892 | 903 |
| 893 return IntRect(0, m_items[index]->y, visibleWidth(), getRowHeight(index)); | 904 return IntRect(0, m_items[index]->yOffset, visibleWidth(), getRowHeight(inde
x)); |
| 894 } | 905 } |
| 895 | 906 |
| 896 void PopupListBox::invalidateRow(int index) | 907 void PopupListBox::invalidateRow(int index) |
| 897 { | 908 { |
| 898 if (index < 0) | 909 if (index < 0) |
| 899 return; | 910 return; |
| 900 | 911 |
| 901 // Invalidate in the window contents, as FramelessScrollView::invalidateRect | 912 // Invalidate in the window contents, as FramelessScrollView::invalidateRect |
| 902 // paints in the window coordinates. | 913 // paints in the window coordinates. |
| 903 invalidateRect(contentsToWindow(getRowBounds(index))); | 914 invalidateRect(contentsToWindow(getRowBounds(index))); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 914 // Row is above current scroll position, scroll up. | 925 // Row is above current scroll position, scroll up. |
| 915 ScrollView::setScrollPosition(IntPoint(0, rowRect.y())); | 926 ScrollView::setScrollPosition(IntPoint(0, rowRect.y())); |
| 916 } else if (rowRect.bottom() > scrollY() + visibleHeight()) { | 927 } else if (rowRect.bottom() > scrollY() + visibleHeight()) { |
| 917 // Row is below current scroll position, scroll down. | 928 // Row is below current scroll position, scroll down. |
| 918 ScrollView::setScrollPosition(IntPoint(0, rowRect.bottom() - visibleHeig
ht())); | 929 ScrollView::setScrollPosition(IntPoint(0, rowRect.bottom() - visibleHeig
ht())); |
| 919 } | 930 } |
| 920 } | 931 } |
| 921 | 932 |
| 922 bool PopupListBox::isSelectableItem(int index) | 933 bool PopupListBox::isSelectableItem(int index) |
| 923 { | 934 { |
| 924 return m_items[index]->type == TypeOption && m_popupClient->itemIsEnabled(in
dex); | 935 return m_items[index]->type == PopupItem::TypeOption && m_popupClient->itemI
sEnabled(index); |
| 925 } | 936 } |
| 926 | 937 |
| 927 void PopupListBox::clearSelection() | 938 void PopupListBox::clearSelection() |
| 928 { | 939 { |
| 929 if (m_selectedIndex != -1) { | 940 if (m_selectedIndex != -1) { |
| 930 invalidateRow(m_selectedIndex); | 941 invalidateRow(m_selectedIndex); |
| 931 m_selectedIndex = -1; | 942 m_selectedIndex = -1; |
| 932 } | 943 } |
| 933 } | 944 } |
| 934 | 945 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 // is called before abandon, which causes discarding of the select result.
| 1014 // is called before abandon, which causes discarding of the select result.
|
| 1004 if (m_willAcceptOnAbandon) { | 1015 if (m_willAcceptOnAbandon) { |
| 1005 m_popupClient->valueChanged(m_selectedIndex); | 1016 m_popupClient->valueChanged(m_selectedIndex); |
| 1006 m_willAcceptOnAbandon = false; | 1017 m_willAcceptOnAbandon = false; |
| 1007 } | 1018 } |
| 1008 | 1019 |
| 1009 clear(); | 1020 clear(); |
| 1010 | 1021 |
| 1011 int size = m_popupClient->listSize(); | 1022 int size = m_popupClient->listSize(); |
| 1012 for (int i = 0; i < size; ++i) { | 1023 for (int i = 0; i < size; ++i) { |
| 1013 ListItemType type; | 1024 PopupItem::Type type; |
| 1014 if (m_popupClient->itemIsSeparator(i)) | 1025 if (m_popupClient->itemIsSeparator(i)) |
| 1015 type = PopupListBox::TypeSeparator; | 1026 type = PopupItem::TypeSeparator; |
| 1016 else if (m_popupClient->itemIsLabel(i)) | 1027 else if (m_popupClient->itemIsLabel(i)) |
| 1017 type = PopupListBox::TypeGroup; | 1028 type = PopupItem::TypeGroup; |
| 1018 else | 1029 else |
| 1019 type = PopupListBox::TypeOption; | 1030 type = PopupItem::TypeOption; |
| 1020 m_items.append(new ListItem(m_popupClient->itemText(i), type)); | 1031 m_items.append(new PopupItem(m_popupClient->itemText(i), type)); |
| 1032 m_items[i]->enabled = isSelectableItem(i); |
| 1021 } | 1033 } |
| 1022 | 1034 |
| 1023 m_selectedIndex = m_popupClient->selectedIndex(); | 1035 m_selectedIndex = m_popupClient->selectedIndex(); |
| 1024 setOriginalIndex(m_selectedIndex); | 1036 setOriginalIndex(m_selectedIndex); |
| 1025 | 1037 |
| 1026 layout(); | 1038 layout(); |
| 1027 } | 1039 } |
| 1028 | 1040 |
| 1029 void PopupListBox::layout() | 1041 void PopupListBox::layout() |
| 1030 { | 1042 { |
| 1031 // Size our child items. | 1043 // Size our child items. |
| 1032 int baseWidth = 0; | 1044 int baseWidth = 0; |
| 1033 int paddingWidth = 0; | 1045 int paddingWidth = 0; |
| 1034 int y = 0; | 1046 int y = 0; |
| 1035 for (int i = 0; i < numItems(); ++i) { | 1047 for (int i = 0; i < numItems(); ++i) { |
| 1036 Font itemFont = getRowFont(i); | 1048 Font itemFont = getRowFont(i); |
| 1037 | 1049 |
| 1038 // Place the item vertically. | 1050 // Place the item vertically. |
| 1039 m_items[i]->y = y; | 1051 m_items[i]->yOffset = y; |
| 1040 y += itemFont.height(); | 1052 y += itemFont.height(); |
| 1041 | 1053 |
| 1042 // Ensure the popup is wide enough to fit this item. | 1054 // Ensure the popup is wide enough to fit this item. |
| 1043 String text = m_popupClient->itemText(i); | 1055 String text = m_popupClient->itemText(i); |
| 1044 if (!text.isEmpty()) { | 1056 if (!text.isEmpty()) { |
| 1045 int width = itemFont.width(TextRun(text)); | 1057 int width = itemFont.width(TextRun(text)); |
| 1046 baseWidth = max(baseWidth, width); | 1058 baseWidth = max(baseWidth, width); |
| 1047 } | 1059 } |
| 1048 // FIXME: http://b/1210481 We should get the padding of individual optio
n elements. | 1060 // FIXME: http://b/1210481 We should get the padding of individual optio
n elements. |
| 1049 paddingWidth = max(paddingWidth, | 1061 paddingWidth = max(paddingWidth, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 setContentsSize(IntSize(contentWidth, getRowBounds(numItems() - 1).bottom())
); | 1093 setContentsSize(IntSize(contentWidth, getRowBounds(numItems() - 1).bottom())
); |
| 1082 | 1094 |
| 1083 if (hostWindow()) | 1095 if (hostWindow()) |
| 1084 scrollToRevealSelection(); | 1096 scrollToRevealSelection(); |
| 1085 | 1097 |
| 1086 invalidate(); | 1098 invalidate(); |
| 1087 } | 1099 } |
| 1088 | 1100 |
| 1089 void PopupListBox::clear() | 1101 void PopupListBox::clear() |
| 1090 { | 1102 { |
| 1091 for (Vector<ListItem*>::iterator it = m_items.begin(); it != m_items.end();
++it) | 1103 for (Vector<PopupItem*>::iterator it = m_items.begin(); it != m_items.end();
++it) |
| 1092 delete *it; | 1104 delete *it; |
| 1093 m_items.clear(); | 1105 m_items.clear(); |
| 1094 } | 1106 } |
| 1095 | 1107 |
| 1096 bool PopupListBox::isPointInBounds(const IntPoint& point) | 1108 bool PopupListBox::isPointInBounds(const IntPoint& point) |
| 1097 { | 1109 { |
| 1098 return numItems() != 0 && IntRect(0, 0, width(), height()).contains(point); | 1110 return numItems() != 0 && IntRect(0, 0, width(), height()).contains(point); |
| 1099 } | 1111 } |
| 1100 | 1112 |
| 1101 /////////////////////////////////////////////////////////////////////////////// | 1113 /////////////////////////////////////////////////////////////////////////////// |
| 1102 // PopupMenu implementation | 1114 // PopupMenu implementation |
| 1103 // | 1115 // |
| 1104 // Note: you cannot add methods to this class, since it is defined above the | 1116 // Note: you cannot add methods to this class, since it is defined above the |
| 1105 // portability layer. To access methods and properties on the | 1117 // portability layer. To access methods and properties on the |
| 1106 // popup widgets, use |popupWindow| above. | 1118 // popup widgets, use |popupWindow| above. |
| 1107 | 1119 |
| 1108 PopupMenu::PopupMenu(PopupMenuClient* client) | 1120 PopupMenu::PopupMenu(PopupMenuClient* client) |
| 1109 : m_popupClient(client) | 1121 : m_popupClient(client) |
| 1110 { | 1122 { |
| 1111 } | 1123 } |
| 1112 | 1124 |
| 1113 PopupMenu::~PopupMenu() | 1125 PopupMenu::~PopupMenu() |
| 1114 { | 1126 { |
| 1115 hide(); | 1127 hide(); |
| 1116 } | 1128 } |
| 1117 | 1129 |
| 1118 void PopupMenu::show(const IntRect& r, FrameView* v, int index) | 1130 // The Mac Chromium implementation relies on external control (a Cocoa control) |
| 1131 // to display, handle the input tracking and menu item selection for the popup. |
| 1132 // Windows and Linux Chromium let our WebKit port handle the display, while |
| 1133 // another process manages the popup window and input handling. |
| 1134 void PopupMenu::show(const IntRect& r, FrameView* v, int index) |
| 1119 { | 1135 { |
| 1120 if (!p.popup) | 1136 if (!p.popup) |
| 1121 p.popup = PopupContainer::create(client(), dropDownSettings); | 1137 p.popup = PopupContainer::create(client(), dropDownSettings); |
| 1138 #if PLATFORM(DARWIN) |
| 1139 p.popup->showExternal(r, v, index); |
| 1140 #else |
| 1122 p.popup->show(r, v, index); | 1141 p.popup->show(r, v, index); |
| 1142 #endif |
| 1123 } | 1143 } |
| 1124 | 1144 |
| 1125 void PopupMenu::hide() | 1145 void PopupMenu::hide() |
| 1126 { | 1146 { |
| 1127 if (p.popup) | 1147 if (p.popup) |
| 1128 p.popup->hidePopup(); | 1148 p.popup->hidePopup(); |
| 1129 } | 1149 } |
| 1130 | 1150 |
| 1131 void PopupMenu::updateFromElement() | 1151 void PopupMenu::updateFromElement() |
| 1132 { | 1152 { |
| 1133 p.popup->listBox()->updateFromElement(); | 1153 p.popup->listBox()->updateFromElement(); |
| 1134 } | 1154 } |
| 1135 | 1155 |
| 1136 bool PopupMenu::itemWritingDirectionIsNatural() | 1156 bool PopupMenu::itemWritingDirectionIsNatural() |
| 1137 { | 1157 { |
| 1138 return false; | 1158 return false; |
| 1139 } | 1159 } |
| 1140 | 1160 |
| 1141 } // namespace WebCore | 1161 } // namespace WebCore |
| OLD | NEW |