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