1 /* 2 * This file is part of the popup menu implementation for <select> elements in WebCore. 3 * 4 * Copyright (C) 2008 Apple Computer, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #include "config.h" 24 #include "PopupMenu.h" 25 26 #include "Frame.h" 27 #include "FrameView.h" 28 #include "PopupMenuClient.h" 29 #include "PlatformString.h" 30 31 #include <wx/defs.h> 32 #if __WXMSW__ 33 #include <wx/msw/winundef.h> 34 #endif 35 #include <wx/event.h> 36 #include <wx/menu.h> 37 38 static int s_menuStartId = wxNewId(); 39 40 41 42 namespace WebCore { 43 44 PopupMenu::PopupMenu(PopupMenuClient* client) 45 : m_popupClient(client) 46 , m_menu(NULL) 47 { 48 } 49 50 PopupMenu::~PopupMenu() 51 { 52 delete m_menu; 53 } 54 55 void PopupMenu::show(const IntRect& r, FrameView* v, int index) 56 { 57 // just delete and recreate 58 delete m_menu; 59 ASSERT(client()); 60 61 wxWindow* nativeWin = v->platformWidget(); 62 63 if (nativeWin) { 64 // construct the menu 65 m_menu = new wxMenu(); 66 int size = client()->listSize(); 67 for (int i = 0; i < size; i++) { 68 int id = s_menuStartId + i; 69 70 if (client()->itemIsSeparator(i)) { 71 m_menu->AppendSeparator(); 72 } 73 else { 74 // FIXME: appending a menu item with an empty label asserts in 75 // wx. This needs to be fixed at wx level so that we can have 76 // the concept of "no selection" in choice boxes, etc. 77 if (!client()->itemText(i).isEmpty()) 78 m_menu->Append(s_menuStartId + i, client()->itemText(i)); 79 } 80 } 81 nativeWin->Connect(s_menuStartId, s_menuStartId + (size-1), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(PopupMenu::OnMenuItemSelected), NULL, this); 82 nativeWin->PopupMenu(m_menu, r.x() - v->scrollX(), r.y() - v->scrollY()); 83 nativeWin->Disconnect(s_menuStartId, s_menuStartId + (size-1), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(PopupMenu::OnMenuItemSelected), NULL, this); 84 } 85 } 86 87 void PopupMenu::OnMenuItemSelected(wxCommandEvent& event) 88 { 89 if (client()) { 90 client()->valueChanged(event.GetId() - s_menuStartId); 91 client()->popupDidHide(); 92 } 93 // TODO: Do we need to call Disconnect here? Do we have a ref to the native window still? 94 } 95 96 void PopupMenu::hide() 97 { 98 // we don't need to do anything here, the native control only exists during the time 99 // show is called 100 } 101 102 void PopupMenu::updateFromElement() 103 { 104 client()->setTextFromItem(m_popupClient->selectedIndex()); 105 } 106 107 bool PopupMenu::itemWritingDirectionIsNatural() 108 { 109 return false; 110 } 111 112 } 113