]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/window.cpp
Some manual updates; in MDI sample, child frames now have default size/position ...
[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
5e0aa05a 8// Licence: wxWindows licence
c801d85f
KB
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"
d4c99d6f
RR
29#include "wx/statusbr.h"
30#include "wx/treectrl.h"
c801d85f
KB
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
40extern wxList wxPendingDelete;
41extern wxList wxTopLevelWindows;
42extern 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
51void 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/*
d4c99d6f
RR
57 if (IS_KIND_OF(win,wxTreeCtrl))
58 {
59 printf( "OnExpose from " );
c801d85f
KB
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 );
d4c99d6f 68}
c801d85f
KB
69*/
70
71 win->m_updateRegion.Union( gdk_event->area.x,
72 gdk_event->area.y,
5e0aa05a
VZ
73 gdk_event->area.width,
74 gdk_event->area.height );
75
c801d85f
KB
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
88void 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 );
5e0aa05a 106
c801d85f
KB
107 wxPaintEvent event( win->GetId() );
108 event.SetEventObject( win );
109 win->ProcessEvent( event );
110
111 win->m_updateRegion.Clear();
112};
113
114//-----------------------------------------------------------------------------
115// size
33d0b396
RR
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).
c801d85f
KB
119
120/*
121void 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
158gint 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 {
5e0aa05a
VZ
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;
c801d85f
KB
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
265gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
266{
e3e65dac
RR
267 if (widget->window != gdk_event->window) return TRUE;
268 if (g_blockEventsOnDrag) return TRUE;
c801d85f
KB
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
e3e65dac 286 if (!win->HasVMT()) return TRUE;
c801d85f
KB
287
288/*
289 printf( "OnButtonPress from " );
290 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
291 printf( win->GetClassInfo()->GetClassName() );
292 printf( ".\n" );
293*/
294
7798a18e 295 wxEventType event_type = wxEVT_LEFT_DOWN;
c801d85f
KB
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
346gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
347{
348 if (widget->window != gdk_event->window) return TRUE;
349
e3e65dac 350 if (g_blockEventsOnDrag) return TRUE;
c801d85f 351
e3e65dac 352 if (!win->HasVMT()) return TRUE;
c801d85f
KB
353
354/*
355 printf( "OnButtonRelease from " );
356 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
357 printf( win->GetClassInfo()->GetClassName() );
358 printf( ".\n" );
359*/
360
7798a18e 361 wxEventType event_type = wxEVT_NULL;
c801d85f
KB
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
e3e65dac
RR
382 win->ProcessEvent( event );
383
384 return TRUE;
c801d85f
KB
385};
386
387//-----------------------------------------------------------------------------
388// motion_notify
389
390gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
391{
392 if (widget->window != gdk_event->window) return TRUE;
393
e3e65dac 394 if (g_blockEventsOnDrag) return TRUE;
c801d85f 395
e3e65dac 396 if (!win->HasVMT()) return TRUE;
c801d85f
KB
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
e3e65dac 420 return TRUE;
c801d85f
KB
421};
422
423//-----------------------------------------------------------------------------
424// focus_in
425
401ec7b6 426gint gtk_window_focus_in_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 427{
e3e65dac 428 if (g_blockEventsOnDrag) return TRUE;
c801d85f
KB
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
e3e65dac 443 if (!win->HasVMT()) return TRUE;
c801d85f
KB
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 );
e3e65dac
RR
456 win->ProcessEvent( event );
457
458 return TRUE;
c801d85f
KB
459};
460
461//-----------------------------------------------------------------------------
462// focus out
463
401ec7b6 464gint gtk_window_focus_out_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 465{
e3e65dac 466 if (g_blockEventsOnDrag) return TRUE;
c801d85f
KB
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
e3e65dac 473 if (!win->HasVMT()) return TRUE;
c801d85f
KB
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 );
e3e65dac
RR
484 win->ProcessEvent( event );
485
486 return TRUE;
c801d85f
KB
487};
488
489//-----------------------------------------------------------------------------
490// vertical scroll
491
492void 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
7798a18e 515 wxEventType command = wxEVT_NULL;
c801d85f
KB
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
536void 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
7798a18e 559 wxEventType command = wxEVT_NULL;
c801d85f
KB
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
580void 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
7798a18e 593 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
c801d85f
KB
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
604void 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
7798a18e 617 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
c801d85f
KB
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
628void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWindow *win )
629{
c801d85f
KB
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
647bool 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
401ec7b6 662bool gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
c801d85f 663{
401ec7b6
RR
664 if (widget->window != gdk_event->window) return TRUE;
665
c801d85f
KB
666 if (g_blockEventsOnDrag) return FALSE;
667
668 if (widget->window)
669 gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() );
670
401ec7b6
RR
671 wxMouseEvent event( wxEVT_ENTER_WINDOW );
672 event.SetEventObject( win );
673 return win->ProcessEvent( event );
c801d85f
KB
674};
675
676//-----------------------------------------------------------------------------
677// leave
678
401ec7b6 679bool gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
c801d85f 680{
401ec7b6
RR
681 if (widget->window != gdk_event->window) return TRUE;
682
c801d85f
KB
683 if (g_blockEventsOnDrag) return FALSE;
684
685 if (widget->window)
686 gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
687
401ec7b6
RR
688 wxMouseEvent event( wxEVT_LEAVE_WINDOW );
689 event.SetEventObject( win );
690 return win->ProcessEvent( event );
c801d85f
KB
691};
692
693//-----------------------------------------------------------------------------
694// wxWindow implementation
695//-----------------------------------------------------------------------------
696
697IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
698
699BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
c801d85f 700 EVT_SIZE(wxWindow::OnSize)
c801d85f
KB
701 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
702 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
5e0aa05a 703 EVT_IDLE(wxWindow::OnIdle)
c801d85f
KB
704END_EVENT_TABLE()
705
706wxWindow::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;
33d0b396 742 m_resizing = FALSE;
c801d85f
KB
743};
744
debe6624
JS
745wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
746 const wxPoint &pos, const wxSize &size,
747 long style, const wxString &name )
c801d85f
KB
748{
749 Create( parent, id, pos, size, style, name );
750};
751
debe6624
JS
752bool wxWindow::Create( wxWindow *parent, wxWindowID id,
753 const wxPoint &pos, const wxSize &size,
754 long style, const wxString &name )
c801d85f
KB
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",
5e0aa05a 780 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
c801d85f 781 gtk_signal_connect (GTK_OBJECT (m_vAdjust), "value_changed",
5e0aa05a
VZ
782 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
783
c801d85f 784 gtk_signal_connect (GTK_OBJECT (m_hAdjust), "changed",
5e0aa05a 785 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
c801d85f 786 gtk_signal_connect (GTK_OBJECT (m_vAdjust), "changed",
5e0aa05a 787 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
c801d85f
KB
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
843wxWindow::~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
debe6624
JS
890void wxWindow::PreCreation( wxWindow *parent, wxWindowID id,
891 const wxPoint &pos, const wxSize &size,
892 long style, const wxString &name )
c801d85f
KB
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;
33d0b396 926 m_resizing = FALSE;
c801d85f
KB
927}
928
929void 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
c801d85f
KB
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
1011bool wxWindow::HasVMT(void)
1012{
1013 return m_hasVMT;
1014};
1015
debe6624 1016bool wxWindow::Close( bool force )
c801d85f
KB
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
1025bool wxWindow::Destroy(void)
1026{
1027 m_hasVMT = FALSE;
1028 delete this;
1029 return TRUE;
1030};
1031
1032bool 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;
5e0aa05a 1043 if (GetChildren()->Member(child)) delete node;
c801d85f
KB
1044 };
1045 };
1046 };
1047 return TRUE;
1048};
1049
1050void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
1051{
1052 // are we to set fonts here ?
1053};
1054
1055void wxWindow::ImplementSetSize(void)
1056{
1057 gtk_widget_set_usize( m_widget, m_width, m_height );
1058};
1059
1060void wxWindow::ImplementSetPosition(void)
1061{
1a6944fd
RR
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
c801d85f
KB
1076 if ((m_parent) && (m_parent->m_wxwindow))
1077 gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
1a6944fd
RR
1078
1079 // Don't do anything for children of wxNotebook and wxMDIChildFrame
c801d85f
KB
1080};
1081
debe6624 1082void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 1083{
33d0b396
RR
1084 if (m_resizing) return; // I don't like recursions
1085 m_resizing = TRUE;
1086
c801d85f
KB
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 );
33d0b396
RR
1127
1128 m_resizing = FALSE;
c801d85f
KB
1129};
1130
debe6624 1131void wxWindow::SetSize( int width, int height )
c801d85f
KB
1132{
1133 SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
1134};
1135
debe6624 1136void wxWindow::Move( int x, int y )
c801d85f
KB
1137{
1138 SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
1139};
1140
1141void wxWindow::GetSize( int *width, int *height ) const
1142{
33d0b396
RR
1143 if (width) (*width) = m_width;
1144 if (height) (*height) = m_height;
c801d85f
KB
1145};
1146
debe6624 1147void wxWindow::SetClientSize( int width, int height )
c801d85f
KB
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)
5e0aa05a 1182 )
c801d85f
KB
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
1205void 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)
5e0aa05a 1241 )
c801d85f
KB
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
1267void wxWindow::GetPosition( int *x, int *y ) const
1268{
1269 if (x) (*x) = m_x;
1270 if (y) (*y) = m_y;
1271};
1272
1273void 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
1300void 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
debe6624 1325void wxWindow::Centre( int direction )
c801d85f 1326{
c801d85f
KB
1327 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
1328 {
d4c99d6f
RR
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();
c801d85f
KB
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 );
d4c99d6f
RR
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();
c801d85f
KB
1343 };
1344 }
1345};
1346
1347void wxWindow::Fit(void)
1348{
5e0aa05a
VZ
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);
c801d85f
KB
1366};
1367
1368void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
1369{
da7f8ac4 1370 //if (GetAutoLayout()) Layout();
c801d85f
KB
1371};
1372
debe6624 1373bool wxWindow::Show( bool show )
c801d85f
KB
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
debe6624 1383void wxWindow::Enable( bool enable )
c801d85f
KB
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
debe6624 1390void wxWindow::MakeModal( bool modal )
c801d85f
KB
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
1408void 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
1421bool wxWindow::OnClose(void)
1422{
c801d85f
KB
1423 return TRUE;
1424};
1425
1426void 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
46dc76ba
RR
1436 // wxFrame and wxDialog as children aren't placed into the parents
1437
d4c99d6f
RR
1438 if (( IS_KIND_OF(child,wxFrame) || IS_KIND_OF(child,wxDialog) ) &&
1439 (!IS_KIND_OF(child,wxMDIChildFrame)))
46dc76ba
RR
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
d4c99d6f 1452 if (IS_KIND_OF(this,wxMDIParentFrame))
c801d85f 1453 {
d4c99d6f 1454 if (IS_KIND_OF(child,wxMDIChildFrame))
c801d85f
KB
1455 {
1456 wxMDIClientWindow *client = ((wxMDIParentFrame*)this)->GetClientWindow();
1457 if (client)
1458 {
1459 client->AddChild( child );
1460 return;
46dc76ba
RR
1461 }
1462 }
1463 }
7f4dc78d 1464
46dc76ba 1465 // wxNotebook is very special, so it has a private AddChild()
33d0b396 1466
d4c99d6f 1467 if (IS_KIND_OF(this,wxNotebook))
7f4dc78d 1468 {
53b28675 1469 wxNotebook *tab = (wxNotebook*)this;
7f4dc78d
RR
1470 tab->AddChild( child );
1471 return;
46dc76ba 1472 }
7f4dc78d 1473
46dc76ba
RR
1474 // wxFrame has a private AddChild
1475
d4c99d6f 1476 if (IS_KIND_OF(this,wxFrame))
c801d85f 1477 {
46dc76ba
RR
1478 wxFrame *frame = (wxFrame*)this;
1479 frame->AddChild( child );
1480 return;
c801d85f 1481 }
46dc76ba
RR
1482
1483 // All the rest
1484
1485 m_children.Append( child );
d4c99d6f
RR
1486 if (m_wxwindow) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), child->m_widget,
1487 child->m_x, child->m_y );
e3e65dac 1488
c801d85f
KB
1489 gtk_widget_set_usize( child->m_widget, child->m_width, child->m_height );
1490};
1491
1492wxList *wxWindow::GetChildren(void)
1493{
1494 return (&m_children);
1495};
1496
1497void wxWindow::RemoveChild( wxWindow *child )
1498{
1499 if (GetChildren())
1500 GetChildren()->DeleteObject( child );
1501 child->m_parent = NULL;
1502};
1503
1504void wxWindow::SetReturnCode( int retCode )
1505{
1506 m_retCode = retCode;
1507};
1508
1509int wxWindow::GetReturnCode(void)
1510{
1511 return m_retCode;
1512};
1513
1514wxWindow *wxWindow::GetParent(void)
1515{
1516 return m_parent;
1517};
1518
1519wxEvtHandler *wxWindow::GetEventHandler(void)
1520{
1521 return m_eventHandler;
1522};
1523
1524void wxWindow::SetEventhandler( wxEvtHandler *handler )
1525{
1526 m_eventHandler = handler;
1527};
1528
1529wxValidator *wxWindow::GetValidator(void)
1530{
1531 return m_windowValidator;
1532};
1533
1534void wxWindow::SetValidator( wxValidator *validator )
1535{
1536 m_windowValidator = validator;
1537};
1538
1539bool wxWindow::IsBeingDeleted(void)
1540{
1541 return FALSE;
1542};
1543
1544void wxWindow::SetId( wxWindowID id )
1545{
1546 m_windowId = id;
1547};
1548
1549wxWindowID wxWindow::GetId(void)
1550{
1551 return m_windowId;
1552};
1553
1554void 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
debe6624 1564void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f
KB
1565{
1566 if (eraseBackground && m_wxwindow && m_wxwindow->window)
1567 {
1568 if (rect)
1569 gdk_window_clear_area( m_wxwindow->window,
1570 rect->x,
d4c99d6f
RR
1571 rect->y,
1572 rect->width,
1573 rect->height );
c801d85f
KB
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;
d4c99d6f
RR
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
c801d85f
KB
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
debe6624 1620bool wxWindow::IsExposed( long x, long y )
c801d85f
KB
1621{
1622 return (m_updateRegion.Contains( x, y ) != wxOutRegion );
1623};
1624
debe6624 1625bool wxWindow::IsExposed( long x, long y, long width, long height )
c801d85f
KB
1626{
1627 return (m_updateRegion.Contains( x, y, width, height ) != wxOutRegion );
1628};
1629
1630void wxWindow::Clear(void)
1631{
1632 if (m_wxwindow && m_wxwindow->window) gdk_window_clear( m_wxwindow->window );
1633};
1634
1635wxColour wxWindow::GetBackgroundColour(void) const
1636{
1637 return m_backgroundColour;
1638};
1639
1640void 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
1652bool 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
1665bool 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() && */
5e0aa05a 1672 !child->GetValidator()->TransferToWindow() )
c801d85f
KB
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
1682bool 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
1695void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
1696{
1697 TransferDataToWindow();
1698};
1699
1700void wxWindow::InitDialog(void)
1701{
1702 wxInitDialogEvent event(GetId());
1703 event.SetEventObject( this );
1704 GetEventHandler()->ProcessEvent(event);
1705};
1706
1707void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
1708{
e3e65dac
RR
1709 GtkWidget *dnd_widget = GetDropTargetWidget();
1710
c801d85f
KB
1711 if (m_pDropTarget)
1712 {
e3e65dac
RR
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 );
c801d85f
KB
1717 delete m_pDropTarget;
1718 };
1719 m_pDropTarget = dropTarget;
1720 if (m_pDropTarget)
1721 {
e3e65dac
RR
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 );
c801d85f
KB
1726 };
1727};
1728
1729wxDropTarget *wxWindow::GetDropTarget() const
1730{
1731 return m_pDropTarget;
1732};
1733
e3e65dac
RR
1734GtkWidget* 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
c801d85f
KB
1742void 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
1756wxFont *wxWindow::GetFont(void)
1757{
1758 return &m_font;
1759};
1760
1761void wxWindow::SetWindowStyleFlag( long flag )
1762{
1763 m_windowStyle = flag;
1764};
1765
1766long wxWindow::GetWindowStyleFlag(void) const
1767{
1768 return m_windowStyle;
1769};
1770
1771void 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)
5e0aa05a
VZ
1778 (GDK_BUTTON_PRESS_MASK |
1779 GDK_BUTTON_RELEASE_MASK |
1780 GDK_POINTER_MOTION_MASK),
1781 NULL, NULL, GDK_CURRENT_TIME );
c801d85f
KB
1782};
1783
1784void 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
1792void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
1793{
1794};
1795
1796wxString wxWindow::GetTitle(void) const
1797{
1798 return (wxString&)m_windowName;
1799};
1800
1801wxString wxWindow::GetLabel(void) const
1802{
1803 return GetTitle();
1804};
1805
1806void wxWindow::SetName( const wxString &name )
1807{
1808 m_windowName = name;
1809};
1810
1811wxString wxWindow::GetName(void) const
1812{
1813 return (wxString&)m_windowName;
1814};
1815
7fd1d163 1816bool wxWindow::IsShown(void) const
c801d85f
KB
1817{
1818 return m_isShown;
1819};
1820
1821bool wxWindow::IsRetained(void)
1822{
1823 return FALSE;
1824};
1825
debe6624 1826wxWindow *wxWindow::FindWindow( long id )
c801d85f
KB
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
1840wxWindow *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
debe6624
JS
1854void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
1855 int range, bool WXUNUSED(refresh) )
c801d85f
KB
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) &&
5e0aa05a 1868 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
c801d85f
KB
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) &&
5e0aa05a 1887 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
c801d85f
KB
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 };
33d0b396 1897
c801d85f 1898 if (m_wxwindow->window)
d4c99d6f 1899 {
c801d85f 1900 if (orient == wxHORIZONTAL)
d4c99d6f
RR
1901 {
1902/*
1903 m_drawingOffsetX = -16000;
1904
1905 gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
1906*/
c801d85f 1907 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
d4c99d6f
RR
1908 }
1909 else
1910 {
1911/*
1912 m_drawingOffsetY = -16000;
1913
1914 gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
1915*/
c801d85f 1916 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
d4c99d6f 1917 }
c801d85f 1918
401ec7b6 1919 gtk_widget_set_usize( m_widget, m_width, m_height );
c801d85f
KB
1920 };
1921};
1922
debe6624 1923void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f
KB
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
debe6624 1952int wxWindow::GetScrollThumb( int orient ) const
c801d85f
KB
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
debe6624 1962int wxWindow::GetScrollPos( int orient ) const
c801d85f
KB
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
debe6624 1972int wxWindow::GetScrollRange( int orient ) const
c801d85f
KB
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
debe6624 1982void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f
KB
1983{
1984 if (!m_wxwindow) return;
1985
d4c99d6f
RR
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 }
c801d85f
KB
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
d4c99d6f
RR
2004 if (refresh) Refresh();
2005
c801d85f
KB
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
2042void 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
2052wxLayoutConstraints *wxWindow::GetConstraints(void) const
2053{
2054 return m_constraints;
2055};
2056
2057void 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
debe6624 2089void wxWindow::SetAutoLayout( bool autoLayout )
c801d85f
KB
2090{
2091 m_autoLayout = autoLayout;
2092};
2093
2094bool wxWindow::GetAutoLayout(void) const
2095{
2096 return m_autoLayout;
2097};
2098
2099wxSizer *wxWindow::GetSizer(void) const
2100{
2101 return m_windowSizer;
2102};
2103
2104void wxWindow::SetSizerParent( wxWindow *win )
2105{
2106 m_sizerParent = win;
2107};
2108
2109wxWindow *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.
2116void 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.
2141void 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.
2150void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
2151{
2152 if (m_constraintsInvolvedIn)
2153 m_constraintsInvolvedIn->DeleteObject(otherWin);
2154}
2155
2156// Reset any constraints that mention this window
2157void 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
2188void 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
2199bool 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.
2235bool 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
2246bool 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
debe6624 2257bool wxWindow::DoPhase(int phase)
c801d85f
KB
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
2299void 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.
debe6624 2325void wxWindow::SetConstraintSizes(bool recurse)
c801d85f
KB
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;
5e0aa05a
VZ
2354 if (GetName() == "")
2355 winName = "unnamed";
2356 else
2357 winName = GetName();
c801d85f
KB
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.
2385void wxWindow::TransformSizerToActual(int *x, int *y) const
2386{
2387 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
5e0aa05a 2388 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
c801d85f
KB
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
debe6624 2398void wxWindow::SizerSetSize(int x, int y, int w, int h)
c801d85f 2399{
5e0aa05a
VZ
2400 int xx = x;
2401 int yy = y;
c801d85f
KB
2402 TransformSizerToActual(&xx, &yy);
2403 SetSize(xx, yy, w, h);
2404}
2405
debe6624 2406void wxWindow::SizerMove(int x, int y)
c801d85f 2407{
5e0aa05a
VZ
2408 int xx = x;
2409 int yy = y;
c801d85f
KB
2410 TransformSizerToActual(&xx, &yy);
2411 Move(xx, yy);
2412}
2413
2414// Only set the size/position of the constraint (if any)
debe6624 2415void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
c801d85f
KB
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
debe6624 2443void wxWindow::MoveConstraint(int x, int y)
c801d85f
KB
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
2461void 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
2473void 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
2485void 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
7fd1d163 2497bool wxWindow::AcceptsFocus() const
0abbe297
VZ
2498{
2499 return IsEnabled() && IsShown();
2500}
5e0aa05a 2501
e3e65dac 2502void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) )
5e0aa05a
VZ
2503{
2504 UpdateWindowUI();
2505}