1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
24 #include "wx/dcclient.h"
27 #include "wx/statusbr.h"
29 #include "wx/settings.h"
31 #include "gdk/gdkprivate.h"
32 #include "gdk/gdkkeysyms.h"
36 //-----------------------------------------------------------------------------
37 // documentation on internals
38 //-----------------------------------------------------------------------------
41 I have been asked several times about writing some documentation about
42 the GTK port of wxWindows, especially its internal structures. Obviously,
43 you cannot understand wxGTK without knowing a little about the GTK, but
44 some more information about what the wxWindow, which is the base class
45 for all other window classes, does seems required as well.
47 What does wxWindow do? It contains the common interface for the following
48 jobs of its descendants:
50 1) Define the rudimentary behaviour common to all window classes, such as
51 resizing, intercepting user input (so as to make it possible to use these
52 events for special purposes in a derived class), window names etc.
54 2) Provide the possibility to contain and manage children, if the derived
55 class is allowed to contain children, which holds true for those window
56 classes which do not display a native GTK widget. To name them, these
57 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
58 work classes are a special case and are handled a bit differently from
59 the rest. The same holds true for the wxNotebook class.
61 3) Provide the possibility to draw into a client area of a window. This,
62 too, only holds true for classes that do not display a native GTK widget
65 4) Provide the entire mechanism for scrolling widgets. This actual inter-
66 face for this is usually in wxScrolledWindow, but the GTK implementation
69 5) A multitude of helper or extra methods for special purposes, such as
70 Drag'n'Drop, managing validators etc.
72 Normally one might expect, that one wxWindows window would always correspond
73 to one GTK widget. Under GTK, there is no such allround widget that has all
74 the functionality. Moreover, the GTK defines a client area as a different
75 widget from the actual widget you are handling. Last but not least some
76 special classes (e.g. wxFrame) handle different categories of widgets and
77 still have the possibility to draw something in the client area.
78 It was therefore required to write a special purpose GTK widget, that would
79 represent a client area in the sense of wxWindows capable to do the jobs
80 2), 3) and 4). I have written this class and it resides in win_gtk.c of
83 All windows must have a widget, with which they interact with other under-
84 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
85 thw wxWindow class has a member variable called m_widget which holds a
86 pointer to this widget. When the window class represents a GTK native widget,
87 this is (in most cases) the only GTK widget the class manages. E.g. the
88 wxStatitText class handles only a GtkLabel widget a pointer to which you
89 can find in m_widget (defined in wxWindow)
91 When the class has a client area for drawing into and for containing children
92 it has to handle the client area widget (of the type GtkMyFixed, defined in
93 win_gtk.c), but there could be any number of widgets, handled by a class
94 The common rule for all windows is only, that the widget that interacts with
95 the rest of GTK must be referenced in m_widget and all other widgets must be
96 children of this widget on the GTK level. The top-most widget, which also
97 represents the client area, must be in the m_wxwindow field and must be of
100 As I said, the window classes that display a GTK native widget only have
101 one widget, so in the case of e.g. the wxButton class m_widget holds a
102 pointer to a GtkButton widget. But windows with client areas (for drawing
103 and children) have a m_widget field that is a pointer to a GtkScrolled-
104 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
105 one is (in the GTK sense) a child of the GtkScrolledWindow.
107 If the m_wxwindow field is set, then all input to this widget is inter-
108 cepted and sent to the wxWindows class. If not, all input to the widget
109 that gets pointed to by m_widget gets intercepted and sent to the class.
113 //-------------------------------------------------------------------------
114 // conditional compilation
115 //-------------------------------------------------------------------------
117 #if (GTK_MINOR_VERSION == 1)
118 #if (GTK_MICRO_VERSION >= 5)
119 #define NEW_GTK_SCROLL_CODE
123 //-----------------------------------------------------------------------------
125 //-----------------------------------------------------------------------------
127 extern wxList wxPendingDelete
;
128 extern wxList wxTopLevelWindows
;
129 extern bool g_blockEventsOnDrag
;
130 extern bool g_blockEventsOnScroll
;
131 static bool g_capturing
= FALSE
;
133 // hack: we need something to pass to gtk_menu_popup, so we store the time of
134 // the last click here
135 static guint32 gs_timeLastClick
= 0;
137 //-----------------------------------------------------------------------------
138 // "expose_event" (of m_wxwindow, not of m_widget)
139 //-----------------------------------------------------------------------------
141 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
143 if (!win
->HasVMT()) return;
145 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
147 gdk_event
->area
.width
,
148 gdk_event
->area
.height
);
150 if (gdk_event
->count
> 0) return;
153 printf( "OnExpose from " );
154 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
155 printf( win->GetClassInfo()->GetClassName() );
159 wxPaintEvent
event( win
->GetId() );
160 event
.SetEventObject( win
);
161 win
->GetEventHandler()->ProcessEvent( event
);
163 win
->m_updateRegion
.Clear();
166 //-----------------------------------------------------------------------------
167 // "draw" (of m_wxwindow, not of m_widget)
168 //-----------------------------------------------------------------------------
170 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
172 if (!win
->HasVMT()) return;
174 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
176 wxPaintEvent
event( win
->GetId() );
177 event
.SetEventObject( win
);
178 win
->GetEventHandler()->ProcessEvent( event
);
180 win
->m_updateRegion
.Clear();
183 //-----------------------------------------------------------------------------
185 //-----------------------------------------------------------------------------
187 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
189 if (!win
->HasVMT()) return FALSE
;
190 if (g_blockEventsOnDrag
) return FALSE
;
193 printf( "OnKeyPress from " );
194 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
195 printf( win->GetClassInfo()->GetClassName() );
200 switch (gdk_event
->keyval
)
202 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
203 case GDK_Tab
: key_code
= WXK_TAB
; break;
204 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
205 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
206 case GDK_Return
: key_code
= WXK_RETURN
; break;
207 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
208 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
209 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
210 case GDK_Delete
: key_code
= WXK_DELETE
; break;
211 case GDK_Home
: key_code
= WXK_HOME
; break;
212 case GDK_Left
: key_code
= WXK_LEFT
; break;
213 case GDK_Up
: key_code
= WXK_UP
; break;
214 case GDK_Right
: key_code
= WXK_RIGHT
; break;
215 case GDK_Down
: key_code
= WXK_DOWN
; break;
216 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
217 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
218 case GDK_Next
: key_code
= WXK_NEXT
; break;
219 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
220 case GDK_End
: key_code
= WXK_END
; break;
221 case GDK_Begin
: key_code
= WXK_HOME
; break;
222 case GDK_Select
: key_code
= WXK_SELECT
; break;
223 case GDK_Print
: key_code
= WXK_PRINT
; break;
224 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
225 case GDK_Insert
: key_code
= WXK_INSERT
; break;
226 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
227 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
228 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
229 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
230 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
231 case GDK_KP_Up
: key_code
= WXK_UP
; break;
232 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
233 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
234 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
235 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
236 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
237 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
238 case GDK_KP_End
: key_code
= WXK_END
; break;
239 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
240 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
241 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
242 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
243 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
244 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
245 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
246 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
247 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
248 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
249 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
250 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
251 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
252 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
253 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
254 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
255 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
256 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
257 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
258 case GDK_F1
: key_code
= WXK_F1
; break;
259 case GDK_F2
: key_code
= WXK_F2
; break;
260 case GDK_F3
: key_code
= WXK_F3
; break;
261 case GDK_F4
: key_code
= WXK_F4
; break;
262 case GDK_F5
: key_code
= WXK_F5
; break;
263 case GDK_F6
: key_code
= WXK_F6
; break;
264 case GDK_F7
: key_code
= WXK_F7
; break;
265 case GDK_F8
: key_code
= WXK_F8
; break;
266 case GDK_F9
: key_code
= WXK_F9
; break;
267 case GDK_F10
: key_code
= WXK_F10
; break;
268 case GDK_F11
: key_code
= WXK_F11
; break;
269 case GDK_F12
: key_code
= WXK_F12
; break;
272 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
273 key_code
= gdk_event
->keyval
;
277 if (!key_code
) return FALSE
;
279 wxKeyEvent
event( wxEVT_CHAR
);
280 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
281 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
282 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
283 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
284 event
.m_keyCode
= key_code
;
287 event
.SetEventObject( win
);
289 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
293 wxWindow
*ancestor
= win
;
296 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
299 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
300 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
303 ancestor
= ancestor
->GetParent();
309 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
310 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
316 //-----------------------------------------------------------------------------
317 // "button_press_event"
318 //-----------------------------------------------------------------------------
320 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
322 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
324 if (g_blockEventsOnDrag
) return TRUE
;
325 if (g_blockEventsOnScroll
) return TRUE
;
329 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
331 gtk_widget_grab_focus (win
->m_wxwindow
);
334 printf( "GrabFocus from " );
335 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
336 printf( win->GetClassInfo()->GetClassName() );
343 if (!win
->HasVMT()) return TRUE
;
346 printf( "OnButtonPress from " );
347 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
348 printf( win->GetClassInfo()->GetClassName() );
352 wxEventType event_type
= wxEVT_LEFT_DOWN
;
354 if (gdk_event
->button
== 1)
356 switch (gdk_event
->type
)
358 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
359 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
363 else if (gdk_event
->button
== 2)
365 switch (gdk_event
->type
)
367 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
368 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
372 else if (gdk_event
->button
== 3)
374 switch (gdk_event
->type
)
376 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
377 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
382 wxMouseEvent
event( event_type
);
383 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
384 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
385 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
386 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
387 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
388 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
389 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
391 event
.m_x
= (long)gdk_event
->x
;
392 event
.m_y
= (long)gdk_event
->y
;
394 // Some control don't have their own X window and thus cannot get
399 wxNode
*node
= win
->GetChildren().First();
402 wxWindow
*child
= (wxWindow
*)node
->Data();
403 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
404 (child
->m_x
<= event
.m_x
) &&
405 (child
->m_y
<= event
.m_y
) &&
406 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
407 (child
->m_y
+child
->m_height
>= event
.m_y
))
410 event
.m_x
-= child
->m_x
;
411 event
.m_y
-= child
->m_y
;
418 event
.SetEventObject( win
);
420 gs_timeLastClick
= gdk_event
->time
;
422 if (win
->GetEventHandler()->ProcessEvent( event
))
423 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
428 //-----------------------------------------------------------------------------
429 // "button_release_event"
430 //-----------------------------------------------------------------------------
432 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
434 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
436 if (g_blockEventsOnDrag
) return TRUE
;
437 if (g_blockEventsOnScroll
) return TRUE
;
439 if (!win
->HasVMT()) return TRUE
;
442 printf( "OnButtonRelease from " );
443 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
444 printf( win->GetClassInfo()->GetClassName() );
448 wxEventType event_type
= wxEVT_NULL
;
450 switch (gdk_event
->button
)
452 case 1: event_type
= wxEVT_LEFT_UP
; break;
453 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
454 case 3: event_type
= wxEVT_RIGHT_UP
; break;
457 wxMouseEvent
event( event_type
);
458 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
459 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
460 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
461 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
462 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
463 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
464 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
465 event
.m_x
= (long)gdk_event
->x
;
466 event
.m_y
= (long)gdk_event
->y
;
468 // Some control don't have their own X window and thus cannot get
473 wxNode
*node
= win
->GetChildren().First();
476 wxWindow
*child
= (wxWindow
*)node
->Data();
477 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
478 (child
->m_x
<= event
.m_x
) &&
479 (child
->m_y
<= event
.m_y
) &&
480 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
481 (child
->m_y
+child
->m_height
>= event
.m_y
))
484 event
.m_x
-= child
->m_x
;
485 event
.m_y
-= child
->m_y
;
492 event
.SetEventObject( win
);
494 if (win
->GetEventHandler()->ProcessEvent( event
))
495 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
500 //-----------------------------------------------------------------------------
501 // "motion_notify_event"
502 //-----------------------------------------------------------------------------
504 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
506 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
508 if (g_blockEventsOnDrag
) return TRUE
;
509 if (g_blockEventsOnScroll
) return TRUE
;
511 if (!win
->HasVMT()) return TRUE
;
514 printf( "OnMotion from " );
515 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
516 printf( win->GetClassInfo()->GetClassName() );
520 wxMouseEvent
event( wxEVT_MOTION
);
521 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
522 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
523 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
524 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
525 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
526 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
527 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
529 event
.m_x
= (long)gdk_event
->x
;
530 event
.m_y
= (long)gdk_event
->y
;
532 // Some control don't have their own X window and thus cannot get
537 wxNode
*node
= win
->GetChildren().First();
540 wxWindow
*child
= (wxWindow
*)node
->Data();
541 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
542 (child
->m_x
<= event
.m_x
) &&
543 (child
->m_y
<= event
.m_y
) &&
544 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
545 (child
->m_y
+child
->m_height
>= event
.m_y
))
548 event
.m_x
-= child
->m_x
;
549 event
.m_y
-= child
->m_y
;
556 event
.SetEventObject( win
);
558 if (win
->GetEventHandler()->ProcessEvent( event
))
559 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
564 //-----------------------------------------------------------------------------
566 //-----------------------------------------------------------------------------
568 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
570 if (g_blockEventsOnDrag
) return TRUE
;
573 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
575 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
577 printf( "SetFocus flag from " );
578 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
579 printf( win->GetClassInfo()->GetClassName() );
585 if (!win
->HasVMT()) return TRUE
;
588 printf( "OnSetFocus from " );
589 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
590 printf( win->GetClassInfo()->GetClassName() );
592 printf( WXSTRINGCAST win->GetLabel() );
596 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
597 event
.SetEventObject( win
);
599 if (win
->GetEventHandler()->ProcessEvent( event
))
600 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
605 //-----------------------------------------------------------------------------
607 //-----------------------------------------------------------------------------
609 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
611 if (g_blockEventsOnDrag
) return TRUE
;
614 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
615 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
618 if (!win
->HasVMT()) return TRUE
;
621 printf( "OnKillFocus from " );
622 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
623 printf( win->GetClassInfo()->GetClassName() );
627 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
628 event
.SetEventObject( win
);
630 if (win
->GetEventHandler()->ProcessEvent( event
))
631 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
636 //-----------------------------------------------------------------------------
637 // "enter_notify_event"
638 //-----------------------------------------------------------------------------
640 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
642 if (widget
->window
!= gdk_event
->window
) return TRUE
;
644 if (g_blockEventsOnDrag
) return TRUE
;
646 if (!win
->HasVMT()) return TRUE
;
649 printf( "OnEnter from " );
650 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
651 printf( win->GetClassInfo()->GetClassName() );
655 if ((widget
->window
) && (win
->m_cursor
))
656 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
658 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
659 event
.SetEventObject( win
);
663 GdkModifierType state
= (GdkModifierType
)0;
665 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
667 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
668 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
669 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
670 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
671 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
672 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
673 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
678 if (win
->GetEventHandler()->ProcessEvent( event
))
679 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
684 //-----------------------------------------------------------------------------
685 // "leave_notify_event"
686 //-----------------------------------------------------------------------------
688 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
690 if (widget
->window
!= gdk_event
->window
) return TRUE
;
692 if (g_blockEventsOnDrag
) return TRUE
;
694 if (!win
->HasVMT()) return TRUE
;
697 printf( "OnLeave from " );
698 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
699 printf( win->GetClassInfo()->GetClassName() );
703 if ((widget
->window
) && (win
->m_cursor
))
704 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
706 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
707 event
.SetEventObject( win
);
711 GdkModifierType state
= (GdkModifierType
)0;
713 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
715 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
716 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
717 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
718 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
719 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
720 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
721 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
726 if (win
->GetEventHandler()->ProcessEvent( event
))
727 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
732 //-----------------------------------------------------------------------------
733 // "value_changed" from m_vAdjust
734 //-----------------------------------------------------------------------------
736 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
738 if (g_blockEventsOnDrag
) return;
741 printf( "OnVScroll from " );
742 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
743 printf( win->GetClassInfo()->GetClassName() );
747 if (!win
->HasVMT()) return;
749 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
750 if (fabs(diff
) < 0.2) return;
752 wxEventType command
= wxEVT_NULL
;
754 float line_step
= win
->m_vAdjust
->step_increment
;
755 float page_step
= win
->m_vAdjust
->page_increment
;
757 if (win
->m_isScrolling
)
759 command
= wxEVT_SCROLL_THUMBTRACK
;
763 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
764 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
765 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
766 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
767 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
768 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
769 else command
= wxEVT_SCROLL_THUMBTRACK
;
772 int value
= (int)(win
->m_vAdjust
->value
+0.5);
774 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
775 event
.SetEventObject( win
);
776 win
->GetEventHandler()->ProcessEvent( event
);
779 //-----------------------------------------------------------------------------
780 // "value_changed" from m_hAdjust
781 //-----------------------------------------------------------------------------
783 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
785 if (g_blockEventsOnDrag
) return;
788 printf( "OnHScroll from " );
789 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
790 printf( win->GetClassInfo()->GetClassName() );
794 if (!win
->HasVMT()) return;
796 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
797 if (fabs(diff
) < 0.2) return;
799 wxEventType command
= wxEVT_NULL
;
801 float line_step
= win
->m_hAdjust
->step_increment
;
802 float page_step
= win
->m_hAdjust
->page_increment
;
804 if (win
->m_isScrolling
)
806 command
= wxEVT_SCROLL_THUMBTRACK
;
810 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
811 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
812 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
813 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
814 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
815 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
816 else command
= wxEVT_SCROLL_THUMBTRACK
;
819 int value
= (int)(win
->m_hAdjust
->value
+0.5);
821 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
822 event
.SetEventObject( win
);
823 win
->GetEventHandler()->ProcessEvent( event
);
826 //-----------------------------------------------------------------------------
827 // "changed" from m_vAdjust
828 //-----------------------------------------------------------------------------
830 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
832 if (g_blockEventsOnDrag
) return;
835 printf( "OnVScroll change from " );
836 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
837 printf( win->GetClassInfo()->GetClassName() );
841 if (!win
->HasVMT()) return;
843 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
844 int value
= (int)(win
->m_vAdjust
->value
+0.5);
846 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
847 event
.SetEventObject( win
);
848 win
->GetEventHandler()->ProcessEvent( event
);
851 //-----------------------------------------------------------------------------
852 // "changed" from m_hAdjust
853 //-----------------------------------------------------------------------------
855 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
857 if (g_blockEventsOnDrag
) return;
860 printf( "OnHScroll change from " );
861 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
862 printf( win->GetClassInfo()->GetClassName() );
866 if (!win
->HasVMT()) return;
868 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
869 int value
= (int)(win
->m_hAdjust
->value
+0.5);
871 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
872 event
.SetEventObject( win
);
873 win
->GetEventHandler()->ProcessEvent( event
);
876 //-----------------------------------------------------------------------------
877 // "button_press_event" from scrollbar
878 //-----------------------------------------------------------------------------
880 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
881 GdkEventButton
*WXUNUSED(gdk_event
),
884 // if (gdk_event->window != widget->slider) return FALSE;
886 win
->m_isScrolling
= TRUE
;
887 g_blockEventsOnScroll
= TRUE
;
892 //-----------------------------------------------------------------------------
893 // "button_release_event" from scrollbar
894 //-----------------------------------------------------------------------------
896 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
897 GdkEventButton
*WXUNUSED(gdk_event
),
901 // don't test here as we can reelase the mouse while being over
902 // a different window then the slider
904 // if (gdk_event->window != widget->slider) return FALSE;
906 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
908 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
909 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
911 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
913 win
->m_isScrolling
= FALSE
;
914 g_blockEventsOnScroll
= FALSE
;
919 //-----------------------------------------------------------------------------
920 // InsertChild for wxWindow.
921 //-----------------------------------------------------------------------------
923 // Callback for wxWindow. This very strange beast has to be used because
924 // C++ has no virtual methods in a constructor. We have to emulate a
925 // virtual function here as wxNotebook requires a different way to insert
926 // a child in it. I had opted for creating a wxNotebookPage window class
927 // which would have made this superflouus (such in the MDI window system),
928 // but no-one is listening to me...
930 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
932 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
933 GTK_WIDGET(child
->m_widget
),
937 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
942 //-----------------------------------------------------------------------------
944 //-----------------------------------------------------------------------------
946 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
948 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
949 EVT_SIZE(wxWindow::OnSize
)
950 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
951 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
952 EVT_IDLE(wxWindow::OnIdle
)
957 m_widget
= (GtkWidget
*) NULL
;
958 m_wxwindow
= (GtkWidget
*) NULL
;
959 m_parent
= (wxWindow
*) NULL
;
960 m_children
.DeleteContents( FALSE
);
973 m_eventHandler
= this;
974 m_windowValidator
= (wxValidator
*) NULL
;
978 m_cursor
= (wxCursor
*) NULL
;
979 m_font
= *wxSWISS_FONT
;
981 m_windowName
= "noname";
983 m_constraints
= (wxLayoutConstraints
*) NULL
;
984 m_constraintsInvolvedIn
= (wxList
*) NULL
;
985 m_windowSizer
= (wxSizer
*) NULL
;
986 m_sizerParent
= (wxWindow
*) NULL
;
987 m_autoLayout
= FALSE
;
993 m_hasScrolling
= FALSE
;
994 m_isScrolling
= FALSE
;
995 m_hAdjust
= (GtkAdjustment
*) NULL
;
996 m_vAdjust
= (GtkAdjustment
*) NULL
;
997 m_oldHorizontalPos
= 0.0;
998 m_oldVerticalPos
= 0.0;
1003 m_dropTarget
= (wxDropTarget
*) NULL
;
1005 m_scrollGC
= (GdkGC
*) NULL
;
1006 m_widgetStyle
= (GtkStyle
*) NULL
;
1008 m_insertCallback
= wxInsertChildInWindow
;
1010 m_clientObject
= (wxClientData
*) NULL
;
1011 m_clientData
= NULL
;
1014 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1015 const wxPoint
&pos
, const wxSize
&size
,
1016 long style
, const wxString
&name
)
1018 m_insertCallback
= wxInsertChildInWindow
;
1019 Create( parent
, id
, pos
, size
, style
, name
);
1022 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1023 const wxPoint
&pos
, const wxSize
&size
,
1024 long style
, const wxString
&name
)
1028 m_needParent
= TRUE
;
1030 PreCreation( parent
, id
, pos
, size
, style
, name
);
1032 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1033 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1035 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1037 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1038 scroll_class
->scrollbar_spacing
= 0;
1040 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1042 m_oldHorizontalPos
= 0.0;
1043 m_oldVerticalPos
= 0.0;
1045 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1046 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1048 m_wxwindow
= gtk_myfixed_new();
1050 #ifdef NEW_GTK_SCROLL_CODE
1051 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1052 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1054 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1055 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1058 if (m_windowStyle
& wxRAISED_BORDER
)
1060 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1062 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1064 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1068 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1071 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
1072 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1074 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1076 // shut the viewport up
1077 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1078 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1080 // I _really_ don't want scrollbars in the beginning
1081 m_vAdjust
->lower
= 0.0;
1082 m_vAdjust
->upper
= 1.0;
1083 m_vAdjust
->value
= 0.0;
1084 m_vAdjust
->step_increment
= 1.0;
1085 m_vAdjust
->page_increment
= 1.0;
1086 m_vAdjust
->page_size
= 5.0;
1087 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1088 m_hAdjust
->lower
= 0.0;
1089 m_hAdjust
->upper
= 1.0;
1090 m_hAdjust
->value
= 0.0;
1091 m_hAdjust
->step_increment
= 1.0;
1092 m_hAdjust
->page_increment
= 1.0;
1093 m_hAdjust
->page_size
= 5.0;
1094 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1096 // these handlers block mouse events to any window during scrolling
1097 // such as motion events and prevent GTK and wxWindows from fighting
1098 // over where the slider should be
1100 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1101 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1103 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1104 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1106 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1107 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1109 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1110 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1112 // these handers het notified when screen updates are required either when
1113 // scrolling or when the window size (and therefore scrollbar configuration)
1116 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1117 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1118 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1119 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1121 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1122 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1123 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1124 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1126 gtk_widget_show( m_wxwindow
);
1128 if (m_parent
) m_parent
->AddChild( this );
1130 (m_parent
->m_insertCallback
)( m_parent
, this );
1139 wxWindow::~wxWindow()
1143 if (m_dropTarget
) delete m_dropTarget
;
1145 if (m_parent
) m_parent
->RemoveChild( this );
1146 if (m_widget
) Show( FALSE
);
1150 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1152 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1154 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1156 if (m_widget
) gtk_widget_destroy( m_widget
);
1158 if (m_cursor
) delete m_cursor
;
1160 DeleteRelatedConstraints();
1163 // This removes any dangling pointers to this window
1164 // in other windows' constraintsInvolvedIn lists.
1165 UnsetConstraints(m_constraints
);
1166 delete m_constraints
;
1167 m_constraints
= (wxLayoutConstraints
*) NULL
;
1171 delete m_windowSizer
;
1172 m_windowSizer
= (wxSizer
*) NULL
;
1174 // If this is a child of a sizer, remove self from parent
1175 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1177 // Just in case the window has been Closed, but
1178 // we're then deleting immediately: don't leave
1179 // dangling pointers.
1180 wxPendingDelete
.DeleteObject(this);
1182 // Just in case we've loaded a top-level window via
1183 // wxWindow::LoadNativeDialog but we weren't a dialog
1185 wxTopLevelWindows
.DeleteObject(this);
1187 if (m_windowValidator
) delete m_windowValidator
;
1189 if (m_clientObject
) delete m_clientObject
;
1192 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1193 const wxPoint
&pos
, const wxSize
&size
,
1194 long style
, const wxString
&name
)
1196 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1198 m_widget
= (GtkWidget
*) NULL
;
1199 m_wxwindow
= (GtkWidget
*) NULL
;
1202 m_children
.DeleteContents( FALSE
);
1205 if (m_width
== -1) m_width
= 20;
1207 if (m_height
== -1) m_height
= 20;
1212 if (!m_needParent
) // some reasonable defaults
1216 m_x
= (gdk_screen_width () - m_width
) / 2;
1217 if (m_x
< 10) m_x
= 10;
1221 m_y
= (gdk_screen_height () - m_height
) / 2;
1222 if (m_y
< 10) m_y
= 10;
1233 m_eventHandler
= this;
1235 m_windowId
= id
== -1 ? wxNewId() : id
;
1239 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1240 m_font
= *wxSWISS_FONT
;
1241 // m_backgroundColour = wxWHITE;
1242 // m_foregroundColour = wxBLACK;
1243 m_windowStyle
= style
;
1244 m_windowName
= name
;
1246 m_constraints
= (wxLayoutConstraints
*) NULL
;
1247 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1248 m_windowSizer
= (wxSizer
*) NULL
;
1249 m_sizerParent
= (wxWindow
*) NULL
;
1250 m_autoLayout
= FALSE
;
1252 m_hasScrolling
= FALSE
;
1253 m_isScrolling
= FALSE
;
1254 m_hAdjust
= (GtkAdjustment
*) NULL
;
1255 m_vAdjust
= (GtkAdjustment
*) NULL
;
1256 m_oldHorizontalPos
= 0.0;
1257 m_oldVerticalPos
= 0.0;
1262 m_dropTarget
= (wxDropTarget
*) NULL
;
1264 m_windowValidator
= (wxValidator
*) NULL
;
1265 m_scrollGC
= (GdkGC
*) NULL
;
1266 m_widgetStyle
= (GtkStyle
*) NULL
;
1268 m_clientObject
= (wxClientData
*)NULL
;
1269 m_clientData
= NULL
;
1272 void wxWindow::PostCreation()
1276 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1277 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1279 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1280 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1283 ConnectWidget( GetConnectWidget() );
1285 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1287 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1289 SetCursor( *wxSTANDARD_CURSOR
);
1294 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1296 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1297 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1299 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1300 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1302 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1303 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1305 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1306 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1308 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1309 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1311 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1312 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1314 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1315 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1317 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1318 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1321 bool wxWindow::HasVMT()
1326 bool wxWindow::Close( bool force
)
1328 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1330 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1331 event
.SetEventObject(this);
1332 event
.SetForce(force
);
1334 return GetEventHandler()->ProcessEvent(event
);
1337 bool wxWindow::Destroy()
1339 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1346 bool wxWindow::DestroyChildren()
1349 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1352 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1355 if (m_children
.Member(child
)) delete node
;
1361 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1363 // are we to set fonts here ?
1366 wxPoint
wxWindow::GetClientAreaOrigin() const
1368 return wxPoint(0,0);
1371 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1373 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1375 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1381 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1383 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1384 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1386 if (m_resizing
) return; // I don't like recursions
1389 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1391 // don't set the size for children of wxNotebook, just take the values.
1399 int old_width
= m_width
;
1400 int old_height
= m_height
;
1402 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1404 if (x
!= -1) m_x
= x
;
1405 if (y
!= -1) m_y
= y
;
1406 if (width
!= -1) m_width
= width
;
1407 if (height
!= -1) m_height
= height
;
1417 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1419 if (width
== -1) m_width
= 80;
1422 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1424 if (height
== -1) m_height
= 26;
1427 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1428 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1429 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1430 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1432 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1433 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1435 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1436 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1441 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1442 event
.SetEventObject( this );
1443 GetEventHandler()->ProcessEvent( event
);
1448 void wxWindow::SetSize( int width
, int height
)
1450 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1453 void wxWindow::Move( int x
, int y
)
1455 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1458 void wxWindow::GetSize( int *width
, int *height
) const
1460 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1462 if (width
) (*width
) = m_width
;
1463 if (height
) (*height
) = m_height
;
1466 void wxWindow::SetClientSize( int width
, int height
)
1468 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1472 SetSize( width
, height
);
1479 if (!m_hasScrolling
)
1481 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1483 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1484 (m_windowStyle
& wxSUNKEN_BORDER
))
1486 dw
+= 2 * window_class
->xthickness
;
1487 dh
+= 2 * window_class
->ythickness
;
1492 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1493 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1495 #ifdef NEW_GTK_SCROLL_CODE
1496 GtkWidget
*viewport
= scroll_window
->child
;
1498 GtkWidget
*viewport
= scroll_window
->viewport
;
1501 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1503 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1504 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1506 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1507 (m_windowStyle
& wxSUNKEN_BORDER
))
1509 dw
+= 2 * viewport_class
->xthickness
;
1510 dh
+= 2 * viewport_class
->ythickness
;
1513 if (scroll_window
->vscrollbar_visible
)
1515 dw
+= vscrollbar
->allocation
.width
;
1516 dw
+= scroll_class
->scrollbar_spacing
;
1519 if (scroll_window
->hscrollbar_visible
)
1521 dh
+= hscrollbar
->allocation
.height
;
1522 dw
+= scroll_class
->scrollbar_spacing
;
1526 SetSize( width
+dw
, height
+dh
);
1530 void wxWindow::GetClientSize( int *width
, int *height
) const
1532 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1536 if (width
) (*width
) = m_width
;
1537 if (height
) (*height
) = m_height
;
1544 if (!m_hasScrolling
)
1546 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1548 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1549 (m_windowStyle
& wxSUNKEN_BORDER
))
1551 dw
+= 2 * window_class
->xthickness
;
1552 dh
+= 2 * window_class
->ythickness
;
1557 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1558 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1560 #ifdef NEW_GTK_SCROLL_CODE
1561 GtkWidget
*viewport
= scroll_window
->child
;
1563 GtkWidget
*viewport
= scroll_window
->viewport
;
1566 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1568 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1569 (m_windowStyle
& wxSUNKEN_BORDER
))
1571 dw
+= 2 * viewport_class
->xthickness
;
1572 dh
+= 2 * viewport_class
->ythickness
;
1575 if (scroll_window
->vscrollbar_visible
)
1577 // dw += vscrollbar->allocation.width;
1578 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1579 dw
+= scroll_class
->scrollbar_spacing
;
1582 if (scroll_window
->hscrollbar_visible
)
1584 // dh += hscrollbar->allocation.height;
1586 dh
+= scroll_class
->scrollbar_spacing
;
1590 if (width
) (*width
) = m_width
- dw
;
1591 if (height
) (*height
) = m_height
- dh
;
1595 void wxWindow::GetPosition( int *x
, int *y
) const
1597 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1603 void wxWindow::ClientToScreen( int *x
, int *y
)
1605 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1607 GdkWindow
*source
= (GdkWindow
*) NULL
;
1609 source
= m_wxwindow
->window
;
1611 source
= m_widget
->window
;
1615 gdk_window_get_origin( source
, &org_x
, &org_y
);
1619 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1621 org_x
+= m_widget
->allocation
.x
;
1622 org_y
+= m_widget
->allocation
.y
;
1626 wxPoint
pt(GetClientAreaOrigin());
1634 void wxWindow::ScreenToClient( int *x
, int *y
)
1636 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1638 GdkWindow
*source
= (GdkWindow
*) NULL
;
1640 source
= m_wxwindow
->window
;
1642 source
= m_widget
->window
;
1646 gdk_window_get_origin( source
, &org_x
, &org_y
);
1650 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1652 org_x
+= m_widget
->allocation
.x
;
1653 org_y
+= m_widget
->allocation
.y
;
1657 wxPoint
pt(GetClientAreaOrigin());
1665 void wxWindow::Centre( int direction
)
1667 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1676 m_parent
->GetSize( &p_w
, &p_h
);
1677 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
1678 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
1682 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
1683 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
1689 void wxWindow::Fit()
1691 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1695 wxNode
*node
= m_children
.First();
1698 wxWindow
*win
= (wxWindow
*)node
->Data();
1700 win
->GetPosition(&wx
, &wy
);
1701 win
->GetSize(&ww
, &wh
);
1702 if ( wx
+ ww
> maxX
)
1704 if ( wy
+ wh
> maxY
)
1707 node
= node
->Next();
1709 SetClientSize(maxX
+ 5, maxY
+ 10);
1712 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1714 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1722 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1724 // if (GetAutoLayout()) Layout();
1727 bool wxWindow::Show( bool show
)
1729 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1732 gtk_widget_show( m_widget
);
1734 gtk_widget_hide( m_widget
);
1739 void wxWindow::Enable( bool enable
)
1741 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1743 m_isEnabled
= enable
;
1744 gtk_widget_set_sensitive( m_widget
, enable
);
1745 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1748 int wxWindow::GetCharHeight() const
1750 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1754 wxFAIL_MSG( "invalid font" );
1758 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1759 return font
->ascent
+ font
->descent
;
1762 int wxWindow::GetCharWidth() const
1764 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1768 wxFAIL_MSG( "invalid font" );
1772 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1773 return gdk_string_width( font
, "H" );
1776 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1777 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1779 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1781 wxFont fontToUse
= m_font
;
1782 if (theFont
) fontToUse
= *theFont
;
1784 if (!fontToUse
.Ok())
1786 wxFAIL_MSG( "invalid font" );
1789 wxASSERT_MSG( (m_font
.Ok()), "invalid font" );
1791 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1792 if (x
) (*x
) = gdk_string_width( font
, string
);
1793 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1794 if (descent
) (*descent
) = font
->descent
;
1795 if (externalLeading
) (*externalLeading
) = 0; // ??
1798 void wxWindow::MakeModal( bool modal
)
1801 // Disable all other windows
1802 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1804 wxNode
*node
= wxTopLevelWindows
.First();
1807 wxWindow
*win
= (wxWindow
*)node
->Data();
1809 win
->Enable(!modal
);
1811 node
= node
->Next();
1816 void wxWindow::SetFocus()
1818 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1820 GtkWidget
*connect_widget
= GetConnectWidget();
1823 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1825 gtk_widget_grab_focus (connect_widget
);
1830 bool wxWindow::OnClose()
1835 void wxWindow::AddChild( wxWindow
*child
)
1837 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1838 wxASSERT_MSG( (child
!= NULL
), "invalid child" );
1840 m_children
.Append( child
);
1843 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
1845 wxWindow
*oldParent
= GetParent();
1847 if (oldParent
) oldParent
->RemoveChild( this );
1849 gtk_widget_unparent( m_widget
);
1853 newParent
->AddChild( this );
1854 (newParent
->m_insertCallback
)( newParent
, this );
1860 void wxWindow::RemoveChild( wxWindow
*child
)
1862 m_children
.DeleteObject( child
);
1863 child
->m_parent
= (wxWindow
*) NULL
;
1866 void wxWindow::SetReturnCode( int retCode
)
1868 m_retCode
= retCode
;
1871 int wxWindow::GetReturnCode()
1876 void wxWindow::Raise()
1878 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1880 if (m_widget
) gdk_window_raise( m_widget
->window
);
1883 void wxWindow::Lower()
1885 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1887 if (m_widget
) gdk_window_lower( m_widget
->window
);
1890 wxEvtHandler
*wxWindow::GetEventHandler() const
1892 return m_eventHandler
;
1895 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1897 m_eventHandler
= handler
;
1900 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1902 handler
->SetNextHandler(GetEventHandler());
1903 SetEventHandler(handler
);
1906 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1908 if (GetEventHandler())
1910 wxEvtHandler
*handlerA
= GetEventHandler();
1911 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
1912 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
1913 SetEventHandler(handlerB
);
1917 return (wxEvtHandler
*) NULL
;
1923 return (wxEvtHandler
*) NULL
;
1926 wxValidator
*wxWindow::GetValidator()
1928 return m_windowValidator
;
1931 void wxWindow::SetValidator( const wxValidator
& validator
)
1933 if (m_windowValidator
) delete m_windowValidator
;
1934 m_windowValidator
= validator
.Clone();
1935 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
1938 void wxWindow::SetClientObject( wxClientData
*data
)
1940 if (m_clientObject
) delete m_clientObject
;
1941 m_clientObject
= data
;
1944 wxClientData
*wxWindow::GetClientObject()
1946 return m_clientObject
;
1949 void wxWindow::SetClientData( void *data
)
1951 m_clientData
= data
;
1954 void *wxWindow::GetClientData()
1956 return m_clientData
;
1959 bool wxWindow::IsBeingDeleted()
1964 void wxWindow::SetId( wxWindowID id
)
1969 wxWindowID
wxWindow::GetId() const
1974 void wxWindow::SetCursor( const wxCursor
&cursor
)
1976 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1978 if (m_cursor
== NULL
)
1980 wxFAIL_MSG( "wxWindow::SetCursor m_cursor == NULL" );
1981 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1986 if ( cursor
== *m_cursor
)
1992 *m_cursor
= *wxSTANDARD_CURSOR
;
1995 if ((m_widget
) && (m_widget
->window
))
1996 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
1998 if ((m_wxwindow
) && (m_wxwindow
->window
))
1999 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2002 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2004 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2006 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2010 gdk_window_clear_area( m_wxwindow
->window
,
2024 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2026 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2030 GdkRectangle gdk_rect
;
2031 gdk_rect
.x
= rect
->x
;
2032 gdk_rect
.y
= rect
->y
;
2033 gdk_rect
.width
= rect
->width
;
2034 gdk_rect
.height
= rect
->height
;
2037 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2039 gtk_widget_draw( m_widget
, &gdk_rect
);
2043 wxRegion
wxWindow::GetUpdateRegion() const
2045 return m_updateRegion
;
2048 bool wxWindow::IsExposed( int x
, int y
) const
2050 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2053 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2055 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2058 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2060 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2063 bool wxWindow::IsExposed( const wxRect
& rect
) const
2065 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2068 void wxWindow::Clear()
2070 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2072 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2075 wxColour
wxWindow::GetBackgroundColour() const
2077 return m_backgroundColour
;
2080 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2082 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2084 if (m_backgroundColour
== colour
) return;
2086 if (!m_backgroundColour
.Ok())
2087 if (wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
) == colour
) return;
2089 m_backgroundColour
= colour
;
2090 if (!m_backgroundColour
.Ok()) return;
2094 GdkWindow
*window
= m_wxwindow
->window
;
2095 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2096 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2097 gdk_window_clear( window
);
2103 wxColour
wxWindow::GetForegroundColour() const
2105 return m_foregroundColour
;
2108 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2110 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2112 if (m_foregroundColour
== colour
) return;
2114 m_foregroundColour
= colour
;
2115 if (!m_foregroundColour
.Ok()) return;
2120 GtkStyle
*wxWindow::GetWidgetStyle()
2122 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2126 gtk_widget_get_style( m_widget
) );
2128 return m_widgetStyle
;
2131 void wxWindow::SetWidgetStyle()
2133 GtkStyle
*style
= GetWidgetStyle();
2135 gdk_font_unref( style
->font
);
2136 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2138 if (m_foregroundColour
.Ok())
2140 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2141 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2142 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2143 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2146 if (m_backgroundColour
.Ok())
2148 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2149 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2150 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2151 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2152 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2153 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2154 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2155 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2156 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2160 void wxWindow::ApplyWidgetStyle()
2164 bool wxWindow::Validate()
2166 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2168 wxNode
*node
= m_children
.First();
2171 wxWindow
*child
= (wxWindow
*)node
->Data();
2172 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2174 node
= node
->Next();
2179 bool wxWindow::TransferDataToWindow()
2181 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2183 wxNode
*node
= m_children
.First();
2186 wxWindow
*child
= (wxWindow
*)node
->Data();
2187 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2188 !child
->GetValidator()->TransferToWindow() )
2190 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2193 node
= node
->Next();
2198 bool wxWindow::TransferDataFromWindow()
2200 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2202 wxNode
*node
= m_children
.First();
2205 wxWindow
*child
= (wxWindow
*)node
->Data();
2206 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2208 node
= node
->Next();
2213 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2215 m_acceleratorTable
= accel
;
2218 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2220 TransferDataToWindow();
2223 void wxWindow::InitDialog()
2225 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2227 wxInitDialogEvent
event(GetId());
2228 event
.SetEventObject( this );
2229 GetEventHandler()->ProcessEvent(event
);
2232 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2234 menu
->SetInvokingWindow( win
);
2235 wxNode
*node
= menu
->m_items
.First();
2238 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2239 if (menuitem
->IsSubMenu())
2240 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2241 node
= node
->Next();
2245 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2247 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2249 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2251 SetInvokingWindow( menu
, this );
2253 GTK_MENU(menu
->m_menu
),
2254 (GtkWidget
*)NULL
, // parent menu shell
2255 (GtkWidget
*)NULL
, // parent menu item
2256 (GtkMenuPositionFunc
)NULL
,
2257 NULL
, // client data
2258 0, // button used to activate it
2259 0//gs_timeLastClick // the time of activation
2264 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2266 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2268 GtkWidget
*dnd_widget
= GetConnectWidget();
2270 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2272 if (m_dropTarget
) delete m_dropTarget
;
2273 m_dropTarget
= dropTarget
;
2275 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2278 wxDropTarget
*wxWindow::GetDropTarget() const
2280 return m_dropTarget
;
2283 GtkWidget
* wxWindow::GetConnectWidget()
2285 GtkWidget
*connect_widget
= m_widget
;
2286 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2288 return connect_widget
;
2291 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2293 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2294 return (window
== m_widget
->window
);
2297 void wxWindow::SetFont( const wxFont
&font
)
2299 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2301 if (((wxFont
*)&font
)->Ok())
2304 m_font
= *wxSWISS_FONT
;
2309 void wxWindow::SetWindowStyleFlag( long flag
)
2311 m_windowStyle
= flag
;
2314 long wxWindow::GetWindowStyleFlag() const
2316 return m_windowStyle
;
2319 void wxWindow::CaptureMouse()
2321 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2323 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2325 GtkWidget
*connect_widget
= GetConnectWidget();
2326 gtk_grab_add( connect_widget
);
2327 gdk_pointer_grab ( connect_widget
->window
, FALSE
,
2329 (GDK_BUTTON_PRESS_MASK
|
2330 GDK_BUTTON_RELEASE_MASK
|
2331 GDK_POINTER_MOTION_MASK
),
2332 (GdkWindow
*) NULL
, (GdkCursor
*) NULL
, GDK_CURRENT_TIME
);
2336 void wxWindow::ReleaseMouse()
2338 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2340 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2342 GtkWidget
*connect_widget
= GetConnectWidget();
2343 gtk_grab_remove( connect_widget
);
2344 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2345 g_capturing
= FALSE
;
2348 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2352 wxString
wxWindow::GetTitle() const
2354 return (wxString
&)m_windowName
;
2357 wxString
wxWindow::GetLabel() const
2362 void wxWindow::SetName( const wxString
&name
)
2364 m_windowName
= name
;
2367 wxString
wxWindow::GetName() const
2369 return (wxString
&)m_windowName
;
2372 bool wxWindow::IsShown() const
2377 bool wxWindow::IsRetained()
2382 wxWindow
*wxWindow::FindWindow( long id
)
2384 if (id
== m_windowId
) return this;
2385 wxNode
*node
= m_children
.First();
2388 wxWindow
*child
= (wxWindow
*)node
->Data();
2389 wxWindow
*res
= child
->FindWindow( id
);
2390 if (res
) return res
;
2391 node
= node
->Next();
2393 return (wxWindow
*) NULL
;
2396 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2398 if (name
== m_windowName
) return this;
2399 wxNode
*node
= m_children
.First();
2402 wxWindow
*child
= (wxWindow
*)node
->Data();
2403 wxWindow
*res
= child
->FindWindow( name
);
2404 if (res
) return res
;
2405 node
= node
->Next();
2407 return (wxWindow
*) NULL
;
2410 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2411 int range
, bool refresh
)
2413 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2415 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2417 if (!m_wxwindow
) return;
2419 m_hasScrolling
= TRUE
;
2421 if (orient
== wxHORIZONTAL
)
2423 float fpos
= (float)pos
;
2424 float frange
= (float)range
;
2425 float fthumb
= (float)thumbVisible
;
2426 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2427 if (fpos
< 0.0) fpos
= 0.0;
2429 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2430 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2432 SetScrollPos( orient
, pos
, refresh
);
2436 m_oldHorizontalPos
= fpos
;
2438 m_hAdjust
->lower
= 0.0;
2439 m_hAdjust
->upper
= frange
;
2440 m_hAdjust
->value
= fpos
;
2441 m_hAdjust
->step_increment
= 1.0;
2442 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2443 m_hAdjust
->page_size
= fthumb
;
2447 float fpos
= (float)pos
;
2448 float frange
= (float)range
;
2449 float fthumb
= (float)thumbVisible
;
2450 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2451 if (fpos
< 0.0) fpos
= 0.0;
2453 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2454 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2456 SetScrollPos( orient
, pos
, refresh
);
2460 m_oldVerticalPos
= fpos
;
2462 m_vAdjust
->lower
= 0.0;
2463 m_vAdjust
->upper
= frange
;
2464 m_vAdjust
->value
= fpos
;
2465 m_vAdjust
->step_increment
= 1.0;
2466 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2467 m_vAdjust
->page_size
= fthumb
;
2470 if (m_wxwindow
->window
)
2472 if (orient
== wxHORIZONTAL
)
2473 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2475 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2477 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2481 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2483 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2485 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2487 if (!m_wxwindow
) return;
2489 if (orient
== wxHORIZONTAL
)
2491 float fpos
= (float)pos
;
2492 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2493 if (fpos
< 0.0) fpos
= 0.0;
2494 m_oldHorizontalPos
= fpos
;
2496 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2497 m_hAdjust
->value
= fpos
;
2501 float fpos
= (float)pos
;
2502 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2503 if (fpos
< 0.0) fpos
= 0.0;
2504 m_oldVerticalPos
= fpos
;
2506 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2507 m_vAdjust
->value
= fpos
;
2512 if (m_wxwindow
->window
)
2514 if (orient
== wxHORIZONTAL
)
2515 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2517 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2522 int wxWindow::GetScrollThumb( int orient
) const
2524 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2526 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2528 if (!m_wxwindow
) return 0;
2530 if (orient
== wxHORIZONTAL
)
2531 return (int)(m_hAdjust
->page_size
+0.5);
2533 return (int)(m_vAdjust
->page_size
+0.5);
2536 int wxWindow::GetScrollPos( int orient
) const
2538 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2540 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2542 if (!m_wxwindow
) return 0;
2544 if (orient
== wxHORIZONTAL
)
2545 return (int)(m_hAdjust
->value
+0.5);
2547 return (int)(m_vAdjust
->value
+0.5);
2550 int wxWindow::GetScrollRange( int orient
) const
2552 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2554 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2556 if (!m_wxwindow
) return 0;
2558 if (orient
== wxHORIZONTAL
)
2559 return (int)(m_hAdjust
->upper
+0.5);
2561 return (int)(m_vAdjust
->upper
+0.5);
2564 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2566 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2568 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2570 if (!m_wxwindow
) return;
2574 GetClientSize( &cw
, &ch
);
2576 int w
= cw
- abs(dx
);
2577 int h
= ch
- abs(dy
);
2578 if ((h
< 0) || (w
< 0))
2585 if (dx
< 0) s_x
= -dx
;
2586 if (dy
< 0) s_y
= -dy
;
2589 if (dx
> 0) d_x
= dx
;
2590 if (dy
> 0) d_y
= dy
;
2594 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2595 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2598 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2599 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2602 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2603 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2604 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2605 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2607 Refresh( TRUE
, &rect
);
2610 //-------------------------------------------------------------------------------------
2612 //-------------------------------------------------------------------------------------
2614 wxLayoutConstraints
*wxWindow::GetConstraints() const
2616 return m_constraints
;
2619 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2623 UnsetConstraints(m_constraints
);
2624 delete m_constraints
;
2626 m_constraints
= constraints
;
2629 // Make sure other windows know they're part of a 'meaningful relationship'
2630 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2631 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2632 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2633 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2634 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2635 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2636 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2637 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2638 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2639 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2640 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2641 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2642 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2643 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2644 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2645 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2651 void wxWindow::SetAutoLayout( bool autoLayout
)
2653 m_autoLayout
= autoLayout
;
2656 bool wxWindow::GetAutoLayout() const
2658 return m_autoLayout
;
2661 wxSizer
*wxWindow::GetSizer() const
2663 return m_windowSizer
;
2666 void wxWindow::SetSizerParent( wxWindow
*win
)
2668 m_sizerParent
= win
;
2671 wxWindow
*wxWindow::GetSizerParent() const
2673 return m_sizerParent
;
2676 // This removes any dangling pointers to this window
2677 // in other windows' constraintsInvolvedIn lists.
2678 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2682 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2683 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2684 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2685 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2686 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2687 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2688 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2689 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2690 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2691 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2692 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2693 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2694 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2695 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2696 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2697 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2701 // Back-pointer to other windows we're involved with, so if we delete
2702 // this window, we must delete any constraints we're involved with.
2703 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2705 if (!m_constraintsInvolvedIn
)
2706 m_constraintsInvolvedIn
= new wxList
;
2707 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2708 m_constraintsInvolvedIn
->Append(otherWin
);
2711 // REMOVE back-pointer to other windows we're involved with.
2712 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2714 if (m_constraintsInvolvedIn
)
2715 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2718 // Reset any constraints that mention this window
2719 void wxWindow::DeleteRelatedConstraints()
2721 if (m_constraintsInvolvedIn
)
2723 wxNode
*node
= m_constraintsInvolvedIn
->First();
2726 wxWindow
*win
= (wxWindow
*)node
->Data();
2727 wxNode
*next
= node
->Next();
2728 wxLayoutConstraints
*constr
= win
->GetConstraints();
2730 // Reset any constraints involving this window
2733 constr
->left
.ResetIfWin((wxWindow
*)this);
2734 constr
->top
.ResetIfWin((wxWindow
*)this);
2735 constr
->right
.ResetIfWin((wxWindow
*)this);
2736 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2737 constr
->width
.ResetIfWin((wxWindow
*)this);
2738 constr
->height
.ResetIfWin((wxWindow
*)this);
2739 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2740 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2745 delete m_constraintsInvolvedIn
;
2746 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2750 void wxWindow::SetSizer(wxSizer
*sizer
)
2752 m_windowSizer
= sizer
;
2754 sizer
->SetSizerParent((wxWindow
*)this);
2761 bool wxWindow::Layout()
2763 if (GetConstraints())
2766 GetClientSize(&w
, &h
);
2767 GetConstraints()->width
.SetValue(w
);
2768 GetConstraints()->height
.SetValue(h
);
2771 // If top level (one sizer), evaluate the sizer's constraints.
2775 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2776 GetSizer()->LayoutPhase1(&noChanges
);
2777 GetSizer()->LayoutPhase2(&noChanges
);
2778 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2783 // Otherwise, evaluate child constraints
2784 ResetConstraints(); // Mark all constraints as unevaluated
2785 DoPhase(1); // Just one phase need if no sizers involved
2787 SetConstraintSizes(); // Recursively set the real window sizes
2793 // Do a phase of evaluating constraints:
2794 // the default behaviour. wxSizers may do a similar
2795 // thing, but also impose their own 'constraints'
2796 // and order the evaluation differently.
2797 bool wxWindow::LayoutPhase1(int *noChanges
)
2799 wxLayoutConstraints
*constr
= GetConstraints();
2802 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2808 bool wxWindow::LayoutPhase2(int *noChanges
)
2818 // Do a phase of evaluating child constraints
2819 bool wxWindow::DoPhase(int phase
)
2821 int noIterations
= 0;
2822 int maxIterations
= 500;
2826 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2830 wxNode
*node
= m_children
.First();
2833 wxWindow
*child
= (wxWindow
*)node
->Data();
2834 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2836 wxLayoutConstraints
*constr
= child
->GetConstraints();
2839 if (succeeded
.Member(child
))
2844 int tempNoChanges
= 0;
2845 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2846 noChanges
+= tempNoChanges
;
2849 succeeded
.Append(child
);
2854 node
= node
->Next();
2861 void wxWindow::ResetConstraints()
2863 wxLayoutConstraints
*constr
= GetConstraints();
2866 constr
->left
.SetDone(FALSE
);
2867 constr
->top
.SetDone(FALSE
);
2868 constr
->right
.SetDone(FALSE
);
2869 constr
->bottom
.SetDone(FALSE
);
2870 constr
->width
.SetDone(FALSE
);
2871 constr
->height
.SetDone(FALSE
);
2872 constr
->centreX
.SetDone(FALSE
);
2873 constr
->centreY
.SetDone(FALSE
);
2875 wxNode
*node
= m_children
.First();
2878 wxWindow
*win
= (wxWindow
*)node
->Data();
2879 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2880 win
->ResetConstraints();
2881 node
= node
->Next();
2885 // Need to distinguish between setting the 'fake' size for
2886 // windows and sizers, and setting the real values.
2887 void wxWindow::SetConstraintSizes(bool recurse
)
2889 wxLayoutConstraints
*constr
= GetConstraints();
2890 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2891 constr
->width
.GetDone() && constr
->height
.GetDone())
2893 int x
= constr
->left
.GetValue();
2894 int y
= constr
->top
.GetValue();
2895 int w
= constr
->width
.GetValue();
2896 int h
= constr
->height
.GetValue();
2898 // If we don't want to resize this window, just move it...
2899 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2900 (constr
->height
.GetRelationship() != wxAsIs
))
2902 // Calls Layout() recursively. AAAGH. How can we stop that.
2903 // Simply take Layout() out of non-top level OnSizes.
2904 SizerSetSize(x
, y
, w
, h
);
2913 char *windowClass
= this->GetClassInfo()->GetClassName();
2916 if (GetName() == "")
2917 winName
= "unnamed";
2919 winName
= GetName();
2920 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
2921 (const char *)windowClass
,
2922 (const char *)winName
);
2923 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
2924 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
2925 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
2926 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
2927 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
2932 wxNode
*node
= m_children
.First();
2935 wxWindow
*win
= (wxWindow
*)node
->Data();
2936 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2937 win
->SetConstraintSizes();
2938 node
= node
->Next();
2943 // This assumes that all sizers are 'on' the same
2944 // window, i.e. the parent of this window.
2945 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
2947 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
2948 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
2952 m_sizerParent
->GetPosition(&xp
, &yp
);
2953 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
2958 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
2962 TransformSizerToActual(&xx
, &yy
);
2963 SetSize(xx
, yy
, w
, h
);
2966 void wxWindow::SizerMove(int x
, int y
)
2970 TransformSizerToActual(&xx
, &yy
);
2974 // Only set the size/position of the constraint (if any)
2975 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
2977 wxLayoutConstraints
*constr
= GetConstraints();
2982 constr
->left
.SetValue(x
);
2983 constr
->left
.SetDone(TRUE
);
2987 constr
->top
.SetValue(y
);
2988 constr
->top
.SetDone(TRUE
);
2992 constr
->width
.SetValue(w
);
2993 constr
->width
.SetDone(TRUE
);
2997 constr
->height
.SetValue(h
);
2998 constr
->height
.SetDone(TRUE
);
3003 void wxWindow::MoveConstraint(int x
, int y
)
3005 wxLayoutConstraints
*constr
= GetConstraints();
3010 constr
->left
.SetValue(x
);
3011 constr
->left
.SetDone(TRUE
);
3015 constr
->top
.SetValue(y
);
3016 constr
->top
.SetDone(TRUE
);
3021 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3023 wxLayoutConstraints
*constr
= GetConstraints();
3026 *w
= constr
->width
.GetValue();
3027 *h
= constr
->height
.GetValue();
3033 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3035 wxLayoutConstraints
*constr
= GetConstraints();
3038 *w
= constr
->width
.GetValue();
3039 *h
= constr
->height
.GetValue();
3042 GetClientSize(w
, h
);
3045 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3047 wxLayoutConstraints
*constr
= GetConstraints();
3050 *x
= constr
->left
.GetValue();
3051 *y
= constr
->top
.GetValue();
3057 bool wxWindow::AcceptsFocus() const
3059 return IsEnabled() && IsShown();
3062 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )