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