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