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