1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "window.h"
17 #include "wx/window.h"
21 #include "wx/layout.h"
23 #include "wx/dialog.h"
24 #include "wx/msgdlg.h"
25 #include "wx/dcclient.h"
29 #include "wx/notebook.h"
30 #include "wx/statusbr.h"
32 #include "gdk/gdkkeysyms.h"
34 #include "wx/gtk/win_gtk.h"
35 #include "gdk/gdkprivate.h"
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 extern wxList wxPendingDelete
;
42 extern wxList wxTopLevelWindows
;
43 extern bool g_blockEventsOnDrag
;
45 //-----------------------------------------------------------------------------
46 // GTK callbacks for wxWindows event system
47 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
50 // expose (of m_wxwindow, not of m_widget)
52 void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
54 if (!win
->HasVMT()) return;
55 if (g_blockEventsOnDrag
) return;
58 if (IS_KIND_OF(win,wxStatusBar))
60 printf( "OnExpose from " );
61 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
62 printf( win->GetClassInfo()->GetClassName() );
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 );
72 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
74 gdk_event
->area
.width
,
75 gdk_event
->area
.height
);
77 if (gdk_event
->count
> 0) return;
79 wxPaintEvent
event( win
->GetId() );
80 event
.SetEventObject( win
);
81 win
->ProcessEvent( event
);
83 win
->m_updateRegion
.Clear();
86 //-----------------------------------------------------------------------------
87 // draw (of m_wxwindow, not of m_widget)
89 void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
91 if (!win
->HasVMT()) return;
92 if (g_blockEventsOnDrag
) return;
95 if (IS_KIND_OF(win,wxStatusBar))
97 printf( "OnDraw from " );
98 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
99 printf( win->GetClassInfo()->GetClassName() );
102 printf( "x: %d \n", rect->x );
103 printf( "y: %d \n", rect->y );
104 printf( "w: %d \n", rect->width );
105 printf( "h: %d \n", rect->height );
109 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
111 wxPaintEvent
event( win
->GetId() );
112 event
.SetEventObject( win
);
113 win
->ProcessEvent( event
);
115 win
->m_updateRegion
.Clear();
118 //-----------------------------------------------------------------------------
120 // I don't any longer intercept GTK's internal resize events, except
121 // for frames and from within MDI and tabbed windows (client area
122 // size determined internally by GTK, not wxWin).
125 void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
127 if (!win->HasVMT()) return;
128 if (g_blockEventsOnDrag) return;
132 if ((win->m_x == alloc->x) &&
133 (win->m_y == alloc->y) &&
134 (win->m_width == alloc->width) &&
135 (win->m_height == alloc->height))
140 printf( "OnResize from " );
141 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
142 printf( win->GetClassInfo()->GetClassName() );
145 printf( " Old: X: %d Y: %d ", win->m_x, win->m_y );
146 printf( " W: %d H: %d ", win->m_width, win->m_height );
149 printf( " New: X: %d Y: %d ", alloc->x, alloc->y );
150 printf( " W: %d H: %d ", alloc->width, alloc->height );
153 wxSizeEvent event( wxSize( alloc->width, alloc->height), win->GetId() );
154 event.SetEventObject( win );
155 win->ProcessEvent( event );
159 //-----------------------------------------------------------------------------
162 gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
164 if (!win
->HasVMT()) return FALSE
;
165 if (g_blockEventsOnDrag
) return FALSE
;
168 printf( "OnKeyPress from " );
169 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
170 printf( win->GetClassInfo()->GetClassName() );
175 switch (gdk_event
->keyval
)
177 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
178 case GDK_Tab
: key_code
= WXK_TAB
; break;
179 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
180 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
181 case GDK_Return
: key_code
= WXK_RETURN
; break;
182 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
183 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
184 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
185 case GDK_Delete
: key_code
= WXK_DELETE
; break;
186 case GDK_Home
: key_code
= WXK_HOME
; break;
187 case GDK_Left
: key_code
= WXK_LEFT
; break;
188 case GDK_Up
: key_code
= WXK_UP
; break;
189 case GDK_Right
: key_code
= WXK_RIGHT
; break;
190 case GDK_Down
: key_code
= WXK_DOWN
; break;
191 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
192 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
193 case GDK_Next
: key_code
= WXK_NEXT
; break;
194 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
195 case GDK_End
: key_code
= WXK_END
; break;
196 case GDK_Begin
: key_code
= WXK_HOME
; break;
197 case GDK_Select
: key_code
= WXK_SELECT
; break;
198 case GDK_Print
: key_code
= WXK_PRINT
; break;
199 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
200 case GDK_Insert
: key_code
= WXK_INSERT
; break;
201 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
202 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
203 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
204 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
205 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
206 case GDK_KP_Up
: key_code
= WXK_UP
; break;
207 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
208 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
209 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
210 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
211 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
212 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
213 case GDK_KP_End
: key_code
= WXK_END
; break;
214 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
215 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
216 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
217 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
218 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
219 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
220 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
221 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
222 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
223 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
224 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
225 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
226 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
227 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
228 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
229 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
230 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
231 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
232 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
233 case GDK_F1
: key_code
= WXK_F1
; break;
234 case GDK_F2
: key_code
= WXK_F2
; break;
235 case GDK_F3
: key_code
= WXK_F3
; break;
236 case GDK_F4
: key_code
= WXK_F4
; break;
237 case GDK_F5
: key_code
= WXK_F5
; break;
238 case GDK_F6
: key_code
= WXK_F6
; break;
239 case GDK_F7
: key_code
= WXK_F7
; break;
240 case GDK_F8
: key_code
= WXK_F8
; break;
241 case GDK_F9
: key_code
= WXK_F9
; break;
242 case GDK_F10
: key_code
= WXK_F10
; break;
243 case GDK_F11
: key_code
= WXK_F11
; break;
244 case GDK_F12
: key_code
= WXK_F12
; break;
247 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
248 key_code
= gdk_event
->keyval
;
252 if (!key_code
) return FALSE
;
254 wxKeyEvent
event( wxEVT_CHAR
);
255 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
256 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
257 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
258 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
259 event
.m_keyCode
= key_code
;
262 event
.SetEventObject( win
);
264 bool ret
= win
->ProcessEvent( event
);
268 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
269 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
273 if (ret) printf( "found.\n") ;
278 //-----------------------------------------------------------------------------
281 gint
gtk_window_button_press_callback( GtkWidget
*WXUNUSED(widget
), GdkEventButton
*gdk_event
, wxWindow
*win
)
283 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
285 if (g_blockEventsOnDrag
) return TRUE
;
289 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
291 gtk_widget_grab_focus (win
->m_wxwindow
);
294 printf( "GrabFocus from " );
295 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
296 printf( win->GetClassInfo()->GetClassName() );
303 if (!win
->HasVMT()) return TRUE
;
306 printf( "OnButtonPress from " );
307 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
308 printf( win->GetClassInfo()->GetClassName() );
312 wxEventType event_type
= wxEVT_LEFT_DOWN
;
314 if (gdk_event
->button
== 1)
316 switch (gdk_event
->type
)
318 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
319 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
323 else if (gdk_event
->button
== 2)
325 switch (gdk_event
->type
)
327 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
328 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
332 else if (gdk_event
->button
== 3)
334 switch (gdk_event
->type
)
336 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
337 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
342 wxMouseEvent
event( event_type
);
343 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
344 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
345 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
346 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
347 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
348 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
349 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
351 event
.m_x
= (long)gdk_event
->x
;
352 event
.m_y
= (long)gdk_event
->y
;
353 event
.SetEventObject( win
);
355 win
->ProcessEvent( event
);
360 //-----------------------------------------------------------------------------
363 gint
gtk_window_button_release_callback( GtkWidget
*WXUNUSED(widget
), GdkEventButton
*gdk_event
, wxWindow
*win
)
365 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
366 if (g_blockEventsOnDrag
) return TRUE
;
368 if (!win
->HasVMT()) return TRUE
;
371 printf( "OnButtonRelease from " );
372 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
373 printf( win->GetClassInfo()->GetClassName() );
377 wxEventType event_type
= wxEVT_NULL
;
379 switch (gdk_event
->button
)
381 case 1: event_type
= wxEVT_LEFT_UP
; break;
382 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
383 case 3: event_type
= wxEVT_RIGHT_UP
; break;
386 wxMouseEvent
event( event_type
);
387 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
388 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
389 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
390 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
391 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
392 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
393 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
394 event
.m_x
= (long)gdk_event
->x
;
395 event
.m_y
= (long)gdk_event
->y
;
396 event
.SetEventObject( win
);
398 win
->ProcessEvent( event
);
403 //-----------------------------------------------------------------------------
406 gint
gtk_window_motion_notify_callback( GtkWidget
*WXUNUSED(widget
), GdkEventMotion
*gdk_event
, wxWindow
*win
)
408 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
409 if (g_blockEventsOnDrag
) return TRUE
;
411 if (!win
->HasVMT()) return TRUE
;
414 printf( "OnMotion from " );
415 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
416 printf( win->GetClassInfo()->GetClassName() );
420 wxMouseEvent
event( wxEVT_MOTION
);
421 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
422 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
423 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
424 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
425 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
426 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
427 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
429 event
.m_x
= (long)gdk_event
->x
;
430 event
.m_y
= (long)gdk_event
->y
;
431 event
.SetEventObject( win
);
433 win
->ProcessEvent( event
);
438 //-----------------------------------------------------------------------------
441 gint
gtk_window_focus_in_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
443 if (g_blockEventsOnDrag
) return TRUE
;
446 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
448 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
450 printf( "SetFocus flag from " );
451 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
452 printf( win->GetClassInfo()->GetClassName() );
458 if (!win
->HasVMT()) return TRUE
;
461 printf( "OnSetFocus from " );
462 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
463 printf( win->GetClassInfo()->GetClassName() );
465 printf( WXSTRINGCAST win->GetLabel() );
469 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
470 event
.SetEventObject( win
);
471 win
->ProcessEvent( event
);
476 //-----------------------------------------------------------------------------
479 gint
gtk_window_focus_out_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
481 if (g_blockEventsOnDrag
) return TRUE
;
484 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
485 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
488 if (!win
->HasVMT()) return TRUE
;
491 printf( "OnKillFocus from " );
492 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
493 printf( win->GetClassInfo()->GetClassName() );
497 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
498 event
.SetEventObject( win
);
499 win
->ProcessEvent( event
);
504 //-----------------------------------------------------------------------------
507 void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
509 if (g_blockEventsOnDrag
) return;
512 printf( "OnVScroll from " );
513 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
514 printf( win->GetClassInfo()->GetClassName() );
518 if (!win
->HasVMT()) return;
520 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
521 if (fabs(diff
) < 0.2) return;
524 int i = (int)(win->m_oldVerticalPos+0.5);
525 printf( "Old value: %d.\n", i );
526 i = (int)(win->m_vAdjust->value+0.5);
527 printf( "Sending new value: %d.\n", i );
530 wxEventType command
= wxEVT_NULL
;
532 float line_step
= win
->m_vAdjust
->step_increment
;
533 float page_step
= win
->m_vAdjust
->page_increment
;
535 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
536 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
537 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
538 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
539 else command
= wxEVT_SCROLL_THUMBTRACK
;
541 int value
= (int)(win
->m_vAdjust
->value
+0.5);
543 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
544 event
.SetEventObject( win
);
545 win
->ProcessEvent( event
);
548 //-----------------------------------------------------------------------------
551 void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
553 if (g_blockEventsOnDrag
) return;
556 printf( "OnHScroll from " );
557 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
558 printf( win->GetClassInfo()->GetClassName() );
562 if (!win
->HasVMT()) return;
564 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
565 if (fabs(diff
) < 0.2) return;
568 int i = (int)(win->m_oldHorizontalPos+0.5);
569 printf( "Old value: %d.\n", i );
570 i = (int)(win->m_hAdjust->value+0.5);
571 printf( "Sending new value: %d.\n", i );
574 wxEventType command
= wxEVT_NULL
;
576 float line_step
= win
->m_hAdjust
->step_increment
;
577 float page_step
= win
->m_hAdjust
->page_increment
;
579 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
580 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
581 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
582 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
583 else command
= wxEVT_SCROLL_THUMBTRACK
;
585 int value
= (int)(win
->m_hAdjust
->value
+0.5);
587 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
588 event
.SetEventObject( win
);
589 win
->ProcessEvent( event
);
592 //-----------------------------------------------------------------------------
593 // vertical scroll change
595 void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
597 if (g_blockEventsOnDrag
) return;
600 printf( "OnVScroll change from " );
601 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
602 printf( win->GetClassInfo()->GetClassName() );
606 if (!win
->HasVMT()) return;
608 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
609 int value
= (int)(win
->m_vAdjust
->value
+0.5);
611 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
612 event
.SetEventObject( win
);
613 win
->ProcessEvent( event
);
616 //-----------------------------------------------------------------------------
617 // horizontal scroll change
619 void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
621 if (g_blockEventsOnDrag
) return;
624 printf( "OnHScroll change from " );
625 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
626 printf( win->GetClassInfo()->GetClassName() );
630 if (!win
->HasVMT()) return;
632 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
633 int value
= (int)(win
->m_hAdjust
->value
+0.5);
635 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
636 event
.SetEventObject( win
);
637 win
->ProcessEvent( event
);
640 //-----------------------------------------------------------------------------
643 void gtk_window_drop_callback( GtkWidget
*widget
, GdkEvent
*event
, wxWindow
*win
)
645 if (!win
->HasVMT()) return;
647 if (win
->GetDropTarget())
651 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
652 win
->GetDropTarget()->Drop( event
, x
, y
);
656 g_free (event->dropdataavailable.data);
657 g_free (event->dropdataavailable.data_type);
661 //-----------------------------------------------------------------------------
664 bool gtk_window_destroy_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
666 printf( "OnDestroy from " );
667 if (win
->GetClassInfo() && win
->GetClassInfo()->GetClassName())
668 printf( win
->GetClassInfo()->GetClassName() );
670 printf( "Goodbye.\n" );
671 printf( " Robert Roebling.\n" );
676 //-----------------------------------------------------------------------------
679 bool gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
681 if (widget
->window
!= gdk_event
->window
) return TRUE
;
682 if (g_blockEventsOnDrag
) return TRUE
;
683 if (!win
->HasVMT()) return TRUE
;
686 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
688 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
689 event
.SetEventObject( win
);
690 return win
->ProcessEvent( event
);
693 //-----------------------------------------------------------------------------
696 bool gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
698 if (widget
->window
!= gdk_event
->window
) return TRUE
;
699 if (!win
->HasVMT()) return TRUE
;
700 if (g_blockEventsOnDrag
) return TRUE
;
703 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
705 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
706 event
.SetEventObject( win
);
707 return win
->ProcessEvent( event
);
710 //-----------------------------------------------------------------------------
711 // wxWindow implementation
712 //-----------------------------------------------------------------------------
714 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
716 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
717 EVT_SIZE(wxWindow::OnSize
)
718 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
719 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
720 EVT_IDLE(wxWindow::OnIdle
)
725 m_widget
= (GtkWidget
*) NULL
;
726 m_wxwindow
= (GtkWidget
*) NULL
;
727 m_parent
= (wxWindow
*) NULL
;
728 m_children
.DeleteContents( FALSE
);
734 m_eventHandler
= this;
735 m_windowValidator
= (wxValidator
*) NULL
;
737 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
738 m_font
= *wxSWISS_FONT
;
740 m_windowName
= "noname";
741 m_constraints
= (wxLayoutConstraints
*) NULL
;
742 m_constraintsInvolvedIn
= (wxList
*) NULL
;
743 m_windowSizer
= (wxSizer
*) NULL
;
744 m_sizerParent
= (wxWindow
*) NULL
;
745 m_autoLayout
= FALSE
;
749 m_hasScrolling
= FALSE
;
750 m_hAdjust
= (GtkAdjustment
*) NULL
;
751 m_vAdjust
= (GtkAdjustment
*) NULL
;
752 m_oldHorizontalPos
= 0.0;
753 m_oldVerticalPos
= 0.0;
756 m_pDropTarget
= (wxDropTarget
*) NULL
;
760 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
761 const wxPoint
&pos
, const wxSize
&size
,
762 long style
, const wxString
&name
)
768 m_cursor
= (wxCursor
*) NULL
;
770 PreCreation( parent
, id
, pos
, size
, style
, name
);
772 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
773 m_hasScrolling
= TRUE
;
775 GtkScrolledWindow
*s_window
;
776 s_window
= GTK_SCROLLED_WINDOW(m_widget
);
778 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
779 scroll_class
->scrollbar_spacing
= 0;
781 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
783 m_oldHorizontalPos
= 0.0;
784 m_oldVerticalPos
= 0.0;
786 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
787 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
789 gtk_signal_connect (GTK_OBJECT (m_hAdjust
), "value_changed",
790 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
791 gtk_signal_connect (GTK_OBJECT (m_vAdjust
), "value_changed",
792 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
794 gtk_signal_connect (GTK_OBJECT (m_hAdjust
), "changed",
795 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
796 gtk_signal_connect (GTK_OBJECT (m_vAdjust
), "changed",
797 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
799 GtkViewport
*viewport
;
800 viewport
= GTK_VIEWPORT(s_window
->viewport
);
802 if (m_windowStyle
& wxRAISED_BORDER
)
804 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
806 else if (m_windowStyle
& wxSUNKEN_BORDER
)
808 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
812 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
815 m_wxwindow
= gtk_myfixed_new();
817 if (m_wxwindow
) GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
819 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
820 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
822 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
824 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
826 // shut the viewport up
827 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
828 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
830 // I _really_ don't want scrollbars in the beginning
831 m_vAdjust
->lower
= 0.0;
832 m_vAdjust
->upper
= 1.0;
833 m_vAdjust
->value
= 0.0;
834 m_vAdjust
->step_increment
= 1.0;
835 m_vAdjust
->page_increment
= 1.0;
836 m_vAdjust
->page_size
= 5.0;
837 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
838 m_hAdjust
->lower
= 0.0;
839 m_hAdjust
->upper
= 1.0;
840 m_hAdjust
->value
= 0.0;
841 m_hAdjust
->step_increment
= 1.0;
842 m_hAdjust
->page_increment
= 1.0;
843 m_hAdjust
->page_size
= 5.0;
844 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
846 gtk_widget_show( m_wxwindow
);
855 wxWindow::~wxWindow(void)
859 if (m_pDropTarget
) delete m_pDropTarget
;
861 if (m_parent
) m_parent
->RemoveChild( this );
862 if (m_widget
) Show( FALSE
);
866 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
868 if (m_widget
) gtk_widget_destroy( m_widget
);
872 DeleteRelatedConstraints();
875 // This removes any dangling pointers to this window
876 // in other windows' constraintsInvolvedIn lists.
877 UnsetConstraints(m_constraints
);
878 delete m_constraints
;
879 m_constraints
= (wxLayoutConstraints
*) NULL
;
883 delete m_windowSizer
;
884 m_windowSizer
= (wxSizer
*) NULL
;
886 // If this is a child of a sizer, remove self from parent
887 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
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);
894 // Just in case we've loaded a top-level window via
895 // wxWindow::LoadNativeDialog but we weren't a dialog
897 wxTopLevelWindows
.DeleteObject(this);
899 if (m_windowValidator
) delete m_windowValidator
;
902 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
903 const wxPoint
&pos
, const wxSize
&size
,
904 long style
, const wxString
&name
)
906 if (m_needParent
&& (parent
== NULL
))
907 wxFatalError( _("Need complete parent."), name
);
909 m_widget
= (GtkWidget
*) NULL
;
912 m_children
.DeleteContents( FALSE
);
916 if (m_width
== -1) m_width
= 20;
918 if (m_height
== -1) m_height
= 20;
920 m_eventHandler
= this;
923 if (m_cursor
== NULL
)
924 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
925 m_font
= *wxSWISS_FONT
;
926 m_backgroundColour
= wxWHITE
;
927 m_foregroundColour
= wxBLACK
;
928 m_windowStyle
= style
;
930 m_constraints
= (wxLayoutConstraints
*) NULL
;
931 m_constraintsInvolvedIn
= (wxList
*) NULL
;
932 m_windowSizer
= (wxSizer
*) NULL
;
933 m_sizerParent
= (wxWindow
*) NULL
;
934 m_autoLayout
= FALSE
;
935 m_pDropTarget
= (wxDropTarget
*) NULL
;
937 m_windowValidator
= (wxValidator
*) NULL
;
940 void wxWindow::PostCreation(void)
942 if (m_parent
) m_parent
->AddChild( this );
944 // GtkStyle *style = m_widget->style;
945 // style->font = m_font.GetInternalFont( 1.0 ); // destroy old font ?
947 GtkWidget
*connect_widget
= GetConnectWidget();
949 gtk_object_set_data (GTK_OBJECT (connect_widget
), "MyWxWindow", (gpointer
)this );
953 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
954 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
956 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
957 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
961 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
962 GTK_SIGNAL_FUNC(gtk_window_size_callback), (gpointer)this );
965 gtk_signal_connect( GTK_OBJECT(connect_widget
), "key_press_event",
966 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
968 gtk_signal_connect( GTK_OBJECT(connect_widget
), "button_press_event",
969 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
971 gtk_signal_connect( GTK_OBJECT(connect_widget
), "button_release_event",
972 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
974 gtk_signal_connect( GTK_OBJECT(connect_widget
), "motion_notify_event",
975 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
977 gtk_signal_connect( GTK_OBJECT(connect_widget
), "focus_in_event",
978 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
980 gtk_signal_connect( GTK_OBJECT(connect_widget
), "focus_out_event",
981 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
983 // Only for cursor handling
985 gtk_signal_connect( GTK_OBJECT(m_widget
), "enter_notify_event",
986 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
988 gtk_signal_connect( GTK_OBJECT(m_widget
), "leave_notify_event",
989 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
993 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "enter_notify_event",
994 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
996 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "leave_notify_event",
997 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1001 // Does destroy ever get called ?
1003 gtk_signal_connect( GTK_OBJECT(m_widget), "destroy_event",
1004 GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this );
1008 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "destroy_event",
1009 GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this );
1013 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1017 gtk_widget_realize( m_wxwindow
);
1018 gdk_gc_set_exposures( m_wxwindow
->style
->fg_gc
[0], TRUE
);
1021 SetCursor( wxSTANDARD_CURSOR
);
1026 bool wxWindow::HasVMT(void)
1031 bool wxWindow::Close( bool force
)
1033 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1034 event
.SetEventObject(this);
1035 event
.SetForce(force
);
1037 return GetEventHandler()->ProcessEvent(event
);
1040 bool wxWindow::Destroy(void)
1047 bool wxWindow::DestroyChildren(void)
1052 while ((node
= GetChildren()->First()) != (wxNode
*)NULL
)
1055 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1058 if (GetChildren()->Member(child
)) delete node
;
1065 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1067 // are we to set fonts here ?
1070 void wxWindow::ImplementSetSize(void)
1072 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1075 void wxWindow::ImplementSetPosition(void)
1077 if (IS_KIND_OF(this,wxFrame
) || IS_KIND_OF(this,wxDialog
))
1079 if ((m_x
!= -1) || (m_y
!= -1))
1080 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
1086 wxFAIL_MSG( _("wxWindow::SetSize error.\n") );
1090 if ((m_parent
) && (m_parent
->m_wxwindow
))
1091 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1093 // Don't do anything for children of wxNotebook and wxMDIChildFrame
1096 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1098 if (m_resizing
) return; // I don't like recursions
1106 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1108 if (newX
== -1) newX
= m_x
;
1109 if (newY
== -1) newY
= m_y
;
1110 if (newW
== -1) newW
= m_width
;
1111 if (newH
== -1) newH
= m_height
;
1114 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1116 if (newW
== -1) newW
= 80;
1119 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1121 if (newH
== -1) newH
= 26;
1124 if ((m_x
!= newX
) || (m_y
!= newY
) || (!m_sizeSet
))
1128 ImplementSetPosition();
1130 if ((m_width
!= newW
) || (m_height
!= newH
) || (!m_sizeSet
))
1138 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1139 event
.SetEventObject( this );
1140 ProcessEvent( event
);
1145 void wxWindow::SetSize( int width
, int height
)
1147 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1150 void wxWindow::Move( int x
, int y
)
1152 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1155 void wxWindow::GetSize( int *width
, int *height
) const
1157 if (width
) (*width
) = m_width
;
1158 if (height
) (*height
) = m_height
;
1161 void wxWindow::SetClientSize( int width
, int height
)
1165 SetSize( width
, height
);
1172 if (!m_hasScrolling
)
1175 do we have sunken dialogs ?
1177 GtkStyleClass *window_class = m_wxwindow->style->klass;
1179 dw += 2 * window_class->xthickness;
1180 dh += 2 * window_class->ythickness;
1185 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1186 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1188 GtkWidget
*viewport
= scroll_window
->viewport
;
1189 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1191 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1192 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1194 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1195 (m_windowStyle
& wxSUNKEN_BORDER
)
1198 dw
+= 2 * viewport_class
->xthickness
;
1199 dh
+= 2 * viewport_class
->ythickness
;
1202 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1204 dw
+= vscrollbar
->allocation
.width
;
1205 dw
+= scroll_class
->scrollbar_spacing
;
1208 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1210 dh
+= hscrollbar
->allocation
.height
;
1211 dw
+= scroll_class
->scrollbar_spacing
;
1215 SetSize( width
+dw
, height
+dh
);
1219 void wxWindow::GetClientSize( int *width
, int *height
) const
1223 if (width
) (*width
) = m_width
;
1224 if (height
) (*height
) = m_height
;
1231 if (!m_hasScrolling
)
1234 do we have sunken dialogs ?
1236 GtkStyleClass *window_class = m_wxwindow->style->klass;
1238 dw += 2 * window_class->xthickness;
1239 dh += 2 * window_class->ythickness;
1244 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1245 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1247 GtkWidget
*viewport
= scroll_window
->viewport
;
1248 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1250 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1251 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1253 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1254 (m_windowStyle
& wxSUNKEN_BORDER
)
1257 dw
+= 2 * viewport_class
->xthickness
;
1258 dh
+= 2 * viewport_class
->ythickness
;
1261 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1263 // dw += vscrollbar->allocation.width;
1264 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1265 dw
+= scroll_class
->scrollbar_spacing
;
1268 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1270 // dh += hscrollbar->allocation.height;
1272 dh
+= scroll_class
->scrollbar_spacing
;
1276 if (width
) (*width
) = m_width
- dw
;
1277 if (height
) (*height
) = m_height
- dh
;
1281 void wxWindow::GetPosition( int *x
, int *y
) const
1287 void wxWindow::ClientToScreen( int *x
, int *y
)
1289 // Does this look simple ?
1291 GdkWindow
*source
= (GdkWindow
*) NULL
;
1293 source
= m_wxwindow
->window
;
1295 source
= m_widget
->window
;
1299 gdk_window_get_origin( source
, &org_x
, &org_y
);
1303 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1305 org_x
+= m_widget
->allocation
.x
;
1306 org_y
+= m_widget
->allocation
.y
;
1314 void wxWindow::ScreenToClient( int *x
, int *y
)
1316 GdkWindow
*source
= (GdkWindow
*) NULL
;
1318 source
= m_wxwindow
->window
;
1320 source
= m_widget
->window
;
1324 gdk_window_get_origin( source
, &org_x
, &org_y
);
1328 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1330 org_x
+= m_widget
->allocation
.x
;
1331 org_y
+= m_widget
->allocation
.y
;
1339 void wxWindow::Centre( int direction
)
1341 if (IS_KIND_OF(this,wxDialog
) || IS_KIND_OF(this,wxFrame
))
1343 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (gdk_screen_width () - m_width
) / 2;
1344 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (gdk_screen_height () - m_height
) / 2;
1345 ImplementSetPosition();
1353 m_parent
->GetSize( &p_w
, &p_h
);
1354 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (p_w
- m_width
) / 2;
1355 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (p_h
- m_height
) / 2;
1356 ImplementSetPosition();
1361 void wxWindow::Fit(void)
1365 wxNode
*node
= GetChildren()->First();
1368 wxWindow
*win
= (wxWindow
*)node
->Data();
1370 win
->GetPosition(&wx
, &wy
);
1371 win
->GetSize(&ww
, &wh
);
1372 if ( wx
+ ww
> maxX
)
1374 if ( wy
+ wh
> maxY
)
1377 node
= node
->Next();
1379 SetClientSize(maxX
+ 5, maxY
+ 10);
1382 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1384 //if (GetAutoLayout()) Layout();
1387 bool wxWindow::Show( bool show
)
1390 gtk_widget_show( m_widget
);
1392 gtk_widget_hide( m_widget
);
1397 void wxWindow::Enable( bool enable
)
1399 m_isEnabled
= enable
;
1400 gtk_widget_set_sensitive( m_widget
, enable
);
1401 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1404 int wxWindow::GetCharHeight(void) const
1406 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1407 return font
->ascent
+ font
->descent
;
1410 int wxWindow::GetCharWidth(void) const
1412 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1413 return gdk_string_width( font
, "H" );
1416 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1417 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1419 wxFont fontToUse
= m_font
;
1420 if (theFont
) fontToUse
= *theFont
;
1422 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1423 if (x
) (*y
) = gdk_string_width( font
, string
);
1424 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1425 if (descent
) (*descent
) = font
->descent
;
1426 if (externalLeading
) (*externalLeading
) = 0; // ??
1429 void wxWindow::MakeModal( bool modal
)
1432 // Disable all other windows
1433 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1435 wxNode
*node
= wxTopLevelWindows
.First();
1438 wxWindow
*win
= (wxWindow
*)node
->Data();
1440 win
->Enable(!modal
);
1442 node
= node
->Next();
1447 void wxWindow::SetFocus(void)
1449 GtkWidget
*connect_widget
= GetConnectWidget();
1452 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1454 gtk_widget_grab_focus (connect_widget
);
1459 bool wxWindow::OnClose(void)
1464 void wxWindow::AddChild( wxWindow
*child
)
1466 // Addchild is (often) called before the program
1467 // has left the parents constructor so that no
1468 // virtual tables work yet. The approach below
1469 // practically imitates virtual tables, i.e. it
1470 // implements a different AddChild() behaviour
1471 // for wxFrame, wxDialog, wxWindow and
1472 // wxMDIParentFrame.
1474 // wxFrame and wxDialog as children aren't placed into the parents
1476 if (( IS_KIND_OF(child
,wxFrame
) || IS_KIND_OF(child
,wxDialog
) ) &&
1477 (!IS_KIND_OF(child
,wxMDIChildFrame
)))
1479 m_children
.Append( child
);
1481 if ((child
->m_x
!= -1) && (child
->m_y
!= -1))
1482 gtk_widget_set_uposition( child
->m_widget
, child
->m_x
, child
->m_y
);
1487 // In the case of an wxMDIChildFrame descendant, we use the
1488 // client windows's AddChild()
1490 if (IS_KIND_OF(this,wxMDIParentFrame
))
1492 if (IS_KIND_OF(child
,wxMDIChildFrame
))
1494 wxMDIClientWindow
*client
= ((wxMDIParentFrame
*)this)->GetClientWindow();
1497 client
->AddChild( child
);
1503 // wxNotebook is very special, so it has a private AddChild()
1505 if (IS_KIND_OF(this,wxNotebook
))
1507 wxNotebook
*tab
= (wxNotebook
*)this;
1508 tab
->AddChild( child
);
1512 // wxFrame has a private AddChild
1514 if (IS_KIND_OF(this,wxFrame
) && !IS_KIND_OF(this,wxMDIChildFrame
))
1516 wxFrame
*frame
= (wxFrame
*)this;
1517 frame
->AddChild( child
);
1523 m_children
.Append( child
);
1524 if (m_wxwindow
) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), child
->m_widget
,
1525 child
->m_x
, child
->m_y
);
1527 gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height
);
1530 wxList
*wxWindow::GetChildren(void)
1532 return (&m_children
);
1535 void wxWindow::RemoveChild( wxWindow
*child
)
1538 GetChildren()->DeleteObject( child
);
1539 child
->m_parent
= (wxWindow
*) NULL
;
1542 void wxWindow::SetReturnCode( int retCode
)
1544 m_retCode
= retCode
;
1547 int wxWindow::GetReturnCode(void)
1552 void wxWindow::Raise(void)
1554 if (m_widget
) gdk_window_raise( m_widget
->window
);
1557 void wxWindow::Lower(void)
1559 if (m_widget
) gdk_window_lower( m_widget
->window
);
1562 wxEvtHandler
*wxWindow::GetEventHandler(void)
1564 return m_eventHandler
;
1567 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1569 m_eventHandler
= handler
;
1572 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1574 handler
->SetNextHandler(GetEventHandler());
1575 SetEventHandler(handler
);
1578 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1580 if ( GetEventHandler() )
1582 wxEvtHandler
*handlerA
= GetEventHandler();
1583 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
1584 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
1585 SetEventHandler(handlerB
);
1586 if ( deleteHandler
)
1589 return (wxEvtHandler
*) NULL
;
1595 return (wxEvtHandler
*) NULL
;
1598 wxValidator
*wxWindow::GetValidator(void)
1600 return m_windowValidator
;
1603 void wxWindow::SetValidator( const wxValidator
& validator
)
1605 if (m_windowValidator
) delete m_windowValidator
;
1606 m_windowValidator
= validator
.Clone();
1607 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
1610 bool wxWindow::IsBeingDeleted(void)
1615 void wxWindow::SetId( wxWindowID id
)
1620 wxWindowID
wxWindow::GetId(void)
1625 void wxWindow::SetCursor( const wxCursor
&cursor
)
1627 wxASSERT(m_cursor
!= NULL
);
1629 if (m_cursor
!= NULL
)
1630 if (*m_cursor
== cursor
)
1632 (*m_cursor
) = cursor
;
1633 if (m_widget
->window
)
1634 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
1635 if (m_wxwindow
&& m_wxwindow
->window
)
1636 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
1639 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
1641 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
1644 gdk_window_clear_area( m_wxwindow
->window
,
1658 GetClientSize( &w
, &h
);
1660 GdkRectangle gdk_rect
;
1664 gdk_rect
.height
= h
;
1665 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1670 GdkRectangle gdk_rect
;
1671 gdk_rect
.x
= rect
->x
;
1672 gdk_rect
.y
= rect
->y
;
1673 gdk_rect
.width
= rect
->width
;
1674 gdk_rect
.height
= rect
->height
;
1677 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1679 gtk_widget_draw( m_widget
, &gdk_rect
);
1683 bool wxWindow::IsExposed( long x
, long y
)
1685 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
1688 bool wxWindow::IsExposed( long x
, long y
, long width
, long height
)
1690 return (m_updateRegion
.Contains( x
, y
, width
, height
) != wxOutRegion
);
1693 void wxWindow::Clear(void)
1695 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
1698 wxColour
wxWindow::GetBackgroundColour(void) const
1700 return m_backgroundColour
;
1703 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
1705 m_backgroundColour
= colour
;
1708 m_backgroundColour
.CalcPixel( m_wxwindow
->style
->colormap
);
1709 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
1710 gdk_window_clear( m_wxwindow
->window
);
1715 wxColour
wxWindow::GetForegroundColour(void) const
1717 return m_foregroundColour
;
1720 void wxWindow::SetForegroundColour( const wxColour
&colour
)
1722 m_foregroundColour
= colour
;
1725 bool wxWindow::Validate(void)
1727 wxNode
*node
= GetChildren()->First();
1730 wxWindow
*child
= (wxWindow
*)node
->Data();
1731 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
1733 node
= node
->Next();
1738 bool wxWindow::TransferDataToWindow(void)
1740 wxNode
*node
= GetChildren()->First();
1743 wxWindow
*child
= (wxWindow
*)node
->Data();
1744 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
1745 !child
->GetValidator()->TransferToWindow() )
1747 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
1750 node
= node
->Next();
1755 bool wxWindow::TransferDataFromWindow(void)
1757 wxNode
*node
= GetChildren()->First();
1760 wxWindow
*child
= (wxWindow
*)node
->Data();
1761 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
1763 node
= node
->Next();
1768 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
1770 TransferDataToWindow();
1773 void wxWindow::InitDialog(void)
1775 wxInitDialogEvent
event(GetId());
1776 event
.SetEventObject( this );
1777 GetEventHandler()->ProcessEvent(event
);
1780 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
1782 menu
->SetInvokingWindow( win
);
1783 wxNode
*node
= menu
->m_items
.First();
1786 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
1787 if (menuitem
->IsSubMenu())
1788 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
1789 node
= node
->Next();
1793 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
1795 SetInvokingWindow( menu
, this );
1796 gtk_menu_popup( GTK_MENU(menu
->m_menu
), (GtkWidget
*) NULL
, (GtkWidget
*) NULL
, (GtkMenuPositionFunc
) NULL
, NULL
, 0, 0 );
1800 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
1802 GtkWidget
*dnd_widget
= GetConnectWidget();
1806 gtk_signal_disconnect_by_func( GTK_OBJECT(dnd_widget
),
1807 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
1809 m_pDropTarget
->UnregisterWidget( dnd_widget
);
1810 delete m_pDropTarget
;
1812 m_pDropTarget
= dropTarget
;
1815 m_pDropTarget
->RegisterWidget( dnd_widget
);
1817 gtk_signal_connect( GTK_OBJECT(dnd_widget
), "drop_data_available_event",
1818 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
1822 wxDropTarget
*wxWindow::GetDropTarget() const
1824 return m_pDropTarget
;
1827 GtkWidget
* wxWindow::GetConnectWidget(void)
1829 GtkWidget
*connect_widget
= m_widget
;
1830 if (m_wxwindow
) connect_widget
= m_wxwindow
;
1832 return connect_widget
;
1835 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
1837 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
1838 return (window
== m_widget
->window
);
1841 void wxWindow::SetFont( const wxFont
&font
)
1846 copy old style values to new one
1847 set font in new style
1848 -> takes to many resources
1850 GtkStyle *style = gtk_style_new();
1855 wxFont
*wxWindow::GetFont(void)
1860 void wxWindow::SetWindowStyleFlag( long flag
)
1862 m_windowStyle
= flag
;
1865 long wxWindow::GetWindowStyleFlag(void) const
1867 return m_windowStyle
;
1870 void wxWindow::CaptureMouse(void)
1872 GtkWidget
*connect_widget
= GetConnectWidget();
1873 gtk_grab_add( connect_widget
);
1874 gdk_pointer_grab ( connect_widget
->window
, FALSE
,
1876 (GDK_BUTTON_PRESS_MASK
|
1877 GDK_BUTTON_RELEASE_MASK
|
1878 GDK_POINTER_MOTION_MASK
),
1879 (GdkWindow
*) NULL
, (GdkCursor
*) NULL
, GDK_CURRENT_TIME
);
1882 void wxWindow::ReleaseMouse(void)
1884 GtkWidget
*connect_widget
= GetConnectWidget();
1885 gtk_grab_remove( connect_widget
);
1886 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
1889 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
1893 wxString
wxWindow::GetTitle(void) const
1895 return (wxString
&)m_windowName
;
1898 wxString
wxWindow::GetLabel(void) const
1903 void wxWindow::SetName( const wxString
&name
)
1905 m_windowName
= name
;
1908 wxString
wxWindow::GetName(void) const
1910 return (wxString
&)m_windowName
;
1913 bool wxWindow::IsShown(void) const
1918 bool wxWindow::IsRetained(void)
1923 wxWindow
*wxWindow::FindWindow( long id
)
1925 if (id
== m_windowId
) return this;
1926 wxNode
*node
= m_children
.First();
1929 wxWindow
*child
= (wxWindow
*)node
->Data();
1930 wxWindow
*res
= child
->FindWindow( id
);
1931 if (res
) return res
;
1932 node
= node
->Next();
1934 return (wxWindow
*) NULL
;
1937 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
1939 if (name
== m_windowName
) return this;
1940 wxNode
*node
= m_children
.First();
1943 wxWindow
*child
= (wxWindow
*)node
->Data();
1944 wxWindow
*res
= child
->FindWindow( name
);
1945 if (res
) return res
;
1946 node
= node
->Next();
1948 return (wxWindow
*) NULL
;
1951 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
1952 int range
, bool WXUNUSED(refresh
) )
1954 if (!m_wxwindow
) return;
1956 if (orient
== wxHORIZONTAL
)
1958 float fpos
= (float)pos
;
1959 m_oldHorizontalPos
= fpos
;
1960 float frange
= (float)range
;
1961 float fthumb
= (float)thumbVisible
;
1963 if ((fabs(fpos
-m_hAdjust
->value
) < 0.2) &&
1964 (fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
1965 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
1968 m_hAdjust
->lower
= 0.0;
1969 m_hAdjust
->upper
= frange
;
1970 m_hAdjust
->value
= fpos
;
1971 m_hAdjust
->step_increment
= 1.0;
1972 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
-2,0));
1973 m_hAdjust
->page_size
= fthumb
;
1977 float fpos
= (float)pos
;
1978 m_oldVerticalPos
= fpos
;
1979 float frange
= (float)range
;
1980 float fthumb
= (float)thumbVisible
;
1982 if ((fabs(fpos
-m_vAdjust
->value
) < 0.2) &&
1983 (fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
1984 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
1987 m_vAdjust
->lower
= 0.0;
1988 m_vAdjust
->upper
= frange
;
1989 m_vAdjust
->value
= fpos
;
1990 m_vAdjust
->step_increment
= 1.0;
1991 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
-2,0));
1992 m_vAdjust
->page_size
= fthumb
;
1995 if (m_wxwindow
->window
)
1997 if (orient
== wxHORIZONTAL
)
1998 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2000 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2002 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2006 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2008 if (!m_wxwindow
) return;
2010 if (orient
== wxHORIZONTAL
)
2012 float fpos
= (float)pos
;
2013 m_oldHorizontalPos
= fpos
;
2015 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2016 m_hAdjust
->value
= fpos
;
2020 float fpos
= (float)pos
;
2021 m_oldVerticalPos
= fpos
;
2022 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2023 m_vAdjust
->value
= fpos
;
2026 if (m_wxwindow
->window
)
2028 if (orient
== wxHORIZONTAL
)
2029 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2031 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2035 int wxWindow::GetScrollThumb( int orient
) const
2037 if (!m_wxwindow
) return 0;
2039 if (orient
== wxHORIZONTAL
)
2040 return (int)(m_hAdjust
->page_size
+0.5);
2042 return (int)(m_vAdjust
->page_size
+0.5);
2045 int wxWindow::GetScrollPos( int orient
) const
2047 if (!m_wxwindow
) return 0;
2049 if (orient
== wxHORIZONTAL
)
2050 return (int)(m_hAdjust
->value
+0.5);
2052 return (int)(m_vAdjust
->value
+0.5);
2055 int wxWindow::GetScrollRange( int orient
) const
2057 if (!m_wxwindow
) return 0;
2059 if (orient
== wxHORIZONTAL
)
2060 return (int)(m_hAdjust
->upper
+0.5);
2062 return (int)(m_vAdjust
->upper
+0.5);
2065 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2067 if (!m_wxwindow
) return;
2070 bool refresh = FALSE;
2072 if ((m_drawingOffsetX == 0) && (m_drawingOffsetY == 0))
2074 m_drawingOffsetX = -16000;
2075 m_drawingOffsetY = -16000;
2080 m_drawingOffsetX += dx;
2081 m_drawingOffsetY += dy;
2084 // printf( "X: %d Y: %d \n", (int)m_drawingOffsetX, (int)m_drawingOffsetY );
2086 gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
2088 if (refresh) Refresh();
2090 The code here is very nifty, but it doesn't work with
2091 overlapping windows...
2096 GetClientSize( &cw
, &ch
);
2098 int w
= cw
- abs(dx
);
2099 int h
= ch
- abs(dy
);
2100 if ((h
< 0) || (w
< 0))
2107 if (dx
< 0) s_x
= -dx
;
2108 if (dy
< 0) s_y
= -dy
;
2111 if (dx
> 0) d_x
= dx
;
2112 if (dy
> 0) d_y
= dy
;
2113 gdk_window_copy_area( m_wxwindow
->window
, m_wxwindow
->style
->fg_gc
[0], d_x
, d_y
,
2114 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2117 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2118 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2119 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2120 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2122 Refresh( TRUE
, &rect
);
2125 //-------------------------------------------------------------------------------------
2127 //-------------------------------------------------------------------------------------
2129 wxLayoutConstraints
*wxWindow::GetConstraints(void) const
2131 return m_constraints
;
2134 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2138 UnsetConstraints(m_constraints
);
2139 delete m_constraints
;
2141 m_constraints
= constraints
;
2144 // Make sure other windows know they're part of a 'meaningful relationship'
2145 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2146 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2147 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2148 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2149 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2150 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2151 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2152 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2153 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2154 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2155 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2156 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2157 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2158 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2159 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2160 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2166 void wxWindow::SetAutoLayout( bool autoLayout
)
2168 m_autoLayout
= autoLayout
;
2171 bool wxWindow::GetAutoLayout(void) const
2173 return m_autoLayout
;
2176 wxSizer
*wxWindow::GetSizer(void) const
2178 return m_windowSizer
;
2181 void wxWindow::SetSizerParent( wxWindow
*win
)
2183 m_sizerParent
= win
;
2186 wxWindow
*wxWindow::GetSizerParent(void) const
2188 return m_sizerParent
;
2191 // This removes any dangling pointers to this window
2192 // in other windows' constraintsInvolvedIn lists.
2193 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2197 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2198 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2199 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2200 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2201 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2202 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2203 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2204 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2205 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2206 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2207 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2208 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2209 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2210 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2211 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2212 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2216 // Back-pointer to other windows we're involved with, so if we delete
2217 // this window, we must delete any constraints we're involved with.
2218 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2220 if (!m_constraintsInvolvedIn
)
2221 m_constraintsInvolvedIn
= new wxList
;
2222 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2223 m_constraintsInvolvedIn
->Append(otherWin
);
2226 // REMOVE back-pointer to other windows we're involved with.
2227 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2229 if (m_constraintsInvolvedIn
)
2230 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2233 // Reset any constraints that mention this window
2234 void wxWindow::DeleteRelatedConstraints(void)
2236 if (m_constraintsInvolvedIn
)
2238 wxNode
*node
= m_constraintsInvolvedIn
->First();
2241 wxWindow
*win
= (wxWindow
*)node
->Data();
2242 wxNode
*next
= node
->Next();
2243 wxLayoutConstraints
*constr
= win
->GetConstraints();
2245 // Reset any constraints involving this window
2248 constr
->left
.ResetIfWin((wxWindow
*)this);
2249 constr
->top
.ResetIfWin((wxWindow
*)this);
2250 constr
->right
.ResetIfWin((wxWindow
*)this);
2251 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2252 constr
->width
.ResetIfWin((wxWindow
*)this);
2253 constr
->height
.ResetIfWin((wxWindow
*)this);
2254 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2255 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2260 delete m_constraintsInvolvedIn
;
2261 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2265 void wxWindow::SetSizer(wxSizer
*sizer
)
2267 m_windowSizer
= sizer
;
2269 sizer
->SetSizerParent((wxWindow
*)this);
2276 bool wxWindow::Layout(void)
2278 if (GetConstraints())
2281 GetClientSize(&w
, &h
);
2282 GetConstraints()->width
.SetValue(w
);
2283 GetConstraints()->height
.SetValue(h
);
2286 // If top level (one sizer), evaluate the sizer's constraints.
2290 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2291 GetSizer()->LayoutPhase1(&noChanges
);
2292 GetSizer()->LayoutPhase2(&noChanges
);
2293 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2298 // Otherwise, evaluate child constraints
2299 ResetConstraints(); // Mark all constraints as unevaluated
2300 DoPhase(1); // Just one phase need if no sizers involved
2302 SetConstraintSizes(); // Recursively set the real window sizes
2308 // Do a phase of evaluating constraints:
2309 // the default behaviour. wxSizers may do a similar
2310 // thing, but also impose their own 'constraints'
2311 // and order the evaluation differently.
2312 bool wxWindow::LayoutPhase1(int *noChanges
)
2314 wxLayoutConstraints
*constr
= GetConstraints();
2317 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2323 bool wxWindow::LayoutPhase2(int *noChanges
)
2333 // Do a phase of evaluating child constraints
2334 bool wxWindow::DoPhase(int phase
)
2336 int noIterations
= 0;
2337 int maxIterations
= 500;
2341 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2345 wxNode
*node
= GetChildren()->First();
2348 wxWindow
*child
= (wxWindow
*)node
->Data();
2349 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2351 wxLayoutConstraints
*constr
= child
->GetConstraints();
2354 if (succeeded
.Member(child
))
2359 int tempNoChanges
= 0;
2360 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2361 noChanges
+= tempNoChanges
;
2364 succeeded
.Append(child
);
2369 node
= node
->Next();
2376 void wxWindow::ResetConstraints(void)
2378 wxLayoutConstraints
*constr
= GetConstraints();
2381 constr
->left
.SetDone(FALSE
);
2382 constr
->top
.SetDone(FALSE
);
2383 constr
->right
.SetDone(FALSE
);
2384 constr
->bottom
.SetDone(FALSE
);
2385 constr
->width
.SetDone(FALSE
);
2386 constr
->height
.SetDone(FALSE
);
2387 constr
->centreX
.SetDone(FALSE
);
2388 constr
->centreY
.SetDone(FALSE
);
2390 wxNode
*node
= GetChildren()->First();
2393 wxWindow
*win
= (wxWindow
*)node
->Data();
2394 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2395 win
->ResetConstraints();
2396 node
= node
->Next();
2400 // Need to distinguish between setting the 'fake' size for
2401 // windows and sizers, and setting the real values.
2402 void wxWindow::SetConstraintSizes(bool recurse
)
2404 wxLayoutConstraints
*constr
= GetConstraints();
2405 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2406 constr
->width
.GetDone() && constr
->height
.GetDone())
2408 int x
= constr
->left
.GetValue();
2409 int y
= constr
->top
.GetValue();
2410 int w
= constr
->width
.GetValue();
2411 int h
= constr
->height
.GetValue();
2413 // If we don't want to resize this window, just move it...
2414 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2415 (constr
->height
.GetRelationship() != wxAsIs
))
2417 // Calls Layout() recursively. AAAGH. How can we stop that.
2418 // Simply take Layout() out of non-top level OnSizes.
2419 SizerSetSize(x
, y
, w
, h
);
2428 char *windowClass
= this->GetClassInfo()->GetClassName();
2431 if (GetName() == "")
2432 winName
= _("unnamed");
2434 winName
= GetName();
2435 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass
, (const char *)winName
);
2436 if (!constr
->left
.GetDone())
2437 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
2438 if (!constr
->right
.GetDone())
2439 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
2440 if (!constr
->width
.GetDone())
2441 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
2442 if (!constr
->height
.GetDone())
2443 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2444 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
2449 wxNode
*node
= GetChildren()->First();
2452 wxWindow
*win
= (wxWindow
*)node
->Data();
2453 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2454 win
->SetConstraintSizes();
2455 node
= node
->Next();
2460 // This assumes that all sizers are 'on' the same
2461 // window, i.e. the parent of this window.
2462 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
2464 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
2465 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
2469 m_sizerParent
->GetPosition(&xp
, &yp
);
2470 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
2475 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
2479 TransformSizerToActual(&xx
, &yy
);
2480 SetSize(xx
, yy
, w
, h
);
2483 void wxWindow::SizerMove(int x
, int y
)
2487 TransformSizerToActual(&xx
, &yy
);
2491 // Only set the size/position of the constraint (if any)
2492 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
2494 wxLayoutConstraints
*constr
= GetConstraints();
2499 constr
->left
.SetValue(x
);
2500 constr
->left
.SetDone(TRUE
);
2504 constr
->top
.SetValue(y
);
2505 constr
->top
.SetDone(TRUE
);
2509 constr
->width
.SetValue(w
);
2510 constr
->width
.SetDone(TRUE
);
2514 constr
->height
.SetValue(h
);
2515 constr
->height
.SetDone(TRUE
);
2520 void wxWindow::MoveConstraint(int x
, int y
)
2522 wxLayoutConstraints
*constr
= GetConstraints();
2527 constr
->left
.SetValue(x
);
2528 constr
->left
.SetDone(TRUE
);
2532 constr
->top
.SetValue(y
);
2533 constr
->top
.SetDone(TRUE
);
2538 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
2540 wxLayoutConstraints
*constr
= GetConstraints();
2543 *w
= constr
->width
.GetValue();
2544 *h
= constr
->height
.GetValue();
2550 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
2552 wxLayoutConstraints
*constr
= GetConstraints();
2555 *w
= constr
->width
.GetValue();
2556 *h
= constr
->height
.GetValue();
2559 GetClientSize(w
, h
);
2562 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
2564 wxLayoutConstraints
*constr
= GetConstraints();
2567 *x
= constr
->left
.GetValue();
2568 *y
= constr
->top
.GetValue();
2574 bool wxWindow::AcceptsFocus() const
2576 return IsEnabled() && IsShown();
2579 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )