]>
Commit | Line | Data |
---|---|---|
9f41d601 | 1 | ///////////////////////////////////////////////////////////////////////////// |
670f9935 | 2 | // Name: src/gtk/popupwin.cpp |
9f41d601 RR |
3 | // Purpose: |
4 | // Author: Robert Roebling | |
9f41d601 | 5 | // Copyright: (c) 1998 Robert Roebling |
65571936 | 6 | // Licence: wxWindows licence |
9f41d601 RR |
7 | ///////////////////////////////////////////////////////////////////////////// |
8 | ||
14f355c2 VS |
9 | // For compilers that support precompilation, includes "wx.h". |
10 | #include "wx/wxprec.h" | |
f3ecfad1 VS |
11 | |
12 | #if wxUSE_POPUPWIN | |
13 | ||
9f41d601 | 14 | #include "wx/popupwin.h" |
670f9935 WS |
15 | |
16 | #ifndef WX_PRECOMP | |
670f9935 WS |
17 | #endif // WX_PRECOMP |
18 | ||
9f41d601 | 19 | #include <gtk/gtk.h> |
9f41d601 | 20 | |
bbd92d1d | 21 | #include "wx/gtk/private/win_gtk.h" |
9f41d601 | 22 | |
f7204798 RR |
23 | //----------------------------------------------------------------------------- |
24 | // "button_press" | |
25 | //----------------------------------------------------------------------------- | |
26 | ||
865bb325 | 27 | extern "C" { |
f7204798 RR |
28 | static gint gtk_popup_button_press (GtkWidget *widget, GdkEvent *gdk_event, wxPopupWindow* win ) |
29 | { | |
30 | GtkWidget *child = gtk_get_event_widget (gdk_event); | |
31 | ||
33c0d0ed RR |
32 | /* Ignore events sent out before we connected to the signal */ |
33 | if (win->m_time >= ((GdkEventButton*)gdk_event)->time) | |
34 | return FALSE; | |
35 | ||
36 | /* We don't ask for button press events on the grab widget, so | |
37 | * if an event is reported directly to the grab widget, it must | |
38 | * be on a window outside the application (and thus we remove | |
39 | * the popup window). Otherwise, we check if the widget is a child | |
40 | * of the grab widget, and only remove the popup window if it | |
41 | * is not. */ | |
f7204798 RR |
42 | if (child != widget) |
43 | { | |
44 | while (child) | |
88d19775 MR |
45 | { |
46 | if (child == widget) | |
47 | return FALSE; | |
385e8575 | 48 | child = gtk_widget_get_parent(child); |
f7204798 RR |
49 | } |
50 | } | |
51 | ||
52 | wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); | |
53 | event.SetEventObject( win ); | |
54 | ||
937013e0 | 55 | (void)win->HandleWindowEvent( event ); |
f7204798 RR |
56 | |
57 | return TRUE; | |
58 | } | |
865bb325 | 59 | } |
f7204798 | 60 | |
9f41d601 RR |
61 | //----------------------------------------------------------------------------- |
62 | // "delete_event" | |
63 | //----------------------------------------------------------------------------- | |
64 | ||
865bb325 | 65 | extern "C" { |
9f41d601 RR |
66 | bool gtk_dialog_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxPopupWindow *win ) |
67 | { | |
9f41d601 RR |
68 | if (win->IsEnabled()) |
69 | win->Close(); | |
70 | ||
71 | return TRUE; | |
72 | } | |
865bb325 | 73 | } |
9f41d601 | 74 | |
9f41d601 RR |
75 | //----------------------------------------------------------------------------- |
76 | // wxPopupWindow | |
77 | //----------------------------------------------------------------------------- | |
78 | ||
8f0db49c | 79 | #ifdef __WXUNIVERSAL__ |
cca410b3 | 80 | BEGIN_EVENT_TABLE(wxPopupWindow,wxPopupWindowBase) |
6522713c | 81 | EVT_SIZE(wxPopupWindow::OnSize) |
9f41d601 | 82 | END_EVENT_TABLE() |
cca410b3 | 83 | #endif |
9f41d601 | 84 | |
ad9fb033 RR |
85 | wxPopupWindow::~wxPopupWindow() |
86 | { | |
ad9fb033 RR |
87 | } |
88 | ||
9f41d601 RR |
89 | bool wxPopupWindow::Create( wxWindow *parent, int style ) |
90 | { | |
9f41d601 | 91 | if (!PreCreation( parent, wxDefaultPosition, wxDefaultSize ) || |
2b5f62a0 | 92 | !CreateBase( parent, -1, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, wxT("popup") )) |
9f41d601 RR |
93 | { |
94 | wxFAIL_MSG( wxT("wxPopupWindow creation failed") ); | |
670f9935 | 95 | return false; |
9f41d601 RR |
96 | } |
97 | ||
da19de36 RR |
98 | // Unlike windows, top level windows are created hidden by default. |
99 | m_isShown = false; | |
88d19775 | 100 | |
9f41d601 RR |
101 | // All dialogs should really have this style |
102 | m_windowStyle |= wxTAB_TRAVERSAL; | |
103 | ||
9f41d601 | 104 | m_widget = gtk_window_new( GTK_WINDOW_POPUP ); |
3591d10f | 105 | g_object_ref( m_widget ); |
9f41d601 | 106 | |
3591d10f | 107 | gtk_widget_set_name( m_widget, "wxPopupWindow" ); |
62d934aa RR |
108 | // wxPopupWindow is used for different windows as well |
109 | // gtk_window_set_type_hint( GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_COMBO ); | |
9f41d601 | 110 | |
b561290c VZ |
111 | // Popup windows can be created without parent, so handle this correctly. |
112 | if (parent) | |
3591d10f | 113 | { |
b561290c VZ |
114 | GtkWidget *toplevel = gtk_widget_get_toplevel( parent->m_widget ); |
115 | if (GTK_IS_WINDOW (toplevel)) | |
116 | { | |
451673f7 | 117 | #if GTK_CHECK_VERSION(2,10,0) |
9dc44eff | 118 | #ifndef __WXGTK3__ |
b561290c | 119 | if (!gtk_check_version(2,10,0)) |
9dc44eff | 120 | #endif |
b561290c VZ |
121 | { |
122 | gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)), GTK_WINDOW (m_widget)); | |
123 | } | |
451673f7 | 124 | #endif |
b561290c VZ |
125 | gtk_window_set_transient_for (GTK_WINDOW (m_widget), GTK_WINDOW (toplevel)); |
126 | } | |
127 | gtk_window_set_screen (GTK_WINDOW (m_widget), gtk_widget_get_screen (GTK_WIDGET (parent->m_widget))); | |
3591d10f | 128 | } |
b561290c | 129 | |
3591d10f | 130 | gtk_window_set_resizable (GTK_WINDOW (m_widget), FALSE); |
9f41d601 | 131 | |
9fa72bd2 MR |
132 | g_signal_connect (m_widget, "delete_event", |
133 | G_CALLBACK (gtk_dialog_delete_callback), this); | |
9f41d601 | 134 | |
9dc44eff | 135 | m_wxwindow = wxPizza::New(); |
9f41d601 | 136 | gtk_widget_show( m_wxwindow ); |
9f41d601 RR |
137 | |
138 | gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); | |
139 | ||
140 | if (m_parent) m_parent->AddChild( this ); | |
141 | ||
142 | PostCreation(); | |
143 | ||
33c0d0ed RR |
144 | m_time = gtk_get_current_event_time(); |
145 | ||
9fa72bd2 MR |
146 | g_signal_connect (m_widget, "button_press_event", |
147 | G_CALLBACK (gtk_popup_button_press), this); | |
88d19775 | 148 | |
670f9935 | 149 | return true; |
9f41d601 RR |
150 | } |
151 | ||
152 | void wxPopupWindow::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) ) | |
153 | { | |
154 | wxFAIL_MSG( wxT("DoMoveWindow called for wxPopupWindow") ); | |
155 | } | |
156 | ||
157 | void wxPopupWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) | |
158 | { | |
159 | wxASSERT_MSG( (m_widget != NULL), wxT("invalid dialog") ); | |
160 | wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid dialog") ); | |
161 | ||
9f41d601 RR |
162 | int old_x = m_x; |
163 | int old_y = m_y; | |
164 | ||
165 | int old_width = m_width; | |
166 | int old_height = m_height; | |
167 | ||
cca410b3 | 168 | if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) |
9f41d601 | 169 | m_x = x; |
cca410b3 | 170 | if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) |
9f41d601 | 171 | m_y = y; |
cca410b3 | 172 | if (width != -1) |
9f41d601 | 173 | m_width = width; |
cca410b3 | 174 | if (height != -1) |
9f41d601 | 175 | m_height = height; |
9f41d601 | 176 | |
82008f15 | 177 | ConstrainSize(); |
9f41d601 RR |
178 | |
179 | if ((m_x != -1) || (m_y != -1)) | |
180 | { | |
181 | if ((m_x != old_x) || (m_y != old_y)) | |
182 | { | |
cd6645a2 | 183 | gtk_window_move( GTK_WINDOW(m_widget), m_x, m_y ); |
9f41d601 RR |
184 | } |
185 | } | |
186 | ||
187 | if ((m_width != old_width) || (m_height != old_height)) | |
188 | { | |
cca410b3 | 189 | // gtk_window_resize does not work for GTK_WINDOW_POPUP |
370dc79c | 190 | gtk_widget_set_size_request( m_widget, m_width, m_height ); |
cca410b3 PC |
191 | wxSizeEvent event(GetSize(), GetId()); |
192 | event.SetEventObject(this); | |
937013e0 | 193 | HandleWindowEvent(event); |
9f41d601 | 194 | } |
9f41d601 RR |
195 | } |
196 | ||
3591d10f RR |
197 | void wxPopupWindow::SetFocus() |
198 | { | |
199 | // set the focus to the first child who wants it | |
200 | wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); | |
201 | while ( node ) | |
202 | { | |
203 | wxWindow *child = node->GetData(); | |
204 | node = node->GetNext(); | |
205 | ||
206 | if ( child->CanAcceptFocus() && !child->IsTopLevel() ) | |
207 | { | |
208 | child->SetFocus(); | |
209 | return; | |
210 | } | |
211 | } | |
03647350 | 212 | |
3591d10f RR |
213 | wxPopupWindowBase::SetFocus(); |
214 | } | |
215 | ||
9f41d601 RR |
216 | bool wxPopupWindow::Show( bool show ) |
217 | { | |
cca410b3 | 218 | if (show && !IsShown()) |
9f41d601 | 219 | { |
cca410b3 PC |
220 | wxSizeEvent event(GetSize(), GetId()); |
221 | event.SetEventObject(this); | |
937013e0 | 222 | HandleWindowEvent(event); |
9f41d601 | 223 | } |
88d19775 | 224 | |
9f41d601 | 225 | bool ret = wxWindow::Show( show ); |
88d19775 | 226 | |
9f41d601 RR |
227 | return ret; |
228 | } | |
229 | ||
f3ecfad1 | 230 | #endif // wxUSE_POPUPWIN |