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