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