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