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