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