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