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