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