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