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 wxPoint
pt(win
->GetClientAreaOrigin());
639 event
.SetEventObject( win
);
641 gs_timeLastClick
= gdk_event
->time
;
643 if (win
->GetEventHandler()->ProcessEvent( event
))
644 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
649 //-----------------------------------------------------------------------------
650 // "button_release_event"
651 //-----------------------------------------------------------------------------
653 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
655 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
657 if (g_blockEventsOnDrag
) return TRUE
;
658 if (g_blockEventsOnScroll
) return TRUE
;
660 if (!win
->HasVMT()) return TRUE
;
663 printf( "OnButtonRelease from " );
664 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
665 printf( win->GetClassInfo()->GetClassName() );
669 wxEventType event_type
= wxEVT_NULL
;
671 switch (gdk_event
->button
)
673 case 1: event_type
= wxEVT_LEFT_UP
; break;
674 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
675 case 3: event_type
= wxEVT_RIGHT_UP
; break;
678 wxMouseEvent
event( event_type
);
679 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
680 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
681 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
682 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
683 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
684 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
685 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
686 event
.m_x
= (long)gdk_event
->x
;
687 event
.m_y
= (long)gdk_event
->y
;
689 // Some control don't have their own X window and thus cannot get
694 wxNode
*node
= win
->GetChildren().First();
697 wxWindow
*child
= (wxWindow
*)node
->Data();
699 if (child
->m_isStaticBox
)
701 // wxStaticBox is transparent in the box itself
704 int xx1
= child
->m_x
;
705 int yy1
= child
->m_y
;
706 int xx2
= child
->m_x
+ child
->m_width
;
707 int yy2
= child
->m_x
+ child
->m_height
;
710 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
712 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
714 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
716 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
719 event
.m_x
-= child
->m_x
;
720 event
.m_y
-= child
->m_y
;
727 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
728 (child
->m_x
<= event
.m_x
) &&
729 (child
->m_y
<= event
.m_y
) &&
730 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
731 (child
->m_y
+child
->m_height
>= event
.m_y
))
734 event
.m_x
-= child
->m_x
;
735 event
.m_y
-= child
->m_y
;
743 wxPoint
pt(win
->GetClientAreaOrigin());
747 event
.SetEventObject( win
);
749 if (win
->GetEventHandler()->ProcessEvent( event
))
750 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
755 //-----------------------------------------------------------------------------
756 // "motion_notify_event"
757 //-----------------------------------------------------------------------------
759 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
761 if (gdk_event
->is_hint
)
765 GdkModifierType state
;
766 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
769 gdk_event
->state
= state
;
772 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
774 if (g_blockEventsOnDrag
) return TRUE
;
775 if (g_blockEventsOnScroll
) return TRUE
;
777 if (!win
->HasVMT()) return TRUE
;
780 printf( "OnMotion from " );
781 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
782 printf( win->GetClassInfo()->GetClassName() );
786 wxMouseEvent
event( wxEVT_MOTION
);
787 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
788 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
789 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
790 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
791 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
792 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
793 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
795 event
.m_x
= (long)gdk_event
->x
;
796 event
.m_y
= (long)gdk_event
->y
;
798 // Some control don't have their own X window and thus cannot get
803 wxNode
*node
= win
->GetChildren().First();
806 wxWindow
*child
= (wxWindow
*)node
->Data();
808 if (child
->m_isStaticBox
)
810 // wxStaticBox is transparent in the box itself
813 int xx1
= child
->m_x
;
814 int yy1
= child
->m_y
;
815 int xx2
= child
->m_x
+ child
->m_width
;
816 int yy2
= child
->m_x
+ child
->m_height
;
819 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
821 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
823 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
825 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
828 event
.m_x
-= child
->m_x
;
829 event
.m_y
-= child
->m_y
;
836 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
837 (child
->m_x
<= event
.m_x
) &&
838 (child
->m_y
<= event
.m_y
) &&
839 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
840 (child
->m_y
+child
->m_height
>= event
.m_y
))
843 event
.m_x
-= child
->m_x
;
844 event
.m_y
-= child
->m_y
;
852 wxPoint
pt(win
->GetClientAreaOrigin());
856 event
.SetEventObject( win
);
858 if (win
->GetEventHandler()->ProcessEvent( event
))
859 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
864 //-----------------------------------------------------------------------------
866 //-----------------------------------------------------------------------------
868 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
870 if (g_blockEventsOnDrag
) return TRUE
;
876 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
878 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
880 printf( "SetFocus flag from " );
881 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
882 printf( win->GetClassInfo()->GetClassName() );
888 if (!win
->HasVMT()) return TRUE
;
891 printf( "OnSetFocus from " );
892 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
893 printf( win->GetClassInfo()->GetClassName() );
895 printf( WXSTRINGCAST win->GetLabel() );
899 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
900 event
.SetEventObject( win
);
902 if (win
->GetEventHandler()->ProcessEvent( event
))
903 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
908 //-----------------------------------------------------------------------------
910 //-----------------------------------------------------------------------------
912 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
914 if (g_blockEventsOnDrag
) return TRUE
;
917 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
918 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
921 if (!win
->HasVMT()) return TRUE
;
924 printf( "OnKillFocus from " );
925 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
926 printf( win->GetClassInfo()->GetClassName() );
930 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
931 event
.SetEventObject( win
);
933 if (win
->GetEventHandler()->ProcessEvent( event
))
934 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
939 //-----------------------------------------------------------------------------
940 // "enter_notify_event"
941 //-----------------------------------------------------------------------------
943 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
945 if (g_blockEventsOnDrag
) return TRUE
;
947 if ((widget
->window
) && (win
->m_cursor
))
948 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
950 if (widget
->window
!= gdk_event
->window
) return TRUE
;
952 if (!win
->HasVMT()) return TRUE
;
955 printf( "OnEnter from " );
956 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
957 printf( win->GetClassInfo()->GetClassName() );
961 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
962 event
.SetEventObject( win
);
966 GdkModifierType state
= (GdkModifierType
)0;
968 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
970 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
971 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
972 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
973 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
974 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
975 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
976 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
981 wxPoint
pt(win
->GetClientAreaOrigin());
985 if (win
->GetEventHandler()->ProcessEvent( event
))
986 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
991 //-----------------------------------------------------------------------------
992 // "leave_notify_event"
993 //-----------------------------------------------------------------------------
995 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
997 if (g_blockEventsOnDrag
) return TRUE
;
999 if ((widget
->window
) && (win
->m_cursor
))
1000 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1002 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1004 if (!win
->HasVMT()) return TRUE
;
1007 printf( "OnLeave from " );
1008 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1009 printf( win->GetClassInfo()->GetClassName() );
1013 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1014 event
.SetEventObject( win
);
1018 GdkModifierType state
= (GdkModifierType
)0;
1020 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1022 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1023 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1024 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1025 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1026 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1027 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1028 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1030 event
.m_x
= (long)x
;
1031 event
.m_y
= (long)y
;
1033 wxPoint
pt(win
->GetClientAreaOrigin());
1037 if (win
->GetEventHandler()->ProcessEvent( event
))
1038 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1043 //-----------------------------------------------------------------------------
1044 // "value_changed" from m_vAdjust
1045 //-----------------------------------------------------------------------------
1047 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1049 if (g_blockEventsOnDrag
) return;
1052 printf( "OnVScroll from " );
1053 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1054 printf( win->GetClassInfo()->GetClassName() );
1058 if (!win
->HasVMT()) return;
1060 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1061 if (fabs(diff
) < 0.2) return;
1063 wxEventType command
= wxEVT_NULL
;
1065 float line_step
= win
->m_vAdjust
->step_increment
;
1066 float page_step
= win
->m_vAdjust
->page_increment
;
1068 if (win
->m_isScrolling
)
1070 command
= wxEVT_SCROLL_THUMBTRACK
;
1074 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1075 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1076 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1077 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1078 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1079 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1080 else command
= wxEVT_SCROLL_THUMBTRACK
;
1083 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1085 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1086 event
.SetEventObject( win
);
1087 win
->GetEventHandler()->ProcessEvent( event
);
1090 //-----------------------------------------------------------------------------
1091 // "value_changed" from m_hAdjust
1092 //-----------------------------------------------------------------------------
1094 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1096 if (g_blockEventsOnDrag
) return;
1099 printf( "OnHScroll from " );
1100 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1101 printf( win->GetClassInfo()->GetClassName() );
1105 if (!win
->HasVMT()) return;
1107 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1108 if (fabs(diff
) < 0.2) return;
1110 wxEventType command
= wxEVT_NULL
;
1112 float line_step
= win
->m_hAdjust
->step_increment
;
1113 float page_step
= win
->m_hAdjust
->page_increment
;
1115 if (win
->m_isScrolling
)
1117 command
= wxEVT_SCROLL_THUMBTRACK
;
1121 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1122 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1123 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1124 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1125 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1126 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1127 else command
= wxEVT_SCROLL_THUMBTRACK
;
1130 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1132 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1133 event
.SetEventObject( win
);
1134 win
->GetEventHandler()->ProcessEvent( event
);
1137 //-----------------------------------------------------------------------------
1138 // "changed" from m_vAdjust
1139 //-----------------------------------------------------------------------------
1141 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1143 if (g_blockEventsOnDrag
) return;
1146 printf( "OnVScroll change from " );
1147 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1148 printf( win->GetClassInfo()->GetClassName() );
1152 if (!win
->HasVMT()) return;
1154 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1155 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1157 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1158 event
.SetEventObject( win
);
1159 win
->GetEventHandler()->ProcessEvent( event
);
1162 //-----------------------------------------------------------------------------
1163 // "changed" from m_hAdjust
1164 //-----------------------------------------------------------------------------
1166 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1168 if (g_blockEventsOnDrag
) return;
1171 printf( "OnHScroll change from " );
1172 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1173 printf( win->GetClassInfo()->GetClassName() );
1177 if (!win
->HasVMT()) return;
1179 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1180 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1182 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1183 event
.SetEventObject( win
);
1184 win
->GetEventHandler()->ProcessEvent( event
);
1187 //-----------------------------------------------------------------------------
1188 // "button_press_event" from scrollbar
1189 //-----------------------------------------------------------------------------
1191 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1192 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 win
->m_isScrolling
= TRUE
;
1201 g_blockEventsOnScroll
= TRUE
;
1206 //-----------------------------------------------------------------------------
1207 // "button_release_event" from scrollbar
1208 //-----------------------------------------------------------------------------
1210 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1211 GdkEventButton
*WXUNUSED(gdk_event
),
1215 // don't test here as we can release the mouse while being over
1216 // a different window then the slider
1218 // if (gdk_event->window != widget->slider) return FALSE;
1220 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1222 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1223 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1225 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1227 win
->m_isScrolling
= FALSE
;
1228 g_blockEventsOnScroll
= FALSE
;
1233 //-----------------------------------------------------------------------------
1234 // InsertChild for wxWindow.
1235 //-----------------------------------------------------------------------------
1237 // Callback for wxWindow. This very strange beast has to be used because
1238 // C++ has no virtual methods in a constructor. We have to emulate a
1239 // virtual function here as wxNotebook requires a different way to insert
1240 // a child in it. I had opted for creating a wxNotebookPage window class
1241 // which would have made this superfluous (such in the MDI window system),
1242 // but no-one was listening to me...
1244 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1246 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1247 GTK_WIDGET(child
->m_widget
),
1251 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1255 if (wxIS_KIND_OF(parent
,wxFrame
))
1257 parent
->m_sizeSet
= FALSE
;
1261 //-----------------------------------------------------------------------------
1263 //-----------------------------------------------------------------------------
1265 wxWindow
* wxGetActiveWindow()
1267 return g_focusWindow
;
1270 //-----------------------------------------------------------------------------
1272 //-----------------------------------------------------------------------------
1274 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1276 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1277 EVT_SIZE(wxWindow::OnSize
)
1278 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1279 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1280 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1283 wxWindow::wxWindow()
1285 m_widget
= (GtkWidget
*) NULL
;
1286 m_wxwindow
= (GtkWidget
*) NULL
;
1287 m_parent
= (wxWindow
*) NULL
;
1288 m_children
.DeleteContents( FALSE
);
1301 m_eventHandler
= this;
1302 m_windowValidator
= (wxValidator
*) NULL
;
1306 m_cursor
= (wxCursor
*) NULL
;
1307 m_font
= *wxSWISS_FONT
;
1309 m_windowName
= "noname";
1311 m_constraints
= (wxLayoutConstraints
*) NULL
;
1312 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1313 m_windowSizer
= (wxSizer
*) NULL
;
1314 m_sizerParent
= (wxWindow
*) NULL
;
1315 m_autoLayout
= FALSE
;
1319 m_needParent
= TRUE
;
1321 m_hasScrolling
= FALSE
;
1322 m_isScrolling
= FALSE
;
1323 m_hAdjust
= (GtkAdjustment
*) NULL
;
1324 m_vAdjust
= (GtkAdjustment
*) NULL
;
1325 m_oldHorizontalPos
= 0.0;
1326 m_oldVerticalPos
= 0.0;
1331 #if wxUSE_DRAG_AND_DROP
1332 m_dropTarget
= (wxDropTarget
*) NULL
;
1335 m_scrollGC
= (GdkGC
*) NULL
;
1336 m_widgetStyle
= (GtkStyle
*) NULL
;
1338 m_insertCallback
= wxInsertChildInWindow
;
1340 m_clientObject
= (wxClientData
*) NULL
;
1341 m_clientData
= NULL
;
1343 m_isStaticBox
= FALSE
;
1344 m_acceptsFocus
= FALSE
;
1347 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1348 const wxPoint
&pos
, const wxSize
&size
,
1349 long style
, const wxString
&name
)
1351 m_insertCallback
= wxInsertChildInWindow
;
1352 Create( parent
, id
, pos
, size
, style
, name
);
1355 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1356 const wxPoint
&pos
, const wxSize
&size
,
1357 long style
, const wxString
&name
)
1361 m_needParent
= TRUE
;
1363 PreCreation( parent
, id
, pos
, size
, style
, name
);
1365 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1366 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1369 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1372 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1375 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1376 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1379 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1380 scroll_class
->scrollbar_spacing
= 0;
1382 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1384 m_oldHorizontalPos
= 0.0;
1385 m_oldVerticalPos
= 0.0;
1387 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1388 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1390 m_wxwindow
= gtk_myfixed_new();
1393 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1396 #ifdef NEW_GTK_SCROLL_CODE
1397 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1398 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1400 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1401 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1405 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1408 if (m_windowStyle
& wxRAISED_BORDER
)
1410 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1412 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1414 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1418 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1421 if ((m_windowStyle
& wxTAB_TRAVERSAL
) != 0)
1423 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1424 m_acceptsFocus
= FALSE
;
1428 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1429 m_acceptsFocus
= TRUE
;
1432 // shut the viewport up
1433 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1434 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1436 // I _really_ don't want scrollbars in the beginning
1437 m_vAdjust
->lower
= 0.0;
1438 m_vAdjust
->upper
= 1.0;
1439 m_vAdjust
->value
= 0.0;
1440 m_vAdjust
->step_increment
= 1.0;
1441 m_vAdjust
->page_increment
= 1.0;
1442 m_vAdjust
->page_size
= 5.0;
1443 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1444 m_hAdjust
->lower
= 0.0;
1445 m_hAdjust
->upper
= 1.0;
1446 m_hAdjust
->value
= 0.0;
1447 m_hAdjust
->step_increment
= 1.0;
1448 m_hAdjust
->page_increment
= 1.0;
1449 m_hAdjust
->page_size
= 5.0;
1450 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1452 // these handlers block mouse events to any window during scrolling
1453 // such as motion events and prevent GTK and wxWindows from fighting
1454 // over where the slider should be
1456 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1457 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1459 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1460 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1462 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1463 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1465 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1466 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1468 // these handers het notified when screen updates are required either when
1469 // scrolling or when the window size (and therefore scrollbar configuration)
1472 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1473 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1474 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1475 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1477 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1478 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1479 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1480 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1482 gtk_widget_show( m_wxwindow
);
1484 if (m_parent
) m_parent
->AddChild( this );
1486 (m_parent
->m_insertCallback
)( m_parent
, this );
1495 wxWindow::~wxWindow()
1499 #if wxUSE_DRAG_AND_DROP
1500 if (m_dropTarget
) delete m_dropTarget
;
1503 if (m_parent
) m_parent
->RemoveChild( this );
1504 if (m_widget
) Show( FALSE
);
1508 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1510 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1512 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1514 if (m_widget
) gtk_widget_destroy( m_widget
);
1516 if (m_cursor
) delete m_cursor
;
1518 DeleteRelatedConstraints();
1521 // This removes any dangling pointers to this window
1522 // in other windows' constraintsInvolvedIn lists.
1523 UnsetConstraints(m_constraints
);
1524 delete m_constraints
;
1525 m_constraints
= (wxLayoutConstraints
*) NULL
;
1529 delete m_windowSizer
;
1530 m_windowSizer
= (wxSizer
*) NULL
;
1532 // If this is a child of a sizer, remove self from parent
1533 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1535 // Just in case the window has been Closed, but
1536 // we're then deleting immediately: don't leave
1537 // dangling pointers.
1538 wxPendingDelete
.DeleteObject(this);
1540 // Just in case we've loaded a top-level window via
1541 // wxWindow::LoadNativeDialog but we weren't a dialog
1543 wxTopLevelWindows
.DeleteObject(this);
1545 if (m_windowValidator
) delete m_windowValidator
;
1547 if (m_clientObject
) delete m_clientObject
;
1550 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1551 const wxPoint
&pos
, const wxSize
&size
,
1552 long style
, const wxString
&name
)
1554 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1556 m_widget
= (GtkWidget
*) NULL
;
1557 m_wxwindow
= (GtkWidget
*) NULL
;
1560 m_children
.DeleteContents( FALSE
);
1563 if (m_width
== -1) m_width
= 20;
1565 if (m_height
== -1) m_height
= 20;
1570 if (!m_needParent
) // some reasonable defaults
1574 m_x
= (gdk_screen_width () - m_width
) / 2;
1575 if (m_x
< 10) m_x
= 10;
1579 m_y
= (gdk_screen_height () - m_height
) / 2;
1580 if (m_y
< 10) m_y
= 10;
1591 m_eventHandler
= this;
1593 m_windowId
= id
== -1 ? wxNewId() : id
;
1597 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1598 m_font
= *wxSWISS_FONT
;
1599 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1600 m_foregroundColour
= *wxBLACK
;
1601 m_windowStyle
= style
;
1602 m_windowName
= name
;
1604 m_constraints
= (wxLayoutConstraints
*) NULL
;
1605 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1606 m_windowSizer
= (wxSizer
*) NULL
;
1607 m_sizerParent
= (wxWindow
*) NULL
;
1608 m_autoLayout
= FALSE
;
1610 m_hasScrolling
= FALSE
;
1611 m_isScrolling
= FALSE
;
1612 m_hAdjust
= (GtkAdjustment
*) NULL
;
1613 m_vAdjust
= (GtkAdjustment
*) NULL
;
1614 m_oldHorizontalPos
= 0.0;
1615 m_oldVerticalPos
= 0.0;
1620 #if wxUSE_DRAG_AND_DROP
1621 m_dropTarget
= (wxDropTarget
*) NULL
;
1624 m_windowValidator
= (wxValidator
*) NULL
;
1625 m_scrollGC
= (GdkGC
*) NULL
;
1626 m_widgetStyle
= (GtkStyle
*) NULL
;
1628 m_clientObject
= (wxClientData
*)NULL
;
1629 m_clientData
= NULL
;
1631 m_isStaticBox
= FALSE
;
1634 void wxWindow::PostCreation()
1638 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1639 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1641 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1642 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1645 ConnectWidget( GetConnectWidget() );
1647 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1649 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1651 SetCursor( *wxSTANDARD_CURSOR
);
1656 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1658 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1659 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1661 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1662 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1664 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1665 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1667 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1668 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1670 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1671 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1673 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1674 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1676 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1677 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1679 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1680 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1682 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1683 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1686 bool wxWindow::HasVMT()
1691 bool wxWindow::Close( bool force
)
1693 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1695 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1696 event
.SetEventObject(this);
1697 event
.SetForce(force
);
1699 return GetEventHandler()->ProcessEvent(event
);
1702 bool wxWindow::Destroy()
1704 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1711 bool wxWindow::DestroyChildren()
1714 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1717 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1720 if (m_children
.Member(child
)) delete node
;
1726 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1728 // are we to set fonts here ?
1731 wxPoint
wxWindow::GetClientAreaOrigin() const
1733 return wxPoint(0,0);
1736 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1738 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1740 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1746 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1748 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1749 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1751 if (m_resizing
) return; // I don't like recursions
1754 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1756 // don't set the size for children of wxNotebook, just take the values.
1764 int old_width
= m_width
;
1765 int old_height
= m_height
;
1767 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1769 if (x
!= -1) m_x
= x
;
1770 if (y
!= -1) m_y
= y
;
1771 if (width
!= -1) m_width
= width
;
1772 if (height
!= -1) m_height
= height
;
1782 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1784 if (width
== -1) m_width
= 80;
1787 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1789 if (height
== -1) m_height
= 26;
1792 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1793 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1794 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1795 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1797 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1798 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1800 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1801 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1806 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1807 event
.SetEventObject( this );
1808 GetEventHandler()->ProcessEvent( event
);
1813 void wxWindow::OnInternalIdle()
1818 void wxWindow::SetSize( int width
, int height
)
1820 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1823 void wxWindow::Move( int x
, int y
)
1825 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1828 void wxWindow::GetSize( int *width
, int *height
) const
1830 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1832 if (width
) (*width
) = m_width
;
1833 if (height
) (*height
) = m_height
;
1836 void wxWindow::SetClientSize( int width
, int height
)
1838 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1842 SetSize( width
, height
);
1849 if (!m_hasScrolling
)
1851 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1853 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1854 (m_windowStyle
& wxSUNKEN_BORDER
))
1856 dw
+= 2 * window_class
->xthickness
;
1857 dh
+= 2 * window_class
->ythickness
;
1862 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1863 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1865 #ifdef NEW_GTK_SCROLL_CODE
1866 GtkWidget
*viewport
= scroll_window
->child
;
1868 GtkWidget
*viewport
= scroll_window
->viewport
;
1871 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1873 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1874 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1876 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1877 (m_windowStyle
& wxSUNKEN_BORDER
))
1879 dw
+= 2 * viewport_class
->xthickness
;
1880 dh
+= 2 * viewport_class
->ythickness
;
1883 if (scroll_window
->vscrollbar_visible
)
1885 dw
+= vscrollbar
->allocation
.width
;
1886 dw
+= scroll_class
->scrollbar_spacing
;
1889 if (scroll_window
->hscrollbar_visible
)
1891 dh
+= hscrollbar
->allocation
.height
;
1892 dw
+= scroll_class
->scrollbar_spacing
;
1896 SetSize( width
+dw
, height
+dh
);
1900 void wxWindow::GetClientSize( int *width
, int *height
) const
1902 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1906 if (width
) (*width
) = m_width
;
1907 if (height
) (*height
) = m_height
;
1914 if (!m_hasScrolling
)
1916 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1918 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1919 (m_windowStyle
& wxSUNKEN_BORDER
))
1921 dw
+= 2 * window_class
->xthickness
;
1922 dh
+= 2 * window_class
->ythickness
;
1927 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1928 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1930 #ifdef NEW_GTK_SCROLL_CODE
1931 GtkWidget
*viewport
= scroll_window
->child
;
1933 GtkWidget
*viewport
= scroll_window
->viewport
;
1936 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1938 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1939 (m_windowStyle
& wxSUNKEN_BORDER
))
1941 dw
+= 2 * viewport_class
->xthickness
;
1942 dh
+= 2 * viewport_class
->ythickness
;
1945 if (scroll_window
->vscrollbar_visible
)
1947 // dw += vscrollbar->allocation.width;
1948 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1949 dw
+= scroll_class
->scrollbar_spacing
;
1952 if (scroll_window
->hscrollbar_visible
)
1954 // dh += hscrollbar->allocation.height;
1956 dh
+= scroll_class
->scrollbar_spacing
;
1960 if (width
) (*width
) = m_width
- dw
;
1961 if (height
) (*height
) = m_height
- dh
;
1965 void wxWindow::GetPosition( int *x
, int *y
) const
1967 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1973 void wxWindow::ClientToScreen( int *x
, int *y
)
1975 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1977 GdkWindow
*source
= (GdkWindow
*) NULL
;
1979 source
= m_wxwindow
->window
;
1981 source
= m_widget
->window
;
1985 gdk_window_get_origin( source
, &org_x
, &org_y
);
1989 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1991 org_x
+= m_widget
->allocation
.x
;
1992 org_y
+= m_widget
->allocation
.y
;
1996 wxPoint
pt(GetClientAreaOrigin());
2004 void wxWindow::ScreenToClient( int *x
, int *y
)
2006 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2008 GdkWindow
*source
= (GdkWindow
*) NULL
;
2010 source
= m_wxwindow
->window
;
2012 source
= m_widget
->window
;
2016 gdk_window_get_origin( source
, &org_x
, &org_y
);
2020 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2022 org_x
+= m_widget
->allocation
.x
;
2023 org_y
+= m_widget
->allocation
.y
;
2027 wxPoint
pt(GetClientAreaOrigin());
2035 void wxWindow::Centre( int direction
)
2037 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2046 m_parent
->GetSize( &p_w
, &p_h
);
2047 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2048 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2052 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2053 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2059 void wxWindow::Fit()
2061 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2065 wxNode
*node
= m_children
.First();
2068 wxWindow
*win
= (wxWindow
*)node
->Data();
2070 win
->GetPosition(&wx
, &wy
);
2071 win
->GetSize(&ww
, &wh
);
2072 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2073 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2075 node
= node
->Next();
2078 SetClientSize(maxX
+ 7, maxY
+ 14);
2081 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2083 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2091 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2093 // if (GetAutoLayout()) Layout();
2096 bool wxWindow::Show( bool show
)
2098 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2101 gtk_widget_show( m_widget
);
2103 gtk_widget_hide( m_widget
);
2110 void wxWindow::Enable( bool enable
)
2112 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2114 m_isEnabled
= enable
;
2116 gtk_widget_set_sensitive( m_widget
, enable
);
2117 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2120 int wxWindow::GetCharHeight() const
2122 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2124 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2126 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2128 return font
->ascent
+ font
->descent
;
2131 int wxWindow::GetCharWidth() const
2133 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2135 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2137 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2139 return gdk_string_width( font
, "H" );
2142 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2143 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2145 wxFont fontToUse
= m_font
;
2146 if (theFont
) fontToUse
= *theFont
;
2148 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2150 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2151 if (x
) (*x
) = gdk_string_width( font
, string
);
2152 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2153 if (descent
) (*descent
) = font
->descent
;
2154 if (externalLeading
) (*externalLeading
) = 0; // ??
2157 void wxWindow::MakeModal( bool modal
)
2161 // Disable all other windows
2162 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2164 wxNode
*node
= wxTopLevelWindows
.First();
2167 wxWindow
*win
= (wxWindow
*)node
->Data();
2168 if (win
!= this) win
->Enable(!modal
);
2170 node
= node
->Next();
2175 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2177 event
.SetEventType( wxEVT_CHAR
);
2179 if (!GetEventHandler()->ProcessEvent( event
))
2185 void wxWindow::SetFocus()
2187 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2189 GtkWidget
*connect_widget
= GetConnectWidget();
2192 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2194 gtk_widget_grab_focus (connect_widget
);
2196 else if (GTK_IS_CONTAINER(connect_widget
))
2198 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2206 wxWindow
*wxWindow::FindFocus()
2208 return g_focusWindow
;
2211 bool wxWindow::AcceptsFocus() const
2213 return IsEnabled() && IsShown() && m_acceptsFocus
;
2216 bool wxWindow::OnClose()
2221 void wxWindow::AddChild( wxWindow
*child
)
2223 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2224 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2226 m_children
.Append( child
);
2229 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2231 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2233 wxWindow
*oldParent
= GetParent();
2235 if (oldParent
) oldParent
->RemoveChild( this );
2237 gtk_widget_unparent( m_widget
);
2241 newParent
->AddChild( this );
2242 (newParent
->m_insertCallback
)( newParent
, this );
2248 void wxWindow::RemoveChild( wxWindow
*child
)
2250 m_children
.DeleteObject( child
);
2251 child
->m_parent
= (wxWindow
*) NULL
;
2254 void wxWindow::SetReturnCode( int retCode
)
2256 m_retCode
= retCode
;
2259 int wxWindow::GetReturnCode()
2264 void wxWindow::Raise()
2266 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2268 if (m_widget
) gdk_window_raise( m_widget
->window
);
2271 void wxWindow::Lower()
2273 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2275 if (m_widget
) gdk_window_lower( m_widget
->window
);
2278 wxEvtHandler
*wxWindow::GetEventHandler() const
2280 return m_eventHandler
;
2283 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2285 m_eventHandler
= handler
;
2288 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2290 handler
->SetNextHandler(GetEventHandler());
2291 SetEventHandler(handler
);
2294 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2296 if (GetEventHandler())
2298 wxEvtHandler
*handlerA
= GetEventHandler();
2299 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2300 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2301 SetEventHandler(handlerB
);
2305 return (wxEvtHandler
*) NULL
;
2311 return (wxEvtHandler
*) NULL
;
2314 wxValidator
*wxWindow::GetValidator()
2316 return m_windowValidator
;
2319 void wxWindow::SetValidator( const wxValidator
& validator
)
2321 if (m_windowValidator
) delete m_windowValidator
;
2322 m_windowValidator
= validator
.Clone();
2323 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2326 void wxWindow::SetClientObject( wxClientData
*data
)
2328 if (m_clientObject
) delete m_clientObject
;
2329 m_clientObject
= data
;
2332 wxClientData
*wxWindow::GetClientObject()
2334 return m_clientObject
;
2337 void wxWindow::SetClientData( void *data
)
2339 m_clientData
= data
;
2342 void *wxWindow::GetClientData()
2344 return m_clientData
;
2347 bool wxWindow::IsBeingDeleted()
2352 void wxWindow::SetId( wxWindowID id
)
2357 wxWindowID
wxWindow::GetId() const
2362 void wxWindow::SetCursor( const wxCursor
&cursor
)
2364 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2368 if (cursor
== *m_cursor
) return;
2373 *m_cursor
= *wxSTANDARD_CURSOR
;
2376 if ((m_widget
) && (m_widget
->window
))
2377 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2379 if ((m_wxwindow
) && (m_wxwindow
->window
))
2380 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2383 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2388 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2390 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2392 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2396 gdk_window_clear_area( m_wxwindow
->window
,
2410 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2412 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2416 GdkRectangle gdk_rect
;
2417 gdk_rect
.x
= rect
->x
;
2418 gdk_rect
.y
= rect
->y
;
2419 gdk_rect
.width
= rect
->width
;
2420 gdk_rect
.height
= rect
->height
;
2423 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2425 gtk_widget_draw( m_widget
, &gdk_rect
);
2429 wxRegion
wxWindow::GetUpdateRegion() const
2431 return m_updateRegion
;
2434 bool wxWindow::IsExposed( int x
, int y
) const
2436 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2439 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2441 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2444 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2446 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2449 bool wxWindow::IsExposed( const wxRect
& rect
) const
2451 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2454 void wxWindow::Clear()
2456 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2458 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2461 wxColour
wxWindow::GetBackgroundColour() const
2463 return m_backgroundColour
;
2466 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2468 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2470 if (m_backgroundColour
== colour
) return;
2472 m_backgroundColour
= colour
;
2473 if (!m_backgroundColour
.Ok()) return;
2477 GdkWindow
*window
= m_wxwindow
->window
;
2478 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2479 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2480 gdk_window_clear( window
);
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 wxColour
wxWindow::GetForegroundColour() const
2500 return m_foregroundColour
;
2503 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2505 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2507 if (m_foregroundColour
== colour
) return;
2509 m_foregroundColour
= colour
;
2510 if (!m_foregroundColour
.Ok()) return;
2512 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2513 if (sysbg
.Red() == colour
.Red() &&
2514 sysbg
.Green() == colour
.Green() &&
2515 sysbg
.Blue() == colour
.Blue())
2517 m_backgroundColour
= wxNullColour
;
2519 m_backgroundColour
= sysbg
;
2527 GtkStyle
*wxWindow::GetWidgetStyle()
2529 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2533 gtk_widget_get_style( m_widget
) );
2535 return m_widgetStyle
;
2538 void wxWindow::SetWidgetStyle()
2540 GtkStyle
*style
= GetWidgetStyle();
2542 gdk_font_unref( style
->font
);
2543 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2545 if (m_foregroundColour
.Ok())
2547 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2548 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2549 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2550 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2553 if (m_backgroundColour
.Ok())
2555 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2556 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2557 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2558 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2559 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2560 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2561 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2562 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2563 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2567 void wxWindow::ApplyWidgetStyle()
2571 bool wxWindow::Validate()
2573 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2575 wxNode
*node
= m_children
.First();
2578 wxWindow
*child
= (wxWindow
*)node
->Data();
2579 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2583 node
= node
->Next();
2588 bool wxWindow::TransferDataToWindow()
2590 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2592 wxNode
*node
= m_children
.First();
2595 wxWindow
*child
= (wxWindow
*)node
->Data();
2596 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2597 !child
->GetValidator()->TransferToWindow() )
2599 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2602 node
= node
->Next();
2607 bool wxWindow::TransferDataFromWindow()
2609 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2611 wxNode
*node
= m_children
.First();
2614 wxWindow
*child
= (wxWindow
*)node
->Data();
2615 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2619 node
= node
->Next();
2624 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2626 m_acceleratorTable
= accel
;
2629 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2631 TransferDataToWindow();
2634 void wxWindow::InitDialog()
2636 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2638 wxInitDialogEvent
event(GetId());
2639 event
.SetEventObject( this );
2640 GetEventHandler()->ProcessEvent(event
);
2643 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2645 menu
->SetInvokingWindow( win
);
2646 wxNode
*node
= menu
->m_items
.First();
2649 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2650 if (menuitem
->IsSubMenu())
2652 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2654 node
= node
->Next();
2658 static gint gs_pop_x
= 0;
2659 static gint gs_pop_y
= 0;
2661 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2663 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2668 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2670 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2672 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2674 SetInvokingWindow( menu
, this );
2680 GTK_MENU(menu
->m_menu
),
2681 (GtkWidget
*) NULL
, // parent menu shell
2682 (GtkWidget
*) NULL
, // parent menu item
2683 (GtkMenuPositionFunc
) pop_pos_callback
,
2684 (gpointer
) this, // client data
2685 0, // button used to activate it
2686 0 //gs_timeLastClick // the time of activation
2691 #if wxUSE_DRAG_AND_DROP
2693 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2695 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2697 GtkWidget
*dnd_widget
= GetConnectWidget();
2699 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2701 if (m_dropTarget
) delete m_dropTarget
;
2702 m_dropTarget
= dropTarget
;
2704 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2707 wxDropTarget
*wxWindow::GetDropTarget() const
2709 return m_dropTarget
;
2714 GtkWidget
* wxWindow::GetConnectWidget()
2716 GtkWidget
*connect_widget
= m_widget
;
2717 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2719 return connect_widget
;
2722 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2724 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2725 return (window
== m_widget
->window
);
2728 void wxWindow::SetFont( const wxFont
&font
)
2730 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2732 if (((wxFont
*)&font
)->Ok())
2735 m_font
= *wxSWISS_FONT
;
2737 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2738 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2739 sysbg
.Green() == m_backgroundColour
.Green() &&
2740 sysbg
.Blue() == m_backgroundColour
.Blue())
2742 m_backgroundColour
= wxNullColour
;
2744 m_backgroundColour
= sysbg
;
2752 void wxWindow::SetWindowStyleFlag( long flag
)
2754 m_windowStyle
= flag
;
2757 long wxWindow::GetWindowStyleFlag() const
2759 return m_windowStyle
;
2762 void wxWindow::CaptureMouse()
2764 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2766 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2768 GtkWidget
*connect_widget
= GetConnectWidget();
2769 gtk_grab_add( connect_widget
);
2770 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2772 (GDK_BUTTON_PRESS_MASK
|
2773 GDK_BUTTON_RELEASE_MASK
|
2774 GDK_POINTER_MOTION_MASK
),
2781 void wxWindow::ReleaseMouse()
2783 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2785 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2787 GtkWidget
*connect_widget
= GetConnectWidget();
2788 gtk_grab_remove( connect_widget
);
2789 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2790 g_capturing
= FALSE
;
2793 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2797 wxString
wxWindow::GetTitle() const
2799 return (wxString
&)m_windowName
;
2802 wxString
wxWindow::GetLabel() const
2807 void wxWindow::SetName( const wxString
&name
)
2809 m_windowName
= name
;
2812 wxString
wxWindow::GetName() const
2814 return (wxString
&)m_windowName
;
2817 bool wxWindow::IsShown() const
2822 bool wxWindow::IsRetained()
2827 wxWindow
*wxWindow::FindWindow( long id
)
2829 if (id
== m_windowId
) return this;
2830 wxNode
*node
= m_children
.First();
2833 wxWindow
*child
= (wxWindow
*)node
->Data();
2834 wxWindow
*res
= child
->FindWindow( id
);
2835 if (res
) return res
;
2836 node
= node
->Next();
2838 return (wxWindow
*) NULL
;
2841 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2843 if (name
== m_windowName
) return this;
2844 wxNode
*node
= m_children
.First();
2847 wxWindow
*child
= (wxWindow
*)node
->Data();
2848 wxWindow
*res
= child
->FindWindow( name
);
2849 if (res
) return res
;
2850 node
= node
->Next();
2852 return (wxWindow
*) NULL
;
2855 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2856 int range
, bool refresh
)
2858 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2860 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2862 m_hasScrolling
= TRUE
;
2864 if (orient
== wxHORIZONTAL
)
2866 float fpos
= (float)pos
;
2867 float frange
= (float)range
;
2868 float fthumb
= (float)thumbVisible
;
2869 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2870 if (fpos
< 0.0) fpos
= 0.0;
2872 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2873 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2875 SetScrollPos( orient
, pos
, refresh
);
2879 m_oldHorizontalPos
= fpos
;
2881 m_hAdjust
->lower
= 0.0;
2882 m_hAdjust
->upper
= frange
;
2883 m_hAdjust
->value
= fpos
;
2884 m_hAdjust
->step_increment
= 1.0;
2885 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2886 m_hAdjust
->page_size
= fthumb
;
2890 float fpos
= (float)pos
;
2891 float frange
= (float)range
;
2892 float fthumb
= (float)thumbVisible
;
2893 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2894 if (fpos
< 0.0) fpos
= 0.0;
2896 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2897 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2899 SetScrollPos( orient
, pos
, refresh
);
2903 m_oldVerticalPos
= fpos
;
2905 m_vAdjust
->lower
= 0.0;
2906 m_vAdjust
->upper
= frange
;
2907 m_vAdjust
->value
= fpos
;
2908 m_vAdjust
->step_increment
= 1.0;
2909 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2910 m_vAdjust
->page_size
= fthumb
;
2913 if (m_wxwindow
->window
)
2915 if (orient
== wxHORIZONTAL
)
2916 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2918 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2920 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2924 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2926 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2928 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2930 if (orient
== wxHORIZONTAL
)
2932 float fpos
= (float)pos
;
2933 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2934 if (fpos
< 0.0) fpos
= 0.0;
2935 m_oldHorizontalPos
= fpos
;
2937 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2938 m_hAdjust
->value
= fpos
;
2942 float fpos
= (float)pos
;
2943 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2944 if (fpos
< 0.0) fpos
= 0.0;
2945 m_oldVerticalPos
= fpos
;
2947 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2948 m_vAdjust
->value
= fpos
;
2953 if (m_wxwindow
->window
)
2955 if (orient
== wxHORIZONTAL
)
2956 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2958 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2963 int wxWindow::GetScrollThumb( int orient
) const
2965 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2967 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2969 if (orient
== wxHORIZONTAL
)
2970 return (int)(m_hAdjust
->page_size
+0.5);
2972 return (int)(m_vAdjust
->page_size
+0.5);
2975 int wxWindow::GetScrollPos( int orient
) const
2977 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2979 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2981 if (orient
== wxHORIZONTAL
)
2982 return (int)(m_hAdjust
->value
+0.5);
2984 return (int)(m_vAdjust
->value
+0.5);
2987 int wxWindow::GetScrollRange( int orient
) const
2989 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2991 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2993 if (orient
== wxHORIZONTAL
)
2994 return (int)(m_hAdjust
->upper
+0.5);
2996 return (int)(m_vAdjust
->upper
+0.5);
2999 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3001 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3003 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3007 GetClientSize( &cw
, &ch
);
3009 int w
= cw
- abs(dx
);
3010 int h
= ch
- abs(dy
);
3011 if ((h
< 0) || (w
< 0))
3018 if (dx
< 0) s_x
= -dx
;
3019 if (dy
< 0) s_y
= -dy
;
3022 if (dx
> 0) d_x
= dx
;
3023 if (dy
> 0) d_y
= dy
;
3027 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3028 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3031 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3032 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3035 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3036 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3037 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3038 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3040 Refresh( TRUE
, &rect
);
3043 //-------------------------------------------------------------------------------------
3045 //-------------------------------------------------------------------------------------
3047 wxLayoutConstraints
*wxWindow::GetConstraints() const
3049 return m_constraints
;
3052 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3056 UnsetConstraints(m_constraints
);
3057 delete m_constraints
;
3059 m_constraints
= constraints
;
3062 // Make sure other windows know they're part of a 'meaningful relationship'
3063 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3064 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3065 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3066 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3067 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3068 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3069 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3070 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3071 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3072 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3073 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3074 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3075 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3076 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3077 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3078 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3084 void wxWindow::SetAutoLayout( bool autoLayout
)
3086 m_autoLayout
= autoLayout
;
3089 bool wxWindow::GetAutoLayout() const
3091 return m_autoLayout
;
3094 wxSizer
*wxWindow::GetSizer() const
3096 return m_windowSizer
;
3099 void wxWindow::SetSizerParent( wxWindow
*win
)
3101 m_sizerParent
= win
;
3104 wxWindow
*wxWindow::GetSizerParent() const
3106 return m_sizerParent
;
3109 // This removes any dangling pointers to this window
3110 // in other windows' constraintsInvolvedIn lists.
3111 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3115 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3116 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3117 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3118 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3119 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3120 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3121 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3122 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3123 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3124 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3125 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3126 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3127 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3128 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3129 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3130 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3134 // Back-pointer to other windows we're involved with, so if we delete
3135 // this window, we must delete any constraints we're involved with.
3136 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3138 if (!m_constraintsInvolvedIn
)
3139 m_constraintsInvolvedIn
= new wxList
;
3140 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3141 m_constraintsInvolvedIn
->Append(otherWin
);
3144 // REMOVE back-pointer to other windows we're involved with.
3145 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3147 if (m_constraintsInvolvedIn
)
3148 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3151 // Reset any constraints that mention this window
3152 void wxWindow::DeleteRelatedConstraints()
3154 if (m_constraintsInvolvedIn
)
3156 wxNode
*node
= m_constraintsInvolvedIn
->First();
3159 wxWindow
*win
= (wxWindow
*)node
->Data();
3160 wxNode
*next
= node
->Next();
3161 wxLayoutConstraints
*constr
= win
->GetConstraints();
3163 // Reset any constraints involving this window
3166 constr
->left
.ResetIfWin((wxWindow
*)this);
3167 constr
->top
.ResetIfWin((wxWindow
*)this);
3168 constr
->right
.ResetIfWin((wxWindow
*)this);
3169 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3170 constr
->width
.ResetIfWin((wxWindow
*)this);
3171 constr
->height
.ResetIfWin((wxWindow
*)this);
3172 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3173 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3178 delete m_constraintsInvolvedIn
;
3179 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3183 void wxWindow::SetSizer(wxSizer
*sizer
)
3185 m_windowSizer
= sizer
;
3187 sizer
->SetSizerParent((wxWindow
*)this);
3194 bool wxWindow::Layout()
3196 if (GetConstraints())
3199 GetClientSize(&w
, &h
);
3200 GetConstraints()->width
.SetValue(w
);
3201 GetConstraints()->height
.SetValue(h
);
3204 // If top level (one sizer), evaluate the sizer's constraints.
3208 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3209 GetSizer()->LayoutPhase1(&noChanges
);
3210 GetSizer()->LayoutPhase2(&noChanges
);
3211 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3216 // Otherwise, evaluate child constraints
3217 ResetConstraints(); // Mark all constraints as unevaluated
3218 DoPhase(1); // Just one phase need if no sizers involved
3220 SetConstraintSizes(); // Recursively set the real window sizes
3226 // Do a phase of evaluating constraints:
3227 // the default behaviour. wxSizers may do a similar
3228 // thing, but also impose their own 'constraints'
3229 // and order the evaluation differently.
3230 bool wxWindow::LayoutPhase1(int *noChanges
)
3232 wxLayoutConstraints
*constr
= GetConstraints();
3235 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3241 bool wxWindow::LayoutPhase2(int *noChanges
)
3251 // Do a phase of evaluating child constraints
3252 bool wxWindow::DoPhase(int phase
)
3254 int noIterations
= 0;
3255 int maxIterations
= 500;
3259 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3263 wxNode
*node
= m_children
.First();
3266 wxWindow
*child
= (wxWindow
*)node
->Data();
3267 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3269 wxLayoutConstraints
*constr
= child
->GetConstraints();
3272 if (succeeded
.Member(child
))
3277 int tempNoChanges
= 0;
3278 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3279 noChanges
+= tempNoChanges
;
3282 succeeded
.Append(child
);
3287 node
= node
->Next();
3294 void wxWindow::ResetConstraints()
3296 wxLayoutConstraints
*constr
= GetConstraints();
3299 constr
->left
.SetDone(FALSE
);
3300 constr
->top
.SetDone(FALSE
);
3301 constr
->right
.SetDone(FALSE
);
3302 constr
->bottom
.SetDone(FALSE
);
3303 constr
->width
.SetDone(FALSE
);
3304 constr
->height
.SetDone(FALSE
);
3305 constr
->centreX
.SetDone(FALSE
);
3306 constr
->centreY
.SetDone(FALSE
);
3308 wxNode
*node
= m_children
.First();
3311 wxWindow
*win
= (wxWindow
*)node
->Data();
3312 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3313 win
->ResetConstraints();
3314 node
= node
->Next();
3318 // Need to distinguish between setting the 'fake' size for
3319 // windows and sizers, and setting the real values.
3320 void wxWindow::SetConstraintSizes(bool recurse
)
3322 wxLayoutConstraints
*constr
= GetConstraints();
3323 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3324 constr
->width
.GetDone() && constr
->height
.GetDone())
3326 int x
= constr
->left
.GetValue();
3327 int y
= constr
->top
.GetValue();
3328 int w
= constr
->width
.GetValue();
3329 int h
= constr
->height
.GetValue();
3331 // If we don't want to resize this window, just move it...
3332 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3333 (constr
->height
.GetRelationship() != wxAsIs
))
3335 // Calls Layout() recursively. AAAGH. How can we stop that.
3336 // Simply take Layout() out of non-top level OnSizes.
3337 SizerSetSize(x
, y
, w
, h
);
3346 char *windowClass
= this->GetClassInfo()->GetClassName();
3349 if (GetName() == "")
3350 winName
= "unnamed";
3352 winName
= GetName();
3353 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3354 (const char *)windowClass
,
3355 (const char *)winName
);
3356 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3357 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3358 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3359 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3360 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3365 wxNode
*node
= m_children
.First();
3368 wxWindow
*win
= (wxWindow
*)node
->Data();
3369 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3370 win
->SetConstraintSizes();
3371 node
= node
->Next();
3376 // This assumes that all sizers are 'on' the same
3377 // window, i.e. the parent of this window.
3378 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3380 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3381 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3385 m_sizerParent
->GetPosition(&xp
, &yp
);
3386 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3391 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3395 TransformSizerToActual(&xx
, &yy
);
3396 SetSize(xx
, yy
, w
, h
);
3399 void wxWindow::SizerMove(int x
, int y
)
3403 TransformSizerToActual(&xx
, &yy
);
3407 // Only set the size/position of the constraint (if any)
3408 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3410 wxLayoutConstraints
*constr
= GetConstraints();
3415 constr
->left
.SetValue(x
);
3416 constr
->left
.SetDone(TRUE
);
3420 constr
->top
.SetValue(y
);
3421 constr
->top
.SetDone(TRUE
);
3425 constr
->width
.SetValue(w
);
3426 constr
->width
.SetDone(TRUE
);
3430 constr
->height
.SetValue(h
);
3431 constr
->height
.SetDone(TRUE
);
3436 void wxWindow::MoveConstraint(int x
, int y
)
3438 wxLayoutConstraints
*constr
= GetConstraints();
3443 constr
->left
.SetValue(x
);
3444 constr
->left
.SetDone(TRUE
);
3448 constr
->top
.SetValue(y
);
3449 constr
->top
.SetDone(TRUE
);
3454 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3456 wxLayoutConstraints
*constr
= GetConstraints();
3459 *w
= constr
->width
.GetValue();
3460 *h
= constr
->height
.GetValue();
3466 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3468 wxLayoutConstraints
*constr
= GetConstraints();
3471 *w
= constr
->width
.GetValue();
3472 *h
= constr
->height
.GetValue();
3475 GetClientSize(w
, h
);
3478 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3480 wxLayoutConstraints
*constr
= GetConstraints();
3483 *x
= constr
->left
.GetValue();
3484 *y
= constr
->top
.GetValue();