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