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