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