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