root/trunk/WebCore/platform/gtk/PopupMenuGtk.cpp

Revision 37295, 4.9 KB (checked in by hyatt@apple.com, 2 months ago)

2008-10-04 David Hyatt <hyatt@apple.com>

Make PopupMenuClient obey the platform abstraction. Remove any connection to Document and RenderStyle.

Reviewed by Darin Adler

  • WebCore.xcodeproj/project.pbxproj:
  • platform/PopupMenuClient.h:
  • platform/gtk/PopupMenuGtk.cpp: (WebCore::PopupMenu::show):
  • platform/mac/PopupMenuMac.mm: (WebCore::PopupMenu::populate): (WebCore::PopupMenu::show):
  • platform/qt/PopupMenuQt.cpp: (WebCore::PopupMenu::populate):
  • platform/win/PopupMenuWin.cpp: (WebCore::PopupMenu::calculatePositionAndSize): (WebCore::PopupMenu::paint): (WebCore::PopupWndProc):
  • rendering/RenderMenuList.cpp: (WebCore::RenderMenuList::itemStyle): (WebCore::RenderMenuList::menuStyle): (WebCore::RenderMenuList::hostWindow):
  • rendering/RenderMenuList.h:
  • rendering/RenderTextControl.cpp: (WebCore::RenderTextControl::itemStyle): (WebCore::RenderTextControl::menuStyle): (WebCore::RenderTextControl::hostWindow):
  • rendering/RenderTextControl.h:
  • Property svn:eol-style set to native
Line 
1/*
2 * This file is part of the popup menu implementation for <select> elements in WebCore.
3 *
4 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
6 * Copyright (C) 2008 Collabora Ltd.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "PopupMenu.h"
27
28#include "CString.h"
29#include "FrameView.h"
30#include "HostWindow.h"
31#include "NotImplemented.h"
32#include "PlatformString.h"
33#include <gtk/gtk.h>
34
35namespace WebCore {
36
37PopupMenu::PopupMenu(PopupMenuClient* client)
38    : m_popupClient(client)
39    , m_popup(0)
40{
41}
42
43PopupMenu::~PopupMenu()
44{
45    if (m_popup)
46        g_object_unref(m_popup);
47}
48
49void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
50{
51    ASSERT(client());
52
53    if (!m_popup) {
54        m_popup = GTK_MENU(gtk_menu_new());
55#if GLIB_CHECK_VERSION(2,10,0)
56        g_object_ref_sink(G_OBJECT(m_popup));
57#else
58        g_object_ref(G_OBJECT(m_popup));
59        gtk_object_sink(GTK_OBJECT(m_popup));
60#endif
61        g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmapped), this);
62    } else
63        gtk_container_foreach(GTK_CONTAINER(m_popup), reinterpret_cast<GtkCallback>(menuRemoveItem), this);
64
65    int x, y;
66    gdk_window_get_origin(GTK_WIDGET(view->hostWindow()->platformWindow())->window, &x, &y);
67    m_menuPosition = view->contentsToWindow(rect.location());
68    m_menuPosition = IntPoint(m_menuPosition.x() + x, m_menuPosition.y() + y + rect.height());
69    m_indexMap.clear();
70
71    const int size = client()->listSize();
72    for (int i = 0; i < size; ++i) {
73        GtkWidget* item;
74        if (client()->itemIsSeparator(i))
75            item = gtk_separator_menu_item_new();
76        else
77            item = gtk_menu_item_new_with_label(client()->itemText(i).utf8().data());
78
79        m_indexMap.add(item, i);
80        g_signal_connect(item, "activate", G_CALLBACK(menuItemActivated), this);
81
82        // FIXME: Apply the PopupMenuStyle from client()->itemStyle(i)
83        gtk_widget_set_sensitive(item, client()->itemIsEnabled(i));
84        gtk_menu_shell_append(GTK_MENU_SHELL(m_popup), item);
85        gtk_widget_show(item);
86    }
87
88    gtk_menu_set_active(m_popup, index);
89
90
91    // The size calls are directly copied from gtkcombobox.c which is LGPL
92    GtkRequisition requisition;
93    gtk_widget_set_size_request(GTK_WIDGET(m_popup), -1, -1);
94    gtk_widget_size_request(GTK_WIDGET(m_popup), &requisition);
95    gtk_widget_set_size_request(GTK_WIDGET(m_popup), MAX(rect.width(), requisition.width), -1);
96
97    GList* children = GTK_MENU_SHELL(m_popup)->children;
98    if (size)
99        for (int i = 0; i < size; i++) {
100            if (i > index)
101              break;
102
103            GtkWidget* item = reinterpret_cast<GtkWidget*>(children->data);
104            GtkRequisition itemRequisition;
105            gtk_widget_get_child_requisition(item, &itemRequisition);
106            m_menuPosition.setY(m_menuPosition.y() - itemRequisition.height);
107
108            children = g_list_next(children);
109        }
110    else
111        // Center vertically the empty popup in the combo box area
112        m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2);
113
114    gtk_menu_popup(m_popup, NULL, NULL, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, 0, gtk_get_current_event_time());
115}
116
117void PopupMenu::hide()
118{
119    ASSERT(m_popup);
120    gtk_menu_popdown(m_popup);
121}
122
123void PopupMenu::updateFromElement()
124{
125    client()->setTextFromItem(client()->selectedIndex());
126}
127
128bool PopupMenu::itemWritingDirectionIsNatural()
129{
130    return true;
131}
132
133void PopupMenu::menuItemActivated(GtkMenuItem* item, PopupMenu* that)
134{
135    ASSERT(that->client());
136    ASSERT(that->m_indexMap.contains(GTK_WIDGET(item)));
137    that->client()->valueChanged(that->m_indexMap.get(GTK_WIDGET(item)));
138}
139
140void PopupMenu::menuUnmapped(GtkWidget*, PopupMenu* that)
141{
142    ASSERT(that->client());
143    that->client()->hidePopup();
144}
145
146void PopupMenu::menuPositionFunction(GtkMenu*, gint* x, gint* y, gboolean* pushIn, PopupMenu* that)
147{
148    *x = that->m_menuPosition.x();
149    *y = that->m_menuPosition.y();
150    *pushIn = true;
151}
152
153void PopupMenu::menuRemoveItem(GtkWidget* widget, PopupMenu* that)
154{
155    ASSERT(that->m_popup);
156    gtk_container_remove(GTK_CONTAINER(that->m_popup), widget);
157}
158
159}
Note: See TracBrowser for help on using the browser.