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 #if wxUSE_DRAG_AND_DROP
28 #include "wx/statusbr.h"
30 #include "wx/settings.h"
37 #include "gdk/gdkprivate.h"
38 #include "gdk/gdkkeysyms.h"
39 #include "wx/gtk/win_gtk.h"
41 //-----------------------------------------------------------------------------
42 // documentation on internals
43 //-----------------------------------------------------------------------------
46 I have been asked several times about writing some documentation about
47 the GTK port of wxWindows, especially its internal structures. Obviously,
48 you cannot understand wxGTK without knowing a little about the GTK, but
49 some more information about what the wxWindow, which is the base class
50 for all other window classes, does seems required as well.
52 What does wxWindow do? It contains the common interface for the following
53 jobs of its descendants:
55 1) Define the rudimentary behaviour common to all window classes, such as
56 resizing, intercepting user input (so as to make it possible to use these
57 events for special purposes in a derived class), window names etc.
59 2) Provide the possibility to contain and manage children, if the derived
60 class is allowed to contain children, which holds true for those window
61 classes which do not display a native GTK widget. To name them, these
62 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
63 work classes are a special case and are handled a bit differently from
64 the rest. The same holds true for the wxNotebook class.
66 3) Provide the possibility to draw into a client area of a window. This,
67 too, only holds true for classes that do not display a native GTK widget
70 4) Provide the entire mechanism for scrolling widgets. This actual inter-
71 face for this is usually in wxScrolledWindow, but the GTK implementation
74 5) A multitude of helper or extra methods for special purposes, such as
75 Drag'n'Drop, managing validators etc.
77 Normally one might expect, that one wxWindows window would always correspond
78 to one GTK widget. Under GTK, there is no such allround widget that has all
79 the functionality. Moreover, the GTK defines a client area as a different
80 widget from the actual widget you are handling. Last but not least some
81 special classes (e.g. wxFrame) handle different categories of widgets and
82 still have the possibility to draw something in the client area.
83 It was therefore required to write a special purpose GTK widget, that would
84 represent a client area in the sense of wxWindows capable to do the jobs
85 2), 3) and 4). I have written this class and it resides in win_gtk.c of
88 All windows must have a widget, with which they interact with other under-
89 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
90 thw wxWindow class has a member variable called m_widget which holds a
91 pointer to this widget. When the window class represents a GTK native widget,
92 this is (in most cases) the only GTK widget the class manages. E.g. the
93 wxStatitText class handles only a GtkLabel widget a pointer to which you
94 can find in m_widget (defined in wxWindow)
96 When the class has a client area for drawing into and for containing children
97 it has to handle the client area widget (of the type GtkMyFixed, defined in
98 win_gtk.c), but there could be any number of widgets, handled by a class
99 The common rule for all windows is only, that the widget that interacts with
100 the rest of GTK must be referenced in m_widget and all other widgets must be
101 children of this widget on the GTK level. The top-most widget, which also
102 represents the client area, must be in the m_wxwindow field and must be of
105 As I said, the window classes that display a GTK native widget only have
106 one widget, so in the case of e.g. the wxButton class m_widget holds a
107 pointer to a GtkButton widget. But windows with client areas (for drawing
108 and children) have a m_widget field that is a pointer to a GtkScrolled-
109 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
110 one is (in the GTK sense) a child of the GtkScrolledWindow.
112 If the m_wxwindow field is set, then all input to this widget is inter-
113 cepted and sent to the wxWindows class. If not, all input to the widget
114 that gets pointed to by m_widget gets intercepted and sent to the class.
118 //-------------------------------------------------------------------------
119 // conditional compilation
120 //-------------------------------------------------------------------------
122 #if (GTK_MINOR_VERSION == 1)
123 #if (GTK_MICRO_VERSION >= 5)
124 #define NEW_GTK_SCROLL_CODE
128 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
134 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
135 GdkEvent
*WXUNUSED(event
),
138 printf( "FOCUS NOW AT: " );
145 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
153 char *s
= new char[tmp
.Length()+1];
155 strcpy( s
, WXSTRINGCAST tmp
);
157 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
158 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
163 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
167 extern wxList wxPendingDelete
;
168 extern wxList wxTopLevelWindows
;
169 extern bool g_blockEventsOnDrag
;
170 extern bool g_blockEventsOnScroll
;
171 static bool g_capturing
= FALSE
;
172 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
174 // hack: we need something to pass to gtk_menu_popup, so we store the time of
175 // the last click here
176 static guint32 gs_timeLastClick
= 0;
178 //-----------------------------------------------------------------------------
179 // "expose_event" (of m_wxwindow, not of m_widget)
180 //-----------------------------------------------------------------------------
182 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
184 if (!win
->HasVMT()) return;
186 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
188 gdk_event
->area
.width
,
189 gdk_event
->area
.height
);
191 if (gdk_event
->count
> 0) return;
194 printf( "OnExpose from " );
195 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
196 printf( win->GetClassInfo()->GetClassName() );
200 wxPaintEvent
event( win
->GetId() );
201 event
.SetEventObject( win
);
202 win
->GetEventHandler()->ProcessEvent( event
);
204 win
->m_updateRegion
.Clear();
207 //-----------------------------------------------------------------------------
208 // "draw" (of m_wxwindow, not of m_widget)
209 //-----------------------------------------------------------------------------
211 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
213 if (!win
->HasVMT()) return;
215 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
217 wxPaintEvent
event( win
->GetId() );
218 event
.SetEventObject( win
);
219 win
->GetEventHandler()->ProcessEvent( event
);
221 win
->m_updateRegion
.Clear();
224 //-----------------------------------------------------------------------------
225 // "key_press_event" from any window
226 //-----------------------------------------------------------------------------
228 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
230 if (!win
->HasVMT()) return FALSE
;
231 if (g_blockEventsOnDrag
) return FALSE
;
234 printf( "OnKeyPress from " );
235 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
236 printf( win->GetClassInfo()->GetClassName() );
241 switch (gdk_event
->keyval
)
243 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
244 case GDK_Tab
: key_code
= WXK_TAB
; break;
245 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
246 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
247 case GDK_Return
: key_code
= WXK_RETURN
; break;
248 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
249 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
250 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
251 case GDK_Delete
: key_code
= WXK_DELETE
; break;
252 case GDK_Home
: key_code
= WXK_HOME
; break;
253 case GDK_Left
: key_code
= WXK_LEFT
; break;
254 case GDK_Up
: key_code
= WXK_UP
; break;
255 case GDK_Right
: key_code
= WXK_RIGHT
; break;
256 case GDK_Down
: key_code
= WXK_DOWN
; break;
257 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
258 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
259 case GDK_Next
: key_code
= WXK_NEXT
; break;
260 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
261 case GDK_End
: key_code
= WXK_END
; break;
262 case GDK_Begin
: key_code
= WXK_HOME
; break;
263 case GDK_Select
: key_code
= WXK_SELECT
; break;
264 case GDK_Print
: key_code
= WXK_PRINT
; break;
265 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
266 case GDK_Insert
: key_code
= WXK_INSERT
; break;
267 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
268 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
269 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
270 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
271 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
272 case GDK_KP_Up
: key_code
= WXK_UP
; break;
273 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
274 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
275 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
276 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
277 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
278 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
279 case GDK_KP_End
: key_code
= WXK_END
; break;
280 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
281 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
282 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
283 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
284 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
285 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
286 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
287 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
288 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
289 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
290 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
291 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
292 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
293 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
294 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
295 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
296 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
297 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
298 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
299 case GDK_F1
: key_code
= WXK_F1
; break;
300 case GDK_F2
: key_code
= WXK_F2
; break;
301 case GDK_F3
: key_code
= WXK_F3
; break;
302 case GDK_F4
: key_code
= WXK_F4
; break;
303 case GDK_F5
: key_code
= WXK_F5
; break;
304 case GDK_F6
: key_code
= WXK_F6
; break;
305 case GDK_F7
: key_code
= WXK_F7
; break;
306 case GDK_F8
: key_code
= WXK_F8
; break;
307 case GDK_F9
: key_code
= WXK_F9
; break;
308 case GDK_F10
: key_code
= WXK_F10
; break;
309 case GDK_F11
: key_code
= WXK_F11
; break;
310 case GDK_F12
: key_code
= WXK_F12
; break;
313 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
314 key_code
= gdk_event
->keyval
;
318 if (!key_code
) return FALSE
;
320 wxKeyEvent
event( wxEVT_KEY_DOWN
);
321 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
322 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
323 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
324 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
325 event
.m_keyCode
= key_code
;
328 event
.SetEventObject( win
);
330 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
334 wxWindow
*ancestor
= win
;
337 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
340 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
341 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
344 ancestor
= ancestor
->GetParent();
348 // win is a control: tab can be propagated up
349 if ((!ret
) && (gdk_event
->keyval
== GDK_Tab
))
351 wxNavigationKeyEvent new_event
;
352 new_event
.SetDirection( !(gdk_event
->state
& GDK_SHIFT_MASK
) );
353 new_event
.SetWindowChange( FALSE
);
354 new_event
.SetCurrentFocus( win
);
355 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
359 // win is a panel: up can be propagated to the panel
360 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
361 (gdk_event->keyval == GDK_Up))
363 win->m_parent->SetFocus();
367 // win is a panel: left/right can be propagated to the panel
368 if ((!ret) && (win->m_wxwindow) &&
369 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
370 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
372 wxNavigationKeyEvent new_event;
373 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
374 new_event.SetCurrentFocus( win );
375 ret = win->GetEventHandler()->ProcessEvent( new_event );
381 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
387 //-----------------------------------------------------------------------------
388 // "key_release_event" from any window
389 //-----------------------------------------------------------------------------
391 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
393 if (!win
->HasVMT()) return FALSE
;
394 if (g_blockEventsOnDrag
) return FALSE
;
397 printf( "OnKeyRelease from " );
398 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
399 printf( win->GetClassInfo()->GetClassName() );
404 switch (gdk_event
->keyval
)
406 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
407 case GDK_Tab
: key_code
= WXK_TAB
; break;
408 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
409 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
410 case GDK_Return
: key_code
= WXK_RETURN
; break;
411 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
412 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
413 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
414 case GDK_Delete
: key_code
= WXK_DELETE
; break;
415 case GDK_Home
: key_code
= WXK_HOME
; break;
416 case GDK_Left
: key_code
= WXK_LEFT
; break;
417 case GDK_Up
: key_code
= WXK_UP
; break;
418 case GDK_Right
: key_code
= WXK_RIGHT
; break;
419 case GDK_Down
: key_code
= WXK_DOWN
; break;
420 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
421 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
422 case GDK_Next
: key_code
= WXK_NEXT
; break;
423 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
424 case GDK_End
: key_code
= WXK_END
; break;
425 case GDK_Begin
: key_code
= WXK_HOME
; break;
426 case GDK_Select
: key_code
= WXK_SELECT
; break;
427 case GDK_Print
: key_code
= WXK_PRINT
; break;
428 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
429 case GDK_Insert
: key_code
= WXK_INSERT
; break;
430 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
431 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
432 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
433 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
434 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
435 case GDK_KP_Up
: key_code
= WXK_UP
; break;
436 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
437 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
438 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
439 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
440 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
441 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
442 case GDK_KP_End
: key_code
= WXK_END
; break;
443 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
444 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
445 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
446 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
447 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
448 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
449 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
450 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
451 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
452 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
453 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
454 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
455 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
456 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
457 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
458 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
459 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
460 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
461 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
462 case GDK_F1
: key_code
= WXK_F1
; break;
463 case GDK_F2
: key_code
= WXK_F2
; break;
464 case GDK_F3
: key_code
= WXK_F3
; break;
465 case GDK_F4
: key_code
= WXK_F4
; break;
466 case GDK_F5
: key_code
= WXK_F5
; break;
467 case GDK_F6
: key_code
= WXK_F6
; break;
468 case GDK_F7
: key_code
= WXK_F7
; break;
469 case GDK_F8
: key_code
= WXK_F8
; break;
470 case GDK_F9
: key_code
= WXK_F9
; break;
471 case GDK_F10
: key_code
= WXK_F10
; break;
472 case GDK_F11
: key_code
= WXK_F11
; break;
473 case GDK_F12
: key_code
= WXK_F12
; break;
476 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
477 key_code
= gdk_event
->keyval
;
481 if (!key_code
) return FALSE
;
483 wxKeyEvent
event( wxEVT_KEY_UP
);
484 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
485 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
486 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
487 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
488 event
.m_keyCode
= key_code
;
491 event
.SetEventObject( win
);
493 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
497 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
503 //-----------------------------------------------------------------------------
504 // "button_press_event"
505 //-----------------------------------------------------------------------------
507 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
509 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
511 if (g_blockEventsOnDrag
) return TRUE
;
512 if (g_blockEventsOnScroll
) return TRUE
;
516 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
518 gtk_widget_grab_focus (win
->m_wxwindow
);
521 printf( "GrabFocus from " );
522 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
523 printf( win->GetClassInfo()->GetClassName() );
530 if (!win
->HasVMT()) return TRUE
;
533 printf( "OnButtonPress from " );
534 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
535 printf( win->GetClassInfo()->GetClassName() );
539 wxEventType event_type
= wxEVT_LEFT_DOWN
;
541 if (gdk_event
->button
== 1)
543 switch (gdk_event
->type
)
545 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
546 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
550 else if (gdk_event
->button
== 2)
552 switch (gdk_event
->type
)
554 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
555 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
559 else if (gdk_event
->button
== 3)
561 switch (gdk_event
->type
)
563 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
564 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
569 wxMouseEvent
event( event_type
);
570 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
571 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
572 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
573 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
574 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
575 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
576 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
578 event
.m_x
= (long)gdk_event
->x
;
579 event
.m_y
= (long)gdk_event
->y
;
581 // Some control don't have their own X window and thus cannot get
586 wxNode
*node
= win
->GetChildren().First();
589 wxWindow
*child
= (wxWindow
*)node
->Data();
591 if (child
->m_isStaticBox
)
593 // wxStaticBox is transparent in the box itself
596 int xx1
= child
->m_x
;
597 int yy1
= child
->m_y
;
598 int xx2
= child
->m_x
+ child
->m_width
;
599 int yy2
= child
->m_x
+ child
->m_height
;
602 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
604 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
606 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
608 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
611 event
.m_x
-= child
->m_x
;
612 event
.m_y
-= child
->m_y
;
619 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
620 (child
->m_x
<= event
.m_x
) &&
621 (child
->m_y
<= event
.m_y
) &&
622 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
623 (child
->m_y
+child
->m_height
>= event
.m_y
))
626 event
.m_x
-= child
->m_x
;
627 event
.m_y
-= child
->m_y
;
635 event
.SetEventObject( win
);
637 gs_timeLastClick
= gdk_event
->time
;
639 if (win
->GetEventHandler()->ProcessEvent( event
))
640 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
645 //-----------------------------------------------------------------------------
646 // "button_release_event"
647 //-----------------------------------------------------------------------------
649 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
651 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
653 if (g_blockEventsOnDrag
) return TRUE
;
654 if (g_blockEventsOnScroll
) return TRUE
;
656 if (!win
->HasVMT()) return TRUE
;
659 printf( "OnButtonRelease from " );
660 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
661 printf( win->GetClassInfo()->GetClassName() );
665 wxEventType event_type
= wxEVT_NULL
;
667 switch (gdk_event
->button
)
669 case 1: event_type
= wxEVT_LEFT_UP
; break;
670 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
671 case 3: event_type
= wxEVT_RIGHT_UP
; break;
674 wxMouseEvent
event( event_type
);
675 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
676 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
677 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
678 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
679 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
680 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
681 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
682 event
.m_x
= (long)gdk_event
->x
;
683 event
.m_y
= (long)gdk_event
->y
;
685 // Some control don't have their own X window and thus cannot get
690 wxNode
*node
= win
->GetChildren().First();
693 wxWindow
*child
= (wxWindow
*)node
->Data();
695 if (child
->m_isStaticBox
)
697 // wxStaticBox is transparent in the box itself
700 int xx1
= child
->m_x
;
701 int yy1
= child
->m_y
;
702 int xx2
= child
->m_x
+ child
->m_width
;
703 int yy2
= child
->m_x
+ child
->m_height
;
706 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
708 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
710 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
712 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
715 event
.m_x
-= child
->m_x
;
716 event
.m_y
-= child
->m_y
;
723 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
724 (child
->m_x
<= event
.m_x
) &&
725 (child
->m_y
<= event
.m_y
) &&
726 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
727 (child
->m_y
+child
->m_height
>= event
.m_y
))
730 event
.m_x
-= child
->m_x
;
731 event
.m_y
-= child
->m_y
;
739 event
.SetEventObject( win
);
741 if (win
->GetEventHandler()->ProcessEvent( event
))
742 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
747 //-----------------------------------------------------------------------------
748 // "motion_notify_event"
749 //-----------------------------------------------------------------------------
751 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
753 if (gdk_event
->is_hint
)
757 GdkModifierType state
;
758 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
761 gdk_event
->state
= state
;
764 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
766 if (g_blockEventsOnDrag
) return TRUE
;
767 if (g_blockEventsOnScroll
) return TRUE
;
769 if (!win
->HasVMT()) return TRUE
;
772 printf( "OnMotion from " );
773 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
774 printf( win->GetClassInfo()->GetClassName() );
778 wxMouseEvent
event( wxEVT_MOTION
);
779 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
780 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
781 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
782 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
783 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
784 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
785 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
787 event
.m_x
= (long)gdk_event
->x
;
788 event
.m_y
= (long)gdk_event
->y
;
790 // Some control don't have their own X window and thus cannot get
795 wxNode
*node
= win
->GetChildren().First();
798 wxWindow
*child
= (wxWindow
*)node
->Data();
800 if (child
->m_isStaticBox
)
802 // wxStaticBox is transparent in the box itself
805 int xx1
= child
->m_x
;
806 int yy1
= child
->m_y
;
807 int xx2
= child
->m_x
+ child
->m_width
;
808 int yy2
= child
->m_x
+ child
->m_height
;
811 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
813 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
815 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
817 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
820 event
.m_x
-= child
->m_x
;
821 event
.m_y
-= child
->m_y
;
828 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
829 (child
->m_x
<= event
.m_x
) &&
830 (child
->m_y
<= event
.m_y
) &&
831 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
832 (child
->m_y
+child
->m_height
>= event
.m_y
))
835 event
.m_x
-= child
->m_x
;
836 event
.m_y
-= child
->m_y
;
844 event
.SetEventObject( win
);
846 if (win
->GetEventHandler()->ProcessEvent( event
))
847 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
852 //-----------------------------------------------------------------------------
854 //-----------------------------------------------------------------------------
856 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
858 if (g_blockEventsOnDrag
) return TRUE
;
864 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
866 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
868 printf( "SetFocus flag from " );
869 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
870 printf( win->GetClassInfo()->GetClassName() );
876 if (!win
->HasVMT()) return TRUE
;
879 printf( "OnSetFocus from " );
880 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
881 printf( win->GetClassInfo()->GetClassName() );
883 printf( WXSTRINGCAST win->GetLabel() );
887 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
888 event
.SetEventObject( win
);
890 if (win
->GetEventHandler()->ProcessEvent( event
))
891 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
896 //-----------------------------------------------------------------------------
898 //-----------------------------------------------------------------------------
900 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
902 if (g_blockEventsOnDrag
) return TRUE
;
905 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
906 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
909 if (!win
->HasVMT()) return TRUE
;
912 printf( "OnKillFocus from " );
913 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
914 printf( win->GetClassInfo()->GetClassName() );
918 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
919 event
.SetEventObject( win
);
921 if (win
->GetEventHandler()->ProcessEvent( event
))
922 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
927 //-----------------------------------------------------------------------------
928 // "enter_notify_event"
929 //-----------------------------------------------------------------------------
931 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
933 if (g_blockEventsOnDrag
) return TRUE
;
935 if ((widget
->window
) && (win
->m_cursor
))
936 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
938 if (widget
->window
!= gdk_event
->window
) return TRUE
;
940 if (!win
->HasVMT()) return TRUE
;
943 printf( "OnEnter from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
949 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
950 event
.SetEventObject( win
);
954 GdkModifierType state
= (GdkModifierType
)0;
956 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
958 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
959 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
960 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
961 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
962 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
963 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
964 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
969 if (win
->GetEventHandler()->ProcessEvent( event
))
970 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
975 //-----------------------------------------------------------------------------
976 // "leave_notify_event"
977 //-----------------------------------------------------------------------------
979 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
981 if (g_blockEventsOnDrag
) return TRUE
;
983 if ((widget
->window
) && (win
->m_cursor
))
984 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
986 if (widget
->window
!= gdk_event
->window
) return TRUE
;
988 if (!win
->HasVMT()) return TRUE
;
991 printf( "OnLeave from " );
992 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
993 printf( win->GetClassInfo()->GetClassName() );
997 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
998 event
.SetEventObject( win
);
1002 GdkModifierType state
= (GdkModifierType
)0;
1004 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1006 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1007 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1008 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1009 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1010 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1011 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1012 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1014 event
.m_x
= (long)x
;
1015 event
.m_y
= (long)y
;
1017 if (win
->GetEventHandler()->ProcessEvent( event
))
1018 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1023 //-----------------------------------------------------------------------------
1024 // "value_changed" from m_vAdjust
1025 //-----------------------------------------------------------------------------
1027 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1029 if (g_blockEventsOnDrag
) return;
1032 printf( "OnVScroll from " );
1033 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1034 printf( win->GetClassInfo()->GetClassName() );
1038 if (!win
->HasVMT()) return;
1040 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1041 if (fabs(diff
) < 0.2) return;
1043 wxEventType command
= wxEVT_NULL
;
1045 float line_step
= win
->m_vAdjust
->step_increment
;
1046 float page_step
= win
->m_vAdjust
->page_increment
;
1048 if (win
->m_isScrolling
)
1050 command
= wxEVT_SCROLL_THUMBTRACK
;
1054 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1055 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1056 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1057 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1058 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1059 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1060 else command
= wxEVT_SCROLL_THUMBTRACK
;
1063 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1065 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1066 event
.SetEventObject( win
);
1067 win
->GetEventHandler()->ProcessEvent( event
);
1070 //-----------------------------------------------------------------------------
1071 // "value_changed" from m_hAdjust
1072 //-----------------------------------------------------------------------------
1074 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1076 if (g_blockEventsOnDrag
) return;
1079 printf( "OnHScroll from " );
1080 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1081 printf( win->GetClassInfo()->GetClassName() );
1085 if (!win
->HasVMT()) return;
1087 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1088 if (fabs(diff
) < 0.2) return;
1090 wxEventType command
= wxEVT_NULL
;
1092 float line_step
= win
->m_hAdjust
->step_increment
;
1093 float page_step
= win
->m_hAdjust
->page_increment
;
1095 if (win
->m_isScrolling
)
1097 command
= wxEVT_SCROLL_THUMBTRACK
;
1101 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1102 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1103 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1104 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1105 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1106 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1107 else command
= wxEVT_SCROLL_THUMBTRACK
;
1110 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1112 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1113 event
.SetEventObject( win
);
1114 win
->GetEventHandler()->ProcessEvent( event
);
1117 //-----------------------------------------------------------------------------
1118 // "changed" from m_vAdjust
1119 //-----------------------------------------------------------------------------
1121 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1123 if (g_blockEventsOnDrag
) return;
1126 printf( "OnVScroll change from " );
1127 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1128 printf( win->GetClassInfo()->GetClassName() );
1132 if (!win
->HasVMT()) return;
1134 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1135 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1137 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1138 event
.SetEventObject( win
);
1139 win
->GetEventHandler()->ProcessEvent( event
);
1142 //-----------------------------------------------------------------------------
1143 // "changed" from m_hAdjust
1144 //-----------------------------------------------------------------------------
1146 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1148 if (g_blockEventsOnDrag
) return;
1151 printf( "OnHScroll change from " );
1152 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1153 printf( win->GetClassInfo()->GetClassName() );
1157 if (!win
->HasVMT()) return;
1159 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1160 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1162 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1163 event
.SetEventObject( win
);
1164 win
->GetEventHandler()->ProcessEvent( event
);
1167 //-----------------------------------------------------------------------------
1168 // "button_press_event" from scrollbar
1169 //-----------------------------------------------------------------------------
1171 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1172 GdkEventButton
*WXUNUSED(gdk_event
),
1175 // don't test here as we can release the mouse while being over
1176 // a different window then the slider
1178 // if (gdk_event->window != widget->slider) return FALSE;
1180 win
->m_isScrolling
= TRUE
;
1181 g_blockEventsOnScroll
= TRUE
;
1186 //-----------------------------------------------------------------------------
1187 // "button_release_event" from scrollbar
1188 //-----------------------------------------------------------------------------
1190 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1191 GdkEventButton
*WXUNUSED(gdk_event
),
1195 // don't test here as we can release the mouse while being over
1196 // a different window then the slider
1198 // if (gdk_event->window != widget->slider) return FALSE;
1200 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1202 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1203 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1205 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1207 win
->m_isScrolling
= FALSE
;
1208 g_blockEventsOnScroll
= FALSE
;
1213 //-----------------------------------------------------------------------------
1214 // InsertChild for wxWindow.
1215 //-----------------------------------------------------------------------------
1217 // Callback for wxWindow. This very strange beast has to be used because
1218 // C++ has no virtual methods in a constructor. We have to emulate a
1219 // virtual function here as wxNotebook requires a different way to insert
1220 // a child in it. I had opted for creating a wxNotebookPage window class
1221 // which would have made this superfluous (such in the MDI window system),
1222 // but no-one was listening to me...
1224 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1226 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1227 GTK_WIDGET(child
->m_widget
),
1231 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1236 //-----------------------------------------------------------------------------
1238 //-----------------------------------------------------------------------------
1240 wxWindow
* wxGetActiveWindow()
1242 return g_focusWindow
;
1245 //-----------------------------------------------------------------------------
1247 //-----------------------------------------------------------------------------
1249 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1251 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1252 EVT_SIZE(wxWindow::OnSize
)
1253 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1254 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1255 EVT_IDLE(wxWindow::OnIdle
)
1256 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1259 wxWindow::wxWindow()
1261 m_widget
= (GtkWidget
*) NULL
;
1262 m_wxwindow
= (GtkWidget
*) NULL
;
1263 m_parent
= (wxWindow
*) NULL
;
1264 m_children
.DeleteContents( FALSE
);
1277 m_eventHandler
= this;
1278 m_windowValidator
= (wxValidator
*) NULL
;
1282 m_cursor
= (wxCursor
*) NULL
;
1283 m_font
= *wxSWISS_FONT
;
1285 m_windowName
= "noname";
1287 m_constraints
= (wxLayoutConstraints
*) NULL
;
1288 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1289 m_windowSizer
= (wxSizer
*) NULL
;
1290 m_sizerParent
= (wxWindow
*) NULL
;
1291 m_autoLayout
= FALSE
;
1295 m_needParent
= TRUE
;
1297 m_hasScrolling
= FALSE
;
1298 m_isScrolling
= FALSE
;
1299 m_hAdjust
= (GtkAdjustment
*) NULL
;
1300 m_vAdjust
= (GtkAdjustment
*) NULL
;
1301 m_oldHorizontalPos
= 0.0;
1302 m_oldVerticalPos
= 0.0;
1307 #if wxUSE_DRAG_AND_DROP
1308 m_dropTarget
= (wxDropTarget
*) NULL
;
1311 m_scrollGC
= (GdkGC
*) NULL
;
1312 m_widgetStyle
= (GtkStyle
*) NULL
;
1314 m_insertCallback
= wxInsertChildInWindow
;
1316 m_clientObject
= (wxClientData
*) NULL
;
1317 m_clientData
= NULL
;
1319 m_isStaticBox
= FALSE
;
1320 m_acceptsFocus
= FALSE
;
1323 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1324 const wxPoint
&pos
, const wxSize
&size
,
1325 long style
, const wxString
&name
)
1327 m_insertCallback
= wxInsertChildInWindow
;
1328 Create( parent
, id
, pos
, size
, style
, name
);
1331 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1332 const wxPoint
&pos
, const wxSize
&size
,
1333 long style
, const wxString
&name
)
1337 m_needParent
= TRUE
;
1339 PreCreation( parent
, id
, pos
, size
, style
, name
);
1341 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1342 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1345 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1348 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1351 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1352 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1355 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1356 scroll_class
->scrollbar_spacing
= 0;
1358 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1360 m_oldHorizontalPos
= 0.0;
1361 m_oldVerticalPos
= 0.0;
1363 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1364 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1366 m_wxwindow
= gtk_myfixed_new();
1369 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1372 #ifdef NEW_GTK_SCROLL_CODE
1373 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1374 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1376 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1377 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1381 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1384 if (m_windowStyle
& wxRAISED_BORDER
)
1386 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1388 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1390 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1394 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1397 if ((m_windowStyle
& wxTAB_TRAVERSAL
) != 0)
1399 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1400 m_acceptsFocus
= FALSE
;
1404 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1405 m_acceptsFocus
= TRUE
;
1408 // shut the viewport up
1409 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1410 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1412 // I _really_ don't want scrollbars in the beginning
1413 m_vAdjust
->lower
= 0.0;
1414 m_vAdjust
->upper
= 1.0;
1415 m_vAdjust
->value
= 0.0;
1416 m_vAdjust
->step_increment
= 1.0;
1417 m_vAdjust
->page_increment
= 1.0;
1418 m_vAdjust
->page_size
= 5.0;
1419 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1420 m_hAdjust
->lower
= 0.0;
1421 m_hAdjust
->upper
= 1.0;
1422 m_hAdjust
->value
= 0.0;
1423 m_hAdjust
->step_increment
= 1.0;
1424 m_hAdjust
->page_increment
= 1.0;
1425 m_hAdjust
->page_size
= 5.0;
1426 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1428 // these handlers block mouse events to any window during scrolling
1429 // such as motion events and prevent GTK and wxWindows from fighting
1430 // over where the slider should be
1432 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1433 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1435 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1436 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1438 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1439 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1441 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1442 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1444 // these handers het notified when screen updates are required either when
1445 // scrolling or when the window size (and therefore scrollbar configuration)
1448 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1449 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1450 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1451 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1453 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1454 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1455 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1456 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1458 gtk_widget_show( m_wxwindow
);
1460 if (m_parent
) m_parent
->AddChild( this );
1462 (m_parent
->m_insertCallback
)( m_parent
, this );
1471 wxWindow::~wxWindow()
1475 #if wxUSE_DRAG_AND_DROP
1476 if (m_dropTarget
) delete m_dropTarget
;
1479 if (m_parent
) m_parent
->RemoveChild( this );
1480 if (m_widget
) Show( FALSE
);
1484 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1486 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1488 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1490 if (m_widget
) gtk_widget_destroy( m_widget
);
1492 if (m_cursor
) delete m_cursor
;
1494 DeleteRelatedConstraints();
1497 // This removes any dangling pointers to this window
1498 // in other windows' constraintsInvolvedIn lists.
1499 UnsetConstraints(m_constraints
);
1500 delete m_constraints
;
1501 m_constraints
= (wxLayoutConstraints
*) NULL
;
1505 delete m_windowSizer
;
1506 m_windowSizer
= (wxSizer
*) NULL
;
1508 // If this is a child of a sizer, remove self from parent
1509 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1511 // Just in case the window has been Closed, but
1512 // we're then deleting immediately: don't leave
1513 // dangling pointers.
1514 wxPendingDelete
.DeleteObject(this);
1516 // Just in case we've loaded a top-level window via
1517 // wxWindow::LoadNativeDialog but we weren't a dialog
1519 wxTopLevelWindows
.DeleteObject(this);
1521 if (m_windowValidator
) delete m_windowValidator
;
1523 if (m_clientObject
) delete m_clientObject
;
1526 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1527 const wxPoint
&pos
, const wxSize
&size
,
1528 long style
, const wxString
&name
)
1530 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1532 m_widget
= (GtkWidget
*) NULL
;
1533 m_wxwindow
= (GtkWidget
*) NULL
;
1536 m_children
.DeleteContents( FALSE
);
1539 if (m_width
== -1) m_width
= 20;
1541 if (m_height
== -1) m_height
= 20;
1546 if (!m_needParent
) // some reasonable defaults
1550 m_x
= (gdk_screen_width () - m_width
) / 2;
1551 if (m_x
< 10) m_x
= 10;
1555 m_y
= (gdk_screen_height () - m_height
) / 2;
1556 if (m_y
< 10) m_y
= 10;
1567 m_eventHandler
= this;
1569 m_windowId
= id
== -1 ? wxNewId() : id
;
1573 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1574 m_font
= *wxSWISS_FONT
;
1575 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1576 m_foregroundColour
= *wxBLACK
;
1577 m_windowStyle
= style
;
1578 m_windowName
= name
;
1580 m_constraints
= (wxLayoutConstraints
*) NULL
;
1581 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1582 m_windowSizer
= (wxSizer
*) NULL
;
1583 m_sizerParent
= (wxWindow
*) NULL
;
1584 m_autoLayout
= FALSE
;
1586 m_hasScrolling
= FALSE
;
1587 m_isScrolling
= FALSE
;
1588 m_hAdjust
= (GtkAdjustment
*) NULL
;
1589 m_vAdjust
= (GtkAdjustment
*) NULL
;
1590 m_oldHorizontalPos
= 0.0;
1591 m_oldVerticalPos
= 0.0;
1596 #if wxUSE_DRAG_AND_DROP
1597 m_dropTarget
= (wxDropTarget
*) NULL
;
1600 m_windowValidator
= (wxValidator
*) NULL
;
1601 m_scrollGC
= (GdkGC
*) NULL
;
1602 m_widgetStyle
= (GtkStyle
*) NULL
;
1604 m_clientObject
= (wxClientData
*)NULL
;
1605 m_clientData
= NULL
;
1607 m_isStaticBox
= FALSE
;
1610 void wxWindow::PostCreation()
1614 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1615 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1617 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1618 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1621 ConnectWidget( GetConnectWidget() );
1623 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1625 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1627 SetCursor( *wxSTANDARD_CURSOR
);
1632 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1634 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1635 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1637 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1638 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1640 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1641 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1643 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1644 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1646 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1647 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1649 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1650 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1652 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1653 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1655 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1656 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1658 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1659 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1662 bool wxWindow::HasVMT()
1667 bool wxWindow::Close( bool force
)
1669 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1671 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1672 event
.SetEventObject(this);
1673 event
.SetForce(force
);
1675 return GetEventHandler()->ProcessEvent(event
);
1678 bool wxWindow::Destroy()
1680 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1687 bool wxWindow::DestroyChildren()
1690 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1693 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1696 if (m_children
.Member(child
)) delete node
;
1702 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1704 // are we to set fonts here ?
1707 wxPoint
wxWindow::GetClientAreaOrigin() const
1709 return wxPoint(0,0);
1712 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1714 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1716 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1722 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1724 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1725 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1727 if (m_resizing
) return; // I don't like recursions
1730 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1732 // don't set the size for children of wxNotebook, just take the values.
1740 int old_width
= m_width
;
1741 int old_height
= m_height
;
1743 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1745 if (x
!= -1) m_x
= x
;
1746 if (y
!= -1) m_y
= y
;
1747 if (width
!= -1) m_width
= width
;
1748 if (height
!= -1) m_height
= height
;
1758 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1760 if (width
== -1) m_width
= 80;
1763 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1765 if (height
== -1) m_height
= 26;
1768 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1769 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1770 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1771 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1773 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1774 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1776 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1777 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1782 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1783 event
.SetEventObject( this );
1784 GetEventHandler()->ProcessEvent( event
);
1789 void wxWindow::SetSize( int width
, int height
)
1791 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1794 void wxWindow::Move( int x
, int y
)
1796 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1799 void wxWindow::GetSize( int *width
, int *height
) const
1801 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1803 if (width
) (*width
) = m_width
;
1804 if (height
) (*height
) = m_height
;
1807 void wxWindow::SetClientSize( int width
, int height
)
1809 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1813 SetSize( width
, height
);
1820 if (!m_hasScrolling
)
1822 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1824 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1825 (m_windowStyle
& wxSUNKEN_BORDER
))
1827 dw
+= 2 * window_class
->xthickness
;
1828 dh
+= 2 * window_class
->ythickness
;
1833 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1834 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1836 #ifdef NEW_GTK_SCROLL_CODE
1837 GtkWidget
*viewport
= scroll_window
->child
;
1839 GtkWidget
*viewport
= scroll_window
->viewport
;
1842 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1844 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1845 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1847 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1848 (m_windowStyle
& wxSUNKEN_BORDER
))
1850 dw
+= 2 * viewport_class
->xthickness
;
1851 dh
+= 2 * viewport_class
->ythickness
;
1854 if (scroll_window
->vscrollbar_visible
)
1856 dw
+= vscrollbar
->allocation
.width
;
1857 dw
+= scroll_class
->scrollbar_spacing
;
1860 if (scroll_window
->hscrollbar_visible
)
1862 dh
+= hscrollbar
->allocation
.height
;
1863 dw
+= scroll_class
->scrollbar_spacing
;
1867 SetSize( width
+dw
, height
+dh
);
1871 void wxWindow::GetClientSize( int *width
, int *height
) const
1873 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1877 if (width
) (*width
) = m_width
;
1878 if (height
) (*height
) = m_height
;
1885 if (!m_hasScrolling
)
1887 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1889 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1890 (m_windowStyle
& wxSUNKEN_BORDER
))
1892 dw
+= 2 * window_class
->xthickness
;
1893 dh
+= 2 * window_class
->ythickness
;
1898 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1899 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1901 #ifdef NEW_GTK_SCROLL_CODE
1902 GtkWidget
*viewport
= scroll_window
->child
;
1904 GtkWidget
*viewport
= scroll_window
->viewport
;
1907 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1909 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1910 (m_windowStyle
& wxSUNKEN_BORDER
))
1912 dw
+= 2 * viewport_class
->xthickness
;
1913 dh
+= 2 * viewport_class
->ythickness
;
1916 if (scroll_window
->vscrollbar_visible
)
1918 // dw += vscrollbar->allocation.width;
1919 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1920 dw
+= scroll_class
->scrollbar_spacing
;
1923 if (scroll_window
->hscrollbar_visible
)
1925 // dh += hscrollbar->allocation.height;
1927 dh
+= scroll_class
->scrollbar_spacing
;
1931 if (width
) (*width
) = m_width
- dw
;
1932 if (height
) (*height
) = m_height
- dh
;
1936 void wxWindow::GetPosition( int *x
, int *y
) const
1938 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1944 void wxWindow::ClientToScreen( int *x
, int *y
)
1946 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1948 GdkWindow
*source
= (GdkWindow
*) NULL
;
1950 source
= m_wxwindow
->window
;
1952 source
= m_widget
->window
;
1956 gdk_window_get_origin( source
, &org_x
, &org_y
);
1960 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1962 org_x
+= m_widget
->allocation
.x
;
1963 org_y
+= m_widget
->allocation
.y
;
1967 wxPoint
pt(GetClientAreaOrigin());
1975 void wxWindow::ScreenToClient( int *x
, int *y
)
1977 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1979 GdkWindow
*source
= (GdkWindow
*) NULL
;
1981 source
= m_wxwindow
->window
;
1983 source
= m_widget
->window
;
1987 gdk_window_get_origin( source
, &org_x
, &org_y
);
1991 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1993 org_x
+= m_widget
->allocation
.x
;
1994 org_y
+= m_widget
->allocation
.y
;
1998 wxPoint
pt(GetClientAreaOrigin());
2006 void wxWindow::Centre( int direction
)
2008 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2017 m_parent
->GetSize( &p_w
, &p_h
);
2018 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2019 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2023 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2024 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2030 void wxWindow::Fit()
2032 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2036 wxNode
*node
= m_children
.First();
2039 wxWindow
*win
= (wxWindow
*)node
->Data();
2041 win
->GetPosition(&wx
, &wy
);
2042 win
->GetSize(&ww
, &wh
);
2043 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2044 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2046 node
= node
->Next();
2049 SetClientSize(maxX
+ 7, maxY
+ 14);
2052 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2054 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2062 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2064 // if (GetAutoLayout()) Layout();
2067 bool wxWindow::Show( bool show
)
2069 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2072 gtk_widget_show( m_widget
);
2074 gtk_widget_hide( m_widget
);
2081 void wxWindow::Enable( bool enable
)
2083 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2085 m_isEnabled
= enable
;
2087 gtk_widget_set_sensitive( m_widget
, enable
);
2088 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2091 int wxWindow::GetCharHeight() const
2093 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2095 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2097 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2099 return font
->ascent
+ font
->descent
;
2102 int wxWindow::GetCharWidth() const
2104 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2106 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2108 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2110 return gdk_string_width( font
, "H" );
2113 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2114 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2116 wxFont fontToUse
= m_font
;
2117 if (theFont
) fontToUse
= *theFont
;
2119 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2121 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2122 if (x
) (*x
) = gdk_string_width( font
, string
);
2123 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2124 if (descent
) (*descent
) = font
->descent
;
2125 if (externalLeading
) (*externalLeading
) = 0; // ??
2128 void wxWindow::MakeModal( bool modal
)
2132 // Disable all other windows
2133 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2135 wxNode
*node
= wxTopLevelWindows
.First();
2138 wxWindow
*win
= (wxWindow
*)node
->Data();
2139 if (win
!= this) win
->Enable(!modal
);
2141 node
= node
->Next();
2146 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2148 event
.SetEventType( wxEVT_CHAR
);
2150 if (!GetEventHandler()->ProcessEvent( event
))
2156 void wxWindow::SetFocus()
2158 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2160 GtkWidget
*connect_widget
= GetConnectWidget();
2163 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2165 gtk_widget_grab_focus (connect_widget
);
2167 else if (GTK_IS_CONTAINER(connect_widget
))
2169 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2177 wxWindow
*wxWindow::FindFocus()
2179 return g_focusWindow
;
2182 bool wxWindow::AcceptsFocus() const
2184 return IsEnabled() && IsShown() && m_acceptsFocus
;
2187 bool wxWindow::OnClose()
2192 void wxWindow::AddChild( wxWindow
*child
)
2194 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2195 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2197 m_children
.Append( child
);
2200 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2202 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2204 wxWindow
*oldParent
= GetParent();
2206 if (oldParent
) oldParent
->RemoveChild( this );
2208 gtk_widget_unparent( m_widget
);
2212 newParent
->AddChild( this );
2213 (newParent
->m_insertCallback
)( newParent
, this );
2219 void wxWindow::RemoveChild( wxWindow
*child
)
2221 m_children
.DeleteObject( child
);
2222 child
->m_parent
= (wxWindow
*) NULL
;
2225 void wxWindow::SetReturnCode( int retCode
)
2227 m_retCode
= retCode
;
2230 int wxWindow::GetReturnCode()
2235 void wxWindow::Raise()
2237 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2239 if (m_widget
) gdk_window_raise( m_widget
->window
);
2242 void wxWindow::Lower()
2244 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2246 if (m_widget
) gdk_window_lower( m_widget
->window
);
2249 wxEvtHandler
*wxWindow::GetEventHandler() const
2251 return m_eventHandler
;
2254 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2256 m_eventHandler
= handler
;
2259 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2261 handler
->SetNextHandler(GetEventHandler());
2262 SetEventHandler(handler
);
2265 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2267 if (GetEventHandler())
2269 wxEvtHandler
*handlerA
= GetEventHandler();
2270 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2271 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2272 SetEventHandler(handlerB
);
2276 return (wxEvtHandler
*) NULL
;
2282 return (wxEvtHandler
*) NULL
;
2285 wxValidator
*wxWindow::GetValidator()
2287 return m_windowValidator
;
2290 void wxWindow::SetValidator( const wxValidator
& validator
)
2292 if (m_windowValidator
) delete m_windowValidator
;
2293 m_windowValidator
= validator
.Clone();
2294 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2297 void wxWindow::SetClientObject( wxClientData
*data
)
2299 if (m_clientObject
) delete m_clientObject
;
2300 m_clientObject
= data
;
2303 wxClientData
*wxWindow::GetClientObject()
2305 return m_clientObject
;
2308 void wxWindow::SetClientData( void *data
)
2310 m_clientData
= data
;
2313 void *wxWindow::GetClientData()
2315 return m_clientData
;
2318 bool wxWindow::IsBeingDeleted()
2323 void wxWindow::SetId( wxWindowID id
)
2328 wxWindowID
wxWindow::GetId() const
2333 void wxWindow::SetCursor( const wxCursor
&cursor
)
2335 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2339 if (cursor
== *m_cursor
) return;
2344 *m_cursor
= *wxSTANDARD_CURSOR
;
2347 if ((m_widget
) && (m_widget
->window
))
2348 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2350 if ((m_wxwindow
) && (m_wxwindow
->window
))
2351 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2354 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2359 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2361 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2363 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2367 gdk_window_clear_area( m_wxwindow
->window
,
2381 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2383 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2387 GdkRectangle gdk_rect
;
2388 gdk_rect
.x
= rect
->x
;
2389 gdk_rect
.y
= rect
->y
;
2390 gdk_rect
.width
= rect
->width
;
2391 gdk_rect
.height
= rect
->height
;
2394 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2396 gtk_widget_draw( m_widget
, &gdk_rect
);
2400 wxRegion
wxWindow::GetUpdateRegion() const
2402 return m_updateRegion
;
2405 bool wxWindow::IsExposed( int x
, int y
) const
2407 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2410 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2412 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2415 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2417 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2420 bool wxWindow::IsExposed( const wxRect
& rect
) const
2422 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2425 void wxWindow::Clear()
2427 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2429 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2432 wxColour
wxWindow::GetBackgroundColour() const
2434 return m_backgroundColour
;
2437 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2439 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2441 if (m_backgroundColour
== colour
) return;
2443 m_backgroundColour
= colour
;
2444 if (!m_backgroundColour
.Ok()) return;
2448 GdkWindow
*window
= m_wxwindow
->window
;
2449 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2450 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2451 gdk_window_clear( window
);
2454 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2455 if (sysbg
.Red() == colour
.Red() &&
2456 sysbg
.Green() == colour
.Green() &&
2457 sysbg
.Blue() == colour
.Blue())
2459 m_backgroundColour
= wxNullColour
;
2461 m_backgroundColour
= sysbg
;
2469 wxColour
wxWindow::GetForegroundColour() const
2471 return m_foregroundColour
;
2474 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2476 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2478 if (m_foregroundColour
== colour
) return;
2480 m_foregroundColour
= colour
;
2481 if (!m_foregroundColour
.Ok()) return;
2483 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2484 if (sysbg
.Red() == colour
.Red() &&
2485 sysbg
.Green() == colour
.Green() &&
2486 sysbg
.Blue() == colour
.Blue())
2488 m_backgroundColour
= wxNullColour
;
2490 m_backgroundColour
= sysbg
;
2498 GtkStyle
*wxWindow::GetWidgetStyle()
2500 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2504 gtk_widget_get_style( m_widget
) );
2506 return m_widgetStyle
;
2509 void wxWindow::SetWidgetStyle()
2511 GtkStyle
*style
= GetWidgetStyle();
2513 gdk_font_unref( style
->font
);
2514 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2516 if (m_foregroundColour
.Ok())
2518 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2519 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2520 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2521 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2524 if (m_backgroundColour
.Ok())
2526 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2527 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2528 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2529 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2530 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2531 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2532 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2533 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2534 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2538 void wxWindow::ApplyWidgetStyle()
2542 bool wxWindow::Validate()
2544 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2546 wxNode
*node
= m_children
.First();
2549 wxWindow
*child
= (wxWindow
*)node
->Data();
2550 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2554 node
= node
->Next();
2559 bool wxWindow::TransferDataToWindow()
2561 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2563 wxNode
*node
= m_children
.First();
2566 wxWindow
*child
= (wxWindow
*)node
->Data();
2567 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2568 !child
->GetValidator()->TransferToWindow() )
2570 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2573 node
= node
->Next();
2578 bool wxWindow::TransferDataFromWindow()
2580 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2582 wxNode
*node
= m_children
.First();
2585 wxWindow
*child
= (wxWindow
*)node
->Data();
2586 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2590 node
= node
->Next();
2595 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2597 m_acceleratorTable
= accel
;
2600 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2602 TransferDataToWindow();
2605 void wxWindow::InitDialog()
2607 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2609 wxInitDialogEvent
event(GetId());
2610 event
.SetEventObject( this );
2611 GetEventHandler()->ProcessEvent(event
);
2614 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2616 menu
->SetInvokingWindow( win
);
2617 wxNode
*node
= menu
->m_items
.First();
2620 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2621 if (menuitem
->IsSubMenu())
2623 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2625 node
= node
->Next();
2629 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2631 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2633 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2635 SetInvokingWindow( menu
, this );
2637 GTK_MENU(menu
->m_menu
),
2638 (GtkWidget
*)NULL
, // parent menu shell
2639 (GtkWidget
*)NULL
, // parent menu item
2640 (GtkMenuPositionFunc
)NULL
,
2641 NULL
, // client data
2642 0, // button used to activate it
2643 0//gs_timeLastClick // the time of activation
2648 #if wxUSE_DRAG_AND_DROP
2650 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2652 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2654 GtkWidget
*dnd_widget
= GetConnectWidget();
2656 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2658 if (m_dropTarget
) delete m_dropTarget
;
2659 m_dropTarget
= dropTarget
;
2661 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2664 wxDropTarget
*wxWindow::GetDropTarget() const
2666 return m_dropTarget
;
2671 GtkWidget
* wxWindow::GetConnectWidget()
2673 GtkWidget
*connect_widget
= m_widget
;
2674 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2676 return connect_widget
;
2679 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2681 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2682 return (window
== m_widget
->window
);
2685 void wxWindow::SetFont( const wxFont
&font
)
2687 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2689 if (((wxFont
*)&font
)->Ok())
2692 m_font
= *wxSWISS_FONT
;
2694 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2695 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2696 sysbg
.Green() == m_backgroundColour
.Green() &&
2697 sysbg
.Blue() == m_backgroundColour
.Blue())
2699 m_backgroundColour
= wxNullColour
;
2701 m_backgroundColour
= sysbg
;
2709 void wxWindow::SetWindowStyleFlag( long flag
)
2711 m_windowStyle
= flag
;
2714 long wxWindow::GetWindowStyleFlag() const
2716 return m_windowStyle
;
2719 void wxWindow::CaptureMouse()
2721 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2723 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2725 GtkWidget
*connect_widget
= GetConnectWidget();
2726 gtk_grab_add( connect_widget
);
2727 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2729 (GDK_BUTTON_PRESS_MASK
|
2730 GDK_BUTTON_RELEASE_MASK
|
2731 GDK_POINTER_MOTION_MASK
),
2738 void wxWindow::ReleaseMouse()
2740 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2742 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2744 GtkWidget
*connect_widget
= GetConnectWidget();
2745 gtk_grab_remove( connect_widget
);
2746 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2747 g_capturing
= FALSE
;
2750 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2754 wxString
wxWindow::GetTitle() const
2756 return (wxString
&)m_windowName
;
2759 wxString
wxWindow::GetLabel() const
2764 void wxWindow::SetName( const wxString
&name
)
2766 m_windowName
= name
;
2769 wxString
wxWindow::GetName() const
2771 return (wxString
&)m_windowName
;
2774 bool wxWindow::IsShown() const
2779 bool wxWindow::IsRetained()
2784 wxWindow
*wxWindow::FindWindow( long id
)
2786 if (id
== m_windowId
) return this;
2787 wxNode
*node
= m_children
.First();
2790 wxWindow
*child
= (wxWindow
*)node
->Data();
2791 wxWindow
*res
= child
->FindWindow( id
);
2792 if (res
) return res
;
2793 node
= node
->Next();
2795 return (wxWindow
*) NULL
;
2798 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2800 if (name
== m_windowName
) return this;
2801 wxNode
*node
= m_children
.First();
2804 wxWindow
*child
= (wxWindow
*)node
->Data();
2805 wxWindow
*res
= child
->FindWindow( name
);
2806 if (res
) return res
;
2807 node
= node
->Next();
2809 return (wxWindow
*) NULL
;
2812 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2813 int range
, bool refresh
)
2815 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2817 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2819 m_hasScrolling
= TRUE
;
2821 if (orient
== wxHORIZONTAL
)
2823 float fpos
= (float)pos
;
2824 float frange
= (float)range
;
2825 float fthumb
= (float)thumbVisible
;
2826 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2827 if (fpos
< 0.0) fpos
= 0.0;
2829 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2830 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2832 SetScrollPos( orient
, pos
, refresh
);
2836 m_oldHorizontalPos
= fpos
;
2838 m_hAdjust
->lower
= 0.0;
2839 m_hAdjust
->upper
= frange
;
2840 m_hAdjust
->value
= fpos
;
2841 m_hAdjust
->step_increment
= 1.0;
2842 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2843 m_hAdjust
->page_size
= fthumb
;
2847 float fpos
= (float)pos
;
2848 float frange
= (float)range
;
2849 float fthumb
= (float)thumbVisible
;
2850 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2851 if (fpos
< 0.0) fpos
= 0.0;
2853 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2854 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2856 SetScrollPos( orient
, pos
, refresh
);
2860 m_oldVerticalPos
= fpos
;
2862 m_vAdjust
->lower
= 0.0;
2863 m_vAdjust
->upper
= frange
;
2864 m_vAdjust
->value
= fpos
;
2865 m_vAdjust
->step_increment
= 1.0;
2866 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2867 m_vAdjust
->page_size
= fthumb
;
2870 if (m_wxwindow
->window
)
2872 if (orient
== wxHORIZONTAL
)
2873 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2875 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2877 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2881 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2883 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2885 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2887 if (orient
== wxHORIZONTAL
)
2889 float fpos
= (float)pos
;
2890 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2891 if (fpos
< 0.0) fpos
= 0.0;
2892 m_oldHorizontalPos
= fpos
;
2894 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2895 m_hAdjust
->value
= fpos
;
2899 float fpos
= (float)pos
;
2900 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2901 if (fpos
< 0.0) fpos
= 0.0;
2902 m_oldVerticalPos
= fpos
;
2904 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2905 m_vAdjust
->value
= fpos
;
2910 if (m_wxwindow
->window
)
2912 if (orient
== wxHORIZONTAL
)
2913 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2915 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2920 int wxWindow::GetScrollThumb( int orient
) const
2922 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2924 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2926 if (orient
== wxHORIZONTAL
)
2927 return (int)(m_hAdjust
->page_size
+0.5);
2929 return (int)(m_vAdjust
->page_size
+0.5);
2932 int wxWindow::GetScrollPos( int orient
) const
2934 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2936 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2938 if (orient
== wxHORIZONTAL
)
2939 return (int)(m_hAdjust
->value
+0.5);
2941 return (int)(m_vAdjust
->value
+0.5);
2944 int wxWindow::GetScrollRange( int orient
) const
2946 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2948 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2950 if (orient
== wxHORIZONTAL
)
2951 return (int)(m_hAdjust
->upper
+0.5);
2953 return (int)(m_vAdjust
->upper
+0.5);
2956 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2958 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2960 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2964 GetClientSize( &cw
, &ch
);
2966 int w
= cw
- abs(dx
);
2967 int h
= ch
- abs(dy
);
2968 if ((h
< 0) || (w
< 0))
2975 if (dx
< 0) s_x
= -dx
;
2976 if (dy
< 0) s_y
= -dy
;
2979 if (dx
> 0) d_x
= dx
;
2980 if (dy
> 0) d_y
= dy
;
2984 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2985 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2988 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2989 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2992 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2993 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2994 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2995 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2997 Refresh( TRUE
, &rect
);
3000 //-------------------------------------------------------------------------------------
3002 //-------------------------------------------------------------------------------------
3004 wxLayoutConstraints
*wxWindow::GetConstraints() const
3006 return m_constraints
;
3009 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3013 UnsetConstraints(m_constraints
);
3014 delete m_constraints
;
3016 m_constraints
= constraints
;
3019 // Make sure other windows know they're part of a 'meaningful relationship'
3020 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3021 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3022 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3023 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3024 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3025 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3026 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3027 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3028 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3029 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3030 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3031 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3032 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3033 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3034 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3035 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3041 void wxWindow::SetAutoLayout( bool autoLayout
)
3043 m_autoLayout
= autoLayout
;
3046 bool wxWindow::GetAutoLayout() const
3048 return m_autoLayout
;
3051 wxSizer
*wxWindow::GetSizer() const
3053 return m_windowSizer
;
3056 void wxWindow::SetSizerParent( wxWindow
*win
)
3058 m_sizerParent
= win
;
3061 wxWindow
*wxWindow::GetSizerParent() const
3063 return m_sizerParent
;
3066 // This removes any dangling pointers to this window
3067 // in other windows' constraintsInvolvedIn lists.
3068 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3072 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3073 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3074 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3075 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3076 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3077 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3078 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3079 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3080 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3081 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3082 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3083 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3084 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3085 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3086 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3087 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3091 // Back-pointer to other windows we're involved with, so if we delete
3092 // this window, we must delete any constraints we're involved with.
3093 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3095 if (!m_constraintsInvolvedIn
)
3096 m_constraintsInvolvedIn
= new wxList
;
3097 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3098 m_constraintsInvolvedIn
->Append(otherWin
);
3101 // REMOVE back-pointer to other windows we're involved with.
3102 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3104 if (m_constraintsInvolvedIn
)
3105 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3108 // Reset any constraints that mention this window
3109 void wxWindow::DeleteRelatedConstraints()
3111 if (m_constraintsInvolvedIn
)
3113 wxNode
*node
= m_constraintsInvolvedIn
->First();
3116 wxWindow
*win
= (wxWindow
*)node
->Data();
3117 wxNode
*next
= node
->Next();
3118 wxLayoutConstraints
*constr
= win
->GetConstraints();
3120 // Reset any constraints involving this window
3123 constr
->left
.ResetIfWin((wxWindow
*)this);
3124 constr
->top
.ResetIfWin((wxWindow
*)this);
3125 constr
->right
.ResetIfWin((wxWindow
*)this);
3126 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3127 constr
->width
.ResetIfWin((wxWindow
*)this);
3128 constr
->height
.ResetIfWin((wxWindow
*)this);
3129 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3130 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3135 delete m_constraintsInvolvedIn
;
3136 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3140 void wxWindow::SetSizer(wxSizer
*sizer
)
3142 m_windowSizer
= sizer
;
3144 sizer
->SetSizerParent((wxWindow
*)this);
3151 bool wxWindow::Layout()
3153 if (GetConstraints())
3156 GetClientSize(&w
, &h
);
3157 GetConstraints()->width
.SetValue(w
);
3158 GetConstraints()->height
.SetValue(h
);
3161 // If top level (one sizer), evaluate the sizer's constraints.
3165 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3166 GetSizer()->LayoutPhase1(&noChanges
);
3167 GetSizer()->LayoutPhase2(&noChanges
);
3168 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3173 // Otherwise, evaluate child constraints
3174 ResetConstraints(); // Mark all constraints as unevaluated
3175 DoPhase(1); // Just one phase need if no sizers involved
3177 SetConstraintSizes(); // Recursively set the real window sizes
3183 // Do a phase of evaluating constraints:
3184 // the default behaviour. wxSizers may do a similar
3185 // thing, but also impose their own 'constraints'
3186 // and order the evaluation differently.
3187 bool wxWindow::LayoutPhase1(int *noChanges
)
3189 wxLayoutConstraints
*constr
= GetConstraints();
3192 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3198 bool wxWindow::LayoutPhase2(int *noChanges
)
3208 // Do a phase of evaluating child constraints
3209 bool wxWindow::DoPhase(int phase
)
3211 int noIterations
= 0;
3212 int maxIterations
= 500;
3216 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3220 wxNode
*node
= m_children
.First();
3223 wxWindow
*child
= (wxWindow
*)node
->Data();
3224 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3226 wxLayoutConstraints
*constr
= child
->GetConstraints();
3229 if (succeeded
.Member(child
))
3234 int tempNoChanges
= 0;
3235 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3236 noChanges
+= tempNoChanges
;
3239 succeeded
.Append(child
);
3244 node
= node
->Next();
3251 void wxWindow::ResetConstraints()
3253 wxLayoutConstraints
*constr
= GetConstraints();
3256 constr
->left
.SetDone(FALSE
);
3257 constr
->top
.SetDone(FALSE
);
3258 constr
->right
.SetDone(FALSE
);
3259 constr
->bottom
.SetDone(FALSE
);
3260 constr
->width
.SetDone(FALSE
);
3261 constr
->height
.SetDone(FALSE
);
3262 constr
->centreX
.SetDone(FALSE
);
3263 constr
->centreY
.SetDone(FALSE
);
3265 wxNode
*node
= m_children
.First();
3268 wxWindow
*win
= (wxWindow
*)node
->Data();
3269 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3270 win
->ResetConstraints();
3271 node
= node
->Next();
3275 // Need to distinguish between setting the 'fake' size for
3276 // windows and sizers, and setting the real values.
3277 void wxWindow::SetConstraintSizes(bool recurse
)
3279 wxLayoutConstraints
*constr
= GetConstraints();
3280 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3281 constr
->width
.GetDone() && constr
->height
.GetDone())
3283 int x
= constr
->left
.GetValue();
3284 int y
= constr
->top
.GetValue();
3285 int w
= constr
->width
.GetValue();
3286 int h
= constr
->height
.GetValue();
3288 // If we don't want to resize this window, just move it...
3289 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3290 (constr
->height
.GetRelationship() != wxAsIs
))
3292 // Calls Layout() recursively. AAAGH. How can we stop that.
3293 // Simply take Layout() out of non-top level OnSizes.
3294 SizerSetSize(x
, y
, w
, h
);
3303 char *windowClass
= this->GetClassInfo()->GetClassName();
3306 if (GetName() == "")
3307 winName
= "unnamed";
3309 winName
= GetName();
3310 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3311 (const char *)windowClass
,
3312 (const char *)winName
);
3313 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3314 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3315 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3316 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3317 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3322 wxNode
*node
= m_children
.First();
3325 wxWindow
*win
= (wxWindow
*)node
->Data();
3326 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3327 win
->SetConstraintSizes();
3328 node
= node
->Next();
3333 // This assumes that all sizers are 'on' the same
3334 // window, i.e. the parent of this window.
3335 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3337 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3338 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3342 m_sizerParent
->GetPosition(&xp
, &yp
);
3343 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3348 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3352 TransformSizerToActual(&xx
, &yy
);
3353 SetSize(xx
, yy
, w
, h
);
3356 void wxWindow::SizerMove(int x
, int y
)
3360 TransformSizerToActual(&xx
, &yy
);
3364 // Only set the size/position of the constraint (if any)
3365 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3367 wxLayoutConstraints
*constr
= GetConstraints();
3372 constr
->left
.SetValue(x
);
3373 constr
->left
.SetDone(TRUE
);
3377 constr
->top
.SetValue(y
);
3378 constr
->top
.SetDone(TRUE
);
3382 constr
->width
.SetValue(w
);
3383 constr
->width
.SetDone(TRUE
);
3387 constr
->height
.SetValue(h
);
3388 constr
->height
.SetDone(TRUE
);
3393 void wxWindow::MoveConstraint(int x
, int y
)
3395 wxLayoutConstraints
*constr
= GetConstraints();
3400 constr
->left
.SetValue(x
);
3401 constr
->left
.SetDone(TRUE
);
3405 constr
->top
.SetValue(y
);
3406 constr
->top
.SetDone(TRUE
);
3411 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3413 wxLayoutConstraints
*constr
= GetConstraints();
3416 *w
= constr
->width
.GetValue();
3417 *h
= constr
->height
.GetValue();
3423 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3425 wxLayoutConstraints
*constr
= GetConstraints();
3428 *w
= constr
->width
.GetValue();
3429 *h
= constr
->height
.GetValue();
3432 GetClientSize(w
, h
);
3435 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3437 wxLayoutConstraints
*constr
= GetConstraints();
3440 *x
= constr
->left
.GetValue();
3441 *y
= constr
->top
.GetValue();
3447 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )