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