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