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