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