]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/window.cpp
Small Tex2RTF fixes; wxMotif compile fixes (motif.inc, wxCheckListBox);
[wxWidgets.git] / src / gtk / window.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: window.cpp
3// Purpose:
4// Author: Robert Roebling
c67d8618 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart
5e0aa05a 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation "window.h"
13#endif
14
15#include "wx/defs.h"
16#include "wx/window.h"
17#include "wx/dc.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/layout.h"
21#include "wx/utils.h"
22#include "wx/dialog.h"
23#include "wx/msgdlg.h"
06cfab17 24#if wxUSE_DRAG_AND_DROP
c801d85f 25#include "wx/dnd.h"
ac57418f 26#endif
cad880f5 27#if wxUSE_TOOLTIPS
b1170810 28#include "wx/tooltip.h"
cad880f5 29#endif
30dea054 30#include "wx/menu.h"
d4c99d6f 31#include "wx/statusbr.h"
b4071e91 32#include "wx/intl.h"
3bc755fc 33#include "wx/settings.h"
3069ac4e 34#include "wx/log.h"
b4071e91
RR
35
36#include <math.h>
c801d85f 37
83624f79
RR
38#include "gdk/gdk.h"
39#include "gtk/gtk.h"
40#include "gdk/gdkprivate.h"
41#include "gdk/gdkkeysyms.h"
42#include "wx/gtk/win_gtk.h"
43
868a2826
RR
44//-----------------------------------------------------------------------------
45// documentation on internals
46//-----------------------------------------------------------------------------
47
48/*
49 I have been asked several times about writing some documentation about
50 the GTK port of wxWindows, especially its internal structures. Obviously,
51 you cannot understand wxGTK without knowing a little about the GTK, but
47d67540 52 some more information about what the wxWindow, which is the base class
868a2826 53 for all other window classes, does seems required as well.
47d67540 54
868a2826 55 What does wxWindow do? It contains the common interface for the following
e380f72b 56 jobs of its descendants:
47d67540 57
868a2826 58 1) Define the rudimentary behaviour common to all window classes, such as
e380f72b
RR
59 resizing, intercepting user input (so as to make it possible to use these
60 events for special purposes in a derived class), window names etc.
868a2826
RR
61
62 2) Provide the possibility to contain and manage children, if the derived
63 class is allowed to contain children, which holds true for those window
e380f72b 64 classes which do not display a native GTK widget. To name them, these
868a2826 65 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
47d67540 66 work classes are a special case and are handled a bit differently from
e380f72b 67 the rest. The same holds true for the wxNotebook class.
47d67540 68
868a2826
RR
69 3) Provide the possibility to draw into a client area of a window. This,
70 too, only holds true for classes that do not display a native GTK widget
71 as above.
47d67540 72
e380f72b
RR
73 4) Provide the entire mechanism for scrolling widgets. This actual inter-
74 face for this is usually in wxScrolledWindow, but the GTK implementation
868a2826 75 is in this class.
47d67540 76
868a2826
RR
77 5) A multitude of helper or extra methods for special purposes, such as
78 Drag'n'Drop, managing validators etc.
47d67540 79
e380f72b
RR
80 Normally one might expect, that one wxWindows window would always correspond
81 to one GTK widget. Under GTK, there is no such allround widget that has all
868a2826
RR
82 the functionality. Moreover, the GTK defines a client area as a different
83 widget from the actual widget you are handling. Last but not least some
84 special classes (e.g. wxFrame) handle different categories of widgets and
85 still have the possibility to draw something in the client area.
86 It was therefore required to write a special purpose GTK widget, that would
87 represent a client area in the sense of wxWindows capable to do the jobs
88 2), 3) and 4). I have written this class and it resides in win_gtk.c of
89 this directory.
47d67540 90
868a2826 91 All windows must have a widget, with which they interact with other under-
e380f72b 92 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
868a2826 93 thw wxWindow class has a member variable called m_widget which holds a
e380f72b
RR
94 pointer to this widget. When the window class represents a GTK native widget,
95 this is (in most cases) the only GTK widget the class manages. E.g. the
96 wxStatitText class handles only a GtkLabel widget a pointer to which you
97 can find in m_widget (defined in wxWindow)
8bbe427f 98
e380f72b 99 When the class has a client area for drawing into and for containing children
8bbe427f
VZ
100 it has to handle the client area widget (of the type GtkMyFixed, defined in
101 win_gtk.c), but there could be any number of widgets, handled by a class
102 The common rule for all windows is only, that the widget that interacts with
103 the rest of GTK must be referenced in m_widget and all other widgets must be
104 children of this widget on the GTK level. The top-most widget, which also
105 represents the client area, must be in the m_wxwindow field and must be of
e380f72b 106 the type GtkMyFixed.
47d67540 107
868a2826
RR
108 As I said, the window classes that display a GTK native widget only have
109 one widget, so in the case of e.g. the wxButton class m_widget holds a
110 pointer to a GtkButton widget. But windows with client areas (for drawing
111 and children) have a m_widget field that is a pointer to a GtkScrolled-
112 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
113 one is (in the GTK sense) a child of the GtkScrolledWindow.
47d67540 114
868a2826
RR
115 If the m_wxwindow field is set, then all input to this widget is inter-
116 cepted and sent to the wxWindows class. If not, all input to the widget
117 that gets pointed to by m_widget gets intercepted and sent to the class.
118
119*/
120
38c7b3d3
RR
121//-------------------------------------------------------------------------
122// conditional compilation
123//-------------------------------------------------------------------------
124
125#if (GTK_MINOR_VERSION == 1)
126#if (GTK_MICRO_VERSION >= 5)
127#define NEW_GTK_SCROLL_CODE
128#endif
129#endif
130
b292e2f5
RR
131//-----------------------------------------------------------------------------
132// (debug)
133//-----------------------------------------------------------------------------
134
135#ifdef __WXDEBUG__
136
ff8bfdbb
VZ
137static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
138 GdkEvent *WXUNUSED(event),
139 const char *name )
b292e2f5
RR
140{
141 printf( "FOCUS NOW AT: " );
142 printf( name );
143 printf( "\n" );
ff8bfdbb 144
b292e2f5
RR
145 return FALSE;
146}
147
148void debug_focus_in( GtkWidget* widget, const char* name, const char *window )
149{
150 return;
151
152 wxString tmp = name;
153 tmp += " FROM ";
154 tmp += window;
ff8bfdbb 155
b292e2f5 156 char *s = new char[tmp.Length()+1];
ff8bfdbb 157
b292e2f5
RR
158 strcpy( s, WXSTRINGCAST tmp );
159
160 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
161 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
162}
163
164#endif
165
c801d85f
KB
166//-----------------------------------------------------------------------------
167// data
168//-----------------------------------------------------------------------------
169
b292e2f5
RR
170extern wxList wxPendingDelete;
171extern wxList wxTopLevelWindows;
172extern bool g_blockEventsOnDrag;
173extern bool g_blockEventsOnScroll;
174static bool g_capturing = FALSE;
175static wxWindow *g_focusWindow = (wxWindow*) NULL;
47d67540
VZ
176
177// hack: we need something to pass to gtk_menu_popup, so we store the time of
178// the last click here
179static guint32 gs_timeLastClick = 0;
c801d85f
KB
180
181//-----------------------------------------------------------------------------
2f2aa628 182// "expose_event" (of m_wxwindow, not of m_widget)
c801d85f
KB
183//-----------------------------------------------------------------------------
184
2f2aa628 185static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
47d67540 186{
f5e27805 187 if (!win->HasVMT()) return;
47d67540 188
f5e27805
RR
189 win->m_updateRegion.Union( gdk_event->area.x,
190 gdk_event->area.y,
191 gdk_event->area.width,
192 gdk_event->area.height );
47d67540 193
f5e27805 194 if (gdk_event->count > 0) return;
c801d85f 195
d8c83875 196/*
f5e27805
RR
197 printf( "OnExpose from " );
198 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
199 printf( win->GetClassInfo()->GetClassName() );
200 printf( ".\n" );
d8c83875
RR
201*/
202
f5e27805
RR
203 wxPaintEvent event( win->GetId() );
204 event.SetEventObject( win );
205 win->GetEventHandler()->ProcessEvent( event );
47d67540 206
f5e27805 207 win->m_updateRegion.Clear();
362c6693 208}
c801d85f
KB
209
210//-----------------------------------------------------------------------------
2f2aa628
RR
211// "draw" (of m_wxwindow, not of m_widget)
212//-----------------------------------------------------------------------------
c801d85f 213
2f2aa628 214static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxWindow *win )
47d67540 215{
f5e27805 216 if (!win->HasVMT()) return;
47d67540 217
f5e27805 218 win->m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
47d67540 219
f5e27805
RR
220 wxPaintEvent event( win->GetId() );
221 event.SetEventObject( win );
222 win->GetEventHandler()->ProcessEvent( event );
47d67540 223
f5e27805 224 win->m_updateRegion.Clear();
362c6693 225}
c801d85f
KB
226
227//-----------------------------------------------------------------------------
b292e2f5 228// "key_press_event" from any window
c801d85f 229//-----------------------------------------------------------------------------
c801d85f 230
2f2aa628 231static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
47d67540 232{
f5e27805
RR
233 if (!win->HasVMT()) return FALSE;
234 if (g_blockEventsOnDrag) return FALSE;
c801d85f 235
7be4c594 236/*
f5e27805
RR
237 printf( "OnKeyPress from " );
238 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
239 printf( win->GetClassInfo()->GetClassName() );
240 printf( ".\n" );
7be4c594 241*/
c801d85f 242
f5e27805
RR
243 long key_code = 0;
244 switch (gdk_event->keyval)
c801d85f 245 {
f5e27805 246 case GDK_BackSpace: key_code = WXK_BACK; break;
5664fc32
RR
247 case GDK_ISO_Left_Tab:
248 case GDK_KP_Tab:
f5e27805
RR
249 case GDK_Tab: key_code = WXK_TAB; break;
250 case GDK_Linefeed: key_code = WXK_RETURN; break;
251 case GDK_Clear: key_code = WXK_CLEAR; break;
252 case GDK_Return: key_code = WXK_RETURN; break;
253 case GDK_Pause: key_code = WXK_PAUSE; break;
254 case GDK_Scroll_Lock: key_code = WXK_SCROLL; break;
255 case GDK_Escape: key_code = WXK_ESCAPE; break;
256 case GDK_Delete: key_code = WXK_DELETE; break;
257 case GDK_Home: key_code = WXK_HOME; break;
258 case GDK_Left: key_code = WXK_LEFT; break;
259 case GDK_Up: key_code = WXK_UP; break;
260 case GDK_Right: key_code = WXK_RIGHT; break;
261 case GDK_Down: key_code = WXK_DOWN; break;
262 case GDK_Prior: key_code = WXK_PRIOR; break;
263// case GDK_Page_Up: key_code = WXK_PAGEUP; break;
264 case GDK_Next: key_code = WXK_NEXT; break;
265// case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
266 case GDK_End: key_code = WXK_END; break;
267 case GDK_Begin: key_code = WXK_HOME; break;
268 case GDK_Select: key_code = WXK_SELECT; break;
269 case GDK_Print: key_code = WXK_PRINT; break;
270 case GDK_Execute: key_code = WXK_EXECUTE; break;
271 case GDK_Insert: key_code = WXK_INSERT; break;
272 case GDK_Num_Lock: key_code = WXK_NUMLOCK; break;
f5e27805
RR
273 case GDK_KP_Enter: key_code = WXK_RETURN; break;
274 case GDK_KP_Home: key_code = WXK_HOME; break;
275 case GDK_KP_Left: key_code = WXK_LEFT; break;
276 case GDK_KP_Up: key_code = WXK_UP; break;
277 case GDK_KP_Right: key_code = WXK_RIGHT; break;
278 case GDK_KP_Down: key_code = WXK_DOWN; break;
279 case GDK_KP_Prior: key_code = WXK_PRIOR; break;
280// case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
281 case GDK_KP_Next: key_code = WXK_NEXT; break;
282// case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
283 case GDK_KP_End: key_code = WXK_END; break;
284 case GDK_KP_Begin: key_code = WXK_HOME; break;
285 case GDK_KP_Insert: key_code = WXK_INSERT; break;
286 case GDK_KP_Delete: key_code = WXK_DELETE; break;
287 case GDK_KP_Multiply: key_code = WXK_MULTIPLY; break;
288 case GDK_KP_Add: key_code = WXK_ADD; break;
289 case GDK_KP_Separator: key_code = WXK_SEPARATOR; break;
290 case GDK_KP_Subtract: key_code = WXK_SUBTRACT; break;
291 case GDK_KP_Decimal: key_code = WXK_DECIMAL; break;
292 case GDK_KP_Divide: key_code = WXK_DIVIDE; break;
293 case GDK_KP_0: key_code = WXK_NUMPAD0; break;
294 case GDK_KP_1: key_code = WXK_NUMPAD1; break;
295 case GDK_KP_2: key_code = WXK_NUMPAD2; break;
296 case GDK_KP_3: key_code = WXK_NUMPAD3; break;
297 case GDK_KP_4: key_code = WXK_NUMPAD4; break;
298 case GDK_KP_5: key_code = WXK_NUMPAD5; break;
299 case GDK_KP_6: key_code = WXK_NUMPAD6; break;
300 case GDK_KP_7: key_code = WXK_NUMPAD7; break;
301 case GDK_KP_8: key_code = WXK_NUMPAD7; break;
302 case GDK_KP_9: key_code = WXK_NUMPAD9; break;
303 case GDK_F1: key_code = WXK_F1; break;
304 case GDK_F2: key_code = WXK_F2; break;
305 case GDK_F3: key_code = WXK_F3; break;
306 case GDK_F4: key_code = WXK_F4; break;
307 case GDK_F5: key_code = WXK_F5; break;
308 case GDK_F6: key_code = WXK_F6; break;
309 case GDK_F7: key_code = WXK_F7; break;
310 case GDK_F8: key_code = WXK_F8; break;
311 case GDK_F9: key_code = WXK_F9; break;
312 case GDK_F10: key_code = WXK_F10; break;
313 case GDK_F11: key_code = WXK_F11; break;
314 case GDK_F12: key_code = WXK_F12; break;
315 default:
316 {
317 if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF))
318 key_code = gdk_event->keyval;
319 }
362c6693 320 }
c801d85f 321
f5e27805 322 if (!key_code) return FALSE;
47d67540 323
b666df2c 324 wxKeyEvent event( wxEVT_KEY_DOWN );
f5e27805
RR
325 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
326 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
327 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
328 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
329 event.m_keyCode = key_code;
330 event.m_x = 0;
331 event.m_y = 0;
332 event.SetEventObject( win );
47d67540 333
f5e27805 334 bool ret = win->GetEventHandler()->ProcessEvent( event );
47d67540 335
f5e27805 336 if (!ret)
47d67540 337 {
f5e27805
RR
338 wxWindow *ancestor = win;
339 while (ancestor)
340 {
341 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
342 if (command != -1)
343 {
344 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
345 ret = ancestor->GetEventHandler()->ProcessEvent( command_event );
346 break;
347 }
348 ancestor = ancestor->GetParent();
349 }
bcf1fa6b 350 }
ff8bfdbb 351
b292e2f5 352 // win is a control: tab can be propagated up
5664fc32
RR
353 if ( (!ret) &&
354 ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
355 ((win->m_windowStyle & wxTE_PROCESS_TAB) == 0))
b292e2f5
RR
356 {
357 wxNavigationKeyEvent new_event;
b98d804b 358 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
5664fc32 359 new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
b98d804b
RR
360 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
361 new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
b292e2f5 362 new_event.SetCurrentFocus( win );
ff8bfdbb 363 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5 364 }
ff8bfdbb 365
b98d804b
RR
366 if ( (!ret) &&
367 (gdk_event->keyval == GDK_Escape) )
368 {
369 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
370 new_event.SetEventObject( win );
371 ret = win->GetEventHandler()->ProcessEvent( new_event );
372 }
373
b292e2f5 374/*
b98d804b
RR
375 Damn, I forgot why this didn't work, but it didn't work.
376
b292e2f5
RR
377 // win is a panel: up can be propagated to the panel
378 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
379 (gdk_event->keyval == GDK_Up))
380 {
381 win->m_parent->SetFocus();
ff8bfdbb 382 ret = TRUE;
b292e2f5 383 }
ff8bfdbb 384
b292e2f5 385 // win is a panel: left/right can be propagated to the panel
ff8bfdbb
VZ
386 if ((!ret) && (win->m_wxwindow) &&
387 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
b292e2f5
RR
388 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
389 {
390 wxNavigationKeyEvent new_event;
391 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
392 new_event.SetCurrentFocus( win );
ff8bfdbb 393 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5
RR
394 }
395*/
ff8bfdbb 396
f5e27805
RR
397 if (ret)
398 {
b292e2f5 399 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
f5e27805 400 }
47d67540 401
f5e27805 402 return ret;
362c6693 403}
c801d85f 404
b666df2c
RR
405//-----------------------------------------------------------------------------
406// "key_release_event" from any window
407//-----------------------------------------------------------------------------
408
409static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
410{
411 if (!win->HasVMT()) return FALSE;
412 if (g_blockEventsOnDrag) return FALSE;
413
414/*
415 printf( "OnKeyRelease from " );
416 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
417 printf( win->GetClassInfo()->GetClassName() );
418 printf( ".\n" );
419*/
420
421 long key_code = 0;
422 switch (gdk_event->keyval)
423 {
424 case GDK_BackSpace: key_code = WXK_BACK; break;
5664fc32
RR
425 case GDK_ISO_Left_Tab:
426 case GDK_KP_Tab:
b666df2c
RR
427 case GDK_Tab: key_code = WXK_TAB; break;
428 case GDK_Linefeed: key_code = WXK_RETURN; break;
429 case GDK_Clear: key_code = WXK_CLEAR; break;
430 case GDK_Return: key_code = WXK_RETURN; break;
431 case GDK_Pause: key_code = WXK_PAUSE; break;
432 case GDK_Scroll_Lock: key_code = WXK_SCROLL; break;
433 case GDK_Escape: key_code = WXK_ESCAPE; break;
434 case GDK_Delete: key_code = WXK_DELETE; break;
435 case GDK_Home: key_code = WXK_HOME; break;
436 case GDK_Left: key_code = WXK_LEFT; break;
437 case GDK_Up: key_code = WXK_UP; break;
438 case GDK_Right: key_code = WXK_RIGHT; break;
439 case GDK_Down: key_code = WXK_DOWN; break;
440 case GDK_Prior: key_code = WXK_PRIOR; break;
441// case GDK_Page_Up: key_code = WXK_PAGEUP; break;
442 case GDK_Next: key_code = WXK_NEXT; break;
443// case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
444 case GDK_End: key_code = WXK_END; break;
445 case GDK_Begin: key_code = WXK_HOME; break;
446 case GDK_Select: key_code = WXK_SELECT; break;
447 case GDK_Print: key_code = WXK_PRINT; break;
448 case GDK_Execute: key_code = WXK_EXECUTE; break;
449 case GDK_Insert: key_code = WXK_INSERT; break;
450 case GDK_Num_Lock: key_code = WXK_NUMLOCK; break;
b666df2c
RR
451 case GDK_KP_Enter: key_code = WXK_RETURN; break;
452 case GDK_KP_Home: key_code = WXK_HOME; break;
453 case GDK_KP_Left: key_code = WXK_LEFT; break;
454 case GDK_KP_Up: key_code = WXK_UP; break;
455 case GDK_KP_Right: key_code = WXK_RIGHT; break;
456 case GDK_KP_Down: key_code = WXK_DOWN; break;
457 case GDK_KP_Prior: key_code = WXK_PRIOR; break;
458// case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
459 case GDK_KP_Next: key_code = WXK_NEXT; break;
460// case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
461 case GDK_KP_End: key_code = WXK_END; break;
462 case GDK_KP_Begin: key_code = WXK_HOME; break;
463 case GDK_KP_Insert: key_code = WXK_INSERT; break;
464 case GDK_KP_Delete: key_code = WXK_DELETE; break;
465 case GDK_KP_Multiply: key_code = WXK_MULTIPLY; break;
466 case GDK_KP_Add: key_code = WXK_ADD; break;
467 case GDK_KP_Separator: key_code = WXK_SEPARATOR; break;
468 case GDK_KP_Subtract: key_code = WXK_SUBTRACT; break;
469 case GDK_KP_Decimal: key_code = WXK_DECIMAL; break;
470 case GDK_KP_Divide: key_code = WXK_DIVIDE; break;
471 case GDK_KP_0: key_code = WXK_NUMPAD0; break;
472 case GDK_KP_1: key_code = WXK_NUMPAD1; break;
473 case GDK_KP_2: key_code = WXK_NUMPAD2; break;
474 case GDK_KP_3: key_code = WXK_NUMPAD3; break;
475 case GDK_KP_4: key_code = WXK_NUMPAD4; break;
476 case GDK_KP_5: key_code = WXK_NUMPAD5; break;
477 case GDK_KP_6: key_code = WXK_NUMPAD6; break;
478 case GDK_KP_7: key_code = WXK_NUMPAD7; break;
479 case GDK_KP_8: key_code = WXK_NUMPAD7; break;
480 case GDK_KP_9: key_code = WXK_NUMPAD9; break;
481 case GDK_F1: key_code = WXK_F1; break;
482 case GDK_F2: key_code = WXK_F2; break;
483 case GDK_F3: key_code = WXK_F3; break;
484 case GDK_F4: key_code = WXK_F4; break;
485 case GDK_F5: key_code = WXK_F5; break;
486 case GDK_F6: key_code = WXK_F6; break;
487 case GDK_F7: key_code = WXK_F7; break;
488 case GDK_F8: key_code = WXK_F8; break;
489 case GDK_F9: key_code = WXK_F9; break;
490 case GDK_F10: key_code = WXK_F10; break;
491 case GDK_F11: key_code = WXK_F11; break;
492 case GDK_F12: key_code = WXK_F12; break;
493 default:
494 {
495 if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF))
496 key_code = gdk_event->keyval;
497 }
498 }
499
500 if (!key_code) return FALSE;
501
502 wxKeyEvent event( wxEVT_KEY_UP );
503 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
504 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
505 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
506 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
507 event.m_keyCode = key_code;
508 event.m_x = 0;
509 event.m_y = 0;
510 event.SetEventObject( win );
511
512 bool ret = win->GetEventHandler()->ProcessEvent( event );
513
514 if (ret)
515 {
b98d804b 516 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" );
b666df2c
RR
517 }
518
519 return ret;
520}
521
c801d85f 522//-----------------------------------------------------------------------------
2f2aa628
RR
523// "button_press_event"
524//-----------------------------------------------------------------------------
c801d85f 525
2f2aa628 526static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
903f689b 527{
f5e27805 528 if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
47d67540 529
f5e27805 530 if (g_blockEventsOnDrag) return TRUE;
76ed8f8d 531 if (g_blockEventsOnScroll) return TRUE;
c801d85f 532
f5e27805 533 if (win->m_wxwindow)
c801d85f 534 {
f5e27805
RR
535 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
536 {
537 gtk_widget_grab_focus (win->m_wxwindow);
47d67540 538
c801d85f 539/*
f5e27805
RR
540 printf( "GrabFocus from " );
541 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
542 printf( win->GetClassInfo()->GetClassName() );
543 printf( ".\n" );
c801d85f 544*/
47d67540 545
f5e27805 546 }
362c6693 547 }
47d67540 548
f5e27805 549 if (!win->HasVMT()) return TRUE;
97b3455a 550
8429bec1 551/*
f5e27805
RR
552 printf( "OnButtonPress from " );
553 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
554 printf( win->GetClassInfo()->GetClassName() );
555 printf( ".\n" );
8429bec1 556*/
30dea054 557
f5e27805 558 wxEventType event_type = wxEVT_LEFT_DOWN;
47d67540 559
f5e27805 560 if (gdk_event->button == 1)
c801d85f 561 {
f5e27805
RR
562 switch (gdk_event->type)
563 {
564 case GDK_BUTTON_PRESS: event_type = wxEVT_LEFT_DOWN; break;
565 case GDK_2BUTTON_PRESS: event_type = wxEVT_LEFT_DCLICK; break;
566 default: break;
567 }
362c6693 568 }
f5e27805 569 else if (gdk_event->button == 2)
c801d85f 570 {
f5e27805
RR
571 switch (gdk_event->type)
572 {
573 case GDK_BUTTON_PRESS: event_type = wxEVT_MIDDLE_DOWN; break;
574 case GDK_2BUTTON_PRESS: event_type = wxEVT_MIDDLE_DCLICK; break;
575 default: break;
576 }
362c6693 577 }
f5e27805 578 else if (gdk_event->button == 3)
c801d85f 579 {
f5e27805
RR
580 switch (gdk_event->type)
581 {
582 case GDK_BUTTON_PRESS: event_type = wxEVT_RIGHT_DOWN; break;
583 case GDK_2BUTTON_PRESS: event_type = wxEVT_RIGHT_DCLICK; break;
584 default: break;
585 }
362c6693 586 }
47d67540 587
f5e27805
RR
588 wxMouseEvent event( event_type );
589 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
590 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
591 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
592 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
593 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
594 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
595 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
47d67540 596
f5e27805
RR
597 event.m_x = (long)gdk_event->x;
598 event.m_y = (long)gdk_event->y;
47d67540 599
f5e27805
RR
600 // Some control don't have their own X window and thus cannot get
601 // any events.
47d67540 602
f5e27805 603 if (!g_capturing)
2f2aa628 604 {
db1b4961 605 wxNode *node = win->GetChildren().First();
f5e27805
RR
606 while (node)
607 {
608 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb
VZ
609
610 if (child->m_isStaticBox)
611 {
612 // wxStaticBox is transparent in the box itself
613 int x = event.m_x;
614 int y = event.m_y;
615 int xx1 = child->m_x;
616 int yy1 = child->m_y;
617 int xx2 = child->m_x + child->m_width;
618 int yy2 = child->m_x + child->m_height;
619
620 // left
621 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
622 // right
623 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
624 // top
625 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
626 // bottom
627 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
628 {
1ecc4d80
RR
629 win = child;
630 event.m_x -= child->m_x;
631 event.m_y -= child->m_y;
632 break;
ff8bfdbb
VZ
633 }
634
635 }
636 else
637 {
1ecc4d80 638 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
ff8bfdbb 639 (child->m_x <= event.m_x) &&
1ecc4d80
RR
640 (child->m_y <= event.m_y) &&
641 (child->m_x+child->m_width >= event.m_x) &&
642 (child->m_y+child->m_height >= event.m_y))
643 {
644 win = child;
645 event.m_x -= child->m_x;
646 event.m_y -= child->m_y;
647 break;
ff8bfdbb 648 }
f5e27805
RR
649 }
650 node = node->Next();
651 }
2f2aa628 652 }
ff8bfdbb 653
0c77152e
RR
654 wxPoint pt(win->GetClientAreaOrigin());
655 event.m_x -= pt.x;
656 event.m_y -= pt.y;
47d67540 657
f5e27805 658 event.SetEventObject( win );
47d67540 659
f5e27805 660 gs_timeLastClick = gdk_event->time;
47d67540 661
f5e27805
RR
662 if (win->GetEventHandler()->ProcessEvent( event ))
663 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" );
47d67540 664
f5e27805 665 return TRUE;
362c6693 666}
c801d85f
KB
667
668//-----------------------------------------------------------------------------
97b3455a 669// "button_release_event"
2f2aa628 670//-----------------------------------------------------------------------------
c801d85f 671
2f2aa628 672static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
47d67540 673{
f5e27805 674 if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
47d67540 675
f5e27805 676 if (g_blockEventsOnDrag) return TRUE;
76ed8f8d 677 if (g_blockEventsOnScroll) return TRUE;
c801d85f 678
f5e27805 679 if (!win->HasVMT()) return TRUE;
47d67540 680
c801d85f 681/*
f5e27805
RR
682 printf( "OnButtonRelease from " );
683 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
684 printf( win->GetClassInfo()->GetClassName() );
685 printf( ".\n" );
c801d85f 686*/
47d67540 687
f5e27805 688 wxEventType event_type = wxEVT_NULL;
47d67540 689
f5e27805
RR
690 switch (gdk_event->button)
691 {
692 case 1: event_type = wxEVT_LEFT_UP; break;
693 case 2: event_type = wxEVT_MIDDLE_UP; break;
694 case 3: event_type = wxEVT_RIGHT_UP; break;
695 }
47d67540 696
f5e27805
RR
697 wxMouseEvent event( event_type );
698 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
699 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
700 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
701 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
702 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
703 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
704 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
705 event.m_x = (long)gdk_event->x;
706 event.m_y = (long)gdk_event->y;
707
708 // Some control don't have their own X window and thus cannot get
709 // any events.
710
711 if (!g_capturing)
2f2aa628 712 {
db1b4961 713 wxNode *node = win->GetChildren().First();
f5e27805
RR
714 while (node)
715 {
716 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb
VZ
717
718 if (child->m_isStaticBox)
719 {
720 // wxStaticBox is transparent in the box itself
721 int x = event.m_x;
722 int y = event.m_y;
723 int xx1 = child->m_x;
724 int yy1 = child->m_y;
725 int xx2 = child->m_x + child->m_width;
726 int yy2 = child->m_x + child->m_height;
727
728 // left
729 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
730 // right
731 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
732 // top
733 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
734 // bottom
735 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
736 {
1ecc4d80
RR
737 win = child;
738 event.m_x -= child->m_x;
739 event.m_y -= child->m_y;
740 break;
ff8bfdbb
VZ
741 }
742
743 }
744 else
745 {
1ecc4d80 746 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
ff8bfdbb 747 (child->m_x <= event.m_x) &&
1ecc4d80
RR
748 (child->m_y <= event.m_y) &&
749 (child->m_x+child->m_width >= event.m_x) &&
750 (child->m_y+child->m_height >= event.m_y))
751 {
752 win = child;
753 event.m_x -= child->m_x;
754 event.m_y -= child->m_y;
755 break;
ff8bfdbb 756 }
f5e27805
RR
757 }
758 node = node->Next();
759 }
2f2aa628 760 }
47d67540 761
0c77152e
RR
762 wxPoint pt(win->GetClientAreaOrigin());
763 event.m_x -= pt.x;
764 event.m_y -= pt.y;
765
f5e27805 766 event.SetEventObject( win );
47d67540 767
f5e27805
RR
768 if (win->GetEventHandler()->ProcessEvent( event ))
769 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" );
47d67540 770
f5e27805 771 return TRUE;
362c6693 772}
c801d85f
KB
773
774//-----------------------------------------------------------------------------
2f2aa628
RR
775// "motion_notify_event"
776//-----------------------------------------------------------------------------
c801d85f 777
2f2aa628 778static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
47d67540 779{
ff8bfdbb 780 if (gdk_event->is_hint)
aae24d21
RR
781 {
782 int x = 0;
783 int y = 0;
784 GdkModifierType state;
785 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
786 gdk_event->x = x;
787 gdk_event->y = y;
788 gdk_event->state = state;
789 }
ff8bfdbb 790
e380f72b 791 if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
47d67540 792
e380f72b 793 if (g_blockEventsOnDrag) return TRUE;
76ed8f8d 794 if (g_blockEventsOnScroll) return TRUE;
8bbe427f 795
e380f72b 796 if (!win->HasVMT()) return TRUE;
47d67540 797
c801d85f 798/*
e380f72b
RR
799 printf( "OnMotion from " );
800 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
801 printf( win->GetClassInfo()->GetClassName() );
802 printf( ".\n" );
aae24d21 803*/
47d67540 804
e380f72b
RR
805 wxMouseEvent event( wxEVT_MOTION );
806 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
807 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
808 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
809 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
810 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
811 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
812 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
813
814 event.m_x = (long)gdk_event->x;
815 event.m_y = (long)gdk_event->y;
816
817 // Some control don't have their own X window and thus cannot get
818 // any events.
819
820 if (!g_capturing)
2f2aa628 821 {
db1b4961 822 wxNode *node = win->GetChildren().First();
e380f72b
RR
823 while (node)
824 {
825 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb
VZ
826
827 if (child->m_isStaticBox)
828 {
829 // wxStaticBox is transparent in the box itself
830 int x = event.m_x;
831 int y = event.m_y;
832 int xx1 = child->m_x;
833 int yy1 = child->m_y;
834 int xx2 = child->m_x + child->m_width;
835 int yy2 = child->m_x + child->m_height;
836
837 // left
838 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
839 // right
840 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
841 // top
842 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
843 // bottom
844 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
845 {
1ecc4d80
RR
846 win = child;
847 event.m_x -= child->m_x;
848 event.m_y -= child->m_y;
849 break;
ff8bfdbb
VZ
850 }
851
852 }
853 else
854 {
1ecc4d80 855 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
ff8bfdbb 856 (child->m_x <= event.m_x) &&
1ecc4d80
RR
857 (child->m_y <= event.m_y) &&
858 (child->m_x+child->m_width >= event.m_x) &&
859 (child->m_y+child->m_height >= event.m_y))
860 {
861 win = child;
862 event.m_x -= child->m_x;
863 event.m_y -= child->m_y;
864 break;
ff8bfdbb 865 }
e380f72b
RR
866 }
867 node = node->Next();
868 }
2f2aa628 869 }
47d67540 870
0c77152e
RR
871 wxPoint pt(win->GetClientAreaOrigin());
872 event.m_x -= pt.x;
873 event.m_y -= pt.y;
874
e380f72b 875 event.SetEventObject( win );
47d67540 876
e380f72b
RR
877 if (win->GetEventHandler()->ProcessEvent( event ))
878 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" );
47d67540 879
e380f72b 880 return TRUE;
362c6693 881}
c801d85f
KB
882
883//-----------------------------------------------------------------------------
2f2aa628
RR
884// "focus_in_event"
885//-----------------------------------------------------------------------------
c801d85f 886
2f2aa628 887static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 888{
e380f72b 889 if (g_blockEventsOnDrag) return TRUE;
ff8bfdbb 890
b292e2f5 891 g_focusWindow = win;
ff8bfdbb 892
e380f72b 893 if (win->m_wxwindow)
c801d85f 894 {
e380f72b
RR
895 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
896 {
897 GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
47d67540 898/*
e380f72b
RR
899 printf( "SetFocus flag from " );
900 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
901 printf( win->GetClassInfo()->GetClassName() );
902 printf( ".\n" );
c801d85f 903*/
e380f72b 904 }
362c6693 905 }
47d67540 906
e380f72b 907 if (!win->HasVMT()) return TRUE;
47d67540 908
c801d85f 909/*
e380f72b
RR
910 printf( "OnSetFocus from " );
911 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
912 printf( win->GetClassInfo()->GetClassName() );
913 printf( " " );
914 printf( WXSTRINGCAST win->GetLabel() );
915 printf( ".\n" );
c801d85f 916*/
47d67540 917
e380f72b
RR
918 wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
919 event.SetEventObject( win );
47d67540 920
e380f72b
RR
921 if (win->GetEventHandler()->ProcessEvent( event ))
922 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
47d67540 923
e380f72b 924 return TRUE;
362c6693 925}
c801d85f
KB
926
927//-----------------------------------------------------------------------------
2f2aa628
RR
928// "focus_out_event"
929//-----------------------------------------------------------------------------
c801d85f 930
2f2aa628 931static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 932{
e380f72b
RR
933 if (g_blockEventsOnDrag) return TRUE;
934 if (win->m_wxwindow)
935 {
936 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
937 GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
938 }
47d67540 939
e380f72b 940 if (!win->HasVMT()) return TRUE;
47d67540 941
c801d85f 942/*
e380f72b
RR
943 printf( "OnKillFocus from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
946 printf( ".\n" );
c801d85f 947*/
47d67540 948
e380f72b
RR
949 wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
950 event.SetEventObject( win );
47d67540 951
e380f72b
RR
952 if (win->GetEventHandler()->ProcessEvent( event ))
953 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
2f2aa628 954
e380f72b 955 return TRUE;
362c6693 956}
c801d85f 957
b4071e91
RR
958//-----------------------------------------------------------------------------
959// "enter_notify_event"
960//-----------------------------------------------------------------------------
961
962static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
963{
e380f72b 964 if (g_blockEventsOnDrag) return TRUE;
47d67540 965
b292e2f5
RR
966 if ((widget->window) && (win->m_cursor))
967 gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() );
968
969 if (widget->window != gdk_event->window) return TRUE;
970
e380f72b 971 if (!win->HasVMT()) return TRUE;
47d67540 972
d8c83875 973/*
e380f72b
RR
974 printf( "OnEnter from " );
975 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
976 printf( win->GetClassInfo()->GetClassName() );
977 printf( ".\n" );
d8c83875 978*/
47d67540 979
e380f72b
RR
980 wxMouseEvent event( wxEVT_ENTER_WINDOW );
981 event.SetEventObject( win );
ff8bfdbb 982
4a33eba6
RR
983 int x = 0;
984 int y = 0;
985 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 986
4a33eba6 987 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 988
4a33eba6
RR
989 event.m_shiftDown = (state & GDK_SHIFT_MASK);
990 event.m_controlDown = (state & GDK_CONTROL_MASK);
991 event.m_altDown = (state & GDK_MOD1_MASK);
992 event.m_metaDown = (state & GDK_MOD2_MASK);
993 event.m_leftDown = (state & GDK_BUTTON1_MASK);
994 event.m_middleDown = (state & GDK_BUTTON2_MASK);
995 event.m_rightDown = (state & GDK_BUTTON3_MASK);
996
997 event.m_x = (long)x;
998 event.m_y = (long)y;
ff8bfdbb 999
0c77152e
RR
1000 wxPoint pt(win->GetClientAreaOrigin());
1001 event.m_x -= pt.x;
1002 event.m_y -= pt.y;
1003
e380f72b
RR
1004 if (win->GetEventHandler()->ProcessEvent( event ))
1005 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" );
47d67540 1006
e380f72b 1007 return TRUE;
b4071e91 1008}
47d67540 1009
b4071e91
RR
1010//-----------------------------------------------------------------------------
1011// "leave_notify_event"
1012//-----------------------------------------------------------------------------
1013
1014static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1015{
e380f72b 1016 if (g_blockEventsOnDrag) return TRUE;
47d67540 1017
b292e2f5
RR
1018 if ((widget->window) && (win->m_cursor))
1019 gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
1020
1021 if (widget->window != gdk_event->window) return TRUE;
1022
e380f72b 1023 if (!win->HasVMT()) return TRUE;
47d67540 1024
d8c83875 1025/*
e380f72b
RR
1026 printf( "OnLeave from " );
1027 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1028 printf( win->GetClassInfo()->GetClassName() );
1029 printf( ".\n" );
d8c83875 1030*/
47d67540 1031
e380f72b
RR
1032 wxMouseEvent event( wxEVT_LEAVE_WINDOW );
1033 event.SetEventObject( win );
47d67540 1034
4a33eba6
RR
1035 int x = 0;
1036 int y = 0;
1037 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1038
4a33eba6 1039 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1040
4a33eba6
RR
1041 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1042 event.m_controlDown = (state & GDK_CONTROL_MASK);
1043 event.m_altDown = (state & GDK_MOD1_MASK);
1044 event.m_metaDown = (state & GDK_MOD2_MASK);
1045 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1046 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1047 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1048
1049 event.m_x = (long)x;
1050 event.m_y = (long)y;
ff8bfdbb 1051
0c77152e
RR
1052 wxPoint pt(win->GetClientAreaOrigin());
1053 event.m_x -= pt.x;
1054 event.m_y -= pt.y;
1055
e380f72b
RR
1056 if (win->GetEventHandler()->ProcessEvent( event ))
1057 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" );
47d67540 1058
e380f72b 1059 return TRUE;
b4071e91 1060}
47d67540 1061
c801d85f 1062//-----------------------------------------------------------------------------
2f2aa628
RR
1063// "value_changed" from m_vAdjust
1064//-----------------------------------------------------------------------------
c801d85f 1065
2f2aa628 1066static void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
c801d85f 1067{
e380f72b 1068 if (g_blockEventsOnDrag) return;
c801d85f
KB
1069
1070/*
e380f72b
RR
1071 printf( "OnVScroll from " );
1072 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1073 printf( win->GetClassInfo()->GetClassName() );
1074 printf( ".\n" );
c801d85f 1075*/
47d67540 1076
e380f72b 1077 if (!win->HasVMT()) return;
47d67540 1078
e380f72b
RR
1079 float diff = win->m_vAdjust->value - win->m_oldVerticalPos;
1080 if (fabs(diff) < 0.2) return;
47d67540 1081
e380f72b 1082 wxEventType command = wxEVT_NULL;
47d67540 1083
e380f72b
RR
1084 float line_step = win->m_vAdjust->step_increment;
1085 float page_step = win->m_vAdjust->page_increment;
47d67540 1086
76ed8f8d
RR
1087 if (win->m_isScrolling)
1088 {
1089 command = wxEVT_SCROLL_THUMBTRACK;
1090 }
1091 else
1092 {
1093 if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
1094 else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
1095 else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
1096 else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
1097 else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
1098 else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
1099 else command = wxEVT_SCROLL_THUMBTRACK;
1100 }
47d67540 1101
e380f72b 1102 int value = (int)(win->m_vAdjust->value+0.5);
c801d85f 1103
e380f72b
RR
1104 wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
1105 event.SetEventObject( win );
1106 win->GetEventHandler()->ProcessEvent( event );
362c6693 1107}
c801d85f
KB
1108
1109//-----------------------------------------------------------------------------
2f2aa628
RR
1110// "value_changed" from m_hAdjust
1111//-----------------------------------------------------------------------------
c801d85f 1112
2f2aa628 1113static void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
47d67540 1114{
e380f72b 1115 if (g_blockEventsOnDrag) return;
47d67540 1116
c801d85f 1117/*
e380f72b
RR
1118 printf( "OnHScroll from " );
1119 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1120 printf( win->GetClassInfo()->GetClassName() );
1121 printf( ".\n" );
c801d85f 1122*/
47d67540 1123
e380f72b 1124 if (!win->HasVMT()) return;
47d67540 1125
e380f72b
RR
1126 float diff = win->m_hAdjust->value - win->m_oldHorizontalPos;
1127 if (fabs(diff) < 0.2) return;
47d67540 1128
e380f72b 1129 wxEventType command = wxEVT_NULL;
47d67540 1130
e380f72b
RR
1131 float line_step = win->m_hAdjust->step_increment;
1132 float page_step = win->m_hAdjust->page_increment;
8bbe427f 1133
76ed8f8d
RR
1134 if (win->m_isScrolling)
1135 {
1136 command = wxEVT_SCROLL_THUMBTRACK;
1137 }
1138 else
1139 {
1140 if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
1141 else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
1142 else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
1143 else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
1144 else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
1145 else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
1146 else command = wxEVT_SCROLL_THUMBTRACK;
1147 }
c801d85f 1148
e380f72b 1149 int value = (int)(win->m_hAdjust->value+0.5);
47d67540 1150
e380f72b
RR
1151 wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
1152 event.SetEventObject( win );
1153 win->GetEventHandler()->ProcessEvent( event );
362c6693 1154}
c801d85f
KB
1155
1156//-----------------------------------------------------------------------------
2f2aa628
RR
1157// "changed" from m_vAdjust
1158//-----------------------------------------------------------------------------
c801d85f 1159
2f2aa628 1160static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
c801d85f 1161{
e380f72b 1162 if (g_blockEventsOnDrag) return;
c801d85f
KB
1163
1164/*
e380f72b
RR
1165 printf( "OnVScroll change from " );
1166 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1167 printf( win->GetClassInfo()->GetClassName() );
1168 printf( ".\n" );
c801d85f 1169*/
47d67540 1170
e380f72b 1171 if (!win->HasVMT()) return;
47d67540 1172
e380f72b
RR
1173 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
1174 int value = (int)(win->m_vAdjust->value+0.5);
c801d85f 1175
e380f72b
RR
1176 wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
1177 event.SetEventObject( win );
1178 win->GetEventHandler()->ProcessEvent( event );
362c6693 1179}
c801d85f
KB
1180
1181//-----------------------------------------------------------------------------
2f2aa628
RR
1182// "changed" from m_hAdjust
1183//-----------------------------------------------------------------------------
c801d85f 1184
2f2aa628 1185static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
47d67540 1186{
e380f72b 1187 if (g_blockEventsOnDrag) return;
47d67540 1188
c801d85f 1189/*
e380f72b
RR
1190 printf( "OnHScroll change from " );
1191 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1192 printf( win->GetClassInfo()->GetClassName() );
1193 printf( ".\n" );
c801d85f 1194*/
47d67540 1195
e380f72b 1196 if (!win->HasVMT()) return;
47d67540 1197
e380f72b
RR
1198 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
1199 int value = (int)(win->m_hAdjust->value+0.5);
47d67540 1200
e380f72b
RR
1201 wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
1202 event.SetEventObject( win );
1203 win->GetEventHandler()->ProcessEvent( event );
362c6693 1204}
c801d85f 1205
cb43b372
RR
1206//-----------------------------------------------------------------------------
1207// "button_press_event" from scrollbar
1208//-----------------------------------------------------------------------------
1209
8bbe427f
VZ
1210static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
1211 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1212 wxWindow *win )
cb43b372 1213{
1ecc4d80
RR
1214// don't test here as we can release the mouse while being over
1215// a different window then the slider
1216//
76ed8f8d 1217// if (gdk_event->window != widget->slider) return FALSE;
8bbe427f 1218
e380f72b 1219 win->m_isScrolling = TRUE;
76ed8f8d 1220 g_blockEventsOnScroll = TRUE;
47d67540 1221
e380f72b 1222 return FALSE;
cb43b372
RR
1223}
1224
1225//-----------------------------------------------------------------------------
1226// "button_release_event" from scrollbar
1227//-----------------------------------------------------------------------------
1228
8bbe427f
VZ
1229static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
1230 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1231 wxWindow *win )
cb43b372 1232{
76ed8f8d 1233
1ecc4d80 1234// don't test here as we can release the mouse while being over
76ed8f8d
RR
1235// a different window then the slider
1236//
1237// if (gdk_event->window != widget->slider) return FALSE;
cb43b372 1238
e380f72b 1239 GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(win->m_widget);
47d67540 1240
e380f72b
RR
1241 if (widget == GTK_RANGE(s_window->vscrollbar))
1242 gtk_signal_emit_by_name( GTK_OBJECT(win->m_hAdjust), "value_changed" );
1243 else
1244 gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" );
47d67540 1245
e380f72b 1246 win->m_isScrolling = FALSE;
76ed8f8d 1247 g_blockEventsOnScroll = FALSE;
47d67540 1248
e380f72b 1249 return FALSE;
cb43b372
RR
1250}
1251
6ca41e57
RR
1252//-----------------------------------------------------------------------------
1253// InsertChild for wxWindow.
1254//-----------------------------------------------------------------------------
1255
b1170810
RR
1256/* Callback for wxWindow. This very strange beast has to be used because
1257 * C++ has no virtual methods in a constructor. We have to emulate a
1258 * virtual function here as wxNotebook requires a different way to insert
1259 * a child in it. I had opted for creating a wxNotebookPage window class
1260 * which would have made this superfluous (such in the MDI window system),
1261 * but no-one was listening to me... */
6ca41e57
RR
1262
1263static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child )
1264{
8bbe427f
VZ
1265 gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
1266 GTK_WIDGET(child->m_widget),
ff8bfdbb
VZ
1267 child->m_x,
1268 child->m_y );
6ca41e57 1269
8bbe427f
VZ
1270 gtk_widget_set_usize( GTK_WIDGET(child->m_widget),
1271 child->m_width,
ff8bfdbb
VZ
1272 child->m_height );
1273
5b077d48
RR
1274 if (wxIS_KIND_OF(parent,wxFrame))
1275 {
1276 parent->m_sizeSet = FALSE;
1277 }
ff8bfdbb 1278
3e61c765
RR
1279 if (parent->m_windowStyle & wxTAB_TRAVERSAL)
1280 {
1281 /* we now allow a window to get the focus as long as it
ff8bfdbb
VZ
1282 doesn't have any children. */
1283 GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS );
3e61c765 1284 }
6ca41e57
RR
1285}
1286
bbe0af5b
RR
1287//-----------------------------------------------------------------------------
1288// global functions
1289//-----------------------------------------------------------------------------
1290
1291wxWindow* wxGetActiveWindow()
1292{
1293 return g_focusWindow;
1294}
1295
c801d85f 1296//-----------------------------------------------------------------------------
2f2aa628 1297// wxWindow
c801d85f
KB
1298//-----------------------------------------------------------------------------
1299
1300IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
1301
1302BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
e380f72b
RR
1303 EVT_SIZE(wxWindow::OnSize)
1304 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
1305 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
b666df2c 1306 EVT_KEY_DOWN(wxWindow::OnKeyDown)
c801d85f
KB
1307END_EVENT_TABLE()
1308
1309wxWindow::wxWindow()
1310{
e380f72b
RR
1311 m_widget = (GtkWidget *) NULL;
1312 m_wxwindow = (GtkWidget *) NULL;
1313 m_parent = (wxWindow *) NULL;
1314 m_children.DeleteContents( FALSE );
8bbe427f 1315
e380f72b
RR
1316 m_x = 0;
1317 m_y = 0;
1318 m_width = 0;
1319 m_height = 0;
1320 m_minWidth = -1;
1321 m_minHeight = -1;
1322 m_maxWidth = -1;
1323 m_maxHeight = -1;
8bbe427f 1324
e380f72b 1325 m_retCode = 0;
8bbe427f 1326
e380f72b
RR
1327 m_eventHandler = this;
1328 m_windowValidator = (wxValidator *) NULL;
8bbe427f 1329
e380f72b 1330 m_windowId = -1;
8bbe427f 1331
e380f72b
RR
1332 m_cursor = (wxCursor *) NULL;
1333 m_font = *wxSWISS_FONT;
1334 m_windowStyle = 0;
1335 m_windowName = "noname";
8bbe427f 1336
e380f72b
RR
1337 m_constraints = (wxLayoutConstraints *) NULL;
1338 m_constraintsInvolvedIn = (wxList *) NULL;
1339 m_windowSizer = (wxSizer *) NULL;
1340 m_sizerParent = (wxWindow *) NULL;
1341 m_autoLayout = FALSE;
8bbe427f 1342
e380f72b
RR
1343 m_sizeSet = FALSE;
1344 m_hasVMT = FALSE;
1345 m_needParent = TRUE;
8bbe427f 1346
e380f72b
RR
1347 m_hasScrolling = FALSE;
1348 m_isScrolling = FALSE;
1349 m_hAdjust = (GtkAdjustment*) NULL;
1350 m_vAdjust = (GtkAdjustment*) NULL;
1351 m_oldHorizontalPos = 0.0;
1352 m_oldVerticalPos = 0.0;
8bbe427f 1353
e380f72b
RR
1354 m_isShown = FALSE;
1355 m_isEnabled = TRUE;
8bbe427f 1356
06cfab17 1357#if wxUSE_DRAG_AND_DROP
e380f72b 1358 m_dropTarget = (wxDropTarget*) NULL;
ac57418f 1359#endif
e380f72b
RR
1360 m_resizing = FALSE;
1361 m_scrollGC = (GdkGC*) NULL;
1362 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1363
e380f72b 1364 m_insertCallback = wxInsertChildInWindow;
8bbe427f 1365
e380f72b
RR
1366 m_clientObject = (wxClientData*) NULL;
1367 m_clientData = NULL;
ff8bfdbb 1368
1ecc4d80 1369 m_isStaticBox = FALSE;
b292e2f5 1370 m_acceptsFocus = FALSE;
ff8bfdbb
VZ
1371
1372#if wxUSE_TOOLTIPS
b1170810 1373 m_toolTip = (wxToolTip*) NULL;
ff8bfdbb 1374#endif // wxUSE_TOOLTIPS
362c6693 1375}
c801d85f 1376
6ca41e57 1377wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
e380f72b
RR
1378 const wxPoint &pos, const wxSize &size,
1379 long style, const wxString &name )
6ca41e57 1380{
e380f72b
RR
1381 m_insertCallback = wxInsertChildInWindow;
1382 Create( parent, id, pos, size, style, name );
6ca41e57 1383}
8bbe427f 1384
debe6624 1385bool wxWindow::Create( wxWindow *parent, wxWindowID id,
e380f72b
RR
1386 const wxPoint &pos, const wxSize &size,
1387 long style, const wxString &name )
c801d85f 1388{
e380f72b
RR
1389 m_isShown = FALSE;
1390 m_isEnabled = TRUE;
1391 m_needParent = TRUE;
47d67540 1392
e380f72b 1393 PreCreation( parent, id, pos, size, style, name );
47d67540 1394
e380f72b 1395 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
38c7b3d3 1396 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
ff8bfdbb 1397
b292e2f5
RR
1398#ifdef __WXDEBUG__
1399 debug_focus_in( m_widget, "wxWindow::m_widget", name );
1400#endif
47d67540 1401
e380f72b 1402 GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget);
47d67540 1403
b292e2f5
RR
1404#ifdef __WXDEBUG__
1405 debug_focus_in( s_window->hscrollbar, "wxWindow::hsrcollbar", name );
1406 debug_focus_in( s_window->vscrollbar, "wxWindow::vsrcollbar", name );
1407#endif
1408
e380f72b
RR
1409 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
1410 scroll_class->scrollbar_spacing = 0;
47d67540 1411
e380f72b 1412 gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
47d67540 1413
e380f72b
RR
1414 m_oldHorizontalPos = 0.0;
1415 m_oldVerticalPos = 0.0;
47d67540 1416
e380f72b
RR
1417 m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
1418 m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
47d67540 1419
38c7b3d3
RR
1420 m_wxwindow = gtk_myfixed_new();
1421
b292e2f5
RR
1422#ifdef __WXDEBUG__
1423 debug_focus_in( m_wxwindow, "wxWindow::m_wxwindow", name );
1424#endif
1425
38c7b3d3
RR
1426#ifdef NEW_GTK_SCROLL_CODE
1427 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), m_wxwindow );
1428 GtkViewport *viewport = GTK_VIEWPORT(s_window->child);
1429#else
1430 gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
e380f72b 1431 GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport);
38c7b3d3 1432#endif
47d67540 1433
b292e2f5
RR
1434#ifdef __WXDEBUG__
1435 debug_focus_in( GTK_WIDGET(viewport), "wxWindow::viewport", name );
1436#endif
1437
e380f72b
RR
1438 if (m_windowStyle & wxRAISED_BORDER)
1439 {
1440 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
1441 }
1442 else if (m_windowStyle & wxSUNKEN_BORDER)
1443 {
1444 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
1445 }
1446 else
1447 {
1448 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
1449 }
47d67540 1450
3e61c765 1451 if (m_windowStyle & wxTAB_TRAVERSAL)
b292e2f5 1452 {
3e61c765 1453 /* we now allow a window to get the focus as long as it
ff8bfdbb
VZ
1454 doesn't have any children. */
1455 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1456 m_acceptsFocus = FALSE;
1457 }
e380f72b 1458 else
b292e2f5 1459 {
e380f72b 1460 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1461 m_acceptsFocus = TRUE;
1462 }
e380f72b 1463
e380f72b
RR
1464 // shut the viewport up
1465 gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1466 gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1467
1468 // I _really_ don't want scrollbars in the beginning
1469 m_vAdjust->lower = 0.0;
1470 m_vAdjust->upper = 1.0;
1471 m_vAdjust->value = 0.0;
1472 m_vAdjust->step_increment = 1.0;
1473 m_vAdjust->page_increment = 1.0;
1474 m_vAdjust->page_size = 5.0;
1475 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
1476 m_hAdjust->lower = 0.0;
1477 m_hAdjust->upper = 1.0;
1478 m_hAdjust->value = 0.0;
1479 m_hAdjust->step_increment = 1.0;
1480 m_hAdjust->page_increment = 1.0;
1481 m_hAdjust->page_size = 5.0;
1482 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
1483
76ed8f8d
RR
1484 // these handlers block mouse events to any window during scrolling
1485 // such as motion events and prevent GTK and wxWindows from fighting
1486 // over where the slider should be
8bbe427f 1487
76ed8f8d
RR
1488 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
1489 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1490
1491 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
1492 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1493
1494 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
1495 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
1496
1497 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
1498 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
8bbe427f 1499
76ed8f8d
RR
1500 // these handers het notified when screen updates are required either when
1501 // scrolling or when the window size (and therefore scrollbar configuration)
1502 // has changed
1503
1504 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
1505 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
1506 gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
1507 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
1508
1509 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
1510 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
1511 gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
1512 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
1513
e380f72b 1514 gtk_widget_show( m_wxwindow );
8bbe427f 1515
e380f72b 1516 if (m_parent) m_parent->AddChild( this );
47d67540 1517
e380f72b 1518 (m_parent->m_insertCallback)( m_parent, this );
8bbe427f 1519
e380f72b 1520 PostCreation();
8bbe427f 1521
e380f72b 1522 Show( TRUE );
c801d85f 1523
e380f72b 1524 return TRUE;
362c6693 1525}
c801d85f 1526
68dda785 1527wxWindow::~wxWindow()
c801d85f 1528{
1f916a19
JS
1529 // Remove potential dangling pointer
1530 if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel)))
1531 {
1532 wxPanel* panel = (wxPanel*) GetParent();
1533 if (panel->GetLastFocus() == this)
1534 panel->SetLastFocus((wxWindow*) NULL);
1535 }
1536
43a18898 1537 m_hasVMT = FALSE;
47d67540 1538
06cfab17 1539#if wxUSE_DRAG_AND_DROP
ff8bfdbb 1540 wxDELETE(m_dropTarget);
ac57418f 1541#endif
47d67540 1542
ff8bfdbb
VZ
1543#if wxUSE_TOOLTIPS
1544 wxDELETE(m_toolTip);
1545#endif // wxUSE_TOOLTIPS
b1170810 1546
43a18898
RR
1547 if (m_parent) m_parent->RemoveChild( this );
1548 if (m_widget) Show( FALSE );
c801d85f 1549
43a18898 1550 DestroyChildren();
47d67540 1551
43a18898 1552 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 1553
43a18898 1554 if (m_scrollGC) gdk_gc_unref( m_scrollGC );
8bbe427f 1555
43a18898 1556 if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
47d67540 1557
43a18898 1558 if (m_widget) gtk_widget_destroy( m_widget );
8bbe427f 1559
43a18898 1560 if (m_cursor) delete m_cursor;
c801d85f 1561
43a18898
RR
1562 DeleteRelatedConstraints();
1563 if (m_constraints)
1564 {
1565 // This removes any dangling pointers to this window
1566 // in other windows' constraintsInvolvedIn lists.
1567 UnsetConstraints(m_constraints);
1568 delete m_constraints;
1569 m_constraints = (wxLayoutConstraints *) NULL;
1570 }
1571 if (m_windowSizer)
1572 {
1573 delete m_windowSizer;
1574 m_windowSizer = (wxSizer *) NULL;
1575 }
1576 // If this is a child of a sizer, remove self from parent
1577 if (m_sizerParent) m_sizerParent->RemoveChild((wxWindow *)this);
c801d85f 1578
43a18898
RR
1579 // Just in case the window has been Closed, but
1580 // we're then deleting immediately: don't leave
1581 // dangling pointers.
1582 wxPendingDelete.DeleteObject(this);
c801d85f 1583
43a18898
RR
1584 // Just in case we've loaded a top-level window via
1585 // wxWindow::LoadNativeDialog but we weren't a dialog
1586 // class
1587 wxTopLevelWindows.DeleteObject(this);
47d67540 1588
43a18898 1589 if (m_windowValidator) delete m_windowValidator;
8bbe427f 1590
43a18898 1591 if (m_clientObject) delete m_clientObject;
362c6693 1592}
c801d85f 1593
debe6624
JS
1594void wxWindow::PreCreation( wxWindow *parent, wxWindowID id,
1595 const wxPoint &pos, const wxSize &size,
1596 long style, const wxString &name )
c801d85f 1597{
3069ac4e 1598 wxASSERT_MSG( (!m_needParent) || (parent), "Need complete parent." );
8bbe427f 1599
43a18898
RR
1600 m_widget = (GtkWidget*) NULL;
1601 m_wxwindow = (GtkWidget*) NULL;
1602 m_hasVMT = FALSE;
1603 m_parent = parent;
1604 m_children.DeleteContents( FALSE );
8bbe427f 1605
43a18898
RR
1606 m_width = size.x;
1607 if (m_width == -1) m_width = 20;
1608 m_height = size.y;
1609 if (m_height == -1) m_height = 20;
8bbe427f 1610
43a18898
RR
1611 m_x = (int)pos.x;
1612 m_y = (int)pos.y;
8bbe427f 1613
43a18898 1614 if (!m_needParent) // some reasonable defaults
6ca41e57 1615 {
43a18898
RR
1616 if (m_x == -1)
1617 {
1618 m_x = (gdk_screen_width () - m_width) / 2;
1619 if (m_x < 10) m_x = 10;
1620 }
1621 if (m_y == -1)
1622 {
1623 m_y = (gdk_screen_height () - m_height) / 2;
1624 if (m_y < 10) m_y = 10;
1625 }
6ca41e57 1626 }
8bbe427f 1627
43a18898
RR
1628 m_minWidth = -1;
1629 m_minHeight = -1;
1630 m_maxWidth = -1;
1631 m_maxHeight = -1;
8bbe427f 1632
43a18898 1633 m_retCode = 0;
8bbe427f 1634
43a18898 1635 m_eventHandler = this;
8bbe427f 1636
b749747d 1637 m_windowId = id == -1 ? wxNewId() : id;
8bbe427f 1638
43a18898 1639 m_sizeSet = FALSE;
8bbe427f 1640
43a18898
RR
1641 m_cursor = new wxCursor( wxCURSOR_ARROW );
1642 m_font = *wxSWISS_FONT;
1ecc4d80
RR
1643 m_backgroundColour = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
1644 m_foregroundColour = *wxBLACK;
43a18898
RR
1645 m_windowStyle = style;
1646 m_windowName = name;
8bbe427f 1647
43a18898
RR
1648 m_constraints = (wxLayoutConstraints *) NULL;
1649 m_constraintsInvolvedIn = (wxList *) NULL;
1650 m_windowSizer = (wxSizer *) NULL;
1651 m_sizerParent = (wxWindow *) NULL;
1652 m_autoLayout = FALSE;
8bbe427f 1653
43a18898
RR
1654 m_hasScrolling = FALSE;
1655 m_isScrolling = FALSE;
1656 m_hAdjust = (GtkAdjustment *) NULL;
1657 m_vAdjust = (GtkAdjustment *) NULL;
1658 m_oldHorizontalPos = 0.0;
1659 m_oldVerticalPos = 0.0;
8bbe427f 1660
43a18898
RR
1661 m_isShown = FALSE;
1662 m_isEnabled = TRUE;
8bbe427f 1663
06cfab17 1664#if wxUSE_DRAG_AND_DROP
43a18898 1665 m_dropTarget = (wxDropTarget *) NULL;
ac57418f 1666#endif
43a18898
RR
1667 m_resizing = FALSE;
1668 m_windowValidator = (wxValidator *) NULL;
1669 m_scrollGC = (GdkGC*) NULL;
1670 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1671
43a18898
RR
1672 m_clientObject = (wxClientData*)NULL;
1673 m_clientData = NULL;
ff8bfdbb 1674
1ecc4d80 1675 m_isStaticBox = FALSE;
ff8bfdbb
VZ
1676
1677#if wxUSE_TOOLTIPS
b1170810 1678 m_toolTip = (wxToolTip*) NULL;
ff8bfdbb 1679#endif // wxUSE_TOOLTIPS
c801d85f
KB
1680}
1681
68dda785 1682void wxWindow::PostCreation()
c801d85f 1683{
43a18898
RR
1684 if (m_wxwindow)
1685 {
1686 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
1687 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
47d67540 1688
43a18898
RR
1689 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
1690 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
1691 }
47d67540 1692
43a18898 1693 ConnectWidget( GetConnectWidget() );
47d67540 1694
43a18898 1695 if (m_widget && m_parent) gtk_widget_realize( m_widget );
47d67540 1696
43a18898 1697 if (m_wxwindow) gtk_widget_realize( m_wxwindow );
47d67540 1698
43a18898 1699 SetCursor( *wxSTANDARD_CURSOR );
47d67540 1700
43a18898 1701 m_hasVMT = TRUE;
b4071e91
RR
1702}
1703
1704void wxWindow::ConnectWidget( GtkWidget *widget )
1705{
43a18898
RR
1706 gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
1707 GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
c801d85f 1708
b666df2c
RR
1709 gtk_signal_connect( GTK_OBJECT(widget), "key_release_event",
1710 GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this );
1711
43a18898
RR
1712 gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
1713 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
47d67540 1714
43a18898
RR
1715 gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
1716 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
47d67540 1717
43a18898
RR
1718 gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
1719 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
47d67540 1720
43a18898
RR
1721 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
1722 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
c801d85f 1723
43a18898
RR
1724 gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
1725 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
c801d85f 1726
43a18898
RR
1727 gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
1728 GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
47d67540 1729
43a18898
RR
1730 gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
1731 GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
362c6693 1732}
c801d85f 1733
68dda785 1734bool wxWindow::HasVMT()
c801d85f 1735{
43a18898 1736 return m_hasVMT;
362c6693 1737}
c801d85f 1738
debe6624 1739bool wxWindow::Close( bool force )
c801d85f 1740{
43a18898 1741 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1742
43a18898
RR
1743 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
1744 event.SetEventObject(this);
2b854a32 1745 event.SetCanVeto(!force);
c801d85f 1746
fe4e9e6c
VZ
1747 // return FALSE if window wasn't closed because the application vetoed the
1748 // close event
1749 return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
362c6693 1750}
c801d85f 1751
68dda785 1752bool wxWindow::Destroy()
c801d85f 1753{
43a18898 1754 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1755
43a18898
RR
1756 m_hasVMT = FALSE;
1757 delete this;
1758 return TRUE;
362c6693 1759}
c801d85f 1760
68dda785 1761bool wxWindow::DestroyChildren()
c801d85f 1762{
db1b4961
RR
1763 wxNode *node;
1764 while ((node = m_children.First()) != (wxNode *)NULL)
c801d85f 1765 {
db1b4961
RR
1766 wxWindow *child;
1767 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL)
43a18898 1768 {
db1b4961
RR
1769 delete child;
1770 if (m_children.Member(child)) delete node;
43a18898 1771 }
362c6693 1772 }
43a18898 1773 return TRUE;
362c6693 1774}
c801d85f
KB
1775
1776void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
1777{
43a18898 1778 // are we to set fonts here ?
362c6693 1779}
c801d85f 1780
6ca41e57
RR
1781wxPoint wxWindow::GetClientAreaOrigin() const
1782{
43a18898 1783 return wxPoint(0,0);
6ca41e57
RR
1784}
1785
1786void wxWindow::AdjustForParentClientOrigin( int& x, int& y, int sizeFlags )
1787{
43a18898
RR
1788 if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent())
1789 {
1790 wxPoint pt(GetParent()->GetClientAreaOrigin());
8bbe427f 1791 x += pt.x;
43a18898
RR
1792 y += pt.y;
1793 }
6ca41e57
RR
1794}
1795
debe6624 1796void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 1797{
fb1585ae
RR
1798 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
1799 wxASSERT_MSG( (m_parent != NULL), "wxWindow::SetSize requires parent.\n" );
8bbe427f 1800
fb1585ae
RR
1801 if (m_resizing) return; // I don't like recursions
1802 m_resizing = TRUE;
47d67540 1803
ba4e3652 1804 if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
fb1585ae 1805 {
ba4e3652 1806 // don't set the size for children of wxNotebook, just take the values.
fb1585ae
RR
1807 m_x = x;
1808 m_y = y;
1809 m_width = width;
ba4e3652 1810 m_height = height;
fb1585ae 1811 }
ba4e3652 1812 else
fb1585ae 1813 {
ba4e3652
RR
1814 int old_width = m_width;
1815 int old_height = m_height;
8bbe427f 1816
ba4e3652
RR
1817 if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
1818 {
1819 if (x != -1) m_x = x;
1820 if (y != -1) m_y = y;
1821 if (width != -1) m_width = width;
1822 if (height != -1) m_height = height;
1823 }
1824 else
1825 {
1826 m_x = x;
1827 m_y = y;
1828 m_width = width;
1829 m_height = height;
1830 }
47d67540 1831
ba4e3652
RR
1832 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
1833 {
1834 if (width == -1) m_width = 80;
1835 }
1836
1837 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
1838 {
1839 if (height == -1) m_height = 26;
1840 }
8bbe427f 1841
ba4e3652
RR
1842 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
1843 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
d3b4d113
RR
1844 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
1845 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
47d67540 1846
3502e687
RR
1847 if (GTK_WIDGET_HAS_DEFAULT(m_widget))
1848 {
1849 /* the default button has a border around it */
1850 int border = 5;
1851
1852 wxPoint pt( m_parent->GetClientAreaOrigin() );
1853 gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x-border, m_y+pt.y-border );
1854
1855 gtk_widget_set_usize( m_widget, m_width+2*border, m_height+2*border );
1856 }
1857 else
1858 {
1859 wxPoint pt( m_parent->GetClientAreaOrigin() );
1860 gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y );
1861
1862 if ((old_width != m_width) || (old_height != m_height))
1863 gtk_widget_set_usize( m_widget, m_width, m_height );
1864 }
ba4e3652 1865 }
8bbe427f 1866
fb1585ae 1867 m_sizeSet = TRUE;
47d67540 1868
fb1585ae
RR
1869 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
1870 event.SetEventObject( this );
ba4e3652 1871 GetEventHandler()->ProcessEvent( event );
47d67540 1872
fb1585ae 1873 m_resizing = FALSE;
362c6693 1874}
c801d85f 1875
9390a202
RR
1876void wxWindow::OnInternalIdle()
1877{
1878 UpdateWindowUI();
1879}
1880
debe6624 1881void wxWindow::SetSize( int width, int height )
c801d85f 1882{
fb1585ae 1883 SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
362c6693 1884}
c801d85f 1885
debe6624 1886void wxWindow::Move( int x, int y )
c801d85f 1887{
fb1585ae 1888 SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
362c6693 1889}
c801d85f
KB
1890
1891void wxWindow::GetSize( int *width, int *height ) const
1892{
1ecc4d80 1893 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1894
fb1585ae
RR
1895 if (width) (*width) = m_width;
1896 if (height) (*height) = m_height;
362c6693 1897}
c801d85f 1898
debe6624 1899void wxWindow::SetClientSize( int width, int height )
c801d85f 1900{
1ecc4d80 1901 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1902
1ecc4d80 1903 if (!m_wxwindow)
c801d85f 1904 {
1ecc4d80 1905 SetSize( width, height );
c801d85f
KB
1906 }
1907 else
1908 {
1ecc4d80
RR
1909 int dw = 0;
1910 int dh = 0;
1911
1912 if (!m_hasScrolling)
1913 {
1914 GtkStyleClass *window_class = m_wxwindow->style->klass;
1915
1916 if ((m_windowStyle & wxRAISED_BORDER) ||
1917 (m_windowStyle & wxSUNKEN_BORDER))
1918 {
1919 dw += 2 * window_class->xthickness;
1920 dh += 2 * window_class->ythickness;
1921 }
1922 }
1923 else
1924 {
1925 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
1926 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 1927
38c7b3d3 1928#ifdef NEW_GTK_SCROLL_CODE
1ecc4d80 1929 GtkWidget *viewport = scroll_window->child;
8bbe427f 1930#else
1ecc4d80 1931 GtkWidget *viewport = scroll_window->viewport;
38c7b3d3
RR
1932#endif
1933
1ecc4d80
RR
1934 GtkStyleClass *viewport_class = viewport->style->klass;
1935
1936 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1937 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1938
1939 if ((m_windowStyle & wxRAISED_BORDER) ||
1940 (m_windowStyle & wxSUNKEN_BORDER))
1941 {
1942 dw += 2 * viewport_class->xthickness;
1943 dh += 2 * viewport_class->ythickness;
1944 }
47d67540 1945
1ecc4d80
RR
1946 if (scroll_window->vscrollbar_visible)
1947 {
1948 dw += vscrollbar->allocation.width;
1949 dw += scroll_class->scrollbar_spacing;
1950 }
1951
1952 if (scroll_window->hscrollbar_visible)
1953 {
1954 dh += hscrollbar->allocation.height;
1955 dw += scroll_class->scrollbar_spacing;
1956 }
1957 }
1958
1959 SetSize( width+dw, height+dh );
1960 }
362c6693 1961}
c801d85f
KB
1962
1963void wxWindow::GetClientSize( int *width, int *height ) const
1964{
1ecc4d80 1965 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1966
1ecc4d80
RR
1967 if (!m_wxwindow)
1968 {
1969 if (width) (*width) = m_width;
1970 if (height) (*height) = m_height;
c801d85f
KB
1971 }
1972 else
1973 {
1ecc4d80
RR
1974 int dw = 0;
1975 int dh = 0;
1976
1977 if (!m_hasScrolling)
1978 {
1979 GtkStyleClass *window_class = m_wxwindow->style->klass;
1980
1981 if ((m_windowStyle & wxRAISED_BORDER) ||
1982 (m_windowStyle & wxSUNKEN_BORDER))
1983 {
1984 dw += 2 * window_class->xthickness;
1985 dh += 2 * window_class->ythickness;
1986 }
1987 }
1988 else
1989 {
1990 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
1991 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 1992
38c7b3d3 1993#ifdef NEW_GTK_SCROLL_CODE
1ecc4d80 1994 GtkWidget *viewport = scroll_window->child;
8bbe427f 1995#else
1ecc4d80 1996 GtkWidget *viewport = scroll_window->viewport;
38c7b3d3
RR
1997#endif
1998
1ecc4d80
RR
1999 GtkStyleClass *viewport_class = viewport->style->klass;
2000
2001 if ((m_windowStyle & wxRAISED_BORDER) ||
2002 (m_windowStyle & wxSUNKEN_BORDER))
2003 {
2004 dw += 2 * viewport_class->xthickness;
2005 dh += 2 * viewport_class->ythickness;
2006 }
2007
2008 if (scroll_window->vscrollbar_visible)
2009 {
2010// dw += vscrollbar->allocation.width;
2011 dw += 15; // range.slider_width = 11 + 2*2pts edge
2012 dw += scroll_class->scrollbar_spacing;
2013 }
2014
2015 if (scroll_window->hscrollbar_visible)
2016 {
2017// dh += hscrollbar->allocation.height;
2018 dh += 15;
2019 dh += scroll_class->scrollbar_spacing;
2020 }
2021 }
47d67540 2022
1ecc4d80
RR
2023 if (width) (*width) = m_width - dw;
2024 if (height) (*height) = m_height - dh;
2025 }
362c6693 2026}
c801d85f
KB
2027
2028void wxWindow::GetPosition( int *x, int *y ) const
2029{
1ecc4d80 2030 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2031
43a18898
RR
2032 if (x) (*x) = m_x;
2033 if (y) (*y) = m_y;
362c6693 2034}
c801d85f
KB
2035
2036void wxWindow::ClientToScreen( int *x, int *y )
2037{
1ecc4d80 2038 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2039
43a18898
RR
2040 GdkWindow *source = (GdkWindow *) NULL;
2041 if (m_wxwindow)
2042 source = m_wxwindow->window;
2043 else
2044 source = m_widget->window;
47d67540 2045
43a18898
RR
2046 int org_x = 0;
2047 int org_y = 0;
2048 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2049
43a18898 2050 if (!m_wxwindow)
c801d85f 2051 {
43a18898
RR
2052 if (GTK_WIDGET_NO_WINDOW (m_widget))
2053 {
2054 org_x += m_widget->allocation.x;
2055 org_y += m_widget->allocation.y;
2056 }
362c6693 2057 }
47d67540 2058
43a18898
RR
2059 wxPoint pt(GetClientAreaOrigin());
2060 org_x += pt.x;
2061 org_y += pt.y;
8bbe427f 2062
43a18898
RR
2063 if (x) *x += org_x;
2064 if (y) *y += org_y;
362c6693 2065}
c801d85f
KB
2066
2067void wxWindow::ScreenToClient( int *x, int *y )
2068{
1ecc4d80 2069 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2070
1ecc4d80
RR
2071 GdkWindow *source = (GdkWindow *) NULL;
2072 if (m_wxwindow)
2073 source = m_wxwindow->window;
2074 else
2075 source = m_widget->window;
47d67540 2076
1ecc4d80
RR
2077 int org_x = 0;
2078 int org_y = 0;
2079 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2080
1ecc4d80 2081 if (!m_wxwindow)
c801d85f 2082 {
1ecc4d80
RR
2083 if (GTK_WIDGET_NO_WINDOW (m_widget))
2084 {
2085 org_x += m_widget->allocation.x;
2086 org_y += m_widget->allocation.y;
2087 }
362c6693 2088 }
47d67540 2089
1ecc4d80
RR
2090 wxPoint pt(GetClientAreaOrigin());
2091 org_x -= pt.x;
2092 org_y -= pt.y;
8bbe427f 2093
1ecc4d80
RR
2094 if (x) *x -= org_x;
2095 if (y) *y -= org_y;
362c6693 2096}
c801d85f 2097
debe6624 2098void wxWindow::Centre( int direction )
c801d85f 2099{
1ecc4d80 2100 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2101
1ecc4d80
RR
2102 int x = m_x;
2103 int y = m_y;
8bbe427f 2104
1ecc4d80
RR
2105 if (m_parent)
2106 {
2107 int p_w = 0;
2108 int p_h = 0;
2109 m_parent->GetSize( &p_w, &p_h );
2110 if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (p_w - m_width) / 2;
2111 if (direction & wxVERTICAL == wxVERTICAL) y = (p_h - m_height) / 2;
2112 }
2113 else
2114 {
2115 if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
2116 if (direction & wxVERTICAL == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
2117 }
8bbe427f 2118
1ecc4d80 2119 Move( x, y );
362c6693 2120}
c801d85f 2121
68dda785 2122void wxWindow::Fit()
c801d85f 2123{
1ecc4d80 2124 wxCHECK_RET( (m_widget != NULL), "invalid window" );
5e0aa05a 2125
1ecc4d80
RR
2126 int maxX = 0;
2127 int maxY = 0;
2128 wxNode *node = m_children.First();
2129 while (node)
2130 {
2131 wxWindow *win = (wxWindow *)node->Data();
2132 int wx, wy, ww, wh;
2133 win->GetPosition(&wx, &wy);
2134 win->GetSize(&ww, &wh);
2135 if (wx + ww > maxX) maxX = wx + ww;
2136 if (wy + wh > maxY) maxY = wy + wh;
2137
2138 node = node->Next();
2139 }
ff8bfdbb 2140
1ecc4d80 2141 SetClientSize(maxX + 7, maxY + 14);
362c6693 2142}
c801d85f 2143
2f2aa628
RR
2144void wxWindow::SetSizeHints( int minW, int minH, int maxW, int maxH, int WXUNUSED(incW), int WXUNUSED(incH) )
2145{
1ecc4d80 2146 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2147
1ecc4d80
RR
2148 m_minWidth = minW;
2149 m_minHeight = minH;
2150 m_maxWidth = maxW;
2151 m_maxHeight = maxH;
2f2aa628
RR
2152}
2153
c801d85f
KB
2154void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
2155{
f04371f0 2156// if (GetAutoLayout()) Layout();
362c6693 2157}
c801d85f 2158
debe6624 2159bool wxWindow::Show( bool show )
c801d85f 2160{
1ecc4d80 2161 wxCHECK_MSG( (m_widget != NULL), FALSE, "invalid window" );
47d67540 2162
1ecc4d80
RR
2163 if (show)
2164 gtk_widget_show( m_widget );
2165 else
2166 gtk_widget_hide( m_widget );
ff8bfdbb 2167
1ecc4d80 2168 m_isShown = show;
ff8bfdbb 2169
1ecc4d80 2170 return TRUE;
362c6693 2171}
c801d85f 2172
debe6624 2173void wxWindow::Enable( bool enable )
c801d85f 2174{
1ecc4d80 2175 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2176
1ecc4d80 2177 m_isEnabled = enable;
ff8bfdbb 2178
1ecc4d80
RR
2179 gtk_widget_set_sensitive( m_widget, enable );
2180 if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
362c6693 2181}
c801d85f 2182
68dda785 2183int wxWindow::GetCharHeight() const
c33c4050 2184{
1ecc4d80 2185 wxCHECK_MSG( (m_widget != NULL), 12, "invalid window" );
47d67540 2186
1ecc4d80 2187 wxCHECK_MSG( m_font.Ok(), 12, "invalid font" );
47d67540 2188
1ecc4d80 2189 GdkFont *font = m_font.GetInternalFont( 1.0 );
ff8bfdbb 2190
1ecc4d80 2191 return font->ascent + font->descent;
c33c4050
RR
2192}
2193
68dda785 2194int wxWindow::GetCharWidth() const
c33c4050 2195{
1ecc4d80 2196 wxCHECK_MSG( (m_widget != NULL), 8, "invalid window" );
47d67540 2197
1ecc4d80 2198 wxCHECK_MSG( m_font.Ok(), 8, "invalid font" );
47d67540 2199
463c1fa1 2200 GdkFont *font = m_font.GetInternalFont( 1.0 );
ff8bfdbb 2201
463c1fa1 2202 return gdk_string_width( font, "H" );
c33c4050
RR
2203}
2204
2205void wxWindow::GetTextExtent( const wxString& string, int *x, int *y,
2206 int *descent, int *externalLeading, const wxFont *theFont, bool WXUNUSED(use16) ) const
2207{
463c1fa1
RR
2208 wxFont fontToUse = m_font;
2209 if (theFont) fontToUse = *theFont;
47d67540 2210
1ecc4d80 2211 wxCHECK_RET( fontToUse.Ok(), "invalid font" );
47d67540 2212
463c1fa1
RR
2213 GdkFont *font = fontToUse.GetInternalFont( 1.0 );
2214 if (x) (*x) = gdk_string_width( font, string );
2215 if (y) (*y) = font->ascent + font->descent;
2216 if (descent) (*descent) = font->descent;
2217 if (externalLeading) (*externalLeading) = 0; // ??
c33c4050
RR
2218}
2219
debe6624 2220void wxWindow::MakeModal( bool modal )
c801d85f 2221{
1ecc4d80 2222 return;
ff8bfdbb 2223
1ecc4d80
RR
2224 // Disable all other windows
2225 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
c801d85f 2226 {
1ecc4d80
RR
2227 wxNode *node = wxTopLevelWindows.First();
2228 while (node)
2229 {
2230 wxWindow *win = (wxWindow *)node->Data();
2231 if (win != this) win->Enable(!modal);
c801d85f 2232
1ecc4d80
RR
2233 node = node->Next();
2234 }
c801d85f 2235 }
c801d85f
KB
2236}
2237
b666df2c
RR
2238void wxWindow::OnKeyDown( wxKeyEvent &event )
2239{
2240 event.SetEventType( wxEVT_CHAR );
ff8bfdbb 2241
b666df2c
RR
2242 if (!GetEventHandler()->ProcessEvent( event ))
2243 {
2244 event.Skip();
2245 }
2246}
2247
68dda785 2248void wxWindow::SetFocus()
c801d85f 2249{
1ecc4d80 2250 wxCHECK_RET( (m_widget != NULL), "invalid window" );
ff8bfdbb 2251
463c1fa1
RR
2252 GtkWidget *connect_widget = GetConnectWidget();
2253 if (connect_widget)
c801d85f 2254 {
b292e2f5 2255 if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
463c1fa1
RR
2256 {
2257 gtk_widget_grab_focus (connect_widget);
2258 }
ff8bfdbb
VZ
2259 else if (GTK_IS_CONTAINER(connect_widget))
2260 {
2261 gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD );
2262 }
2263 else
2264 {
2265 }
362c6693 2266 }
362c6693 2267}
c801d85f 2268
b292e2f5
RR
2269wxWindow *wxWindow::FindFocus()
2270{
2271 return g_focusWindow;
2272}
2273
2274bool wxWindow::AcceptsFocus() const
2275{
2276 return IsEnabled() && IsShown() && m_acceptsFocus;
2277}
2278
c801d85f
KB
2279void wxWindow::AddChild( wxWindow *child )
2280{
1ecc4d80
RR
2281 wxCHECK_RET( (m_widget != NULL), "invalid window" );
2282 wxCHECK_RET( (child != NULL), "invalid child" );
47d67540 2283
463c1fa1 2284 m_children.Append( child );
362c6693 2285}
c801d85f 2286
463c1fa1
RR
2287wxWindow *wxWindow::ReParent( wxWindow *newParent )
2288{
1ecc4d80 2289 wxCHECK_MSG( (m_widget != NULL), (wxWindow*) NULL, "invalid window" );
ff8bfdbb 2290
1ecc4d80 2291 wxWindow *oldParent = GetParent();
8bbe427f 2292
1ecc4d80 2293 if (oldParent) oldParent->RemoveChild( this );
8bbe427f 2294
1ecc4d80 2295 gtk_widget_unparent( m_widget );
8bbe427f 2296
1ecc4d80
RR
2297 if (newParent)
2298 {
2299 newParent->AddChild( this );
2300 (newParent->m_insertCallback)( newParent, this );
2301 }
8bbe427f 2302
1ecc4d80 2303 return oldParent;
362c6693 2304}
c801d85f
KB
2305
2306void wxWindow::RemoveChild( wxWindow *child )
2307{
db1b4961 2308 m_children.DeleteObject( child );
463c1fa1 2309 child->m_parent = (wxWindow *) NULL;
362c6693 2310}
c801d85f
KB
2311
2312void wxWindow::SetReturnCode( int retCode )
2313{
463c1fa1 2314 m_retCode = retCode;
362c6693 2315}
c801d85f 2316
68dda785 2317int wxWindow::GetReturnCode()
c801d85f 2318{
463c1fa1 2319 return m_retCode;
362c6693 2320}
c801d85f 2321
68dda785 2322void wxWindow::Raise()
362c6693 2323{
1ecc4d80 2324 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2325
463c1fa1 2326 if (m_widget) gdk_window_raise( m_widget->window );
362c6693
RR
2327}
2328
68dda785 2329void wxWindow::Lower()
362c6693 2330{
1ecc4d80 2331 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2332
463c1fa1 2333 if (m_widget) gdk_window_lower( m_widget->window );
362c6693 2334}
c801d85f 2335
8bbe427f 2336wxEvtHandler *wxWindow::GetEventHandler() const
c801d85f 2337{
463c1fa1 2338 return m_eventHandler;
362c6693 2339}
c801d85f 2340
86b29a61 2341void wxWindow::SetEventHandler( wxEvtHandler *handler )
c801d85f 2342{
463c1fa1 2343 m_eventHandler = handler;
362c6693 2344}
c801d85f 2345
86b29a61
RR
2346void wxWindow::PushEventHandler(wxEvtHandler *handler)
2347{
463c1fa1
RR
2348 handler->SetNextHandler(GetEventHandler());
2349 SetEventHandler(handler);
86b29a61
RR
2350}
2351
2352wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
2353{
463c1fa1 2354 if (GetEventHandler())
e55ad60e 2355 {
463c1fa1
RR
2356 wxEvtHandler *handlerA = GetEventHandler();
2357 wxEvtHandler *handlerB = handlerA->GetNextHandler();
2358 handlerA->SetNextHandler((wxEvtHandler *) NULL);
2359 SetEventHandler(handlerB);
2360 if (deleteHandler)
2361 {
2362 delete handlerA;
2363 return (wxEvtHandler*) NULL;
2364 }
2365 else
2366 return handlerA;
2367 }
2368 else
2369 return (wxEvtHandler *) NULL;
86b29a61
RR
2370}
2371
68dda785 2372wxValidator *wxWindow::GetValidator()
c801d85f 2373{
463c1fa1 2374 return m_windowValidator;
362c6693 2375}
c801d85f 2376
6de97a3b 2377void wxWindow::SetValidator( const wxValidator& validator )
c801d85f 2378{
1ecc4d80
RR
2379 if (m_windowValidator) delete m_windowValidator;
2380 m_windowValidator = validator.Clone();
2381 if (m_windowValidator) m_windowValidator->SetWindow(this);
362c6693 2382}
c801d85f 2383
fd0eed64
RR
2384void wxWindow::SetClientObject( wxClientData *data )
2385{
1ecc4d80
RR
2386 if (m_clientObject) delete m_clientObject;
2387 m_clientObject = data;
fd0eed64
RR
2388}
2389
2390wxClientData *wxWindow::GetClientObject()
2391{
1ecc4d80 2392 return m_clientObject;
fd0eed64
RR
2393}
2394
2395void wxWindow::SetClientData( void *data )
2396{
1ecc4d80 2397 m_clientData = data;
fd0eed64
RR
2398}
2399
2400void *wxWindow::GetClientData()
2401{
1ecc4d80 2402 return m_clientData;
fd0eed64
RR
2403}
2404
68dda785 2405bool wxWindow::IsBeingDeleted()
c801d85f 2406{
1ecc4d80 2407 return FALSE;
362c6693 2408}
c801d85f
KB
2409
2410void wxWindow::SetId( wxWindowID id )
2411{
1ecc4d80 2412 m_windowId = id;
362c6693 2413}
c801d85f 2414
8bbe427f 2415wxWindowID wxWindow::GetId() const
c801d85f 2416{
1ecc4d80 2417 return m_windowId;
362c6693 2418}
c801d85f
KB
2419
2420void wxWindow::SetCursor( const wxCursor &cursor )
2421{
1ecc4d80 2422 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2423
1ecc4d80
RR
2424 if (cursor.Ok())
2425 {
2426 if (cursor == *m_cursor) return;
2427 *m_cursor = cursor;
2428 }
2429 else
2430 {
2431 *m_cursor = *wxSTANDARD_CURSOR;
2432 }
a3622daa 2433
1ecc4d80
RR
2434 if ((m_widget) && (m_widget->window))
2435 gdk_window_set_cursor( m_widget->window, m_cursor->GetCursor() );
47d67540 2436
1ecc4d80
RR
2437 if ((m_wxwindow) && (m_wxwindow->window))
2438 gdk_window_set_cursor( m_wxwindow->window, m_cursor->GetCursor() );
362c6693 2439}
c801d85f 2440
4f22cf8d
RR
2441void wxWindow::WarpPointer( int WXUNUSED(x), int WXUNUSED(y) )
2442{
2443 // TODO
2444}
2445
debe6624 2446void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f 2447{
139adb6a 2448 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2449
139adb6a 2450 if (eraseBackground && m_wxwindow && m_wxwindow->window)
c801d85f 2451 {
139adb6a
RR
2452 if (rect)
2453 {
2454 gdk_window_clear_area( m_wxwindow->window,
2455 rect->x, rect->y,
f234c60c 2456 rect->width, rect->height );
139adb6a
RR
2457 }
2458 else
2459 {
f234c60c 2460 gdk_window_clear( m_wxwindow->window );
139adb6a
RR
2461 }
2462 }
ff8bfdbb 2463
139adb6a
RR
2464 if (!rect)
2465 {
2466 if (m_wxwindow)
2467 gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
ff8bfdbb 2468 else
139adb6a 2469 gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
362c6693 2470 }
c801d85f 2471 else
139adb6a
RR
2472 {
2473 GdkRectangle gdk_rect;
2474 gdk_rect.x = rect->x;
2475 gdk_rect.y = rect->y;
2476 gdk_rect.width = rect->width;
2477 gdk_rect.height = rect->height;
2478
2479 if (m_wxwindow)
2480 gtk_widget_draw( m_wxwindow, &gdk_rect );
2481 else
2482 gtk_widget_draw( m_widget, &gdk_rect );
2483 }
362c6693 2484}
c801d85f 2485
8429bec1
RR
2486wxRegion wxWindow::GetUpdateRegion() const
2487{
2488 return m_updateRegion;
2489}
2490
2491bool wxWindow::IsExposed( int x, int y) const
c801d85f 2492{
1ecc4d80 2493 return (m_updateRegion.Contains( x, y ) != wxOutRegion );
362c6693 2494}
c801d85f 2495
8429bec1
RR
2496bool wxWindow::IsExposed( int x, int y, int w, int h ) const
2497{
1ecc4d80 2498 return (m_updateRegion.Contains( x, y, w, h ) != wxOutRegion );
8429bec1
RR
2499}
2500
2501bool wxWindow::IsExposed( const wxPoint& pt ) const
2502{
1ecc4d80 2503 return (m_updateRegion.Contains( pt.x, pt.y ) != wxOutRegion );
8429bec1
RR
2504}
2505
2506bool wxWindow::IsExposed( const wxRect& rect ) const
c801d85f 2507{
1ecc4d80 2508 return (m_updateRegion.Contains( rect.x, rect.y, rect.width, rect.height ) != wxOutRegion );
362c6693 2509}
c801d85f 2510
68dda785 2511void wxWindow::Clear()
c801d85f 2512{
3bc755fc 2513 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2514
f234c60c
RR
2515 if (m_wxwindow && m_wxwindow->window)
2516 {
2517 gdk_window_clear( m_wxwindow->window );
2518 }
362c6693 2519}
c801d85f 2520
ff8bfdbb 2521#if wxUSE_TOOLTIPS
b1170810
RR
2522void wxWindow::SetToolTip( const wxString &tip )
2523{
301cd871
RR
2524 if (m_toolTip)
2525 {
2526 m_toolTip->SetTip( tip );
2527 }
2528 else
2529 {
ff8bfdbb 2530 SetToolTip( new wxToolTip( tip ) );
301cd871 2531 }
ff8bfdbb
VZ
2532
2533 // setting empty tooltip text does not remove the tooltip any more for
2534 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
b1170810
RR
2535}
2536
2537void wxWindow::SetToolTip( wxToolTip *tip )
2538{
301cd871
RR
2539 if (m_toolTip)
2540 {
2541 m_toolTip->SetTip( (char*) NULL );
2542 delete m_toolTip;
2543 }
ff8bfdbb 2544
b1170810 2545 m_toolTip = tip;
ff8bfdbb
VZ
2546
2547 if (m_toolTip)
2548 m_toolTip->Apply( this );
b1170810
RR
2549}
2550
301cd871 2551void wxWindow::ApplyToolTip( GtkTooltips *tips, const char *tip )
b1170810 2552{
301cd871
RR
2553 gtk_tooltips_set_tip( tips, GetConnectWidget(), tip, (gchar*) NULL );
2554}
ff8bfdbb 2555#endif // wxUSE_TOOLTIPS
b1170810 2556
68dda785 2557wxColour wxWindow::GetBackgroundColour() const
c801d85f 2558{
3bc755fc 2559 return m_backgroundColour;
362c6693 2560}
c801d85f
KB
2561
2562void wxWindow::SetBackgroundColour( const wxColour &colour )
2563{
3bc755fc 2564 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2565
3bc755fc 2566 if (m_backgroundColour == colour) return;
8bbe427f 2567
3bc755fc
RR
2568 m_backgroundColour = colour;
2569 if (!m_backgroundColour.Ok()) return;
8bbe427f 2570
f234c60c 2571 if (m_wxwindow && m_wxwindow->window)
3bc755fc 2572 {
f234c60c
RR
2573 /* wxMSW doesn't clear the window here. I don't do that
2574 either to provide compatibility. call Clear() to do
2575 the job. */
2576
2577 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_wxwindow->window ) );
2578 gdk_window_set_background( m_wxwindow->window, m_backgroundColour.GetColor() );
3bc755fc 2579 }
8bbe427f 2580
ae0bdb01 2581 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
f234c60c 2582
ff8bfdbb
VZ
2583 if (sysbg.Red() == colour.Red() &&
2584 sysbg.Green() == colour.Green() &&
ae0bdb01
RR
2585 sysbg.Blue() == colour.Blue())
2586 {
2587 m_backgroundColour = wxNullColour;
2588 ApplyWidgetStyle();
ff8bfdbb
VZ
2589 m_backgroundColour = sysbg;
2590 }
ae0bdb01
RR
2591 else
2592 {
2593 ApplyWidgetStyle();
2594 }
362c6693 2595}
c801d85f 2596
68dda785 2597wxColour wxWindow::GetForegroundColour() const
6de97a3b 2598{
3bc755fc 2599 return m_foregroundColour;
6de97a3b
RR
2600}
2601
2602void wxWindow::SetForegroundColour( const wxColour &colour )
2603{
3bc755fc 2604 wxCHECK_RET( m_widget != NULL, "invalid window" );
a81258be 2605
3bc755fc 2606 if (m_foregroundColour == colour) return;
8bbe427f 2607
3bc755fc
RR
2608 m_foregroundColour = colour;
2609 if (!m_foregroundColour.Ok()) return;
8bbe427f 2610
ae0bdb01 2611 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
ff8bfdbb
VZ
2612 if (sysbg.Red() == colour.Red() &&
2613 sysbg.Green() == colour.Green() &&
ae0bdb01
RR
2614 sysbg.Blue() == colour.Blue())
2615 {
2616 m_backgroundColour = wxNullColour;
2617 ApplyWidgetStyle();
ff8bfdbb
VZ
2618 m_backgroundColour = sysbg;
2619 }
ae0bdb01
RR
2620 else
2621 {
2622 ApplyWidgetStyle();
2623 }
58614078
RR
2624}
2625
2626GtkStyle *wxWindow::GetWidgetStyle()
2627{
1ecc4d80 2628 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 2629
1ecc4d80
RR
2630 m_widgetStyle =
2631 gtk_style_copy(
2632 gtk_widget_get_style( m_widget ) );
8bbe427f 2633
1ecc4d80 2634 return m_widgetStyle;
58614078
RR
2635}
2636
2637void wxWindow::SetWidgetStyle()
2638{
1ecc4d80
RR
2639 GtkStyle *style = GetWidgetStyle();
2640
2641 gdk_font_unref( style->font );
2642 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
2643
2644 if (m_foregroundColour.Ok())
2645 {
2646 m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2647 style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
2648 style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
2649 style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
2650 }
2651
2652 if (m_backgroundColour.Ok())
2653 {
2654 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2655 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2656 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2657 style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2658 style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2659 style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2660 style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2661 style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2662 style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2663 }
a81258be
RR
2664}
2665
58614078 2666void wxWindow::ApplyWidgetStyle()
a81258be 2667{
6de97a3b
RR
2668}
2669
68dda785 2670bool wxWindow::Validate()
c801d85f 2671{
1ecc4d80 2672 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2673
1ecc4d80
RR
2674 wxNode *node = m_children.First();
2675 while (node)
2676 {
2677 wxWindow *child = (wxWindow *)node->Data();
2678 if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this))
ff8bfdbb
VZ
2679 {
2680 return FALSE;
2681 }
1ecc4d80
RR
2682 node = node->Next();
2683 }
2684 return TRUE;
362c6693 2685}
c801d85f 2686
68dda785 2687bool wxWindow::TransferDataToWindow()
c801d85f 2688{
1ecc4d80 2689 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2690
1ecc4d80
RR
2691 wxNode *node = m_children.First();
2692 while (node)
c801d85f 2693 {
1ecc4d80
RR
2694 wxWindow *child = (wxWindow *)node->Data();
2695 if (child->GetValidator() && /* child->GetValidator()->Ok() && */
2696 !child->GetValidator()->TransferToWindow() )
2697 {
2698 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK|wxICON_EXCLAMATION );
2699 return FALSE;
2700 }
2701 node = node->Next();
362c6693 2702 }
1ecc4d80 2703 return TRUE;
362c6693 2704}
c801d85f 2705
68dda785 2706bool wxWindow::TransferDataFromWindow()
c801d85f 2707{
1ecc4d80 2708 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2709
1ecc4d80
RR
2710 wxNode *node = m_children.First();
2711 while (node)
2712 {
2713 wxWindow *child = (wxWindow *)node->Data();
2714 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
ff8bfdbb
VZ
2715 {
2716 return FALSE;
2717 }
1ecc4d80
RR
2718 node = node->Next();
2719 }
2720 return TRUE;
362c6693 2721}
c801d85f 2722
bcf1fa6b
RR
2723void wxWindow::SetAcceleratorTable( const wxAcceleratorTable& accel )
2724{
1ecc4d80 2725 m_acceleratorTable = accel;
bcf1fa6b
RR
2726}
2727
c801d85f
KB
2728void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
2729{
1ecc4d80 2730 TransferDataToWindow();
362c6693 2731}
c801d85f 2732
68dda785 2733void wxWindow::InitDialog()
c801d85f 2734{
1ecc4d80 2735 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2736
1ecc4d80
RR
2737 wxInitDialogEvent event(GetId());
2738 event.SetEventObject( this );
2739 GetEventHandler()->ProcessEvent(event);
362c6693 2740}
c801d85f 2741
30dea054
RR
2742static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
2743{
1ecc4d80
RR
2744 menu->SetInvokingWindow( win );
2745 wxNode *node = menu->m_items.First();
2746 while (node)
2747 {
2748 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
2749 if (menuitem->IsSubMenu())
2750 {
ff8bfdbb
VZ
2751 SetInvokingWindow( menuitem->GetSubMenu(), win );
2752 }
1ecc4d80
RR
2753 node = node->Next();
2754 }
362c6693 2755}
30dea054 2756
0c77152e
RR
2757static gint gs_pop_x = 0;
2758static gint gs_pop_y = 0;
2759
2760static void pop_pos_callback( GtkMenu *menu, gint *x, gint *y, wxWindow *win )
2761{
2762 win->ClientToScreen( &gs_pop_x, &gs_pop_y );
2763 *x = gs_pop_x;
2764 *y = gs_pop_y;
2765}
2766
2767bool wxWindow::PopupMenu( wxMenu *menu, int x, int y )
30dea054 2768{
1ecc4d80 2769 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2770
1ecc4d80 2771 wxCHECK_MSG( menu != NULL, FALSE, "invalid popup-menu" );
8bbe427f 2772
1ecc4d80 2773 SetInvokingWindow( menu, this );
ff8bfdbb 2774
631f1bfe
JS
2775 menu->UpdateUI();
2776
0c77152e
RR
2777 gs_pop_x = x;
2778 gs_pop_y = y;
ff8bfdbb 2779
1ecc4d80 2780 gtk_menu_popup(
47d67540 2781 GTK_MENU(menu->m_menu),
0c77152e
RR
2782 (GtkWidget *) NULL, // parent menu shell
2783 (GtkWidget *) NULL, // parent menu item
2784 (GtkMenuPositionFunc) pop_pos_callback,
2785 (gpointer) this, // client data
2786 0, // button used to activate it
2787 0 //gs_timeLastClick // the time of activation
47d67540 2788 );
1ecc4d80 2789 return TRUE;
30dea054
RR
2790}
2791
06cfab17 2792#if wxUSE_DRAG_AND_DROP
ac57418f 2793
c801d85f
KB
2794void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
2795{
1ecc4d80 2796 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2797
1ecc4d80 2798 GtkWidget *dnd_widget = GetConnectWidget();
47d67540 2799
1ecc4d80 2800 if (m_dropTarget) m_dropTarget->UnregisterWidget( dnd_widget );
47d67540 2801
1ecc4d80
RR
2802 if (m_dropTarget) delete m_dropTarget;
2803 m_dropTarget = dropTarget;
47d67540 2804
1ecc4d80 2805 if (m_dropTarget) m_dropTarget->RegisterWidget( dnd_widget );
362c6693 2806}
c801d85f
KB
2807
2808wxDropTarget *wxWindow::GetDropTarget() const
2809{
1ecc4d80 2810 return m_dropTarget;
362c6693 2811}
c801d85f 2812
ac57418f
RR
2813#endif
2814
68dda785 2815GtkWidget* wxWindow::GetConnectWidget()
e3e65dac 2816{
1ecc4d80
RR
2817 GtkWidget *connect_widget = m_widget;
2818 if (m_wxwindow) connect_widget = m_wxwindow;
47d67540 2819
1ecc4d80 2820 return connect_widget;
e3e65dac 2821}
47d67540 2822
903f689b
RR
2823bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
2824{
1ecc4d80
RR
2825 if (m_wxwindow) return (window == m_wxwindow->window);
2826 return (window == m_widget->window);
903f689b
RR
2827}
2828
c801d85f
KB
2829void wxWindow::SetFont( const wxFont &font )
2830{
1ecc4d80 2831 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2832
1ecc4d80
RR
2833 if (((wxFont*)&font)->Ok())
2834 m_font = font;
2835 else
2836 m_font = *wxSWISS_FONT;
c801d85f 2837
ae0bdb01 2838 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
ff8bfdbb
VZ
2839 if (sysbg.Red() == m_backgroundColour.Red() &&
2840 sysbg.Green() == m_backgroundColour.Green() &&
ae0bdb01
RR
2841 sysbg.Blue() == m_backgroundColour.Blue())
2842 {
2843 m_backgroundColour = wxNullColour;
2844 ApplyWidgetStyle();
ff8bfdbb
VZ
2845 m_backgroundColour = sysbg;
2846 }
ae0bdb01
RR
2847 else
2848 {
2849 ApplyWidgetStyle();
2850 }
362c6693 2851}
c801d85f
KB
2852
2853void wxWindow::SetWindowStyleFlag( long flag )
2854{
1ecc4d80 2855 m_windowStyle = flag;
362c6693 2856}
c801d85f 2857
68dda785 2858long wxWindow::GetWindowStyleFlag() const
c801d85f 2859{
1ecc4d80 2860 return m_windowStyle;
362c6693 2861}
c801d85f 2862
68dda785 2863void wxWindow::CaptureMouse()
c801d85f 2864{
1ecc4d80 2865 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2866
1ecc4d80 2867 wxCHECK_RET( g_capturing == FALSE, "CaptureMouse called twice" );
47d67540 2868
1ecc4d80
RR
2869 GtkWidget *connect_widget = GetConnectWidget();
2870 gtk_grab_add( connect_widget );
2871 gdk_pointer_grab( connect_widget->window, FALSE,
2872 (GdkEventMask)
2873 (GDK_BUTTON_PRESS_MASK |
2874 GDK_BUTTON_RELEASE_MASK |
2875 GDK_POINTER_MOTION_MASK),
ff8bfdbb
VZ
2876 (GdkWindow *) NULL,
2877 (GdkCursor *) NULL,
2878 GDK_CURRENT_TIME );
1ecc4d80 2879 g_capturing = TRUE;
362c6693 2880}
c801d85f 2881
68dda785 2882void wxWindow::ReleaseMouse()
c801d85f 2883{
1ecc4d80 2884 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2885
1ecc4d80 2886 wxCHECK_RET( g_capturing == TRUE, "ReleaseMouse called twice" );
47d67540 2887
1ecc4d80
RR
2888 GtkWidget *connect_widget = GetConnectWidget();
2889 gtk_grab_remove( connect_widget );
2890 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
2891 g_capturing = FALSE;
362c6693 2892}
c801d85f
KB
2893
2894void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
2895{
362c6693 2896}
c801d85f 2897
68dda785 2898wxString wxWindow::GetTitle() const
c801d85f 2899{
1ecc4d80 2900 return (wxString&)m_windowName;
362c6693 2901}
c801d85f 2902
68dda785 2903wxString wxWindow::GetLabel() const
c801d85f 2904{
1ecc4d80 2905 return GetTitle();
362c6693 2906}
c801d85f
KB
2907
2908void wxWindow::SetName( const wxString &name )
2909{
1ecc4d80 2910 m_windowName = name;
362c6693 2911}
c801d85f 2912
68dda785 2913wxString wxWindow::GetName() const
c801d85f 2914{
1ecc4d80 2915 return (wxString&)m_windowName;
362c6693 2916}
c801d85f 2917
68dda785 2918bool wxWindow::IsShown() const
c801d85f 2919{
1ecc4d80 2920 return m_isShown;
362c6693 2921}
c801d85f 2922
68dda785 2923bool wxWindow::IsRetained()
c801d85f 2924{
1ecc4d80 2925 return FALSE;
362c6693 2926}
c801d85f 2927
debe6624 2928wxWindow *wxWindow::FindWindow( long id )
c801d85f 2929{
1ecc4d80
RR
2930 if (id == m_windowId) return this;
2931 wxNode *node = m_children.First();
2932 while (node)
2933 {
2934 wxWindow *child = (wxWindow*)node->Data();
2935 wxWindow *res = child->FindWindow( id );
2936 if (res) return res;
2937 node = node->Next();
2938 }
2939 return (wxWindow *) NULL;
362c6693 2940}
c801d85f
KB
2941
2942wxWindow *wxWindow::FindWindow( const wxString& name )
2943{
1ecc4d80
RR
2944 if (name == m_windowName) return this;
2945 wxNode *node = m_children.First();
2946 while (node)
2947 {
2948 wxWindow *child = (wxWindow*)node->Data();
2949 wxWindow *res = child->FindWindow( name );
2950 if (res) return res;
2951 node = node->Next();
2952 }
2953 return (wxWindow *) NULL;
362c6693 2954}
c801d85f 2955
debe6624 2956void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
cb43b372 2957 int range, bool refresh )
c801d85f 2958{
1ecc4d80 2959 wxCHECK_RET( m_widget != NULL, "invalid window" );
8bbe427f 2960
1ecc4d80 2961 wxCHECK_RET( m_wxwindow != NULL, "window needs client area for scrolling" );
c801d85f 2962
1ecc4d80 2963 m_hasScrolling = TRUE;
47d67540 2964
1ecc4d80 2965 if (orient == wxHORIZONTAL)
cb43b372 2966 {
1ecc4d80
RR
2967 float fpos = (float)pos;
2968 float frange = (float)range;
2969 float fthumb = (float)thumbVisible;
2970 if (fpos > frange-fthumb) fpos = frange-fthumb;
2971 if (fpos < 0.0) fpos = 0.0;
2972
2973 if ((fabs(frange-m_hAdjust->upper) < 0.2) &&
2974 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
2975 {
2976 SetScrollPos( orient, pos, refresh );
2977 return;
2978 }
47d67540 2979
1ecc4d80 2980 m_oldHorizontalPos = fpos;
47d67540 2981
1ecc4d80
RR
2982 m_hAdjust->lower = 0.0;
2983 m_hAdjust->upper = frange;
2984 m_hAdjust->value = fpos;
2985 m_hAdjust->step_increment = 1.0;
2986 m_hAdjust->page_increment = (float)(wxMax(fthumb,0));
2987 m_hAdjust->page_size = fthumb;
cb43b372 2988 }
1ecc4d80
RR
2989 else
2990 {
2991 float fpos = (float)pos;
2992 float frange = (float)range;
2993 float fthumb = (float)thumbVisible;
2994 if (fpos > frange-fthumb) fpos = frange-fthumb;
2995 if (fpos < 0.0) fpos = 0.0;
2996
2997 if ((fabs(frange-m_vAdjust->upper) < 0.2) &&
2998 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
2999 {
3000 SetScrollPos( orient, pos, refresh );
3001 return;
3002 }
47d67540 3003
1ecc4d80 3004 m_oldVerticalPos = fpos;
47d67540 3005
1ecc4d80
RR
3006 m_vAdjust->lower = 0.0;
3007 m_vAdjust->upper = frange;
3008 m_vAdjust->value = fpos;
3009 m_vAdjust->step_increment = 1.0;
3010 m_vAdjust->page_increment = (float)(wxMax(fthumb,0));
3011 m_vAdjust->page_size = fthumb;
3012 }
47d67540 3013
1ecc4d80
RR
3014 if (m_wxwindow->window)
3015 {
3016 if (orient == wxHORIZONTAL)
3017 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
3018 else
3019 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
47d67540 3020
1ecc4d80
RR
3021 gtk_widget_set_usize( m_widget, m_width, m_height );
3022 }
362c6693 3023}
c801d85f 3024
debe6624 3025void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f 3026{
1ecc4d80
RR
3027 wxCHECK_RET( m_widget != NULL, "invalid window" );
3028
3029 wxCHECK_RET( m_wxwindow != NULL, "window needs client area for scrolling" );
3030
3031 if (orient == wxHORIZONTAL)
3032 {
3033 float fpos = (float)pos;
3034 if (fpos > m_hAdjust->upper - m_hAdjust->page_size) fpos = m_hAdjust->upper - m_hAdjust->page_size;
3035 if (fpos < 0.0) fpos = 0.0;
3036 m_oldHorizontalPos = fpos;
3037
3038 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
3039 m_hAdjust->value = fpos;
3040 }
3041 else
3042 {
3043 float fpos = (float)pos;
3044 if (fpos > m_vAdjust->upper - m_vAdjust->page_size) fpos = m_vAdjust->upper - m_vAdjust->page_size;
3045 if (fpos < 0.0) fpos = 0.0;
3046 m_oldVerticalPos = fpos;
ff8bfdbb 3047
1ecc4d80
RR
3048 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
3049 m_vAdjust->value = fpos;
3050 }
47d67540 3051
1ecc4d80 3052 if (!m_isScrolling)
47d67540 3053 {
1ecc4d80
RR
3054 if (m_wxwindow->window)
3055 {
3056 if (orient == wxHORIZONTAL)
3057 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
3058 else
3059 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
3060 }
cb43b372 3061 }
362c6693 3062}
c801d85f 3063
debe6624 3064int wxWindow::GetScrollThumb( int orient ) const
c801d85f 3065{
1ecc4d80 3066 wxCHECK_MSG( m_widget != NULL, 0, "invalid window" );
47d67540 3067
1ecc4d80 3068 wxCHECK_MSG( m_wxwindow != NULL, 0, "window needs client area for scrolling" );
47d67540 3069
1ecc4d80
RR
3070 if (orient == wxHORIZONTAL)
3071 return (int)(m_hAdjust->page_size+0.5);
3072 else
3073 return (int)(m_vAdjust->page_size+0.5);
362c6693 3074}
c801d85f 3075
debe6624 3076int wxWindow::GetScrollPos( int orient ) const
c801d85f 3077{
1ecc4d80 3078 wxCHECK_MSG( m_widget != NULL, 0, "invalid window" );
47d67540 3079
1ecc4d80 3080 wxCHECK_MSG( m_wxwindow != NULL, 0, "window needs client area for scrolling" );
c801d85f 3081
1ecc4d80
RR
3082 if (orient == wxHORIZONTAL)
3083 return (int)(m_hAdjust->value+0.5);
3084 else
3085 return (int)(m_vAdjust->value+0.5);
362c6693 3086}
c801d85f 3087
debe6624 3088int wxWindow::GetScrollRange( int orient ) const
c801d85f 3089{
1ecc4d80 3090 wxCHECK_MSG( m_widget != NULL, 0, "invalid window" );
47d67540 3091
1ecc4d80 3092 wxCHECK_MSG( m_wxwindow != NULL, 0, "window needs client area for scrolling" );
c801d85f 3093
1ecc4d80
RR
3094 if (orient == wxHORIZONTAL)
3095 return (int)(m_hAdjust->upper+0.5);
3096 else
3097 return (int)(m_vAdjust->upper+0.5);
362c6693 3098}
c801d85f 3099
debe6624 3100void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f 3101{
1ecc4d80 3102 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 3103
1ecc4d80 3104 wxCHECK_RET( m_wxwindow != NULL, "window needs client area for scrolling" );
c801d85f
KB
3105
3106 int cw = 0;
3107 int ch = 0;
3108 GetClientSize( &cw, &ch );
47d67540 3109
c801d85f
KB
3110 int w = cw - abs(dx);
3111 int h = ch - abs(dy);
3112 if ((h < 0) || (w < 0))
3113 {
1ecc4d80
RR
3114 Refresh();
3115 return;
362c6693 3116 }
c801d85f
KB
3117 int s_x = 0;
3118 int s_y = 0;
3119 if (dx < 0) s_x = -dx;
3120 if (dy < 0) s_y = -dy;
3121 int d_x = 0;
3122 int d_y = 0;
3123 if (dx > 0) d_x = dx;
3124 if (dy > 0) d_y = dy;
8bbe427f 3125
32e9da8b
RR
3126 if (!m_scrollGC)
3127 {
1ecc4d80
RR
3128 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3129 gdk_gc_set_exposures( m_scrollGC, TRUE );
32e9da8b 3130 }
8bbe427f 3131
32e9da8b 3132 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
1ecc4d80 3133 m_wxwindow->window, s_x, s_y, w, h );
47d67540 3134
c801d85f
KB
3135 wxRect rect;
3136 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3137 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3138 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3139 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
47d67540 3140
c801d85f 3141 Refresh( TRUE, &rect );
362c6693 3142}
c801d85f
KB
3143
3144//-------------------------------------------------------------------------------------
3145// Layout
3146//-------------------------------------------------------------------------------------
3147
68dda785 3148wxLayoutConstraints *wxWindow::GetConstraints() const
c801d85f
KB
3149{
3150 return m_constraints;
362c6693 3151}
c801d85f
KB
3152
3153void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
3154{
3155 if (m_constraints)
3156 {
3157 UnsetConstraints(m_constraints);
3158 delete m_constraints;
3159 }
3160 m_constraints = constraints;
3161 if (m_constraints)
3162 {
3163 // Make sure other windows know they're part of a 'meaningful relationship'
3164 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
3165 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3166 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
3167 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3168 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
3169 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3170 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
3171 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3172 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
3173 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3174 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
3175 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3176 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
3177 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3178 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
3179 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3180 }
3181;
3182}
3183;
3184
debe6624 3185void wxWindow::SetAutoLayout( bool autoLayout )
c801d85f
KB
3186{
3187 m_autoLayout = autoLayout;
362c6693 3188}
c801d85f 3189
68dda785 3190bool wxWindow::GetAutoLayout() const
c801d85f
KB
3191{
3192 return m_autoLayout;
362c6693 3193}
c801d85f 3194
68dda785 3195wxSizer *wxWindow::GetSizer() const
c801d85f
KB
3196{
3197 return m_windowSizer;
362c6693 3198}
c801d85f
KB
3199
3200void wxWindow::SetSizerParent( wxWindow *win )
3201{
3202 m_sizerParent = win;
362c6693 3203}
c801d85f 3204
68dda785 3205wxWindow *wxWindow::GetSizerParent() const
c801d85f
KB
3206{
3207 return m_sizerParent;
362c6693 3208}
c801d85f
KB
3209
3210// This removes any dangling pointers to this window
3211// in other windows' constraintsInvolvedIn lists.
3212void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
3213{
3214 if (c)
3215 {
3216 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3217 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3218 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3219 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3220 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
3221 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3222 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
3223 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3224 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
3225 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3226 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
3227 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3228 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
3229 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3230 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
3231 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3232 }
3233}
3234
3235// Back-pointer to other windows we're involved with, so if we delete
3236// this window, we must delete any constraints we're involved with.
3237void wxWindow::AddConstraintReference(wxWindow *otherWin)
3238{
3239 if (!m_constraintsInvolvedIn)
3240 m_constraintsInvolvedIn = new wxList;
3241 if (!m_constraintsInvolvedIn->Member(otherWin))
3242 m_constraintsInvolvedIn->Append(otherWin);
3243}
3244
3245// REMOVE back-pointer to other windows we're involved with.
3246void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
3247{
3248 if (m_constraintsInvolvedIn)
3249 m_constraintsInvolvedIn->DeleteObject(otherWin);
3250}
3251
3252// Reset any constraints that mention this window
68dda785 3253void wxWindow::DeleteRelatedConstraints()
c801d85f
KB
3254{
3255 if (m_constraintsInvolvedIn)
3256 {
3257 wxNode *node = m_constraintsInvolvedIn->First();
3258 while (node)
3259 {
3260 wxWindow *win = (wxWindow *)node->Data();
3261 wxNode *next = node->Next();
3262 wxLayoutConstraints *constr = win->GetConstraints();
3263
3264 // Reset any constraints involving this window
3265 if (constr)
3266 {
3267 constr->left.ResetIfWin((wxWindow *)this);
3268 constr->top.ResetIfWin((wxWindow *)this);
3269 constr->right.ResetIfWin((wxWindow *)this);
3270 constr->bottom.ResetIfWin((wxWindow *)this);
3271 constr->width.ResetIfWin((wxWindow *)this);
3272 constr->height.ResetIfWin((wxWindow *)this);
3273 constr->centreX.ResetIfWin((wxWindow *)this);
3274 constr->centreY.ResetIfWin((wxWindow *)this);
3275 }
3276 delete node;
3277 node = next;
3278 }
3279 delete m_constraintsInvolvedIn;
c67daf87 3280 m_constraintsInvolvedIn = (wxList *) NULL;
c801d85f
KB
3281 }
3282}
3283
3284void wxWindow::SetSizer(wxSizer *sizer)
3285{
3286 m_windowSizer = sizer;
3287 if (sizer)
3288 sizer->SetSizerParent((wxWindow *)this);
3289}
3290
3291/*
3292 * New version
3293 */
3294
68dda785 3295bool wxWindow::Layout()
c801d85f
KB
3296{
3297 if (GetConstraints())
3298 {
3299 int w, h;
3300 GetClientSize(&w, &h);
3301 GetConstraints()->width.SetValue(w);
3302 GetConstraints()->height.SetValue(h);
3303 }
47d67540 3304
c801d85f
KB
3305 // If top level (one sizer), evaluate the sizer's constraints.
3306 if (GetSizer())
3307 {
3308 int noChanges;
3309 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3310 GetSizer()->LayoutPhase1(&noChanges);
3311 GetSizer()->LayoutPhase2(&noChanges);
3312 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3313 return TRUE;
3314 }
3315 else
3316 {
3317 // Otherwise, evaluate child constraints
3318 ResetConstraints(); // Mark all constraints as unevaluated
3319 DoPhase(1); // Just one phase need if no sizers involved
3320 DoPhase(2);
3321 SetConstraintSizes(); // Recursively set the real window sizes
3322 }
3323 return TRUE;
3324}
3325
3326
3327// Do a phase of evaluating constraints:
3328// the default behaviour. wxSizers may do a similar
3329// thing, but also impose their own 'constraints'
3330// and order the evaluation differently.
3331bool wxWindow::LayoutPhase1(int *noChanges)
3332{
3333 wxLayoutConstraints *constr = GetConstraints();
3334 if (constr)
3335 {
3336 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
3337 }
3338 else
3339 return TRUE;
3340}
3341
3342bool wxWindow::LayoutPhase2(int *noChanges)
3343{
3344 *noChanges = 0;
47d67540 3345
c801d85f
KB
3346 // Layout children
3347 DoPhase(1);
3348 DoPhase(2);
3349 return TRUE;
3350}
3351
3352// Do a phase of evaluating child constraints
debe6624 3353bool wxWindow::DoPhase(int phase)
c801d85f
KB
3354{
3355 int noIterations = 0;
3356 int maxIterations = 500;
3357 int noChanges = 1;
3358 int noFailures = 0;
3359 wxList succeeded;
3360 while ((noChanges > 0) && (noIterations < maxIterations))
3361 {
3362 noChanges = 0;
3363 noFailures = 0;
8bbe427f 3364 wxNode *node = m_children.First();
c801d85f
KB
3365 while (node)
3366 {
3367 wxWindow *child = (wxWindow *)node->Data();
3368 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
3369 {
3370 wxLayoutConstraints *constr = child->GetConstraints();
3371 if (constr)
3372 {
3373 if (succeeded.Member(child))
3374 {
3375 }
3376 else
3377 {
3378 int tempNoChanges = 0;
3379 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
3380 noChanges += tempNoChanges;
3381 if (success)
3382 {
3383 succeeded.Append(child);
3384 }
3385 }
3386 }
3387 }
3388 node = node->Next();
3389 }
3390 noIterations ++;
3391 }
3392 return TRUE;
3393}
3394
68dda785 3395void wxWindow::ResetConstraints()
c801d85f
KB
3396{
3397 wxLayoutConstraints *constr = GetConstraints();
3398 if (constr)
3399 {
3400 constr->left.SetDone(FALSE);
3401 constr->top.SetDone(FALSE);
3402 constr->right.SetDone(FALSE);
3403 constr->bottom.SetDone(FALSE);
3404 constr->width.SetDone(FALSE);
3405 constr->height.SetDone(FALSE);
3406 constr->centreX.SetDone(FALSE);
3407 constr->centreY.SetDone(FALSE);
3408 }
db1b4961 3409 wxNode *node = m_children.First();
c801d85f
KB
3410 while (node)
3411 {
3412 wxWindow *win = (wxWindow *)node->Data();
3413 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
3414 win->ResetConstraints();
3415 node = node->Next();
3416 }
3417}
3418
3419// Need to distinguish between setting the 'fake' size for
3420// windows and sizers, and setting the real values.
debe6624 3421void wxWindow::SetConstraintSizes(bool recurse)
c801d85f
KB
3422{
3423 wxLayoutConstraints *constr = GetConstraints();
3424 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
3425 constr->width.GetDone() && constr->height.GetDone())
3426 {
3427 int x = constr->left.GetValue();
3428 int y = constr->top.GetValue();
3429 int w = constr->width.GetValue();
3430 int h = constr->height.GetValue();
3431
3432 // If we don't want to resize this window, just move it...
3433 if ((constr->width.GetRelationship() != wxAsIs) ||
3434 (constr->height.GetRelationship() != wxAsIs))
3435 {
3436 // Calls Layout() recursively. AAAGH. How can we stop that.
3437 // Simply take Layout() out of non-top level OnSizes.
3438 SizerSetSize(x, y, w, h);
3439 }
3440 else
3441 {
3442 SizerMove(x, y);
3443 }
3444 }
3445 else if (constr)
3446 {
3447 char *windowClass = this->GetClassInfo()->GetClassName();
3448
3449 wxString winName;
5e0aa05a 3450 if (GetName() == "")
3069ac4e 3451 winName = "unnamed";
5e0aa05a
VZ
3452 else
3453 winName = GetName();
ff8bfdbb
VZ
3454 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3455 (const char *)windowClass,
3456 (const char *)winName);
3069ac4e
RR
3457 if (!constr->left.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3458 if (!constr->right.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3459 if (!constr->width.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3460 if (!constr->height.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3461 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
c801d85f
KB
3462 }
3463
3464 if (recurse)
3465 {
db1b4961 3466 wxNode *node = m_children.First();
c801d85f
KB
3467 while (node)
3468 {
3469 wxWindow *win = (wxWindow *)node->Data();
3470 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
3471 win->SetConstraintSizes();
3472 node = node->Next();
3473 }
3474 }
3475}
3476
3477// This assumes that all sizers are 'on' the same
3478// window, i.e. the parent of this window.
3479void wxWindow::TransformSizerToActual(int *x, int *y) const
3480{
3481 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
5e0aa05a 3482 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
c801d85f 3483 return;
47d67540 3484
c801d85f
KB
3485 int xp, yp;
3486 m_sizerParent->GetPosition(&xp, &yp);
3487 m_sizerParent->TransformSizerToActual(&xp, &yp);
3488 *x += xp;
3489 *y += yp;
3490}
3491
debe6624 3492void wxWindow::SizerSetSize(int x, int y, int w, int h)
c801d85f 3493{
5e0aa05a
VZ
3494 int xx = x;
3495 int yy = y;
c801d85f
KB
3496 TransformSizerToActual(&xx, &yy);
3497 SetSize(xx, yy, w, h);
3498}
3499
debe6624 3500void wxWindow::SizerMove(int x, int y)
c801d85f 3501{
5e0aa05a
VZ
3502 int xx = x;
3503 int yy = y;
c801d85f
KB
3504 TransformSizerToActual(&xx, &yy);
3505 Move(xx, yy);
3506}
3507
3508// Only set the size/position of the constraint (if any)
debe6624 3509void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
c801d85f
KB
3510{
3511 wxLayoutConstraints *constr = GetConstraints();
3512 if (constr)
3513 {
3514 if (x != -1)
3515 {
3516 constr->left.SetValue(x);
3517 constr->left.SetDone(TRUE);
3518 }
3519 if (y != -1)
3520 {
3521 constr->top.SetValue(y);
3522 constr->top.SetDone(TRUE);
3523 }
3524 if (w != -1)
3525 {
3526 constr->width.SetValue(w);
3527 constr->width.SetDone(TRUE);
3528 }
3529 if (h != -1)
3530 {
3531 constr->height.SetValue(h);
3532 constr->height.SetDone(TRUE);
3533 }
3534 }
3535}
3536
debe6624 3537void wxWindow::MoveConstraint(int x, int y)
c801d85f
KB
3538{
3539 wxLayoutConstraints *constr = GetConstraints();
3540 if (constr)
3541 {
3542 if (x != -1)
3543 {
3544 constr->left.SetValue(x);
3545 constr->left.SetDone(TRUE);
3546 }
3547 if (y != -1)
3548 {
3549 constr->top.SetValue(y);
3550 constr->top.SetDone(TRUE);
3551 }
3552 }
3553}
3554
3555void wxWindow::GetSizeConstraint(int *w, int *h) const
3556{
3557 wxLayoutConstraints *constr = GetConstraints();
3558 if (constr)
3559 {
3560 *w = constr->width.GetValue();
3561 *h = constr->height.GetValue();
3562 }
3563 else
3564 GetSize(w, h);
3565}
3566
3567void wxWindow::GetClientSizeConstraint(int *w, int *h) const
3568{
3569 wxLayoutConstraints *constr = GetConstraints();
3570 if (constr)
3571 {
3572 *w = constr->width.GetValue();
3573 *h = constr->height.GetValue();
3574 }
3575 else
3576 GetClientSize(w, h);
3577}
3578
3579void wxWindow::GetPositionConstraint(int *x, int *y) const
3580{
b292e2f5
RR
3581 wxLayoutConstraints *constr = GetConstraints();
3582 if (constr)
c801d85f
KB
3583 {
3584 *x = constr->left.GetValue();
3585 *y = constr->top.GetValue();
3586 }
3587 else
3588 GetPosition(x, y);
3589}
3590