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