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"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
47 //-----------------------------------------------------------------------------
48 // documentation on internals
49 //-----------------------------------------------------------------------------
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
55 some more information about what the wxWindow, which is the base class
56 for all other window classes, does seems required as well.
58 What does wxWindow do? It contains the common interface for the following
59 jobs of its descendants:
61 1) Define the rudimentary behaviour common to all window classes, such as
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
67 classes which do not display a native GTK widget. To name them, these
68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
69 work classes are a special case and are handled a bit differently from
70 the rest. The same holds true for the wxNotebook class.
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 All windows must have a widget, with which they interact with other under-
95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
96 thw wxWindow class has a member variable called m_widget which holds a
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
102 When the class has a client area for drawing into and for containing children
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
124 //-----------------------------------------------------------------------------
126 //-----------------------------------------------------------------------------
128 extern wxList wxPendingDelete
;
129 extern bool g_blockEventsOnDrag
;
130 extern bool g_blockEventsOnScroll
;
131 static bool g_capturing
= FALSE
;
132 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
134 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
135 the last click here */
136 static guint32 gs_timeLastClick
= 0;
138 #if (GTK_MINOR_VERSION > 0)
140 //-----------------------------------------------------------------------------
141 // local code (see below)
142 //-----------------------------------------------------------------------------
144 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
146 if (!win
->HasVMT()) return;
151 if (win
->m_hasScrolling
)
153 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
154 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
157 GtkWidget *hscrollbar = scroll_window->hscrollbar;
158 GtkWidget *vscrollbar = scroll_window->vscrollbar;
160 we use this instead: range.slider_width = 11 + 2*2pts edge
163 if (scroll_window
->vscrollbar_visible
)
165 dw
+= 15; /* dw += vscrollbar->allocation.width; */
166 dw
+= scroll_class
->scrollbar_spacing
;
169 if (scroll_window
->hscrollbar_visible
)
171 dh
+= 15; /* dh += hscrollbar->allocation.height; */
172 dw
+= scroll_class
->scrollbar_spacing
;
178 if (GTK_WIDGET_NO_WINDOW (widget
))
180 dx
+= widget
->allocation
.x
;
181 dy
+= widget
->allocation
.y
;
184 if (win
->m_windowStyle
& wxRAISED_BORDER
)
186 gtk_draw_shadow( widget
->style
,
191 win
->m_width
-dw
, win
->m_height
-dh
);
195 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
197 gtk_draw_shadow( widget
->style
,
202 win
->m_width
-dw
, win
->m_height
-dh
);
207 //-----------------------------------------------------------------------------
208 // "expose_event" of m_widget
209 //-----------------------------------------------------------------------------
211 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
213 if (gdk_event
->count
> 0) return;
214 draw_frame( widget
, win
);
217 //-----------------------------------------------------------------------------
218 // "draw" of m_wxwindow
219 //-----------------------------------------------------------------------------
221 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
223 draw_frame( widget
, win
);
228 //-----------------------------------------------------------------------------
229 // "expose_event" of m_wxwindow
230 //-----------------------------------------------------------------------------
232 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
234 if (!win
->HasVMT()) return;
236 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
238 gdk_event
->area
.width
,
239 gdk_event
->area
.height
);
241 if (gdk_event
->count
> 0) return;
244 printf( "OnExpose from " );
245 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
246 printf( win->GetClassInfo()->GetClassName() );
250 wxPaintEvent
event( win
->GetId() );
251 event
.SetEventObject( win
);
252 win
->GetEventHandler()->ProcessEvent( event
);
254 win
->m_updateRegion
.Clear();
257 //-----------------------------------------------------------------------------
258 // "draw" of m_wxwindow
259 //-----------------------------------------------------------------------------
261 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
263 if (!win
->HasVMT()) return;
265 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
267 wxPaintEvent
event( win
->GetId() );
268 event
.SetEventObject( win
);
269 win
->GetEventHandler()->ProcessEvent( event
);
271 win
->m_updateRegion
.Clear();
274 //-----------------------------------------------------------------------------
275 // "key_press_event" from any window
276 //-----------------------------------------------------------------------------
278 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
280 if (!win
->HasVMT()) return FALSE
;
281 if (g_blockEventsOnDrag
) return FALSE
;
284 wxPrintf( _T("OnKeyPress from ") );
285 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
286 wxPrintf( win->GetClassInfo()->GetClassName() );
287 wxPrintf( _T(".\n") );
291 switch (gdk_event
->keyval
)
293 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
294 case GDK_ISO_Left_Tab
:
296 case GDK_Tab
: key_code
= WXK_TAB
; break;
297 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
298 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
299 case GDK_Return
: key_code
= WXK_RETURN
; break;
300 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
301 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
302 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
303 case GDK_Delete
: key_code
= WXK_DELETE
; break;
304 case GDK_Home
: key_code
= WXK_HOME
; break;
305 case GDK_Left
: key_code
= WXK_LEFT
; break;
306 case GDK_Up
: key_code
= WXK_UP
; break;
307 case GDK_Right
: key_code
= WXK_RIGHT
; break;
308 case GDK_Down
: key_code
= WXK_DOWN
; break;
309 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
310 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
311 case GDK_Next
: key_code
= WXK_NEXT
; break;
312 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
313 case GDK_End
: key_code
= WXK_END
; break;
314 case GDK_Begin
: key_code
= WXK_HOME
; break;
315 case GDK_Select
: key_code
= WXK_SELECT
; break;
316 case GDK_Print
: key_code
= WXK_PRINT
; break;
317 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
318 case GDK_Insert
: key_code
= WXK_INSERT
; break;
319 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
320 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
321 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
322 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
323 case GDK_KP_Up
: key_code
= WXK_UP
; break;
324 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
325 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
326 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
327 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
328 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
329 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
330 case GDK_KP_End
: key_code
= WXK_END
; break;
331 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
332 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
333 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
334 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
335 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
336 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
337 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
338 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
339 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
340 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
341 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
342 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
343 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
344 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
345 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
346 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
347 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
348 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
349 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
350 case GDK_F1
: key_code
= WXK_F1
; break;
351 case GDK_F2
: key_code
= WXK_F2
; break;
352 case GDK_F3
: key_code
= WXK_F3
; break;
353 case GDK_F4
: key_code
= WXK_F4
; break;
354 case GDK_F5
: key_code
= WXK_F5
; break;
355 case GDK_F6
: key_code
= WXK_F6
; break;
356 case GDK_F7
: key_code
= WXK_F7
; break;
357 case GDK_F8
: key_code
= WXK_F8
; break;
358 case GDK_F9
: key_code
= WXK_F9
; break;
359 case GDK_F10
: key_code
= WXK_F10
; break;
360 case GDK_F11
: key_code
= WXK_F11
; break;
361 case GDK_F12
: key_code
= WXK_F12
; break;
364 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
365 key_code
= gdk_event
->keyval
;
369 if (!key_code
) return FALSE
;
371 wxKeyEvent
event( wxEVT_KEY_DOWN
);
372 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
373 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
374 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
375 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
376 event
.m_keyCode
= key_code
;
379 event
.SetEventObject( win
);
381 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
385 wxWindow
*ancestor
= win
;
388 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
391 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
392 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
395 ancestor
= ancestor
->GetParent();
399 // win is a control: tab can be propagated up
401 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
402 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
404 wxNavigationKeyEvent new_event
;
405 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
406 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
407 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
408 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
409 new_event
.SetCurrentFocus( win
);
410 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
414 (gdk_event
->keyval
== GDK_Escape
) )
416 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
417 new_event
.SetEventObject( win
);
418 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
422 Damn, I forgot why this didn't work, but it didn't work.
424 // win is a panel: up can be propagated to the panel
425 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
426 (gdk_event->keyval == GDK_Up))
428 win->m_parent->SetFocus();
432 // win is a panel: left/right can be propagated to the panel
433 if ((!ret) && (win->m_wxwindow) &&
434 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
435 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
437 wxNavigationKeyEvent new_event;
438 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
439 new_event.SetCurrentFocus( win );
440 ret = win->GetEventHandler()->ProcessEvent( new_event );
446 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
453 //-----------------------------------------------------------------------------
454 // "key_release_event" from any window
455 //-----------------------------------------------------------------------------
457 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
459 if (!win
->HasVMT()) return FALSE
;
460 if (g_blockEventsOnDrag
) return FALSE
;
463 printf( "OnKeyRelease from " );
464 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
465 printf( win->GetClassInfo()->GetClassName() );
470 switch (gdk_event
->keyval
)
472 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
473 case GDK_ISO_Left_Tab
:
475 case GDK_Tab
: key_code
= WXK_TAB
; break;
476 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
477 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
478 case GDK_Return
: key_code
= WXK_RETURN
; break;
479 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
480 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
481 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
482 case GDK_Delete
: key_code
= WXK_DELETE
; break;
483 case GDK_Home
: key_code
= WXK_HOME
; break;
484 case GDK_Left
: key_code
= WXK_LEFT
; break;
485 case GDK_Up
: key_code
= WXK_UP
; break;
486 case GDK_Right
: key_code
= WXK_RIGHT
; break;
487 case GDK_Down
: key_code
= WXK_DOWN
; break;
488 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
489 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
490 case GDK_Next
: key_code
= WXK_NEXT
; break;
491 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
492 case GDK_End
: key_code
= WXK_END
; break;
493 case GDK_Begin
: key_code
= WXK_HOME
; break;
494 case GDK_Select
: key_code
= WXK_SELECT
; break;
495 case GDK_Print
: key_code
= WXK_PRINT
; break;
496 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
497 case GDK_Insert
: key_code
= WXK_INSERT
; break;
498 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
499 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
500 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
501 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
502 case GDK_KP_Up
: key_code
= WXK_UP
; break;
503 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
504 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
505 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
506 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
507 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
508 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
509 case GDK_KP_End
: key_code
= WXK_END
; break;
510 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
511 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
512 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
513 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
514 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
515 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
516 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
517 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
518 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
519 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
520 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
521 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
522 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
523 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
524 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
525 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
526 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
527 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
528 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
529 case GDK_F1
: key_code
= WXK_F1
; break;
530 case GDK_F2
: key_code
= WXK_F2
; break;
531 case GDK_F3
: key_code
= WXK_F3
; break;
532 case GDK_F4
: key_code
= WXK_F4
; break;
533 case GDK_F5
: key_code
= WXK_F5
; break;
534 case GDK_F6
: key_code
= WXK_F6
; break;
535 case GDK_F7
: key_code
= WXK_F7
; break;
536 case GDK_F8
: key_code
= WXK_F8
; break;
537 case GDK_F9
: key_code
= WXK_F9
; break;
538 case GDK_F10
: key_code
= WXK_F10
; break;
539 case GDK_F11
: key_code
= WXK_F11
; break;
540 case GDK_F12
: key_code
= WXK_F12
; break;
543 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
544 key_code
= gdk_event
->keyval
;
548 if (!key_code
) return FALSE
;
550 wxKeyEvent
event( wxEVT_KEY_UP
);
551 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
552 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
553 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
554 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
555 event
.m_keyCode
= key_code
;
558 event
.SetEventObject( win
);
560 if (win
->GetEventHandler()->ProcessEvent( event
))
562 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
569 //-----------------------------------------------------------------------------
570 // "button_press_event"
571 //-----------------------------------------------------------------------------
573 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
576 wxPrintf( _T("1) OnButtonPress from ") );
577 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
578 wxPrintf( win->GetClassInfo()->GetClassName() );
579 wxPrintf( _T(".\n") );
582 if (!win
->HasVMT()) return FALSE
;
583 if (g_blockEventsOnDrag
) return TRUE
;
584 if (g_blockEventsOnScroll
) return TRUE
;
586 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
590 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
592 gtk_widget_grab_focus (win
->m_wxwindow
);
595 wxPrintf( _T("GrabFocus from ") );
596 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
597 wxPrintf( win->GetClassInfo()->GetClassName() );
598 wxPrintf( _T(".\n") );
605 wxPrintf( _T("No GrabFocus from ") );
606 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
607 wxPrintf( win->GetClassInfo()->GetClassName() );
608 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
609 wxPrintf( _T(" because it already has") );
610 wxPrintf( _T(".\n") );
616 wxPrintf( _T("2) OnButtonPress from ") );
617 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
618 wxPrintf( win->GetClassInfo()->GetClassName() );
619 wxPrintf( _T(".\n") );
622 wxEventType event_type
= wxEVT_LEFT_DOWN
;
624 if (gdk_event
->button
== 1)
626 switch (gdk_event
->type
)
628 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
629 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
633 else if (gdk_event
->button
== 2)
635 switch (gdk_event
->type
)
637 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
638 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
642 else if (gdk_event
->button
== 3)
644 switch (gdk_event
->type
)
646 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
647 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
652 wxMouseEvent
event( event_type
);
653 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
654 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
655 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
656 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
657 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
658 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
659 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
661 event
.m_x
= (long)gdk_event
->x
;
662 event
.m_y
= (long)gdk_event
->y
;
664 // Some control don't have their own X window and thus cannot get
669 wxNode
*node
= win
->GetChildren().First();
672 wxWindow
*child
= (wxWindow
*)node
->Data();
674 if (child
->m_isStaticBox
)
676 // wxStaticBox is transparent in the box itself
679 int xx1
= child
->m_x
;
680 int yy1
= child
->m_y
;
681 int xx2
= child
->m_x
+ child
->m_width
;
682 int yy2
= child
->m_x
+ child
->m_height
;
685 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
687 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
689 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
691 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
694 event
.m_x
-= child
->m_x
;
695 event
.m_y
-= child
->m_y
;
702 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
703 (child
->m_x
<= event
.m_x
) &&
704 (child
->m_y
<= event
.m_y
) &&
705 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
706 (child
->m_y
+child
->m_height
>= event
.m_y
))
709 event
.m_x
-= child
->m_x
;
710 event
.m_y
-= child
->m_y
;
718 event
.SetEventObject( win
);
720 gs_timeLastClick
= gdk_event
->time
;
722 if (win
->GetEventHandler()->ProcessEvent( event
))
724 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
731 //-----------------------------------------------------------------------------
732 // "button_release_event"
733 //-----------------------------------------------------------------------------
735 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
737 if (!win
->HasVMT()) return FALSE
;
738 if (g_blockEventsOnDrag
) return FALSE
;
739 if (g_blockEventsOnScroll
) return FALSE
;
741 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
744 printf( "OnButtonRelease from " );
745 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
746 printf( win->GetClassInfo()->GetClassName() );
750 wxEventType event_type
= wxEVT_NULL
;
752 switch (gdk_event
->button
)
754 case 1: event_type
= wxEVT_LEFT_UP
; break;
755 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
756 case 3: event_type
= wxEVT_RIGHT_UP
; break;
759 wxMouseEvent
event( event_type
);
760 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
761 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
762 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
763 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
764 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
765 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
766 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
767 event
.m_x
= (long)gdk_event
->x
;
768 event
.m_y
= (long)gdk_event
->y
;
770 // Some control don't have their own X window and thus cannot get
775 wxNode
*node
= win
->GetChildren().First();
778 wxWindow
*child
= (wxWindow
*)node
->Data();
780 if (child
->m_isStaticBox
)
782 // wxStaticBox is transparent in the box itself
785 int xx1
= child
->m_x
;
786 int yy1
= child
->m_y
;
787 int xx2
= child
->m_x
+ child
->m_width
;
788 int yy2
= child
->m_x
+ child
->m_height
;
791 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
793 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
795 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
797 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
800 event
.m_x
-= child
->m_x
;
801 event
.m_y
-= child
->m_y
;
808 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
809 (child
->m_x
<= event
.m_x
) &&
810 (child
->m_y
<= event
.m_y
) &&
811 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
812 (child
->m_y
+child
->m_height
>= event
.m_y
))
815 event
.m_x
-= child
->m_x
;
816 event
.m_y
-= child
->m_y
;
824 event
.SetEventObject( win
);
826 if (win
->GetEventHandler()->ProcessEvent( event
))
828 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
835 //-----------------------------------------------------------------------------
836 // "motion_notify_event"
837 //-----------------------------------------------------------------------------
839 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
841 if (!win
->HasVMT()) return FALSE
;
842 if (g_blockEventsOnDrag
) return FALSE
;
843 if (g_blockEventsOnScroll
) return FALSE
;
845 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
847 if (gdk_event
->is_hint
)
851 GdkModifierType state
;
852 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
855 gdk_event
->state
= state
;
859 printf( "OnMotion from " );
860 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
861 printf( win->GetClassInfo()->GetClassName() );
865 wxMouseEvent
event( wxEVT_MOTION
);
866 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
867 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
868 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
869 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
870 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
871 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
872 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
874 event
.m_x
= (long)gdk_event
->x
;
875 event
.m_y
= (long)gdk_event
->y
;
877 // Some control don't have their own X window and thus cannot get
882 wxNode
*node
= win
->GetChildren().First();
885 wxWindow
*child
= (wxWindow
*)node
->Data();
887 if (child
->m_isStaticBox
)
889 // wxStaticBox is transparent in the box itself
892 int xx1
= child
->m_x
;
893 int yy1
= child
->m_y
;
894 int xx2
= child
->m_x
+ child
->m_width
;
895 int yy2
= child
->m_x
+ child
->m_height
;
898 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
900 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
902 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
904 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
907 event
.m_x
-= child
->m_x
;
908 event
.m_y
-= child
->m_y
;
915 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
916 (child
->m_x
<= event
.m_x
) &&
917 (child
->m_y
<= event
.m_y
) &&
918 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
919 (child
->m_y
+child
->m_height
>= event
.m_y
))
922 event
.m_x
-= child
->m_x
;
923 event
.m_y
-= child
->m_y
;
931 event
.SetEventObject( win
);
933 if (win
->GetEventHandler()->ProcessEvent( event
))
935 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
942 //-----------------------------------------------------------------------------
944 //-----------------------------------------------------------------------------
946 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
948 if (!win
->HasVMT()) return FALSE
;
949 if (g_blockEventsOnDrag
) return FALSE
;
955 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
957 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
959 printf( "SetFocus flag from " );
960 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
961 printf( win->GetClassInfo()->GetClassName() );
969 wxPrintf( _T("OnSetFocus from ") );
970 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
971 wxPrintf( win->GetClassInfo()->GetClassName() );
973 wxPrintf( win->GetLabel() );
974 wxPrintf( _T(".\n") );
977 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
978 event
.SetEventObject( win
);
980 if (win
->GetEventHandler()->ProcessEvent( event
))
982 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
989 //-----------------------------------------------------------------------------
991 //-----------------------------------------------------------------------------
993 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
995 if (!win
->HasVMT()) return FALSE
;
996 if (g_blockEventsOnDrag
) return FALSE
;
1000 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1001 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1005 wxPrintf( _T("OnKillFocus from ") );
1006 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1007 wxPrintf( win->GetClassInfo()->GetClassName() );
1008 wxPrintf( _T(" ") );
1009 wxPrintf( win->GetLabel() );
1010 wxPrintf( _T(".\n") );
1013 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1014 event
.SetEventObject( win
);
1016 if (win
->GetEventHandler()->ProcessEvent( event
))
1018 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1025 //-----------------------------------------------------------------------------
1026 // "enter_notify_event"
1027 //-----------------------------------------------------------------------------
1029 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1031 if (!win
->HasVMT()) return FALSE
;
1032 if (g_blockEventsOnDrag
) return FALSE
;
1034 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1036 if ((widget
->window
) && (win
->m_cursor
.Ok()))
1037 gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() );
1040 printf( "OnEnter from " );
1041 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1042 printf( win->GetClassInfo()->GetClassName() );
1046 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1047 event
.SetEventObject( win
);
1051 GdkModifierType state
= (GdkModifierType
)0;
1053 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1055 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1056 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1057 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1058 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1059 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1060 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1061 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1063 event
.m_x
= (long)x
;
1064 event
.m_y
= (long)y
;
1066 if (win
->GetEventHandler()->ProcessEvent( event
))
1068 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1075 //-----------------------------------------------------------------------------
1076 // "leave_notify_event"
1077 //-----------------------------------------------------------------------------
1079 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1081 if (!win
->HasVMT()) return FALSE
;
1082 if (g_blockEventsOnDrag
) return FALSE
;
1084 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1087 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1090 printf( "OnLeave from " );
1091 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1092 printf( win->GetClassInfo()->GetClassName() );
1096 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1097 event
.SetEventObject( win
);
1101 GdkModifierType state
= (GdkModifierType
)0;
1103 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1105 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1106 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1107 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1108 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1109 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1110 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1111 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1113 event
.m_x
= (long)x
;
1114 event
.m_y
= (long)y
;
1116 if (win
->GetEventHandler()->ProcessEvent( event
))
1118 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1125 //-----------------------------------------------------------------------------
1126 // "value_changed" from m_vAdjust
1127 //-----------------------------------------------------------------------------
1129 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1131 if (g_blockEventsOnDrag
) return;
1134 printf( "OnVScroll from " );
1135 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1136 printf( win->GetClassInfo()->GetClassName() );
1140 if (!win
->HasVMT()) return;
1142 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1143 if (fabs(diff
) < 0.2) return;
1144 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1146 wxEventType command
= wxEVT_NULL
;
1148 float line_step
= win
->m_vAdjust
->step_increment
;
1149 float page_step
= win
->m_vAdjust
->page_increment
;
1151 if (win
->m_isScrolling
)
1153 command
= wxEVT_SCROLL_THUMBTRACK
;
1157 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1158 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1159 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1160 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1161 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1162 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1163 else command
= wxEVT_SCROLL_THUMBTRACK
;
1166 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1168 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1169 event
.SetEventObject( win
);
1170 win
->GetEventHandler()->ProcessEvent( event
);
1173 //-----------------------------------------------------------------------------
1174 // "value_changed" from m_hAdjust
1175 //-----------------------------------------------------------------------------
1177 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1179 if (g_blockEventsOnDrag
) return;
1182 printf( "OnHScroll from " );
1183 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1184 printf( win->GetClassInfo()->GetClassName() );
1188 if (!win
->HasVMT()) return;
1190 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1191 if (fabs(diff
) < 0.2) return;
1192 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1194 wxEventType command
= wxEVT_NULL
;
1196 float line_step
= win
->m_hAdjust
->step_increment
;
1197 float page_step
= win
->m_hAdjust
->page_increment
;
1199 if (win
->m_isScrolling
)
1201 command
= wxEVT_SCROLL_THUMBTRACK
;
1205 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1206 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1207 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1208 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1209 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1210 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1211 else command
= wxEVT_SCROLL_THUMBTRACK
;
1214 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1216 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1217 event
.SetEventObject( win
);
1218 win
->GetEventHandler()->ProcessEvent( event
);
1221 //-----------------------------------------------------------------------------
1222 // "changed" from m_vAdjust
1223 //-----------------------------------------------------------------------------
1225 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1227 if (g_blockEventsOnDrag
) return;
1230 printf( "OnVScroll change from " );
1231 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1232 printf( win->GetClassInfo()->GetClassName() );
1236 if (!win
->HasVMT()) return;
1238 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1239 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1241 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1242 event
.SetEventObject( win
);
1243 win
->GetEventHandler()->ProcessEvent( event
);
1246 //-----------------------------------------------------------------------------
1247 // "changed" from m_hAdjust
1248 //-----------------------------------------------------------------------------
1250 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1252 if (g_blockEventsOnDrag
) return;
1255 printf( "OnHScroll change from " );
1256 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1257 printf( win->GetClassInfo()->GetClassName() );
1261 if (!win
->HasVMT()) return;
1263 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1264 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1266 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1267 event
.SetEventObject( win
);
1268 win
->GetEventHandler()->ProcessEvent( event
);
1271 //-----------------------------------------------------------------------------
1272 // "button_press_event" from scrollbar
1273 //-----------------------------------------------------------------------------
1275 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1276 GdkEventButton
*WXUNUSED(gdk_event
),
1279 // don't test here as we can release the mouse while being over
1280 // a different window then the slider
1282 // if (gdk_event->window != widget->slider) return FALSE;
1284 win
->m_isScrolling
= TRUE
;
1285 g_blockEventsOnScroll
= TRUE
;
1290 //-----------------------------------------------------------------------------
1291 // "button_release_event" from scrollbar
1292 //-----------------------------------------------------------------------------
1294 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1295 GdkEventButton
*WXUNUSED(gdk_event
),
1299 // don't test here as we can release the mouse while being over
1300 // a different window then the slider
1302 // if (gdk_event->window != widget->slider) return FALSE;
1304 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1306 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1307 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1309 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1311 win
->m_isScrolling
= FALSE
;
1312 g_blockEventsOnScroll
= FALSE
;
1317 //-----------------------------------------------------------------------------
1318 // "realize" from m_widget
1319 //-----------------------------------------------------------------------------
1321 /* we cannot set colours, fonts and cursors before the widget has
1322 been realized, so we do this directly after realization */
1325 gtk_window_realized_callback( GtkWidget
*widget
, wxWindow
*win
)
1327 if (win
->m_font
!= *wxSWISS_FONT
)
1329 wxFont
font( win
->m_font
);
1330 win
->m_font
= wxNullFont
;
1331 win
->SetFont( font
);
1334 if (win
->m_backgroundColour
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
))
1336 wxColour
bg( win
->m_backgroundColour
);
1337 win
->m_backgroundColour
= wxNullColour
;
1338 win
->SetBackgroundColour( bg
);
1341 if (win
->m_foregroundColour
!= *wxBLACK
)
1343 wxColour
fg( win
->m_foregroundColour
);
1344 win
->m_foregroundColour
= wxNullColour
;
1345 win
->SetForegroundColour( fg
);
1348 wxCursor
cursor( win
->m_cursor
);
1349 win
->m_cursor
= wxNullCursor
;
1350 win
->SetCursor( cursor
);
1355 //-----------------------------------------------------------------------------
1356 // InsertChild for wxWindow.
1357 //-----------------------------------------------------------------------------
1359 /* Callback for wxWindow. This very strange beast has to be used because
1360 * C++ has no virtual methods in a constructor. We have to emulate a
1361 * virtual function here as wxNotebook requires a different way to insert
1362 * a child in it. I had opted for creating a wxNotebookPage window class
1363 * which would have made this superfluous (such in the MDI window system),
1364 * but no-one was listening to me... */
1366 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1368 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1369 GTK_WIDGET(child
->m_widget
),
1373 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1377 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1379 /* we now allow a window to get the focus as long as it
1380 doesn't have any children. */
1381 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1385 //-----------------------------------------------------------------------------
1387 //-----------------------------------------------------------------------------
1389 wxWindow
* wxGetActiveWindow()
1391 return g_focusWindow
;
1394 //-----------------------------------------------------------------------------
1396 //-----------------------------------------------------------------------------
1398 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1400 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1401 EVT_SIZE(wxWindow::OnSize
)
1402 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1403 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1404 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1407 void wxWindow::Init()
1411 m_widget
= (GtkWidget
*) NULL
;
1412 m_wxwindow
= (GtkWidget
*) NULL
;
1413 m_parent
= (wxWindow
*) NULL
;
1414 m_children
.DeleteContents( FALSE
);
1427 m_eventHandler
= this;
1428 m_windowValidator
= (wxValidator
*) NULL
;
1432 m_cursor
= *wxSTANDARD_CURSOR
;
1433 m_font
= *wxSWISS_FONT
;
1435 m_windowName
= "noname";
1437 m_constraints
= (wxLayoutConstraints
*) NULL
;
1438 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1439 m_windowSizer
= (wxSizer
*) NULL
;
1440 m_sizerParent
= (wxWindow
*) NULL
;
1441 m_autoLayout
= FALSE
;
1445 m_needParent
= TRUE
;
1447 m_hasScrolling
= FALSE
;
1448 m_isScrolling
= FALSE
;
1449 m_hAdjust
= (GtkAdjustment
*) NULL
;
1450 m_vAdjust
= (GtkAdjustment
*) NULL
;
1451 m_oldHorizontalPos
= 0.0;
1452 m_oldVerticalPos
= 0.0;
1457 #if wxUSE_DRAG_AND_DROP
1458 m_dropTarget
= (wxDropTarget
*) NULL
;
1461 m_scrollGC
= (GdkGC
*) NULL
;
1462 m_widgetStyle
= (GtkStyle
*) NULL
;
1464 m_insertCallback
= wxInsertChildInWindow
;
1466 m_clientObject
= (wxClientData
*) NULL
;
1467 m_clientData
= NULL
;
1469 m_isStaticBox
= FALSE
;
1470 m_acceptsFocus
= FALSE
;
1473 m_toolTip
= (wxToolTip
*) NULL
;
1474 #endif // wxUSE_TOOLTIPS
1477 wxWindow::wxWindow()
1482 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1483 const wxPoint
&pos
, const wxSize
&size
,
1484 long style
, const wxString
&name
)
1488 Create( parent
, id
, pos
, size
, style
, name
);
1491 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1492 const wxPoint
&pos
, const wxSize
&size
,
1493 long style
, const wxString
&name
)
1495 wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") );
1497 PreCreation( parent
, id
, pos
, size
, style
, name
);
1499 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1500 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1502 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1504 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1505 scroll_class
->scrollbar_spacing
= 0;
1507 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1509 m_oldHorizontalPos
= 0.0;
1510 m_oldVerticalPos
= 0.0;
1512 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1513 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1515 m_wxwindow
= gtk_myfixed_new();
1516 gtk_widget_show( m_wxwindow
);
1518 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1520 #if (GTK_MINOR_VERSION > 0)
1521 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1523 if (m_windowStyle
& wxRAISED_BORDER
)
1525 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1527 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1529 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1533 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1536 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1538 if (m_windowStyle
& wxRAISED_BORDER
)
1540 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1542 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1544 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1548 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1552 /* we always allow a window to get the focus as long as it
1553 doesn't have any children. */
1554 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1556 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1557 m_acceptsFocus
= FALSE
;
1561 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1562 m_acceptsFocus
= TRUE
;
1565 /* grab the actual focus */
1566 gtk_widget_grab_focus( m_wxwindow
);
1568 #if (GTK_MINOR_VERSION == 0)
1569 // shut the viewport up
1570 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1571 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1574 // I _really_ don't want scrollbars in the beginning
1575 m_vAdjust
->lower
= 0.0;
1576 m_vAdjust
->upper
= 1.0;
1577 m_vAdjust
->value
= 0.0;
1578 m_vAdjust
->step_increment
= 1.0;
1579 m_vAdjust
->page_increment
= 1.0;
1580 m_vAdjust
->page_size
= 5.0;
1581 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1582 m_hAdjust
->lower
= 0.0;
1583 m_hAdjust
->upper
= 1.0;
1584 m_hAdjust
->value
= 0.0;
1585 m_hAdjust
->step_increment
= 1.0;
1586 m_hAdjust
->page_increment
= 1.0;
1587 m_hAdjust
->page_size
= 5.0;
1588 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1590 // these handlers block mouse events to any window during scrolling
1591 // such as motion events and prevent GTK and wxWindows from fighting
1592 // over where the slider should be
1594 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1595 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1597 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1598 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1600 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1601 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1603 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1604 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1606 // these handlers get notified when screen updates are required either when
1607 // scrolling or when the window size (and therefore scrollbar configuration)
1610 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1611 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1612 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1613 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1615 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1616 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1617 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1618 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1620 if (m_parent
) m_parent
->AddChild( this );
1622 (m_parent
->m_insertCallback
)( m_parent
, this );
1631 wxWindow::~wxWindow()
1635 #if wxUSE_DRAG_AND_DROP
1638 delete m_dropTarget
;
1639 m_dropTarget
= (wxDropTarget
*) NULL
;
1647 m_toolTip
= (wxToolTip
*) NULL
;
1649 #endif // wxUSE_TOOLTIPS
1651 if (m_widget
) Show( FALSE
);
1655 if (m_parent
) m_parent
->RemoveChild( this );
1657 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1659 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1661 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1663 if (m_widget
) gtk_widget_destroy( m_widget
);
1665 DeleteRelatedConstraints();
1668 /* This removes any dangling pointers to this window
1669 * in other windows' constraintsInvolvedIn lists. */
1670 UnsetConstraints(m_constraints
);
1671 delete m_constraints
;
1672 m_constraints
= (wxLayoutConstraints
*) NULL
;
1677 delete m_windowSizer
;
1678 m_windowSizer
= (wxSizer
*) NULL
;
1680 /* If this is a child of a sizer, remove self from parent */
1681 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1683 /* Just in case the window has been Closed, but
1684 * we're then deleting immediately: don't leave
1685 * dangling pointers. */
1686 wxPendingDelete
.DeleteObject(this);
1688 /* Just in case we've loaded a top-level window via
1689 * wxWindow::LoadNativeDialog but we weren't a dialog
1691 wxTopLevelWindows
.DeleteObject(this);
1693 if (m_windowValidator
) delete m_windowValidator
;
1695 if (m_clientObject
) delete m_clientObject
;
1698 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1699 const wxPoint
&pos
, const wxSize
&size
,
1700 long style
, const wxString
&name
)
1702 wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") );
1704 m_widget
= (GtkWidget
*) NULL
;
1705 m_wxwindow
= (GtkWidget
*) NULL
;
1708 m_children
.DeleteContents( FALSE
);
1711 if (m_width
== -1) m_width
= 20;
1713 if (m_height
== -1) m_height
= 20;
1718 if (!m_needParent
) /* some reasonable defaults */
1722 m_x
= (gdk_screen_width () - m_width
) / 2;
1723 if (m_x
< 10) m_x
= 10;
1727 m_y
= (gdk_screen_height () - m_height
) / 2;
1728 if (m_y
< 10) m_y
= 10;
1739 m_eventHandler
= this;
1741 m_windowId
= id
== -1 ? wxNewId() : id
;
1745 m_cursor
= *wxSTANDARD_CURSOR
;
1746 m_font
= *wxSWISS_FONT
;
1747 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1748 m_foregroundColour
= *wxBLACK
;
1749 m_windowStyle
= style
;
1750 m_windowName
= name
;
1752 m_constraints
= (wxLayoutConstraints
*) NULL
;
1753 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1754 m_windowSizer
= (wxSizer
*) NULL
;
1755 m_sizerParent
= (wxWindow
*) NULL
;
1756 m_autoLayout
= FALSE
;
1758 m_hasScrolling
= FALSE
;
1759 m_isScrolling
= FALSE
;
1760 m_hAdjust
= (GtkAdjustment
*) NULL
;
1761 m_vAdjust
= (GtkAdjustment
*) NULL
;
1762 m_oldHorizontalPos
= 0.0;
1763 m_oldVerticalPos
= 0.0;
1768 #if wxUSE_DRAG_AND_DROP
1769 m_dropTarget
= (wxDropTarget
*) NULL
;
1772 m_windowValidator
= (wxValidator
*) NULL
;
1773 m_scrollGC
= (GdkGC
*) NULL
;
1774 m_widgetStyle
= (GtkStyle
*) NULL
;
1776 m_clientObject
= (wxClientData
*)NULL
;
1777 m_clientData
= NULL
;
1779 m_isStaticBox
= FALSE
;
1782 m_toolTip
= (wxToolTip
*) NULL
;
1783 #endif // wxUSE_TOOLTIPS
1786 void wxWindow::PostCreation()
1788 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1792 /* these get reported to wxWindows -> wxPaintEvent */
1793 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1794 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1796 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1797 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1799 #if (GTK_MINOR_VERSION > 0)
1800 /* these are called when the "sunken" or "raised" borders are drawn */
1801 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1802 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1804 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1805 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1809 GtkWidget
*connect_widget
= GetConnectWidget();
1811 ConnectWidget( connect_widget
);
1813 /* we cannot set colours, fonts and cursors before the widget has
1814 been realized, so we do this directly after realization */
1815 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1816 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1821 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1823 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1824 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1826 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1827 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1829 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1830 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1832 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1833 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1835 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1836 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1838 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1839 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1841 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1842 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1844 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1845 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1847 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1848 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1851 bool wxWindow::HasVMT()
1856 bool wxWindow::Close( bool force
)
1858 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1860 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1861 event
.SetEventObject(this);
1862 event
.SetCanVeto(!force
);
1864 /* return FALSE if window wasn't closed because the application vetoed the
1866 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1869 bool wxWindow::Destroy()
1871 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1878 bool wxWindow::DestroyChildren()
1881 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1884 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1887 if (m_children
.Member(child
)) delete node
;
1893 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1895 // are we to set fonts here ?
1898 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1900 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1901 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1903 if (m_resizing
) return; /* I don't like recursions */
1906 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1908 /* don't set the size for children of wxNotebook, just take the values. */
1916 int old_width
= m_width
;
1917 int old_height
= m_height
;
1919 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1921 if (x
!= -1) m_x
= x
;
1922 if (y
!= -1) m_y
= y
;
1923 if (width
!= -1) m_width
= width
;
1924 if (height
!= -1) m_height
= height
;
1934 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1936 if (width
== -1) m_width
= 80;
1939 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1941 if (height
== -1) m_height
= 26;
1944 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1945 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1946 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1947 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1949 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1951 /* the default button has a border around it */
1954 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
-border
, m_y
-border
);
1956 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1960 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1962 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1963 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1969 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1970 event
.SetEventObject( this );
1971 GetEventHandler()->ProcessEvent( event
);
1976 void wxWindow::OnInternalIdle()
1981 void wxWindow::GetSize( int *width
, int *height
) const
1983 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1985 if (width
) (*width
) = m_width
;
1986 if (height
) (*height
) = m_height
;
1989 void wxWindow::DoSetClientSize( int width
, int height
)
1991 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1995 SetSize( width
, height
);
2002 if (!m_hasScrolling
)
2004 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2006 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2007 (m_windowStyle
& wxSUNKEN_BORDER
))
2009 dw
+= 2 * window_class
->xthickness
;
2010 dh
+= 2 * window_class
->ythickness
;
2015 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2016 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2018 #if (GTK_MINOR_VERSION == 0)
2019 GtkWidget
*viewport
= scroll_window
->viewport
;
2020 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2022 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2023 (m_windowStyle
& wxSUNKEN_BORDER
))
2025 dw
+= 2 * viewport_class
->xthickness
;
2026 dh
+= 2 * viewport_class
->ythickness
;
2031 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2032 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2034 we use this instead: range.slider_width = 11 + 2*2pts edge
2037 if (scroll_window
->vscrollbar_visible
)
2039 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2040 dw
+= scroll_class
->scrollbar_spacing
;
2043 if (scroll_window
->hscrollbar_visible
)
2045 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2046 dw
+= scroll_class
->scrollbar_spacing
;
2050 SetSize( width
+dw
, height
+dh
);
2054 void wxWindow::GetClientSize( int *width
, int *height
) const
2056 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2060 if (width
) (*width
) = m_width
;
2061 if (height
) (*height
) = m_height
;
2068 if (!m_hasScrolling
)
2070 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2072 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2073 (m_windowStyle
& wxSUNKEN_BORDER
))
2075 dw
+= 2 * window_class
->xthickness
;
2076 dh
+= 2 * window_class
->ythickness
;
2081 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2082 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2084 #if (GTK_MINOR_VERSION == 0)
2085 GtkWidget
*viewport
= scroll_window
->viewport
;
2086 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2088 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2089 (m_windowStyle
& wxSUNKEN_BORDER
))
2091 dw
+= 2 * viewport_class
->xthickness
;
2092 dh
+= 2 * viewport_class
->ythickness
;
2096 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2097 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2099 we use this instead: range.slider_width = 11 + 2*2pts edge
2102 if (scroll_window
->vscrollbar_visible
)
2104 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2105 dw
+= scroll_class
->scrollbar_spacing
;
2108 if (scroll_window
->hscrollbar_visible
)
2110 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2111 dh
+= scroll_class
->scrollbar_spacing
;
2115 if (width
) (*width
) = m_width
- dw
;
2116 if (height
) (*height
) = m_height
- dh
;
2120 void wxWindow::GetPosition( int *x
, int *y
) const
2122 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2128 void wxWindow::ClientToScreen( int *x
, int *y
)
2130 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2132 if (!m_widget
->window
) return;
2134 GdkWindow
*source
= (GdkWindow
*) NULL
;
2136 source
= m_wxwindow
->window
;
2138 source
= m_widget
->window
;
2142 gdk_window_get_origin( source
, &org_x
, &org_y
);
2146 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2148 org_x
+= m_widget
->allocation
.x
;
2149 org_y
+= m_widget
->allocation
.y
;
2157 void wxWindow::ScreenToClient( int *x
, int *y
)
2159 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2161 if (!m_widget
->window
) return;
2163 GdkWindow
*source
= (GdkWindow
*) NULL
;
2165 source
= m_wxwindow
->window
;
2167 source
= m_widget
->window
;
2171 gdk_window_get_origin( source
, &org_x
, &org_y
);
2175 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2177 org_x
+= m_widget
->allocation
.x
;
2178 org_y
+= m_widget
->allocation
.y
;
2186 void wxWindow::Centre( int direction
)
2188 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2197 m_parent
->GetSize( &p_w
, &p_h
);
2198 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2199 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2203 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2204 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2210 void wxWindow::Fit()
2212 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2216 wxNode
*node
= m_children
.First();
2219 wxWindow
*win
= (wxWindow
*)node
->Data();
2221 win
->GetPosition(&wx
, &wy
);
2222 win
->GetSize(&ww
, &wh
);
2223 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2224 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2226 node
= node
->Next();
2229 SetClientSize(maxX
+ 7, maxY
+ 14);
2232 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2234 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2242 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2244 // if (GetAutoLayout()) Layout();
2247 bool wxWindow::Show( bool show
)
2249 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2251 if (show
== m_isShown
) return TRUE
;
2254 gtk_widget_show( m_widget
);
2256 gtk_widget_hide( m_widget
);
2263 void wxWindow::Enable( bool enable
)
2265 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2267 m_isEnabled
= enable
;
2269 gtk_widget_set_sensitive( m_widget
, enable
);
2270 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2273 int wxWindow::GetCharHeight() const
2275 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2277 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2279 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2281 return font
->ascent
+ font
->descent
;
2284 int wxWindow::GetCharWidth() const
2286 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2288 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2290 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2292 return gdk_string_width( font
, "H" );
2295 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2296 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2298 wxFont fontToUse
= m_font
;
2299 if (theFont
) fontToUse
= *theFont
;
2301 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2303 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2304 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2305 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2306 if (descent
) (*descent
) = font
->descent
;
2307 if (externalLeading
) (*externalLeading
) = 0; // ??
2310 void wxWindow::MakeModal( bool modal
)
2314 // Disable all other windows
2315 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2317 wxNode
*node
= wxTopLevelWindows
.First();
2320 wxWindow
*win
= (wxWindow
*)node
->Data();
2321 if (win
!= this) win
->Enable(!modal
);
2323 node
= node
->Next();
2328 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2330 event
.SetEventType( wxEVT_CHAR
);
2332 if (!GetEventHandler()->ProcessEvent( event
))
2338 void wxWindow::SetFocus()
2340 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2342 GtkWidget
*connect_widget
= GetConnectWidget();
2345 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2347 gtk_widget_grab_focus (connect_widget
);
2349 else if (GTK_IS_CONTAINER(connect_widget
))
2351 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2359 wxWindow
*wxWindow::FindFocus()
2361 return g_focusWindow
;
2364 bool wxWindow::AcceptsFocus() const
2366 return IsEnabled() && IsShown() && m_acceptsFocus
;
2369 void wxWindow::AddChild( wxWindow
*child
)
2371 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2372 wxCHECK_RET( (child
!= NULL
), _T("invalid child") );
2374 m_children
.Append( child
);
2377 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2379 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2381 wxWindow
*oldParent
= GetParent();
2383 if (oldParent
) oldParent
->RemoveChild( this );
2385 gtk_widget_unparent( m_widget
);
2389 newParent
->AddChild( this );
2390 (newParent
->m_insertCallback
)( newParent
, this );
2396 void wxWindow::RemoveChild( wxWindow
*child
)
2398 m_children
.DeleteObject( child
);
2399 child
->m_parent
= (wxWindow
*) NULL
;
2402 void wxWindow::SetReturnCode( int retCode
)
2404 m_retCode
= retCode
;
2407 int wxWindow::GetReturnCode()
2412 void wxWindow::Raise()
2414 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2416 if (!m_widget
->window
) return;
2418 if (m_widget
) gdk_window_raise( m_widget
->window
);
2421 void wxWindow::Lower()
2423 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2425 if (!m_widget
->window
) return;
2427 if (m_widget
) gdk_window_lower( m_widget
->window
);
2430 wxEvtHandler
*wxWindow::GetEventHandler() const
2432 return m_eventHandler
;
2435 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2437 m_eventHandler
= handler
;
2440 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2442 handler
->SetNextHandler(GetEventHandler());
2443 SetEventHandler(handler
);
2446 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2448 if (GetEventHandler())
2450 wxEvtHandler
*handlerA
= GetEventHandler();
2451 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2452 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2453 SetEventHandler(handlerB
);
2457 return (wxEvtHandler
*) NULL
;
2463 return (wxEvtHandler
*) NULL
;
2466 wxValidator
*wxWindow::GetValidator()
2468 return m_windowValidator
;
2471 void wxWindow::SetValidator( const wxValidator
& validator
)
2473 if (m_windowValidator
) delete m_windowValidator
;
2474 m_windowValidator
= validator
.Clone();
2475 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2478 void wxWindow::SetClientObject( wxClientData
*data
)
2480 if (m_clientObject
) delete m_clientObject
;
2481 m_clientObject
= data
;
2484 wxClientData
*wxWindow::GetClientObject()
2486 return m_clientObject
;
2489 void wxWindow::SetClientData( void *data
)
2491 m_clientData
= data
;
2494 void *wxWindow::GetClientData()
2496 return m_clientData
;
2499 bool wxWindow::IsBeingDeleted()
2504 void wxWindow::SetId( wxWindowID id
)
2509 wxWindowID
wxWindow::GetId() const
2514 void wxWindow::SetCursor( const wxCursor
&cursor
)
2516 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2520 if (cursor
== m_cursor
) return;
2525 m_cursor
= *wxSTANDARD_CURSOR
;
2528 if (!m_widget
->window
) return;
2530 gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() );
2532 if ((m_wxwindow
) && (m_wxwindow
->window
))
2533 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() );
2536 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2541 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2543 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2545 if (!m_widget
->window
) return;
2547 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2551 gdk_window_clear_area( m_wxwindow
->window
,
2553 rect
->width
, rect
->height
);
2557 gdk_window_clear( m_wxwindow
->window
);
2564 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2566 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2570 GdkRectangle gdk_rect
;
2571 gdk_rect
.x
= rect
->x
;
2572 gdk_rect
.y
= rect
->y
;
2573 gdk_rect
.width
= rect
->width
;
2574 gdk_rect
.height
= rect
->height
;
2577 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2579 gtk_widget_draw( m_widget
, &gdk_rect
);
2583 wxRegion
wxWindow::GetUpdateRegion() const
2585 return m_updateRegion
;
2588 bool wxWindow::IsExposed( int x
, int y
) const
2590 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2593 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2595 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2598 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2600 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2603 bool wxWindow::IsExposed( const wxRect
& rect
) const
2605 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2608 void wxWindow::Clear()
2610 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2612 if (!m_widget
->window
) return;
2614 if (m_wxwindow
&& m_wxwindow
->window
)
2616 gdk_window_clear( m_wxwindow
->window
);
2621 void wxWindow::SetToolTip( const wxString
&tip
)
2625 m_toolTip
->SetTip( tip
);
2629 SetToolTip( new wxToolTip( tip
) );
2632 // setting empty tooltip text does not remove the tooltip any more for
2633 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2636 void wxWindow::SetToolTip( wxToolTip
*tip
)
2640 m_toolTip
->SetTip( (char*) NULL
);
2647 m_toolTip
->Apply( this );
2650 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2652 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2654 #endif // wxUSE_TOOLTIPS
2656 wxColour
wxWindow::GetBackgroundColour() const
2658 return m_backgroundColour
;
2661 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2663 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2665 if (m_backgroundColour
== colour
) return;
2667 m_backgroundColour
= colour
;
2668 if (!m_backgroundColour
.Ok()) return;
2670 GtkWidget
*connect_widget
= GetConnectWidget();
2671 if (!connect_widget
->window
) return;
2673 if (m_wxwindow
&& m_wxwindow
->window
)
2675 /* wxMSW doesn't clear the window here. I don't do that
2676 either to provide compatibility. call Clear() to do
2679 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2680 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2683 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2685 if (sysbg
.Red() == colour
.Red() &&
2686 sysbg
.Green() == colour
.Green() &&
2687 sysbg
.Blue() == colour
.Blue())
2689 m_backgroundColour
= wxNullColour
;
2691 m_backgroundColour
= sysbg
;
2699 wxColour
wxWindow::GetForegroundColour() const
2701 return m_foregroundColour
;
2704 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2706 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2708 if (m_foregroundColour
== colour
) return;
2710 m_foregroundColour
= colour
;
2711 if (!m_foregroundColour
.Ok()) return;
2713 if (!m_widget
->window
) return;
2715 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2716 if (sysbg
.Red() == colour
.Red() &&
2717 sysbg
.Green() == colour
.Green() &&
2718 sysbg
.Blue() == colour
.Blue())
2720 m_backgroundColour
= wxNullColour
;
2722 m_backgroundColour
= sysbg
;
2730 GtkStyle
*wxWindow::GetWidgetStyle()
2732 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2736 gtk_widget_get_style( m_widget
) );
2738 return m_widgetStyle
;
2741 void wxWindow::SetWidgetStyle()
2743 GtkStyle
*style
= GetWidgetStyle();
2745 gdk_font_unref( style
->font
);
2746 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2748 if (m_foregroundColour
.Ok())
2750 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2751 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2752 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2753 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2756 if (m_backgroundColour
.Ok())
2758 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2759 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2760 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2761 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2762 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2763 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2764 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2765 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2766 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2770 void wxWindow::ApplyWidgetStyle()
2774 bool wxWindow::Validate()
2776 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2778 wxNode
*node
= m_children
.First();
2781 wxWindow
*child
= (wxWindow
*)node
->Data();
2782 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2786 node
= node
->Next();
2791 bool wxWindow::TransferDataToWindow()
2793 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2795 wxNode
*node
= m_children
.First();
2798 wxWindow
*child
= (wxWindow
*)node
->Data();
2799 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2800 !child
->GetValidator()->TransferToWindow() )
2802 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2805 node
= node
->Next();
2810 bool wxWindow::TransferDataFromWindow()
2812 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2814 wxNode
*node
= m_children
.First();
2817 wxWindow
*child
= (wxWindow
*)node
->Data();
2818 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2822 node
= node
->Next();
2827 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2829 m_acceleratorTable
= accel
;
2832 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2834 TransferDataToWindow();
2837 void wxWindow::InitDialog()
2839 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2841 wxInitDialogEvent
event(GetId());
2842 event
.SetEventObject( this );
2843 GetEventHandler()->ProcessEvent(event
);
2846 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2848 menu
->SetInvokingWindow( win
);
2849 wxNode
*node
= menu
->GetItems().First();
2852 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2853 if (menuitem
->IsSubMenu())
2855 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2857 node
= node
->Next();
2861 static gint gs_pop_x
= 0;
2862 static gint gs_pop_y
= 0;
2864 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2866 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2871 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2873 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2875 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2877 SetInvokingWindow( menu
, this );
2885 GTK_MENU(menu
->m_menu
),
2886 (GtkWidget
*) NULL
, // parent menu shell
2887 (GtkWidget
*) NULL
, // parent menu item
2888 (GtkMenuPositionFunc
) pop_pos_callback
,
2889 (gpointer
) this, // client data
2890 0, // button used to activate it
2891 0 //gs_timeLastClick // the time of activation
2896 #if wxUSE_DRAG_AND_DROP
2898 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2900 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2902 GtkWidget
*dnd_widget
= GetConnectWidget();
2904 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2906 if (m_dropTarget
) delete m_dropTarget
;
2907 m_dropTarget
= dropTarget
;
2909 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2912 wxDropTarget
*wxWindow::GetDropTarget() const
2914 return m_dropTarget
;
2919 GtkWidget
* wxWindow::GetConnectWidget()
2921 GtkWidget
*connect_widget
= m_widget
;
2922 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2924 return connect_widget
;
2927 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2929 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2930 return (window
== m_widget
->window
);
2933 void wxWindow::SetFont( const wxFont
&font
)
2935 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2937 if (m_font
== font
) return;
2939 if (((wxFont
*)&font
)->Ok())
2942 m_font
= *wxSWISS_FONT
;
2944 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2945 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2946 sysbg
.Green() == m_backgroundColour
.Green() &&
2947 sysbg
.Blue() == m_backgroundColour
.Blue())
2949 m_backgroundColour
= wxNullColour
;
2951 m_backgroundColour
= sysbg
;
2959 void wxWindow::SetWindowStyleFlag( long flag
)
2961 m_windowStyle
= flag
;
2964 long wxWindow::GetWindowStyleFlag() const
2966 return m_windowStyle
;
2969 void wxWindow::CaptureMouse()
2971 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2973 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2975 if (!m_widget
->window
) return;
2977 GtkWidget
*connect_widget
= GetConnectWidget();
2978 gtk_grab_add( connect_widget
);
2979 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2981 (GDK_BUTTON_PRESS_MASK
|
2982 GDK_BUTTON_RELEASE_MASK
|
2983 GDK_POINTER_MOTION_MASK
),
2990 void wxWindow::ReleaseMouse()
2992 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2994 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2996 if (!m_widget
->window
) return;
2998 GtkWidget
*connect_widget
= GetConnectWidget();
2999 gtk_grab_remove( connect_widget
);
3000 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3001 g_capturing
= FALSE
;
3004 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
3008 wxString
wxWindow::GetTitle() const
3010 return (wxString
&)m_windowName
;
3013 wxString
wxWindow::GetLabel() const
3018 void wxWindow::SetName( const wxString
&name
)
3020 m_windowName
= name
;
3023 wxString
wxWindow::GetName() const
3025 return (wxString
&)m_windowName
;
3028 bool wxWindow::IsShown() const
3033 bool wxWindow::IsRetained()
3038 wxWindow
*wxWindow::FindWindow( long id
)
3040 if (id
== m_windowId
) return this;
3041 wxNode
*node
= m_children
.First();
3044 wxWindow
*child
= (wxWindow
*)node
->Data();
3045 wxWindow
*res
= child
->FindWindow( id
);
3046 if (res
) return res
;
3047 node
= node
->Next();
3049 return (wxWindow
*) NULL
;
3052 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
3054 if (name
== m_windowName
) return this;
3055 wxNode
*node
= m_children
.First();
3058 wxWindow
*child
= (wxWindow
*)node
->Data();
3059 wxWindow
*res
= child
->FindWindow( name
);
3060 if (res
) return res
;
3061 node
= node
->Next();
3063 return (wxWindow
*) NULL
;
3066 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3067 int range
, bool refresh
)
3069 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3071 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3073 m_hasScrolling
= TRUE
;
3075 if (orient
== wxHORIZONTAL
)
3077 float fpos
= (float)pos
;
3078 float frange
= (float)range
;
3079 float fthumb
= (float)thumbVisible
;
3080 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3081 if (fpos
< 0.0) fpos
= 0.0;
3083 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3084 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3086 SetScrollPos( orient
, pos
, refresh
);
3090 m_oldHorizontalPos
= fpos
;
3092 m_hAdjust
->lower
= 0.0;
3093 m_hAdjust
->upper
= frange
;
3094 m_hAdjust
->value
= fpos
;
3095 m_hAdjust
->step_increment
= 1.0;
3096 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3097 m_hAdjust
->page_size
= fthumb
;
3101 float fpos
= (float)pos
;
3102 float frange
= (float)range
;
3103 float fthumb
= (float)thumbVisible
;
3104 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3105 if (fpos
< 0.0) fpos
= 0.0;
3107 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3108 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3110 SetScrollPos( orient
, pos
, refresh
);
3114 m_oldVerticalPos
= fpos
;
3116 m_vAdjust
->lower
= 0.0;
3117 m_vAdjust
->upper
= frange
;
3118 m_vAdjust
->value
= fpos
;
3119 m_vAdjust
->step_increment
= 1.0;
3120 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3121 m_vAdjust
->page_size
= fthumb
;
3126 if (orient
== wxHORIZONTAL
)
3127 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3129 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3131 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3135 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3137 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3139 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3141 if (orient
== wxHORIZONTAL
)
3143 float fpos
= (float)pos
;
3144 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3145 if (fpos
< 0.0) fpos
= 0.0;
3146 m_oldHorizontalPos
= fpos
;
3148 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3149 m_hAdjust
->value
= fpos
;
3153 float fpos
= (float)pos
;
3154 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3155 if (fpos
< 0.0) fpos
= 0.0;
3156 m_oldVerticalPos
= fpos
;
3158 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3159 m_vAdjust
->value
= fpos
;
3164 if (m_wxwindow
->window
)
3166 if (orient
== wxHORIZONTAL
)
3167 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3169 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3174 int wxWindow::GetScrollThumb( int orient
) const
3176 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3178 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3180 if (orient
== wxHORIZONTAL
)
3181 return (int)(m_hAdjust
->page_size
+0.5);
3183 return (int)(m_vAdjust
->page_size
+0.5);
3186 int wxWindow::GetScrollPos( int orient
) const
3188 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3190 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3192 if (orient
== wxHORIZONTAL
)
3193 return (int)(m_hAdjust
->value
+0.5);
3195 return (int)(m_vAdjust
->value
+0.5);
3198 int wxWindow::GetScrollRange( int orient
) const
3200 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3202 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3204 if (orient
== wxHORIZONTAL
)
3205 return (int)(m_hAdjust
->upper
+0.5);
3207 return (int)(m_vAdjust
->upper
+0.5);
3210 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3212 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3214 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3216 wxNode
*node
= m_children
.First();
3219 wxWindow
*child
= (wxWindow
*) node
->Data();
3220 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3221 node
= node
->Next();
3226 GetClientSize( &cw
, &ch
);
3228 int w
= cw
- abs(dx
);
3229 int h
= ch
- abs(dy
);
3230 if ((h
< 0) || (w
< 0))
3237 if (dx
< 0) s_x
= -dx
;
3238 if (dy
< 0) s_y
= -dy
;
3241 if (dx
> 0) d_x
= dx
;
3242 if (dy
> 0) d_y
= dy
;
3246 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3247 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3250 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3251 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3254 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3255 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3256 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3257 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3259 Refresh( TRUE
, &rect
);
3262 //-------------------------------------------------------------------------------------
3264 //-------------------------------------------------------------------------------------
3266 wxLayoutConstraints
*wxWindow::GetConstraints() const
3268 return m_constraints
;
3271 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3275 UnsetConstraints(m_constraints
);
3276 delete m_constraints
;
3278 m_constraints
= constraints
;
3281 // Make sure other windows know they're part of a 'meaningful relationship'
3282 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3283 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3284 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3285 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3286 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3287 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3288 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3289 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3290 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3291 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3292 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3293 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3294 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3295 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3296 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3297 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3303 void wxWindow::SetAutoLayout( bool autoLayout
)
3305 m_autoLayout
= autoLayout
;
3308 bool wxWindow::GetAutoLayout() const
3310 return m_autoLayout
;
3313 wxSizer
*wxWindow::GetSizer() const
3315 return m_windowSizer
;
3318 void wxWindow::SetSizerParent( wxWindow
*win
)
3320 m_sizerParent
= win
;
3323 wxWindow
*wxWindow::GetSizerParent() const
3325 return m_sizerParent
;
3328 // This removes any dangling pointers to this window
3329 // in other windows' constraintsInvolvedIn lists.
3330 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3334 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3335 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3336 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3337 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3338 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3339 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3340 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3341 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3342 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3343 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3344 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3345 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3346 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3347 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3348 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3349 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3353 // Back-pointer to other windows we're involved with, so if we delete
3354 // this window, we must delete any constraints we're involved with.
3355 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3357 if (!m_constraintsInvolvedIn
)
3358 m_constraintsInvolvedIn
= new wxList
;
3359 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3360 m_constraintsInvolvedIn
->Append(otherWin
);
3363 // REMOVE back-pointer to other windows we're involved with.
3364 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3366 if (m_constraintsInvolvedIn
)
3367 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3370 // Reset any constraints that mention this window
3371 void wxWindow::DeleteRelatedConstraints()
3373 if (m_constraintsInvolvedIn
)
3375 wxNode
*node
= m_constraintsInvolvedIn
->First();
3378 wxWindow
*win
= (wxWindow
*)node
->Data();
3379 wxNode
*next
= node
->Next();
3380 wxLayoutConstraints
*constr
= win
->GetConstraints();
3382 // Reset any constraints involving this window
3385 constr
->left
.ResetIfWin((wxWindow
*)this);
3386 constr
->top
.ResetIfWin((wxWindow
*)this);
3387 constr
->right
.ResetIfWin((wxWindow
*)this);
3388 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3389 constr
->width
.ResetIfWin((wxWindow
*)this);
3390 constr
->height
.ResetIfWin((wxWindow
*)this);
3391 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3392 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3397 delete m_constraintsInvolvedIn
;
3398 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3402 void wxWindow::SetSizer(wxSizer
*sizer
)
3404 m_windowSizer
= sizer
;
3406 sizer
->SetSizerParent((wxWindow
*)this);
3413 bool wxWindow::Layout()
3415 if (GetConstraints())
3418 GetClientSize(&w
, &h
);
3419 GetConstraints()->width
.SetValue(w
);
3420 GetConstraints()->height
.SetValue(h
);
3423 // If top level (one sizer), evaluate the sizer's constraints.
3427 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3428 GetSizer()->LayoutPhase1(&noChanges
);
3429 GetSizer()->LayoutPhase2(&noChanges
);
3430 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3435 // Otherwise, evaluate child constraints
3436 ResetConstraints(); // Mark all constraints as unevaluated
3437 DoPhase(1); // Just one phase need if no sizers involved
3439 SetConstraintSizes(); // Recursively set the real window sizes
3445 // Do a phase of evaluating constraints:
3446 // the default behaviour. wxSizers may do a similar
3447 // thing, but also impose their own 'constraints'
3448 // and order the evaluation differently.
3449 bool wxWindow::LayoutPhase1(int *noChanges
)
3451 wxLayoutConstraints
*constr
= GetConstraints();
3454 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3460 bool wxWindow::LayoutPhase2(int *noChanges
)
3470 // Do a phase of evaluating child constraints
3471 bool wxWindow::DoPhase(int phase
)
3473 int noIterations
= 0;
3474 int maxIterations
= 500;
3478 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3482 wxNode
*node
= m_children
.First();
3485 wxWindow
*child
= (wxWindow
*)node
->Data();
3486 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3488 wxLayoutConstraints
*constr
= child
->GetConstraints();
3491 if (succeeded
.Member(child
))
3496 int tempNoChanges
= 0;
3497 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3498 noChanges
+= tempNoChanges
;
3501 succeeded
.Append(child
);
3506 node
= node
->Next();
3513 void wxWindow::ResetConstraints()
3515 wxLayoutConstraints
*constr
= GetConstraints();
3518 constr
->left
.SetDone(FALSE
);
3519 constr
->top
.SetDone(FALSE
);
3520 constr
->right
.SetDone(FALSE
);
3521 constr
->bottom
.SetDone(FALSE
);
3522 constr
->width
.SetDone(FALSE
);
3523 constr
->height
.SetDone(FALSE
);
3524 constr
->centreX
.SetDone(FALSE
);
3525 constr
->centreY
.SetDone(FALSE
);
3527 wxNode
*node
= m_children
.First();
3530 wxWindow
*win
= (wxWindow
*)node
->Data();
3531 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3532 win
->ResetConstraints();
3533 node
= node
->Next();
3537 // Need to distinguish between setting the 'fake' size for
3538 // windows and sizers, and setting the real values.
3539 void wxWindow::SetConstraintSizes(bool recurse
)
3541 wxLayoutConstraints
*constr
= GetConstraints();
3542 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3543 constr
->width
.GetDone() && constr
->height
.GetDone())
3545 int x
= constr
->left
.GetValue();
3546 int y
= constr
->top
.GetValue();
3547 int w
= constr
->width
.GetValue();
3548 int h
= constr
->height
.GetValue();
3550 // If we don't want to resize this window, just move it...
3551 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3552 (constr
->height
.GetRelationship() != wxAsIs
))
3554 // Calls Layout() recursively. AAAGH. How can we stop that.
3555 // Simply take Layout() out of non-top level OnSizes.
3556 SizerSetSize(x
, y
, w
, h
);
3565 wxChar
*windowClass
= this->GetClassInfo()->GetClassName();
3568 if (GetName() == _T(""))
3569 winName
= _T("unnamed");
3571 winName
= GetName();
3572 wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"),
3573 (const wxChar
*)windowClass
,
3574 (const wxChar
*)winName
);
3575 if (!constr
->left
.GetDone()) wxLogDebug( _T(" unsatisfied 'left' constraint.\n") );
3576 if (!constr
->right
.GetDone()) wxLogDebug( _T(" unsatisfied 'right' constraint.\n") );
3577 if (!constr
->width
.GetDone()) wxLogDebug( _T(" unsatisfied 'width' constraint.\n") );
3578 if (!constr
->height
.GetDone()) wxLogDebug( _T(" unsatisfied 'height' constraint.\n") );
3579 wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") );
3584 wxNode
*node
= m_children
.First();
3587 wxWindow
*win
= (wxWindow
*)node
->Data();
3588 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3589 win
->SetConstraintSizes();
3590 node
= node
->Next();
3595 // This assumes that all sizers are 'on' the same
3596 // window, i.e. the parent of this window.
3597 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3599 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3600 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3604 m_sizerParent
->GetPosition(&xp
, &yp
);
3605 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3610 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3614 TransformSizerToActual(&xx
, &yy
);
3615 SetSize(xx
, yy
, w
, h
);
3618 void wxWindow::SizerMove(int x
, int y
)
3622 TransformSizerToActual(&xx
, &yy
);
3626 // Only set the size/position of the constraint (if any)
3627 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3629 wxLayoutConstraints
*constr
= GetConstraints();
3634 constr
->left
.SetValue(x
);
3635 constr
->left
.SetDone(TRUE
);
3639 constr
->top
.SetValue(y
);
3640 constr
->top
.SetDone(TRUE
);
3644 constr
->width
.SetValue(w
);
3645 constr
->width
.SetDone(TRUE
);
3649 constr
->height
.SetValue(h
);
3650 constr
->height
.SetDone(TRUE
);
3655 void wxWindow::MoveConstraint(int x
, int y
)
3657 wxLayoutConstraints
*constr
= GetConstraints();
3662 constr
->left
.SetValue(x
);
3663 constr
->left
.SetDone(TRUE
);
3667 constr
->top
.SetValue(y
);
3668 constr
->top
.SetDone(TRUE
);
3673 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3675 wxLayoutConstraints
*constr
= GetConstraints();
3678 *w
= constr
->width
.GetValue();
3679 *h
= constr
->height
.GetValue();
3685 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3687 wxLayoutConstraints
*constr
= GetConstraints();
3690 *w
= constr
->width
.GetValue();
3691 *h
= constr
->height
.GetValue();
3694 GetClientSize(w
, h
);
3697 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3699 wxLayoutConstraints
*constr
= GetConstraints();
3702 *x
= constr
->left
.GetValue();
3703 *y
= constr
->top
.GetValue();