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