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 //-----------------------------------------------------------------------------
130 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
131 GdkEvent
*WXUNUSED(event
),
134 // to enable logging of the focus events replace 0 with 1
136 static bool s_done
= FALSE
;
139 wxLog::AddTraceMask("focus");
143 wxLogTrace(_T("FOCUS NOW AT: %s"), name
);
148 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
154 wxChar
*s
= new wxChar
[tmp
.Length()+1];
158 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
159 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
164 //-----------------------------------------------------------------------------
166 //-----------------------------------------------------------------------------
168 extern wxList wxPendingDelete
;
169 extern bool g_blockEventsOnDrag
;
170 extern bool g_blockEventsOnScroll
;
171 extern bool g_isIdle
;
172 static bool g_capturing
= FALSE
;
173 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
175 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
176 the last click here */
177 static guint32 gs_timeLastClick
= 0;
179 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
183 extern void wxapp_install_idle_handler();
184 extern bool g_isIdle
;
186 #if (GTK_MINOR_VERSION > 0)
188 //-----------------------------------------------------------------------------
189 // local code (see below)
190 //-----------------------------------------------------------------------------
192 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
194 if (!win
->HasVMT()) return;
199 if (win
->m_hasScrolling
)
201 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
202 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
205 GtkWidget *hscrollbar = scroll_window->hscrollbar;
206 GtkWidget *vscrollbar = scroll_window->vscrollbar;
208 we use this instead: range.slider_width = 11 + 2*2pts edge
211 if (scroll_window
->vscrollbar_visible
)
213 dw
+= 15; /* dw += vscrollbar->allocation.width; */
214 dw
+= scroll_class
->scrollbar_spacing
;
217 if (scroll_window
->hscrollbar_visible
)
219 dh
+= 15; /* dh += hscrollbar->allocation.height; */
220 dw
+= scroll_class
->scrollbar_spacing
;
226 if (GTK_WIDGET_NO_WINDOW (widget
))
228 dx
+= widget
->allocation
.x
;
229 dy
+= widget
->allocation
.y
;
232 if (win
->m_windowStyle
& wxRAISED_BORDER
)
234 gtk_draw_shadow( widget
->style
,
239 win
->m_width
-dw
, win
->m_height
-dh
);
243 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
245 gtk_draw_shadow( widget
->style
,
250 win
->m_width
-dw
, win
->m_height
-dh
);
255 //-----------------------------------------------------------------------------
256 // "expose_event" of m_widget
257 //-----------------------------------------------------------------------------
259 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
261 if (gdk_event
->count
> 0) return;
262 draw_frame( widget
, win
);
265 //-----------------------------------------------------------------------------
266 // "draw" of m_wxwindow
267 //-----------------------------------------------------------------------------
269 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
271 draw_frame( widget
, win
);
276 //-----------------------------------------------------------------------------
277 // "expose_event" of m_wxwindow
278 //-----------------------------------------------------------------------------
280 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
282 if (g_isIdle
) wxapp_install_idle_handler();
284 if (!win
->HasVMT()) return;
286 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
288 gdk_event
->area
.width
,
289 gdk_event
->area
.height
);
291 if (gdk_event
->count
> 0) return;
294 printf( "OnExpose from " );
295 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
296 printf( win->GetClassInfo()->GetClassName() );
300 wxPaintEvent
event( win
->GetId() );
301 event
.SetEventObject( win
);
302 win
->GetEventHandler()->ProcessEvent( event
);
304 win
->m_updateRegion
.Clear();
307 //-----------------------------------------------------------------------------
308 // "draw" of m_wxwindow
309 //-----------------------------------------------------------------------------
311 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
313 if (g_isIdle
) wxapp_install_idle_handler();
315 if (!win
->HasVMT()) return;
317 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
319 wxPaintEvent
event( win
->GetId() );
320 event
.SetEventObject( win
);
321 win
->GetEventHandler()->ProcessEvent( event
);
323 win
->m_updateRegion
.Clear();
326 //-----------------------------------------------------------------------------
327 // "key_press_event" from any window
328 //-----------------------------------------------------------------------------
330 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
332 if (g_isIdle
) wxapp_install_idle_handler();
334 if (!win
->HasVMT()) return FALSE
;
335 if (g_blockEventsOnDrag
) return FALSE
;
338 wxPrintf( _T("OnKeyPress from ") );
339 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
340 wxPrintf( win->GetClassInfo()->GetClassName() );
341 wxPrintf( _T(".\n") );
343 wxPrintf( _T("keyval: %d.\n"), (int) gdk_event->keyval );
347 switch (gdk_event
->keyval
)
349 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
350 case GDK_ISO_Left_Tab
:
352 case GDK_Tab
: key_code
= WXK_TAB
; break;
353 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
354 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
355 case GDK_Return
: key_code
= WXK_RETURN
; break;
356 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
357 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
358 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
359 case GDK_Delete
: key_code
= WXK_DELETE
; break;
360 case GDK_Home
: key_code
= WXK_HOME
; break;
361 case GDK_Left
: key_code
= WXK_LEFT
; break;
362 case GDK_Up
: key_code
= WXK_UP
; break;
363 case GDK_Right
: key_code
= WXK_RIGHT
; break;
364 case GDK_Down
: key_code
= WXK_DOWN
; break;
365 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
366 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
367 case GDK_Next
: key_code
= WXK_NEXT
; break;
368 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
369 case GDK_End
: key_code
= WXK_END
; break;
370 case GDK_Begin
: key_code
= WXK_HOME
; break;
371 case GDK_Select
: key_code
= WXK_SELECT
; break;
372 case GDK_Print
: key_code
= WXK_PRINT
; break;
373 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
374 case GDK_Insert
: key_code
= WXK_INSERT
; break;
375 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
376 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
377 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
378 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
379 case GDK_KP_Up
: key_code
= WXK_UP
; break;
380 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
381 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
382 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
383 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
384 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
385 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
386 case GDK_KP_End
: key_code
= WXK_END
; break;
387 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
388 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
389 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
390 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
391 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
392 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
393 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
394 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
395 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
396 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
397 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
398 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
399 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
400 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
401 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
402 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
403 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
404 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
405 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
406 case GDK_F1
: key_code
= WXK_F1
; break;
407 case GDK_F2
: key_code
= WXK_F2
; break;
408 case GDK_F3
: key_code
= WXK_F3
; break;
409 case GDK_F4
: key_code
= WXK_F4
; break;
410 case GDK_F5
: key_code
= WXK_F5
; break;
411 case GDK_F6
: key_code
= WXK_F6
; break;
412 case GDK_F7
: key_code
= WXK_F7
; break;
413 case GDK_F8
: key_code
= WXK_F8
; break;
414 case GDK_F9
: key_code
= WXK_F9
; break;
415 case GDK_F10
: key_code
= WXK_F10
; break;
416 case GDK_F11
: key_code
= WXK_F11
; break;
417 case GDK_F12
: key_code
= WXK_F12
; break;
420 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
421 key_code
= gdk_event
->keyval
;
425 if (!key_code
) return FALSE
;
427 wxKeyEvent
event( wxEVT_KEY_DOWN
);
428 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
429 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
430 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
431 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
432 event
.m_keyCode
= key_code
;
435 event
.SetEventObject( win
);
437 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
441 wxWindow
*ancestor
= win
;
444 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
447 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
448 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
451 ancestor
= ancestor
->GetParent();
455 // win is a control: tab can be propagated up
457 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
458 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
460 wxNavigationKeyEvent new_event
;
461 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
462 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
463 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
464 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
465 new_event
.SetCurrentFocus( win
);
466 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
470 (gdk_event
->keyval
== GDK_Escape
) )
472 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
473 new_event
.SetEventObject( win
);
474 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
478 Damn, I forgot why this didn't work, but it didn't work.
480 // win is a panel: up can be propagated to the panel
481 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
482 (gdk_event->keyval == GDK_Up))
484 win->m_parent->SetFocus();
488 // win is a panel: left/right can be propagated to the panel
489 if ((!ret) && (win->m_wxwindow) &&
490 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
491 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
493 wxNavigationKeyEvent new_event;
494 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
495 new_event.SetCurrentFocus( win );
496 ret = win->GetEventHandler()->ProcessEvent( new_event );
502 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
509 //-----------------------------------------------------------------------------
510 // "key_release_event" from any window
511 //-----------------------------------------------------------------------------
513 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
515 if (g_isIdle
) wxapp_install_idle_handler();
517 if (!win
->HasVMT()) return FALSE
;
518 if (g_blockEventsOnDrag
) return FALSE
;
521 printf( "OnKeyRelease from " );
522 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
523 printf( win->GetClassInfo()->GetClassName() );
528 switch (gdk_event
->keyval
)
530 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
531 case GDK_ISO_Left_Tab
:
533 case GDK_Tab
: key_code
= WXK_TAB
; break;
534 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
535 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
536 case GDK_Return
: key_code
= WXK_RETURN
; break;
537 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
538 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
539 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
540 case GDK_Delete
: key_code
= WXK_DELETE
; break;
541 case GDK_Home
: key_code
= WXK_HOME
; break;
542 case GDK_Left
: key_code
= WXK_LEFT
; break;
543 case GDK_Up
: key_code
= WXK_UP
; break;
544 case GDK_Right
: key_code
= WXK_RIGHT
; break;
545 case GDK_Down
: key_code
= WXK_DOWN
; break;
546 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
547 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
548 case GDK_Next
: key_code
= WXK_NEXT
; break;
549 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
550 case GDK_End
: key_code
= WXK_END
; break;
551 case GDK_Begin
: key_code
= WXK_HOME
; break;
552 case GDK_Select
: key_code
= WXK_SELECT
; break;
553 case GDK_Print
: key_code
= WXK_PRINT
; break;
554 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
555 case GDK_Insert
: key_code
= WXK_INSERT
; break;
556 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
557 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
558 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
559 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
560 case GDK_KP_Up
: key_code
= WXK_UP
; break;
561 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
562 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
563 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
564 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
565 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
566 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
567 case GDK_KP_End
: key_code
= WXK_END
; break;
568 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
569 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
570 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
571 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
572 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
573 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
574 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
575 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
576 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
577 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
578 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
579 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
580 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
581 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
582 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
583 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
584 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
585 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
586 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
587 case GDK_F1
: key_code
= WXK_F1
; break;
588 case GDK_F2
: key_code
= WXK_F2
; break;
589 case GDK_F3
: key_code
= WXK_F3
; break;
590 case GDK_F4
: key_code
= WXK_F4
; break;
591 case GDK_F5
: key_code
= WXK_F5
; break;
592 case GDK_F6
: key_code
= WXK_F6
; break;
593 case GDK_F7
: key_code
= WXK_F7
; break;
594 case GDK_F8
: key_code
= WXK_F8
; break;
595 case GDK_F9
: key_code
= WXK_F9
; break;
596 case GDK_F10
: key_code
= WXK_F10
; break;
597 case GDK_F11
: key_code
= WXK_F11
; break;
598 case GDK_F12
: key_code
= WXK_F12
; break;
601 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
602 key_code
= gdk_event
->keyval
;
606 if (!key_code
) return FALSE
;
608 wxKeyEvent
event( wxEVT_KEY_UP
);
609 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
610 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
611 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
612 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
613 event
.m_keyCode
= key_code
;
616 event
.SetEventObject( win
);
618 if (win
->GetEventHandler()->ProcessEvent( event
))
620 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
627 //-----------------------------------------------------------------------------
628 // "button_press_event"
629 //-----------------------------------------------------------------------------
631 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
633 if (g_isIdle
) wxapp_install_idle_handler();
636 wxPrintf( _T("1) OnButtonPress from ") );
637 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
638 wxPrintf( win->GetClassInfo()->GetClassName() );
639 wxPrintf( _T(".\n") );
642 if (!win
->HasVMT()) return FALSE
;
643 if (g_blockEventsOnDrag
) return TRUE
;
644 if (g_blockEventsOnScroll
) return TRUE
;
646 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
650 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
652 gtk_widget_grab_focus (win
->m_wxwindow
);
655 wxPrintf( _T("GrabFocus from ") );
656 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
657 wxPrintf( win->GetClassInfo()->GetClassName() );
658 wxPrintf( _T(".\n") );
665 wxPrintf( _T("No GrabFocus from ") );
666 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
667 wxPrintf( win->GetClassInfo()->GetClassName() );
668 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
669 wxPrintf( _T(" because it already has") );
670 wxPrintf( _T(".\n") );
676 wxPrintf( _T("2) OnButtonPress from ") );
677 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
678 wxPrintf( win->GetClassInfo()->GetClassName() );
679 wxPrintf( _T(".\n") );
682 wxEventType event_type
= wxEVT_LEFT_DOWN
;
684 if (gdk_event
->button
== 1)
686 switch (gdk_event
->type
)
688 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
689 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
693 else if (gdk_event
->button
== 2)
695 switch (gdk_event
->type
)
697 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
698 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
702 else if (gdk_event
->button
== 3)
704 switch (gdk_event
->type
)
706 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
707 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
712 wxMouseEvent
event( event_type
);
713 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
714 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
715 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
716 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
717 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
718 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
719 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
721 event
.m_x
= (long)gdk_event
->x
;
722 event
.m_y
= (long)gdk_event
->y
;
724 // Some control don't have their own X window and thus cannot get
729 wxNode
*node
= win
->GetChildren().First();
732 wxWindow
*child
= (wxWindow
*)node
->Data();
734 if (child
->m_isStaticBox
)
736 // wxStaticBox is transparent in the box itself
739 int xx1
= child
->m_x
;
740 int yy1
= child
->m_y
;
741 int xx2
= child
->m_x
+ child
->m_width
;
742 int yy2
= child
->m_x
+ child
->m_height
;
745 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
747 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
749 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
751 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
754 event
.m_x
-= child
->m_x
;
755 event
.m_y
-= child
->m_y
;
762 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
763 (child
->m_x
<= event
.m_x
) &&
764 (child
->m_y
<= event
.m_y
) &&
765 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
766 (child
->m_y
+child
->m_height
>= event
.m_y
))
769 event
.m_x
-= child
->m_x
;
770 event
.m_y
-= child
->m_y
;
778 event
.SetEventObject( win
);
780 gs_timeLastClick
= gdk_event
->time
;
782 if (win
->GetEventHandler()->ProcessEvent( event
))
784 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
791 //-----------------------------------------------------------------------------
792 // "button_release_event"
793 //-----------------------------------------------------------------------------
795 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
797 if (g_isIdle
) wxapp_install_idle_handler();
799 if (!win
->HasVMT()) return FALSE
;
800 if (g_blockEventsOnDrag
) return FALSE
;
801 if (g_blockEventsOnScroll
) return FALSE
;
803 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
806 printf( "OnButtonRelease from " );
807 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
808 printf( win->GetClassInfo()->GetClassName() );
812 wxEventType event_type
= wxEVT_NULL
;
814 switch (gdk_event
->button
)
816 case 1: event_type
= wxEVT_LEFT_UP
; break;
817 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
818 case 3: event_type
= wxEVT_RIGHT_UP
; break;
821 wxMouseEvent
event( event_type
);
822 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
823 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
824 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
825 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
826 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
827 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
828 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
829 event
.m_x
= (long)gdk_event
->x
;
830 event
.m_y
= (long)gdk_event
->y
;
832 // Some control don't have their own X window and thus cannot get
837 wxNode
*node
= win
->GetChildren().First();
840 wxWindow
*child
= (wxWindow
*)node
->Data();
842 if (child
->m_isStaticBox
)
844 // wxStaticBox is transparent in the box itself
847 int xx1
= child
->m_x
;
848 int yy1
= child
->m_y
;
849 int xx2
= child
->m_x
+ child
->m_width
;
850 int yy2
= child
->m_x
+ child
->m_height
;
853 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
855 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
857 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
859 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
862 event
.m_x
-= child
->m_x
;
863 event
.m_y
-= child
->m_y
;
870 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
871 (child
->m_x
<= event
.m_x
) &&
872 (child
->m_y
<= event
.m_y
) &&
873 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
874 (child
->m_y
+child
->m_height
>= event
.m_y
))
877 event
.m_x
-= child
->m_x
;
878 event
.m_y
-= child
->m_y
;
886 event
.SetEventObject( win
);
888 if (win
->GetEventHandler()->ProcessEvent( event
))
890 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
897 //-----------------------------------------------------------------------------
898 // "motion_notify_event"
899 //-----------------------------------------------------------------------------
901 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
903 if (g_isIdle
) wxapp_install_idle_handler();
905 if (!win
->HasVMT()) return FALSE
;
906 if (g_blockEventsOnDrag
) return FALSE
;
907 if (g_blockEventsOnScroll
) return FALSE
;
909 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
911 if (gdk_event
->is_hint
)
915 GdkModifierType state
;
916 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
919 gdk_event
->state
= state
;
923 printf( "OnMotion from " );
924 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
925 printf( win->GetClassInfo()->GetClassName() );
929 wxMouseEvent
event( wxEVT_MOTION
);
930 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
931 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
932 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
933 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
934 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
935 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
936 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
938 event
.m_x
= (long)gdk_event
->x
;
939 event
.m_y
= (long)gdk_event
->y
;
941 // Some control don't have their own X window and thus cannot get
946 wxNode
*node
= win
->GetChildren().First();
949 wxWindow
*child
= (wxWindow
*)node
->Data();
951 if (child
->m_isStaticBox
)
953 // wxStaticBox is transparent in the box itself
956 int xx1
= child
->m_x
;
957 int yy1
= child
->m_y
;
958 int xx2
= child
->m_x
+ child
->m_width
;
959 int yy2
= child
->m_x
+ child
->m_height
;
962 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
964 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
966 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
968 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
971 event
.m_x
-= child
->m_x
;
972 event
.m_y
-= child
->m_y
;
979 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
980 (child
->m_x
<= event
.m_x
) &&
981 (child
->m_y
<= event
.m_y
) &&
982 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
983 (child
->m_y
+child
->m_height
>= event
.m_y
))
986 event
.m_x
-= child
->m_x
;
987 event
.m_y
-= child
->m_y
;
995 event
.SetEventObject( win
);
997 if (win
->GetEventHandler()->ProcessEvent( event
))
999 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1006 //-----------------------------------------------------------------------------
1008 //-----------------------------------------------------------------------------
1010 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1012 if (g_isIdle
) wxapp_install_idle_handler();
1014 if (!win
->HasVMT()) return FALSE
;
1015 if (g_blockEventsOnDrag
) return FALSE
;
1017 g_focusWindow
= win
;
1019 if (win
->m_wxwindow
)
1021 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1023 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1025 printf( "SetFocus flag from " );
1026 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1027 printf( win->GetClassInfo()->GetClassName() );
1035 wxPrintf( _T("OnSetFocus from ") );
1036 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1037 wxPrintf( win->GetClassInfo()->GetClassName() );
1038 wxPrintf( _T(" ") );
1039 wxPrintf( win->GetLabel() );
1040 wxPrintf( _T(".\n") );
1043 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1044 event
.SetEventObject( win
);
1046 if (win
->GetEventHandler()->ProcessEvent( event
))
1048 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1055 //-----------------------------------------------------------------------------
1056 // "focus_out_event"
1057 //-----------------------------------------------------------------------------
1059 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1061 if (g_isIdle
) wxapp_install_idle_handler();
1063 if (!win
->HasVMT()) return FALSE
;
1064 if (g_blockEventsOnDrag
) return FALSE
;
1066 if (win
->m_wxwindow
)
1068 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1069 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1073 wxPrintf( _T("OnKillFocus from ") );
1074 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1075 wxPrintf( win->GetClassInfo()->GetClassName() );
1076 wxPrintf( _T(" ") );
1077 wxPrintf( win->GetLabel() );
1078 wxPrintf( _T(".\n") );
1081 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1082 event
.SetEventObject( win
);
1084 if (win
->GetEventHandler()->ProcessEvent( event
))
1086 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1093 //-----------------------------------------------------------------------------
1094 // "enter_notify_event"
1095 //-----------------------------------------------------------------------------
1097 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1099 if (g_isIdle
) wxapp_install_idle_handler();
1101 if (!win
->HasVMT()) return FALSE
;
1102 if (g_blockEventsOnDrag
) return FALSE
;
1104 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1106 if ((widget
->window
) && (win
->m_cursor
.Ok()))
1107 gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() );
1110 printf( "OnEnter from " );
1111 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1112 printf( win->GetClassInfo()->GetClassName() );
1116 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1117 event
.SetEventObject( win
);
1121 GdkModifierType state
= (GdkModifierType
)0;
1123 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1125 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1126 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1127 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1128 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1129 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1130 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1131 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1133 event
.m_x
= (long)x
;
1134 event
.m_y
= (long)y
;
1136 if (win
->GetEventHandler()->ProcessEvent( event
))
1138 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1145 //-----------------------------------------------------------------------------
1146 // "leave_notify_event"
1147 //-----------------------------------------------------------------------------
1149 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1151 if (g_isIdle
) wxapp_install_idle_handler();
1153 if (!win
->HasVMT()) return FALSE
;
1154 if (g_blockEventsOnDrag
) return FALSE
;
1156 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1159 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1162 wxPrintf( _T("OnLeave from ") );
1163 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1164 wxPrintf( win->GetClassInfo()->GetClassName() );
1165 wxPrintf( _T(".\n") );
1168 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1169 event
.SetEventObject( win
);
1173 GdkModifierType state
= (GdkModifierType
)0;
1175 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1177 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1178 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1179 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1180 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1181 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1182 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1183 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1185 event
.m_x
= (long)x
;
1186 event
.m_y
= (long)y
;
1188 if (win
->GetEventHandler()->ProcessEvent( event
))
1190 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1197 //-----------------------------------------------------------------------------
1198 // "value_changed" from m_vAdjust
1199 //-----------------------------------------------------------------------------
1201 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1203 if (g_isIdle
) wxapp_install_idle_handler();
1205 if (g_blockEventsOnDrag
) return;
1208 printf( "OnVScroll from " );
1209 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1210 printf( win->GetClassInfo()->GetClassName() );
1214 if (!win
->HasVMT()) return;
1216 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1217 if (fabs(diff
) < 0.2) return;
1218 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1220 wxEventType command
= wxEVT_NULL
;
1222 float line_step
= win
->m_vAdjust
->step_increment
;
1223 float page_step
= win
->m_vAdjust
->page_increment
;
1225 if (win
->m_isScrolling
)
1227 command
= wxEVT_SCROLL_THUMBTRACK
;
1231 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1232 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1233 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1234 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1235 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1236 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1237 else command
= wxEVT_SCROLL_THUMBTRACK
;
1240 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1242 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1243 event
.SetEventObject( win
);
1244 win
->GetEventHandler()->ProcessEvent( event
);
1247 //-----------------------------------------------------------------------------
1248 // "value_changed" from m_hAdjust
1249 //-----------------------------------------------------------------------------
1251 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1253 if (g_isIdle
) wxapp_install_idle_handler();
1255 if (g_blockEventsOnDrag
) return;
1258 printf( "OnHScroll from " );
1259 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1260 printf( win->GetClassInfo()->GetClassName() );
1264 if (!win
->HasVMT()) return;
1266 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1267 if (fabs(diff
) < 0.2) return;
1268 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1270 wxEventType command
= wxEVT_NULL
;
1272 float line_step
= win
->m_hAdjust
->step_increment
;
1273 float page_step
= win
->m_hAdjust
->page_increment
;
1275 if (win
->m_isScrolling
)
1277 command
= wxEVT_SCROLL_THUMBTRACK
;
1281 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1282 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1283 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1284 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1285 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1286 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1287 else command
= wxEVT_SCROLL_THUMBTRACK
;
1290 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1292 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1293 event
.SetEventObject( win
);
1294 win
->GetEventHandler()->ProcessEvent( event
);
1297 //-----------------------------------------------------------------------------
1298 // "changed" from m_vAdjust
1299 //-----------------------------------------------------------------------------
1301 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1303 if (g_isIdle
) wxapp_install_idle_handler();
1305 if (g_blockEventsOnDrag
) return;
1308 printf( "OnVScroll change from " );
1309 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1310 printf( win->GetClassInfo()->GetClassName() );
1314 if (!win
->HasVMT()) return;
1316 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1317 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1319 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1320 event
.SetEventObject( win
);
1321 win
->GetEventHandler()->ProcessEvent( event
);
1324 //-----------------------------------------------------------------------------
1325 // "changed" from m_hAdjust
1326 //-----------------------------------------------------------------------------
1328 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1330 if (g_isIdle
) wxapp_install_idle_handler();
1332 if (g_blockEventsOnDrag
) return;
1335 printf( "OnHScroll change from " );
1336 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1337 printf( win->GetClassInfo()->GetClassName() );
1341 if (!win
->HasVMT()) return;
1343 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1344 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1346 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1347 event
.SetEventObject( win
);
1348 win
->GetEventHandler()->ProcessEvent( event
);
1351 //-----------------------------------------------------------------------------
1352 // "button_press_event" from scrollbar
1353 //-----------------------------------------------------------------------------
1355 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1356 GdkEventButton
*WXUNUSED(gdk_event
),
1359 if (g_isIdle
) wxapp_install_idle_handler();
1361 // don't test here as we can release the mouse while being over
1362 // a different window then the slider
1364 // if (gdk_event->window != widget->slider) return FALSE;
1366 win
->m_isScrolling
= TRUE
;
1367 g_blockEventsOnScroll
= TRUE
;
1372 //-----------------------------------------------------------------------------
1373 // "button_release_event" from scrollbar
1374 //-----------------------------------------------------------------------------
1376 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1377 GdkEventButton
*WXUNUSED(gdk_event
),
1380 if (g_isIdle
) wxapp_install_idle_handler();
1382 // don't test here as we can release the mouse while being over
1383 // a different window then the slider
1385 // if (gdk_event->window != widget->slider) return FALSE;
1387 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1389 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1390 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1392 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1394 win
->m_isScrolling
= FALSE
;
1395 g_blockEventsOnScroll
= FALSE
;
1400 //-----------------------------------------------------------------------------
1401 // "realize" from m_widget
1402 //-----------------------------------------------------------------------------
1404 /* we cannot set colours, fonts and cursors before the widget has
1405 been realized, so we do this directly after realization */
1408 gtk_window_realized_callback( GtkWidget
*widget
, wxWindow
*win
)
1410 if (g_isIdle
) wxapp_install_idle_handler();
1412 if (win
->m_font
!= *wxSWISS_FONT
)
1414 wxFont
font( win
->m_font
);
1415 win
->m_font
= wxNullFont
;
1416 win
->SetFont( font
);
1419 if (win
->m_backgroundColour
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
))
1421 wxColour
bg( win
->m_backgroundColour
);
1422 win
->m_backgroundColour
= wxNullColour
;
1423 win
->SetBackgroundColour( bg
);
1426 if (win
->m_foregroundColour
!= *wxBLACK
)
1428 wxColour
fg( win
->m_foregroundColour
);
1429 win
->m_foregroundColour
= wxNullColour
;
1430 win
->SetForegroundColour( fg
);
1433 wxCursor
cursor( win
->m_cursor
);
1434 win
->m_cursor
= wxNullCursor
;
1435 win
->SetCursor( cursor
);
1440 //-----------------------------------------------------------------------------
1441 // InsertChild for wxWindow.
1442 //-----------------------------------------------------------------------------
1444 /* Callback for wxWindow. This very strange beast has to be used because
1445 * C++ has no virtual methods in a constructor. We have to emulate a
1446 * virtual function here as wxNotebook requires a different way to insert
1447 * a child in it. I had opted for creating a wxNotebookPage window class
1448 * which would have made this superfluous (such in the MDI window system),
1449 * but no-one was listening to me... */
1451 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1453 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1454 GTK_WIDGET(child
->m_widget
),
1460 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1462 /* we now allow a window to get the focus as long as it
1463 doesn't have any children. */
1464 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1468 //-----------------------------------------------------------------------------
1470 //-----------------------------------------------------------------------------
1472 wxWindow
* wxGetActiveWindow()
1474 return g_focusWindow
;
1477 //-----------------------------------------------------------------------------
1479 //-----------------------------------------------------------------------------
1481 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1483 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1484 EVT_SIZE(wxWindow::OnSize
)
1485 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1486 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1487 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1490 void wxWindow::Init()
1494 m_widget
= (GtkWidget
*) NULL
;
1495 m_wxwindow
= (GtkWidget
*) NULL
;
1496 m_parent
= (wxWindow
*) NULL
;
1497 m_children
.DeleteContents( FALSE
);
1510 m_eventHandler
= this;
1511 m_windowValidator
= (wxValidator
*) NULL
;
1515 m_cursor
= *wxSTANDARD_CURSOR
;
1516 m_font
= *wxSWISS_FONT
;
1518 m_windowName
= "noname";
1520 m_constraints
= (wxLayoutConstraints
*) NULL
;
1521 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1522 m_windowSizer
= (wxSizer
*) NULL
;
1523 m_sizerParent
= (wxWindow
*) NULL
;
1524 m_autoLayout
= FALSE
;
1528 m_needParent
= TRUE
;
1530 m_hasScrolling
= FALSE
;
1531 m_isScrolling
= FALSE
;
1532 m_hAdjust
= (GtkAdjustment
*) NULL
;
1533 m_vAdjust
= (GtkAdjustment
*) NULL
;
1534 m_oldHorizontalPos
= 0.0;
1535 m_oldVerticalPos
= 0.0;
1540 #if wxUSE_DRAG_AND_DROP
1541 m_dropTarget
= (wxDropTarget
*) NULL
;
1544 m_scrollGC
= (GdkGC
*) NULL
;
1545 m_widgetStyle
= (GtkStyle
*) NULL
;
1547 m_insertCallback
= wxInsertChildInWindow
;
1549 m_clientObject
= (wxClientData
*) NULL
;
1550 m_clientData
= NULL
;
1552 m_isStaticBox
= FALSE
;
1553 m_acceptsFocus
= FALSE
;
1556 m_toolTip
= (wxToolTip
*) NULL
;
1557 #endif // wxUSE_TOOLTIPS
1560 wxWindow::wxWindow()
1565 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1566 const wxPoint
&pos
, const wxSize
&size
,
1567 long style
, const wxString
&name
)
1571 Create( parent
, id
, pos
, size
, style
, name
);
1574 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1575 const wxPoint
&pos
, const wxSize
&size
,
1576 long style
, const wxString
&name
)
1578 wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") );
1580 PreCreation( parent
, id
, pos
, size
, style
, name
);
1582 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1583 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1586 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1589 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1592 debug_focus_in( s_window
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1593 debug_focus_in( s_window
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1596 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1597 scroll_class
->scrollbar_spacing
= 0;
1599 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1601 m_oldHorizontalPos
= 0.0;
1602 m_oldVerticalPos
= 0.0;
1604 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1605 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1607 m_wxwindow
= gtk_myfixed_new();
1610 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1613 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1615 #if (GTK_MINOR_VERSION > 0)
1616 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1618 if (m_windowStyle
& wxRAISED_BORDER
)
1620 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1622 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1624 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1628 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1631 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1633 if (m_windowStyle
& wxRAISED_BORDER
)
1635 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1637 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1639 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1643 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1647 /* we always allow a window to get the focus as long as it
1648 doesn't have any children. */
1649 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1651 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1652 m_acceptsFocus
= FALSE
;
1656 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1657 m_acceptsFocus
= TRUE
;
1660 /* grab the actual focus */
1661 // gtk_widget_grab_focus( m_wxwindow );
1663 gtk_widget_show( m_wxwindow
);
1666 #if (GTK_MINOR_VERSION == 0)
1667 // shut the viewport up
1668 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1669 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1672 // I _really_ don't want scrollbars in the beginning
1673 m_vAdjust
->lower
= 0.0;
1674 m_vAdjust
->upper
= 1.0;
1675 m_vAdjust
->value
= 0.0;
1676 m_vAdjust
->step_increment
= 1.0;
1677 m_vAdjust
->page_increment
= 1.0;
1678 m_vAdjust
->page_size
= 5.0;
1679 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1680 m_hAdjust
->lower
= 0.0;
1681 m_hAdjust
->upper
= 1.0;
1682 m_hAdjust
->value
= 0.0;
1683 m_hAdjust
->step_increment
= 1.0;
1684 m_hAdjust
->page_increment
= 1.0;
1685 m_hAdjust
->page_size
= 5.0;
1686 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1688 // these handlers block mouse events to any window during scrolling
1689 // such as motion events and prevent GTK and wxWindows from fighting
1690 // over where the slider should be
1692 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1693 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1695 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1696 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1698 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1699 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1701 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1702 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1704 // these handlers get notified when screen updates are required either when
1705 // scrolling or when the window size (and therefore scrollbar configuration)
1708 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1709 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1710 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1711 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1713 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1714 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1715 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1716 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1718 if (m_parent
) m_parent
->AddChild( this );
1720 (m_parent
->m_insertCallback
)( m_parent
, this );
1729 wxWindow::~wxWindow()
1733 #if wxUSE_DRAG_AND_DROP
1736 delete m_dropTarget
;
1737 m_dropTarget
= (wxDropTarget
*) NULL
;
1745 m_toolTip
= (wxToolTip
*) NULL
;
1747 #endif // wxUSE_TOOLTIPS
1749 if (m_widget
) Show( FALSE
);
1753 if (m_parent
) m_parent
->RemoveChild( this );
1755 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1757 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1759 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1761 if (m_widget
) gtk_widget_destroy( m_widget
);
1763 DeleteRelatedConstraints();
1766 /* This removes any dangling pointers to this window
1767 * in other windows' constraintsInvolvedIn lists. */
1768 UnsetConstraints(m_constraints
);
1769 delete m_constraints
;
1770 m_constraints
= (wxLayoutConstraints
*) NULL
;
1775 delete m_windowSizer
;
1776 m_windowSizer
= (wxSizer
*) NULL
;
1778 /* If this is a child of a sizer, remove self from parent */
1779 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1781 /* Just in case the window has been Closed, but
1782 * we're then deleting immediately: don't leave
1783 * dangling pointers. */
1784 wxPendingDelete
.DeleteObject(this);
1786 /* Just in case we've loaded a top-level window via
1787 * wxWindow::LoadNativeDialog but we weren't a dialog
1789 wxTopLevelWindows
.DeleteObject(this);
1791 if (m_windowValidator
) delete m_windowValidator
;
1793 if (m_clientObject
) delete m_clientObject
;
1796 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1797 const wxPoint
&pos
, const wxSize
&size
,
1798 long style
, const wxString
&name
)
1800 wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") );
1802 m_widget
= (GtkWidget
*) NULL
;
1803 m_wxwindow
= (GtkWidget
*) NULL
;
1806 m_children
.DeleteContents( FALSE
);
1809 if (m_width
== -1) m_width
= 20;
1811 if (m_height
== -1) m_height
= 20;
1816 if (!m_needParent
) /* some reasonable defaults */
1820 m_x
= (gdk_screen_width () - m_width
) / 2;
1821 if (m_x
< 10) m_x
= 10;
1825 m_y
= (gdk_screen_height () - m_height
) / 2;
1826 if (m_y
< 10) m_y
= 10;
1837 m_eventHandler
= this;
1839 m_windowId
= id
== -1 ? wxNewId() : id
;
1843 m_cursor
= *wxSTANDARD_CURSOR
;
1844 m_font
= *wxSWISS_FONT
;
1845 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1846 m_foregroundColour
= *wxBLACK
;
1847 m_windowStyle
= style
;
1848 m_windowName
= name
;
1850 m_constraints
= (wxLayoutConstraints
*) NULL
;
1851 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1852 m_windowSizer
= (wxSizer
*) NULL
;
1853 m_sizerParent
= (wxWindow
*) NULL
;
1854 m_autoLayout
= FALSE
;
1856 m_hasScrolling
= FALSE
;
1857 m_isScrolling
= FALSE
;
1858 m_hAdjust
= (GtkAdjustment
*) NULL
;
1859 m_vAdjust
= (GtkAdjustment
*) NULL
;
1860 m_oldHorizontalPos
= 0.0;
1861 m_oldVerticalPos
= 0.0;
1866 #if wxUSE_DRAG_AND_DROP
1867 m_dropTarget
= (wxDropTarget
*) NULL
;
1870 m_windowValidator
= (wxValidator
*) NULL
;
1871 m_scrollGC
= (GdkGC
*) NULL
;
1872 m_widgetStyle
= (GtkStyle
*) NULL
;
1874 m_clientObject
= (wxClientData
*)NULL
;
1875 m_clientData
= NULL
;
1877 m_isStaticBox
= FALSE
;
1880 m_toolTip
= (wxToolTip
*) NULL
;
1881 #endif // wxUSE_TOOLTIPS
1884 void wxWindow::PostCreation()
1886 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1890 /* these get reported to wxWindows -> wxPaintEvent */
1891 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1892 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1894 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1895 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1897 #if (GTK_MINOR_VERSION > 0)
1898 /* these are called when the "sunken" or "raised" borders are drawn */
1899 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1900 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1902 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1903 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1907 GtkWidget
*connect_widget
= GetConnectWidget();
1909 ConnectWidget( connect_widget
);
1911 /* we cannot set colours, fonts and cursors before the widget has
1912 been realized, so we do this directly after realization */
1913 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1914 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1919 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1921 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1922 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1924 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1925 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1927 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1928 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1930 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1931 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1933 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1934 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1936 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1937 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1939 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1940 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1942 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1943 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1945 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1946 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1949 bool wxWindow::HasVMT()
1954 bool wxWindow::Close( bool force
)
1956 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1958 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1959 event
.SetEventObject(this);
1960 event
.SetCanVeto(!force
);
1962 /* return FALSE if window wasn't closed because the application vetoed the
1964 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1967 bool wxWindow::Destroy()
1969 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1976 bool wxWindow::DestroyChildren()
1979 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1982 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1985 if (m_children
.Member(child
)) delete node
;
1991 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1993 // are we to set fonts here ?
1996 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1998 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1999 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
2001 if (m_resizing
) return; /* I don't like recursions */
2004 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook page */
2006 /* don't set the size for children of wxNotebook, just take the values. */
2014 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
2016 if (x
!= -1) m_x
= x
;
2017 if (y
!= -1) m_y
= y
;
2018 if (width
!= -1) m_width
= width
;
2019 if (height
!= -1) m_height
= height
;
2029 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2031 if (width
== -1) m_width
= 80;
2034 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2036 if (height
== -1) m_height
= 26;
2039 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2040 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2041 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2042 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2046 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
2048 /* the default button has a border around it */
2052 /* this is the result of hours of debugging: the following code
2053 means that if we have a m_wxwindow and we set the size of
2054 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2055 automatically propagate its size down to its m_wxwindow,
2056 which is its client area. therefore, we have to tell the
2057 client area directly that it has to resize itself.
2058 this will lead to that m_widget (GtkScrolledWindow) will
2059 calculate how much size it needs for scrollbars etc and
2060 it will then call XXX_size_allocate of its child, which
2061 is m_wxwindow. m_wxwindow in turn will do the same with its
2062 children and so on. problems can arise if this happens
2063 before all the children have been realized as some widgets
2064 stupidy need to be realized during XXX_size_allocate (e.g.
2065 GtkNotebook) and they will segv if called otherwise. this
2066 emergency is tested in gtk_myfixed_size_allocate. Normally
2067 this shouldn't be needed and only gtk_widget_queue_resize()
2068 should be enough to provoke a resize at the next appropriate
2069 moment, but this seems to fail, e.g. when a wxNotebook contains
2070 a wxSplitterWindow: the splitter window's children won't
2071 show up properly resized then. */
2073 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2078 m_height
+2*border
);
2084 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2085 event
.SetEventObject( this );
2086 GetEventHandler()->ProcessEvent( event
);
2091 void wxWindow::OnInternalIdle()
2096 void wxWindow::GetSize( int *width
, int *height
) const
2098 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2100 if (width
) (*width
) = m_width
;
2101 if (height
) (*height
) = m_height
;
2104 void wxWindow::DoSetClientSize( int width
, int height
)
2106 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2110 SetSize( width
, height
);
2117 if (!m_hasScrolling
)
2119 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2121 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2122 (m_windowStyle
& wxSUNKEN_BORDER
))
2124 dw
+= 2 * window_class
->xthickness
;
2125 dh
+= 2 * window_class
->ythickness
;
2130 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2131 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2133 #if (GTK_MINOR_VERSION == 0)
2134 GtkWidget
*viewport
= scroll_window
->viewport
;
2135 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2137 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2138 (m_windowStyle
& wxSUNKEN_BORDER
))
2140 dw
+= 2 * viewport_class
->xthickness
;
2141 dh
+= 2 * viewport_class
->ythickness
;
2146 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2147 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2149 we use this instead: range.slider_width = 11 + 2*2pts edge
2152 if (scroll_window
->vscrollbar_visible
)
2154 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2155 dw
+= scroll_class
->scrollbar_spacing
;
2158 if (scroll_window
->hscrollbar_visible
)
2160 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2161 dw
+= scroll_class
->scrollbar_spacing
;
2165 SetSize( width
+dw
, height
+dh
);
2169 void wxWindow::GetClientSize( int *width
, int *height
) const
2171 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2175 if (width
) (*width
) = m_width
;
2176 if (height
) (*height
) = m_height
;
2183 if (!m_hasScrolling
)
2185 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2187 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2188 (m_windowStyle
& wxSUNKEN_BORDER
))
2190 dw
+= 2 * window_class
->xthickness
;
2191 dh
+= 2 * window_class
->ythickness
;
2196 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2197 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2199 #if (GTK_MINOR_VERSION == 0)
2200 GtkWidget
*viewport
= scroll_window
->viewport
;
2201 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2203 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2204 (m_windowStyle
& wxSUNKEN_BORDER
))
2206 dw
+= 2 * viewport_class
->xthickness
;
2207 dh
+= 2 * viewport_class
->ythickness
;
2211 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2212 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2214 we use this instead: range.slider_width = 11 + 2*2pts edge
2217 if (scroll_window
->vscrollbar_visible
)
2219 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2220 dw
+= scroll_class
->scrollbar_spacing
;
2223 if (scroll_window
->hscrollbar_visible
)
2225 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2226 dh
+= scroll_class
->scrollbar_spacing
;
2230 if (width
) (*width
) = m_width
- dw
;
2231 if (height
) (*height
) = m_height
- dh
;
2235 void wxWindow::GetPosition( int *x
, int *y
) const
2237 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2243 void wxWindow::ClientToScreen( int *x
, int *y
)
2245 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2247 if (!m_widget
->window
) return;
2249 GdkWindow
*source
= (GdkWindow
*) NULL
;
2251 source
= m_wxwindow
->window
;
2253 source
= m_widget
->window
;
2257 gdk_window_get_origin( source
, &org_x
, &org_y
);
2261 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2263 org_x
+= m_widget
->allocation
.x
;
2264 org_y
+= m_widget
->allocation
.y
;
2272 void wxWindow::ScreenToClient( int *x
, int *y
)
2274 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2276 if (!m_widget
->window
) return;
2278 GdkWindow
*source
= (GdkWindow
*) NULL
;
2280 source
= m_wxwindow
->window
;
2282 source
= m_widget
->window
;
2286 gdk_window_get_origin( source
, &org_x
, &org_y
);
2290 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2292 org_x
+= m_widget
->allocation
.x
;
2293 org_y
+= m_widget
->allocation
.y
;
2301 void wxWindow::Centre( int direction
)
2303 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2312 m_parent
->GetSize( &p_w
, &p_h
);
2313 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2314 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2318 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2319 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2325 void wxWindow::Fit()
2327 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2331 wxNode
*node
= m_children
.First();
2334 wxWindow
*win
= (wxWindow
*)node
->Data();
2336 win
->GetPosition(&wx
, &wy
);
2337 win
->GetSize(&ww
, &wh
);
2338 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2339 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2341 node
= node
->Next();
2344 SetClientSize(maxX
+ 7, maxY
+ 14);
2347 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2349 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2357 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2359 /* this is commented because it also is commented
2360 in wxMSW. before I get even more questions about
2362 // if (GetAutoLayout()) Layout();
2365 bool wxWindow::Show( bool show
)
2367 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2369 if (show
== m_isShown
) return TRUE
;
2372 gtk_widget_show( m_widget
);
2374 gtk_widget_hide( m_widget
);
2381 void wxWindow::Enable( bool enable
)
2383 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2385 m_isEnabled
= enable
;
2387 gtk_widget_set_sensitive( m_widget
, enable
);
2388 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2391 int wxWindow::GetCharHeight() const
2393 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2395 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2397 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2399 return font
->ascent
+ font
->descent
;
2402 int wxWindow::GetCharWidth() const
2404 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2406 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2408 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2410 return gdk_string_width( font
, "H" );
2413 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2414 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2416 wxFont fontToUse
= m_font
;
2417 if (theFont
) fontToUse
= *theFont
;
2419 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2421 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2422 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2423 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2424 if (descent
) (*descent
) = font
->descent
;
2425 if (externalLeading
) (*externalLeading
) = 0; // ??
2428 void wxWindow::MakeModal( bool modal
)
2432 // Disable all other windows
2433 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2435 wxNode
*node
= wxTopLevelWindows
.First();
2438 wxWindow
*win
= (wxWindow
*)node
->Data();
2439 if (win
!= this) win
->Enable(!modal
);
2441 node
= node
->Next();
2446 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2448 event
.SetEventType( wxEVT_CHAR
);
2450 if (!GetEventHandler()->ProcessEvent( event
))
2456 void wxWindow::SetFocus()
2458 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2460 GtkWidget
*connect_widget
= GetConnectWidget();
2463 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2465 gtk_widget_grab_focus (connect_widget
);
2467 else if (GTK_IS_CONTAINER(connect_widget
))
2469 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2477 wxWindow
*wxWindow::FindFocus()
2479 return g_focusWindow
;
2482 bool wxWindow::AcceptsFocus() const
2484 return IsEnabled() && IsShown() && m_acceptsFocus
;
2487 void wxWindow::AddChild( wxWindow
*child
)
2489 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2490 wxCHECK_RET( (child
!= NULL
), _T("invalid child") );
2492 m_children
.Append( child
);
2495 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2497 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2499 wxWindow
*oldParent
= GetParent();
2501 if (oldParent
) oldParent
->RemoveChild( this );
2503 gtk_widget_unparent( m_widget
);
2507 newParent
->AddChild( this );
2508 (newParent
->m_insertCallback
)( newParent
, this );
2514 void wxWindow::RemoveChild( wxWindow
*child
)
2516 m_children
.DeleteObject( child
);
2517 child
->m_parent
= (wxWindow
*) NULL
;
2520 void wxWindow::SetReturnCode( int retCode
)
2522 m_retCode
= retCode
;
2525 int wxWindow::GetReturnCode()
2530 void wxWindow::Raise()
2532 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2534 if (!m_widget
->window
) return;
2536 if (m_widget
) gdk_window_raise( m_widget
->window
);
2539 void wxWindow::Lower()
2541 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2543 if (!m_widget
->window
) return;
2545 if (m_widget
) gdk_window_lower( m_widget
->window
);
2548 wxEvtHandler
*wxWindow::GetEventHandler() const
2550 return m_eventHandler
;
2553 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2555 m_eventHandler
= handler
;
2558 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2560 handler
->SetNextHandler(GetEventHandler());
2561 SetEventHandler(handler
);
2564 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2566 if (GetEventHandler())
2568 wxEvtHandler
*handlerA
= GetEventHandler();
2569 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2570 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2571 SetEventHandler(handlerB
);
2575 return (wxEvtHandler
*) NULL
;
2581 return (wxEvtHandler
*) NULL
;
2584 wxValidator
*wxWindow::GetValidator()
2586 return m_windowValidator
;
2589 void wxWindow::SetValidator( const wxValidator
& validator
)
2591 if (m_windowValidator
) delete m_windowValidator
;
2592 m_windowValidator
= (wxValidator
*)validator
.Clone();
2593 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2596 void wxWindow::SetClientObject( wxClientData
*data
)
2598 if (m_clientObject
) delete m_clientObject
;
2599 m_clientObject
= data
;
2602 wxClientData
*wxWindow::GetClientObject()
2604 return m_clientObject
;
2607 void wxWindow::SetClientData( void *data
)
2609 m_clientData
= data
;
2612 void *wxWindow::GetClientData()
2614 return m_clientData
;
2617 bool wxWindow::IsBeingDeleted()
2622 void wxWindow::SetId( wxWindowID id
)
2627 wxWindowID
wxWindow::GetId() const
2632 void wxWindow::SetCursor( const wxCursor
&cursor
)
2634 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2638 if (cursor
== m_cursor
) return;
2643 m_cursor
= *wxSTANDARD_CURSOR
;
2646 if (!m_widget
->window
) return;
2648 gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() );
2650 if ((m_wxwindow
) && (m_wxwindow
->window
))
2651 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() );
2654 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2659 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2661 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2663 if (!m_widget
->window
) return;
2665 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2669 gdk_window_clear_area( m_wxwindow
->window
,
2671 rect
->width
, rect
->height
);
2675 gdk_window_clear( m_wxwindow
->window
);
2682 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2684 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2688 GdkRectangle gdk_rect
;
2689 gdk_rect
.x
= rect
->x
;
2690 gdk_rect
.y
= rect
->y
;
2691 gdk_rect
.width
= rect
->width
;
2692 gdk_rect
.height
= rect
->height
;
2695 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2697 gtk_widget_draw( m_widget
, &gdk_rect
);
2701 wxRegion
wxWindow::GetUpdateRegion() const
2703 return m_updateRegion
;
2706 bool wxWindow::IsExposed( int x
, int y
) const
2708 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2711 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2713 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2716 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2718 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2721 bool wxWindow::IsExposed( const wxRect
& rect
) const
2723 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2726 void wxWindow::Clear()
2728 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2730 if (!m_widget
->window
) return;
2732 if (m_wxwindow
&& m_wxwindow
->window
)
2734 gdk_window_clear( m_wxwindow
->window
);
2739 void wxWindow::SetToolTip( const wxString
&tip
)
2743 m_toolTip
->SetTip( tip
);
2747 SetToolTip( new wxToolTip( tip
) );
2750 // setting empty tooltip text does not remove the tooltip any more for
2751 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2754 void wxWindow::SetToolTip( wxToolTip
*tip
)
2758 m_toolTip
->SetTip( (char*) NULL
);
2765 m_toolTip
->Apply( this );
2768 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2770 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2772 #endif // wxUSE_TOOLTIPS
2774 wxColour
wxWindow::GetBackgroundColour() const
2776 return m_backgroundColour
;
2779 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2781 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2783 if (m_backgroundColour
== colour
) return;
2785 m_backgroundColour
= colour
;
2786 if (!m_backgroundColour
.Ok()) return;
2788 GtkWidget
*connect_widget
= GetConnectWidget();
2789 if (!connect_widget
->window
) return;
2791 if (m_wxwindow
&& m_wxwindow
->window
)
2793 /* wxMSW doesn't clear the window here. I don't do that
2794 either to provide compatibility. call Clear() to do
2797 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2798 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2801 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2803 if (sysbg
.Red() == colour
.Red() &&
2804 sysbg
.Green() == colour
.Green() &&
2805 sysbg
.Blue() == colour
.Blue())
2807 m_backgroundColour
= wxNullColour
;
2809 m_backgroundColour
= sysbg
;
2817 wxColour
wxWindow::GetForegroundColour() const
2819 return m_foregroundColour
;
2822 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2824 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2826 if (m_foregroundColour
== colour
) return;
2828 m_foregroundColour
= colour
;
2829 if (!m_foregroundColour
.Ok()) return;
2831 if (!m_widget
->window
) return;
2833 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2834 if (sysbg
.Red() == colour
.Red() &&
2835 sysbg
.Green() == colour
.Green() &&
2836 sysbg
.Blue() == colour
.Blue())
2838 m_backgroundColour
= wxNullColour
;
2840 m_backgroundColour
= sysbg
;
2848 GtkStyle
*wxWindow::GetWidgetStyle()
2850 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2854 gtk_widget_get_style( m_widget
) );
2856 return m_widgetStyle
;
2859 void wxWindow::SetWidgetStyle()
2861 GtkStyle
*style
= GetWidgetStyle();
2863 gdk_font_unref( style
->font
);
2864 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2866 if (m_foregroundColour
.Ok())
2868 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2869 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2870 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2871 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2874 if (m_backgroundColour
.Ok())
2876 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2877 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2878 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2879 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2880 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2881 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2882 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2883 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2884 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2888 void wxWindow::ApplyWidgetStyle()
2892 bool wxWindow::Validate()
2894 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2896 wxNode
*node
= m_children
.First();
2899 wxWindow
*child
= (wxWindow
*)node
->Data();
2900 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2904 node
= node
->Next();
2909 bool wxWindow::TransferDataToWindow()
2911 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2913 wxNode
*node
= m_children
.First();
2916 wxWindow
*child
= (wxWindow
*)node
->Data();
2917 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2918 !child
->GetValidator()->TransferToWindow() )
2920 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2923 node
= node
->Next();
2928 bool wxWindow::TransferDataFromWindow()
2930 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2932 wxNode
*node
= m_children
.First();
2935 wxWindow
*child
= (wxWindow
*)node
->Data();
2936 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2940 node
= node
->Next();
2945 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2947 m_acceleratorTable
= accel
;
2950 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2952 TransferDataToWindow();
2955 void wxWindow::InitDialog()
2957 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2959 wxInitDialogEvent
event(GetId());
2960 event
.SetEventObject( this );
2961 GetEventHandler()->ProcessEvent(event
);
2964 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2966 menu
->SetInvokingWindow( win
);
2967 wxNode
*node
= menu
->GetItems().First();
2970 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2971 if (menuitem
->IsSubMenu())
2973 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2975 node
= node
->Next();
2979 static gint gs_pop_x
= 0;
2980 static gint gs_pop_y
= 0;
2982 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2984 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2989 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2991 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2993 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2995 SetInvokingWindow( menu
, this );
3003 GTK_MENU(menu
->m_menu
),
3004 (GtkWidget
*) NULL
, // parent menu shell
3005 (GtkWidget
*) NULL
, // parent menu item
3006 (GtkMenuPositionFunc
) pop_pos_callback
,
3007 (gpointer
) this, // client data
3008 0, // button used to activate it
3009 0 //gs_timeLastClick // the time of activation
3014 #if wxUSE_DRAG_AND_DROP
3016 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
3018 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3020 GtkWidget
*dnd_widget
= GetConnectWidget();
3022 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
3024 if (m_dropTarget
) delete m_dropTarget
;
3025 m_dropTarget
= dropTarget
;
3027 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
3030 wxDropTarget
*wxWindow::GetDropTarget() const
3032 return m_dropTarget
;
3037 GtkWidget
* wxWindow::GetConnectWidget()
3039 GtkWidget
*connect_widget
= m_widget
;
3040 if (m_wxwindow
) connect_widget
= m_wxwindow
;
3042 return connect_widget
;
3045 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
3047 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
3048 return (window
== m_widget
->window
);
3051 void wxWindow::SetFont( const wxFont
&font
)
3053 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3055 if (m_font
== font
) return;
3057 if (((wxFont
*)&font
)->Ok())
3060 m_font
= *wxSWISS_FONT
;
3062 if (!m_widget
->window
) return;
3064 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3065 if (sysbg
.Red() == m_backgroundColour
.Red() &&
3066 sysbg
.Green() == m_backgroundColour
.Green() &&
3067 sysbg
.Blue() == m_backgroundColour
.Blue())
3069 m_backgroundColour
= wxNullColour
;
3071 m_backgroundColour
= sysbg
;
3079 void wxWindow::SetWindowStyleFlag( long flag
)
3081 m_windowStyle
= flag
;
3084 long wxWindow::GetWindowStyleFlag() const
3086 return m_windowStyle
;
3089 void wxWindow::CaptureMouse()
3091 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3093 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
3095 if (!m_widget
->window
) return;
3097 GtkWidget
*connect_widget
= GetConnectWidget();
3098 gtk_grab_add( connect_widget
);
3099 gdk_pointer_grab( connect_widget
->window
, FALSE
,
3101 (GDK_BUTTON_PRESS_MASK
|
3102 GDK_BUTTON_RELEASE_MASK
|
3103 GDK_POINTER_MOTION_MASK
),
3110 void wxWindow::ReleaseMouse()
3112 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3114 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
3116 if (!m_widget
->window
) return;
3118 GtkWidget
*connect_widget
= GetConnectWidget();
3119 gtk_grab_remove( connect_widget
);
3120 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3121 g_capturing
= FALSE
;
3124 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
3128 wxString
wxWindow::GetTitle() const
3130 return (wxString
&)m_windowName
;
3133 wxString
wxWindow::GetLabel() const
3138 void wxWindow::SetName( const wxString
&name
)
3140 m_windowName
= name
;
3143 wxString
wxWindow::GetName() const
3145 return (wxString
&)m_windowName
;
3148 bool wxWindow::IsShown() const
3153 bool wxWindow::IsRetained()
3158 wxWindow
*wxWindow::FindWindow( long id
)
3160 if (id
== m_windowId
) return this;
3161 wxNode
*node
= m_children
.First();
3164 wxWindow
*child
= (wxWindow
*)node
->Data();
3165 wxWindow
*res
= child
->FindWindow( id
);
3166 if (res
) return res
;
3167 node
= node
->Next();
3169 return (wxWindow
*) NULL
;
3172 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
3174 if (name
== m_windowName
) return this;
3175 wxNode
*node
= m_children
.First();
3178 wxWindow
*child
= (wxWindow
*)node
->Data();
3179 wxWindow
*res
= child
->FindWindow( name
);
3180 if (res
) return res
;
3181 node
= node
->Next();
3183 return (wxWindow
*) NULL
;
3186 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3187 int range
, bool refresh
)
3189 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3191 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3193 m_hasScrolling
= TRUE
;
3195 if (orient
== wxHORIZONTAL
)
3197 float fpos
= (float)pos
;
3198 float frange
= (float)range
;
3199 float fthumb
= (float)thumbVisible
;
3200 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3201 if (fpos
< 0.0) fpos
= 0.0;
3203 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3204 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3206 SetScrollPos( orient
, pos
, refresh
);
3210 m_oldHorizontalPos
= fpos
;
3212 m_hAdjust
->lower
= 0.0;
3213 m_hAdjust
->upper
= frange
;
3214 m_hAdjust
->value
= fpos
;
3215 m_hAdjust
->step_increment
= 1.0;
3216 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3217 m_hAdjust
->page_size
= fthumb
;
3221 float fpos
= (float)pos
;
3222 float frange
= (float)range
;
3223 float fthumb
= (float)thumbVisible
;
3224 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3225 if (fpos
< 0.0) fpos
= 0.0;
3227 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3228 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3230 SetScrollPos( orient
, pos
, refresh
);
3234 m_oldVerticalPos
= fpos
;
3236 m_vAdjust
->lower
= 0.0;
3237 m_vAdjust
->upper
= frange
;
3238 m_vAdjust
->value
= fpos
;
3239 m_vAdjust
->step_increment
= 1.0;
3240 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3241 m_vAdjust
->page_size
= fthumb
;
3246 if (orient
== wxHORIZONTAL
)
3247 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3249 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3251 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3255 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3257 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3259 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3261 if (orient
== wxHORIZONTAL
)
3263 float fpos
= (float)pos
;
3264 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3265 if (fpos
< 0.0) fpos
= 0.0;
3266 m_oldHorizontalPos
= fpos
;
3268 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3269 m_hAdjust
->value
= fpos
;
3273 float fpos
= (float)pos
;
3274 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3275 if (fpos
< 0.0) fpos
= 0.0;
3276 m_oldVerticalPos
= fpos
;
3278 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3279 m_vAdjust
->value
= fpos
;
3284 if (m_wxwindow
->window
)
3286 if (orient
== wxHORIZONTAL
)
3287 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3289 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3294 int wxWindow::GetScrollThumb( int orient
) const
3296 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3298 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3300 if (orient
== wxHORIZONTAL
)
3301 return (int)(m_hAdjust
->page_size
+0.5);
3303 return (int)(m_vAdjust
->page_size
+0.5);
3306 int wxWindow::GetScrollPos( int orient
) const
3308 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3310 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3312 if (orient
== wxHORIZONTAL
)
3313 return (int)(m_hAdjust
->value
+0.5);
3315 return (int)(m_vAdjust
->value
+0.5);
3318 int wxWindow::GetScrollRange( int orient
) const
3320 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3322 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3324 if (orient
== wxHORIZONTAL
)
3325 return (int)(m_hAdjust
->upper
+0.5);
3327 return (int)(m_vAdjust
->upper
+0.5);
3330 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3332 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3334 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3338 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3339 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3344 GetClientSize( &cw
, &ch
);
3345 int w
= cw
- abs(dx
);
3346 int h
= ch
- abs(dy
);
3348 if ((h
< 0) || (w
< 0))
3356 if (dx
< 0) s_x
= -dx
;
3357 if (dy
< 0) s_y
= -dy
;
3360 if (dx
> 0) d_x
= dx
;
3361 if (dy
> 0) d_y
= dy
;
3363 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3364 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3367 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3368 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3369 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3370 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3372 Refresh( TRUE
, &rect
);
3375 wxNode
*node
= m_children
.First();
3378 wxWindow
*child
= (wxWindow
*) node
->Data();
3379 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3380 node
= node
->Next();
3385 //-------------------------------------------------------------------------------------
3387 //-------------------------------------------------------------------------------------
3389 wxLayoutConstraints
*wxWindow::GetConstraints() const
3391 return m_constraints
;
3394 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3398 UnsetConstraints(m_constraints
);
3399 delete m_constraints
;
3401 m_constraints
= constraints
;
3404 // Make sure other windows know they're part of a 'meaningful relationship'
3405 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3406 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3407 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3408 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3409 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3410 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3411 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3412 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3413 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3414 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3415 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3416 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3417 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3418 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3419 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3420 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3426 void wxWindow::SetAutoLayout( bool autoLayout
)
3428 m_autoLayout
= autoLayout
;
3431 bool wxWindow::GetAutoLayout() const
3433 return m_autoLayout
;
3436 wxSizer
*wxWindow::GetSizer() const
3438 return m_windowSizer
;
3441 void wxWindow::SetSizerParent( wxWindow
*win
)
3443 m_sizerParent
= win
;
3446 wxWindow
*wxWindow::GetSizerParent() const
3448 return m_sizerParent
;
3451 // This removes any dangling pointers to this window
3452 // in other windows' constraintsInvolvedIn lists.
3453 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3457 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3458 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3459 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3460 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3461 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3462 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3463 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3464 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3465 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3466 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3467 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3468 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3469 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3470 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3471 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3472 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3476 // Back-pointer to other windows we're involved with, so if we delete
3477 // this window, we must delete any constraints we're involved with.
3478 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3480 if (!m_constraintsInvolvedIn
)
3481 m_constraintsInvolvedIn
= new wxList
;
3482 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3483 m_constraintsInvolvedIn
->Append(otherWin
);
3486 // REMOVE back-pointer to other windows we're involved with.
3487 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3489 if (m_constraintsInvolvedIn
)
3490 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3493 // Reset any constraints that mention this window
3494 void wxWindow::DeleteRelatedConstraints()
3496 if (m_constraintsInvolvedIn
)
3498 wxNode
*node
= m_constraintsInvolvedIn
->First();
3501 wxWindow
*win
= (wxWindow
*)node
->Data();
3502 wxNode
*next
= node
->Next();
3503 wxLayoutConstraints
*constr
= win
->GetConstraints();
3505 // Reset any constraints involving this window
3508 constr
->left
.ResetIfWin((wxWindow
*)this);
3509 constr
->top
.ResetIfWin((wxWindow
*)this);
3510 constr
->right
.ResetIfWin((wxWindow
*)this);
3511 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3512 constr
->width
.ResetIfWin((wxWindow
*)this);
3513 constr
->height
.ResetIfWin((wxWindow
*)this);
3514 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3515 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3520 delete m_constraintsInvolvedIn
;
3521 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3525 void wxWindow::SetSizer(wxSizer
*sizer
)
3527 m_windowSizer
= sizer
;
3529 sizer
->SetSizerParent((wxWindow
*)this);
3536 bool wxWindow::Layout()
3538 if (GetConstraints())
3541 GetClientSize(&w
, &h
);
3542 GetConstraints()->width
.SetValue(w
);
3543 GetConstraints()->height
.SetValue(h
);
3546 // If top level (one sizer), evaluate the sizer's constraints.
3550 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3551 GetSizer()->LayoutPhase1(&noChanges
);
3552 GetSizer()->LayoutPhase2(&noChanges
);
3553 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3559 // Otherwise, evaluate child constraints
3560 ResetConstraints(); // Mark all constraints as unevaluated
3561 DoPhase(1); // Just one phase need if no sizers involved
3563 SetConstraintSizes(); // Recursively set the real window sizes
3569 // Do a phase of evaluating constraints:
3570 // the default behaviour. wxSizers may do a similar
3571 // thing, but also impose their own 'constraints'
3572 // and order the evaluation differently.
3573 bool wxWindow::LayoutPhase1(int *noChanges
)
3575 wxLayoutConstraints
*constr
= GetConstraints();
3578 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3584 bool wxWindow::LayoutPhase2(int *noChanges
)
3594 // Do a phase of evaluating child constraints
3595 bool wxWindow::DoPhase(int phase
)
3597 int noIterations
= 0;
3598 int maxIterations
= 500;
3602 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3606 wxNode
*node
= m_children
.First();
3609 wxWindow
*child
= (wxWindow
*)node
->Data();
3610 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3612 wxLayoutConstraints
*constr
= child
->GetConstraints();
3615 if (succeeded
.Member(child
))
3620 int tempNoChanges
= 0;
3621 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3622 noChanges
+= tempNoChanges
;
3625 succeeded
.Append(child
);
3630 node
= node
->Next();
3637 void wxWindow::ResetConstraints()
3639 wxLayoutConstraints
*constr
= GetConstraints();
3642 constr
->left
.SetDone(FALSE
);
3643 constr
->top
.SetDone(FALSE
);
3644 constr
->right
.SetDone(FALSE
);
3645 constr
->bottom
.SetDone(FALSE
);
3646 constr
->width
.SetDone(FALSE
);
3647 constr
->height
.SetDone(FALSE
);
3648 constr
->centreX
.SetDone(FALSE
);
3649 constr
->centreY
.SetDone(FALSE
);
3651 wxNode
*node
= m_children
.First();
3654 wxWindow
*win
= (wxWindow
*)node
->Data();
3655 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3656 win
->ResetConstraints();
3657 node
= node
->Next();
3661 // Need to distinguish between setting the 'fake' size for
3662 // windows and sizers, and setting the real values.
3663 void wxWindow::SetConstraintSizes(bool recurse
)
3665 wxLayoutConstraints
*constr
= GetConstraints();
3666 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3667 constr
->width
.GetDone() && constr
->height
.GetDone())
3669 int x
= constr
->left
.GetValue();
3670 int y
= constr
->top
.GetValue();
3671 int w
= constr
->width
.GetValue();
3672 int h
= constr
->height
.GetValue();
3674 // If we don't want to resize this window, just move it...
3675 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3676 (constr
->height
.GetRelationship() != wxAsIs
))
3678 // Calls Layout() recursively. AAAGH. How can we stop that.
3679 // Simply take Layout() out of non-top level OnSizes.
3680 SizerSetSize(x
, y
, w
, h
);
3689 wxChar
*windowClass
= this->GetClassInfo()->GetClassName();
3692 if (GetName() == _T(""))
3693 winName
= _T("unnamed");
3695 winName
= GetName();
3696 wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"),
3697 (const wxChar
*)windowClass
,
3698 (const wxChar
*)winName
);
3699 if (!constr
->left
.GetDone()) wxLogDebug( _T(" unsatisfied 'left' constraint.\n") );
3700 if (!constr
->right
.GetDone()) wxLogDebug( _T(" unsatisfied 'right' constraint.\n") );
3701 if (!constr
->width
.GetDone()) wxLogDebug( _T(" unsatisfied 'width' constraint.\n") );
3702 if (!constr
->height
.GetDone()) wxLogDebug( _T(" unsatisfied 'height' constraint.\n") );
3703 wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") );
3708 wxNode
*node
= m_children
.First();
3711 wxWindow
*win
= (wxWindow
*)node
->Data();
3712 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3713 win
->SetConstraintSizes();
3714 node
= node
->Next();
3719 // This assumes that all sizers are 'on' the same
3720 // window, i.e. the parent of this window.
3721 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3723 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3724 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3728 m_sizerParent
->GetPosition(&xp
, &yp
);
3729 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3734 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3738 TransformSizerToActual(&xx
, &yy
);
3739 SetSize(xx
, yy
, w
, h
);
3742 void wxWindow::SizerMove(int x
, int y
)
3746 TransformSizerToActual(&xx
, &yy
);
3750 // Only set the size/position of the constraint (if any)
3751 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3753 wxLayoutConstraints
*constr
= GetConstraints();
3758 constr
->left
.SetValue(x
);
3759 constr
->left
.SetDone(TRUE
);
3763 constr
->top
.SetValue(y
);
3764 constr
->top
.SetDone(TRUE
);
3768 constr
->width
.SetValue(w
);
3769 constr
->width
.SetDone(TRUE
);
3773 constr
->height
.SetValue(h
);
3774 constr
->height
.SetDone(TRUE
);
3779 void wxWindow::MoveConstraint(int x
, int y
)
3781 wxLayoutConstraints
*constr
= GetConstraints();
3786 constr
->left
.SetValue(x
);
3787 constr
->left
.SetDone(TRUE
);
3791 constr
->top
.SetValue(y
);
3792 constr
->top
.SetDone(TRUE
);
3797 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3799 wxLayoutConstraints
*constr
= GetConstraints();
3802 *w
= constr
->width
.GetValue();
3803 *h
= constr
->height
.GetValue();
3809 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3811 wxLayoutConstraints
*constr
= GetConstraints();
3814 *w
= constr
->width
.GetValue();
3815 *h
= constr
->height
.GetValue();
3818 GetClientSize(w
, h
);
3821 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3823 wxLayoutConstraints
*constr
= GetConstraints();
3826 *x
= constr
->left
.GetValue();
3827 *y
= constr
->top
.GetValue();