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