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/tooltip.h"
31 #include "wx/statusbr.h"
33 #include "wx/settings.h"
40 #include "gdk/gdkprivate.h"
41 #include "gdk/gdkkeysyms.h"
42 #include "wx/gtk/win_gtk.h"
44 //-----------------------------------------------------------------------------
45 // documentation on internals
46 //-----------------------------------------------------------------------------
49 I have been asked several times about writing some documentation about
50 the GTK port of wxWindows, especially its internal structures. Obviously,
51 you cannot understand wxGTK without knowing a little about the GTK, but
52 some more information about what the wxWindow, which is the base class
53 for all other window classes, does seems required as well.
55 What does wxWindow do? It contains the common interface for the following
56 jobs of its descendants:
58 1) Define the rudimentary behaviour common to all window classes, such as
59 resizing, intercepting user input (so as to make it possible to use these
60 events for special purposes in a derived class), window names etc.
62 2) Provide the possibility to contain and manage children, if the derived
63 class is allowed to contain children, which holds true for those window
64 classes which do not display a native GTK widget. To name them, these
65 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
66 work classes are a special case and are handled a bit differently from
67 the rest. The same holds true for the wxNotebook class.
69 3) Provide the possibility to draw into a client area of a window. This,
70 too, only holds true for classes that do not display a native GTK widget
73 4) Provide the entire mechanism for scrolling widgets. This actual inter-
74 face for this is usually in wxScrolledWindow, but the GTK implementation
77 5) A multitude of helper or extra methods for special purposes, such as
78 Drag'n'Drop, managing validators etc.
80 Normally one might expect, that one wxWindows window would always correspond
81 to one GTK widget. Under GTK, there is no such allround widget that has all
82 the functionality. Moreover, the GTK defines a client area as a different
83 widget from the actual widget you are handling. Last but not least some
84 special classes (e.g. wxFrame) handle different categories of widgets and
85 still have the possibility to draw something in the client area.
86 It was therefore required to write a special purpose GTK widget, that would
87 represent a client area in the sense of wxWindows capable to do the jobs
88 2), 3) and 4). I have written this class and it resides in win_gtk.c of
91 All windows must have a widget, with which they interact with other under-
92 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
93 thw wxWindow class has a member variable called m_widget which holds a
94 pointer to this widget. When the window class represents a GTK native widget,
95 this is (in most cases) the only GTK widget the class manages. E.g. the
96 wxStatitText class handles only a GtkLabel widget a pointer to which you
97 can find in m_widget (defined in wxWindow)
99 When the class has a client area for drawing into and for containing children
100 it has to handle the client area widget (of the type GtkMyFixed, defined in
101 win_gtk.c), but there could be any number of widgets, handled by a class
102 The common rule for all windows is only, that the widget that interacts with
103 the rest of GTK must be referenced in m_widget and all other widgets must be
104 children of this widget on the GTK level. The top-most widget, which also
105 represents the client area, must be in the m_wxwindow field and must be of
108 As I said, the window classes that display a GTK native widget only have
109 one widget, so in the case of e.g. the wxButton class m_widget holds a
110 pointer to a GtkButton widget. But windows with client areas (for drawing
111 and children) have a m_widget field that is a pointer to a GtkScrolled-
112 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
113 one is (in the GTK sense) a child of the GtkScrolledWindow.
115 If the m_wxwindow field is set, then all input to this widget is inter-
116 cepted and sent to the wxWindows class. If not, all input to the widget
117 that gets pointed to by m_widget gets intercepted and sent to the class.
121 //-------------------------------------------------------------------------
122 // conditional compilation
123 //-------------------------------------------------------------------------
125 #if (GTK_MINOR_VERSION == 1)
126 #if (GTK_MICRO_VERSION >= 5)
127 #define NEW_GTK_SCROLL_CODE
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
137 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
138 GdkEvent
*WXUNUSED(event
),
141 printf( "FOCUS NOW AT: " );
148 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
156 char *s
= new char[tmp
.Length()+1];
158 strcpy( s
, WXSTRINGCAST tmp
);
160 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
161 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
166 //-----------------------------------------------------------------------------
168 //-----------------------------------------------------------------------------
170 extern wxList wxPendingDelete
;
171 extern wxList wxTopLevelWindows
;
172 extern bool g_blockEventsOnDrag
;
173 extern bool g_blockEventsOnScroll
;
174 static bool g_capturing
= FALSE
;
175 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
177 // hack: we need something to pass to gtk_menu_popup, so we store the time of
178 // the last click here
179 static guint32 gs_timeLastClick
= 0;
181 //-----------------------------------------------------------------------------
182 // "expose_event" (of m_wxwindow, not of m_widget)
183 //-----------------------------------------------------------------------------
185 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
187 if (!win
->HasVMT()) return;
189 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
191 gdk_event
->area
.width
,
192 gdk_event
->area
.height
);
194 if (gdk_event
->count
> 0) return;
197 printf( "OnExpose from " );
198 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
199 printf( win->GetClassInfo()->GetClassName() );
203 wxPaintEvent
event( win
->GetId() );
204 event
.SetEventObject( win
);
205 win
->GetEventHandler()->ProcessEvent( event
);
207 win
->m_updateRegion
.Clear();
210 //-----------------------------------------------------------------------------
211 // "draw" (of m_wxwindow, not of m_widget)
212 //-----------------------------------------------------------------------------
214 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
216 if (!win
->HasVMT()) return;
218 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
220 wxPaintEvent
event( win
->GetId() );
221 event
.SetEventObject( win
);
222 win
->GetEventHandler()->ProcessEvent( event
);
224 win
->m_updateRegion
.Clear();
227 //-----------------------------------------------------------------------------
228 // "key_press_event" from any window
229 //-----------------------------------------------------------------------------
231 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
233 if (!win
->HasVMT()) return FALSE
;
234 if (g_blockEventsOnDrag
) return FALSE
;
237 printf( "OnKeyPress from " );
238 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
239 printf( win->GetClassInfo()->GetClassName() );
244 switch (gdk_event
->keyval
)
246 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
247 case GDK_ISO_Left_Tab
:
249 case GDK_Tab
: key_code
= WXK_TAB
; break;
250 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
251 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
252 case GDK_Return
: key_code
= WXK_RETURN
; break;
253 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
254 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
255 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
256 case GDK_Delete
: key_code
= WXK_DELETE
; break;
257 case GDK_Home
: key_code
= WXK_HOME
; break;
258 case GDK_Left
: key_code
= WXK_LEFT
; break;
259 case GDK_Up
: key_code
= WXK_UP
; break;
260 case GDK_Right
: key_code
= WXK_RIGHT
; break;
261 case GDK_Down
: key_code
= WXK_DOWN
; break;
262 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
263 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
264 case GDK_Next
: key_code
= WXK_NEXT
; break;
265 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
266 case GDK_End
: key_code
= WXK_END
; break;
267 case GDK_Begin
: key_code
= WXK_HOME
; break;
268 case GDK_Select
: key_code
= WXK_SELECT
; break;
269 case GDK_Print
: key_code
= WXK_PRINT
; break;
270 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
271 case GDK_Insert
: key_code
= WXK_INSERT
; break;
272 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
273 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
274 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
275 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
276 case GDK_KP_Up
: key_code
= WXK_UP
; break;
277 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
278 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
279 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
280 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
281 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
282 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
283 case GDK_KP_End
: key_code
= WXK_END
; break;
284 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
285 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
286 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
287 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
288 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
289 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
290 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
291 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
292 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
293 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
294 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
295 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
296 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
297 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
298 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
299 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
300 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
301 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
302 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
303 case GDK_F1
: key_code
= WXK_F1
; break;
304 case GDK_F2
: key_code
= WXK_F2
; break;
305 case GDK_F3
: key_code
= WXK_F3
; break;
306 case GDK_F4
: key_code
= WXK_F4
; break;
307 case GDK_F5
: key_code
= WXK_F5
; break;
308 case GDK_F6
: key_code
= WXK_F6
; break;
309 case GDK_F7
: key_code
= WXK_F7
; break;
310 case GDK_F8
: key_code
= WXK_F8
; break;
311 case GDK_F9
: key_code
= WXK_F9
; break;
312 case GDK_F10
: key_code
= WXK_F10
; break;
313 case GDK_F11
: key_code
= WXK_F11
; break;
314 case GDK_F12
: key_code
= WXK_F12
; break;
317 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
318 key_code
= gdk_event
->keyval
;
322 if (!key_code
) return FALSE
;
324 wxKeyEvent
event( wxEVT_KEY_DOWN
);
325 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
326 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
327 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
328 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
329 event
.m_keyCode
= key_code
;
332 event
.SetEventObject( win
);
334 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
338 wxWindow
*ancestor
= win
;
341 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
344 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
345 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
348 ancestor
= ancestor
->GetParent();
352 // win is a control: tab can be propagated up
354 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
355 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
357 wxNavigationKeyEvent new_event
;
358 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
359 new_event
.SetWindowChange( FALSE
);
360 new_event
.SetCurrentFocus( win
);
361 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
365 // win is a panel: up can be propagated to the panel
366 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
367 (gdk_event->keyval == GDK_Up))
369 win->m_parent->SetFocus();
373 // win is a panel: left/right can be propagated to the panel
374 if ((!ret) && (win->m_wxwindow) &&
375 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
376 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
378 wxNavigationKeyEvent new_event;
379 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
380 new_event.SetCurrentFocus( win );
381 ret = win->GetEventHandler()->ProcessEvent( new_event );
387 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
393 //-----------------------------------------------------------------------------
394 // "key_release_event" from any window
395 //-----------------------------------------------------------------------------
397 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
399 if (!win
->HasVMT()) return FALSE
;
400 if (g_blockEventsOnDrag
) return FALSE
;
403 printf( "OnKeyRelease from " );
404 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
405 printf( win->GetClassInfo()->GetClassName() );
410 switch (gdk_event
->keyval
)
412 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
413 case GDK_ISO_Left_Tab
:
415 case GDK_Tab
: key_code
= WXK_TAB
; break;
416 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
417 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
418 case GDK_Return
: key_code
= WXK_RETURN
; break;
419 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
420 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
421 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
422 case GDK_Delete
: key_code
= WXK_DELETE
; break;
423 case GDK_Home
: key_code
= WXK_HOME
; break;
424 case GDK_Left
: key_code
= WXK_LEFT
; break;
425 case GDK_Up
: key_code
= WXK_UP
; break;
426 case GDK_Right
: key_code
= WXK_RIGHT
; break;
427 case GDK_Down
: key_code
= WXK_DOWN
; break;
428 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
429 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
430 case GDK_Next
: key_code
= WXK_NEXT
; break;
431 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
432 case GDK_End
: key_code
= WXK_END
; break;
433 case GDK_Begin
: key_code
= WXK_HOME
; break;
434 case GDK_Select
: key_code
= WXK_SELECT
; break;
435 case GDK_Print
: key_code
= WXK_PRINT
; break;
436 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
437 case GDK_Insert
: key_code
= WXK_INSERT
; break;
438 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
439 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
440 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
441 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
442 case GDK_KP_Up
: key_code
= WXK_UP
; break;
443 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
444 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
445 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
446 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
447 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
448 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
449 case GDK_KP_End
: key_code
= WXK_END
; break;
450 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
451 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
452 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
453 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
454 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
455 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
456 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
457 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
458 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
459 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
460 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
461 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
462 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
463 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
464 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
465 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
466 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
467 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
468 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
469 case GDK_F1
: key_code
= WXK_F1
; break;
470 case GDK_F2
: key_code
= WXK_F2
; break;
471 case GDK_F3
: key_code
= WXK_F3
; break;
472 case GDK_F4
: key_code
= WXK_F4
; break;
473 case GDK_F5
: key_code
= WXK_F5
; break;
474 case GDK_F6
: key_code
= WXK_F6
; break;
475 case GDK_F7
: key_code
= WXK_F7
; break;
476 case GDK_F8
: key_code
= WXK_F8
; break;
477 case GDK_F9
: key_code
= WXK_F9
; break;
478 case GDK_F10
: key_code
= WXK_F10
; break;
479 case GDK_F11
: key_code
= WXK_F11
; break;
480 case GDK_F12
: key_code
= WXK_F12
; break;
483 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
484 key_code
= gdk_event
->keyval
;
488 if (!key_code
) return FALSE
;
490 wxKeyEvent
event( wxEVT_KEY_UP
);
491 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
492 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
493 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
494 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
495 event
.m_keyCode
= key_code
;
498 event
.SetEventObject( win
);
500 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
504 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
510 //-----------------------------------------------------------------------------
511 // "button_press_event"
512 //-----------------------------------------------------------------------------
514 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
516 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
518 if (g_blockEventsOnDrag
) return TRUE
;
519 if (g_blockEventsOnScroll
) return TRUE
;
523 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
525 gtk_widget_grab_focus (win
->m_wxwindow
);
528 printf( "GrabFocus from " );
529 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
530 printf( win->GetClassInfo()->GetClassName() );
537 if (!win
->HasVMT()) return TRUE
;
540 printf( "OnButtonPress from " );
541 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
542 printf( win->GetClassInfo()->GetClassName() );
546 wxEventType event_type
= wxEVT_LEFT_DOWN
;
548 if (gdk_event
->button
== 1)
550 switch (gdk_event
->type
)
552 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
553 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
557 else if (gdk_event
->button
== 2)
559 switch (gdk_event
->type
)
561 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
562 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
566 else if (gdk_event
->button
== 3)
568 switch (gdk_event
->type
)
570 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
571 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
576 wxMouseEvent
event( event_type
);
577 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
578 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
579 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
580 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
581 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
582 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
583 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
585 event
.m_x
= (long)gdk_event
->x
;
586 event
.m_y
= (long)gdk_event
->y
;
588 // Some control don't have their own X window and thus cannot get
593 wxNode
*node
= win
->GetChildren().First();
596 wxWindow
*child
= (wxWindow
*)node
->Data();
598 if (child
->m_isStaticBox
)
600 // wxStaticBox is transparent in the box itself
603 int xx1
= child
->m_x
;
604 int yy1
= child
->m_y
;
605 int xx2
= child
->m_x
+ child
->m_width
;
606 int yy2
= child
->m_x
+ child
->m_height
;
609 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
611 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
613 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
615 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
618 event
.m_x
-= child
->m_x
;
619 event
.m_y
-= child
->m_y
;
626 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
627 (child
->m_x
<= event
.m_x
) &&
628 (child
->m_y
<= event
.m_y
) &&
629 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
630 (child
->m_y
+child
->m_height
>= event
.m_y
))
633 event
.m_x
-= child
->m_x
;
634 event
.m_y
-= child
->m_y
;
642 wxPoint
pt(win
->GetClientAreaOrigin());
646 event
.SetEventObject( win
);
648 gs_timeLastClick
= gdk_event
->time
;
650 if (win
->GetEventHandler()->ProcessEvent( event
))
651 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
656 //-----------------------------------------------------------------------------
657 // "button_release_event"
658 //-----------------------------------------------------------------------------
660 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
662 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
664 if (g_blockEventsOnDrag
) return TRUE
;
665 if (g_blockEventsOnScroll
) return TRUE
;
667 if (!win
->HasVMT()) return TRUE
;
670 printf( "OnButtonRelease from " );
671 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
672 printf( win->GetClassInfo()->GetClassName() );
676 wxEventType event_type
= wxEVT_NULL
;
678 switch (gdk_event
->button
)
680 case 1: event_type
= wxEVT_LEFT_UP
; break;
681 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
682 case 3: event_type
= wxEVT_RIGHT_UP
; break;
685 wxMouseEvent
event( event_type
);
686 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
687 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
688 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
689 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
690 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
691 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
692 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
693 event
.m_x
= (long)gdk_event
->x
;
694 event
.m_y
= (long)gdk_event
->y
;
696 // Some control don't have their own X window and thus cannot get
701 wxNode
*node
= win
->GetChildren().First();
704 wxWindow
*child
= (wxWindow
*)node
->Data();
706 if (child
->m_isStaticBox
)
708 // wxStaticBox is transparent in the box itself
711 int xx1
= child
->m_x
;
712 int yy1
= child
->m_y
;
713 int xx2
= child
->m_x
+ child
->m_width
;
714 int yy2
= child
->m_x
+ child
->m_height
;
717 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
719 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
721 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
723 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
726 event
.m_x
-= child
->m_x
;
727 event
.m_y
-= child
->m_y
;
734 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
735 (child
->m_x
<= event
.m_x
) &&
736 (child
->m_y
<= event
.m_y
) &&
737 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
738 (child
->m_y
+child
->m_height
>= event
.m_y
))
741 event
.m_x
-= child
->m_x
;
742 event
.m_y
-= child
->m_y
;
750 wxPoint
pt(win
->GetClientAreaOrigin());
754 event
.SetEventObject( win
);
756 if (win
->GetEventHandler()->ProcessEvent( event
))
757 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
762 //-----------------------------------------------------------------------------
763 // "motion_notify_event"
764 //-----------------------------------------------------------------------------
766 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
768 if (gdk_event
->is_hint
)
772 GdkModifierType state
;
773 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
776 gdk_event
->state
= state
;
779 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
781 if (g_blockEventsOnDrag
) return TRUE
;
782 if (g_blockEventsOnScroll
) return TRUE
;
784 if (!win
->HasVMT()) return TRUE
;
787 printf( "OnMotion from " );
788 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
789 printf( win->GetClassInfo()->GetClassName() );
793 wxMouseEvent
event( wxEVT_MOTION
);
794 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
795 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
796 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
797 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
798 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
799 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
800 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
802 event
.m_x
= (long)gdk_event
->x
;
803 event
.m_y
= (long)gdk_event
->y
;
805 // Some control don't have their own X window and thus cannot get
810 wxNode
*node
= win
->GetChildren().First();
813 wxWindow
*child
= (wxWindow
*)node
->Data();
815 if (child
->m_isStaticBox
)
817 // wxStaticBox is transparent in the box itself
820 int xx1
= child
->m_x
;
821 int yy1
= child
->m_y
;
822 int xx2
= child
->m_x
+ child
->m_width
;
823 int yy2
= child
->m_x
+ child
->m_height
;
826 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
828 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
830 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
832 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
835 event
.m_x
-= child
->m_x
;
836 event
.m_y
-= child
->m_y
;
843 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
844 (child
->m_x
<= event
.m_x
) &&
845 (child
->m_y
<= event
.m_y
) &&
846 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
847 (child
->m_y
+child
->m_height
>= event
.m_y
))
850 event
.m_x
-= child
->m_x
;
851 event
.m_y
-= child
->m_y
;
859 wxPoint
pt(win
->GetClientAreaOrigin());
863 event
.SetEventObject( win
);
865 if (win
->GetEventHandler()->ProcessEvent( event
))
866 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
871 //-----------------------------------------------------------------------------
873 //-----------------------------------------------------------------------------
875 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
877 if (g_blockEventsOnDrag
) return TRUE
;
883 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
885 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
887 printf( "SetFocus flag from " );
888 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
889 printf( win->GetClassInfo()->GetClassName() );
895 if (!win
->HasVMT()) return TRUE
;
898 printf( "OnSetFocus from " );
899 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
900 printf( win->GetClassInfo()->GetClassName() );
902 printf( WXSTRINGCAST win->GetLabel() );
906 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
907 event
.SetEventObject( win
);
909 if (win
->GetEventHandler()->ProcessEvent( event
))
910 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
915 //-----------------------------------------------------------------------------
917 //-----------------------------------------------------------------------------
919 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
921 if (g_blockEventsOnDrag
) return TRUE
;
924 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
925 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
928 if (!win
->HasVMT()) return TRUE
;
931 printf( "OnKillFocus from " );
932 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
933 printf( win->GetClassInfo()->GetClassName() );
937 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
938 event
.SetEventObject( win
);
940 if (win
->GetEventHandler()->ProcessEvent( event
))
941 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
946 //-----------------------------------------------------------------------------
947 // "enter_notify_event"
948 //-----------------------------------------------------------------------------
950 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
952 if (g_blockEventsOnDrag
) return TRUE
;
954 if ((widget
->window
) && (win
->m_cursor
))
955 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
957 if (widget
->window
!= gdk_event
->window
) return TRUE
;
959 if (!win
->HasVMT()) return TRUE
;
962 printf( "OnEnter from " );
963 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
964 printf( win->GetClassInfo()->GetClassName() );
968 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
969 event
.SetEventObject( win
);
973 GdkModifierType state
= (GdkModifierType
)0;
975 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
977 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
978 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
979 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
980 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
981 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
982 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
983 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
988 wxPoint
pt(win
->GetClientAreaOrigin());
992 if (win
->GetEventHandler()->ProcessEvent( event
))
993 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
998 //-----------------------------------------------------------------------------
999 // "leave_notify_event"
1000 //-----------------------------------------------------------------------------
1002 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1004 if (g_blockEventsOnDrag
) return TRUE
;
1006 if ((widget
->window
) && (win
->m_cursor
))
1007 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1009 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1011 if (!win
->HasVMT()) return TRUE
;
1014 printf( "OnLeave from " );
1015 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1016 printf( win->GetClassInfo()->GetClassName() );
1020 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1021 event
.SetEventObject( win
);
1025 GdkModifierType state
= (GdkModifierType
)0;
1027 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1029 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1030 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1031 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1032 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1033 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1034 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1035 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1037 event
.m_x
= (long)x
;
1038 event
.m_y
= (long)y
;
1040 wxPoint
pt(win
->GetClientAreaOrigin());
1044 if (win
->GetEventHandler()->ProcessEvent( event
))
1045 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1050 //-----------------------------------------------------------------------------
1051 // "value_changed" from m_vAdjust
1052 //-----------------------------------------------------------------------------
1054 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1056 if (g_blockEventsOnDrag
) return;
1059 printf( "OnVScroll from " );
1060 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1061 printf( win->GetClassInfo()->GetClassName() );
1065 if (!win
->HasVMT()) return;
1067 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1068 if (fabs(diff
) < 0.2) return;
1070 wxEventType command
= wxEVT_NULL
;
1072 float line_step
= win
->m_vAdjust
->step_increment
;
1073 float page_step
= win
->m_vAdjust
->page_increment
;
1075 if (win
->m_isScrolling
)
1077 command
= wxEVT_SCROLL_THUMBTRACK
;
1081 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1082 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1083 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1084 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1085 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1086 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1087 else command
= wxEVT_SCROLL_THUMBTRACK
;
1090 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1092 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1093 event
.SetEventObject( win
);
1094 win
->GetEventHandler()->ProcessEvent( event
);
1097 //-----------------------------------------------------------------------------
1098 // "value_changed" from m_hAdjust
1099 //-----------------------------------------------------------------------------
1101 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1103 if (g_blockEventsOnDrag
) return;
1106 printf( "OnHScroll from " );
1107 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1108 printf( win->GetClassInfo()->GetClassName() );
1112 if (!win
->HasVMT()) return;
1114 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1115 if (fabs(diff
) < 0.2) return;
1117 wxEventType command
= wxEVT_NULL
;
1119 float line_step
= win
->m_hAdjust
->step_increment
;
1120 float page_step
= win
->m_hAdjust
->page_increment
;
1122 if (win
->m_isScrolling
)
1124 command
= wxEVT_SCROLL_THUMBTRACK
;
1128 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1129 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1130 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1131 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1132 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1133 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1134 else command
= wxEVT_SCROLL_THUMBTRACK
;
1137 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1139 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1140 event
.SetEventObject( win
);
1141 win
->GetEventHandler()->ProcessEvent( event
);
1144 //-----------------------------------------------------------------------------
1145 // "changed" from m_vAdjust
1146 //-----------------------------------------------------------------------------
1148 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1150 if (g_blockEventsOnDrag
) return;
1153 printf( "OnVScroll change from " );
1154 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1155 printf( win->GetClassInfo()->GetClassName() );
1159 if (!win
->HasVMT()) return;
1161 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1162 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1164 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1165 event
.SetEventObject( win
);
1166 win
->GetEventHandler()->ProcessEvent( event
);
1169 //-----------------------------------------------------------------------------
1170 // "changed" from m_hAdjust
1171 //-----------------------------------------------------------------------------
1173 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1175 if (g_blockEventsOnDrag
) return;
1178 printf( "OnHScroll change from " );
1179 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1180 printf( win->GetClassInfo()->GetClassName() );
1184 if (!win
->HasVMT()) return;
1186 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1187 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1189 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1190 event
.SetEventObject( win
);
1191 win
->GetEventHandler()->ProcessEvent( event
);
1194 //-----------------------------------------------------------------------------
1195 // "button_press_event" from scrollbar
1196 //-----------------------------------------------------------------------------
1198 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1199 GdkEventButton
*WXUNUSED(gdk_event
),
1202 // don't test here as we can release the mouse while being over
1203 // a different window then the slider
1205 // if (gdk_event->window != widget->slider) return FALSE;
1207 win
->m_isScrolling
= TRUE
;
1208 g_blockEventsOnScroll
= TRUE
;
1213 //-----------------------------------------------------------------------------
1214 // "button_release_event" from scrollbar
1215 //-----------------------------------------------------------------------------
1217 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1218 GdkEventButton
*WXUNUSED(gdk_event
),
1222 // don't test here as we can release the mouse while being over
1223 // a different window then the slider
1225 // if (gdk_event->window != widget->slider) return FALSE;
1227 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1229 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1230 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1232 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1234 win
->m_isScrolling
= FALSE
;
1235 g_blockEventsOnScroll
= FALSE
;
1240 //-----------------------------------------------------------------------------
1241 // InsertChild for wxWindow.
1242 //-----------------------------------------------------------------------------
1244 /* Callback for wxWindow. This very strange beast has to be used because
1245 * C++ has no virtual methods in a constructor. We have to emulate a
1246 * virtual function here as wxNotebook requires a different way to insert
1247 * a child in it. I had opted for creating a wxNotebookPage window class
1248 * which would have made this superfluous (such in the MDI window system),
1249 * but no-one was listening to me... */
1251 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1253 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1254 GTK_WIDGET(child
->m_widget
),
1258 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1262 if (wxIS_KIND_OF(parent
,wxFrame
))
1264 parent
->m_sizeSet
= FALSE
;
1267 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1269 /* we now allow a window to get the focus as long as it
1270 doesn't have any children. */
1271 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1275 //-----------------------------------------------------------------------------
1277 //-----------------------------------------------------------------------------
1279 wxWindow
* wxGetActiveWindow()
1281 return g_focusWindow
;
1284 //-----------------------------------------------------------------------------
1286 //-----------------------------------------------------------------------------
1288 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1290 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1291 EVT_SIZE(wxWindow::OnSize
)
1292 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1293 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1294 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1297 wxWindow::wxWindow()
1299 m_widget
= (GtkWidget
*) NULL
;
1300 m_wxwindow
= (GtkWidget
*) NULL
;
1301 m_parent
= (wxWindow
*) NULL
;
1302 m_children
.DeleteContents( FALSE
);
1315 m_eventHandler
= this;
1316 m_windowValidator
= (wxValidator
*) NULL
;
1320 m_cursor
= (wxCursor
*) NULL
;
1321 m_font
= *wxSWISS_FONT
;
1323 m_windowName
= "noname";
1325 m_constraints
= (wxLayoutConstraints
*) NULL
;
1326 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1327 m_windowSizer
= (wxSizer
*) NULL
;
1328 m_sizerParent
= (wxWindow
*) NULL
;
1329 m_autoLayout
= FALSE
;
1333 m_needParent
= TRUE
;
1335 m_hasScrolling
= FALSE
;
1336 m_isScrolling
= FALSE
;
1337 m_hAdjust
= (GtkAdjustment
*) NULL
;
1338 m_vAdjust
= (GtkAdjustment
*) NULL
;
1339 m_oldHorizontalPos
= 0.0;
1340 m_oldVerticalPos
= 0.0;
1345 #if wxUSE_DRAG_AND_DROP
1346 m_dropTarget
= (wxDropTarget
*) NULL
;
1349 m_scrollGC
= (GdkGC
*) NULL
;
1350 m_widgetStyle
= (GtkStyle
*) NULL
;
1352 m_insertCallback
= wxInsertChildInWindow
;
1354 m_clientObject
= (wxClientData
*) NULL
;
1355 m_clientData
= NULL
;
1357 m_isStaticBox
= FALSE
;
1358 m_acceptsFocus
= FALSE
;
1361 m_toolTip
= (wxToolTip
*) NULL
;
1362 #endif // wxUSE_TOOLTIPS
1365 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1366 const wxPoint
&pos
, const wxSize
&size
,
1367 long style
, const wxString
&name
)
1369 m_insertCallback
= wxInsertChildInWindow
;
1370 Create( parent
, id
, pos
, size
, style
, name
);
1373 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1374 const wxPoint
&pos
, const wxSize
&size
,
1375 long style
, const wxString
&name
)
1379 m_needParent
= TRUE
;
1381 PreCreation( parent
, id
, pos
, size
, style
, name
);
1383 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1384 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1387 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1390 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1393 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1394 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1397 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1398 scroll_class
->scrollbar_spacing
= 0;
1400 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1402 m_oldHorizontalPos
= 0.0;
1403 m_oldVerticalPos
= 0.0;
1405 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1406 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1408 m_wxwindow
= gtk_myfixed_new();
1411 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1414 #ifdef NEW_GTK_SCROLL_CODE
1415 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1416 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1418 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1419 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1423 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1426 if (m_windowStyle
& wxRAISED_BORDER
)
1428 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1430 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1432 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1436 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1439 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1441 /* we now allow a window to get the focus as long as it
1442 doesn't have any children. */
1443 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1444 m_acceptsFocus
= FALSE
;
1448 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1449 m_acceptsFocus
= TRUE
;
1452 // shut the viewport up
1453 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1454 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1456 // I _really_ don't want scrollbars in the beginning
1457 m_vAdjust
->lower
= 0.0;
1458 m_vAdjust
->upper
= 1.0;
1459 m_vAdjust
->value
= 0.0;
1460 m_vAdjust
->step_increment
= 1.0;
1461 m_vAdjust
->page_increment
= 1.0;
1462 m_vAdjust
->page_size
= 5.0;
1463 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1464 m_hAdjust
->lower
= 0.0;
1465 m_hAdjust
->upper
= 1.0;
1466 m_hAdjust
->value
= 0.0;
1467 m_hAdjust
->step_increment
= 1.0;
1468 m_hAdjust
->page_increment
= 1.0;
1469 m_hAdjust
->page_size
= 5.0;
1470 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1472 // these handlers block mouse events to any window during scrolling
1473 // such as motion events and prevent GTK and wxWindows from fighting
1474 // over where the slider should be
1476 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1477 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1479 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1480 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1482 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1483 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1485 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1486 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1488 // these handers het notified when screen updates are required either when
1489 // scrolling or when the window size (and therefore scrollbar configuration)
1492 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1493 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1494 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1495 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1497 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1498 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1499 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1500 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1502 gtk_widget_show( m_wxwindow
);
1504 if (m_parent
) m_parent
->AddChild( this );
1506 (m_parent
->m_insertCallback
)( m_parent
, this );
1515 wxWindow::~wxWindow()
1517 // Remove potential dangling pointer
1518 if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel
)))
1520 wxPanel
* panel
= (wxPanel
*) GetParent();
1521 if (panel
->GetLastFocus() == this)
1522 panel
->SetLastFocus((wxWindow
*) NULL
);
1527 #if wxUSE_DRAG_AND_DROP
1528 wxDELETE(m_dropTarget
);
1532 wxDELETE(m_toolTip
);
1533 #endif // wxUSE_TOOLTIPS
1535 if (m_parent
) m_parent
->RemoveChild( this );
1536 if (m_widget
) Show( FALSE
);
1540 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1542 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1544 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1546 if (m_widget
) gtk_widget_destroy( m_widget
);
1548 if (m_cursor
) delete m_cursor
;
1550 DeleteRelatedConstraints();
1553 // This removes any dangling pointers to this window
1554 // in other windows' constraintsInvolvedIn lists.
1555 UnsetConstraints(m_constraints
);
1556 delete m_constraints
;
1557 m_constraints
= (wxLayoutConstraints
*) NULL
;
1561 delete m_windowSizer
;
1562 m_windowSizer
= (wxSizer
*) NULL
;
1564 // If this is a child of a sizer, remove self from parent
1565 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1567 // Just in case the window has been Closed, but
1568 // we're then deleting immediately: don't leave
1569 // dangling pointers.
1570 wxPendingDelete
.DeleteObject(this);
1572 // Just in case we've loaded a top-level window via
1573 // wxWindow::LoadNativeDialog but we weren't a dialog
1575 wxTopLevelWindows
.DeleteObject(this);
1577 if (m_windowValidator
) delete m_windowValidator
;
1579 if (m_clientObject
) delete m_clientObject
;
1582 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1583 const wxPoint
&pos
, const wxSize
&size
,
1584 long style
, const wxString
&name
)
1586 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1588 m_widget
= (GtkWidget
*) NULL
;
1589 m_wxwindow
= (GtkWidget
*) NULL
;
1592 m_children
.DeleteContents( FALSE
);
1595 if (m_width
== -1) m_width
= 20;
1597 if (m_height
== -1) m_height
= 20;
1602 if (!m_needParent
) // some reasonable defaults
1606 m_x
= (gdk_screen_width () - m_width
) / 2;
1607 if (m_x
< 10) m_x
= 10;
1611 m_y
= (gdk_screen_height () - m_height
) / 2;
1612 if (m_y
< 10) m_y
= 10;
1623 m_eventHandler
= this;
1625 m_windowId
= id
== -1 ? wxNewId() : id
;
1629 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1630 m_font
= *wxSWISS_FONT
;
1631 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1632 m_foregroundColour
= *wxBLACK
;
1633 m_windowStyle
= style
;
1634 m_windowName
= name
;
1636 m_constraints
= (wxLayoutConstraints
*) NULL
;
1637 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1638 m_windowSizer
= (wxSizer
*) NULL
;
1639 m_sizerParent
= (wxWindow
*) NULL
;
1640 m_autoLayout
= FALSE
;
1642 m_hasScrolling
= FALSE
;
1643 m_isScrolling
= FALSE
;
1644 m_hAdjust
= (GtkAdjustment
*) NULL
;
1645 m_vAdjust
= (GtkAdjustment
*) NULL
;
1646 m_oldHorizontalPos
= 0.0;
1647 m_oldVerticalPos
= 0.0;
1652 #if wxUSE_DRAG_AND_DROP
1653 m_dropTarget
= (wxDropTarget
*) NULL
;
1656 m_windowValidator
= (wxValidator
*) NULL
;
1657 m_scrollGC
= (GdkGC
*) NULL
;
1658 m_widgetStyle
= (GtkStyle
*) NULL
;
1660 m_clientObject
= (wxClientData
*)NULL
;
1661 m_clientData
= NULL
;
1663 m_isStaticBox
= FALSE
;
1666 m_toolTip
= (wxToolTip
*) NULL
;
1667 #endif // wxUSE_TOOLTIPS
1670 void wxWindow::PostCreation()
1674 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1675 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1677 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1678 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1681 ConnectWidget( GetConnectWidget() );
1683 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1685 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1687 SetCursor( *wxSTANDARD_CURSOR
);
1692 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1694 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1695 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1697 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1698 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1700 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1701 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1703 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1704 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1706 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1707 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1709 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1710 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1712 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1713 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1715 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1716 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1718 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1719 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1722 bool wxWindow::HasVMT()
1727 bool wxWindow::Close( bool force
)
1729 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1731 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1732 event
.SetEventObject(this);
1733 event
.SetCanVeto(!force
);
1735 // return FALSE if window wasn't closed because the application vetoed the
1737 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1740 bool wxWindow::Destroy()
1742 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1749 bool wxWindow::DestroyChildren()
1752 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1755 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1758 if (m_children
.Member(child
)) delete node
;
1764 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1766 // are we to set fonts here ?
1769 wxPoint
wxWindow::GetClientAreaOrigin() const
1771 return wxPoint(0,0);
1774 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1776 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1778 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1784 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1786 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1787 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1789 if (m_resizing
) return; // I don't like recursions
1792 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1794 // don't set the size for children of wxNotebook, just take the values.
1802 int old_width
= m_width
;
1803 int old_height
= m_height
;
1805 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1807 if (x
!= -1) m_x
= x
;
1808 if (y
!= -1) m_y
= y
;
1809 if (width
!= -1) m_width
= width
;
1810 if (height
!= -1) m_height
= height
;
1820 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1822 if (width
== -1) m_width
= 80;
1825 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1827 if (height
== -1) m_height
= 26;
1830 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1831 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1832 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1833 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1835 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1837 /* the default button has a border around it */
1840 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1841 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1843 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1847 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1848 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1850 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1851 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1857 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1858 event
.SetEventObject( this );
1859 GetEventHandler()->ProcessEvent( event
);
1864 void wxWindow::OnInternalIdle()
1869 void wxWindow::SetSize( int width
, int height
)
1871 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1874 void wxWindow::Move( int x
, int y
)
1876 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1879 void wxWindow::GetSize( int *width
, int *height
) const
1881 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1883 if (width
) (*width
) = m_width
;
1884 if (height
) (*height
) = m_height
;
1887 void wxWindow::SetClientSize( int width
, int height
)
1889 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1893 SetSize( width
, height
);
1900 if (!m_hasScrolling
)
1902 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1904 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1905 (m_windowStyle
& wxSUNKEN_BORDER
))
1907 dw
+= 2 * window_class
->xthickness
;
1908 dh
+= 2 * window_class
->ythickness
;
1913 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1914 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1916 #ifdef NEW_GTK_SCROLL_CODE
1917 GtkWidget
*viewport
= scroll_window
->child
;
1919 GtkWidget
*viewport
= scroll_window
->viewport
;
1922 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1924 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1925 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1927 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1928 (m_windowStyle
& wxSUNKEN_BORDER
))
1930 dw
+= 2 * viewport_class
->xthickness
;
1931 dh
+= 2 * viewport_class
->ythickness
;
1934 if (scroll_window
->vscrollbar_visible
)
1936 dw
+= vscrollbar
->allocation
.width
;
1937 dw
+= scroll_class
->scrollbar_spacing
;
1940 if (scroll_window
->hscrollbar_visible
)
1942 dh
+= hscrollbar
->allocation
.height
;
1943 dw
+= scroll_class
->scrollbar_spacing
;
1947 SetSize( width
+dw
, height
+dh
);
1951 void wxWindow::GetClientSize( int *width
, int *height
) const
1953 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1957 if (width
) (*width
) = m_width
;
1958 if (height
) (*height
) = m_height
;
1965 if (!m_hasScrolling
)
1967 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1969 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1970 (m_windowStyle
& wxSUNKEN_BORDER
))
1972 dw
+= 2 * window_class
->xthickness
;
1973 dh
+= 2 * window_class
->ythickness
;
1978 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1979 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1981 #ifdef NEW_GTK_SCROLL_CODE
1982 GtkWidget
*viewport
= scroll_window
->child
;
1984 GtkWidget
*viewport
= scroll_window
->viewport
;
1987 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1989 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1990 (m_windowStyle
& wxSUNKEN_BORDER
))
1992 dw
+= 2 * viewport_class
->xthickness
;
1993 dh
+= 2 * viewport_class
->ythickness
;
1996 if (scroll_window
->vscrollbar_visible
)
1998 // dw += vscrollbar->allocation.width;
1999 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2000 dw
+= scroll_class
->scrollbar_spacing
;
2003 if (scroll_window
->hscrollbar_visible
)
2005 // dh += hscrollbar->allocation.height;
2007 dh
+= scroll_class
->scrollbar_spacing
;
2011 if (width
) (*width
) = m_width
- dw
;
2012 if (height
) (*height
) = m_height
- dh
;
2016 void wxWindow::GetPosition( int *x
, int *y
) const
2018 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2024 void wxWindow::ClientToScreen( int *x
, int *y
)
2026 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2028 GdkWindow
*source
= (GdkWindow
*) NULL
;
2030 source
= m_wxwindow
->window
;
2032 source
= m_widget
->window
;
2036 gdk_window_get_origin( source
, &org_x
, &org_y
);
2040 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2042 org_x
+= m_widget
->allocation
.x
;
2043 org_y
+= m_widget
->allocation
.y
;
2047 wxPoint
pt(GetClientAreaOrigin());
2055 void wxWindow::ScreenToClient( int *x
, int *y
)
2057 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2059 GdkWindow
*source
= (GdkWindow
*) NULL
;
2061 source
= m_wxwindow
->window
;
2063 source
= m_widget
->window
;
2067 gdk_window_get_origin( source
, &org_x
, &org_y
);
2071 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2073 org_x
+= m_widget
->allocation
.x
;
2074 org_y
+= m_widget
->allocation
.y
;
2078 wxPoint
pt(GetClientAreaOrigin());
2086 void wxWindow::Centre( int direction
)
2088 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2097 m_parent
->GetSize( &p_w
, &p_h
);
2098 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2099 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2103 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2104 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2110 void wxWindow::Fit()
2112 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2116 wxNode
*node
= m_children
.First();
2119 wxWindow
*win
= (wxWindow
*)node
->Data();
2121 win
->GetPosition(&wx
, &wy
);
2122 win
->GetSize(&ww
, &wh
);
2123 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2124 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2126 node
= node
->Next();
2129 SetClientSize(maxX
+ 7, maxY
+ 14);
2132 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2134 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2142 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2144 // if (GetAutoLayout()) Layout();
2147 bool wxWindow::Show( bool show
)
2149 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2152 gtk_widget_show( m_widget
);
2154 gtk_widget_hide( m_widget
);
2161 void wxWindow::Enable( bool enable
)
2163 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2165 m_isEnabled
= enable
;
2167 gtk_widget_set_sensitive( m_widget
, enable
);
2168 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2171 int wxWindow::GetCharHeight() const
2173 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2175 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2177 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2179 return font
->ascent
+ font
->descent
;
2182 int wxWindow::GetCharWidth() const
2184 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2186 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2188 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2190 return gdk_string_width( font
, "H" );
2193 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2194 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2196 wxFont fontToUse
= m_font
;
2197 if (theFont
) fontToUse
= *theFont
;
2199 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2201 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2202 if (x
) (*x
) = gdk_string_width( font
, string
);
2203 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2204 if (descent
) (*descent
) = font
->descent
;
2205 if (externalLeading
) (*externalLeading
) = 0; // ??
2208 void wxWindow::MakeModal( bool modal
)
2212 // Disable all other windows
2213 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2215 wxNode
*node
= wxTopLevelWindows
.First();
2218 wxWindow
*win
= (wxWindow
*)node
->Data();
2219 if (win
!= this) win
->Enable(!modal
);
2221 node
= node
->Next();
2226 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2228 event
.SetEventType( wxEVT_CHAR
);
2230 if (!GetEventHandler()->ProcessEvent( event
))
2236 void wxWindow::SetFocus()
2238 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2240 GtkWidget
*connect_widget
= GetConnectWidget();
2243 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2245 gtk_widget_grab_focus (connect_widget
);
2247 else if (GTK_IS_CONTAINER(connect_widget
))
2249 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2257 wxWindow
*wxWindow::FindFocus()
2259 return g_focusWindow
;
2262 bool wxWindow::AcceptsFocus() const
2264 return IsEnabled() && IsShown() && m_acceptsFocus
;
2267 void wxWindow::AddChild( wxWindow
*child
)
2269 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2270 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2272 m_children
.Append( child
);
2275 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2277 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2279 wxWindow
*oldParent
= GetParent();
2281 if (oldParent
) oldParent
->RemoveChild( this );
2283 gtk_widget_unparent( m_widget
);
2287 newParent
->AddChild( this );
2288 (newParent
->m_insertCallback
)( newParent
, this );
2294 void wxWindow::RemoveChild( wxWindow
*child
)
2296 m_children
.DeleteObject( child
);
2297 child
->m_parent
= (wxWindow
*) NULL
;
2300 void wxWindow::SetReturnCode( int retCode
)
2302 m_retCode
= retCode
;
2305 int wxWindow::GetReturnCode()
2310 void wxWindow::Raise()
2312 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2314 if (m_widget
) gdk_window_raise( m_widget
->window
);
2317 void wxWindow::Lower()
2319 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2321 if (m_widget
) gdk_window_lower( m_widget
->window
);
2324 wxEvtHandler
*wxWindow::GetEventHandler() const
2326 return m_eventHandler
;
2329 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2331 m_eventHandler
= handler
;
2334 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2336 handler
->SetNextHandler(GetEventHandler());
2337 SetEventHandler(handler
);
2340 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2342 if (GetEventHandler())
2344 wxEvtHandler
*handlerA
= GetEventHandler();
2345 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2346 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2347 SetEventHandler(handlerB
);
2351 return (wxEvtHandler
*) NULL
;
2357 return (wxEvtHandler
*) NULL
;
2360 wxValidator
*wxWindow::GetValidator()
2362 return m_windowValidator
;
2365 void wxWindow::SetValidator( const wxValidator
& validator
)
2367 if (m_windowValidator
) delete m_windowValidator
;
2368 m_windowValidator
= validator
.Clone();
2369 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2372 void wxWindow::SetClientObject( wxClientData
*data
)
2374 if (m_clientObject
) delete m_clientObject
;
2375 m_clientObject
= data
;
2378 wxClientData
*wxWindow::GetClientObject()
2380 return m_clientObject
;
2383 void wxWindow::SetClientData( void *data
)
2385 m_clientData
= data
;
2388 void *wxWindow::GetClientData()
2390 return m_clientData
;
2393 bool wxWindow::IsBeingDeleted()
2398 void wxWindow::SetId( wxWindowID id
)
2403 wxWindowID
wxWindow::GetId() const
2408 void wxWindow::SetCursor( const wxCursor
&cursor
)
2410 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2414 if (cursor
== *m_cursor
) return;
2419 *m_cursor
= *wxSTANDARD_CURSOR
;
2422 if ((m_widget
) && (m_widget
->window
))
2423 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2425 if ((m_wxwindow
) && (m_wxwindow
->window
))
2426 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2429 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2434 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2436 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2438 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2442 gdk_window_clear_area( m_wxwindow
->window
,
2444 rect
->width
, rect
->height
);
2448 gdk_window_clear( m_wxwindow
->window
);
2455 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2457 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2461 GdkRectangle gdk_rect
;
2462 gdk_rect
.x
= rect
->x
;
2463 gdk_rect
.y
= rect
->y
;
2464 gdk_rect
.width
= rect
->width
;
2465 gdk_rect
.height
= rect
->height
;
2468 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2470 gtk_widget_draw( m_widget
, &gdk_rect
);
2474 wxRegion
wxWindow::GetUpdateRegion() const
2476 return m_updateRegion
;
2479 bool wxWindow::IsExposed( int x
, int y
) const
2481 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2484 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2486 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2489 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2491 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2494 bool wxWindow::IsExposed( const wxRect
& rect
) const
2496 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2499 void wxWindow::Clear()
2501 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2503 if (m_wxwindow
&& m_wxwindow
->window
)
2505 gdk_window_clear( m_wxwindow
->window
);
2510 void wxWindow::SetToolTip( const wxString
&tip
)
2514 m_toolTip
->SetTip( tip
);
2518 SetToolTip( new wxToolTip( tip
) );
2521 // setting empty tooltip text does not remove the tooltip any more for
2522 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2525 void wxWindow::SetToolTip( wxToolTip
*tip
)
2529 m_toolTip
->SetTip( (char*) NULL
);
2536 m_toolTip
->Apply( this );
2539 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2541 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2543 #endif // wxUSE_TOOLTIPS
2545 wxColour
wxWindow::GetBackgroundColour() const
2547 return m_backgroundColour
;
2550 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2552 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2554 if (m_backgroundColour
== colour
) return;
2556 m_backgroundColour
= colour
;
2557 if (!m_backgroundColour
.Ok()) return;
2559 if (m_wxwindow
&& m_wxwindow
->window
)
2561 /* wxMSW doesn't clear the window here. I don't do that
2562 either to provide compatibility. call Clear() to do
2565 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2566 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2569 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2571 if (sysbg
.Red() == colour
.Red() &&
2572 sysbg
.Green() == colour
.Green() &&
2573 sysbg
.Blue() == colour
.Blue())
2575 m_backgroundColour
= wxNullColour
;
2577 m_backgroundColour
= sysbg
;
2585 wxColour
wxWindow::GetForegroundColour() const
2587 return m_foregroundColour
;
2590 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2592 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2594 if (m_foregroundColour
== colour
) return;
2596 m_foregroundColour
= colour
;
2597 if (!m_foregroundColour
.Ok()) return;
2599 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2600 if (sysbg
.Red() == colour
.Red() &&
2601 sysbg
.Green() == colour
.Green() &&
2602 sysbg
.Blue() == colour
.Blue())
2604 m_backgroundColour
= wxNullColour
;
2606 m_backgroundColour
= sysbg
;
2614 GtkStyle
*wxWindow::GetWidgetStyle()
2616 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2620 gtk_widget_get_style( m_widget
) );
2622 return m_widgetStyle
;
2625 void wxWindow::SetWidgetStyle()
2627 GtkStyle
*style
= GetWidgetStyle();
2629 gdk_font_unref( style
->font
);
2630 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2632 if (m_foregroundColour
.Ok())
2634 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2635 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2636 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2637 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2640 if (m_backgroundColour
.Ok())
2642 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2643 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2644 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2645 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2646 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2647 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2648 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2649 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2650 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2654 void wxWindow::ApplyWidgetStyle()
2658 bool wxWindow::Validate()
2660 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2662 wxNode
*node
= m_children
.First();
2665 wxWindow
*child
= (wxWindow
*)node
->Data();
2666 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2670 node
= node
->Next();
2675 bool wxWindow::TransferDataToWindow()
2677 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2679 wxNode
*node
= m_children
.First();
2682 wxWindow
*child
= (wxWindow
*)node
->Data();
2683 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2684 !child
->GetValidator()->TransferToWindow() )
2686 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2689 node
= node
->Next();
2694 bool wxWindow::TransferDataFromWindow()
2696 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2698 wxNode
*node
= m_children
.First();
2701 wxWindow
*child
= (wxWindow
*)node
->Data();
2702 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2706 node
= node
->Next();
2711 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2713 m_acceleratorTable
= accel
;
2716 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2718 TransferDataToWindow();
2721 void wxWindow::InitDialog()
2723 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2725 wxInitDialogEvent
event(GetId());
2726 event
.SetEventObject( this );
2727 GetEventHandler()->ProcessEvent(event
);
2730 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2732 menu
->SetInvokingWindow( win
);
2733 wxNode
*node
= menu
->m_items
.First();
2736 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2737 if (menuitem
->IsSubMenu())
2739 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2741 node
= node
->Next();
2745 static gint gs_pop_x
= 0;
2746 static gint gs_pop_y
= 0;
2748 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2750 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2755 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2757 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2759 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2761 SetInvokingWindow( menu
, this );
2769 GTK_MENU(menu
->m_menu
),
2770 (GtkWidget
*) NULL
, // parent menu shell
2771 (GtkWidget
*) NULL
, // parent menu item
2772 (GtkMenuPositionFunc
) pop_pos_callback
,
2773 (gpointer
) this, // client data
2774 0, // button used to activate it
2775 0 //gs_timeLastClick // the time of activation
2780 #if wxUSE_DRAG_AND_DROP
2782 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2784 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2786 GtkWidget
*dnd_widget
= GetConnectWidget();
2788 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2790 if (m_dropTarget
) delete m_dropTarget
;
2791 m_dropTarget
= dropTarget
;
2793 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2796 wxDropTarget
*wxWindow::GetDropTarget() const
2798 return m_dropTarget
;
2803 GtkWidget
* wxWindow::GetConnectWidget()
2805 GtkWidget
*connect_widget
= m_widget
;
2806 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2808 return connect_widget
;
2811 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2813 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2814 return (window
== m_widget
->window
);
2817 void wxWindow::SetFont( const wxFont
&font
)
2819 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2821 if (((wxFont
*)&font
)->Ok())
2824 m_font
= *wxSWISS_FONT
;
2826 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2827 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2828 sysbg
.Green() == m_backgroundColour
.Green() &&
2829 sysbg
.Blue() == m_backgroundColour
.Blue())
2831 m_backgroundColour
= wxNullColour
;
2833 m_backgroundColour
= sysbg
;
2841 void wxWindow::SetWindowStyleFlag( long flag
)
2843 m_windowStyle
= flag
;
2846 long wxWindow::GetWindowStyleFlag() const
2848 return m_windowStyle
;
2851 void wxWindow::CaptureMouse()
2853 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2855 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2857 GtkWidget
*connect_widget
= GetConnectWidget();
2858 gtk_grab_add( connect_widget
);
2859 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2861 (GDK_BUTTON_PRESS_MASK
|
2862 GDK_BUTTON_RELEASE_MASK
|
2863 GDK_POINTER_MOTION_MASK
),
2870 void wxWindow::ReleaseMouse()
2872 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2874 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2876 GtkWidget
*connect_widget
= GetConnectWidget();
2877 gtk_grab_remove( connect_widget
);
2878 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2879 g_capturing
= FALSE
;
2882 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2886 wxString
wxWindow::GetTitle() const
2888 return (wxString
&)m_windowName
;
2891 wxString
wxWindow::GetLabel() const
2896 void wxWindow::SetName( const wxString
&name
)
2898 m_windowName
= name
;
2901 wxString
wxWindow::GetName() const
2903 return (wxString
&)m_windowName
;
2906 bool wxWindow::IsShown() const
2911 bool wxWindow::IsRetained()
2916 wxWindow
*wxWindow::FindWindow( long id
)
2918 if (id
== m_windowId
) return this;
2919 wxNode
*node
= m_children
.First();
2922 wxWindow
*child
= (wxWindow
*)node
->Data();
2923 wxWindow
*res
= child
->FindWindow( id
);
2924 if (res
) return res
;
2925 node
= node
->Next();
2927 return (wxWindow
*) NULL
;
2930 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2932 if (name
== m_windowName
) return this;
2933 wxNode
*node
= m_children
.First();
2936 wxWindow
*child
= (wxWindow
*)node
->Data();
2937 wxWindow
*res
= child
->FindWindow( name
);
2938 if (res
) return res
;
2939 node
= node
->Next();
2941 return (wxWindow
*) NULL
;
2944 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2945 int range
, bool refresh
)
2947 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2949 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2951 m_hasScrolling
= TRUE
;
2953 if (orient
== wxHORIZONTAL
)
2955 float fpos
= (float)pos
;
2956 float frange
= (float)range
;
2957 float fthumb
= (float)thumbVisible
;
2958 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2959 if (fpos
< 0.0) fpos
= 0.0;
2961 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2962 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2964 SetScrollPos( orient
, pos
, refresh
);
2968 m_oldHorizontalPos
= fpos
;
2970 m_hAdjust
->lower
= 0.0;
2971 m_hAdjust
->upper
= frange
;
2972 m_hAdjust
->value
= fpos
;
2973 m_hAdjust
->step_increment
= 1.0;
2974 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2975 m_hAdjust
->page_size
= fthumb
;
2979 float fpos
= (float)pos
;
2980 float frange
= (float)range
;
2981 float fthumb
= (float)thumbVisible
;
2982 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2983 if (fpos
< 0.0) fpos
= 0.0;
2985 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2986 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2988 SetScrollPos( orient
, pos
, refresh
);
2992 m_oldVerticalPos
= fpos
;
2994 m_vAdjust
->lower
= 0.0;
2995 m_vAdjust
->upper
= frange
;
2996 m_vAdjust
->value
= fpos
;
2997 m_vAdjust
->step_increment
= 1.0;
2998 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2999 m_vAdjust
->page_size
= fthumb
;
3002 if (m_wxwindow
->window
)
3004 if (orient
== wxHORIZONTAL
)
3005 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3007 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3009 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3013 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3015 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3017 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3019 if (orient
== wxHORIZONTAL
)
3021 float fpos
= (float)pos
;
3022 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3023 if (fpos
< 0.0) fpos
= 0.0;
3024 m_oldHorizontalPos
= fpos
;
3026 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3027 m_hAdjust
->value
= fpos
;
3031 float fpos
= (float)pos
;
3032 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3033 if (fpos
< 0.0) fpos
= 0.0;
3034 m_oldVerticalPos
= fpos
;
3036 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3037 m_vAdjust
->value
= fpos
;
3042 if (m_wxwindow
->window
)
3044 if (orient
== wxHORIZONTAL
)
3045 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3047 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3052 int wxWindow::GetScrollThumb( int orient
) const
3054 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3056 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3058 if (orient
== wxHORIZONTAL
)
3059 return (int)(m_hAdjust
->page_size
+0.5);
3061 return (int)(m_vAdjust
->page_size
+0.5);
3064 int wxWindow::GetScrollPos( int orient
) const
3066 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3068 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3070 if (orient
== wxHORIZONTAL
)
3071 return (int)(m_hAdjust
->value
+0.5);
3073 return (int)(m_vAdjust
->value
+0.5);
3076 int wxWindow::GetScrollRange( int orient
) const
3078 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3080 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3082 if (orient
== wxHORIZONTAL
)
3083 return (int)(m_hAdjust
->upper
+0.5);
3085 return (int)(m_vAdjust
->upper
+0.5);
3088 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3090 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3092 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3096 GetClientSize( &cw
, &ch
);
3098 int w
= cw
- abs(dx
);
3099 int h
= ch
- abs(dy
);
3100 if ((h
< 0) || (w
< 0))
3107 if (dx
< 0) s_x
= -dx
;
3108 if (dy
< 0) s_y
= -dy
;
3111 if (dx
> 0) d_x
= dx
;
3112 if (dy
> 0) d_y
= dy
;
3116 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3117 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3120 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3121 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3124 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3125 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3126 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3127 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3129 Refresh( TRUE
, &rect
);
3132 //-------------------------------------------------------------------------------------
3134 //-------------------------------------------------------------------------------------
3136 wxLayoutConstraints
*wxWindow::GetConstraints() const
3138 return m_constraints
;
3141 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3145 UnsetConstraints(m_constraints
);
3146 delete m_constraints
;
3148 m_constraints
= constraints
;
3151 // Make sure other windows know they're part of a 'meaningful relationship'
3152 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3153 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3154 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3155 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3156 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3157 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3158 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3159 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3160 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3161 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3162 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3163 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3164 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3165 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3166 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3167 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3173 void wxWindow::SetAutoLayout( bool autoLayout
)
3175 m_autoLayout
= autoLayout
;
3178 bool wxWindow::GetAutoLayout() const
3180 return m_autoLayout
;
3183 wxSizer
*wxWindow::GetSizer() const
3185 return m_windowSizer
;
3188 void wxWindow::SetSizerParent( wxWindow
*win
)
3190 m_sizerParent
= win
;
3193 wxWindow
*wxWindow::GetSizerParent() const
3195 return m_sizerParent
;
3198 // This removes any dangling pointers to this window
3199 // in other windows' constraintsInvolvedIn lists.
3200 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3204 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3205 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3206 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3207 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3208 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3209 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3210 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3211 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3212 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3213 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3214 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3215 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3216 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3217 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3218 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3219 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3223 // Back-pointer to other windows we're involved with, so if we delete
3224 // this window, we must delete any constraints we're involved with.
3225 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3227 if (!m_constraintsInvolvedIn
)
3228 m_constraintsInvolvedIn
= new wxList
;
3229 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3230 m_constraintsInvolvedIn
->Append(otherWin
);
3233 // REMOVE back-pointer to other windows we're involved with.
3234 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3236 if (m_constraintsInvolvedIn
)
3237 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3240 // Reset any constraints that mention this window
3241 void wxWindow::DeleteRelatedConstraints()
3243 if (m_constraintsInvolvedIn
)
3245 wxNode
*node
= m_constraintsInvolvedIn
->First();
3248 wxWindow
*win
= (wxWindow
*)node
->Data();
3249 wxNode
*next
= node
->Next();
3250 wxLayoutConstraints
*constr
= win
->GetConstraints();
3252 // Reset any constraints involving this window
3255 constr
->left
.ResetIfWin((wxWindow
*)this);
3256 constr
->top
.ResetIfWin((wxWindow
*)this);
3257 constr
->right
.ResetIfWin((wxWindow
*)this);
3258 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3259 constr
->width
.ResetIfWin((wxWindow
*)this);
3260 constr
->height
.ResetIfWin((wxWindow
*)this);
3261 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3262 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3267 delete m_constraintsInvolvedIn
;
3268 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3272 void wxWindow::SetSizer(wxSizer
*sizer
)
3274 m_windowSizer
= sizer
;
3276 sizer
->SetSizerParent((wxWindow
*)this);
3283 bool wxWindow::Layout()
3285 if (GetConstraints())
3288 GetClientSize(&w
, &h
);
3289 GetConstraints()->width
.SetValue(w
);
3290 GetConstraints()->height
.SetValue(h
);
3293 // If top level (one sizer), evaluate the sizer's constraints.
3297 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3298 GetSizer()->LayoutPhase1(&noChanges
);
3299 GetSizer()->LayoutPhase2(&noChanges
);
3300 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3305 // Otherwise, evaluate child constraints
3306 ResetConstraints(); // Mark all constraints as unevaluated
3307 DoPhase(1); // Just one phase need if no sizers involved
3309 SetConstraintSizes(); // Recursively set the real window sizes
3315 // Do a phase of evaluating constraints:
3316 // the default behaviour. wxSizers may do a similar
3317 // thing, but also impose their own 'constraints'
3318 // and order the evaluation differently.
3319 bool wxWindow::LayoutPhase1(int *noChanges
)
3321 wxLayoutConstraints
*constr
= GetConstraints();
3324 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3330 bool wxWindow::LayoutPhase2(int *noChanges
)
3340 // Do a phase of evaluating child constraints
3341 bool wxWindow::DoPhase(int phase
)
3343 int noIterations
= 0;
3344 int maxIterations
= 500;
3348 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3352 wxNode
*node
= m_children
.First();
3355 wxWindow
*child
= (wxWindow
*)node
->Data();
3356 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3358 wxLayoutConstraints
*constr
= child
->GetConstraints();
3361 if (succeeded
.Member(child
))
3366 int tempNoChanges
= 0;
3367 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3368 noChanges
+= tempNoChanges
;
3371 succeeded
.Append(child
);
3376 node
= node
->Next();
3383 void wxWindow::ResetConstraints()
3385 wxLayoutConstraints
*constr
= GetConstraints();
3388 constr
->left
.SetDone(FALSE
);
3389 constr
->top
.SetDone(FALSE
);
3390 constr
->right
.SetDone(FALSE
);
3391 constr
->bottom
.SetDone(FALSE
);
3392 constr
->width
.SetDone(FALSE
);
3393 constr
->height
.SetDone(FALSE
);
3394 constr
->centreX
.SetDone(FALSE
);
3395 constr
->centreY
.SetDone(FALSE
);
3397 wxNode
*node
= m_children
.First();
3400 wxWindow
*win
= (wxWindow
*)node
->Data();
3401 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3402 win
->ResetConstraints();
3403 node
= node
->Next();
3407 // Need to distinguish between setting the 'fake' size for
3408 // windows and sizers, and setting the real values.
3409 void wxWindow::SetConstraintSizes(bool recurse
)
3411 wxLayoutConstraints
*constr
= GetConstraints();
3412 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3413 constr
->width
.GetDone() && constr
->height
.GetDone())
3415 int x
= constr
->left
.GetValue();
3416 int y
= constr
->top
.GetValue();
3417 int w
= constr
->width
.GetValue();
3418 int h
= constr
->height
.GetValue();
3420 // If we don't want to resize this window, just move it...
3421 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3422 (constr
->height
.GetRelationship() != wxAsIs
))
3424 // Calls Layout() recursively. AAAGH. How can we stop that.
3425 // Simply take Layout() out of non-top level OnSizes.
3426 SizerSetSize(x
, y
, w
, h
);
3435 char *windowClass
= this->GetClassInfo()->GetClassName();
3438 if (GetName() == "")
3439 winName
= "unnamed";
3441 winName
= GetName();
3442 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3443 (const char *)windowClass
,
3444 (const char *)winName
);
3445 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3446 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3447 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3448 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3449 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3454 wxNode
*node
= m_children
.First();
3457 wxWindow
*win
= (wxWindow
*)node
->Data();
3458 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3459 win
->SetConstraintSizes();
3460 node
= node
->Next();
3465 // This assumes that all sizers are 'on' the same
3466 // window, i.e. the parent of this window.
3467 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3469 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3470 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3474 m_sizerParent
->GetPosition(&xp
, &yp
);
3475 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3480 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3484 TransformSizerToActual(&xx
, &yy
);
3485 SetSize(xx
, yy
, w
, h
);
3488 void wxWindow::SizerMove(int x
, int y
)
3492 TransformSizerToActual(&xx
, &yy
);
3496 // Only set the size/position of the constraint (if any)
3497 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3499 wxLayoutConstraints
*constr
= GetConstraints();
3504 constr
->left
.SetValue(x
);
3505 constr
->left
.SetDone(TRUE
);
3509 constr
->top
.SetValue(y
);
3510 constr
->top
.SetDone(TRUE
);
3514 constr
->width
.SetValue(w
);
3515 constr
->width
.SetDone(TRUE
);
3519 constr
->height
.SetValue(h
);
3520 constr
->height
.SetDone(TRUE
);
3525 void wxWindow::MoveConstraint(int x
, int y
)
3527 wxLayoutConstraints
*constr
= GetConstraints();
3532 constr
->left
.SetValue(x
);
3533 constr
->left
.SetDone(TRUE
);
3537 constr
->top
.SetValue(y
);
3538 constr
->top
.SetDone(TRUE
);
3543 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3545 wxLayoutConstraints
*constr
= GetConstraints();
3548 *w
= constr
->width
.GetValue();
3549 *h
= constr
->height
.GetValue();
3555 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3557 wxLayoutConstraints
*constr
= GetConstraints();
3560 *w
= constr
->width
.GetValue();
3561 *h
= constr
->height
.GetValue();
3564 GetClientSize(w
, h
);
3567 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3569 wxLayoutConstraints
*constr
= GetConstraints();
3572 *x
= constr
->left
.GetValue();
3573 *y
= constr
->top
.GetValue();