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