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