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