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