]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/window.cpp
Test for image conversion correctness.
[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{
c801d85f
KB
127 if (!win->HasVMT()) return;
128 if (g_blockEventsOnDrag) return;
47d67540 129
c801d85f
KB
130 win->m_updateRegion.Union( gdk_event->area.x,
131 gdk_event->area.y,
47d67540 132 gdk_event->area.width,
2f2aa628 133 gdk_event->area.height );
47d67540 134
c801d85f
KB
135 if (gdk_event->count > 0) return;
136
d8c83875 137/*
a81258be 138 printf( "OnExpose from " );
d8c83875
RR
139 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
140 printf( win->GetClassInfo()->GetClassName() );
141 printf( ".\n" );
142*/
143
c801d85f
KB
144 wxPaintEvent event( win->GetId() );
145 event.SetEventObject( win );
2f2aa628 146 win->GetEventHandler()->ProcessEvent( event );
47d67540 147
c801d85f 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{
c801d85f
KB
157 if (!win->HasVMT()) return;
158 if (g_blockEventsOnDrag) return;
47d67540 159
c801d85f 160 win->m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
47d67540 161
c801d85f
KB
162 wxPaintEvent event( win->GetId() );
163 event.SetEventObject( win );
2f2aa628 164 win->GetEventHandler()->ProcessEvent( event );
47d67540 165
c801d85f 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{
c801d85f
KB
175 if (!win->HasVMT()) return FALSE;
176 if (g_blockEventsOnDrag) return FALSE;
177
178/*
179 printf( "OnKeyPress from " );
180 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
181 printf( win->GetClassInfo()->GetClassName() );
182 printf( ".\n" );
183*/
184
185 long key_code = 0;
186 switch (gdk_event->keyval)
187 {
2f2aa628
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;
c801d85f
KB
256 default:
257 {
47d67540 258 if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF))
c801d85f 259 key_code = gdk_event->keyval;
362c6693
RR
260 }
261 }
c801d85f
KB
262
263 if (!key_code) return FALSE;
47d67540 264
c801d85f
KB
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
2f2aa628 275 bool ret = win->GetEventHandler()->ProcessEvent( event );
47d67540 276
bcf1fa6b
RR
277 if (!ret)
278 {
66c135f3
RR
279 wxWindow *ancestor = win;
280 while (ancestor)
47d67540 281 {
66c135f3
RR
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 );
47d67540 287 break;
66c135f3
RR
288 }
289 ancestor = ancestor->GetParent();
bcf1fa6b
RR
290 }
291 }
47d67540 292
30f82ea4
RR
293 if (ret)
294 {
47d67540 295 if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF))
30f82ea4
RR
296 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
297 }
47d67540 298
66bd6b93 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
RR
307{
308 if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
47d67540 309
e3e65dac 310 if (g_blockEventsOnDrag) return TRUE;
c801d85f
KB
311
312 if (win->m_wxwindow)
313 {
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
KB
318/*
319 printf( "GrabFocus from " );
320 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
321 printf( win->GetClassInfo()->GetClassName() );
322 printf( ".\n" );
323*/
47d67540 324
362c6693
RR
325 }
326 }
47d67540 327
e3e65dac 328 if (!win->HasVMT()) return TRUE;
97b3455a 329
8429bec1 330/*
c801d85f
KB
331 printf( "OnButtonPress from " );
332 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
333 printf( win->GetClassInfo()->GetClassName() );
334 printf( ".\n" );
8429bec1 335*/
30dea054 336
7798a18e 337 wxEventType event_type = wxEVT_LEFT_DOWN;
47d67540 338
c801d85f
KB
339 if (gdk_event->button == 1)
340 {
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;
362c6693 346 }
c801d85f
KB
347 }
348 else if (gdk_event->button == 2)
349 {
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;
362c6693 355 }
c801d85f
KB
356 }
357 else if (gdk_event->button == 3)
358 {
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;
362c6693
RR
364 }
365 }
47d67540 366
c801d85f
KB
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
c801d85f
KB
376 event.m_x = (long)gdk_event->x;
377 event.m_y = (long)gdk_event->y;
47d67540 378
2f2aa628 379 // Some control don't have their own X window and thus cannot get
47d67540
VZ
380 // any events.
381
6987a6c3 382 if (!g_capturing)
2f2aa628 383 {
6987a6c3
RR
384 wxNode *node = win->GetChildren()->First();
385 while (node)
2f2aa628 386 {
6987a6c3
RR
387 wxWindow *child = (wxWindow*)node->Data();
388 if ((child->m_x <= event.m_x) &&
389 (child->m_y <= event.m_y) &&
47d67540
VZ
390 (child->m_x+child->m_width >= event.m_x) &&
391 (child->m_y+child->m_height >= event.m_y))
6987a6c3
RR
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();
2f2aa628 399 }
2f2aa628 400 }
47d67540 401
c801d85f 402 event.SetEventObject( win );
47d67540
VZ
403
404 gs_timeLastClick = gdk_event->time;
405
2f2aa628
RR
406 if (win->GetEventHandler()->ProcessEvent( event ))
407 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" );
47d67540 408
c801d85f 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{
903f689b 418 if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
47d67540 419
e3e65dac 420 if (g_blockEventsOnDrag) return TRUE;
c801d85f 421
e3e65dac 422 if (!win->HasVMT()) return TRUE;
47d67540 423
c801d85f
KB
424/*
425 printf( "OnButtonRelease from " );
426 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
427 printf( win->GetClassInfo()->GetClassName() );
428 printf( ".\n" );
429*/
47d67540 430
7798a18e 431 wxEventType event_type = wxEVT_NULL;
47d67540 432
c801d85f
KB
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;
362c6693 438 }
c801d85f
KB
439
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;
47d67540 450
2f2aa628 451 // Some control don't have their own X window and thus cannot get
47d67540
VZ
452 // any events.
453
6987a6c3 454 if (!g_capturing)
2f2aa628 455 {
6987a6c3
RR
456 wxNode *node = win->GetChildren()->First();
457 while (node)
2f2aa628 458 {
6987a6c3
RR
459 wxWindow *child = (wxWindow*)node->Data();
460 if ((child->m_x <= event.m_x) &&
461 (child->m_y <= event.m_y) &&
47d67540
VZ
462 (child->m_x+child->m_width >= event.m_x) &&
463 (child->m_y+child->m_height >= event.m_y))
6987a6c3
RR
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();
2f2aa628 471 }
2f2aa628 472 }
47d67540 473
c801d85f 474 event.SetEventObject( win );
47d67540 475
2f2aa628
RR
476 if (win->GetEventHandler()->ProcessEvent( event ))
477 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" );
47d67540 478
e3e65dac 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{
875 gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
876 GTK_WIDGET(child->m_widget),
877 child->m_x,
878 child->m_y );
879
880 gtk_widget_set_usize( GTK_WIDGET(child->m_widget),
881 child->m_width,
882 child->m_height );
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
KB
903 m_children.DeleteContents( FALSE );
904 m_x = 0;
905 m_y = 0;
906 m_width = 0;
907 m_height = 0;
2f2aa628
RR
908 m_minWidth = -1;
909 m_minHeight = -1;
910 m_maxWidth = -1;
911 m_maxHeight = -1;
c801d85f
KB
912 m_retCode = 0;
913 m_eventHandler = this;
c67daf87 914 m_windowValidator = (wxValidator *) NULL;
c801d85f 915 m_windowId = -1;
d8c83875 916 m_cursor = (wxCursor *) NULL;
c801d85f
KB
917 m_font = *wxSWISS_FONT;
918 m_windowStyle = 0;
919 m_windowName = "noname";
c67daf87
UR
920 m_constraints = (wxLayoutConstraints *) NULL;
921 m_constraintsInvolvedIn = (wxList *) NULL;
922 m_windowSizer = (wxSizer *) NULL;
923 m_sizerParent = (wxWindow *) NULL;
c801d85f
KB
924 m_autoLayout = FALSE;
925 m_sizeSet = FALSE;
926 m_hasVMT = FALSE;
927 m_needParent = TRUE;
928 m_hasScrolling = FALSE;
cb43b372 929 m_isScrolling = FALSE;
c67daf87
UR
930 m_hAdjust = (GtkAdjustment *) NULL;
931 m_vAdjust = (GtkAdjustment *) NULL;
c801d85f
KB
932 m_oldHorizontalPos = 0.0;
933 m_oldVerticalPos = 0.0;
934 m_isShown = FALSE;
935 m_isEnabled = TRUE;
c67daf87 936 m_pDropTarget = (wxDropTarget *) NULL;
33d0b396 937 m_resizing = FALSE;
32e9da8b 938 m_scrollGC = (GdkGC*) NULL;
a81258be 939 m_widgetStyle = (GtkStyle*) NULL;
6ca41e57 940 m_insertCallback = wxInsertChildInWindow;
362c6693 941}
c801d85f 942
6ca41e57
RR
943wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
944 const wxPoint &pos, const wxSize &size,
945 long style, const wxString &name )
946{
947 m_insertCallback = wxInsertChildInWindow;
948 Create( parent, id, pos, size, style, name );
949}
950
debe6624
JS
951bool wxWindow::Create( wxWindow *parent, wxWindowID id,
952 const wxPoint &pos, const wxSize &size,
6de97a3b 953 long style, const wxString &name )
c801d85f
KB
954{
955 m_isShown = FALSE;
956 m_isEnabled = TRUE;
957 m_needParent = TRUE;
47d67540 958
c801d85f 959 PreCreation( parent, id, pos, size, style, name );
47d67540 960
c67daf87 961 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
c801d85f 962 m_hasScrolling = TRUE;
47d67540 963
cb43b372 964 GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget);
47d67540 965
cb43b372
RR
966 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
967 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
968
84efdbf1
RR
969 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
970 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
971
972 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
973 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
974
cb43b372
RR
975 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
976 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
977
c801d85f
KB
978 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
979 scroll_class->scrollbar_spacing = 0;
47d67540 980
c801d85f 981 gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
47d67540 982
c801d85f
KB
983 m_oldHorizontalPos = 0.0;
984 m_oldVerticalPos = 0.0;
47d67540 985
c801d85f
KB
986 m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
987 m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
47d67540 988
cb43b372 989 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
5e0aa05a 990 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
cb43b372 991 gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
5e0aa05a 992 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
47d67540 993
cb43b372 994 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
5e0aa05a 995 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
cb43b372 996 gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
5e0aa05a 997 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
47d67540 998
cb43b372 999 GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport);
47d67540 1000
c801d85f
KB
1001 if (m_windowStyle & wxRAISED_BORDER)
1002 {
1003 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
1004 }
1005 else if (m_windowStyle & wxSUNKEN_BORDER)
1006 {
1007 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
1008 }
1009 else
1010 {
1011 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
362c6693 1012 }
47d67540 1013
c801d85f 1014 m_wxwindow = gtk_myfixed_new();
47d67540 1015
32e9da8b 1016 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
47d67540 1017
c801d85f
KB
1018 if (m_windowStyle & wxTAB_TRAVERSAL == wxTAB_TRAVERSAL)
1019 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
1020 else
1021 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
1022
1023 gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
1024
1025 // shut the viewport up
1026 gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1027 gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
47d67540
VZ
1028
1029 // I _really_ don't want scrollbars in the beginning
c801d85f
KB
1030 m_vAdjust->lower = 0.0;
1031 m_vAdjust->upper = 1.0;
1032 m_vAdjust->value = 0.0;
1033 m_vAdjust->step_increment = 1.0;
1034 m_vAdjust->page_increment = 1.0;
1035 m_vAdjust->page_size = 5.0;
1036 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
1037 m_hAdjust->lower = 0.0;
1038 m_hAdjust->upper = 1.0;
1039 m_hAdjust->value = 0.0;
1040 m_hAdjust->step_increment = 1.0;
1041 m_hAdjust->page_increment = 1.0;
1042 m_hAdjust->page_size = 5.0;
1043 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
47d67540 1044
c801d85f 1045 gtk_widget_show( m_wxwindow );
6ca41e57
RR
1046
1047 if (m_parent) m_parent->AddChild( this );
47d67540 1048
6ca41e57
RR
1049 (m_parent->m_insertCallback)( m_parent, this );
1050
c801d85f 1051 PostCreation();
32e9da8b 1052
c801d85f
KB
1053 Show( TRUE );
1054
47d67540 1055 return TRUE;
362c6693 1056}
c801d85f 1057
68dda785 1058wxWindow::~wxWindow()
c801d85f
KB
1059{
1060 m_hasVMT = FALSE;
47d67540 1061
c801d85f 1062 if (m_pDropTarget) delete m_pDropTarget;
47d67540 1063
c801d85f
KB
1064 if (m_parent) m_parent->RemoveChild( this );
1065 if (m_widget) Show( FALSE );
1066
1067 DestroyChildren();
47d67540 1068
a81258be
RR
1069 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
1070
32e9da8b
RR
1071 if (m_scrollGC) gdk_gc_unref( m_scrollGC );
1072
c801d85f 1073 if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
47d67540 1074
c801d85f 1075 if (m_widget) gtk_widget_destroy( m_widget );
47d67540 1076
a3622daa 1077 wxDELETE(m_cursor);
c801d85f
KB
1078
1079 DeleteRelatedConstraints();
1080 if (m_constraints)
1081 {
1082 // This removes any dangling pointers to this window
1083 // in other windows' constraintsInvolvedIn lists.
1084 UnsetConstraints(m_constraints);
1085 delete m_constraints;
c67daf87 1086 m_constraints = (wxLayoutConstraints *) NULL;
c801d85f
KB
1087 }
1088 if (m_windowSizer)
1089 {
1090 delete m_windowSizer;
c67daf87 1091 m_windowSizer = (wxSizer *) NULL;
c801d85f
KB
1092 }
1093 // If this is a child of a sizer, remove self from parent
6de97a3b 1094 if (m_sizerParent) m_sizerParent->RemoveChild((wxWindow *)this);
c801d85f
KB
1095
1096 // Just in case the window has been Closed, but
1097 // we're then deleting immediately: don't leave
1098 // dangling pointers.
1099 wxPendingDelete.DeleteObject(this);
1100
1101 // Just in case we've loaded a top-level window via
1102 // wxWindow::LoadNativeDialog but we weren't a dialog
1103 // class
1104 wxTopLevelWindows.DeleteObject(this);
47d67540 1105
6de97a3b 1106 if (m_windowValidator) delete m_windowValidator;
362c6693 1107}
c801d85f 1108
debe6624
JS
1109void wxWindow::PreCreation( wxWindow *parent, wxWindowID id,
1110 const wxPoint &pos, const wxSize &size,
1111 long style, const wxString &name )
c801d85f
KB
1112{
1113 if (m_needParent && (parent == NULL))
2f2aa628 1114 wxFatalError( "Need complete parent.", name );
6ca41e57 1115
c67daf87 1116 m_widget = (GtkWidget *) NULL;
c801d85f
KB
1117 m_hasVMT = FALSE;
1118 m_parent = parent;
1119 m_children.DeleteContents( FALSE );
6ca41e57 1120
c801d85f
KB
1121 m_width = size.x;
1122 if (m_width == -1) m_width = 20;
1123 m_height = size.y;
1124 if (m_height == -1) m_height = 20;
6ca41e57
RR
1125
1126 m_x = (int)pos.x;
1127 m_y = (int)pos.y;
1128
1129 if (!m_needParent) // some reasonable defaults
1130 {
1131 if (m_x == -1)
1132 {
1133 m_x = (gdk_screen_width () - m_width) / 2;
1134 if (m_x < 10) m_x = 10;
1135 }
1136 if (m_y == -1)
1137 {
1138 m_y = (gdk_screen_height () - m_height) / 2;
1139 if (m_y < 10) m_y = 10;
1140 }
1141 }
1142
2f2aa628
RR
1143 m_minWidth = -1;
1144 m_minHeight = -1;
1145 m_maxWidth = -1;
1146 m_maxHeight = -1;
c801d85f
KB
1147 m_retCode = 0;
1148 m_eventHandler = this;
c801d85f
KB
1149 m_windowId = id;
1150 m_sizeSet = FALSE;
a3622daa
VZ
1151 if (m_cursor == NULL)
1152 m_cursor = new wxCursor( wxCURSOR_ARROW );
c801d85f 1153 m_font = *wxSWISS_FONT;
fc54776e 1154// m_backgroundColour = wxWHITE;
58614078 1155// m_foregroundColour = wxBLACK;
c801d85f
KB
1156 m_windowStyle = style;
1157 m_windowName = name;
c67daf87
UR
1158 m_constraints = (wxLayoutConstraints *) NULL;
1159 m_constraintsInvolvedIn = (wxList *) NULL;
1160 m_windowSizer = (wxSizer *) NULL;
1161 m_sizerParent = (wxWindow *) NULL;
c801d85f 1162 m_autoLayout = FALSE;
cb43b372
RR
1163 m_hasScrolling = FALSE;
1164 m_isScrolling = FALSE;
c67daf87 1165 m_pDropTarget = (wxDropTarget *) NULL;
33d0b396 1166 m_resizing = FALSE;
c67daf87 1167 m_windowValidator = (wxValidator *) NULL;
f96aa4d9 1168 m_scrollGC = (GdkGC*) NULL;
a81258be 1169 m_widgetStyle = (GtkStyle*) NULL;
c801d85f
KB
1170}
1171
68dda785 1172void wxWindow::PostCreation()
c801d85f 1173{
c801d85f
KB
1174 if (m_wxwindow)
1175 {
47d67540 1176 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
c801d85f 1177 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
47d67540
VZ
1178
1179 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
c801d85f 1180 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
362c6693 1181 }
47d67540 1182
b4071e91 1183 ConnectWidget( GetConnectWidget() );
47d67540 1184
b4071e91 1185 if (m_widget && m_parent) gtk_widget_realize( m_widget );
47d67540 1186
32e9da8b 1187 if (m_wxwindow) gtk_widget_realize( m_wxwindow );
47d67540 1188
d8c83875 1189 SetCursor( *wxSTANDARD_CURSOR );
47d67540 1190
b4071e91
RR
1191 m_hasVMT = TRUE;
1192}
1193
1194void wxWindow::ConnectWidget( GtkWidget *widget )
1195{
1196 gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
c801d85f
KB
1197 GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
1198
b4071e91 1199 gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
c801d85f 1200 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
47d67540 1201
b4071e91 1202 gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
c801d85f 1203 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
47d67540 1204
b4071e91 1205 gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
c801d85f 1206 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
47d67540
VZ
1207
1208 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
c801d85f
KB
1209 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
1210
47d67540 1211 gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
c801d85f
KB
1212 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
1213
47d67540 1214 gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
c801d85f 1215 GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
47d67540
VZ
1216
1217 gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
c801d85f 1218 GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
362c6693 1219}
c801d85f 1220
68dda785 1221bool wxWindow::HasVMT()
c801d85f
KB
1222{
1223 return m_hasVMT;
362c6693 1224}
c801d85f 1225
debe6624 1226bool wxWindow::Close( bool force )
c801d85f 1227{
e55ad60e 1228 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1229
c801d85f
KB
1230 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
1231 event.SetEventObject(this);
1232 event.SetForce(force);
1233
1234 return GetEventHandler()->ProcessEvent(event);
362c6693 1235}
c801d85f 1236
68dda785 1237bool wxWindow::Destroy()
c801d85f 1238{
e55ad60e 1239 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1240
c801d85f
KB
1241 m_hasVMT = FALSE;
1242 delete this;
1243 return TRUE;
362c6693 1244}
c801d85f 1245
68dda785 1246bool wxWindow::DestroyChildren()
c801d85f 1247{
47d67540 1248 if (GetChildren())
c801d85f
KB
1249 {
1250 wxNode *node;
47d67540 1251 while ((node = GetChildren()->First()) != (wxNode *)NULL)
c801d85f
KB
1252 {
1253 wxWindow *child;
47d67540 1254 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL)
c801d85f
KB
1255 {
1256 delete child;
11026f7b 1257 if (GetChildren()->Member(child)) delete node;
362c6693
RR
1258 }
1259 }
1260 }
c801d85f 1261 return TRUE;
362c6693 1262}
c801d85f
KB
1263
1264void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
1265{
1266 // are we to set fonts here ?
362c6693 1267}
c801d85f 1268
6ca41e57
RR
1269wxPoint wxWindow::GetClientAreaOrigin() const
1270{
1271 return wxPoint(0,0);
1272}
1273
1274void wxWindow::AdjustForParentClientOrigin( int& x, int& y, int sizeFlags )
1275{
1276 if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent())
1277 {
1278 wxPoint pt(GetParent()->GetClientAreaOrigin());
1279 x += pt.x;
1280 y += pt.y;
1281 }
1282}
1283
68dda785 1284void wxWindow::ImplementSetSize()
47d67540 1285{
2f2aa628
RR
1286 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
1287 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
1288 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_minWidth;
1289 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_minHeight;
c801d85f 1290 gtk_widget_set_usize( m_widget, m_width, m_height );
362c6693 1291}
c801d85f 1292
68dda785 1293void wxWindow::ImplementSetPosition()
c801d85f 1294{
1a6944fd
RR
1295 if (!m_parent)
1296 {
2f2aa628 1297 wxFAIL_MSG( "wxWindow::SetSize error.\n" );
1a6944fd
RR
1298 return;
1299 }
47d67540 1300
c801d85f
KB
1301 if ((m_parent) && (m_parent->m_wxwindow))
1302 gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
47d67540
VZ
1303
1304 // Don't do anything for children of wxNotebook and wxMDIChildFrame
362c6693 1305}
c801d85f 1306
debe6624 1307void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 1308{
e55ad60e 1309 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1310
33d0b396
RR
1311 if (m_resizing) return; // I don't like recursions
1312 m_resizing = TRUE;
47d67540 1313
c801d85f
KB
1314 int newX = x;
1315 int newY = y;
1316 int newW = width;
1317 int newH = height;
47d67540 1318
c801d85f
KB
1319 if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
1320 {
1321 if (newX == -1) newX = m_x;
1322 if (newY == -1) newY = m_y;
1323 if (newW == -1) newW = m_width;
1324 if (newH == -1) newH = m_height;
362c6693 1325 }
47d67540 1326
c801d85f
KB
1327 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
1328 {
1329 if (newW == -1) newW = 80;
362c6693 1330 }
47d67540 1331
c801d85f
KB
1332 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
1333 {
1334 if (newH == -1) newH = 26;
362c6693 1335 }
47d67540 1336
6ca41e57
RR
1337 AdjustForParentClientOrigin( newX, newY, sizeFlags );
1338
c801d85f
KB
1339 if ((m_x != newX) || (m_y != newY) || (!m_sizeSet))
1340 {
1341 m_x = newX;
1342 m_y = newY;
1343 ImplementSetPosition();
362c6693 1344 }
6ca41e57 1345
c801d85f
KB
1346 if ((m_width != newW) || (m_height != newH) || (!m_sizeSet))
1347 {
1348 m_width = newW;
1349 m_height = newH;
1350 ImplementSetSize();
362c6693 1351 }
c801d85f 1352 m_sizeSet = TRUE;
47d67540 1353
c801d85f
KB
1354 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
1355 event.SetEventObject( this );
1356 ProcessEvent( event );
47d67540 1357
33d0b396 1358 m_resizing = FALSE;
362c6693 1359}
c801d85f 1360
debe6624 1361void wxWindow::SetSize( int width, int height )
c801d85f
KB
1362{
1363 SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
362c6693 1364}
c801d85f 1365
debe6624 1366void wxWindow::Move( int x, int y )
c801d85f
KB
1367{
1368 SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
362c6693 1369}
c801d85f
KB
1370
1371void wxWindow::GetSize( int *width, int *height ) const
1372{
e55ad60e 1373 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1374
33d0b396
RR
1375 if (width) (*width) = m_width;
1376 if (height) (*height) = m_height;
362c6693 1377}
c801d85f 1378
debe6624 1379void wxWindow::SetClientSize( int width, int height )
c801d85f 1380{
e55ad60e 1381 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1382
c801d85f
KB
1383 if (!m_wxwindow)
1384 {
1385 SetSize( width, height );
1386 }
1387 else
1388 {
1389 int dw = 0;
1390 int dh = 0;
47d67540 1391
c801d85f
KB
1392 if (!m_hasScrolling)
1393 {
1394/*
1395 do we have sunken dialogs ?
47d67540 1396
c801d85f 1397 GtkStyleClass *window_class = m_wxwindow->style->klass;
47d67540 1398
c801d85f
KB
1399 dw += 2 * window_class->xthickness;
1400 dh += 2 * window_class->ythickness;
1401*/
1402 }
1403 else
1404 {
1405 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
1406 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 1407
c801d85f
KB
1408 GtkWidget *viewport = scroll_window->viewport;
1409 GtkStyleClass *viewport_class = viewport->style->klass;
47d67540 1410
c801d85f
KB
1411 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1412 GtkWidget *vscrollbar = scroll_window->vscrollbar;
47d67540 1413
c801d85f 1414 if ((m_windowStyle & wxRAISED_BORDER) ||
2f2aa628 1415 (m_windowStyle & wxSUNKEN_BORDER))
c801d85f
KB
1416 {
1417 dw += 2 * viewport_class->xthickness;
1418 dh += 2 * viewport_class->ythickness;
362c6693 1419 }
47d67540 1420
c801d85f
KB
1421 if (GTK_WIDGET_VISIBLE(vscrollbar))
1422 {
1423 dw += vscrollbar->allocation.width;
1424 dw += scroll_class->scrollbar_spacing;
362c6693 1425 }
47d67540 1426
c801d85f
KB
1427 if (GTK_WIDGET_VISIBLE(hscrollbar))
1428 {
1429 dh += hscrollbar->allocation.height;
1430 dw += scroll_class->scrollbar_spacing;
362c6693
RR
1431 }
1432 }
47d67540 1433
c801d85f 1434 SetSize( width+dw, height+dh );
362c6693
RR
1435 }
1436}
c801d85f
KB
1437
1438void wxWindow::GetClientSize( int *width, int *height ) const
1439{
e55ad60e 1440 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1441
c801d85f
KB
1442 if (!m_wxwindow)
1443 {
1444 if (width) (*width) = m_width;
1445 if (height) (*height) = m_height;
1446 }
1447 else
1448 {
1449 int dw = 0;
1450 int dh = 0;
47d67540 1451
c801d85f
KB
1452 if (!m_hasScrolling)
1453 {
1454/*
1455 do we have sunken dialogs ?
47d67540 1456
c801d85f 1457 GtkStyleClass *window_class = m_wxwindow->style->klass;
47d67540 1458
c801d85f
KB
1459 dw += 2 * window_class->xthickness;
1460 dh += 2 * window_class->ythickness;
1461*/
1462 }
1463 else
1464 {
1465 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
1466 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 1467
c801d85f
KB
1468 GtkWidget *viewport = scroll_window->viewport;
1469 GtkStyleClass *viewport_class = viewport->style->klass;
47d67540 1470
c801d85f
KB
1471 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1472 GtkWidget *vscrollbar = scroll_window->vscrollbar;
47d67540 1473
c801d85f 1474 if ((m_windowStyle & wxRAISED_BORDER) ||
2f2aa628 1475 (m_windowStyle & wxSUNKEN_BORDER))
c801d85f
KB
1476 {
1477 dw += 2 * viewport_class->xthickness;
1478 dh += 2 * viewport_class->ythickness;
362c6693 1479 }
47d67540 1480
c801d85f
KB
1481 if (GTK_WIDGET_VISIBLE(vscrollbar))
1482 {
1483// dw += vscrollbar->allocation.width;
1484 dw += 15; // range.slider_width = 11 + 2*2pts edge
1485 dw += scroll_class->scrollbar_spacing;
362c6693 1486 }
47d67540 1487
c801d85f
KB
1488 if (GTK_WIDGET_VISIBLE(hscrollbar))
1489 {
1490// dh += hscrollbar->allocation.height;
1491 dh += 15;
1492 dh += scroll_class->scrollbar_spacing;
362c6693
RR
1493 }
1494 }
47d67540 1495
c801d85f
KB
1496 if (width) (*width) = m_width - dw;
1497 if (height) (*height) = m_height - dh;
362c6693
RR
1498 }
1499}
c801d85f
KB
1500
1501void wxWindow::GetPosition( int *x, int *y ) const
1502{
e55ad60e 1503 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1504
6ca41e57
RR
1505 int xx = m_x;
1506 int yy = m_y;
1507
1508 if (GetParent())
1509 {
1510 wxPoint pt(GetParent()->GetClientAreaOrigin());
1511 xx -= pt.x;
1512 yy -= pt.y;
1513 }
1514
1515 if (x) (*x) = xx;
1516 if (y) (*y) = yy;
362c6693 1517}
c801d85f
KB
1518
1519void wxWindow::ClientToScreen( int *x, int *y )
1520{
e55ad60e 1521 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1522
c67daf87 1523 GdkWindow *source = (GdkWindow *) NULL;
c801d85f
KB
1524 if (m_wxwindow)
1525 source = m_wxwindow->window;
1526 else
1527 source = m_widget->window;
47d67540 1528
c801d85f
KB
1529 int org_x = 0;
1530 int org_y = 0;
1531 gdk_window_get_origin( source, &org_x, &org_y );
1532
1533 if (!m_wxwindow)
47d67540 1534 {
c801d85f
KB
1535 if (GTK_WIDGET_NO_WINDOW (m_widget))
1536 {
1537 org_x += m_widget->allocation.x;
1538 org_y += m_widget->allocation.y;
362c6693
RR
1539 }
1540 }
47d67540 1541
6ca41e57
RR
1542 wxPoint pt(GetClientAreaOrigin());
1543 org_x += pt.x;
1544 org_y += pt.y;
1545
47d67540
VZ
1546 if (x) *x += org_x;
1547 if (y) *y += org_y;
362c6693 1548}
c801d85f
KB
1549
1550void wxWindow::ScreenToClient( int *x, int *y )
1551{
e55ad60e 1552 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1553
c67daf87 1554 GdkWindow *source = (GdkWindow *) NULL;
c801d85f
KB
1555 if (m_wxwindow)
1556 source = m_wxwindow->window;
1557 else
1558 source = m_widget->window;
47d67540 1559
c801d85f
KB
1560 int org_x = 0;
1561 int org_y = 0;
1562 gdk_window_get_origin( source, &org_x, &org_y );
1563
1564 if (!m_wxwindow)
47d67540 1565 {
c801d85f
KB
1566 if (GTK_WIDGET_NO_WINDOW (m_widget))
1567 {
1568 org_x += m_widget->allocation.x;
1569 org_y += m_widget->allocation.y;
362c6693
RR
1570 }
1571 }
47d67540 1572
6ca41e57
RR
1573 wxPoint pt(GetClientAreaOrigin());
1574 org_x -= pt.x;
1575 org_y -= pt.y;
1576
47d67540
VZ
1577 if (x) *x -= org_x;
1578 if (y) *y -= org_y;
362c6693 1579}
c801d85f 1580
debe6624 1581void wxWindow::Centre( int direction )
c801d85f 1582{
e55ad60e 1583 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1584
66bd6b93 1585 if (IS_KIND_OF(this,wxDialog) || IS_KIND_OF(this,wxFrame))
c801d85f 1586 {
d4c99d6f
RR
1587 if (direction & wxHORIZONTAL == wxHORIZONTAL) m_x = (gdk_screen_width () - m_width) / 2;
1588 if (direction & wxVERTICAL == wxVERTICAL) m_y = (gdk_screen_height () - m_height) / 2;
1589 ImplementSetPosition();
c801d85f
KB
1590 }
1591 else
1592 {
1593 if (m_parent)
1594 {
1595 int p_w = 0;
1596 int p_h = 0;
1597 m_parent->GetSize( &p_w, &p_h );
d4c99d6f
RR
1598 if (direction & wxHORIZONTAL == wxHORIZONTAL) m_x = (p_w - m_width) / 2;
1599 if (direction & wxVERTICAL == wxVERTICAL) m_y = (p_h - m_height) / 2;
1600 ImplementSetPosition();
362c6693 1601 }
c801d85f 1602 }
362c6693 1603}
c801d85f 1604
68dda785 1605void wxWindow::Fit()
c801d85f 1606{
e55ad60e 1607 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1608
5e0aa05a
VZ
1609 int maxX = 0;
1610 int maxY = 0;
1611 wxNode *node = GetChildren()->First();
1612 while ( node )
1613 {
1614 wxWindow *win = (wxWindow *)node->Data();
1615 int wx, wy, ww, wh;
1616 win->GetPosition(&wx, &wy);
1617 win->GetSize(&ww, &wh);
1618 if ( wx + ww > maxX )
1619 maxX = wx + ww;
1620 if ( wy + wh > maxY )
1621 maxY = wy + wh;
1622
1623 node = node->Next();
1624 }
47908e25 1625 SetClientSize(maxX + 5, maxY + 10);
362c6693 1626}
c801d85f 1627
2f2aa628
RR
1628void wxWindow::SetSizeHints( int minW, int minH, int maxW, int maxH, int WXUNUSED(incW), int WXUNUSED(incH) )
1629{
e55ad60e 1630 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1631
2f2aa628
RR
1632 m_minWidth = minW;
1633 m_minHeight = minH;
1634 m_maxWidth = maxW;
1635 m_maxHeight = maxH;
1636}
1637
c801d85f
KB
1638void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
1639{
da7f8ac4 1640 //if (GetAutoLayout()) Layout();
362c6693 1641}
c801d85f 1642
debe6624 1643bool wxWindow::Show( bool show )
c801d85f 1644{
e55ad60e 1645 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1646
c801d85f
KB
1647 if (show)
1648 gtk_widget_show( m_widget );
1649 else
1650 gtk_widget_hide( m_widget );
47d67540 1651 m_isShown = show;
c801d85f 1652 return TRUE;
362c6693 1653}
c801d85f 1654
debe6624 1655void wxWindow::Enable( bool enable )
c801d85f 1656{
e55ad60e 1657 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1658
c801d85f
KB
1659 m_isEnabled = enable;
1660 gtk_widget_set_sensitive( m_widget, enable );
1661 if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
362c6693 1662}
c801d85f 1663
68dda785 1664int wxWindow::GetCharHeight() const
c33c4050 1665{
e55ad60e 1666 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1667
e55ad60e
RR
1668 if (!m_font.Ok())
1669 {
1670 wxFAIL_MSG( "invalid font" );
1671 return -1;
1672 }
47d67540 1673
c33c4050
RR
1674 GdkFont *font = m_font.GetInternalFont( 1.0 );
1675 return font->ascent + font->descent;
1676}
1677
68dda785 1678int wxWindow::GetCharWidth() const
c33c4050 1679{
e55ad60e 1680 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1681
e55ad60e
RR
1682 if (!m_font.Ok())
1683 {
1684 wxFAIL_MSG( "invalid font" );
1685 return -1;
1686 }
47d67540 1687
c33c4050
RR
1688 GdkFont *font = m_font.GetInternalFont( 1.0 );
1689 return gdk_string_width( font, "H" );
1690}
1691
1692void wxWindow::GetTextExtent( const wxString& string, int *x, int *y,
1693 int *descent, int *externalLeading, const wxFont *theFont, bool WXUNUSED(use16) ) const
1694{
e55ad60e 1695 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1696
c33c4050
RR
1697 wxFont fontToUse = m_font;
1698 if (theFont) fontToUse = *theFont;
47d67540 1699
e55ad60e
RR
1700 if (!fontToUse.Ok())
1701 {
1702 wxFAIL_MSG( "invalid font" );
1703 return;
1704 }
1705 wxASSERT_MSG( (m_font.Ok()), "invalid font" );
47d67540 1706
c33c4050 1707 GdkFont *font = fontToUse.GetInternalFont( 1.0 );
66c135f3 1708 if (x) (*x) = gdk_string_width( font, string );
c33c4050
RR
1709 if (y) (*y) = font->ascent + font->descent;
1710 if (descent) (*descent) = font->descent;
1711 if (externalLeading) (*externalLeading) = 0; // ??
1712}
1713
debe6624 1714void wxWindow::MakeModal( bool modal )
c801d85f
KB
1715{
1716 return;
1717 // Disable all other windows
1718 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
1719 {
1720 wxNode *node = wxTopLevelWindows.First();
1721 while (node)
1722 {
1723 wxWindow *win = (wxWindow *)node->Data();
1724 if (win != this)
1725 win->Enable(!modal);
1726
1727 node = node->Next();
1728 }
1729 }
1730}
1731
68dda785 1732void wxWindow::SetFocus()
c801d85f 1733{
e55ad60e 1734 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1735
30dea054 1736 GtkWidget *connect_widget = GetConnectWidget();
c801d85f
KB
1737 if (connect_widget)
1738 {
1739 if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) )
1740 {
1741 gtk_widget_grab_focus (connect_widget);
362c6693
RR
1742 }
1743 }
1744}
c801d85f 1745
68dda785 1746bool wxWindow::OnClose()
c801d85f 1747{
c801d85f 1748 return TRUE;
362c6693 1749}
c801d85f
KB
1750
1751void wxWindow::AddChild( wxWindow *child )
1752{
e55ad60e 1753 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
e55ad60e 1754 wxASSERT_MSG( (child != NULL), "invalid child" );
47d67540 1755
46dc76ba 1756 m_children.Append( child );
362c6693 1757}
c801d85f 1758
68dda785 1759wxList *wxWindow::GetChildren()
c801d85f
KB
1760{
1761 return (&m_children);
362c6693 1762}
c801d85f
KB
1763
1764void wxWindow::RemoveChild( wxWindow *child )
1765{
6ca41e57 1766 if (GetChildren()) GetChildren()->DeleteObject( child );
c67daf87 1767 child->m_parent = (wxWindow *) NULL;
362c6693 1768}
c801d85f
KB
1769
1770void wxWindow::SetReturnCode( int retCode )
1771{
1772 m_retCode = retCode;
362c6693 1773}
c801d85f 1774
68dda785 1775int wxWindow::GetReturnCode()
c801d85f
KB
1776{
1777 return m_retCode;
362c6693 1778}
c801d85f 1779
68dda785 1780void wxWindow::Raise()
362c6693 1781{
e55ad60e 1782 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1783
362c6693
RR
1784 if (m_widget) gdk_window_raise( m_widget->window );
1785}
1786
68dda785 1787void wxWindow::Lower()
362c6693 1788{
e55ad60e 1789 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1790
362c6693
RR
1791 if (m_widget) gdk_window_lower( m_widget->window );
1792}
c801d85f 1793
68dda785 1794wxEvtHandler *wxWindow::GetEventHandler()
c801d85f
KB
1795{
1796 return m_eventHandler;
362c6693 1797}
c801d85f 1798
86b29a61 1799void wxWindow::SetEventHandler( wxEvtHandler *handler )
c801d85f
KB
1800{
1801 m_eventHandler = handler;
362c6693 1802}
c801d85f 1803
86b29a61
RR
1804void wxWindow::PushEventHandler(wxEvtHandler *handler)
1805{
e55ad60e
RR
1806 handler->SetNextHandler(GetEventHandler());
1807 SetEventHandler(handler);
86b29a61
RR
1808}
1809
1810wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
1811{
e55ad60e
RR
1812 if (GetEventHandler())
1813 {
1814 wxEvtHandler *handlerA = GetEventHandler();
1815 wxEvtHandler *handlerB = handlerA->GetNextHandler();
1816 handlerA->SetNextHandler((wxEvtHandler *) NULL);
1817 SetEventHandler(handlerB);
1818 if (deleteHandler)
1819 {
1820 delete handlerA;
1821 return (wxEvtHandler*) NULL;
1822 }
1823 else
1824 return handlerA;
1825 }
1826 else
1827 return (wxEvtHandler *) NULL;
86b29a61
RR
1828}
1829
68dda785 1830wxValidator *wxWindow::GetValidator()
c801d85f
KB
1831{
1832 return m_windowValidator;
362c6693 1833}
c801d85f 1834
6de97a3b 1835void wxWindow::SetValidator( const wxValidator& validator )
c801d85f 1836{
6de97a3b
RR
1837 if (m_windowValidator) delete m_windowValidator;
1838 m_windowValidator = validator.Clone();
1839 if (m_windowValidator) m_windowValidator->SetWindow(this);
362c6693 1840}
c801d85f 1841
68dda785 1842bool wxWindow::IsBeingDeleted()
c801d85f
KB
1843{
1844 return FALSE;
362c6693 1845}
c801d85f
KB
1846
1847void wxWindow::SetId( wxWindowID id )
1848{
1849 m_windowId = id;
362c6693 1850}
c801d85f 1851
68dda785 1852wxWindowID wxWindow::GetId()
c801d85f
KB
1853{
1854 return m_windowId;
362c6693 1855}
c801d85f
KB
1856
1857void wxWindow::SetCursor( const wxCursor &cursor )
1858{
e55ad60e 1859 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1860
d8c83875
RR
1861 if (m_cursor == NULL)
1862 {
1863 wxFAIL_MSG( "wxWindow::SetCursor m_cursor == NULL" );
1864 m_cursor = new wxCursor( wxCURSOR_ARROW );
1865 }
47d67540 1866
d8c83875
RR
1867 if (cursor.Ok())
1868 {
1869 if (*((wxCursor*)&cursor) == m_cursor) return;
1870 *m_cursor = cursor;
1871 }
1872 else
1873 {
1874 *m_cursor = *wxSTANDARD_CURSOR;
1875 }
a3622daa 1876
d8c83875 1877 if ((m_widget) && (m_widget->window))
c801d85f 1878 gdk_window_set_cursor( m_widget->window, m_cursor->GetCursor() );
47d67540 1879
d8c83875 1880 if ((m_wxwindow) && (m_wxwindow->window))
c801d85f 1881 gdk_window_set_cursor( m_wxwindow->window, m_cursor->GetCursor() );
362c6693 1882}
c801d85f 1883
debe6624 1884void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f 1885{
e55ad60e 1886 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1887
c801d85f
KB
1888 if (eraseBackground && m_wxwindow && m_wxwindow->window)
1889 {
1890 if (rect)
47d67540
VZ
1891 gdk_window_clear_area( m_wxwindow->window,
1892 rect->x,
1893 rect->y,
1894 rect->width,
d4c99d6f 1895 rect->height );
c801d85f 1896 else
47d67540 1897 Clear();
362c6693 1898 }
c801d85f
KB
1899 if (!rect)
1900 {
1901 if (m_wxwindow)
1902 {
c801d85f
KB
1903 int w = 0;
1904 int h = 0;
1905 GetClientSize( &w, &h );
47d67540 1906
c801d85f 1907 GdkRectangle gdk_rect;
11026f7b
RR
1908 gdk_rect.x = 0;
1909 gdk_rect.y = 0;
c801d85f
KB
1910 gdk_rect.width = w;
1911 gdk_rect.height = h;
1912 gtk_widget_draw( m_wxwindow, &gdk_rect );
362c6693 1913 }
c801d85f
KB
1914 }
1915 else
1916 {
1917 GdkRectangle gdk_rect;
1918 gdk_rect.x = rect->x;
1919 gdk_rect.y = rect->y;
1920 gdk_rect.width = rect->width;
1921 gdk_rect.height = rect->height;
47d67540 1922
c801d85f
KB
1923 if (m_wxwindow)
1924 gtk_widget_draw( m_wxwindow, &gdk_rect );
1925 else
1926 gtk_widget_draw( m_widget, &gdk_rect );
362c6693
RR
1927 }
1928}
c801d85f 1929
8429bec1
RR
1930wxRegion wxWindow::GetUpdateRegion() const
1931{
1932 return m_updateRegion;
1933}
1934
1935bool wxWindow::IsExposed( int x, int y) const
c801d85f
KB
1936{
1937 return (m_updateRegion.Contains( x, y ) != wxOutRegion );
362c6693 1938}
c801d85f 1939
8429bec1
RR
1940bool wxWindow::IsExposed( int x, int y, int w, int h ) const
1941{
1942 return (m_updateRegion.Contains( x, y, w, h ) != wxOutRegion );
1943}
1944
1945bool wxWindow::IsExposed( const wxPoint& pt ) const
1946{
1947 return (m_updateRegion.Contains( pt.x, pt.y ) != wxOutRegion );
1948}
1949
1950bool wxWindow::IsExposed( const wxRect& rect ) const
c801d85f 1951{
8429bec1 1952 return (m_updateRegion.Contains( rect.x, rect.y, rect.width, rect.height ) != wxOutRegion );
362c6693 1953}
c801d85f 1954
68dda785 1955void wxWindow::Clear()
c801d85f 1956{
fc54776e 1957 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 1958
c801d85f 1959 if (m_wxwindow && m_wxwindow->window) gdk_window_clear( m_wxwindow->window );
362c6693 1960}
c801d85f 1961
68dda785 1962wxColour wxWindow::GetBackgroundColour() const
c801d85f
KB
1963{
1964 return m_backgroundColour;
362c6693 1965}
c801d85f
KB
1966
1967void wxWindow::SetBackgroundColour( const wxColour &colour )
1968{
fc54776e 1969 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 1970
fc54776e 1971 m_backgroundColour = colour;
f96aa4d9 1972 if (!m_backgroundColour.Ok()) return;
fc54776e 1973
f96aa4d9
RR
1974 if (m_wxwindow)
1975 {
1976 GdkWindow *window = m_wxwindow->window;
1977 m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) );
1978 gdk_window_set_background( window, m_backgroundColour.GetColor() );
1979 gdk_window_clear( window );
1980 }
58614078
RR
1981
1982 ApplyWidgetStyle();
362c6693 1983}
c801d85f 1984
68dda785 1985wxColour wxWindow::GetForegroundColour() const
6de97a3b
RR
1986{
1987 return m_foregroundColour;
1988}
1989
1990void wxWindow::SetForegroundColour( const wxColour &colour )
1991{
a81258be
RR
1992 wxCHECK_RET( m_widget != NULL, "invalid window" );
1993
6de97a3b 1994 m_foregroundColour = colour;
a81258be
RR
1995 if (!m_foregroundColour.Ok()) return;
1996
58614078
RR
1997 ApplyWidgetStyle();
1998}
1999
2000GtkStyle *wxWindow::GetWidgetStyle()
2001{
2002 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
2003
2004 m_widgetStyle =
2005 gtk_style_copy(
2006 gtk_widget_get_style( m_widget ) );
2007
2008 return m_widgetStyle;
2009}
2010
2011void wxWindow::SetWidgetStyle()
2012{
2013 GtkStyle *style = GetWidgetStyle();
2014
2015 gdk_font_unref( style->font );
2016 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
2017
2018 if (m_foregroundColour.Ok())
a81258be 2019 {
a81258be
RR
2020 m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2021 style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
2022 style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
2023 style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
2024 }
58614078
RR
2025
2026 if (m_backgroundColour.Ok())
2027 {
2028 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2029 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2030 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2031 style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2032 style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2033 style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2034 style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2035 style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2036 style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2037 }
a81258be
RR
2038}
2039
58614078 2040void wxWindow::ApplyWidgetStyle()
a81258be 2041{
6de97a3b
RR
2042}
2043
68dda785 2044bool wxWindow::Validate()
c801d85f 2045{
fc54776e 2046 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2047
c801d85f
KB
2048 wxNode *node = GetChildren()->First();
2049 while (node)
2050 {
2051 wxWindow *child = (wxWindow *)node->Data();
47d67540 2052 if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this))
c801d85f
KB
2053 { return FALSE; }
2054 node = node->Next();
362c6693 2055 }
c801d85f 2056 return TRUE;
362c6693 2057}
c801d85f 2058
68dda785 2059bool wxWindow::TransferDataToWindow()
c801d85f 2060{
fc54776e 2061 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2062
c801d85f
KB
2063 wxNode *node = GetChildren()->First();
2064 while (node)
2065 {
2066 wxWindow *child = (wxWindow *)node->Data();
2067 if (child->GetValidator() && /* child->GetValidator()->Ok() && */
5e0aa05a 2068 !child->GetValidator()->TransferToWindow() )
c801d85f 2069 {
1a5a8367 2070 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK|wxICON_EXCLAMATION );
c801d85f 2071 return FALSE;
362c6693 2072 }
c801d85f 2073 node = node->Next();
362c6693 2074 }
c801d85f 2075 return TRUE;
362c6693 2076}
c801d85f 2077
68dda785 2078bool wxWindow::TransferDataFromWindow()
c801d85f 2079{
e55ad60e 2080 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2081
c801d85f
KB
2082 wxNode *node = GetChildren()->First();
2083 while (node)
2084 {
2085 wxWindow *child = (wxWindow *)node->Data();
2086 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
2087 { return FALSE; }
2088 node = node->Next();
2089 }
2090 return TRUE;
362c6693 2091}
c801d85f 2092
bcf1fa6b
RR
2093void wxWindow::SetAcceleratorTable( const wxAcceleratorTable& accel )
2094{
2095 m_acceleratorTable = accel;
2096}
2097
c801d85f
KB
2098void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
2099{
2100 TransferDataToWindow();
362c6693 2101}
c801d85f 2102
68dda785 2103void wxWindow::InitDialog()
c801d85f 2104{
c67d8618 2105 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2106
c801d85f
KB
2107 wxInitDialogEvent event(GetId());
2108 event.SetEventObject( this );
2109 GetEventHandler()->ProcessEvent(event);
362c6693 2110}
c801d85f 2111
30dea054
RR
2112static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
2113{
2114 menu->SetInvokingWindow( win );
2115 wxNode *node = menu->m_items.First();
2116 while (node)
2117 {
2118 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
2119 if (menuitem->IsSubMenu())
2120 SetInvokingWindow( menuitem->GetSubMenu(), win );
2121 node = node->Next();
362c6693
RR
2122 }
2123}
30dea054
RR
2124
2125bool wxWindow::PopupMenu( wxMenu *menu, int WXUNUSED(x), int WXUNUSED(y) )
2126{
c67d8618 2127 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2128
c67d8618
RR
2129 wxCHECK_MSG( menu != NULL, FALSE, "invalid popup-menu" );
2130
30dea054 2131 SetInvokingWindow( menu, this );
47d67540
VZ
2132 gtk_menu_popup(
2133 GTK_MENU(menu->m_menu),
2134 (GtkWidget *)NULL, // parent menu shell
2135 (GtkWidget *)NULL, // parent menu item
2136 (GtkMenuPositionFunc)NULL,
2137 NULL, // client data
2138 0, // button used to activate it
2139 0//gs_timeLastClick // the time of activation
2140 );
30dea054
RR
2141 return TRUE;
2142}
2143
c801d85f
KB
2144void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
2145{
c67d8618 2146 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2147
30dea054 2148 GtkWidget *dnd_widget = GetConnectWidget();
47d67540 2149
a60c99e6 2150 DisconnectDnDWidget( dnd_widget );
47d67540 2151
a60c99e6 2152 if (m_pDropTarget) delete m_pDropTarget;
c801d85f 2153 m_pDropTarget = dropTarget;
47d67540 2154
a60c99e6 2155 ConnectDnDWidget( dnd_widget );
362c6693 2156}
c801d85f
KB
2157
2158wxDropTarget *wxWindow::GetDropTarget() const
2159{
2160 return m_pDropTarget;
362c6693 2161}
c801d85f 2162
a60c99e6
RR
2163void wxWindow::ConnectDnDWidget( GtkWidget *widget )
2164{
2165 if (!m_pDropTarget) return;
47d67540 2166
a60c99e6 2167 m_pDropTarget->RegisterWidget( widget );
47d67540 2168
a60c99e6
RR
2169 gtk_signal_connect( GTK_OBJECT(widget), "drop_data_available_event",
2170 GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
2171}
2172
2173void wxWindow::DisconnectDnDWidget( GtkWidget *widget )
2174{
2175 if (!m_pDropTarget) return;
47d67540 2176
a60c99e6
RR
2177 gtk_signal_disconnect_by_func( GTK_OBJECT(widget),
2178 GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
47d67540 2179
a60c99e6
RR
2180 m_pDropTarget->UnregisterWidget( widget );
2181}
2182
68dda785 2183GtkWidget* wxWindow::GetConnectWidget()
e3e65dac
RR
2184{
2185 GtkWidget *connect_widget = m_widget;
2186 if (m_wxwindow) connect_widget = m_wxwindow;
47d67540 2187
e3e65dac
RR
2188 return connect_widget;
2189}
47d67540 2190
903f689b
RR
2191bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
2192{
2193 if (m_wxwindow) return (window == m_wxwindow->window);
2194 return (window == m_widget->window);
2195}
2196
c801d85f
KB
2197void wxWindow::SetFont( const wxFont &font )
2198{
c67d8618 2199 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2200
3f659fd6 2201 if (((wxFont*)&font)->Ok())
560b92f5
JS
2202 m_font = font;
2203 else
2204 m_font = *wxSWISS_FONT;
58614078
RR
2205
2206 ApplyWidgetStyle();
362c6693 2207}
c801d85f 2208
68dda785 2209wxFont *wxWindow::GetFont()
c801d85f
KB
2210{
2211 return &m_font;
362c6693 2212}
c801d85f
KB
2213
2214void wxWindow::SetWindowStyleFlag( long flag )
2215{
2216 m_windowStyle = flag;
362c6693 2217}
c801d85f 2218
68dda785 2219long wxWindow::GetWindowStyleFlag() const
c801d85f
KB
2220{
2221 return m_windowStyle;
362c6693 2222}
c801d85f 2223
68dda785 2224void wxWindow::CaptureMouse()
c801d85f 2225{
c67d8618 2226 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2227
c67d8618 2228 wxCHECK_RET( g_capturing == FALSE, "CaptureMouse called twice" );
47d67540 2229
30dea054 2230 GtkWidget *connect_widget = GetConnectWidget();
c801d85f
KB
2231 gtk_grab_add( connect_widget );
2232 gdk_pointer_grab ( connect_widget->window, FALSE,
2233 (GdkEventMask)
47d67540 2234 (GDK_BUTTON_PRESS_MASK |
5e0aa05a 2235 GDK_BUTTON_RELEASE_MASK |
47d67540 2236 GDK_POINTER_MOTION_MASK),
c67daf87 2237 (GdkWindow *) NULL, (GdkCursor *) NULL, GDK_CURRENT_TIME );
6987a6c3 2238 g_capturing = TRUE;
362c6693 2239}
c801d85f 2240
68dda785 2241void wxWindow::ReleaseMouse()
c801d85f 2242{
c67d8618 2243 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2244
c67d8618 2245 wxCHECK_RET( g_capturing == TRUE, "ReleaseMouse called twice" );
47d67540 2246
30dea054 2247 GtkWidget *connect_widget = GetConnectWidget();
c801d85f
KB
2248 gtk_grab_remove( connect_widget );
2249 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
6987a6c3 2250 g_capturing = FALSE;
362c6693 2251}
c801d85f
KB
2252
2253void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
2254{
362c6693 2255}
c801d85f 2256
68dda785 2257wxString wxWindow::GetTitle() const
c801d85f
KB
2258{
2259 return (wxString&)m_windowName;
362c6693 2260}
c801d85f 2261
68dda785 2262wxString wxWindow::GetLabel() const
c801d85f
KB
2263{
2264 return GetTitle();
362c6693 2265}
c801d85f
KB
2266
2267void wxWindow::SetName( const wxString &name )
2268{
2269 m_windowName = name;
362c6693 2270}
c801d85f 2271
68dda785 2272wxString wxWindow::GetName() const
c801d85f
KB
2273{
2274 return (wxString&)m_windowName;
362c6693 2275}
c801d85f 2276
68dda785 2277bool wxWindow::IsShown() const
c801d85f
KB
2278{
2279 return m_isShown;
362c6693 2280}
c801d85f 2281
68dda785 2282bool wxWindow::IsRetained()
c801d85f
KB
2283{
2284 return FALSE;
362c6693 2285}
c801d85f 2286
debe6624 2287wxWindow *wxWindow::FindWindow( long id )
c801d85f
KB
2288{
2289 if (id == m_windowId) return this;
2290 wxNode *node = m_children.First();
2291 while (node)
2292 {
2293 wxWindow *child = (wxWindow*)node->Data();
2294 wxWindow *res = child->FindWindow( id );
2295 if (res) return res;
2296 node = node->Next();
362c6693 2297 }
c67daf87 2298 return (wxWindow *) NULL;
362c6693 2299}
c801d85f
KB
2300
2301wxWindow *wxWindow::FindWindow( const wxString& name )
2302{
2303 if (name == m_windowName) return this;
2304 wxNode *node = m_children.First();
2305 while (node)
2306 {
2307 wxWindow *child = (wxWindow*)node->Data();
2308 wxWindow *res = child->FindWindow( name );
2309 if (res) return res;
2310 node = node->Next();
362c6693 2311 }
c67daf87 2312 return (wxWindow *) NULL;
362c6693 2313}
c801d85f 2314
debe6624 2315void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
cb43b372 2316 int range, bool refresh )
c801d85f 2317{
e55ad60e 2318 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2319
e55ad60e 2320 wxASSERT_MSG( (m_wxwindow != NULL), "window needs client area" );
47d67540 2321
c801d85f
KB
2322 if (!m_wxwindow) return;
2323
2324 if (orient == wxHORIZONTAL)
2325 {
2326 float fpos = (float)pos;
c801d85f
KB
2327 float frange = (float)range;
2328 float fthumb = (float)thumbVisible;
47d67540 2329
cb43b372
RR
2330 if ((fabs(frange-m_hAdjust->upper) < 0.2) &&
2331 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
2332 {
2333 SetScrollPos( orient, pos, refresh );
c801d85f 2334 return;
cb43b372 2335 }
47d67540 2336
cb43b372 2337 m_oldHorizontalPos = fpos;
47d67540 2338
c801d85f
KB
2339 m_hAdjust->lower = 0.0;
2340 m_hAdjust->upper = frange;
2341 m_hAdjust->value = fpos;
2342 m_hAdjust->step_increment = 1.0;
84efdbf1 2343 m_hAdjust->page_increment = (float)(wxMax(fthumb,0));
c801d85f
KB
2344 m_hAdjust->page_size = fthumb;
2345 }
2346 else
2347 {
2348 float fpos = (float)pos;
c801d85f
KB
2349 float frange = (float)range;
2350 float fthumb = (float)thumbVisible;
47d67540 2351
cb43b372
RR
2352 if ((fabs(frange-m_vAdjust->upper) < 0.2) &&
2353 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
2354 {
2355 SetScrollPos( orient, pos, refresh );
c801d85f 2356 return;
cb43b372 2357 }
47d67540 2358
cb43b372 2359 m_oldVerticalPos = fpos;
47d67540 2360
c801d85f
KB
2361 m_vAdjust->lower = 0.0;
2362 m_vAdjust->upper = frange;
2363 m_vAdjust->value = fpos;
2364 m_vAdjust->step_increment = 1.0;
84efdbf1 2365 m_vAdjust->page_increment = (float)(wxMax(fthumb,0));
c801d85f 2366 m_vAdjust->page_size = fthumb;
362c6693 2367 }
47d67540 2368
c801d85f 2369 if (m_wxwindow->window)
d4c99d6f 2370 {
c801d85f
KB
2371 if (orient == wxHORIZONTAL)
2372 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
d4c99d6f 2373 else
c801d85f 2374 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
47d67540 2375
401ec7b6 2376 gtk_widget_set_usize( m_widget, m_width, m_height );
362c6693
RR
2377 }
2378}
c801d85f 2379
debe6624 2380void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f 2381{
e55ad60e 2382 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2383
e55ad60e 2384 wxASSERT_MSG( (m_wxwindow != NULL), "window needs client area" );
47d67540 2385
c801d85f 2386 if (!m_wxwindow) return;
47d67540 2387
c801d85f
KB
2388 if (orient == wxHORIZONTAL)
2389 {
2390 float fpos = (float)pos;
2391 m_oldHorizontalPos = fpos;
2392
2393 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
2394 m_hAdjust->value = fpos;
2395 }
2396 else
2397 {
2398 float fpos = (float)pos;
2399 m_oldVerticalPos = fpos;
2400 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
2401 m_vAdjust->value = fpos;
362c6693 2402 }
47d67540 2403
cb43b372
RR
2404 if (!m_isScrolling)
2405 {
2406 if (m_wxwindow->window)
47d67540 2407 {
cb43b372
RR
2408 if (orient == wxHORIZONTAL)
2409 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
47d67540 2410 else
cb43b372
RR
2411 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
2412 }
362c6693
RR
2413 }
2414}
c801d85f 2415
debe6624 2416int wxWindow::GetScrollThumb( int orient ) const
c801d85f 2417{
e55ad60e 2418 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2419
e55ad60e 2420 wxASSERT_MSG( (m_wxwindow != NULL), "window needs client area" );
47d67540 2421
c801d85f
KB
2422 if (!m_wxwindow) return 0;
2423
2424 if (orient == wxHORIZONTAL)
2425 return (int)(m_hAdjust->page_size+0.5);
2426 else
2427 return (int)(m_vAdjust->page_size+0.5);
362c6693 2428}
c801d85f 2429
debe6624 2430int wxWindow::GetScrollPos( int orient ) const
c801d85f 2431{
e55ad60e 2432 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2433
e55ad60e 2434 wxASSERT_MSG( (m_wxwindow != NULL), "window needs client area" );
47d67540 2435
c801d85f
KB
2436 if (!m_wxwindow) return 0;
2437
2438 if (orient == wxHORIZONTAL)
2439 return (int)(m_hAdjust->value+0.5);
2440 else
2441 return (int)(m_vAdjust->value+0.5);
362c6693 2442}
c801d85f 2443
debe6624 2444int wxWindow::GetScrollRange( int orient ) const
c801d85f 2445{
e55ad60e 2446 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2447
e55ad60e 2448 wxASSERT_MSG( (m_wxwindow != NULL), "window needs client area" );
47d67540 2449
c801d85f
KB
2450 if (!m_wxwindow) return 0;
2451
2452 if (orient == wxHORIZONTAL)
2453 return (int)(m_hAdjust->upper+0.5);
2454 else
2455 return (int)(m_vAdjust->upper+0.5);
362c6693 2456}
c801d85f 2457
debe6624 2458void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f 2459{
e55ad60e 2460 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 2461
e55ad60e 2462 wxASSERT_MSG( (m_wxwindow != NULL), "window needs client area" );
47d67540 2463
e55ad60e 2464 if (!m_wxwindow) return;
c801d85f
KB
2465
2466 int cw = 0;
2467 int ch = 0;
2468 GetClientSize( &cw, &ch );
47d67540 2469
c801d85f
KB
2470 int w = cw - abs(dx);
2471 int h = ch - abs(dy);
2472 if ((h < 0) || (w < 0))
2473 {
2474 Refresh();
2475 return;
362c6693 2476 }
c801d85f
KB
2477 int s_x = 0;
2478 int s_y = 0;
2479 if (dx < 0) s_x = -dx;
2480 if (dy < 0) s_y = -dy;
2481 int d_x = 0;
2482 int d_y = 0;
2483 if (dx > 0) d_x = dx;
2484 if (dy > 0) d_y = dy;
32e9da8b
RR
2485
2486 if (!m_scrollGC)
2487 {
2488 m_scrollGC = gdk_gc_new( m_wxwindow->window );
2489 gdk_gc_set_exposures( m_scrollGC, TRUE );
2490 }
2491
2492 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
c801d85f 2493 m_wxwindow->window, s_x, s_y, w, h );
47d67540 2494
c801d85f
KB
2495 wxRect rect;
2496 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
2497 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
2498 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
2499 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
47d67540 2500
c801d85f 2501 Refresh( TRUE, &rect );
362c6693 2502}
c801d85f
KB
2503
2504//-------------------------------------------------------------------------------------
2505// Layout
2506//-------------------------------------------------------------------------------------
2507
68dda785 2508wxLayoutConstraints *wxWindow::GetConstraints() const
c801d85f
KB
2509{
2510 return m_constraints;
362c6693 2511}
c801d85f
KB
2512
2513void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
2514{
2515 if (m_constraints)
2516 {
2517 UnsetConstraints(m_constraints);
2518 delete m_constraints;
2519 }
2520 m_constraints = constraints;
2521 if (m_constraints)
2522 {
2523 // Make sure other windows know they're part of a 'meaningful relationship'
2524 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
2525 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2526 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
2527 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2528 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
2529 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2530 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
2531 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2532 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
2533 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2534 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
2535 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2536 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
2537 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2538 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
2539 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2540 }
2541;
2542}
2543;
2544
debe6624 2545void wxWindow::SetAutoLayout( bool autoLayout )
c801d85f
KB
2546{
2547 m_autoLayout = autoLayout;
362c6693 2548}
c801d85f 2549
68dda785 2550bool wxWindow::GetAutoLayout() const
c801d85f
KB
2551{
2552 return m_autoLayout;
362c6693 2553}
c801d85f 2554
68dda785 2555wxSizer *wxWindow::GetSizer() const
c801d85f
KB
2556{
2557 return m_windowSizer;
362c6693 2558}
c801d85f
KB
2559
2560void wxWindow::SetSizerParent( wxWindow *win )
2561{
2562 m_sizerParent = win;
362c6693 2563}
c801d85f 2564
68dda785 2565wxWindow *wxWindow::GetSizerParent() const
c801d85f
KB
2566{
2567 return m_sizerParent;
362c6693 2568}
c801d85f
KB
2569
2570// This removes any dangling pointers to this window
2571// in other windows' constraintsInvolvedIn lists.
2572void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
2573{
2574 if (c)
2575 {
2576 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
2577 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2578 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
2579 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2580 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
2581 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2582 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
2583 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2584 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
2585 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2586 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
2587 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2588 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
2589 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2590 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
2591 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2592 }
2593}
2594
2595// Back-pointer to other windows we're involved with, so if we delete
2596// this window, we must delete any constraints we're involved with.
2597void wxWindow::AddConstraintReference(wxWindow *otherWin)
2598{
2599 if (!m_constraintsInvolvedIn)
2600 m_constraintsInvolvedIn = new wxList;
2601 if (!m_constraintsInvolvedIn->Member(otherWin))
2602 m_constraintsInvolvedIn->Append(otherWin);
2603}
2604
2605// REMOVE back-pointer to other windows we're involved with.
2606void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
2607{
2608 if (m_constraintsInvolvedIn)
2609 m_constraintsInvolvedIn->DeleteObject(otherWin);
2610}
2611
2612// Reset any constraints that mention this window
68dda785 2613void wxWindow::DeleteRelatedConstraints()
c801d85f
KB
2614{
2615 if (m_constraintsInvolvedIn)
2616 {
2617 wxNode *node = m_constraintsInvolvedIn->First();
2618 while (node)
2619 {
2620 wxWindow *win = (wxWindow *)node->Data();
2621 wxNode *next = node->Next();
2622 wxLayoutConstraints *constr = win->GetConstraints();
2623
2624 // Reset any constraints involving this window
2625 if (constr)
2626 {
2627 constr->left.ResetIfWin((wxWindow *)this);
2628 constr->top.ResetIfWin((wxWindow *)this);
2629 constr->right.ResetIfWin((wxWindow *)this);
2630 constr->bottom.ResetIfWin((wxWindow *)this);
2631 constr->width.ResetIfWin((wxWindow *)this);
2632 constr->height.ResetIfWin((wxWindow *)this);
2633 constr->centreX.ResetIfWin((wxWindow *)this);
2634 constr->centreY.ResetIfWin((wxWindow *)this);
2635 }
2636 delete node;
2637 node = next;
2638 }
2639 delete m_constraintsInvolvedIn;
c67daf87 2640 m_constraintsInvolvedIn = (wxList *) NULL;
c801d85f
KB
2641 }
2642}
2643
2644void wxWindow::SetSizer(wxSizer *sizer)
2645{
2646 m_windowSizer = sizer;
2647 if (sizer)
2648 sizer->SetSizerParent((wxWindow *)this);
2649}
2650
2651/*
2652 * New version
2653 */
2654
68dda785 2655bool wxWindow::Layout()
c801d85f
KB
2656{
2657 if (GetConstraints())
2658 {
2659 int w, h;
2660 GetClientSize(&w, &h);
2661 GetConstraints()->width.SetValue(w);
2662 GetConstraints()->height.SetValue(h);
2663 }
47d67540 2664
c801d85f
KB
2665 // If top level (one sizer), evaluate the sizer's constraints.
2666 if (GetSizer())
2667 {
2668 int noChanges;
2669 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2670 GetSizer()->LayoutPhase1(&noChanges);
2671 GetSizer()->LayoutPhase2(&noChanges);
2672 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2673 return TRUE;
2674 }
2675 else
2676 {
2677 // Otherwise, evaluate child constraints
2678 ResetConstraints(); // Mark all constraints as unevaluated
2679 DoPhase(1); // Just one phase need if no sizers involved
2680 DoPhase(2);
2681 SetConstraintSizes(); // Recursively set the real window sizes
2682 }
2683 return TRUE;
2684}
2685
2686
2687// Do a phase of evaluating constraints:
2688// the default behaviour. wxSizers may do a similar
2689// thing, but also impose their own 'constraints'
2690// and order the evaluation differently.
2691bool wxWindow::LayoutPhase1(int *noChanges)
2692{
2693 wxLayoutConstraints *constr = GetConstraints();
2694 if (constr)
2695 {
2696 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
2697 }
2698 else
2699 return TRUE;
2700}
2701
2702bool wxWindow::LayoutPhase2(int *noChanges)
2703{
2704 *noChanges = 0;
47d67540 2705
c801d85f
KB
2706 // Layout children
2707 DoPhase(1);
2708 DoPhase(2);
2709 return TRUE;
2710}
2711
2712// Do a phase of evaluating child constraints
debe6624 2713bool wxWindow::DoPhase(int phase)
c801d85f
KB
2714{
2715 int noIterations = 0;
2716 int maxIterations = 500;
2717 int noChanges = 1;
2718 int noFailures = 0;
2719 wxList succeeded;
2720 while ((noChanges > 0) && (noIterations < maxIterations))
2721 {
2722 noChanges = 0;
2723 noFailures = 0;
2724 wxNode *node = GetChildren()->First();
2725 while (node)
2726 {
2727 wxWindow *child = (wxWindow *)node->Data();
2728 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
2729 {
2730 wxLayoutConstraints *constr = child->GetConstraints();
2731 if (constr)
2732 {
2733 if (succeeded.Member(child))
2734 {
2735 }
2736 else
2737 {
2738 int tempNoChanges = 0;
2739 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
2740 noChanges += tempNoChanges;
2741 if (success)
2742 {
2743 succeeded.Append(child);
2744 }
2745 }
2746 }
2747 }
2748 node = node->Next();
2749 }
2750 noIterations ++;
2751 }
2752 return TRUE;
2753}
2754
68dda785 2755void wxWindow::ResetConstraints()
c801d85f
KB
2756{
2757 wxLayoutConstraints *constr = GetConstraints();
2758 if (constr)
2759 {
2760 constr->left.SetDone(FALSE);
2761 constr->top.SetDone(FALSE);
2762 constr->right.SetDone(FALSE);
2763 constr->bottom.SetDone(FALSE);
2764 constr->width.SetDone(FALSE);
2765 constr->height.SetDone(FALSE);
2766 constr->centreX.SetDone(FALSE);
2767 constr->centreY.SetDone(FALSE);
2768 }
2769 wxNode *node = GetChildren()->First();
2770 while (node)
2771 {
2772 wxWindow *win = (wxWindow *)node->Data();
2773 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
2774 win->ResetConstraints();
2775 node = node->Next();
2776 }
2777}
2778
2779// Need to distinguish between setting the 'fake' size for
2780// windows and sizers, and setting the real values.
debe6624 2781void wxWindow::SetConstraintSizes(bool recurse)
c801d85f
KB
2782{
2783 wxLayoutConstraints *constr = GetConstraints();
2784 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
2785 constr->width.GetDone() && constr->height.GetDone())
2786 {
2787 int x = constr->left.GetValue();
2788 int y = constr->top.GetValue();
2789 int w = constr->width.GetValue();
2790 int h = constr->height.GetValue();
2791
2792 // If we don't want to resize this window, just move it...
2793 if ((constr->width.GetRelationship() != wxAsIs) ||
2794 (constr->height.GetRelationship() != wxAsIs))
2795 {
2796 // Calls Layout() recursively. AAAGH. How can we stop that.
2797 // Simply take Layout() out of non-top level OnSizes.
2798 SizerSetSize(x, y, w, h);
2799 }
2800 else
2801 {
2802 SizerMove(x, y);
2803 }
2804 }
2805 else if (constr)
2806 {
2807 char *windowClass = this->GetClassInfo()->GetClassName();
2808
2809 wxString winName;
5e0aa05a 2810 if (GetName() == "")
1a5a8367 2811 winName = _("unnamed");
5e0aa05a
VZ
2812 else
2813 winName = GetName();
1a5a8367 2814 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass, (const char *)winName);
c801d85f 2815 if (!constr->left.GetDone())
1a5a8367 2816 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
c801d85f 2817 if (!constr->right.GetDone())
1a5a8367 2818 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
c801d85f 2819 if (!constr->width.GetDone())
1a5a8367 2820 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
c801d85f 2821 if (!constr->height.GetDone())
1a5a8367
DP
2822 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2823 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
c801d85f
KB
2824 }
2825
2826 if (recurse)
2827 {
2828 wxNode *node = GetChildren()->First();
2829 while (node)
2830 {
2831 wxWindow *win = (wxWindow *)node->Data();
2832 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
2833 win->SetConstraintSizes();
2834 node = node->Next();
2835 }
2836 }
2837}
2838
2839// This assumes that all sizers are 'on' the same
2840// window, i.e. the parent of this window.
2841void wxWindow::TransformSizerToActual(int *x, int *y) const
2842{
2843 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
5e0aa05a 2844 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
c801d85f 2845 return;
47d67540 2846
c801d85f
KB
2847 int xp, yp;
2848 m_sizerParent->GetPosition(&xp, &yp);
2849 m_sizerParent->TransformSizerToActual(&xp, &yp);
2850 *x += xp;
2851 *y += yp;
2852}
2853
debe6624 2854void wxWindow::SizerSetSize(int x, int y, int w, int h)
c801d85f 2855{
5e0aa05a
VZ
2856 int xx = x;
2857 int yy = y;
c801d85f
KB
2858 TransformSizerToActual(&xx, &yy);
2859 SetSize(xx, yy, w, h);
2860}
2861
debe6624 2862void wxWindow::SizerMove(int x, int y)
c801d85f 2863{
5e0aa05a
VZ
2864 int xx = x;
2865 int yy = y;
c801d85f
KB
2866 TransformSizerToActual(&xx, &yy);
2867 Move(xx, yy);
2868}
2869
2870// Only set the size/position of the constraint (if any)
debe6624 2871void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
c801d85f
KB
2872{
2873 wxLayoutConstraints *constr = GetConstraints();
2874 if (constr)
2875 {
2876 if (x != -1)
2877 {
2878 constr->left.SetValue(x);
2879 constr->left.SetDone(TRUE);
2880 }
2881 if (y != -1)
2882 {
2883 constr->top.SetValue(y);
2884 constr->top.SetDone(TRUE);
2885 }
2886 if (w != -1)
2887 {
2888 constr->width.SetValue(w);
2889 constr->width.SetDone(TRUE);
2890 }
2891 if (h != -1)
2892 {
2893 constr->height.SetValue(h);
2894 constr->height.SetDone(TRUE);
2895 }
2896 }
2897}
2898
debe6624 2899void wxWindow::MoveConstraint(int x, int y)
c801d85f
KB
2900{
2901 wxLayoutConstraints *constr = GetConstraints();
2902 if (constr)
2903 {
2904 if (x != -1)
2905 {
2906 constr->left.SetValue(x);
2907 constr->left.SetDone(TRUE);
2908 }
2909 if (y != -1)
2910 {
2911 constr->top.SetValue(y);
2912 constr->top.SetDone(TRUE);
2913 }
2914 }
2915}
2916
2917void wxWindow::GetSizeConstraint(int *w, int *h) const
2918{
2919 wxLayoutConstraints *constr = GetConstraints();
2920 if (constr)
2921 {
2922 *w = constr->width.GetValue();
2923 *h = constr->height.GetValue();
2924 }
2925 else
2926 GetSize(w, h);
2927}
2928
2929void wxWindow::GetClientSizeConstraint(int *w, int *h) const
2930{
2931 wxLayoutConstraints *constr = GetConstraints();
2932 if (constr)
2933 {
2934 *w = constr->width.GetValue();
2935 *h = constr->height.GetValue();
2936 }
2937 else
2938 GetClientSize(w, h);
2939}
2940
2941void wxWindow::GetPositionConstraint(int *x, int *y) const
2942{
2943 wxLayoutConstraints *constr = GetConstraints();
2944 if (constr)
2945 {
2946 *x = constr->left.GetValue();
2947 *y = constr->top.GetValue();
2948 }
2949 else
2950 GetPosition(x, y);
2951}
2952
7fd1d163 2953bool wxWindow::AcceptsFocus() const
0abbe297
VZ
2954{
2955 return IsEnabled() && IsShown();
2956}
5e0aa05a 2957
e3e65dac 2958void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) )
5e0aa05a
VZ
2959{
2960 UpdateWindowUI();
2961}