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