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