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