]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/window.cpp
wxMimeTypesManagerImpl::GetFileTypeFromMimeType() implemented
[wxWidgets.git] / src / gtk1 / window.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: window.cpp
3// Purpose:
4// Author: Robert Roebling
c67d8618 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart
5e0aa05a 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation "window.h"
13#endif
14
15#include "wx/defs.h"
16#include "wx/window.h"
17#include "wx/dc.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/layout.h"
21#include "wx/utils.h"
22#include "wx/dialog.h"
23#include "wx/msgdlg.h"
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 );
6ca41e57
RR
1234}
1235
bbe0af5b
RR
1236//-----------------------------------------------------------------------------
1237// global functions
1238//-----------------------------------------------------------------------------
1239
1240wxWindow* wxGetActiveWindow()
1241{
1242 return g_focusWindow;
1243}
1244
c801d85f 1245//-----------------------------------------------------------------------------
2f2aa628 1246// wxWindow
c801d85f
KB
1247//-----------------------------------------------------------------------------
1248
1249IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
1250
1251BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
e380f72b
RR
1252 EVT_SIZE(wxWindow::OnSize)
1253 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
1254 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
1255 EVT_IDLE(wxWindow::OnIdle)
b666df2c 1256 EVT_KEY_DOWN(wxWindow::OnKeyDown)
c801d85f
KB
1257END_EVENT_TABLE()
1258
1259wxWindow::wxWindow()
1260{
e380f72b
RR
1261 m_widget = (GtkWidget *) NULL;
1262 m_wxwindow = (GtkWidget *) NULL;
1263 m_parent = (wxWindow *) NULL;
1264 m_children.DeleteContents( FALSE );
8bbe427f 1265
e380f72b
RR
1266 m_x = 0;
1267 m_y = 0;
1268 m_width = 0;
1269 m_height = 0;
1270 m_minWidth = -1;
1271 m_minHeight = -1;
1272 m_maxWidth = -1;
1273 m_maxHeight = -1;
8bbe427f 1274
e380f72b 1275 m_retCode = 0;
8bbe427f 1276
e380f72b
RR
1277 m_eventHandler = this;
1278 m_windowValidator = (wxValidator *) NULL;
8bbe427f 1279
e380f72b 1280 m_windowId = -1;
8bbe427f 1281
e380f72b
RR
1282 m_cursor = (wxCursor *) NULL;
1283 m_font = *wxSWISS_FONT;
1284 m_windowStyle = 0;
1285 m_windowName = "noname";
8bbe427f 1286
e380f72b
RR
1287 m_constraints = (wxLayoutConstraints *) NULL;
1288 m_constraintsInvolvedIn = (wxList *) NULL;
1289 m_windowSizer = (wxSizer *) NULL;
1290 m_sizerParent = (wxWindow *) NULL;
1291 m_autoLayout = FALSE;
8bbe427f 1292
e380f72b
RR
1293 m_sizeSet = FALSE;
1294 m_hasVMT = FALSE;
1295 m_needParent = TRUE;
8bbe427f 1296
e380f72b
RR
1297 m_hasScrolling = FALSE;
1298 m_isScrolling = FALSE;
1299 m_hAdjust = (GtkAdjustment*) NULL;
1300 m_vAdjust = (GtkAdjustment*) NULL;
1301 m_oldHorizontalPos = 0.0;
1302 m_oldVerticalPos = 0.0;
8bbe427f 1303
e380f72b
RR
1304 m_isShown = FALSE;
1305 m_isEnabled = TRUE;
8bbe427f 1306
06cfab17 1307#if wxUSE_DRAG_AND_DROP
e380f72b 1308 m_dropTarget = (wxDropTarget*) NULL;
ac57418f 1309#endif
e380f72b
RR
1310 m_resizing = FALSE;
1311 m_scrollGC = (GdkGC*) NULL;
1312 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1313
e380f72b 1314 m_insertCallback = wxInsertChildInWindow;
8bbe427f 1315
e380f72b
RR
1316 m_clientObject = (wxClientData*) NULL;
1317 m_clientData = NULL;
1ecc4d80
RR
1318
1319 m_isStaticBox = FALSE;
b292e2f5 1320 m_acceptsFocus = FALSE;
362c6693 1321}
c801d85f 1322
6ca41e57 1323wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
e380f72b
RR
1324 const wxPoint &pos, const wxSize &size,
1325 long style, const wxString &name )
6ca41e57 1326{
e380f72b
RR
1327 m_insertCallback = wxInsertChildInWindow;
1328 Create( parent, id, pos, size, style, name );
6ca41e57 1329}
8bbe427f 1330
debe6624 1331bool wxWindow::Create( wxWindow *parent, wxWindowID id,
e380f72b
RR
1332 const wxPoint &pos, const wxSize &size,
1333 long style, const wxString &name )
c801d85f 1334{
e380f72b
RR
1335 m_isShown = FALSE;
1336 m_isEnabled = TRUE;
1337 m_needParent = TRUE;
47d67540 1338
e380f72b 1339 PreCreation( parent, id, pos, size, style, name );
47d67540 1340
e380f72b 1341 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
38c7b3d3 1342 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
b292e2f5
RR
1343
1344#ifdef __WXDEBUG__
1345 debug_focus_in( m_widget, "wxWindow::m_widget", name );
1346#endif
47d67540 1347
e380f72b 1348 GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget);
47d67540 1349
b292e2f5
RR
1350#ifdef __WXDEBUG__
1351 debug_focus_in( s_window->hscrollbar, "wxWindow::hsrcollbar", name );
1352 debug_focus_in( s_window->vscrollbar, "wxWindow::vsrcollbar", name );
1353#endif
1354
e380f72b
RR
1355 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
1356 scroll_class->scrollbar_spacing = 0;
47d67540 1357
e380f72b 1358 gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
47d67540 1359
e380f72b
RR
1360 m_oldHorizontalPos = 0.0;
1361 m_oldVerticalPos = 0.0;
47d67540 1362
e380f72b
RR
1363 m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
1364 m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
47d67540 1365
38c7b3d3
RR
1366 m_wxwindow = gtk_myfixed_new();
1367
b292e2f5
RR
1368#ifdef __WXDEBUG__
1369 debug_focus_in( m_wxwindow, "wxWindow::m_wxwindow", name );
1370#endif
1371
38c7b3d3
RR
1372#ifdef NEW_GTK_SCROLL_CODE
1373 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), m_wxwindow );
1374 GtkViewport *viewport = GTK_VIEWPORT(s_window->child);
1375#else
1376 gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
e380f72b 1377 GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport);
38c7b3d3 1378#endif
47d67540 1379
b292e2f5
RR
1380#ifdef __WXDEBUG__
1381 debug_focus_in( GTK_WIDGET(viewport), "wxWindow::viewport", name );
1382#endif
1383
e380f72b
RR
1384 if (m_windowStyle & wxRAISED_BORDER)
1385 {
1386 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
1387 }
1388 else if (m_windowStyle & wxSUNKEN_BORDER)
1389 {
1390 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
1391 }
1392 else
1393 {
1394 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
1395 }
47d67540 1396
b292e2f5
RR
1397 if ((m_windowStyle & wxTAB_TRAVERSAL) != 0)
1398 {
e380f72b 1399 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1400 m_acceptsFocus = FALSE;
1401 }
e380f72b 1402 else
b292e2f5 1403 {
e380f72b 1404 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1405 m_acceptsFocus = TRUE;
1406 }
e380f72b 1407
e380f72b
RR
1408 // shut the viewport up
1409 gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1410 gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1411
1412 // I _really_ don't want scrollbars in the beginning
1413 m_vAdjust->lower = 0.0;
1414 m_vAdjust->upper = 1.0;
1415 m_vAdjust->value = 0.0;
1416 m_vAdjust->step_increment = 1.0;
1417 m_vAdjust->page_increment = 1.0;
1418 m_vAdjust->page_size = 5.0;
1419 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
1420 m_hAdjust->lower = 0.0;
1421 m_hAdjust->upper = 1.0;
1422 m_hAdjust->value = 0.0;
1423 m_hAdjust->step_increment = 1.0;
1424 m_hAdjust->page_increment = 1.0;
1425 m_hAdjust->page_size = 5.0;
1426 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
1427
76ed8f8d
RR
1428 // these handlers block mouse events to any window during scrolling
1429 // such as motion events and prevent GTK and wxWindows from fighting
1430 // over where the slider should be
8bbe427f 1431
76ed8f8d
RR
1432 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
1433 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1434
1435 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
1436 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1437
1438 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
1439 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
1440
1441 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
1442 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
8bbe427f 1443
76ed8f8d
RR
1444 // these handers het notified when screen updates are required either when
1445 // scrolling or when the window size (and therefore scrollbar configuration)
1446 // has changed
1447
1448 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
1449 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
1450 gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
1451 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
1452
1453 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
1454 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
1455 gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
1456 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
1457
e380f72b 1458 gtk_widget_show( m_wxwindow );
8bbe427f 1459
e380f72b 1460 if (m_parent) m_parent->AddChild( this );
47d67540 1461
e380f72b 1462 (m_parent->m_insertCallback)( m_parent, this );
8bbe427f 1463
e380f72b 1464 PostCreation();
8bbe427f 1465
e380f72b 1466 Show( TRUE );
c801d85f 1467
e380f72b 1468 return TRUE;
362c6693 1469}
c801d85f 1470
68dda785 1471wxWindow::~wxWindow()
c801d85f 1472{
43a18898 1473 m_hasVMT = FALSE;
47d67540 1474
06cfab17 1475#if wxUSE_DRAG_AND_DROP
43a18898 1476 if (m_dropTarget) delete m_dropTarget;
ac57418f 1477#endif
47d67540 1478
43a18898
RR
1479 if (m_parent) m_parent->RemoveChild( this );
1480 if (m_widget) Show( FALSE );
c801d85f 1481
43a18898 1482 DestroyChildren();
47d67540 1483
43a18898 1484 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 1485
43a18898 1486 if (m_scrollGC) gdk_gc_unref( m_scrollGC );
8bbe427f 1487
43a18898 1488 if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
47d67540 1489
43a18898 1490 if (m_widget) gtk_widget_destroy( m_widget );
8bbe427f 1491
43a18898 1492 if (m_cursor) delete m_cursor;
c801d85f 1493
43a18898
RR
1494 DeleteRelatedConstraints();
1495 if (m_constraints)
1496 {
1497 // This removes any dangling pointers to this window
1498 // in other windows' constraintsInvolvedIn lists.
1499 UnsetConstraints(m_constraints);
1500 delete m_constraints;
1501 m_constraints = (wxLayoutConstraints *) NULL;
1502 }
1503 if (m_windowSizer)
1504 {
1505 delete m_windowSizer;
1506 m_windowSizer = (wxSizer *) NULL;
1507 }
1508 // If this is a child of a sizer, remove self from parent
1509 if (m_sizerParent) m_sizerParent->RemoveChild((wxWindow *)this);
c801d85f 1510
43a18898
RR
1511 // Just in case the window has been Closed, but
1512 // we're then deleting immediately: don't leave
1513 // dangling pointers.
1514 wxPendingDelete.DeleteObject(this);
c801d85f 1515
43a18898
RR
1516 // Just in case we've loaded a top-level window via
1517 // wxWindow::LoadNativeDialog but we weren't a dialog
1518 // class
1519 wxTopLevelWindows.DeleteObject(this);
47d67540 1520
43a18898 1521 if (m_windowValidator) delete m_windowValidator;
8bbe427f 1522
43a18898 1523 if (m_clientObject) delete m_clientObject;
362c6693 1524}
c801d85f 1525
debe6624
JS
1526void wxWindow::PreCreation( wxWindow *parent, wxWindowID id,
1527 const wxPoint &pos, const wxSize &size,
1528 long style, const wxString &name )
c801d85f 1529{
3069ac4e 1530 wxASSERT_MSG( (!m_needParent) || (parent), "Need complete parent." );
8bbe427f 1531
43a18898
RR
1532 m_widget = (GtkWidget*) NULL;
1533 m_wxwindow = (GtkWidget*) NULL;
1534 m_hasVMT = FALSE;
1535 m_parent = parent;
1536 m_children.DeleteContents( FALSE );
8bbe427f 1537
43a18898
RR
1538 m_width = size.x;
1539 if (m_width == -1) m_width = 20;
1540 m_height = size.y;
1541 if (m_height == -1) m_height = 20;
8bbe427f 1542
43a18898
RR
1543 m_x = (int)pos.x;
1544 m_y = (int)pos.y;
8bbe427f 1545
43a18898 1546 if (!m_needParent) // some reasonable defaults
6ca41e57 1547 {
43a18898
RR
1548 if (m_x == -1)
1549 {
1550 m_x = (gdk_screen_width () - m_width) / 2;
1551 if (m_x < 10) m_x = 10;
1552 }
1553 if (m_y == -1)
1554 {
1555 m_y = (gdk_screen_height () - m_height) / 2;
1556 if (m_y < 10) m_y = 10;
1557 }
6ca41e57 1558 }
8bbe427f 1559
43a18898
RR
1560 m_minWidth = -1;
1561 m_minHeight = -1;
1562 m_maxWidth = -1;
1563 m_maxHeight = -1;
8bbe427f 1564
43a18898 1565 m_retCode = 0;
8bbe427f 1566
43a18898 1567 m_eventHandler = this;
8bbe427f 1568
b749747d 1569 m_windowId = id == -1 ? wxNewId() : id;
8bbe427f 1570
43a18898 1571 m_sizeSet = FALSE;
8bbe427f 1572
43a18898
RR
1573 m_cursor = new wxCursor( wxCURSOR_ARROW );
1574 m_font = *wxSWISS_FONT;
1ecc4d80
RR
1575 m_backgroundColour = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
1576 m_foregroundColour = *wxBLACK;
43a18898
RR
1577 m_windowStyle = style;
1578 m_windowName = name;
8bbe427f 1579
43a18898
RR
1580 m_constraints = (wxLayoutConstraints *) NULL;
1581 m_constraintsInvolvedIn = (wxList *) NULL;
1582 m_windowSizer = (wxSizer *) NULL;
1583 m_sizerParent = (wxWindow *) NULL;
1584 m_autoLayout = FALSE;
8bbe427f 1585
43a18898
RR
1586 m_hasScrolling = FALSE;
1587 m_isScrolling = FALSE;
1588 m_hAdjust = (GtkAdjustment *) NULL;
1589 m_vAdjust = (GtkAdjustment *) NULL;
1590 m_oldHorizontalPos = 0.0;
1591 m_oldVerticalPos = 0.0;
8bbe427f 1592
43a18898
RR
1593 m_isShown = FALSE;
1594 m_isEnabled = TRUE;
8bbe427f 1595
06cfab17 1596#if wxUSE_DRAG_AND_DROP
43a18898 1597 m_dropTarget = (wxDropTarget *) NULL;
ac57418f 1598#endif
43a18898
RR
1599 m_resizing = FALSE;
1600 m_windowValidator = (wxValidator *) NULL;
1601 m_scrollGC = (GdkGC*) NULL;
1602 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1603
43a18898
RR
1604 m_clientObject = (wxClientData*)NULL;
1605 m_clientData = NULL;
1ecc4d80
RR
1606
1607 m_isStaticBox = FALSE;
c801d85f
KB
1608}
1609
68dda785 1610void wxWindow::PostCreation()
c801d85f 1611{
43a18898
RR
1612 if (m_wxwindow)
1613 {
1614 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
1615 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
47d67540 1616
43a18898
RR
1617 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
1618 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
1619 }
47d67540 1620
43a18898 1621 ConnectWidget( GetConnectWidget() );
47d67540 1622
43a18898 1623 if (m_widget && m_parent) gtk_widget_realize( m_widget );
47d67540 1624
43a18898 1625 if (m_wxwindow) gtk_widget_realize( m_wxwindow );
47d67540 1626
43a18898 1627 SetCursor( *wxSTANDARD_CURSOR );
47d67540 1628
43a18898 1629 m_hasVMT = TRUE;
b4071e91
RR
1630}
1631
1632void wxWindow::ConnectWidget( GtkWidget *widget )
1633{
43a18898
RR
1634 gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
1635 GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
c801d85f 1636
b666df2c
RR
1637 gtk_signal_connect( GTK_OBJECT(widget), "key_release_event",
1638 GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this );
1639
43a18898
RR
1640 gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
1641 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
47d67540 1642
43a18898
RR
1643 gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
1644 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
47d67540 1645
43a18898
RR
1646 gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
1647 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
47d67540 1648
43a18898
RR
1649 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
1650 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
c801d85f 1651
43a18898
RR
1652 gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
1653 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
c801d85f 1654
43a18898
RR
1655 gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
1656 GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
47d67540 1657
43a18898
RR
1658 gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
1659 GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
362c6693 1660}
c801d85f 1661
68dda785 1662bool wxWindow::HasVMT()
c801d85f 1663{
43a18898 1664 return m_hasVMT;
362c6693 1665}
c801d85f 1666
debe6624 1667bool wxWindow::Close( bool force )
c801d85f 1668{
43a18898 1669 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1670
43a18898
RR
1671 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
1672 event.SetEventObject(this);
1673 event.SetForce(force);
c801d85f 1674
43a18898 1675 return GetEventHandler()->ProcessEvent(event);
362c6693 1676}
c801d85f 1677
68dda785 1678bool wxWindow::Destroy()
c801d85f 1679{
43a18898 1680 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
47d67540 1681
43a18898
RR
1682 m_hasVMT = FALSE;
1683 delete this;
1684 return TRUE;
362c6693 1685}
c801d85f 1686
68dda785 1687bool wxWindow::DestroyChildren()
c801d85f 1688{
db1b4961
RR
1689 wxNode *node;
1690 while ((node = m_children.First()) != (wxNode *)NULL)
c801d85f 1691 {
db1b4961
RR
1692 wxWindow *child;
1693 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL)
43a18898 1694 {
db1b4961
RR
1695 delete child;
1696 if (m_children.Member(child)) delete node;
43a18898 1697 }
362c6693 1698 }
43a18898 1699 return TRUE;
362c6693 1700}
c801d85f
KB
1701
1702void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
1703{
43a18898 1704 // are we to set fonts here ?
362c6693 1705}
c801d85f 1706
6ca41e57
RR
1707wxPoint wxWindow::GetClientAreaOrigin() const
1708{
43a18898 1709 return wxPoint(0,0);
6ca41e57
RR
1710}
1711
1712void wxWindow::AdjustForParentClientOrigin( int& x, int& y, int sizeFlags )
1713{
43a18898
RR
1714 if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent())
1715 {
1716 wxPoint pt(GetParent()->GetClientAreaOrigin());
8bbe427f 1717 x += pt.x;
43a18898
RR
1718 y += pt.y;
1719 }
6ca41e57
RR
1720}
1721
debe6624 1722void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 1723{
fb1585ae
RR
1724 wxASSERT_MSG( (m_widget != NULL), "invalid window" );
1725 wxASSERT_MSG( (m_parent != NULL), "wxWindow::SetSize requires parent.\n" );
8bbe427f 1726
fb1585ae
RR
1727 if (m_resizing) return; // I don't like recursions
1728 m_resizing = TRUE;
47d67540 1729
ba4e3652 1730 if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
fb1585ae 1731 {
ba4e3652 1732 // don't set the size for children of wxNotebook, just take the values.
fb1585ae
RR
1733 m_x = x;
1734 m_y = y;
1735 m_width = width;
ba4e3652 1736 m_height = height;
fb1585ae 1737 }
ba4e3652 1738 else
fb1585ae 1739 {
ba4e3652
RR
1740 int old_width = m_width;
1741 int old_height = m_height;
8bbe427f 1742
ba4e3652
RR
1743 if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
1744 {
1745 if (x != -1) m_x = x;
1746 if (y != -1) m_y = y;
1747 if (width != -1) m_width = width;
1748 if (height != -1) m_height = height;
1749 }
1750 else
1751 {
1752 m_x = x;
1753 m_y = y;
1754 m_width = width;
1755 m_height = height;
1756 }
47d67540 1757
ba4e3652
RR
1758 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
1759 {
1760 if (width == -1) m_width = 80;
1761 }
1762
1763 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
1764 {
1765 if (height == -1) m_height = 26;
1766 }
8bbe427f 1767
ba4e3652
RR
1768 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
1769 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
d3b4d113
RR
1770 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
1771 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
47d67540 1772
ba4e3652
RR
1773 wxPoint pt( m_parent->GetClientAreaOrigin() );
1774 gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y );
8bbe427f 1775
ba4e3652
RR
1776 if ((old_width != m_width) || (old_height != m_height))
1777 gtk_widget_set_usize( m_widget, m_width, m_height );
1778 }
8bbe427f 1779
fb1585ae 1780 m_sizeSet = TRUE;
47d67540 1781
fb1585ae
RR
1782 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
1783 event.SetEventObject( this );
ba4e3652 1784 GetEventHandler()->ProcessEvent( event );
47d67540 1785
fb1585ae 1786 m_resizing = FALSE;
362c6693 1787}
c801d85f 1788
debe6624 1789void wxWindow::SetSize( int width, int height )
c801d85f 1790{
fb1585ae 1791 SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
362c6693 1792}
c801d85f 1793
debe6624 1794void wxWindow::Move( int x, int y )
c801d85f 1795{
fb1585ae 1796 SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
362c6693 1797}
c801d85f
KB
1798
1799void wxWindow::GetSize( int *width, int *height ) const
1800{
1ecc4d80 1801 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1802
fb1585ae
RR
1803 if (width) (*width) = m_width;
1804 if (height) (*height) = m_height;
362c6693 1805}
c801d85f 1806
debe6624 1807void wxWindow::SetClientSize( int width, int height )
c801d85f 1808{
1ecc4d80 1809 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1810
1ecc4d80 1811 if (!m_wxwindow)
c801d85f 1812 {
1ecc4d80 1813 SetSize( width, height );
c801d85f
KB
1814 }
1815 else
1816 {
1ecc4d80
RR
1817 int dw = 0;
1818 int dh = 0;
1819
1820 if (!m_hasScrolling)
1821 {
1822 GtkStyleClass *window_class = m_wxwindow->style->klass;
1823
1824 if ((m_windowStyle & wxRAISED_BORDER) ||
1825 (m_windowStyle & wxSUNKEN_BORDER))
1826 {
1827 dw += 2 * window_class->xthickness;
1828 dh += 2 * window_class->ythickness;
1829 }
1830 }
1831 else
1832 {
1833 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
1834 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 1835
38c7b3d3 1836#ifdef NEW_GTK_SCROLL_CODE
1ecc4d80 1837 GtkWidget *viewport = scroll_window->child;
8bbe427f 1838#else
1ecc4d80 1839 GtkWidget *viewport = scroll_window->viewport;
38c7b3d3
RR
1840#endif
1841
1ecc4d80
RR
1842 GtkStyleClass *viewport_class = viewport->style->klass;
1843
1844 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1845 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1846
1847 if ((m_windowStyle & wxRAISED_BORDER) ||
1848 (m_windowStyle & wxSUNKEN_BORDER))
1849 {
1850 dw += 2 * viewport_class->xthickness;
1851 dh += 2 * viewport_class->ythickness;
1852 }
47d67540 1853
1ecc4d80
RR
1854 if (scroll_window->vscrollbar_visible)
1855 {
1856 dw += vscrollbar->allocation.width;
1857 dw += scroll_class->scrollbar_spacing;
1858 }
1859
1860 if (scroll_window->hscrollbar_visible)
1861 {
1862 dh += hscrollbar->allocation.height;
1863 dw += scroll_class->scrollbar_spacing;
1864 }
1865 }
1866
1867 SetSize( width+dw, height+dh );
1868 }
362c6693 1869}
c801d85f
KB
1870
1871void wxWindow::GetClientSize( int *width, int *height ) const
1872{
1ecc4d80 1873 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1874
1ecc4d80
RR
1875 if (!m_wxwindow)
1876 {
1877 if (width) (*width) = m_width;
1878 if (height) (*height) = m_height;
c801d85f
KB
1879 }
1880 else
1881 {
1ecc4d80
RR
1882 int dw = 0;
1883 int dh = 0;
1884
1885 if (!m_hasScrolling)
1886 {
1887 GtkStyleClass *window_class = m_wxwindow->style->klass;
1888
1889 if ((m_windowStyle & wxRAISED_BORDER) ||
1890 (m_windowStyle & wxSUNKEN_BORDER))
1891 {
1892 dw += 2 * window_class->xthickness;
1893 dh += 2 * window_class->ythickness;
1894 }
1895 }
1896 else
1897 {
1898 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
1899 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 1900
38c7b3d3 1901#ifdef NEW_GTK_SCROLL_CODE
1ecc4d80 1902 GtkWidget *viewport = scroll_window->child;
8bbe427f 1903#else
1ecc4d80 1904 GtkWidget *viewport = scroll_window->viewport;
38c7b3d3
RR
1905#endif
1906
1ecc4d80
RR
1907 GtkStyleClass *viewport_class = viewport->style->klass;
1908
1909 if ((m_windowStyle & wxRAISED_BORDER) ||
1910 (m_windowStyle & wxSUNKEN_BORDER))
1911 {
1912 dw += 2 * viewport_class->xthickness;
1913 dh += 2 * viewport_class->ythickness;
1914 }
1915
1916 if (scroll_window->vscrollbar_visible)
1917 {
1918// dw += vscrollbar->allocation.width;
1919 dw += 15; // range.slider_width = 11 + 2*2pts edge
1920 dw += scroll_class->scrollbar_spacing;
1921 }
1922
1923 if (scroll_window->hscrollbar_visible)
1924 {
1925// dh += hscrollbar->allocation.height;
1926 dh += 15;
1927 dh += scroll_class->scrollbar_spacing;
1928 }
1929 }
47d67540 1930
1ecc4d80
RR
1931 if (width) (*width) = m_width - dw;
1932 if (height) (*height) = m_height - dh;
1933 }
362c6693 1934}
c801d85f
KB
1935
1936void wxWindow::GetPosition( int *x, int *y ) const
1937{
1ecc4d80 1938 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1939
43a18898
RR
1940 if (x) (*x) = m_x;
1941 if (y) (*y) = m_y;
362c6693 1942}
c801d85f
KB
1943
1944void wxWindow::ClientToScreen( int *x, int *y )
1945{
1ecc4d80 1946 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1947
43a18898
RR
1948 GdkWindow *source = (GdkWindow *) NULL;
1949 if (m_wxwindow)
1950 source = m_wxwindow->window;
1951 else
1952 source = m_widget->window;
47d67540 1953
43a18898
RR
1954 int org_x = 0;
1955 int org_y = 0;
1956 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 1957
43a18898 1958 if (!m_wxwindow)
c801d85f 1959 {
43a18898
RR
1960 if (GTK_WIDGET_NO_WINDOW (m_widget))
1961 {
1962 org_x += m_widget->allocation.x;
1963 org_y += m_widget->allocation.y;
1964 }
362c6693 1965 }
47d67540 1966
43a18898
RR
1967 wxPoint pt(GetClientAreaOrigin());
1968 org_x += pt.x;
1969 org_y += pt.y;
8bbe427f 1970
43a18898
RR
1971 if (x) *x += org_x;
1972 if (y) *y += org_y;
362c6693 1973}
c801d85f
KB
1974
1975void wxWindow::ScreenToClient( int *x, int *y )
1976{
1ecc4d80 1977 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 1978
1ecc4d80
RR
1979 GdkWindow *source = (GdkWindow *) NULL;
1980 if (m_wxwindow)
1981 source = m_wxwindow->window;
1982 else
1983 source = m_widget->window;
47d67540 1984
1ecc4d80
RR
1985 int org_x = 0;
1986 int org_y = 0;
1987 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 1988
1ecc4d80 1989 if (!m_wxwindow)
c801d85f 1990 {
1ecc4d80
RR
1991 if (GTK_WIDGET_NO_WINDOW (m_widget))
1992 {
1993 org_x += m_widget->allocation.x;
1994 org_y += m_widget->allocation.y;
1995 }
362c6693 1996 }
47d67540 1997
1ecc4d80
RR
1998 wxPoint pt(GetClientAreaOrigin());
1999 org_x -= pt.x;
2000 org_y -= pt.y;
8bbe427f 2001
1ecc4d80
RR
2002 if (x) *x -= org_x;
2003 if (y) *y -= org_y;
362c6693 2004}
c801d85f 2005
debe6624 2006void wxWindow::Centre( int direction )
c801d85f 2007{
1ecc4d80 2008 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2009
1ecc4d80
RR
2010 int x = m_x;
2011 int y = m_y;
8bbe427f 2012
1ecc4d80
RR
2013 if (m_parent)
2014 {
2015 int p_w = 0;
2016 int p_h = 0;
2017 m_parent->GetSize( &p_w, &p_h );
2018 if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (p_w - m_width) / 2;
2019 if (direction & wxVERTICAL == wxVERTICAL) y = (p_h - m_height) / 2;
2020 }
2021 else
2022 {
2023 if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
2024 if (direction & wxVERTICAL == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
2025 }
8bbe427f 2026
1ecc4d80 2027 Move( x, y );
362c6693 2028}
c801d85f 2029
68dda785 2030void wxWindow::Fit()
c801d85f 2031{
1ecc4d80 2032 wxCHECK_RET( (m_widget != NULL), "invalid window" );
5e0aa05a 2033
1ecc4d80
RR
2034 int maxX = 0;
2035 int maxY = 0;
2036 wxNode *node = m_children.First();
2037 while (node)
2038 {
2039 wxWindow *win = (wxWindow *)node->Data();
2040 int wx, wy, ww, wh;
2041 win->GetPosition(&wx, &wy);
2042 win->GetSize(&ww, &wh);
2043 if (wx + ww > maxX) maxX = wx + ww;
2044 if (wy + wh > maxY) maxY = wy + wh;
2045
2046 node = node->Next();
2047 }
2048
2049 SetClientSize(maxX + 7, maxY + 14);
362c6693 2050}
c801d85f 2051
2f2aa628
RR
2052void wxWindow::SetSizeHints( int minW, int minH, int maxW, int maxH, int WXUNUSED(incW), int WXUNUSED(incH) )
2053{
1ecc4d80 2054 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2055
1ecc4d80
RR
2056 m_minWidth = minW;
2057 m_minHeight = minH;
2058 m_maxWidth = maxW;
2059 m_maxHeight = maxH;
2f2aa628
RR
2060}
2061
c801d85f
KB
2062void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
2063{
f04371f0 2064// if (GetAutoLayout()) Layout();
362c6693 2065}
c801d85f 2066
debe6624 2067bool wxWindow::Show( bool show )
c801d85f 2068{
1ecc4d80 2069 wxCHECK_MSG( (m_widget != NULL), FALSE, "invalid window" );
47d67540 2070
1ecc4d80
RR
2071 if (show)
2072 gtk_widget_show( m_widget );
2073 else
2074 gtk_widget_hide( m_widget );
2075
2076 m_isShown = show;
2077
2078 return TRUE;
362c6693 2079}
c801d85f 2080
debe6624 2081void wxWindow::Enable( bool enable )
c801d85f 2082{
1ecc4d80 2083 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2084
1ecc4d80
RR
2085 m_isEnabled = enable;
2086
2087 gtk_widget_set_sensitive( m_widget, enable );
2088 if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
362c6693 2089}
c801d85f 2090
68dda785 2091int wxWindow::GetCharHeight() const
c33c4050 2092{
1ecc4d80 2093 wxCHECK_MSG( (m_widget != NULL), 12, "invalid window" );
47d67540 2094
1ecc4d80 2095 wxCHECK_MSG( m_font.Ok(), 12, "invalid font" );
47d67540 2096
1ecc4d80
RR
2097 GdkFont *font = m_font.GetInternalFont( 1.0 );
2098
2099 return font->ascent + font->descent;
c33c4050
RR
2100}
2101
68dda785 2102int wxWindow::GetCharWidth() const
c33c4050 2103{
1ecc4d80 2104 wxCHECK_MSG( (m_widget != NULL), 8, "invalid window" );
47d67540 2105
1ecc4d80 2106 wxCHECK_MSG( m_font.Ok(), 8, "invalid font" );
47d67540 2107
463c1fa1 2108 GdkFont *font = m_font.GetInternalFont( 1.0 );
1ecc4d80 2109
463c1fa1 2110 return gdk_string_width( font, "H" );
c33c4050
RR
2111}
2112
2113void wxWindow::GetTextExtent( const wxString& string, int *x, int *y,
2114 int *descent, int *externalLeading, const wxFont *theFont, bool WXUNUSED(use16) ) const
2115{
463c1fa1
RR
2116 wxFont fontToUse = m_font;
2117 if (theFont) fontToUse = *theFont;
47d67540 2118
1ecc4d80 2119 wxCHECK_RET( fontToUse.Ok(), "invalid font" );
47d67540 2120
463c1fa1
RR
2121 GdkFont *font = fontToUse.GetInternalFont( 1.0 );
2122 if (x) (*x) = gdk_string_width( font, string );
2123 if (y) (*y) = font->ascent + font->descent;
2124 if (descent) (*descent) = font->descent;
2125 if (externalLeading) (*externalLeading) = 0; // ??
c33c4050
RR
2126}
2127
debe6624 2128void wxWindow::MakeModal( bool modal )
c801d85f 2129{
1ecc4d80
RR
2130 return;
2131
2132 // Disable all other windows
2133 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
c801d85f 2134 {
1ecc4d80
RR
2135 wxNode *node = wxTopLevelWindows.First();
2136 while (node)
2137 {
2138 wxWindow *win = (wxWindow *)node->Data();
2139 if (win != this) win->Enable(!modal);
c801d85f 2140
1ecc4d80
RR
2141 node = node->Next();
2142 }
c801d85f 2143 }
c801d85f
KB
2144}
2145
b666df2c
RR
2146void wxWindow::OnKeyDown( wxKeyEvent &event )
2147{
2148 event.SetEventType( wxEVT_CHAR );
2149
2150 if (!GetEventHandler()->ProcessEvent( event ))
2151 {
2152 event.Skip();
2153 }
2154}
2155
68dda785 2156void wxWindow::SetFocus()
c801d85f 2157{
1ecc4d80 2158 wxCHECK_RET( (m_widget != NULL), "invalid window" );
b292e2f5 2159
463c1fa1
RR
2160 GtkWidget *connect_widget = GetConnectWidget();
2161 if (connect_widget)
c801d85f 2162 {
b292e2f5 2163 if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
463c1fa1
RR
2164 {
2165 gtk_widget_grab_focus (connect_widget);
2166 }
b292e2f5
RR
2167 else if (GTK_IS_CONTAINER(connect_widget))
2168 {
2169 gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD );
2170 }
2171 else
2172 {
2173 }
362c6693 2174 }
362c6693 2175}
c801d85f 2176
b292e2f5
RR
2177wxWindow *wxWindow::FindFocus()
2178{
2179 return g_focusWindow;
2180}
2181
2182bool wxWindow::AcceptsFocus() const
2183{
2184 return IsEnabled() && IsShown() && m_acceptsFocus;
2185}
2186
68dda785 2187bool wxWindow::OnClose()
c801d85f 2188{
463c1fa1 2189 return TRUE;
362c6693 2190}
c801d85f
KB
2191
2192void wxWindow::AddChild( wxWindow *child )
2193{
1ecc4d80
RR
2194 wxCHECK_RET( (m_widget != NULL), "invalid window" );
2195 wxCHECK_RET( (child != NULL), "invalid child" );
47d67540 2196
463c1fa1 2197 m_children.Append( child );
362c6693 2198}
c801d85f 2199
463c1fa1
RR
2200wxWindow *wxWindow::ReParent( wxWindow *newParent )
2201{
1ecc4d80
RR
2202 wxCHECK_MSG( (m_widget != NULL), (wxWindow*) NULL, "invalid window" );
2203
2204 wxWindow *oldParent = GetParent();
8bbe427f 2205
1ecc4d80 2206 if (oldParent) oldParent->RemoveChild( this );
8bbe427f 2207
1ecc4d80 2208 gtk_widget_unparent( m_widget );
8bbe427f 2209
1ecc4d80
RR
2210 if (newParent)
2211 {
2212 newParent->AddChild( this );
2213 (newParent->m_insertCallback)( newParent, this );
2214 }
8bbe427f 2215
1ecc4d80 2216 return oldParent;
362c6693 2217}
c801d85f
KB
2218
2219void wxWindow::RemoveChild( wxWindow *child )
2220{
db1b4961 2221 m_children.DeleteObject( child );
463c1fa1 2222 child->m_parent = (wxWindow *) NULL;
362c6693 2223}
c801d85f
KB
2224
2225void wxWindow::SetReturnCode( int retCode )
2226{
463c1fa1 2227 m_retCode = retCode;
362c6693 2228}
c801d85f 2229
68dda785 2230int wxWindow::GetReturnCode()
c801d85f 2231{
463c1fa1 2232 return m_retCode;
362c6693 2233}
c801d85f 2234
68dda785 2235void wxWindow::Raise()
362c6693 2236{
1ecc4d80 2237 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2238
463c1fa1 2239 if (m_widget) gdk_window_raise( m_widget->window );
362c6693
RR
2240}
2241
68dda785 2242void wxWindow::Lower()
362c6693 2243{
1ecc4d80 2244 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2245
463c1fa1 2246 if (m_widget) gdk_window_lower( m_widget->window );
362c6693 2247}
c801d85f 2248
8bbe427f 2249wxEvtHandler *wxWindow::GetEventHandler() const
c801d85f 2250{
463c1fa1 2251 return m_eventHandler;
362c6693 2252}
c801d85f 2253
86b29a61 2254void wxWindow::SetEventHandler( wxEvtHandler *handler )
c801d85f 2255{
463c1fa1 2256 m_eventHandler = handler;
362c6693 2257}
c801d85f 2258
86b29a61
RR
2259void wxWindow::PushEventHandler(wxEvtHandler *handler)
2260{
463c1fa1
RR
2261 handler->SetNextHandler(GetEventHandler());
2262 SetEventHandler(handler);
86b29a61
RR
2263}
2264
2265wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
2266{
463c1fa1 2267 if (GetEventHandler())
e55ad60e 2268 {
463c1fa1
RR
2269 wxEvtHandler *handlerA = GetEventHandler();
2270 wxEvtHandler *handlerB = handlerA->GetNextHandler();
2271 handlerA->SetNextHandler((wxEvtHandler *) NULL);
2272 SetEventHandler(handlerB);
2273 if (deleteHandler)
2274 {
2275 delete handlerA;
2276 return (wxEvtHandler*) NULL;
2277 }
2278 else
2279 return handlerA;
2280 }
2281 else
2282 return (wxEvtHandler *) NULL;
86b29a61
RR
2283}
2284
68dda785 2285wxValidator *wxWindow::GetValidator()
c801d85f 2286{
463c1fa1 2287 return m_windowValidator;
362c6693 2288}
c801d85f 2289
6de97a3b 2290void wxWindow::SetValidator( const wxValidator& validator )
c801d85f 2291{
1ecc4d80
RR
2292 if (m_windowValidator) delete m_windowValidator;
2293 m_windowValidator = validator.Clone();
2294 if (m_windowValidator) m_windowValidator->SetWindow(this);
362c6693 2295}
c801d85f 2296
fd0eed64
RR
2297void wxWindow::SetClientObject( wxClientData *data )
2298{
1ecc4d80
RR
2299 if (m_clientObject) delete m_clientObject;
2300 m_clientObject = data;
fd0eed64
RR
2301}
2302
2303wxClientData *wxWindow::GetClientObject()
2304{
1ecc4d80 2305 return m_clientObject;
fd0eed64
RR
2306}
2307
2308void wxWindow::SetClientData( void *data )
2309{
1ecc4d80 2310 m_clientData = data;
fd0eed64
RR
2311}
2312
2313void *wxWindow::GetClientData()
2314{
1ecc4d80 2315 return m_clientData;
fd0eed64
RR
2316}
2317
68dda785 2318bool wxWindow::IsBeingDeleted()
c801d85f 2319{
1ecc4d80 2320 return FALSE;
362c6693 2321}
c801d85f
KB
2322
2323void wxWindow::SetId( wxWindowID id )
2324{
1ecc4d80 2325 m_windowId = id;
362c6693 2326}
c801d85f 2327
8bbe427f 2328wxWindowID wxWindow::GetId() const
c801d85f 2329{
1ecc4d80 2330 return m_windowId;
362c6693 2331}
c801d85f
KB
2332
2333void wxWindow::SetCursor( const wxCursor &cursor )
2334{
1ecc4d80 2335 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2336
1ecc4d80
RR
2337 if (cursor.Ok())
2338 {
2339 if (cursor == *m_cursor) return;
2340 *m_cursor = cursor;
2341 }
2342 else
2343 {
2344 *m_cursor = *wxSTANDARD_CURSOR;
2345 }
a3622daa 2346
1ecc4d80
RR
2347 if ((m_widget) && (m_widget->window))
2348 gdk_window_set_cursor( m_widget->window, m_cursor->GetCursor() );
47d67540 2349
1ecc4d80
RR
2350 if ((m_wxwindow) && (m_wxwindow->window))
2351 gdk_window_set_cursor( m_wxwindow->window, m_cursor->GetCursor() );
362c6693 2352}
c801d85f 2353
4f22cf8d
RR
2354void wxWindow::WarpPointer( int WXUNUSED(x), int WXUNUSED(y) )
2355{
2356 // TODO
2357}
2358
debe6624 2359void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f 2360{
139adb6a 2361 wxCHECK_RET( (m_widget != NULL), "invalid window" );
47d67540 2362
139adb6a 2363 if (eraseBackground && m_wxwindow && m_wxwindow->window)
c801d85f 2364 {
139adb6a
RR
2365 if (rect)
2366 {
2367 gdk_window_clear_area( m_wxwindow->window,
2368 rect->x, rect->y,
2369 rect->width,
2370 rect->height );
2371 }
2372 else
2373 {
1ecc4d80 2374 Clear();
139adb6a
RR
2375 }
2376 }
2377
2378 if (!rect)
2379 {
2380 if (m_wxwindow)
2381 gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
2382 else
2383 gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
362c6693 2384 }
c801d85f 2385 else
139adb6a
RR
2386 {
2387 GdkRectangle gdk_rect;
2388 gdk_rect.x = rect->x;
2389 gdk_rect.y = rect->y;
2390 gdk_rect.width = rect->width;
2391 gdk_rect.height = rect->height;
2392
2393 if (m_wxwindow)
2394 gtk_widget_draw( m_wxwindow, &gdk_rect );
2395 else
2396 gtk_widget_draw( m_widget, &gdk_rect );
2397 }
362c6693 2398}
c801d85f 2399
8429bec1
RR
2400wxRegion wxWindow::GetUpdateRegion() const
2401{
2402 return m_updateRegion;
2403}
2404
2405bool wxWindow::IsExposed( int x, int y) const
c801d85f 2406{
1ecc4d80 2407 return (m_updateRegion.Contains( x, y ) != wxOutRegion );
362c6693 2408}
c801d85f 2409
8429bec1
RR
2410bool wxWindow::IsExposed( int x, int y, int w, int h ) const
2411{
1ecc4d80 2412 return (m_updateRegion.Contains( x, y, w, h ) != wxOutRegion );
8429bec1
RR
2413}
2414
2415bool wxWindow::IsExposed( const wxPoint& pt ) const
2416{
1ecc4d80 2417 return (m_updateRegion.Contains( pt.x, pt.y ) != wxOutRegion );
8429bec1
RR
2418}
2419
2420bool wxWindow::IsExposed( const wxRect& rect ) const
c801d85f 2421{
1ecc4d80 2422 return (m_updateRegion.Contains( rect.x, rect.y, rect.width, rect.height ) != wxOutRegion );
362c6693 2423}
c801d85f 2424
68dda785 2425void wxWindow::Clear()
c801d85f 2426{
3bc755fc 2427 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2428
3bc755fc 2429 if (m_wxwindow && m_wxwindow->window) gdk_window_clear( m_wxwindow->window );
362c6693 2430}
c801d85f 2431
68dda785 2432wxColour wxWindow::GetBackgroundColour() const
c801d85f 2433{
3bc755fc 2434 return m_backgroundColour;
362c6693 2435}
c801d85f
KB
2436
2437void wxWindow::SetBackgroundColour( const wxColour &colour )
2438{
3bc755fc 2439 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2440
3bc755fc 2441 if (m_backgroundColour == colour) return;
8bbe427f 2442
3bc755fc
RR
2443 m_backgroundColour = colour;
2444 if (!m_backgroundColour.Ok()) return;
8bbe427f 2445
3bc755fc
RR
2446 if (m_wxwindow)
2447 {
2448 GdkWindow *window = m_wxwindow->window;
2449 m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) );
2450 gdk_window_set_background( window, m_backgroundColour.GetColor() );
2451 gdk_window_clear( window );
2452 }
8bbe427f 2453
ae0bdb01
RR
2454 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
2455 if (sysbg.Red() == colour.Red() &&
2456 sysbg.Green() == colour.Green() &&
2457 sysbg.Blue() == colour.Blue())
2458 {
2459 m_backgroundColour = wxNullColour;
2460 ApplyWidgetStyle();
2461 m_backgroundColour = sysbg;
2462 }
2463 else
2464 {
2465 ApplyWidgetStyle();
2466 }
362c6693 2467}
c801d85f 2468
68dda785 2469wxColour wxWindow::GetForegroundColour() const
6de97a3b 2470{
3bc755fc 2471 return m_foregroundColour;
6de97a3b
RR
2472}
2473
2474void wxWindow::SetForegroundColour( const wxColour &colour )
2475{
3bc755fc 2476 wxCHECK_RET( m_widget != NULL, "invalid window" );
a81258be 2477
3bc755fc 2478 if (m_foregroundColour == colour) return;
8bbe427f 2479
3bc755fc
RR
2480 m_foregroundColour = colour;
2481 if (!m_foregroundColour.Ok()) return;
8bbe427f 2482
ae0bdb01
RR
2483 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
2484 if (sysbg.Red() == colour.Red() &&
2485 sysbg.Green() == colour.Green() &&
2486 sysbg.Blue() == colour.Blue())
2487 {
2488 m_backgroundColour = wxNullColour;
2489 ApplyWidgetStyle();
2490 m_backgroundColour = sysbg;
2491 }
2492 else
2493 {
2494 ApplyWidgetStyle();
2495 }
58614078
RR
2496}
2497
2498GtkStyle *wxWindow::GetWidgetStyle()
2499{
1ecc4d80 2500 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 2501
1ecc4d80
RR
2502 m_widgetStyle =
2503 gtk_style_copy(
2504 gtk_widget_get_style( m_widget ) );
8bbe427f 2505
1ecc4d80 2506 return m_widgetStyle;
58614078
RR
2507}
2508
2509void wxWindow::SetWidgetStyle()
2510{
1ecc4d80
RR
2511 GtkStyle *style = GetWidgetStyle();
2512
2513 gdk_font_unref( style->font );
2514 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
2515
2516 if (m_foregroundColour.Ok())
2517 {
2518 m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2519 style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
2520 style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
2521 style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
2522 }
2523
2524 if (m_backgroundColour.Ok())
2525 {
2526 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2527 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2528 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2529 style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2530 style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2531 style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2532 style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2533 style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2534 style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2535 }
a81258be
RR
2536}
2537
58614078 2538void wxWindow::ApplyWidgetStyle()
a81258be 2539{
6de97a3b
RR
2540}
2541
68dda785 2542bool wxWindow::Validate()
c801d85f 2543{
1ecc4d80 2544 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2545
1ecc4d80
RR
2546 wxNode *node = m_children.First();
2547 while (node)
2548 {
2549 wxWindow *child = (wxWindow *)node->Data();
2550 if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this))
2551 {
2552 return FALSE;
2553 }
2554 node = node->Next();
2555 }
2556 return TRUE;
362c6693 2557}
c801d85f 2558
68dda785 2559bool wxWindow::TransferDataToWindow()
c801d85f 2560{
1ecc4d80 2561 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2562
1ecc4d80
RR
2563 wxNode *node = m_children.First();
2564 while (node)
c801d85f 2565 {
1ecc4d80
RR
2566 wxWindow *child = (wxWindow *)node->Data();
2567 if (child->GetValidator() && /* child->GetValidator()->Ok() && */
2568 !child->GetValidator()->TransferToWindow() )
2569 {
2570 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK|wxICON_EXCLAMATION );
2571 return FALSE;
2572 }
2573 node = node->Next();
362c6693 2574 }
1ecc4d80 2575 return TRUE;
362c6693 2576}
c801d85f 2577
68dda785 2578bool wxWindow::TransferDataFromWindow()
c801d85f 2579{
1ecc4d80 2580 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2581
1ecc4d80
RR
2582 wxNode *node = m_children.First();
2583 while (node)
2584 {
2585 wxWindow *child = (wxWindow *)node->Data();
2586 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
2587 {
2588 return FALSE;
2589 }
2590 node = node->Next();
2591 }
2592 return TRUE;
362c6693 2593}
c801d85f 2594
bcf1fa6b
RR
2595void wxWindow::SetAcceleratorTable( const wxAcceleratorTable& accel )
2596{
1ecc4d80 2597 m_acceleratorTable = accel;
bcf1fa6b
RR
2598}
2599
c801d85f
KB
2600void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
2601{
1ecc4d80 2602 TransferDataToWindow();
362c6693 2603}
c801d85f 2604
68dda785 2605void wxWindow::InitDialog()
c801d85f 2606{
1ecc4d80 2607 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2608
1ecc4d80
RR
2609 wxInitDialogEvent event(GetId());
2610 event.SetEventObject( this );
2611 GetEventHandler()->ProcessEvent(event);
362c6693 2612}
c801d85f 2613
30dea054
RR
2614static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
2615{
1ecc4d80
RR
2616 menu->SetInvokingWindow( win );
2617 wxNode *node = menu->m_items.First();
2618 while (node)
2619 {
2620 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
2621 if (menuitem->IsSubMenu())
2622 {
2623 SetInvokingWindow( menuitem->GetSubMenu(), win );
2624 }
2625 node = node->Next();
2626 }
362c6693 2627}
30dea054
RR
2628
2629bool wxWindow::PopupMenu( wxMenu *menu, int WXUNUSED(x), int WXUNUSED(y) )
2630{
1ecc4d80 2631 wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" );
47d67540 2632
1ecc4d80 2633 wxCHECK_MSG( menu != NULL, FALSE, "invalid popup-menu" );
8bbe427f 2634
1ecc4d80
RR
2635 SetInvokingWindow( menu, this );
2636 gtk_menu_popup(
47d67540
VZ
2637 GTK_MENU(menu->m_menu),
2638 (GtkWidget *)NULL, // parent menu shell
2639 (GtkWidget *)NULL, // parent menu item
2640 (GtkMenuPositionFunc)NULL,
2641 NULL, // client data
2642 0, // button used to activate it
2643 0//gs_timeLastClick // the time of activation
2644 );
1ecc4d80 2645 return TRUE;
30dea054
RR
2646}
2647
06cfab17 2648#if wxUSE_DRAG_AND_DROP
ac57418f 2649
c801d85f
KB
2650void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
2651{
1ecc4d80 2652 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2653
1ecc4d80 2654 GtkWidget *dnd_widget = GetConnectWidget();
47d67540 2655
1ecc4d80 2656 if (m_dropTarget) m_dropTarget->UnregisterWidget( dnd_widget );
47d67540 2657
1ecc4d80
RR
2658 if (m_dropTarget) delete m_dropTarget;
2659 m_dropTarget = dropTarget;
47d67540 2660
1ecc4d80 2661 if (m_dropTarget) m_dropTarget->RegisterWidget( dnd_widget );
362c6693 2662}
c801d85f
KB
2663
2664wxDropTarget *wxWindow::GetDropTarget() const
2665{
1ecc4d80 2666 return m_dropTarget;
362c6693 2667}
c801d85f 2668
ac57418f
RR
2669#endif
2670
68dda785 2671GtkWidget* wxWindow::GetConnectWidget()
e3e65dac 2672{
1ecc4d80
RR
2673 GtkWidget *connect_widget = m_widget;
2674 if (m_wxwindow) connect_widget = m_wxwindow;
47d67540 2675
1ecc4d80 2676 return connect_widget;
e3e65dac 2677}
47d67540 2678
903f689b
RR
2679bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
2680{
1ecc4d80
RR
2681 if (m_wxwindow) return (window == m_wxwindow->window);
2682 return (window == m_widget->window);
903f689b
RR
2683}
2684
c801d85f
KB
2685void wxWindow::SetFont( const wxFont &font )
2686{
1ecc4d80 2687 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2688
1ecc4d80
RR
2689 if (((wxFont*)&font)->Ok())
2690 m_font = font;
2691 else
2692 m_font = *wxSWISS_FONT;
c801d85f 2693
ae0bdb01
RR
2694 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
2695 if (sysbg.Red() == m_backgroundColour.Red() &&
2696 sysbg.Green() == m_backgroundColour.Green() &&
2697 sysbg.Blue() == m_backgroundColour.Blue())
2698 {
2699 m_backgroundColour = wxNullColour;
2700 ApplyWidgetStyle();
2701 m_backgroundColour = sysbg;
2702 }
2703 else
2704 {
2705 ApplyWidgetStyle();
2706 }
362c6693 2707}
c801d85f
KB
2708
2709void wxWindow::SetWindowStyleFlag( long flag )
2710{
1ecc4d80 2711 m_windowStyle = flag;
362c6693 2712}
c801d85f 2713
68dda785 2714long wxWindow::GetWindowStyleFlag() const
c801d85f 2715{
1ecc4d80 2716 return m_windowStyle;
362c6693 2717}
c801d85f 2718
68dda785 2719void wxWindow::CaptureMouse()
c801d85f 2720{
1ecc4d80 2721 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2722
1ecc4d80 2723 wxCHECK_RET( g_capturing == FALSE, "CaptureMouse called twice" );
47d67540 2724
1ecc4d80
RR
2725 GtkWidget *connect_widget = GetConnectWidget();
2726 gtk_grab_add( connect_widget );
2727 gdk_pointer_grab( connect_widget->window, FALSE,
2728 (GdkEventMask)
2729 (GDK_BUTTON_PRESS_MASK |
2730 GDK_BUTTON_RELEASE_MASK |
2731 GDK_POINTER_MOTION_MASK),
2732 (GdkWindow *) NULL,
2733 (GdkCursor *) NULL,
2734 GDK_CURRENT_TIME );
2735 g_capturing = TRUE;
362c6693 2736}
c801d85f 2737
68dda785 2738void wxWindow::ReleaseMouse()
c801d85f 2739{
1ecc4d80 2740 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2741
1ecc4d80 2742 wxCHECK_RET( g_capturing == TRUE, "ReleaseMouse called twice" );
47d67540 2743
1ecc4d80
RR
2744 GtkWidget *connect_widget = GetConnectWidget();
2745 gtk_grab_remove( connect_widget );
2746 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
2747 g_capturing = FALSE;
362c6693 2748}
c801d85f
KB
2749
2750void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
2751{
362c6693 2752}
c801d85f 2753
68dda785 2754wxString wxWindow::GetTitle() const
c801d85f 2755{
1ecc4d80 2756 return (wxString&)m_windowName;
362c6693 2757}
c801d85f 2758
68dda785 2759wxString wxWindow::GetLabel() const
c801d85f 2760{
1ecc4d80 2761 return GetTitle();
362c6693 2762}
c801d85f
KB
2763
2764void wxWindow::SetName( const wxString &name )
2765{
1ecc4d80 2766 m_windowName = name;
362c6693 2767}
c801d85f 2768
68dda785 2769wxString wxWindow::GetName() const
c801d85f 2770{
1ecc4d80 2771 return (wxString&)m_windowName;
362c6693 2772}
c801d85f 2773
68dda785 2774bool wxWindow::IsShown() const
c801d85f 2775{
1ecc4d80 2776 return m_isShown;
362c6693 2777}
c801d85f 2778
68dda785 2779bool wxWindow::IsRetained()
c801d85f 2780{
1ecc4d80 2781 return FALSE;
362c6693 2782}
c801d85f 2783
debe6624 2784wxWindow *wxWindow::FindWindow( long id )
c801d85f 2785{
1ecc4d80
RR
2786 if (id == m_windowId) return this;
2787 wxNode *node = m_children.First();
2788 while (node)
2789 {
2790 wxWindow *child = (wxWindow*)node->Data();
2791 wxWindow *res = child->FindWindow( id );
2792 if (res) return res;
2793 node = node->Next();
2794 }
2795 return (wxWindow *) NULL;
362c6693 2796}
c801d85f
KB
2797
2798wxWindow *wxWindow::FindWindow( const wxString& name )
2799{
1ecc4d80
RR
2800 if (name == m_windowName) return this;
2801 wxNode *node = m_children.First();
2802 while (node)
2803 {
2804 wxWindow *child = (wxWindow*)node->Data();
2805 wxWindow *res = child->FindWindow( name );
2806 if (res) return res;
2807 node = node->Next();
2808 }
2809 return (wxWindow *) NULL;
362c6693 2810}
c801d85f 2811
debe6624 2812void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
cb43b372 2813 int range, bool refresh )
c801d85f 2814{
1ecc4d80 2815 wxCHECK_RET( m_widget != NULL, "invalid window" );
8bbe427f 2816
1ecc4d80 2817 wxCHECK_RET( m_wxwindow != NULL, "window needs client area for scrolling" );
c801d85f 2818
1ecc4d80 2819 m_hasScrolling = TRUE;
47d67540 2820
1ecc4d80 2821 if (orient == wxHORIZONTAL)
cb43b372 2822 {
1ecc4d80
RR
2823 float fpos = (float)pos;
2824 float frange = (float)range;
2825 float fthumb = (float)thumbVisible;
2826 if (fpos > frange-fthumb) fpos = frange-fthumb;
2827 if (fpos < 0.0) fpos = 0.0;
2828
2829 if ((fabs(frange-m_hAdjust->upper) < 0.2) &&
2830 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
2831 {
2832 SetScrollPos( orient, pos, refresh );
2833 return;
2834 }
47d67540 2835
1ecc4d80 2836 m_oldHorizontalPos = fpos;
47d67540 2837
1ecc4d80
RR
2838 m_hAdjust->lower = 0.0;
2839 m_hAdjust->upper = frange;
2840 m_hAdjust->value = fpos;
2841 m_hAdjust->step_increment = 1.0;
2842 m_hAdjust->page_increment = (float)(wxMax(fthumb,0));
2843 m_hAdjust->page_size = fthumb;
cb43b372 2844 }
1ecc4d80
RR
2845 else
2846 {
2847 float fpos = (float)pos;
2848 float frange = (float)range;
2849 float fthumb = (float)thumbVisible;
2850 if (fpos > frange-fthumb) fpos = frange-fthumb;
2851 if (fpos < 0.0) fpos = 0.0;
2852
2853 if ((fabs(frange-m_vAdjust->upper) < 0.2) &&
2854 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
2855 {
2856 SetScrollPos( orient, pos, refresh );
2857 return;
2858 }
47d67540 2859
1ecc4d80 2860 m_oldVerticalPos = fpos;
47d67540 2861
1ecc4d80
RR
2862 m_vAdjust->lower = 0.0;
2863 m_vAdjust->upper = frange;
2864 m_vAdjust->value = fpos;
2865 m_vAdjust->step_increment = 1.0;
2866 m_vAdjust->page_increment = (float)(wxMax(fthumb,0));
2867 m_vAdjust->page_size = fthumb;
2868 }
47d67540 2869
1ecc4d80
RR
2870 if (m_wxwindow->window)
2871 {
2872 if (orient == wxHORIZONTAL)
2873 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
2874 else
2875 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
47d67540 2876
1ecc4d80
RR
2877 gtk_widget_set_usize( m_widget, m_width, m_height );
2878 }
362c6693 2879}
c801d85f 2880
debe6624 2881void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f 2882{
1ecc4d80
RR
2883 wxCHECK_RET( m_widget != NULL, "invalid window" );
2884
2885 wxCHECK_RET( m_wxwindow != NULL, "window needs client area for scrolling" );
2886
2887 if (orient == wxHORIZONTAL)
2888 {
2889 float fpos = (float)pos;
2890 if (fpos > m_hAdjust->upper - m_hAdjust->page_size) fpos = m_hAdjust->upper - m_hAdjust->page_size;
2891 if (fpos < 0.0) fpos = 0.0;
2892 m_oldHorizontalPos = fpos;
2893
2894 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
2895 m_hAdjust->value = fpos;
2896 }
2897 else
2898 {
2899 float fpos = (float)pos;
2900 if (fpos > m_vAdjust->upper - m_vAdjust->page_size) fpos = m_vAdjust->upper - m_vAdjust->page_size;
2901 if (fpos < 0.0) fpos = 0.0;
2902 m_oldVerticalPos = fpos;
92976ab6 2903
1ecc4d80
RR
2904 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
2905 m_vAdjust->value = fpos;
2906 }
47d67540 2907
1ecc4d80 2908 if (!m_isScrolling)
47d67540 2909 {
1ecc4d80
RR
2910 if (m_wxwindow->window)
2911 {
2912 if (orient == wxHORIZONTAL)
2913 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
2914 else
2915 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
2916 }
cb43b372 2917 }
362c6693 2918}
c801d85f 2919
debe6624 2920int wxWindow::GetScrollThumb( int orient ) const
c801d85f 2921{
1ecc4d80 2922 wxCHECK_MSG( m_widget != NULL, 0, "invalid window" );
47d67540 2923
1ecc4d80 2924 wxCHECK_MSG( m_wxwindow != NULL, 0, "window needs client area for scrolling" );
47d67540 2925
1ecc4d80
RR
2926 if (orient == wxHORIZONTAL)
2927 return (int)(m_hAdjust->page_size+0.5);
2928 else
2929 return (int)(m_vAdjust->page_size+0.5);
362c6693 2930}
c801d85f 2931
debe6624 2932int wxWindow::GetScrollPos( int orient ) const
c801d85f 2933{
1ecc4d80 2934 wxCHECK_MSG( m_widget != NULL, 0, "invalid window" );
47d67540 2935
1ecc4d80 2936 wxCHECK_MSG( m_wxwindow != NULL, 0, "window needs client area for scrolling" );
c801d85f 2937
1ecc4d80
RR
2938 if (orient == wxHORIZONTAL)
2939 return (int)(m_hAdjust->value+0.5);
2940 else
2941 return (int)(m_vAdjust->value+0.5);
362c6693 2942}
c801d85f 2943
debe6624 2944int wxWindow::GetScrollRange( int orient ) const
c801d85f 2945{
1ecc4d80 2946 wxCHECK_MSG( m_widget != NULL, 0, "invalid window" );
47d67540 2947
1ecc4d80 2948 wxCHECK_MSG( m_wxwindow != NULL, 0, "window needs client area for scrolling" );
c801d85f 2949
1ecc4d80
RR
2950 if (orient == wxHORIZONTAL)
2951 return (int)(m_hAdjust->upper+0.5);
2952 else
2953 return (int)(m_vAdjust->upper+0.5);
362c6693 2954}
c801d85f 2955
debe6624 2956void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f 2957{
1ecc4d80 2958 wxCHECK_RET( m_widget != NULL, "invalid window" );
47d67540 2959
1ecc4d80 2960 wxCHECK_RET( m_wxwindow != NULL, "window needs client area for scrolling" );
c801d85f
KB
2961
2962 int cw = 0;
2963 int ch = 0;
2964 GetClientSize( &cw, &ch );
47d67540 2965
c801d85f
KB
2966 int w = cw - abs(dx);
2967 int h = ch - abs(dy);
2968 if ((h < 0) || (w < 0))
2969 {
1ecc4d80
RR
2970 Refresh();
2971 return;
362c6693 2972 }
c801d85f
KB
2973 int s_x = 0;
2974 int s_y = 0;
2975 if (dx < 0) s_x = -dx;
2976 if (dy < 0) s_y = -dy;
2977 int d_x = 0;
2978 int d_y = 0;
2979 if (dx > 0) d_x = dx;
2980 if (dy > 0) d_y = dy;
8bbe427f 2981
32e9da8b
RR
2982 if (!m_scrollGC)
2983 {
1ecc4d80
RR
2984 m_scrollGC = gdk_gc_new( m_wxwindow->window );
2985 gdk_gc_set_exposures( m_scrollGC, TRUE );
32e9da8b 2986 }
8bbe427f 2987
32e9da8b 2988 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
1ecc4d80 2989 m_wxwindow->window, s_x, s_y, w, h );
47d67540 2990
c801d85f
KB
2991 wxRect rect;
2992 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
2993 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
2994 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
2995 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
47d67540 2996
c801d85f 2997 Refresh( TRUE, &rect );
362c6693 2998}
c801d85f
KB
2999
3000//-------------------------------------------------------------------------------------
3001// Layout
3002//-------------------------------------------------------------------------------------
3003
68dda785 3004wxLayoutConstraints *wxWindow::GetConstraints() const
c801d85f
KB
3005{
3006 return m_constraints;
362c6693 3007}
c801d85f
KB
3008
3009void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
3010{
3011 if (m_constraints)
3012 {
3013 UnsetConstraints(m_constraints);
3014 delete m_constraints;
3015 }
3016 m_constraints = constraints;
3017 if (m_constraints)
3018 {
3019 // Make sure other windows know they're part of a 'meaningful relationship'
3020 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
3021 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3022 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
3023 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3024 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
3025 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3026 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
3027 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3028 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
3029 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3030 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
3031 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3032 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
3033 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3034 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
3035 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3036 }
3037;
3038}
3039;
3040
debe6624 3041void wxWindow::SetAutoLayout( bool autoLayout )
c801d85f
KB
3042{
3043 m_autoLayout = autoLayout;
362c6693 3044}
c801d85f 3045
68dda785 3046bool wxWindow::GetAutoLayout() const
c801d85f
KB
3047{
3048 return m_autoLayout;
362c6693 3049}
c801d85f 3050
68dda785 3051wxSizer *wxWindow::GetSizer() const
c801d85f
KB
3052{
3053 return m_windowSizer;
362c6693 3054}
c801d85f
KB
3055
3056void wxWindow::SetSizerParent( wxWindow *win )
3057{
3058 m_sizerParent = win;
362c6693 3059}
c801d85f 3060
68dda785 3061wxWindow *wxWindow::GetSizerParent() const
c801d85f
KB
3062{
3063 return m_sizerParent;
362c6693 3064}
c801d85f
KB
3065
3066// This removes any dangling pointers to this window
3067// in other windows' constraintsInvolvedIn lists.
3068void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
3069{
3070 if (c)
3071 {
3072 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3073 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3074 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3075 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3076 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
3077 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3078 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
3079 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3080 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
3081 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3082 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
3083 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3084 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
3085 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3086 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
3087 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3088 }
3089}
3090
3091// Back-pointer to other windows we're involved with, so if we delete
3092// this window, we must delete any constraints we're involved with.
3093void wxWindow::AddConstraintReference(wxWindow *otherWin)
3094{
3095 if (!m_constraintsInvolvedIn)
3096 m_constraintsInvolvedIn = new wxList;
3097 if (!m_constraintsInvolvedIn->Member(otherWin))
3098 m_constraintsInvolvedIn->Append(otherWin);
3099}
3100
3101// REMOVE back-pointer to other windows we're involved with.
3102void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
3103{
3104 if (m_constraintsInvolvedIn)
3105 m_constraintsInvolvedIn->DeleteObject(otherWin);
3106}
3107
3108// Reset any constraints that mention this window
68dda785 3109void wxWindow::DeleteRelatedConstraints()
c801d85f
KB
3110{
3111 if (m_constraintsInvolvedIn)
3112 {
3113 wxNode *node = m_constraintsInvolvedIn->First();
3114 while (node)
3115 {
3116 wxWindow *win = (wxWindow *)node->Data();
3117 wxNode *next = node->Next();
3118 wxLayoutConstraints *constr = win->GetConstraints();
3119
3120 // Reset any constraints involving this window
3121 if (constr)
3122 {
3123 constr->left.ResetIfWin((wxWindow *)this);
3124 constr->top.ResetIfWin((wxWindow *)this);
3125 constr->right.ResetIfWin((wxWindow *)this);
3126 constr->bottom.ResetIfWin((wxWindow *)this);
3127 constr->width.ResetIfWin((wxWindow *)this);
3128 constr->height.ResetIfWin((wxWindow *)this);
3129 constr->centreX.ResetIfWin((wxWindow *)this);
3130 constr->centreY.ResetIfWin((wxWindow *)this);
3131 }
3132 delete node;
3133 node = next;
3134 }
3135 delete m_constraintsInvolvedIn;
c67daf87 3136 m_constraintsInvolvedIn = (wxList *) NULL;
c801d85f
KB
3137 }
3138}
3139
3140void wxWindow::SetSizer(wxSizer *sizer)
3141{
3142 m_windowSizer = sizer;
3143 if (sizer)
3144 sizer->SetSizerParent((wxWindow *)this);
3145}
3146
3147/*
3148 * New version
3149 */
3150
68dda785 3151bool wxWindow::Layout()
c801d85f
KB
3152{
3153 if (GetConstraints())
3154 {
3155 int w, h;
3156 GetClientSize(&w, &h);
3157 GetConstraints()->width.SetValue(w);
3158 GetConstraints()->height.SetValue(h);
3159 }
47d67540 3160
c801d85f
KB
3161 // If top level (one sizer), evaluate the sizer's constraints.
3162 if (GetSizer())
3163 {
3164 int noChanges;
3165 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3166 GetSizer()->LayoutPhase1(&noChanges);
3167 GetSizer()->LayoutPhase2(&noChanges);
3168 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3169 return TRUE;
3170 }
3171 else
3172 {
3173 // Otherwise, evaluate child constraints
3174 ResetConstraints(); // Mark all constraints as unevaluated
3175 DoPhase(1); // Just one phase need if no sizers involved
3176 DoPhase(2);
3177 SetConstraintSizes(); // Recursively set the real window sizes
3178 }
3179 return TRUE;
3180}
3181
3182
3183// Do a phase of evaluating constraints:
3184// the default behaviour. wxSizers may do a similar
3185// thing, but also impose their own 'constraints'
3186// and order the evaluation differently.
3187bool wxWindow::LayoutPhase1(int *noChanges)
3188{
3189 wxLayoutConstraints *constr = GetConstraints();
3190 if (constr)
3191 {
3192 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
3193 }
3194 else
3195 return TRUE;
3196}
3197
3198bool wxWindow::LayoutPhase2(int *noChanges)
3199{
3200 *noChanges = 0;
47d67540 3201
c801d85f
KB
3202 // Layout children
3203 DoPhase(1);
3204 DoPhase(2);
3205 return TRUE;
3206}
3207
3208// Do a phase of evaluating child constraints
debe6624 3209bool wxWindow::DoPhase(int phase)
c801d85f
KB
3210{
3211 int noIterations = 0;
3212 int maxIterations = 500;
3213 int noChanges = 1;
3214 int noFailures = 0;
3215 wxList succeeded;
3216 while ((noChanges > 0) && (noIterations < maxIterations))
3217 {
3218 noChanges = 0;
3219 noFailures = 0;
8bbe427f 3220 wxNode *node = m_children.First();
c801d85f
KB
3221 while (node)
3222 {
3223 wxWindow *child = (wxWindow *)node->Data();
3224 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
3225 {
3226 wxLayoutConstraints *constr = child->GetConstraints();
3227 if (constr)
3228 {
3229 if (succeeded.Member(child))
3230 {
3231 }
3232 else
3233 {
3234 int tempNoChanges = 0;
3235 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
3236 noChanges += tempNoChanges;
3237 if (success)
3238 {
3239 succeeded.Append(child);
3240 }
3241 }
3242 }
3243 }
3244 node = node->Next();
3245 }
3246 noIterations ++;
3247 }
3248 return TRUE;
3249}
3250
68dda785 3251void wxWindow::ResetConstraints()
c801d85f
KB
3252{
3253 wxLayoutConstraints *constr = GetConstraints();
3254 if (constr)
3255 {
3256 constr->left.SetDone(FALSE);
3257 constr->top.SetDone(FALSE);
3258 constr->right.SetDone(FALSE);
3259 constr->bottom.SetDone(FALSE);
3260 constr->width.SetDone(FALSE);
3261 constr->height.SetDone(FALSE);
3262 constr->centreX.SetDone(FALSE);
3263 constr->centreY.SetDone(FALSE);
3264 }
db1b4961 3265 wxNode *node = m_children.First();
c801d85f
KB
3266 while (node)
3267 {
3268 wxWindow *win = (wxWindow *)node->Data();
3269 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
3270 win->ResetConstraints();
3271 node = node->Next();
3272 }
3273}
3274
3275// Need to distinguish between setting the 'fake' size for
3276// windows and sizers, and setting the real values.
debe6624 3277void wxWindow::SetConstraintSizes(bool recurse)
c801d85f
KB
3278{
3279 wxLayoutConstraints *constr = GetConstraints();
3280 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
3281 constr->width.GetDone() && constr->height.GetDone())
3282 {
3283 int x = constr->left.GetValue();
3284 int y = constr->top.GetValue();
3285 int w = constr->width.GetValue();
3286 int h = constr->height.GetValue();
3287
3288 // If we don't want to resize this window, just move it...
3289 if ((constr->width.GetRelationship() != wxAsIs) ||
3290 (constr->height.GetRelationship() != wxAsIs))
3291 {
3292 // Calls Layout() recursively. AAAGH. How can we stop that.
3293 // Simply take Layout() out of non-top level OnSizes.
3294 SizerSetSize(x, y, w, h);
3295 }
3296 else
3297 {
3298 SizerMove(x, y);
3299 }
3300 }
3301 else if (constr)
3302 {
3303 char *windowClass = this->GetClassInfo()->GetClassName();
3304
3305 wxString winName;
5e0aa05a 3306 if (GetName() == "")
3069ac4e 3307 winName = "unnamed";
5e0aa05a
VZ
3308 else
3309 winName = GetName();
3069ac4e
RR
3310 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3311 (const char *)windowClass,
3312 (const char *)winName);
3313 if (!constr->left.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3314 if (!constr->right.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3315 if (!constr->width.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3316 if (!constr->height.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3317 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
c801d85f
KB
3318 }
3319
3320 if (recurse)
3321 {
db1b4961 3322 wxNode *node = m_children.First();
c801d85f
KB
3323 while (node)
3324 {
3325 wxWindow *win = (wxWindow *)node->Data();
3326 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
3327 win->SetConstraintSizes();
3328 node = node->Next();
3329 }
3330 }
3331}
3332
3333// This assumes that all sizers are 'on' the same
3334// window, i.e. the parent of this window.
3335void wxWindow::TransformSizerToActual(int *x, int *y) const
3336{
3337 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
5e0aa05a 3338 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
c801d85f 3339 return;
47d67540 3340
c801d85f
KB
3341 int xp, yp;
3342 m_sizerParent->GetPosition(&xp, &yp);
3343 m_sizerParent->TransformSizerToActual(&xp, &yp);
3344 *x += xp;
3345 *y += yp;
3346}
3347
debe6624 3348void wxWindow::SizerSetSize(int x, int y, int w, int h)
c801d85f 3349{
5e0aa05a
VZ
3350 int xx = x;
3351 int yy = y;
c801d85f
KB
3352 TransformSizerToActual(&xx, &yy);
3353 SetSize(xx, yy, w, h);
3354}
3355
debe6624 3356void wxWindow::SizerMove(int x, int y)
c801d85f 3357{
5e0aa05a
VZ
3358 int xx = x;
3359 int yy = y;
c801d85f
KB
3360 TransformSizerToActual(&xx, &yy);
3361 Move(xx, yy);
3362}
3363
3364// Only set the size/position of the constraint (if any)
debe6624 3365void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
c801d85f
KB
3366{
3367 wxLayoutConstraints *constr = GetConstraints();
3368 if (constr)
3369 {
3370 if (x != -1)
3371 {
3372 constr->left.SetValue(x);
3373 constr->left.SetDone(TRUE);
3374 }
3375 if (y != -1)
3376 {
3377 constr->top.SetValue(y);
3378 constr->top.SetDone(TRUE);
3379 }
3380 if (w != -1)
3381 {
3382 constr->width.SetValue(w);
3383 constr->width.SetDone(TRUE);
3384 }
3385 if (h != -1)
3386 {
3387 constr->height.SetValue(h);
3388 constr->height.SetDone(TRUE);
3389 }
3390 }
3391}
3392
debe6624 3393void wxWindow::MoveConstraint(int x, int y)
c801d85f
KB
3394{
3395 wxLayoutConstraints *constr = GetConstraints();
3396 if (constr)
3397 {
3398 if (x != -1)
3399 {
3400 constr->left.SetValue(x);
3401 constr->left.SetDone(TRUE);
3402 }
3403 if (y != -1)
3404 {
3405 constr->top.SetValue(y);
3406 constr->top.SetDone(TRUE);
3407 }
3408 }
3409}
3410
3411void wxWindow::GetSizeConstraint(int *w, int *h) const
3412{
3413 wxLayoutConstraints *constr = GetConstraints();
3414 if (constr)
3415 {
3416 *w = constr->width.GetValue();
3417 *h = constr->height.GetValue();
3418 }
3419 else
3420 GetSize(w, h);
3421}
3422
3423void wxWindow::GetClientSizeConstraint(int *w, int *h) const
3424{
3425 wxLayoutConstraints *constr = GetConstraints();
3426 if (constr)
3427 {
3428 *w = constr->width.GetValue();
3429 *h = constr->height.GetValue();
3430 }
3431 else
3432 GetClientSize(w, h);
3433}
3434
3435void wxWindow::GetPositionConstraint(int *x, int *y) const
3436{
b292e2f5
RR
3437 wxLayoutConstraints *constr = GetConstraints();
3438 if (constr)
c801d85f
KB
3439 {
3440 *x = constr->left.GetValue();
3441 *y = constr->top.GetValue();
3442 }
3443 else
3444 GetPosition(x, y);
3445}
3446
e3e65dac 3447void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) )
5e0aa05a 3448{
b292e2f5 3449 UpdateWindowUI();
5e0aa05a 3450}