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