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 // "expose_event" (of m_wxwindow, not of m_widget)
47 //-----------------------------------------------------------------------------
49 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
51 if (!win
->HasVMT()) return;
52 if (g_blockEventsOnDrag
) return;
54 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
56 gdk_event
->area
.width
,
57 gdk_event
->area
.height
);
59 if (gdk_event
->count
> 0) return;
61 wxPaintEvent
event( win
->GetId() );
62 event
.SetEventObject( win
);
63 win
->GetEventHandler()->ProcessEvent( event
);
65 win
->m_updateRegion
.Clear();
68 //-----------------------------------------------------------------------------
69 // "draw" (of m_wxwindow, not of m_widget)
70 //-----------------------------------------------------------------------------
72 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
74 if (!win
->HasVMT()) return;
75 if (g_blockEventsOnDrag
) return;
77 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
79 wxPaintEvent
event( win
->GetId() );
80 event
.SetEventObject( win
);
81 win
->GetEventHandler()->ProcessEvent( event
);
83 win
->m_updateRegion
.Clear();
86 //-----------------------------------------------------------------------------
88 //-----------------------------------------------------------------------------
90 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
92 if (!win
->HasVMT()) return FALSE
;
93 if (g_blockEventsOnDrag
) return FALSE
;
96 printf( "OnKeyPress from " );
97 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
98 printf( win->GetClassInfo()->GetClassName() );
103 switch (gdk_event
->keyval
)
105 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
106 case GDK_Tab
: key_code
= WXK_TAB
; break;
107 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
108 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
109 case GDK_Return
: key_code
= WXK_RETURN
; break;
110 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
111 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
112 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
113 case GDK_Delete
: key_code
= WXK_DELETE
; break;
114 case GDK_Home
: key_code
= WXK_HOME
; break;
115 case GDK_Left
: key_code
= WXK_LEFT
; break;
116 case GDK_Up
: key_code
= WXK_UP
; break;
117 case GDK_Right
: key_code
= WXK_RIGHT
; break;
118 case GDK_Down
: key_code
= WXK_DOWN
; break;
119 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
120 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
121 case GDK_Next
: key_code
= WXK_NEXT
; break;
122 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
123 case GDK_End
: key_code
= WXK_END
; break;
124 case GDK_Begin
: key_code
= WXK_HOME
; break;
125 case GDK_Select
: key_code
= WXK_SELECT
; break;
126 case GDK_Print
: key_code
= WXK_PRINT
; break;
127 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
128 case GDK_Insert
: key_code
= WXK_INSERT
; break;
129 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
130 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
131 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
132 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
133 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
134 case GDK_KP_Up
: key_code
= WXK_UP
; break;
135 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
136 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
137 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
138 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
139 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
140 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
141 case GDK_KP_End
: key_code
= WXK_END
; break;
142 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
143 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
144 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
145 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
146 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
147 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
148 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
149 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
150 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
151 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
152 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
153 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
154 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
155 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
156 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
157 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
158 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
159 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
160 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
161 case GDK_F1
: key_code
= WXK_F1
; break;
162 case GDK_F2
: key_code
= WXK_F2
; break;
163 case GDK_F3
: key_code
= WXK_F3
; break;
164 case GDK_F4
: key_code
= WXK_F4
; break;
165 case GDK_F5
: key_code
= WXK_F5
; break;
166 case GDK_F6
: key_code
= WXK_F6
; break;
167 case GDK_F7
: key_code
= WXK_F7
; break;
168 case GDK_F8
: key_code
= WXK_F8
; break;
169 case GDK_F9
: key_code
= WXK_F9
; break;
170 case GDK_F10
: key_code
= WXK_F10
; break;
171 case GDK_F11
: key_code
= WXK_F11
; break;
172 case GDK_F12
: key_code
= WXK_F12
; break;
175 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
176 key_code
= gdk_event
->keyval
;
180 if (!key_code
) return FALSE
;
182 wxKeyEvent
event( wxEVT_CHAR
);
183 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
184 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
185 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
186 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
187 event
.m_keyCode
= key_code
;
190 event
.SetEventObject( win
);
192 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
196 wxWindow
*ancestor
= win
;
199 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
202 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
203 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
206 ancestor
= ancestor
->GetParent();
212 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
213 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
219 //-----------------------------------------------------------------------------
220 // "button_press_event"
221 //-----------------------------------------------------------------------------
223 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
225 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
227 if (g_blockEventsOnDrag
) return TRUE
;
231 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
233 gtk_widget_grab_focus (win
->m_wxwindow
);
236 printf( "GrabFocus from " );
237 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
238 printf( win->GetClassInfo()->GetClassName() );
245 if (!win
->HasVMT()) return TRUE
;
248 printf( "OnButtonPress from " );
249 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
250 printf( win->GetClassInfo()->GetClassName() );
254 wxEventType event_type
= wxEVT_LEFT_DOWN
;
256 if (gdk_event
->button
== 1)
258 switch (gdk_event
->type
)
260 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
261 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
265 else if (gdk_event
->button
== 2)
267 switch (gdk_event
->type
)
269 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
270 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
274 else if (gdk_event
->button
== 3)
276 switch (gdk_event
->type
)
278 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
279 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
284 wxMouseEvent
event( event_type
);
285 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
286 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
287 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
288 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
289 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
290 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
291 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
293 event
.m_x
= (long)gdk_event
->x
;
294 event
.m_y
= (long)gdk_event
->y
;
296 // Some control don't have their own X window and thus cannot get
299 wxNode
*node
= win
->GetChildren()->First();
302 wxWindow
*child
= (wxWindow
*)node
->Data();
303 if ((child
->m_x
<= event
.m_x
) &&
304 (child
->m_y
<= event
.m_y
) &&
305 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
306 (child
->m_y
+child
->m_height
>= event
.m_y
))
309 event
.m_x
-= child
->m_x
;
310 event
.m_y
-= child
->m_y
;
316 event
.SetEventObject( win
);
318 if (win
->GetEventHandler()->ProcessEvent( event
))
319 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
324 //-----------------------------------------------------------------------------
326 //-----------------------------------------------------------------------------
328 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
330 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
331 if (g_blockEventsOnDrag
) return TRUE
;
333 if (!win
->HasVMT()) return TRUE
;
336 printf( "OnButtonRelease from " );
337 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
338 printf( win->GetClassInfo()->GetClassName() );
342 wxEventType event_type
= wxEVT_NULL
;
344 switch (gdk_event
->button
)
346 case 1: event_type
= wxEVT_LEFT_UP
; break;
347 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
348 case 3: event_type
= wxEVT_RIGHT_UP
; break;
351 wxMouseEvent
event( event_type
);
352 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
353 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
354 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
355 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
356 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
357 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
358 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
359 event
.m_x
= (long)gdk_event
->x
;
360 event
.m_y
= (long)gdk_event
->y
;
362 // Some control don't have their own X window and thus cannot get
365 wxNode
*node
= win
->GetChildren()->First();
368 wxWindow
*child
= (wxWindow
*)node
->Data();
369 if ((child
->m_x
<= event
.m_x
) &&
370 (child
->m_y
<= event
.m_y
) &&
371 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
372 (child
->m_y
+child
->m_height
>= event
.m_y
))
375 event
.m_x
-= child
->m_x
;
376 event
.m_y
-= child
->m_y
;
382 event
.SetEventObject( win
);
384 if (win
->GetEventHandler()->ProcessEvent( event
))
385 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
390 //-----------------------------------------------------------------------------
391 // "motion_notify_event"
392 //-----------------------------------------------------------------------------
394 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
396 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
397 if (g_blockEventsOnDrag
) return TRUE
;
399 if (!win
->HasVMT()) return TRUE
;
402 printf( "OnMotion from " );
403 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
404 printf( win->GetClassInfo()->GetClassName() );
408 wxMouseEvent
event( wxEVT_MOTION
);
409 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
410 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
411 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
412 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
413 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
414 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
415 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
417 event
.m_x
= (long)gdk_event
->x
;
418 event
.m_y
= (long)gdk_event
->y
;
420 // Some control don't have their own X window and thus cannot get
423 wxNode
*node
= win
->GetChildren()->First();
426 wxWindow
*child
= (wxWindow
*)node
->Data();
427 if ((child
->m_x
<= event
.m_x
) &&
428 (child
->m_y
<= event
.m_y
) &&
429 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
430 (child
->m_y
+child
->m_height
>= event
.m_y
))
433 event
.m_x
-= child
->m_x
;
434 event
.m_y
-= child
->m_y
;
440 event
.SetEventObject( win
);
442 if (win
->GetEventHandler()->ProcessEvent( event
))
443 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
448 //-----------------------------------------------------------------------------
450 //-----------------------------------------------------------------------------
452 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
454 if (g_blockEventsOnDrag
) return TRUE
;
457 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
459 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
461 printf( "SetFocus flag from " );
462 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
463 printf( win->GetClassInfo()->GetClassName() );
469 if (!win
->HasVMT()) return TRUE
;
472 printf( "OnSetFocus from " );
473 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
474 printf( win->GetClassInfo()->GetClassName() );
476 printf( WXSTRINGCAST win->GetLabel() );
480 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
481 event
.SetEventObject( win
);
483 if (win
->GetEventHandler()->ProcessEvent( event
))
484 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
489 //-----------------------------------------------------------------------------
491 //-----------------------------------------------------------------------------
493 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
495 if (g_blockEventsOnDrag
) return TRUE
;
498 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
499 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
502 if (!win
->HasVMT()) return TRUE
;
505 printf( "OnKillFocus from " );
506 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
507 printf( win->GetClassInfo()->GetClassName() );
511 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
512 event
.SetEventObject( win
);
514 if (win
->GetEventHandler()->ProcessEvent( event
))
515 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
520 //-----------------------------------------------------------------------------
521 // "value_changed" from m_vAdjust
522 //-----------------------------------------------------------------------------
524 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
526 if (g_blockEventsOnDrag
) return;
529 printf( "OnVScroll from " );
530 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
531 printf( win->GetClassInfo()->GetClassName() );
535 if (!win
->HasVMT()) return;
537 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
538 if (fabs(diff
) < 0.2) return;
540 wxEventType command
= wxEVT_NULL
;
542 float line_step
= win
->m_vAdjust
->step_increment
;
543 float page_step
= win
->m_vAdjust
->page_increment
;
545 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
546 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
547 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
548 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
549 else command
= wxEVT_SCROLL_THUMBTRACK
;
551 int value
= (int)(win
->m_vAdjust
->value
+0.5);
553 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
554 event
.SetEventObject( win
);
555 win
->GetEventHandler()->ProcessEvent( event
);
558 //-----------------------------------------------------------------------------
559 // "value_changed" from m_hAdjust
560 //-----------------------------------------------------------------------------
562 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
564 if (g_blockEventsOnDrag
) return;
567 printf( "OnHScroll from " );
568 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
569 printf( win->GetClassInfo()->GetClassName() );
573 if (!win
->HasVMT()) return;
575 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
576 if (fabs(diff
) < 0.2) return;
578 wxEventType command
= wxEVT_NULL
;
580 float line_step
= win
->m_hAdjust
->step_increment
;
581 float page_step
= win
->m_hAdjust
->page_increment
;
583 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
584 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
585 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
586 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
587 else command
= wxEVT_SCROLL_THUMBTRACK
;
589 int value
= (int)(win
->m_hAdjust
->value
+0.5);
591 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
592 event
.SetEventObject( win
);
593 win
->GetEventHandler()->ProcessEvent( event
);
596 //-----------------------------------------------------------------------------
597 // "changed" from m_vAdjust
598 //-----------------------------------------------------------------------------
600 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
602 if (g_blockEventsOnDrag
) return;
605 printf( "OnVScroll change from " );
606 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
607 printf( win->GetClassInfo()->GetClassName() );
611 if (!win
->HasVMT()) return;
613 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
614 int value
= (int)(win
->m_vAdjust
->value
+0.5);
616 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
617 event
.SetEventObject( win
);
618 win
->GetEventHandler()->ProcessEvent( event
);
621 //-----------------------------------------------------------------------------
622 // "changed" from m_hAdjust
623 //-----------------------------------------------------------------------------
625 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
627 if (g_blockEventsOnDrag
) return;
630 printf( "OnHScroll change from " );
631 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
632 printf( win->GetClassInfo()->GetClassName() );
636 if (!win
->HasVMT()) return;
638 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
639 int value
= (int)(win
->m_hAdjust
->value
+0.5);
641 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
642 event
.SetEventObject( win
);
643 win
->GetEventHandler()->ProcessEvent( event
);
646 //-----------------------------------------------------------------------------
647 // "drop_data_available_event"
648 //-----------------------------------------------------------------------------
650 static void gtk_window_drop_callback( GtkWidget
*widget
, GdkEvent
*event
, wxWindow
*win
)
652 if (!win
->HasVMT()) return;
654 if (win
->GetDropTarget())
658 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
659 win
->GetDropTarget()->Drop( event
, x
, y
);
663 g_free (event->dropdataavailable.data);
664 g_free (event->dropdataavailable.data_type);
668 //-----------------------------------------------------------------------------
669 // "enter_notify_event"
670 //-----------------------------------------------------------------------------
672 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
674 if (widget
->window
!= gdk_event
->window
) return TRUE
;
675 if (g_blockEventsOnDrag
) return TRUE
;
676 if (!win
->HasVMT()) return TRUE
;
679 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
681 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
682 event
.SetEventObject( win
);
683 return win
->GetEventHandler()->ProcessEvent( event
);
686 //-----------------------------------------------------------------------------
687 // "leave_notify_event"
688 //-----------------------------------------------------------------------------
690 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
692 if (widget
->window
!= gdk_event
->window
) return TRUE
;
693 if (!win
->HasVMT()) return TRUE
;
694 if (g_blockEventsOnDrag
) return TRUE
;
697 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
699 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
700 event
.SetEventObject( win
);
701 return win
->GetEventHandler()->ProcessEvent( event
);
704 //-----------------------------------------------------------------------------
706 //-----------------------------------------------------------------------------
708 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
710 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
711 EVT_SIZE(wxWindow::OnSize
)
712 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
713 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
714 EVT_IDLE(wxWindow::OnIdle
)
719 m_widget
= (GtkWidget
*) NULL
;
720 m_wxwindow
= (GtkWidget
*) NULL
;
721 m_parent
= (wxWindow
*) NULL
;
722 m_children
.DeleteContents( FALSE
);
732 m_eventHandler
= this;
733 m_windowValidator
= (wxValidator
*) NULL
;
735 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
736 m_font
= *wxSWISS_FONT
;
738 m_windowName
= "noname";
739 m_constraints
= (wxLayoutConstraints
*) NULL
;
740 m_constraintsInvolvedIn
= (wxList
*) NULL
;
741 m_windowSizer
= (wxSizer
*) NULL
;
742 m_sizerParent
= (wxWindow
*) NULL
;
743 m_autoLayout
= FALSE
;
747 m_hasScrolling
= FALSE
;
748 m_hAdjust
= (GtkAdjustment
*) NULL
;
749 m_vAdjust
= (GtkAdjustment
*) NULL
;
750 m_oldHorizontalPos
= 0.0;
751 m_oldVerticalPos
= 0.0;
754 m_pDropTarget
= (wxDropTarget
*) NULL
;
758 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
759 const wxPoint
&pos
, const wxSize
&size
,
760 long style
, const wxString
&name
)
766 m_cursor
= (wxCursor
*) NULL
;
768 PreCreation( parent
, id
, pos
, size
, style
, name
);
770 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
771 m_hasScrolling
= TRUE
;
773 GtkScrolledWindow
*s_window
;
774 s_window
= GTK_SCROLLED_WINDOW(m_widget
);
776 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
777 scroll_class
->scrollbar_spacing
= 0;
779 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
781 m_oldHorizontalPos
= 0.0;
782 m_oldVerticalPos
= 0.0;
784 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
785 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
787 gtk_signal_connect (GTK_OBJECT (m_hAdjust
), "value_changed",
788 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
789 gtk_signal_connect (GTK_OBJECT (m_vAdjust
), "value_changed",
790 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
792 gtk_signal_connect (GTK_OBJECT (m_hAdjust
), "changed",
793 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
794 gtk_signal_connect (GTK_OBJECT (m_vAdjust
), "changed",
795 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
797 GtkViewport
*viewport
;
798 viewport
= GTK_VIEWPORT(s_window
->viewport
);
800 if (m_windowStyle
& wxRAISED_BORDER
)
802 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
804 else if (m_windowStyle
& wxSUNKEN_BORDER
)
806 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
810 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
813 m_wxwindow
= gtk_myfixed_new();
815 if (m_wxwindow
) GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
817 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
818 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
820 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
822 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
824 // shut the viewport up
825 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
826 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
828 // I _really_ don't want scrollbars in the beginning
829 m_vAdjust
->lower
= 0.0;
830 m_vAdjust
->upper
= 1.0;
831 m_vAdjust
->value
= 0.0;
832 m_vAdjust
->step_increment
= 1.0;
833 m_vAdjust
->page_increment
= 1.0;
834 m_vAdjust
->page_size
= 5.0;
835 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
836 m_hAdjust
->lower
= 0.0;
837 m_hAdjust
->upper
= 1.0;
838 m_hAdjust
->value
= 0.0;
839 m_hAdjust
->step_increment
= 1.0;
840 m_hAdjust
->page_increment
= 1.0;
841 m_hAdjust
->page_size
= 5.0;
842 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
844 gtk_widget_show( m_wxwindow
);
853 wxWindow::~wxWindow(void)
857 if (m_pDropTarget
) delete m_pDropTarget
;
859 if (m_parent
) m_parent
->RemoveChild( this );
860 if (m_widget
) Show( FALSE
);
864 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
866 if (m_widget
) gtk_widget_destroy( m_widget
);
870 DeleteRelatedConstraints();
873 // This removes any dangling pointers to this window
874 // in other windows' constraintsInvolvedIn lists.
875 UnsetConstraints(m_constraints
);
876 delete m_constraints
;
877 m_constraints
= (wxLayoutConstraints
*) NULL
;
881 delete m_windowSizer
;
882 m_windowSizer
= (wxSizer
*) NULL
;
884 // If this is a child of a sizer, remove self from parent
885 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
887 // Just in case the window has been Closed, but
888 // we're then deleting immediately: don't leave
889 // dangling pointers.
890 wxPendingDelete
.DeleteObject(this);
892 // Just in case we've loaded a top-level window via
893 // wxWindow::LoadNativeDialog but we weren't a dialog
895 wxTopLevelWindows
.DeleteObject(this);
897 if (m_windowValidator
) delete m_windowValidator
;
900 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
901 const wxPoint
&pos
, const wxSize
&size
,
902 long style
, const wxString
&name
)
904 if (m_needParent
&& (parent
== NULL
))
905 wxFatalError( "Need complete parent.", name
);
907 m_widget
= (GtkWidget
*) NULL
;
910 m_children
.DeleteContents( FALSE
);
914 if (m_width
== -1) m_width
= 20;
916 if (m_height
== -1) m_height
= 20;
922 m_eventHandler
= this;
925 if (m_cursor
== NULL
)
926 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
927 m_font
= *wxSWISS_FONT
;
928 m_backgroundColour
= wxWHITE
;
929 m_foregroundColour
= wxBLACK
;
930 m_windowStyle
= style
;
932 m_constraints
= (wxLayoutConstraints
*) NULL
;
933 m_constraintsInvolvedIn
= (wxList
*) NULL
;
934 m_windowSizer
= (wxSizer
*) NULL
;
935 m_sizerParent
= (wxWindow
*) NULL
;
936 m_autoLayout
= FALSE
;
937 m_pDropTarget
= (wxDropTarget
*) NULL
;
939 m_windowValidator
= (wxValidator
*) NULL
;
942 void wxWindow::PostCreation(void)
944 if (m_parent
) m_parent
->AddChild( this );
946 // GtkStyle *style = m_widget->style;
947 // style->font = m_font.GetInternalFont( 1.0 ); // destroy old font ?
949 GtkWidget
*connect_widget
= GetConnectWidget();
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 );
960 gtk_signal_connect( GTK_OBJECT(connect_widget
), "key_press_event",
961 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
963 gtk_signal_connect( GTK_OBJECT(connect_widget
), "button_press_event",
964 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
966 gtk_signal_connect( GTK_OBJECT(connect_widget
), "button_release_event",
967 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
969 gtk_signal_connect( GTK_OBJECT(connect_widget
), "motion_notify_event",
970 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
972 gtk_signal_connect( GTK_OBJECT(connect_widget
), "focus_in_event",
973 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
975 gtk_signal_connect( GTK_OBJECT(connect_widget
), "focus_out_event",
976 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
978 // Only for cursor handling
980 gtk_signal_connect( GTK_OBJECT(m_widget
), "enter_notify_event",
981 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
983 gtk_signal_connect( GTK_OBJECT(m_widget
), "leave_notify_event",
984 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
988 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "enter_notify_event",
989 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
991 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "leave_notify_event",
992 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
995 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
999 gtk_widget_realize( m_wxwindow
);
1000 gdk_gc_set_exposures( m_wxwindow
->style
->fg_gc
[0], TRUE
);
1003 SetCursor( wxSTANDARD_CURSOR
);
1008 bool wxWindow::HasVMT(void)
1013 bool wxWindow::Close( bool force
)
1015 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1016 event
.SetEventObject(this);
1017 event
.SetForce(force
);
1019 return GetEventHandler()->ProcessEvent(event
);
1022 bool wxWindow::Destroy(void)
1029 bool wxWindow::DestroyChildren(void)
1034 while ((node
= GetChildren()->First()) != (wxNode
*)NULL
)
1037 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1040 if (GetChildren()->Member(child
)) delete node
;
1047 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1049 // are we to set fonts here ?
1052 void wxWindow::ImplementSetSize(void)
1054 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1055 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1056 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1057 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1058 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1061 void wxWindow::ImplementSetPosition(void)
1063 if (IS_KIND_OF(this,wxFrame
) || IS_KIND_OF(this,wxDialog
))
1065 if ((m_x
!= -1) || (m_y
!= -1))
1066 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
1072 wxFAIL_MSG( "wxWindow::SetSize error.\n" );
1076 if ((m_parent
) && (m_parent
->m_wxwindow
))
1077 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1079 // Don't do anything for children of wxNotebook and wxMDIChildFrame
1082 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1084 if (m_resizing
) return; // I don't like recursions
1092 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1094 if (newX
== -1) newX
= m_x
;
1095 if (newY
== -1) newY
= m_y
;
1096 if (newW
== -1) newW
= m_width
;
1097 if (newH
== -1) newH
= m_height
;
1100 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1102 if (newW
== -1) newW
= 80;
1105 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1107 if (newH
== -1) newH
= 26;
1110 if ((m_x
!= newX
) || (m_y
!= newY
) || (!m_sizeSet
))
1114 ImplementSetPosition();
1116 if ((m_width
!= newW
) || (m_height
!= newH
) || (!m_sizeSet
))
1124 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1125 event
.SetEventObject( this );
1126 ProcessEvent( event
);
1131 void wxWindow::SetSize( int width
, int height
)
1133 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1136 void wxWindow::Move( int x
, int y
)
1138 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1141 void wxWindow::GetSize( int *width
, int *height
) const
1143 if (width
) (*width
) = m_width
;
1144 if (height
) (*height
) = m_height
;
1147 void wxWindow::SetClientSize( int width
, int height
)
1151 SetSize( width
, height
);
1158 if (!m_hasScrolling
)
1161 do we have sunken dialogs ?
1163 GtkStyleClass *window_class = m_wxwindow->style->klass;
1165 dw += 2 * window_class->xthickness;
1166 dh += 2 * window_class->ythickness;
1171 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1172 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1174 GtkWidget
*viewport
= scroll_window
->viewport
;
1175 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1177 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1178 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1180 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1181 (m_windowStyle
& wxSUNKEN_BORDER
))
1183 dw
+= 2 * viewport_class
->xthickness
;
1184 dh
+= 2 * viewport_class
->ythickness
;
1187 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1189 dw
+= vscrollbar
->allocation
.width
;
1190 dw
+= scroll_class
->scrollbar_spacing
;
1193 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1195 dh
+= hscrollbar
->allocation
.height
;
1196 dw
+= scroll_class
->scrollbar_spacing
;
1200 SetSize( width
+dw
, height
+dh
);
1204 void wxWindow::GetClientSize( int *width
, int *height
) const
1208 if (width
) (*width
) = m_width
;
1209 if (height
) (*height
) = m_height
;
1216 if (!m_hasScrolling
)
1219 do we have sunken dialogs ?
1221 GtkStyleClass *window_class = m_wxwindow->style->klass;
1223 dw += 2 * window_class->xthickness;
1224 dh += 2 * window_class->ythickness;
1229 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1230 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1232 GtkWidget
*viewport
= scroll_window
->viewport
;
1233 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1235 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1236 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1238 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1239 (m_windowStyle
& wxSUNKEN_BORDER
))
1241 dw
+= 2 * viewport_class
->xthickness
;
1242 dh
+= 2 * viewport_class
->ythickness
;
1245 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1247 // dw += vscrollbar->allocation.width;
1248 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1249 dw
+= scroll_class
->scrollbar_spacing
;
1252 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1254 // dh += hscrollbar->allocation.height;
1256 dh
+= scroll_class
->scrollbar_spacing
;
1260 if (width
) (*width
) = m_width
- dw
;
1261 if (height
) (*height
) = m_height
- dh
;
1265 void wxWindow::GetPosition( int *x
, int *y
) const
1271 void wxWindow::ClientToScreen( int *x
, int *y
)
1273 GdkWindow
*source
= (GdkWindow
*) NULL
;
1275 source
= m_wxwindow
->window
;
1277 source
= m_widget
->window
;
1281 gdk_window_get_origin( source
, &org_x
, &org_y
);
1285 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1287 org_x
+= m_widget
->allocation
.x
;
1288 org_y
+= m_widget
->allocation
.y
;
1296 void wxWindow::ScreenToClient( int *x
, int *y
)
1298 GdkWindow
*source
= (GdkWindow
*) NULL
;
1300 source
= m_wxwindow
->window
;
1302 source
= m_widget
->window
;
1306 gdk_window_get_origin( source
, &org_x
, &org_y
);
1310 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1312 org_x
+= m_widget
->allocation
.x
;
1313 org_y
+= m_widget
->allocation
.y
;
1321 void wxWindow::Centre( int direction
)
1323 if (IS_KIND_OF(this,wxDialog
) || IS_KIND_OF(this,wxFrame
))
1325 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (gdk_screen_width () - m_width
) / 2;
1326 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (gdk_screen_height () - m_height
) / 2;
1327 ImplementSetPosition();
1335 m_parent
->GetSize( &p_w
, &p_h
);
1336 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (p_w
- m_width
) / 2;
1337 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (p_h
- m_height
) / 2;
1338 ImplementSetPosition();
1343 void wxWindow::Fit(void)
1347 wxNode
*node
= GetChildren()->First();
1350 wxWindow
*win
= (wxWindow
*)node
->Data();
1352 win
->GetPosition(&wx
, &wy
);
1353 win
->GetSize(&ww
, &wh
);
1354 if ( wx
+ ww
> maxX
)
1356 if ( wy
+ wh
> maxY
)
1359 node
= node
->Next();
1361 SetClientSize(maxX
+ 5, maxY
+ 10);
1364 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1372 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1374 //if (GetAutoLayout()) Layout();
1377 bool wxWindow::Show( bool show
)
1380 gtk_widget_show( m_widget
);
1382 gtk_widget_hide( m_widget
);
1387 void wxWindow::Enable( bool enable
)
1389 m_isEnabled
= enable
;
1390 gtk_widget_set_sensitive( m_widget
, enable
);
1391 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1394 int wxWindow::GetCharHeight(void) const
1396 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1397 return font
->ascent
+ font
->descent
;
1400 int wxWindow::GetCharWidth(void) const
1402 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1403 return gdk_string_width( font
, "H" );
1406 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1407 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1409 wxFont fontToUse
= m_font
;
1410 if (theFont
) fontToUse
= *theFont
;
1412 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1413 if (x
) (*x
) = gdk_string_width( font
, string
);
1414 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1415 if (descent
) (*descent
) = font
->descent
;
1416 if (externalLeading
) (*externalLeading
) = 0; // ??
1419 void wxWindow::MakeModal( bool modal
)
1422 // Disable all other windows
1423 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1425 wxNode
*node
= wxTopLevelWindows
.First();
1428 wxWindow
*win
= (wxWindow
*)node
->Data();
1430 win
->Enable(!modal
);
1432 node
= node
->Next();
1437 void wxWindow::SetFocus(void)
1439 GtkWidget
*connect_widget
= GetConnectWidget();
1442 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1444 gtk_widget_grab_focus (connect_widget
);
1449 bool wxWindow::OnClose(void)
1454 void wxWindow::AddChild( wxWindow
*child
)
1456 // Addchild is (often) called before the program
1457 // has left the parents constructor so that no
1458 // virtual tables work yet. The approach below
1459 // practically imitates virtual tables, i.e. it
1460 // implements a different AddChild() behaviour
1461 // for wxFrame, wxDialog, wxWindow and
1462 // wxMDIParentFrame.
1464 // wxFrame and wxDialog as children aren't placed into the parents
1466 if (( IS_KIND_OF(child
,wxFrame
) || IS_KIND_OF(child
,wxDialog
) ) &&
1467 (!IS_KIND_OF(child
,wxMDIChildFrame
)))
1469 m_children
.Append( child
);
1471 if ((child
->m_x
!= -1) && (child
->m_y
!= -1))
1472 gtk_widget_set_uposition( child
->m_widget
, child
->m_x
, child
->m_y
);
1477 // In the case of an wxMDIChildFrame descendant, we use the
1478 // client windows's AddChild()
1480 if (IS_KIND_OF(this,wxMDIParentFrame
))
1482 if (IS_KIND_OF(child
,wxMDIChildFrame
))
1484 wxMDIClientWindow
*client
= ((wxMDIParentFrame
*)this)->GetClientWindow();
1487 client
->AddChild( child
);
1493 // wxNotebook is very special, so it has a private AddChild()
1495 if (IS_KIND_OF(this,wxNotebook
))
1497 wxNotebook
*tab
= (wxNotebook
*)this;
1498 tab
->AddChild( child
);
1502 // wxFrame has a private AddChild
1504 if (IS_KIND_OF(this,wxFrame
) && !IS_KIND_OF(this,wxMDIChildFrame
))
1506 wxFrame
*frame
= (wxFrame
*)this;
1507 frame
->AddChild( child
);
1513 m_children
.Append( child
);
1514 if (m_wxwindow
) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), child
->m_widget
,
1515 child
->m_x
, child
->m_y
);
1517 gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height
);
1520 wxList
*wxWindow::GetChildren(void)
1522 return (&m_children
);
1525 void wxWindow::RemoveChild( wxWindow
*child
)
1528 GetChildren()->DeleteObject( child
);
1529 child
->m_parent
= (wxWindow
*) NULL
;
1532 void wxWindow::SetReturnCode( int retCode
)
1534 m_retCode
= retCode
;
1537 int wxWindow::GetReturnCode(void)
1542 void wxWindow::Raise(void)
1544 if (m_widget
) gdk_window_raise( m_widget
->window
);
1547 void wxWindow::Lower(void)
1549 if (m_widget
) gdk_window_lower( m_widget
->window
);
1552 wxEvtHandler
*wxWindow::GetEventHandler(void)
1554 return m_eventHandler
;
1557 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1559 m_eventHandler
= handler
;
1562 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1564 handler
->SetNextHandler(GetEventHandler());
1565 SetEventHandler(handler
);
1568 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1570 if ( GetEventHandler() )
1572 wxEvtHandler
*handlerA
= GetEventHandler();
1573 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
1574 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
1575 SetEventHandler(handlerB
);
1576 if ( deleteHandler
)
1579 return (wxEvtHandler
*) NULL
;
1585 return (wxEvtHandler
*) NULL
;
1588 wxValidator
*wxWindow::GetValidator(void)
1590 return m_windowValidator
;
1593 void wxWindow::SetValidator( const wxValidator
& validator
)
1595 if (m_windowValidator
) delete m_windowValidator
;
1596 m_windowValidator
= validator
.Clone();
1597 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
1600 bool wxWindow::IsBeingDeleted(void)
1605 void wxWindow::SetId( wxWindowID id
)
1610 wxWindowID
wxWindow::GetId(void)
1615 void wxWindow::SetCursor( const wxCursor
&cursor
)
1617 wxASSERT(m_cursor
!= NULL
);
1619 if (m_cursor
!= NULL
)
1620 if (*m_cursor
== cursor
)
1622 (*m_cursor
) = cursor
;
1623 if (m_widget
->window
)
1624 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
1625 if (m_wxwindow
&& m_wxwindow
->window
)
1626 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
1629 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
1631 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
1634 gdk_window_clear_area( m_wxwindow
->window
,
1648 GetClientSize( &w
, &h
);
1650 GdkRectangle gdk_rect
;
1654 gdk_rect
.height
= h
;
1655 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1660 GdkRectangle gdk_rect
;
1661 gdk_rect
.x
= rect
->x
;
1662 gdk_rect
.y
= rect
->y
;
1663 gdk_rect
.width
= rect
->width
;
1664 gdk_rect
.height
= rect
->height
;
1667 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1669 gtk_widget_draw( m_widget
, &gdk_rect
);
1673 wxRegion
wxWindow::GetUpdateRegion() const
1675 return m_updateRegion
;
1678 bool wxWindow::IsExposed( int x
, int y
) const
1680 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
1683 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
1685 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
1688 bool wxWindow::IsExposed( const wxPoint
& pt
) const
1690 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
1693 bool wxWindow::IsExposed( const wxRect
& rect
) const
1695 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
1698 void wxWindow::Clear(void)
1700 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
1703 wxColour
wxWindow::GetBackgroundColour(void) const
1705 return m_backgroundColour
;
1708 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
1710 m_backgroundColour
= colour
;
1713 m_backgroundColour
.CalcPixel( m_wxwindow
->style
->colormap
);
1714 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
1715 gdk_window_clear( m_wxwindow
->window
);
1720 wxColour
wxWindow::GetForegroundColour(void) const
1722 return m_foregroundColour
;
1725 void wxWindow::SetForegroundColour( const wxColour
&colour
)
1727 m_foregroundColour
= colour
;
1730 bool wxWindow::Validate(void)
1732 wxNode
*node
= GetChildren()->First();
1735 wxWindow
*child
= (wxWindow
*)node
->Data();
1736 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
1738 node
= node
->Next();
1743 bool wxWindow::TransferDataToWindow(void)
1745 wxNode
*node
= GetChildren()->First();
1748 wxWindow
*child
= (wxWindow
*)node
->Data();
1749 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
1750 !child
->GetValidator()->TransferToWindow() )
1752 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
1755 node
= node
->Next();
1760 bool wxWindow::TransferDataFromWindow(void)
1762 wxNode
*node
= GetChildren()->First();
1765 wxWindow
*child
= (wxWindow
*)node
->Data();
1766 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
1768 node
= node
->Next();
1773 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
1775 m_acceleratorTable
= accel
;
1778 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
1780 TransferDataToWindow();
1783 void wxWindow::InitDialog(void)
1785 wxInitDialogEvent
event(GetId());
1786 event
.SetEventObject( this );
1787 GetEventHandler()->ProcessEvent(event
);
1790 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
1792 menu
->SetInvokingWindow( win
);
1793 wxNode
*node
= menu
->m_items
.First();
1796 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
1797 if (menuitem
->IsSubMenu())
1798 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
1799 node
= node
->Next();
1803 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
1805 SetInvokingWindow( menu
, this );
1806 gtk_menu_popup( GTK_MENU(menu
->m_menu
), (GtkWidget
*) NULL
, (GtkWidget
*) NULL
, (GtkMenuPositionFunc
) NULL
, NULL
, 0, 0 );
1810 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
1812 GtkWidget
*dnd_widget
= GetConnectWidget();
1816 gtk_signal_disconnect_by_func( GTK_OBJECT(dnd_widget
),
1817 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
1819 m_pDropTarget
->UnregisterWidget( dnd_widget
);
1820 delete m_pDropTarget
;
1822 m_pDropTarget
= dropTarget
;
1825 m_pDropTarget
->RegisterWidget( dnd_widget
);
1827 gtk_signal_connect( GTK_OBJECT(dnd_widget
), "drop_data_available_event",
1828 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
1832 wxDropTarget
*wxWindow::GetDropTarget() const
1834 return m_pDropTarget
;
1837 GtkWidget
* wxWindow::GetConnectWidget(void)
1839 GtkWidget
*connect_widget
= m_widget
;
1840 if (m_wxwindow
) connect_widget
= m_wxwindow
;
1842 return connect_widget
;
1845 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
1847 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
1848 return (window
== m_widget
->window
);
1851 void wxWindow::SetFont( const wxFont
&font
)
1856 copy old style values to new one
1857 set font in new style
1858 -> takes to many resources
1860 GtkStyle *style = gtk_style_new();
1865 wxFont
*wxWindow::GetFont(void)
1870 void wxWindow::SetWindowStyleFlag( long flag
)
1872 m_windowStyle
= flag
;
1875 long wxWindow::GetWindowStyleFlag(void) const
1877 return m_windowStyle
;
1880 void wxWindow::CaptureMouse(void)
1882 GtkWidget
*connect_widget
= GetConnectWidget();
1883 gtk_grab_add( connect_widget
);
1884 gdk_pointer_grab ( connect_widget
->window
, FALSE
,
1886 (GDK_BUTTON_PRESS_MASK
|
1887 GDK_BUTTON_RELEASE_MASK
|
1888 GDK_POINTER_MOTION_MASK
),
1889 (GdkWindow
*) NULL
, (GdkCursor
*) NULL
, GDK_CURRENT_TIME
);
1892 void wxWindow::ReleaseMouse(void)
1894 GtkWidget
*connect_widget
= GetConnectWidget();
1895 gtk_grab_remove( connect_widget
);
1896 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
1899 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
1903 wxString
wxWindow::GetTitle(void) const
1905 return (wxString
&)m_windowName
;
1908 wxString
wxWindow::GetLabel(void) const
1913 void wxWindow::SetName( const wxString
&name
)
1915 m_windowName
= name
;
1918 wxString
wxWindow::GetName(void) const
1920 return (wxString
&)m_windowName
;
1923 bool wxWindow::IsShown(void) const
1928 bool wxWindow::IsRetained(void)
1933 wxWindow
*wxWindow::FindWindow( long id
)
1935 if (id
== m_windowId
) return this;
1936 wxNode
*node
= m_children
.First();
1939 wxWindow
*child
= (wxWindow
*)node
->Data();
1940 wxWindow
*res
= child
->FindWindow( id
);
1941 if (res
) return res
;
1942 node
= node
->Next();
1944 return (wxWindow
*) NULL
;
1947 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
1949 if (name
== m_windowName
) return this;
1950 wxNode
*node
= m_children
.First();
1953 wxWindow
*child
= (wxWindow
*)node
->Data();
1954 wxWindow
*res
= child
->FindWindow( name
);
1955 if (res
) return res
;
1956 node
= node
->Next();
1958 return (wxWindow
*) NULL
;
1961 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
1962 int range
, bool WXUNUSED(refresh
) )
1964 if (!m_wxwindow
) return;
1966 if (orient
== wxHORIZONTAL
)
1968 float fpos
= (float)pos
;
1969 m_oldHorizontalPos
= fpos
;
1970 float frange
= (float)range
;
1971 float fthumb
= (float)thumbVisible
;
1973 if ((fabs(fpos
-m_hAdjust
->value
) < 0.2) &&
1974 (fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
1975 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
1978 m_hAdjust
->lower
= 0.0;
1979 m_hAdjust
->upper
= frange
;
1980 m_hAdjust
->value
= fpos
;
1981 m_hAdjust
->step_increment
= 1.0;
1982 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
-2,0));
1983 m_hAdjust
->page_size
= fthumb
;
1987 float fpos
= (float)pos
;
1988 m_oldVerticalPos
= fpos
;
1989 float frange
= (float)range
;
1990 float fthumb
= (float)thumbVisible
;
1992 if ((fabs(fpos
-m_vAdjust
->value
) < 0.2) &&
1993 (fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
1994 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
1997 m_vAdjust
->lower
= 0.0;
1998 m_vAdjust
->upper
= frange
;
1999 m_vAdjust
->value
= fpos
;
2000 m_vAdjust
->step_increment
= 1.0;
2001 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
-2,0));
2002 m_vAdjust
->page_size
= fthumb
;
2005 if (m_wxwindow
->window
)
2007 if (orient
== wxHORIZONTAL
)
2008 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2010 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2012 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2016 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2018 if (!m_wxwindow
) return;
2020 if (orient
== wxHORIZONTAL
)
2022 float fpos
= (float)pos
;
2023 m_oldHorizontalPos
= fpos
;
2025 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2026 m_hAdjust
->value
= fpos
;
2030 float fpos
= (float)pos
;
2031 m_oldVerticalPos
= fpos
;
2032 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2033 m_vAdjust
->value
= fpos
;
2036 if (m_wxwindow
->window
)
2038 if (orient
== wxHORIZONTAL
)
2039 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2041 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2045 int wxWindow::GetScrollThumb( int orient
) const
2047 if (!m_wxwindow
) return 0;
2049 if (orient
== wxHORIZONTAL
)
2050 return (int)(m_hAdjust
->page_size
+0.5);
2052 return (int)(m_vAdjust
->page_size
+0.5);
2055 int wxWindow::GetScrollPos( int orient
) const
2057 if (!m_wxwindow
) return 0;
2059 if (orient
== wxHORIZONTAL
)
2060 return (int)(m_hAdjust
->value
+0.5);
2062 return (int)(m_vAdjust
->value
+0.5);
2065 int wxWindow::GetScrollRange( int orient
) const
2067 if (!m_wxwindow
) return 0;
2069 if (orient
== wxHORIZONTAL
)
2070 return (int)(m_hAdjust
->upper
+0.5);
2072 return (int)(m_vAdjust
->upper
+0.5);
2075 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2077 if (!m_wxwindow
) return;
2080 bool refresh = FALSE;
2082 if ((m_drawingOffsetX == 0) && (m_drawingOffsetY == 0))
2084 m_drawingOffsetX = -16000;
2085 m_drawingOffsetY = -16000;
2090 m_drawingOffsetX += dx;
2091 m_drawingOffsetY += dy;
2094 // printf( "X: %d Y: %d \n", (int)m_drawingOffsetX, (int)m_drawingOffsetY );
2096 gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
2098 if (refresh) Refresh();
2100 The code here is very nifty, but it doesn't work with
2101 overlapping windows...
2106 GetClientSize( &cw
, &ch
);
2108 int w
= cw
- abs(dx
);
2109 int h
= ch
- abs(dy
);
2110 if ((h
< 0) || (w
< 0))
2117 if (dx
< 0) s_x
= -dx
;
2118 if (dy
< 0) s_y
= -dy
;
2121 if (dx
> 0) d_x
= dx
;
2122 if (dy
> 0) d_y
= dy
;
2123 gdk_window_copy_area( m_wxwindow
->window
, m_wxwindow
->style
->fg_gc
[0], d_x
, d_y
,
2124 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2127 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2128 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2129 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2130 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2132 Refresh( TRUE
, &rect
);
2135 //-------------------------------------------------------------------------------------
2137 //-------------------------------------------------------------------------------------
2139 wxLayoutConstraints
*wxWindow::GetConstraints(void) const
2141 return m_constraints
;
2144 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2148 UnsetConstraints(m_constraints
);
2149 delete m_constraints
;
2151 m_constraints
= constraints
;
2154 // Make sure other windows know they're part of a 'meaningful relationship'
2155 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2156 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2157 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2158 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2159 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2160 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2161 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2162 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2163 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2164 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2165 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2166 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2167 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2168 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2169 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2170 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2176 void wxWindow::SetAutoLayout( bool autoLayout
)
2178 m_autoLayout
= autoLayout
;
2181 bool wxWindow::GetAutoLayout(void) const
2183 return m_autoLayout
;
2186 wxSizer
*wxWindow::GetSizer(void) const
2188 return m_windowSizer
;
2191 void wxWindow::SetSizerParent( wxWindow
*win
)
2193 m_sizerParent
= win
;
2196 wxWindow
*wxWindow::GetSizerParent(void) const
2198 return m_sizerParent
;
2201 // This removes any dangling pointers to this window
2202 // in other windows' constraintsInvolvedIn lists.
2203 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2207 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2208 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2209 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2210 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2211 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2212 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2213 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2214 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2215 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2216 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2217 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2218 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2219 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2220 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2221 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2222 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2226 // Back-pointer to other windows we're involved with, so if we delete
2227 // this window, we must delete any constraints we're involved with.
2228 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2230 if (!m_constraintsInvolvedIn
)
2231 m_constraintsInvolvedIn
= new wxList
;
2232 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2233 m_constraintsInvolvedIn
->Append(otherWin
);
2236 // REMOVE back-pointer to other windows we're involved with.
2237 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2239 if (m_constraintsInvolvedIn
)
2240 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2243 // Reset any constraints that mention this window
2244 void wxWindow::DeleteRelatedConstraints(void)
2246 if (m_constraintsInvolvedIn
)
2248 wxNode
*node
= m_constraintsInvolvedIn
->First();
2251 wxWindow
*win
= (wxWindow
*)node
->Data();
2252 wxNode
*next
= node
->Next();
2253 wxLayoutConstraints
*constr
= win
->GetConstraints();
2255 // Reset any constraints involving this window
2258 constr
->left
.ResetIfWin((wxWindow
*)this);
2259 constr
->top
.ResetIfWin((wxWindow
*)this);
2260 constr
->right
.ResetIfWin((wxWindow
*)this);
2261 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2262 constr
->width
.ResetIfWin((wxWindow
*)this);
2263 constr
->height
.ResetIfWin((wxWindow
*)this);
2264 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2265 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2270 delete m_constraintsInvolvedIn
;
2271 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2275 void wxWindow::SetSizer(wxSizer
*sizer
)
2277 m_windowSizer
= sizer
;
2279 sizer
->SetSizerParent((wxWindow
*)this);
2286 bool wxWindow::Layout(void)
2288 if (GetConstraints())
2291 GetClientSize(&w
, &h
);
2292 GetConstraints()->width
.SetValue(w
);
2293 GetConstraints()->height
.SetValue(h
);
2296 // If top level (one sizer), evaluate the sizer's constraints.
2300 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2301 GetSizer()->LayoutPhase1(&noChanges
);
2302 GetSizer()->LayoutPhase2(&noChanges
);
2303 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2308 // Otherwise, evaluate child constraints
2309 ResetConstraints(); // Mark all constraints as unevaluated
2310 DoPhase(1); // Just one phase need if no sizers involved
2312 SetConstraintSizes(); // Recursively set the real window sizes
2318 // Do a phase of evaluating constraints:
2319 // the default behaviour. wxSizers may do a similar
2320 // thing, but also impose their own 'constraints'
2321 // and order the evaluation differently.
2322 bool wxWindow::LayoutPhase1(int *noChanges
)
2324 wxLayoutConstraints
*constr
= GetConstraints();
2327 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2333 bool wxWindow::LayoutPhase2(int *noChanges
)
2343 // Do a phase of evaluating child constraints
2344 bool wxWindow::DoPhase(int phase
)
2346 int noIterations
= 0;
2347 int maxIterations
= 500;
2351 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2355 wxNode
*node
= GetChildren()->First();
2358 wxWindow
*child
= (wxWindow
*)node
->Data();
2359 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2361 wxLayoutConstraints
*constr
= child
->GetConstraints();
2364 if (succeeded
.Member(child
))
2369 int tempNoChanges
= 0;
2370 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2371 noChanges
+= tempNoChanges
;
2374 succeeded
.Append(child
);
2379 node
= node
->Next();
2386 void wxWindow::ResetConstraints(void)
2388 wxLayoutConstraints
*constr
= GetConstraints();
2391 constr
->left
.SetDone(FALSE
);
2392 constr
->top
.SetDone(FALSE
);
2393 constr
->right
.SetDone(FALSE
);
2394 constr
->bottom
.SetDone(FALSE
);
2395 constr
->width
.SetDone(FALSE
);
2396 constr
->height
.SetDone(FALSE
);
2397 constr
->centreX
.SetDone(FALSE
);
2398 constr
->centreY
.SetDone(FALSE
);
2400 wxNode
*node
= GetChildren()->First();
2403 wxWindow
*win
= (wxWindow
*)node
->Data();
2404 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2405 win
->ResetConstraints();
2406 node
= node
->Next();
2410 // Need to distinguish between setting the 'fake' size for
2411 // windows and sizers, and setting the real values.
2412 void wxWindow::SetConstraintSizes(bool recurse
)
2414 wxLayoutConstraints
*constr
= GetConstraints();
2415 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2416 constr
->width
.GetDone() && constr
->height
.GetDone())
2418 int x
= constr
->left
.GetValue();
2419 int y
= constr
->top
.GetValue();
2420 int w
= constr
->width
.GetValue();
2421 int h
= constr
->height
.GetValue();
2423 // If we don't want to resize this window, just move it...
2424 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2425 (constr
->height
.GetRelationship() != wxAsIs
))
2427 // Calls Layout() recursively. AAAGH. How can we stop that.
2428 // Simply take Layout() out of non-top level OnSizes.
2429 SizerSetSize(x
, y
, w
, h
);
2438 char *windowClass
= this->GetClassInfo()->GetClassName();
2441 if (GetName() == "")
2442 winName
= _("unnamed");
2444 winName
= GetName();
2445 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass
, (const char *)winName
);
2446 if (!constr
->left
.GetDone())
2447 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
2448 if (!constr
->right
.GetDone())
2449 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
2450 if (!constr
->width
.GetDone())
2451 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
2452 if (!constr
->height
.GetDone())
2453 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2454 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
2459 wxNode
*node
= GetChildren()->First();
2462 wxWindow
*win
= (wxWindow
*)node
->Data();
2463 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2464 win
->SetConstraintSizes();
2465 node
= node
->Next();
2470 // This assumes that all sizers are 'on' the same
2471 // window, i.e. the parent of this window.
2472 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
2474 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
2475 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
2479 m_sizerParent
->GetPosition(&xp
, &yp
);
2480 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
2485 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
2489 TransformSizerToActual(&xx
, &yy
);
2490 SetSize(xx
, yy
, w
, h
);
2493 void wxWindow::SizerMove(int x
, int y
)
2497 TransformSizerToActual(&xx
, &yy
);
2501 // Only set the size/position of the constraint (if any)
2502 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
2504 wxLayoutConstraints
*constr
= GetConstraints();
2509 constr
->left
.SetValue(x
);
2510 constr
->left
.SetDone(TRUE
);
2514 constr
->top
.SetValue(y
);
2515 constr
->top
.SetDone(TRUE
);
2519 constr
->width
.SetValue(w
);
2520 constr
->width
.SetDone(TRUE
);
2524 constr
->height
.SetValue(h
);
2525 constr
->height
.SetDone(TRUE
);
2530 void wxWindow::MoveConstraint(int x
, int y
)
2532 wxLayoutConstraints
*constr
= GetConstraints();
2537 constr
->left
.SetValue(x
);
2538 constr
->left
.SetDone(TRUE
);
2542 constr
->top
.SetValue(y
);
2543 constr
->top
.SetDone(TRUE
);
2548 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
2550 wxLayoutConstraints
*constr
= GetConstraints();
2553 *w
= constr
->width
.GetValue();
2554 *h
= constr
->height
.GetValue();
2560 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
2562 wxLayoutConstraints
*constr
= GetConstraints();
2565 *w
= constr
->width
.GetValue();
2566 *h
= constr
->height
.GetValue();
2569 GetClientSize(w
, h
);
2572 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
2574 wxLayoutConstraints
*constr
= GetConstraints();
2577 *x
= constr
->left
.GetValue();
2578 *y
= constr
->top
.GetValue();
2584 bool wxWindow::AcceptsFocus() const
2586 return IsEnabled() && IsShown();
2589 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )