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