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