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