]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/window.cpp
863f51e463f4cc55d0606a76dbff64ea4f6f2f15
[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 DisconnectDnDWidget( dnd_widget );
1889
1890 if (m_pDropTarget) delete m_pDropTarget;
1891 m_pDropTarget = dropTarget;
1892
1893 ConnectDnDWidget( dnd_widget );
1894 }
1895
1896 wxDropTarget *wxWindow::GetDropTarget() const
1897 {
1898 return m_pDropTarget;
1899 }
1900
1901 void wxWindow::ConnectDnDWidget( GtkWidget *widget )
1902 {
1903 if (!m_pDropTarget) return;
1904
1905 m_pDropTarget->RegisterWidget( widget );
1906
1907 gtk_signal_connect( GTK_OBJECT(widget), "drop_data_available_event",
1908 GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
1909 }
1910
1911 void wxWindow::DisconnectDnDWidget( GtkWidget *widget )
1912 {
1913 if (!m_pDropTarget) return;
1914
1915 gtk_signal_disconnect_by_func( GTK_OBJECT(widget),
1916 GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
1917
1918 m_pDropTarget->UnregisterWidget( widget );
1919 }
1920
1921 GtkWidget* wxWindow::GetConnectWidget(void)
1922 {
1923 GtkWidget *connect_widget = m_widget;
1924 if (m_wxwindow) connect_widget = m_wxwindow;
1925
1926 return connect_widget;
1927 }
1928
1929 bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
1930 {
1931 if (m_wxwindow) return (window == m_wxwindow->window);
1932 return (window == m_widget->window);
1933 }
1934
1935 void wxWindow::SetFont( const wxFont &font )
1936 {
1937 if (((wxFont*)&font)->Ok())
1938 m_font = font;
1939 else
1940 m_font = *wxSWISS_FONT;
1941
1942 GtkStyle *style = (GtkStyle*) NULL;
1943 if (!m_hasOwnStyle)
1944 {
1945 m_hasOwnStyle = TRUE;
1946 style = gtk_style_copy( gtk_widget_get_style( m_widget ) );
1947 }
1948 else
1949 {
1950 style = gtk_widget_get_style( m_widget );
1951 }
1952
1953 gdk_font_unref( style->font );
1954 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
1955
1956 gtk_widget_set_style( m_widget, style );
1957 }
1958
1959 wxFont *wxWindow::GetFont(void)
1960 {
1961 return &m_font;
1962 }
1963
1964 void wxWindow::SetWindowStyleFlag( long flag )
1965 {
1966 m_windowStyle = flag;
1967 }
1968
1969 long wxWindow::GetWindowStyleFlag(void) const
1970 {
1971 return m_windowStyle;
1972 }
1973
1974 void wxWindow::CaptureMouse(void)
1975 {
1976 GtkWidget *connect_widget = GetConnectWidget();
1977 gtk_grab_add( connect_widget );
1978 gdk_pointer_grab ( connect_widget->window, FALSE,
1979 (GdkEventMask)
1980 (GDK_BUTTON_PRESS_MASK |
1981 GDK_BUTTON_RELEASE_MASK |
1982 GDK_POINTER_MOTION_MASK),
1983 (GdkWindow *) NULL, (GdkCursor *) NULL, GDK_CURRENT_TIME );
1984 }
1985
1986 void wxWindow::ReleaseMouse(void)
1987 {
1988 GtkWidget *connect_widget = GetConnectWidget();
1989 gtk_grab_remove( connect_widget );
1990 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
1991 }
1992
1993 void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
1994 {
1995 }
1996
1997 wxString wxWindow::GetTitle(void) const
1998 {
1999 return (wxString&)m_windowName;
2000 }
2001
2002 wxString wxWindow::GetLabel(void) const
2003 {
2004 return GetTitle();
2005 }
2006
2007 void wxWindow::SetName( const wxString &name )
2008 {
2009 m_windowName = name;
2010 }
2011
2012 wxString wxWindow::GetName(void) const
2013 {
2014 return (wxString&)m_windowName;
2015 }
2016
2017 bool wxWindow::IsShown(void) const
2018 {
2019 return m_isShown;
2020 }
2021
2022 bool wxWindow::IsRetained(void)
2023 {
2024 return FALSE;
2025 }
2026
2027 wxWindow *wxWindow::FindWindow( long id )
2028 {
2029 if (id == m_windowId) return this;
2030 wxNode *node = m_children.First();
2031 while (node)
2032 {
2033 wxWindow *child = (wxWindow*)node->Data();
2034 wxWindow *res = child->FindWindow( id );
2035 if (res) return res;
2036 node = node->Next();
2037 }
2038 return (wxWindow *) NULL;
2039 }
2040
2041 wxWindow *wxWindow::FindWindow( const wxString& name )
2042 {
2043 if (name == m_windowName) return this;
2044 wxNode *node = m_children.First();
2045 while (node)
2046 {
2047 wxWindow *child = (wxWindow*)node->Data();
2048 wxWindow *res = child->FindWindow( name );
2049 if (res) return res;
2050 node = node->Next();
2051 }
2052 return (wxWindow *) NULL;
2053 }
2054
2055 void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
2056 int range, bool WXUNUSED(refresh) )
2057 {
2058 if (!m_wxwindow) return;
2059
2060 if (orient == wxHORIZONTAL)
2061 {
2062 float fpos = (float)pos;
2063 m_oldHorizontalPos = fpos;
2064 float frange = (float)range;
2065 float fthumb = (float)thumbVisible;
2066
2067 if ((fabs(fpos-m_hAdjust->value) < 0.2) &&
2068 (fabs(frange-m_hAdjust->upper) < 0.2) &&
2069 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
2070 return;
2071
2072 m_hAdjust->lower = 0.0;
2073 m_hAdjust->upper = frange;
2074 m_hAdjust->value = fpos;
2075 m_hAdjust->step_increment = 1.0;
2076 m_hAdjust->page_increment = (float)(wxMax(fthumb-2,0));
2077 m_hAdjust->page_size = fthumb;
2078 }
2079 else
2080 {
2081 float fpos = (float)pos;
2082 m_oldVerticalPos = fpos;
2083 float frange = (float)range;
2084 float fthumb = (float)thumbVisible;
2085
2086 if ((fabs(fpos-m_vAdjust->value) < 0.2) &&
2087 (fabs(frange-m_vAdjust->upper) < 0.2) &&
2088 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
2089 return;
2090
2091 m_vAdjust->lower = 0.0;
2092 m_vAdjust->upper = frange;
2093 m_vAdjust->value = fpos;
2094 m_vAdjust->step_increment = 1.0;
2095 m_vAdjust->page_increment = (float)(wxMax(fthumb-2,0));
2096 m_vAdjust->page_size = fthumb;
2097 }
2098
2099 if (m_wxwindow->window)
2100 {
2101 if (orient == wxHORIZONTAL)
2102 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
2103 else
2104 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
2105
2106 gtk_widget_set_usize( m_widget, m_width, m_height );
2107 }
2108 }
2109
2110 void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
2111 {
2112 if (!m_wxwindow) return;
2113
2114 if (orient == wxHORIZONTAL)
2115 {
2116 float fpos = (float)pos;
2117 m_oldHorizontalPos = fpos;
2118
2119 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
2120 m_hAdjust->value = fpos;
2121 }
2122 else
2123 {
2124 float fpos = (float)pos;
2125 m_oldVerticalPos = fpos;
2126 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
2127 m_vAdjust->value = fpos;
2128 }
2129
2130 if (m_wxwindow->window)
2131 {
2132 if (orient == wxHORIZONTAL)
2133 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
2134 else
2135 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
2136 }
2137 }
2138
2139 int wxWindow::GetScrollThumb( int orient ) const
2140 {
2141 if (!m_wxwindow) return 0;
2142
2143 if (orient == wxHORIZONTAL)
2144 return (int)(m_hAdjust->page_size+0.5);
2145 else
2146 return (int)(m_vAdjust->page_size+0.5);
2147 }
2148
2149 int wxWindow::GetScrollPos( int orient ) const
2150 {
2151 if (!m_wxwindow) return 0;
2152
2153 if (orient == wxHORIZONTAL)
2154 return (int)(m_hAdjust->value+0.5);
2155 else
2156 return (int)(m_vAdjust->value+0.5);
2157 }
2158
2159 int wxWindow::GetScrollRange( int orient ) const
2160 {
2161 if (!m_wxwindow) return 0;
2162
2163 if (orient == wxHORIZONTAL)
2164 return (int)(m_hAdjust->upper+0.5);
2165 else
2166 return (int)(m_vAdjust->upper+0.5);
2167 }
2168
2169 void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
2170 {
2171 if (!m_wxwindow) return;
2172
2173 /*
2174 bool refresh = FALSE;
2175
2176 if ((m_drawingOffsetX == 0) && (m_drawingOffsetY == 0))
2177 {
2178 m_drawingOffsetX = -16000;
2179 m_drawingOffsetY = -16000;
2180 refresh = TRUE;
2181 }
2182 else
2183 {
2184 m_drawingOffsetX += dx;
2185 m_drawingOffsetY += dy;
2186 }
2187
2188 // printf( "X: %d Y: %d \n", (int)m_drawingOffsetX, (int)m_drawingOffsetY );
2189
2190 gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
2191
2192 if (refresh) Refresh();
2193
2194 The code here is very nifty, but it doesn't work with
2195 overlapping windows...
2196 */
2197
2198 int cw = 0;
2199 int ch = 0;
2200 GetClientSize( &cw, &ch );
2201
2202 int w = cw - abs(dx);
2203 int h = ch - abs(dy);
2204 if ((h < 0) || (w < 0))
2205 {
2206 Refresh();
2207 return;
2208 }
2209 int s_x = 0;
2210 int s_y = 0;
2211 if (dx < 0) s_x = -dx;
2212 if (dy < 0) s_y = -dy;
2213 int d_x = 0;
2214 int d_y = 0;
2215 if (dx > 0) d_x = dx;
2216 if (dy > 0) d_y = dy;
2217 gdk_window_copy_area( m_wxwindow->window, m_wxwindow->style->fg_gc[0], d_x, d_y,
2218 m_wxwindow->window, s_x, s_y, w, h );
2219
2220 wxRect rect;
2221 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
2222 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
2223 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
2224 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
2225
2226 Refresh( TRUE, &rect );
2227 }
2228
2229 //-------------------------------------------------------------------------------------
2230 // Layout
2231 //-------------------------------------------------------------------------------------
2232
2233 wxLayoutConstraints *wxWindow::GetConstraints(void) const
2234 {
2235 return m_constraints;
2236 }
2237
2238 void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
2239 {
2240 if (m_constraints)
2241 {
2242 UnsetConstraints(m_constraints);
2243 delete m_constraints;
2244 }
2245 m_constraints = constraints;
2246 if (m_constraints)
2247 {
2248 // Make sure other windows know they're part of a 'meaningful relationship'
2249 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
2250 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2251 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
2252 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2253 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
2254 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2255 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
2256 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2257 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
2258 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2259 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
2260 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2261 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
2262 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2263 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
2264 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
2265 }
2266 ;
2267 }
2268 ;
2269
2270 void wxWindow::SetAutoLayout( bool autoLayout )
2271 {
2272 m_autoLayout = autoLayout;
2273 }
2274
2275 bool wxWindow::GetAutoLayout(void) const
2276 {
2277 return m_autoLayout;
2278 }
2279
2280 wxSizer *wxWindow::GetSizer(void) const
2281 {
2282 return m_windowSizer;
2283 }
2284
2285 void wxWindow::SetSizerParent( wxWindow *win )
2286 {
2287 m_sizerParent = win;
2288 }
2289
2290 wxWindow *wxWindow::GetSizerParent(void) const
2291 {
2292 return m_sizerParent;
2293 }
2294
2295 // This removes any dangling pointers to this window
2296 // in other windows' constraintsInvolvedIn lists.
2297 void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
2298 {
2299 if (c)
2300 {
2301 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
2302 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2303 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
2304 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2305 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
2306 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2307 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
2308 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2309 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
2310 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2311 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
2312 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2313 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
2314 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2315 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
2316 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
2317 }
2318 }
2319
2320 // Back-pointer to other windows we're involved with, so if we delete
2321 // this window, we must delete any constraints we're involved with.
2322 void wxWindow::AddConstraintReference(wxWindow *otherWin)
2323 {
2324 if (!m_constraintsInvolvedIn)
2325 m_constraintsInvolvedIn = new wxList;
2326 if (!m_constraintsInvolvedIn->Member(otherWin))
2327 m_constraintsInvolvedIn->Append(otherWin);
2328 }
2329
2330 // REMOVE back-pointer to other windows we're involved with.
2331 void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
2332 {
2333 if (m_constraintsInvolvedIn)
2334 m_constraintsInvolvedIn->DeleteObject(otherWin);
2335 }
2336
2337 // Reset any constraints that mention this window
2338 void wxWindow::DeleteRelatedConstraints(void)
2339 {
2340 if (m_constraintsInvolvedIn)
2341 {
2342 wxNode *node = m_constraintsInvolvedIn->First();
2343 while (node)
2344 {
2345 wxWindow *win = (wxWindow *)node->Data();
2346 wxNode *next = node->Next();
2347 wxLayoutConstraints *constr = win->GetConstraints();
2348
2349 // Reset any constraints involving this window
2350 if (constr)
2351 {
2352 constr->left.ResetIfWin((wxWindow *)this);
2353 constr->top.ResetIfWin((wxWindow *)this);
2354 constr->right.ResetIfWin((wxWindow *)this);
2355 constr->bottom.ResetIfWin((wxWindow *)this);
2356 constr->width.ResetIfWin((wxWindow *)this);
2357 constr->height.ResetIfWin((wxWindow *)this);
2358 constr->centreX.ResetIfWin((wxWindow *)this);
2359 constr->centreY.ResetIfWin((wxWindow *)this);
2360 }
2361 delete node;
2362 node = next;
2363 }
2364 delete m_constraintsInvolvedIn;
2365 m_constraintsInvolvedIn = (wxList *) NULL;
2366 }
2367 }
2368
2369 void wxWindow::SetSizer(wxSizer *sizer)
2370 {
2371 m_windowSizer = sizer;
2372 if (sizer)
2373 sizer->SetSizerParent((wxWindow *)this);
2374 }
2375
2376 /*
2377 * New version
2378 */
2379
2380 bool wxWindow::Layout(void)
2381 {
2382 if (GetConstraints())
2383 {
2384 int w, h;
2385 GetClientSize(&w, &h);
2386 GetConstraints()->width.SetValue(w);
2387 GetConstraints()->height.SetValue(h);
2388 }
2389
2390 // If top level (one sizer), evaluate the sizer's constraints.
2391 if (GetSizer())
2392 {
2393 int noChanges;
2394 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2395 GetSizer()->LayoutPhase1(&noChanges);
2396 GetSizer()->LayoutPhase2(&noChanges);
2397 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2398 return TRUE;
2399 }
2400 else
2401 {
2402 // Otherwise, evaluate child constraints
2403 ResetConstraints(); // Mark all constraints as unevaluated
2404 DoPhase(1); // Just one phase need if no sizers involved
2405 DoPhase(2);
2406 SetConstraintSizes(); // Recursively set the real window sizes
2407 }
2408 return TRUE;
2409 }
2410
2411
2412 // Do a phase of evaluating constraints:
2413 // the default behaviour. wxSizers may do a similar
2414 // thing, but also impose their own 'constraints'
2415 // and order the evaluation differently.
2416 bool wxWindow::LayoutPhase1(int *noChanges)
2417 {
2418 wxLayoutConstraints *constr = GetConstraints();
2419 if (constr)
2420 {
2421 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
2422 }
2423 else
2424 return TRUE;
2425 }
2426
2427 bool wxWindow::LayoutPhase2(int *noChanges)
2428 {
2429 *noChanges = 0;
2430
2431 // Layout children
2432 DoPhase(1);
2433 DoPhase(2);
2434 return TRUE;
2435 }
2436
2437 // Do a phase of evaluating child constraints
2438 bool wxWindow::DoPhase(int phase)
2439 {
2440 int noIterations = 0;
2441 int maxIterations = 500;
2442 int noChanges = 1;
2443 int noFailures = 0;
2444 wxList succeeded;
2445 while ((noChanges > 0) && (noIterations < maxIterations))
2446 {
2447 noChanges = 0;
2448 noFailures = 0;
2449 wxNode *node = GetChildren()->First();
2450 while (node)
2451 {
2452 wxWindow *child = (wxWindow *)node->Data();
2453 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
2454 {
2455 wxLayoutConstraints *constr = child->GetConstraints();
2456 if (constr)
2457 {
2458 if (succeeded.Member(child))
2459 {
2460 }
2461 else
2462 {
2463 int tempNoChanges = 0;
2464 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
2465 noChanges += tempNoChanges;
2466 if (success)
2467 {
2468 succeeded.Append(child);
2469 }
2470 }
2471 }
2472 }
2473 node = node->Next();
2474 }
2475 noIterations ++;
2476 }
2477 return TRUE;
2478 }
2479
2480 void wxWindow::ResetConstraints(void)
2481 {
2482 wxLayoutConstraints *constr = GetConstraints();
2483 if (constr)
2484 {
2485 constr->left.SetDone(FALSE);
2486 constr->top.SetDone(FALSE);
2487 constr->right.SetDone(FALSE);
2488 constr->bottom.SetDone(FALSE);
2489 constr->width.SetDone(FALSE);
2490 constr->height.SetDone(FALSE);
2491 constr->centreX.SetDone(FALSE);
2492 constr->centreY.SetDone(FALSE);
2493 }
2494 wxNode *node = GetChildren()->First();
2495 while (node)
2496 {
2497 wxWindow *win = (wxWindow *)node->Data();
2498 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
2499 win->ResetConstraints();
2500 node = node->Next();
2501 }
2502 }
2503
2504 // Need to distinguish between setting the 'fake' size for
2505 // windows and sizers, and setting the real values.
2506 void wxWindow::SetConstraintSizes(bool recurse)
2507 {
2508 wxLayoutConstraints *constr = GetConstraints();
2509 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
2510 constr->width.GetDone() && constr->height.GetDone())
2511 {
2512 int x = constr->left.GetValue();
2513 int y = constr->top.GetValue();
2514 int w = constr->width.GetValue();
2515 int h = constr->height.GetValue();
2516
2517 // If we don't want to resize this window, just move it...
2518 if ((constr->width.GetRelationship() != wxAsIs) ||
2519 (constr->height.GetRelationship() != wxAsIs))
2520 {
2521 // Calls Layout() recursively. AAAGH. How can we stop that.
2522 // Simply take Layout() out of non-top level OnSizes.
2523 SizerSetSize(x, y, w, h);
2524 }
2525 else
2526 {
2527 SizerMove(x, y);
2528 }
2529 }
2530 else if (constr)
2531 {
2532 char *windowClass = this->GetClassInfo()->GetClassName();
2533
2534 wxString winName;
2535 if (GetName() == "")
2536 winName = _("unnamed");
2537 else
2538 winName = GetName();
2539 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass, (const char *)winName);
2540 if (!constr->left.GetDone())
2541 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
2542 if (!constr->right.GetDone())
2543 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
2544 if (!constr->width.GetDone())
2545 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
2546 if (!constr->height.GetDone())
2547 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2548 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
2549 }
2550
2551 if (recurse)
2552 {
2553 wxNode *node = GetChildren()->First();
2554 while (node)
2555 {
2556 wxWindow *win = (wxWindow *)node->Data();
2557 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
2558 win->SetConstraintSizes();
2559 node = node->Next();
2560 }
2561 }
2562 }
2563
2564 // This assumes that all sizers are 'on' the same
2565 // window, i.e. the parent of this window.
2566 void wxWindow::TransformSizerToActual(int *x, int *y) const
2567 {
2568 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
2569 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
2570 return;
2571
2572 int xp, yp;
2573 m_sizerParent->GetPosition(&xp, &yp);
2574 m_sizerParent->TransformSizerToActual(&xp, &yp);
2575 *x += xp;
2576 *y += yp;
2577 }
2578
2579 void wxWindow::SizerSetSize(int x, int y, int w, int h)
2580 {
2581 int xx = x;
2582 int yy = y;
2583 TransformSizerToActual(&xx, &yy);
2584 SetSize(xx, yy, w, h);
2585 }
2586
2587 void wxWindow::SizerMove(int x, int y)
2588 {
2589 int xx = x;
2590 int yy = y;
2591 TransformSizerToActual(&xx, &yy);
2592 Move(xx, yy);
2593 }
2594
2595 // Only set the size/position of the constraint (if any)
2596 void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
2597 {
2598 wxLayoutConstraints *constr = GetConstraints();
2599 if (constr)
2600 {
2601 if (x != -1)
2602 {
2603 constr->left.SetValue(x);
2604 constr->left.SetDone(TRUE);
2605 }
2606 if (y != -1)
2607 {
2608 constr->top.SetValue(y);
2609 constr->top.SetDone(TRUE);
2610 }
2611 if (w != -1)
2612 {
2613 constr->width.SetValue(w);
2614 constr->width.SetDone(TRUE);
2615 }
2616 if (h != -1)
2617 {
2618 constr->height.SetValue(h);
2619 constr->height.SetDone(TRUE);
2620 }
2621 }
2622 }
2623
2624 void wxWindow::MoveConstraint(int x, int y)
2625 {
2626 wxLayoutConstraints *constr = GetConstraints();
2627 if (constr)
2628 {
2629 if (x != -1)
2630 {
2631 constr->left.SetValue(x);
2632 constr->left.SetDone(TRUE);
2633 }
2634 if (y != -1)
2635 {
2636 constr->top.SetValue(y);
2637 constr->top.SetDone(TRUE);
2638 }
2639 }
2640 }
2641
2642 void wxWindow::GetSizeConstraint(int *w, int *h) const
2643 {
2644 wxLayoutConstraints *constr = GetConstraints();
2645 if (constr)
2646 {
2647 *w = constr->width.GetValue();
2648 *h = constr->height.GetValue();
2649 }
2650 else
2651 GetSize(w, h);
2652 }
2653
2654 void wxWindow::GetClientSizeConstraint(int *w, int *h) const
2655 {
2656 wxLayoutConstraints *constr = GetConstraints();
2657 if (constr)
2658 {
2659 *w = constr->width.GetValue();
2660 *h = constr->height.GetValue();
2661 }
2662 else
2663 GetClientSize(w, h);
2664 }
2665
2666 void wxWindow::GetPositionConstraint(int *x, int *y) const
2667 {
2668 wxLayoutConstraints *constr = GetConstraints();
2669 if (constr)
2670 {
2671 *x = constr->left.GetValue();
2672 *y = constr->top.GetValue();
2673 }
2674 else
2675 GetPosition(x, y);
2676 }
2677
2678 bool wxWindow::AcceptsFocus() const
2679 {
2680 return IsEnabled() && IsShown();
2681 }
2682
2683 void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) )
2684 {
2685 UpdateWindowUI();
2686 }