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