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