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