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 wxPrintf( _T("FOCUS NOW AT: ") );
136 wxPrintf( _T("\n") );
141 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
147 wxChar
*s
= new wxChar
[tmp
.Length()+1];
151 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
152 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
157 //-----------------------------------------------------------------------------
159 //-----------------------------------------------------------------------------
161 extern wxList wxPendingDelete
;
162 extern bool g_blockEventsOnDrag
;
163 extern bool g_blockEventsOnScroll
;
164 extern bool g_isIdle
;
165 static bool g_capturing
= FALSE
;
166 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
168 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
169 the last click here */
170 static guint32 gs_timeLastClick
= 0;
172 //-----------------------------------------------------------------------------
174 //-----------------------------------------------------------------------------
176 extern void wxapp_install_idle_handler();
177 extern bool g_isIdle
;
179 #if (GTK_MINOR_VERSION > 0)
181 //-----------------------------------------------------------------------------
182 // local code (see below)
183 //-----------------------------------------------------------------------------
185 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
187 if (!win
->HasVMT()) return;
192 if (win
->m_hasScrolling
)
194 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
195 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
198 GtkWidget *hscrollbar = scroll_window->hscrollbar;
199 GtkWidget *vscrollbar = scroll_window->vscrollbar;
201 we use this instead: range.slider_width = 11 + 2*2pts edge
204 if (scroll_window
->vscrollbar_visible
)
206 dw
+= 15; /* dw += vscrollbar->allocation.width; */
207 dw
+= scroll_class
->scrollbar_spacing
;
210 if (scroll_window
->hscrollbar_visible
)
212 dh
+= 15; /* dh += hscrollbar->allocation.height; */
213 dw
+= scroll_class
->scrollbar_spacing
;
219 if (GTK_WIDGET_NO_WINDOW (widget
))
221 dx
+= widget
->allocation
.x
;
222 dy
+= widget
->allocation
.y
;
225 if (win
->m_windowStyle
& wxRAISED_BORDER
)
227 gtk_draw_shadow( widget
->style
,
232 win
->m_width
-dw
, win
->m_height
-dh
);
236 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
238 gtk_draw_shadow( widget
->style
,
243 win
->m_width
-dw
, win
->m_height
-dh
);
248 //-----------------------------------------------------------------------------
249 // "expose_event" of m_widget
250 //-----------------------------------------------------------------------------
252 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
254 if (gdk_event
->count
> 0) return;
255 draw_frame( widget
, win
);
258 //-----------------------------------------------------------------------------
259 // "draw" of m_wxwindow
260 //-----------------------------------------------------------------------------
262 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
264 draw_frame( widget
, win
);
269 //-----------------------------------------------------------------------------
270 // "expose_event" of m_wxwindow
271 //-----------------------------------------------------------------------------
273 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
275 if (g_isIdle
) wxapp_install_idle_handler();
277 if (!win
->HasVMT()) return;
279 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
281 gdk_event
->area
.width
,
282 gdk_event
->area
.height
);
284 if (gdk_event
->count
> 0) return;
287 printf( "OnExpose from " );
288 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
289 printf( win->GetClassInfo()->GetClassName() );
293 wxPaintEvent
event( win
->GetId() );
294 event
.SetEventObject( win
);
295 win
->GetEventHandler()->ProcessEvent( event
);
297 win
->m_updateRegion
.Clear();
300 //-----------------------------------------------------------------------------
301 // "draw" of m_wxwindow
302 //-----------------------------------------------------------------------------
304 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
306 if (g_isIdle
) wxapp_install_idle_handler();
308 if (!win
->HasVMT()) return;
310 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
312 wxPaintEvent
event( win
->GetId() );
313 event
.SetEventObject( win
);
314 win
->GetEventHandler()->ProcessEvent( event
);
316 win
->m_updateRegion
.Clear();
319 //-----------------------------------------------------------------------------
320 // "key_press_event" from any window
321 //-----------------------------------------------------------------------------
323 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
325 if (g_isIdle
) wxapp_install_idle_handler();
327 if (!win
->HasVMT()) return FALSE
;
328 if (g_blockEventsOnDrag
) return FALSE
;
331 wxPrintf( _T("OnKeyPress from ") );
332 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
333 wxPrintf( win->GetClassInfo()->GetClassName() );
334 wxPrintf( _T(".\n") );
338 switch (gdk_event
->keyval
)
340 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
341 case GDK_ISO_Left_Tab
:
343 case GDK_Tab
: key_code
= WXK_TAB
; break;
344 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
345 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
346 case GDK_Return
: key_code
= WXK_RETURN
; break;
347 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
348 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
349 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
350 case GDK_Delete
: key_code
= WXK_DELETE
; break;
351 case GDK_Home
: key_code
= WXK_HOME
; break;
352 case GDK_Left
: key_code
= WXK_LEFT
; break;
353 case GDK_Up
: key_code
= WXK_UP
; break;
354 case GDK_Right
: key_code
= WXK_RIGHT
; break;
355 case GDK_Down
: key_code
= WXK_DOWN
; break;
356 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
357 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
358 case GDK_Next
: key_code
= WXK_NEXT
; break;
359 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
360 case GDK_End
: key_code
= WXK_END
; break;
361 case GDK_Begin
: key_code
= WXK_HOME
; break;
362 case GDK_Select
: key_code
= WXK_SELECT
; break;
363 case GDK_Print
: key_code
= WXK_PRINT
; break;
364 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
365 case GDK_Insert
: key_code
= WXK_INSERT
; break;
366 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
367 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
368 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
369 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
370 case GDK_KP_Up
: key_code
= WXK_UP
; break;
371 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
372 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
373 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
374 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
375 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
376 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
377 case GDK_KP_End
: key_code
= WXK_END
; break;
378 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
379 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
380 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
381 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
382 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
383 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
384 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
385 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
386 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
387 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
388 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
389 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
390 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
391 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
392 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
393 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
394 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
395 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
396 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
397 case GDK_F1
: key_code
= WXK_F1
; break;
398 case GDK_F2
: key_code
= WXK_F2
; break;
399 case GDK_F3
: key_code
= WXK_F3
; break;
400 case GDK_F4
: key_code
= WXK_F4
; break;
401 case GDK_F5
: key_code
= WXK_F5
; break;
402 case GDK_F6
: key_code
= WXK_F6
; break;
403 case GDK_F7
: key_code
= WXK_F7
; break;
404 case GDK_F8
: key_code
= WXK_F8
; break;
405 case GDK_F9
: key_code
= WXK_F9
; break;
406 case GDK_F10
: key_code
= WXK_F10
; break;
407 case GDK_F11
: key_code
= WXK_F11
; break;
408 case GDK_F12
: key_code
= WXK_F12
; break;
411 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
412 key_code
= gdk_event
->keyval
;
416 if (!key_code
) return FALSE
;
418 wxKeyEvent
event( wxEVT_KEY_DOWN
);
419 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
420 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
421 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
422 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
423 event
.m_keyCode
= key_code
;
426 event
.SetEventObject( win
);
428 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
432 wxWindow
*ancestor
= win
;
435 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
438 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
439 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
442 ancestor
= ancestor
->GetParent();
446 // win is a control: tab can be propagated up
448 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
449 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
451 wxNavigationKeyEvent new_event
;
452 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
453 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
454 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
455 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
456 new_event
.SetCurrentFocus( win
);
457 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
461 (gdk_event
->keyval
== GDK_Escape
) )
463 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
464 new_event
.SetEventObject( win
);
465 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
469 Damn, I forgot why this didn't work, but it didn't work.
471 // win is a panel: up can be propagated to the panel
472 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
473 (gdk_event->keyval == GDK_Up))
475 win->m_parent->SetFocus();
479 // win is a panel: left/right can be propagated to the panel
480 if ((!ret) && (win->m_wxwindow) &&
481 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
482 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
484 wxNavigationKeyEvent new_event;
485 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
486 new_event.SetCurrentFocus( win );
487 ret = win->GetEventHandler()->ProcessEvent( new_event );
493 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
500 //-----------------------------------------------------------------------------
501 // "key_release_event" from any window
502 //-----------------------------------------------------------------------------
504 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
506 if (g_isIdle
) wxapp_install_idle_handler();
508 if (!win
->HasVMT()) return FALSE
;
509 if (g_blockEventsOnDrag
) return FALSE
;
512 printf( "OnKeyRelease from " );
513 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
514 printf( win->GetClassInfo()->GetClassName() );
519 switch (gdk_event
->keyval
)
521 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
522 case GDK_ISO_Left_Tab
:
524 case GDK_Tab
: key_code
= WXK_TAB
; break;
525 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
526 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
527 case GDK_Return
: key_code
= WXK_RETURN
; break;
528 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
529 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
530 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
531 case GDK_Delete
: key_code
= WXK_DELETE
; break;
532 case GDK_Home
: key_code
= WXK_HOME
; break;
533 case GDK_Left
: key_code
= WXK_LEFT
; break;
534 case GDK_Up
: key_code
= WXK_UP
; break;
535 case GDK_Right
: key_code
= WXK_RIGHT
; break;
536 case GDK_Down
: key_code
= WXK_DOWN
; break;
537 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
538 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
539 case GDK_Next
: key_code
= WXK_NEXT
; break;
540 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
541 case GDK_End
: key_code
= WXK_END
; break;
542 case GDK_Begin
: key_code
= WXK_HOME
; break;
543 case GDK_Select
: key_code
= WXK_SELECT
; break;
544 case GDK_Print
: key_code
= WXK_PRINT
; break;
545 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
546 case GDK_Insert
: key_code
= WXK_INSERT
; break;
547 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
548 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
549 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
550 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
551 case GDK_KP_Up
: key_code
= WXK_UP
; break;
552 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
553 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
554 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
555 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
556 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
557 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
558 case GDK_KP_End
: key_code
= WXK_END
; break;
559 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
560 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
561 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
562 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
563 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
564 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
565 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
566 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
567 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
568 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
569 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
570 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
571 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
572 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
573 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
574 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
575 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
576 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
577 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
578 case GDK_F1
: key_code
= WXK_F1
; break;
579 case GDK_F2
: key_code
= WXK_F2
; break;
580 case GDK_F3
: key_code
= WXK_F3
; break;
581 case GDK_F4
: key_code
= WXK_F4
; break;
582 case GDK_F5
: key_code
= WXK_F5
; break;
583 case GDK_F6
: key_code
= WXK_F6
; break;
584 case GDK_F7
: key_code
= WXK_F7
; break;
585 case GDK_F8
: key_code
= WXK_F8
; break;
586 case GDK_F9
: key_code
= WXK_F9
; break;
587 case GDK_F10
: key_code
= WXK_F10
; break;
588 case GDK_F11
: key_code
= WXK_F11
; break;
589 case GDK_F12
: key_code
= WXK_F12
; break;
592 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
593 key_code
= gdk_event
->keyval
;
597 if (!key_code
) return FALSE
;
599 wxKeyEvent
event( wxEVT_KEY_UP
);
600 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
601 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
602 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
603 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
604 event
.m_keyCode
= key_code
;
607 event
.SetEventObject( win
);
609 if (win
->GetEventHandler()->ProcessEvent( event
))
611 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
618 //-----------------------------------------------------------------------------
619 // "button_press_event"
620 //-----------------------------------------------------------------------------
622 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
624 if (g_isIdle
) wxapp_install_idle_handler();
627 wxPrintf( _T("1) OnButtonPress from ") );
628 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
629 wxPrintf( win->GetClassInfo()->GetClassName() );
630 wxPrintf( _T(".\n") );
633 if (!win
->HasVMT()) return FALSE
;
634 if (g_blockEventsOnDrag
) return TRUE
;
635 if (g_blockEventsOnScroll
) return TRUE
;
637 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
641 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
643 gtk_widget_grab_focus (win
->m_wxwindow
);
646 wxPrintf( _T("GrabFocus from ") );
647 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
648 wxPrintf( win->GetClassInfo()->GetClassName() );
649 wxPrintf( _T(".\n") );
656 wxPrintf( _T("No GrabFocus from ") );
657 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
658 wxPrintf( win->GetClassInfo()->GetClassName() );
659 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
660 wxPrintf( _T(" because it already has") );
661 wxPrintf( _T(".\n") );
667 wxPrintf( _T("2) OnButtonPress from ") );
668 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
669 wxPrintf( win->GetClassInfo()->GetClassName() );
670 wxPrintf( _T(".\n") );
673 wxEventType event_type
= wxEVT_LEFT_DOWN
;
675 if (gdk_event
->button
== 1)
677 switch (gdk_event
->type
)
679 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
680 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
684 else if (gdk_event
->button
== 2)
686 switch (gdk_event
->type
)
688 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
689 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
693 else if (gdk_event
->button
== 3)
695 switch (gdk_event
->type
)
697 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
698 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
703 wxMouseEvent
event( event_type
);
704 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
705 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
706 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
707 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
708 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
709 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
710 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
712 event
.m_x
= (long)gdk_event
->x
;
713 event
.m_y
= (long)gdk_event
->y
;
715 // Some control don't have their own X window and thus cannot get
720 wxNode
*node
= win
->GetChildren().First();
723 wxWindow
*child
= (wxWindow
*)node
->Data();
725 if (child
->m_isStaticBox
)
727 // wxStaticBox is transparent in the box itself
730 int xx1
= child
->m_x
;
731 int yy1
= child
->m_y
;
732 int xx2
= child
->m_x
+ child
->m_width
;
733 int yy2
= child
->m_x
+ child
->m_height
;
736 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
738 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
740 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
742 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
745 event
.m_x
-= child
->m_x
;
746 event
.m_y
-= child
->m_y
;
753 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
754 (child
->m_x
<= event
.m_x
) &&
755 (child
->m_y
<= event
.m_y
) &&
756 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
757 (child
->m_y
+child
->m_height
>= event
.m_y
))
760 event
.m_x
-= child
->m_x
;
761 event
.m_y
-= child
->m_y
;
769 event
.SetEventObject( win
);
771 gs_timeLastClick
= gdk_event
->time
;
773 if (win
->GetEventHandler()->ProcessEvent( event
))
775 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
782 //-----------------------------------------------------------------------------
783 // "button_release_event"
784 //-----------------------------------------------------------------------------
786 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
788 if (g_isIdle
) wxapp_install_idle_handler();
790 if (!win
->HasVMT()) return FALSE
;
791 if (g_blockEventsOnDrag
) return FALSE
;
792 if (g_blockEventsOnScroll
) return FALSE
;
794 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
797 printf( "OnButtonRelease from " );
798 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
799 printf( win->GetClassInfo()->GetClassName() );
803 wxEventType event_type
= wxEVT_NULL
;
805 switch (gdk_event
->button
)
807 case 1: event_type
= wxEVT_LEFT_UP
; break;
808 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
809 case 3: event_type
= wxEVT_RIGHT_UP
; break;
812 wxMouseEvent
event( event_type
);
813 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
814 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
815 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
816 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
817 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
818 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
819 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
820 event
.m_x
= (long)gdk_event
->x
;
821 event
.m_y
= (long)gdk_event
->y
;
823 // Some control don't have their own X window and thus cannot get
828 wxNode
*node
= win
->GetChildren().First();
831 wxWindow
*child
= (wxWindow
*)node
->Data();
833 if (child
->m_isStaticBox
)
835 // wxStaticBox is transparent in the box itself
838 int xx1
= child
->m_x
;
839 int yy1
= child
->m_y
;
840 int xx2
= child
->m_x
+ child
->m_width
;
841 int yy2
= child
->m_x
+ child
->m_height
;
844 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
846 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
848 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
850 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
853 event
.m_x
-= child
->m_x
;
854 event
.m_y
-= child
->m_y
;
861 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
862 (child
->m_x
<= event
.m_x
) &&
863 (child
->m_y
<= event
.m_y
) &&
864 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
865 (child
->m_y
+child
->m_height
>= event
.m_y
))
868 event
.m_x
-= child
->m_x
;
869 event
.m_y
-= child
->m_y
;
877 event
.SetEventObject( win
);
879 if (win
->GetEventHandler()->ProcessEvent( event
))
881 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
888 //-----------------------------------------------------------------------------
889 // "motion_notify_event"
890 //-----------------------------------------------------------------------------
892 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
894 if (g_isIdle
) wxapp_install_idle_handler();
896 if (!win
->HasVMT()) return FALSE
;
897 if (g_blockEventsOnDrag
) return FALSE
;
898 if (g_blockEventsOnScroll
) return FALSE
;
900 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
902 if (gdk_event
->is_hint
)
906 GdkModifierType state
;
907 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
910 gdk_event
->state
= state
;
914 printf( "OnMotion from " );
915 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
916 printf( win->GetClassInfo()->GetClassName() );
920 wxMouseEvent
event( wxEVT_MOTION
);
921 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
922 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
923 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
924 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
925 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
926 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
927 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
929 event
.m_x
= (long)gdk_event
->x
;
930 event
.m_y
= (long)gdk_event
->y
;
932 // Some control don't have their own X window and thus cannot get
937 wxNode
*node
= win
->GetChildren().First();
940 wxWindow
*child
= (wxWindow
*)node
->Data();
942 if (child
->m_isStaticBox
)
944 // wxStaticBox is transparent in the box itself
947 int xx1
= child
->m_x
;
948 int yy1
= child
->m_y
;
949 int xx2
= child
->m_x
+ child
->m_width
;
950 int yy2
= child
->m_x
+ child
->m_height
;
953 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
955 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
957 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
959 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
962 event
.m_x
-= child
->m_x
;
963 event
.m_y
-= child
->m_y
;
970 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
971 (child
->m_x
<= event
.m_x
) &&
972 (child
->m_y
<= event
.m_y
) &&
973 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
974 (child
->m_y
+child
->m_height
>= event
.m_y
))
977 event
.m_x
-= child
->m_x
;
978 event
.m_y
-= child
->m_y
;
986 event
.SetEventObject( win
);
988 if (win
->GetEventHandler()->ProcessEvent( event
))
990 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
997 //-----------------------------------------------------------------------------
999 //-----------------------------------------------------------------------------
1001 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1003 if (g_isIdle
) wxapp_install_idle_handler();
1005 if (!win
->HasVMT()) return FALSE
;
1006 if (g_blockEventsOnDrag
) return FALSE
;
1008 g_focusWindow
= win
;
1010 if (win
->m_wxwindow
)
1012 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1014 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1016 printf( "SetFocus flag from " );
1017 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1018 printf( win->GetClassInfo()->GetClassName() );
1026 wxPrintf( _T("OnSetFocus from ") );
1027 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1028 wxPrintf( win->GetClassInfo()->GetClassName() );
1029 wxPrintf( _T(" ") );
1030 wxPrintf( win->GetLabel() );
1031 wxPrintf( _T(".\n") );
1034 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1035 event
.SetEventObject( win
);
1037 if (win
->GetEventHandler()->ProcessEvent( event
))
1039 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1046 //-----------------------------------------------------------------------------
1047 // "focus_out_event"
1048 //-----------------------------------------------------------------------------
1050 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1052 if (g_isIdle
) wxapp_install_idle_handler();
1054 if (!win
->HasVMT()) return FALSE
;
1055 if (g_blockEventsOnDrag
) return FALSE
;
1057 if (win
->m_wxwindow
)
1059 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1060 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1064 wxPrintf( _T("OnKillFocus from ") );
1065 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1066 wxPrintf( win->GetClassInfo()->GetClassName() );
1067 wxPrintf( _T(" ") );
1068 wxPrintf( win->GetLabel() );
1069 wxPrintf( _T(".\n") );
1072 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1073 event
.SetEventObject( win
);
1075 if (win
->GetEventHandler()->ProcessEvent( event
))
1077 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1084 //-----------------------------------------------------------------------------
1085 // "enter_notify_event"
1086 //-----------------------------------------------------------------------------
1088 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1090 if (g_isIdle
) wxapp_install_idle_handler();
1092 if (!win
->HasVMT()) return FALSE
;
1093 if (g_blockEventsOnDrag
) return FALSE
;
1095 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1097 if ((widget
->window
) && (win
->m_cursor
.Ok()))
1098 gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() );
1101 printf( "OnEnter from " );
1102 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1103 printf( win->GetClassInfo()->GetClassName() );
1107 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1108 event
.SetEventObject( win
);
1112 GdkModifierType state
= (GdkModifierType
)0;
1114 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1116 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1117 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1118 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1119 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1120 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1121 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1122 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1124 event
.m_x
= (long)x
;
1125 event
.m_y
= (long)y
;
1127 if (win
->GetEventHandler()->ProcessEvent( event
))
1129 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1136 //-----------------------------------------------------------------------------
1137 // "leave_notify_event"
1138 //-----------------------------------------------------------------------------
1140 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1142 if (g_isIdle
) wxapp_install_idle_handler();
1144 if (!win
->HasVMT()) return FALSE
;
1145 if (g_blockEventsOnDrag
) return FALSE
;
1147 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1150 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1153 printf( "OnLeave from " );
1154 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1155 printf( win->GetClassInfo()->GetClassName() );
1159 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1160 event
.SetEventObject( win
);
1164 GdkModifierType state
= (GdkModifierType
)0;
1166 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1168 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1169 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1170 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1171 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1172 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1173 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1174 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1176 event
.m_x
= (long)x
;
1177 event
.m_y
= (long)y
;
1179 if (win
->GetEventHandler()->ProcessEvent( event
))
1181 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1188 //-----------------------------------------------------------------------------
1189 // "value_changed" from m_vAdjust
1190 //-----------------------------------------------------------------------------
1192 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1194 if (g_isIdle
) wxapp_install_idle_handler();
1196 if (g_blockEventsOnDrag
) return;
1199 printf( "OnVScroll from " );
1200 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1201 printf( win->GetClassInfo()->GetClassName() );
1205 if (!win
->HasVMT()) return;
1207 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1208 if (fabs(diff
) < 0.2) return;
1209 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1211 wxEventType command
= wxEVT_NULL
;
1213 float line_step
= win
->m_vAdjust
->step_increment
;
1214 float page_step
= win
->m_vAdjust
->page_increment
;
1216 if (win
->m_isScrolling
)
1218 command
= wxEVT_SCROLL_THUMBTRACK
;
1222 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1223 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1224 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1225 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1226 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1227 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1228 else command
= wxEVT_SCROLL_THUMBTRACK
;
1231 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1233 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1234 event
.SetEventObject( win
);
1235 win
->GetEventHandler()->ProcessEvent( event
);
1238 //-----------------------------------------------------------------------------
1239 // "value_changed" from m_hAdjust
1240 //-----------------------------------------------------------------------------
1242 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1244 if (g_isIdle
) wxapp_install_idle_handler();
1246 if (g_blockEventsOnDrag
) return;
1249 printf( "OnHScroll from " );
1250 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1251 printf( win->GetClassInfo()->GetClassName() );
1255 if (!win
->HasVMT()) return;
1257 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1258 if (fabs(diff
) < 0.2) return;
1259 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1261 wxEventType command
= wxEVT_NULL
;
1263 float line_step
= win
->m_hAdjust
->step_increment
;
1264 float page_step
= win
->m_hAdjust
->page_increment
;
1266 if (win
->m_isScrolling
)
1268 command
= wxEVT_SCROLL_THUMBTRACK
;
1272 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1273 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1274 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1275 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1276 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1277 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1278 else command
= wxEVT_SCROLL_THUMBTRACK
;
1281 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1283 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1284 event
.SetEventObject( win
);
1285 win
->GetEventHandler()->ProcessEvent( event
);
1288 //-----------------------------------------------------------------------------
1289 // "changed" from m_vAdjust
1290 //-----------------------------------------------------------------------------
1292 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1294 if (g_isIdle
) wxapp_install_idle_handler();
1296 if (g_blockEventsOnDrag
) return;
1299 printf( "OnVScroll change from " );
1300 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1301 printf( win->GetClassInfo()->GetClassName() );
1305 if (!win
->HasVMT()) return;
1307 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1308 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1310 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1311 event
.SetEventObject( win
);
1312 win
->GetEventHandler()->ProcessEvent( event
);
1315 //-----------------------------------------------------------------------------
1316 // "changed" from m_hAdjust
1317 //-----------------------------------------------------------------------------
1319 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1321 if (g_isIdle
) wxapp_install_idle_handler();
1323 if (g_blockEventsOnDrag
) return;
1326 printf( "OnHScroll change from " );
1327 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1328 printf( win->GetClassInfo()->GetClassName() );
1332 if (!win
->HasVMT()) return;
1334 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1335 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1337 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1338 event
.SetEventObject( win
);
1339 win
->GetEventHandler()->ProcessEvent( event
);
1342 //-----------------------------------------------------------------------------
1343 // "button_press_event" from scrollbar
1344 //-----------------------------------------------------------------------------
1346 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1347 GdkEventButton
*WXUNUSED(gdk_event
),
1350 if (g_isIdle
) wxapp_install_idle_handler();
1352 // don't test here as we can release the mouse while being over
1353 // a different window then the slider
1355 // if (gdk_event->window != widget->slider) return FALSE;
1357 win
->m_isScrolling
= TRUE
;
1358 g_blockEventsOnScroll
= TRUE
;
1363 //-----------------------------------------------------------------------------
1364 // "button_release_event" from scrollbar
1365 //-----------------------------------------------------------------------------
1367 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1368 GdkEventButton
*WXUNUSED(gdk_event
),
1371 if (g_isIdle
) wxapp_install_idle_handler();
1373 // don't test here as we can release the mouse while being over
1374 // a different window then the slider
1376 // if (gdk_event->window != widget->slider) return FALSE;
1378 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1380 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1381 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1383 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1385 win
->m_isScrolling
= FALSE
;
1386 g_blockEventsOnScroll
= FALSE
;
1391 //-----------------------------------------------------------------------------
1392 // "realize" from m_widget
1393 //-----------------------------------------------------------------------------
1395 /* we cannot set colours, fonts and cursors before the widget has
1396 been realized, so we do this directly after realization */
1399 gtk_window_realized_callback( GtkWidget
*widget
, wxWindow
*win
)
1401 if (g_isIdle
) wxapp_install_idle_handler();
1403 if (win
->m_font
!= *wxSWISS_FONT
)
1405 wxFont
font( win
->m_font
);
1406 win
->m_font
= wxNullFont
;
1407 win
->SetFont( font
);
1410 if (win
->m_backgroundColour
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
))
1412 wxColour
bg( win
->m_backgroundColour
);
1413 win
->m_backgroundColour
= wxNullColour
;
1414 win
->SetBackgroundColour( bg
);
1417 if (win
->m_foregroundColour
!= *wxBLACK
)
1419 wxColour
fg( win
->m_foregroundColour
);
1420 win
->m_foregroundColour
= wxNullColour
;
1421 win
->SetForegroundColour( fg
);
1424 wxCursor
cursor( win
->m_cursor
);
1425 win
->m_cursor
= wxNullCursor
;
1426 win
->SetCursor( cursor
);
1431 //-----------------------------------------------------------------------------
1432 // InsertChild for wxWindow.
1433 //-----------------------------------------------------------------------------
1435 /* Callback for wxWindow. This very strange beast has to be used because
1436 * C++ has no virtual methods in a constructor. We have to emulate a
1437 * virtual function here as wxNotebook requires a different way to insert
1438 * a child in it. I had opted for creating a wxNotebookPage window class
1439 * which would have made this superfluous (such in the MDI window system),
1440 * but no-one was listening to me... */
1442 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1444 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1445 GTK_WIDGET(child
->m_widget
),
1449 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1453 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1455 /* we now allow a window to get the focus as long as it
1456 doesn't have any children. */
1457 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1461 //-----------------------------------------------------------------------------
1463 //-----------------------------------------------------------------------------
1465 wxWindow
* wxGetActiveWindow()
1467 return g_focusWindow
;
1470 //-----------------------------------------------------------------------------
1472 //-----------------------------------------------------------------------------
1474 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1476 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1477 EVT_SIZE(wxWindow::OnSize
)
1478 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1479 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1480 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1483 void wxWindow::Init()
1487 m_widget
= (GtkWidget
*) NULL
;
1488 m_wxwindow
= (GtkWidget
*) NULL
;
1489 m_parent
= (wxWindow
*) NULL
;
1490 m_children
.DeleteContents( FALSE
);
1503 m_eventHandler
= this;
1504 m_windowValidator
= (wxValidator
*) NULL
;
1508 m_cursor
= *wxSTANDARD_CURSOR
;
1509 m_font
= *wxSWISS_FONT
;
1511 m_windowName
= "noname";
1513 m_constraints
= (wxLayoutConstraints
*) NULL
;
1514 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1515 m_windowSizer
= (wxSizer
*) NULL
;
1516 m_sizerParent
= (wxWindow
*) NULL
;
1517 m_autoLayout
= FALSE
;
1521 m_needParent
= TRUE
;
1523 m_hasScrolling
= FALSE
;
1524 m_isScrolling
= FALSE
;
1525 m_hAdjust
= (GtkAdjustment
*) NULL
;
1526 m_vAdjust
= (GtkAdjustment
*) NULL
;
1527 m_oldHorizontalPos
= 0.0;
1528 m_oldVerticalPos
= 0.0;
1533 #if wxUSE_DRAG_AND_DROP
1534 m_dropTarget
= (wxDropTarget
*) NULL
;
1537 m_scrollGC
= (GdkGC
*) NULL
;
1538 m_widgetStyle
= (GtkStyle
*) NULL
;
1540 m_insertCallback
= wxInsertChildInWindow
;
1542 m_clientObject
= (wxClientData
*) NULL
;
1543 m_clientData
= NULL
;
1545 m_isStaticBox
= FALSE
;
1546 m_acceptsFocus
= FALSE
;
1549 m_toolTip
= (wxToolTip
*) NULL
;
1550 #endif // wxUSE_TOOLTIPS
1553 wxWindow::wxWindow()
1558 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1559 const wxPoint
&pos
, const wxSize
&size
,
1560 long style
, const wxString
&name
)
1564 Create( parent
, id
, pos
, size
, style
, name
);
1567 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1568 const wxPoint
&pos
, const wxSize
&size
,
1569 long style
, const wxString
&name
)
1571 wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") );
1573 PreCreation( parent
, id
, pos
, size
, style
, name
);
1575 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1576 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1579 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1582 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1585 debug_focus_in( s_window
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1586 debug_focus_in( s_window
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1589 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1590 scroll_class
->scrollbar_spacing
= 0;
1592 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1594 m_oldHorizontalPos
= 0.0;
1595 m_oldVerticalPos
= 0.0;
1597 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1598 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1600 m_wxwindow
= gtk_myfixed_new();
1603 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1606 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1608 #if (GTK_MINOR_VERSION > 0)
1609 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1611 if (m_windowStyle
& wxRAISED_BORDER
)
1613 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1615 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1617 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1621 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1624 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1626 if (m_windowStyle
& wxRAISED_BORDER
)
1628 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1630 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1632 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1636 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1640 /* we always allow a window to get the focus as long as it
1641 doesn't have any children. */
1642 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1644 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1645 m_acceptsFocus
= FALSE
;
1649 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1650 m_acceptsFocus
= TRUE
;
1653 /* grab the actual focus */
1654 // gtk_widget_grab_focus( m_wxwindow );
1656 gtk_widget_show( m_wxwindow
);
1659 #if (GTK_MINOR_VERSION == 0)
1660 // shut the viewport up
1661 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1662 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1665 // I _really_ don't want scrollbars in the beginning
1666 m_vAdjust
->lower
= 0.0;
1667 m_vAdjust
->upper
= 1.0;
1668 m_vAdjust
->value
= 0.0;
1669 m_vAdjust
->step_increment
= 1.0;
1670 m_vAdjust
->page_increment
= 1.0;
1671 m_vAdjust
->page_size
= 5.0;
1672 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1673 m_hAdjust
->lower
= 0.0;
1674 m_hAdjust
->upper
= 1.0;
1675 m_hAdjust
->value
= 0.0;
1676 m_hAdjust
->step_increment
= 1.0;
1677 m_hAdjust
->page_increment
= 1.0;
1678 m_hAdjust
->page_size
= 5.0;
1679 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1681 // these handlers block mouse events to any window during scrolling
1682 // such as motion events and prevent GTK and wxWindows from fighting
1683 // over where the slider should be
1685 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1686 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1688 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1689 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1691 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1692 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1694 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1695 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1697 // these handlers get notified when screen updates are required either when
1698 // scrolling or when the window size (and therefore scrollbar configuration)
1701 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1702 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1703 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1704 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1706 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1707 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1708 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1709 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1711 if (m_parent
) m_parent
->AddChild( this );
1713 (m_parent
->m_insertCallback
)( m_parent
, this );
1722 wxWindow::~wxWindow()
1726 #if wxUSE_DRAG_AND_DROP
1729 delete m_dropTarget
;
1730 m_dropTarget
= (wxDropTarget
*) NULL
;
1738 m_toolTip
= (wxToolTip
*) NULL
;
1740 #endif // wxUSE_TOOLTIPS
1742 if (m_widget
) Show( FALSE
);
1746 if (m_parent
) m_parent
->RemoveChild( this );
1748 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1750 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1752 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1754 if (m_widget
) gtk_widget_destroy( m_widget
);
1756 DeleteRelatedConstraints();
1759 /* This removes any dangling pointers to this window
1760 * in other windows' constraintsInvolvedIn lists. */
1761 UnsetConstraints(m_constraints
);
1762 delete m_constraints
;
1763 m_constraints
= (wxLayoutConstraints
*) NULL
;
1768 delete m_windowSizer
;
1769 m_windowSizer
= (wxSizer
*) NULL
;
1771 /* If this is a child of a sizer, remove self from parent */
1772 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1774 /* Just in case the window has been Closed, but
1775 * we're then deleting immediately: don't leave
1776 * dangling pointers. */
1777 wxPendingDelete
.DeleteObject(this);
1779 /* Just in case we've loaded a top-level window via
1780 * wxWindow::LoadNativeDialog but we weren't a dialog
1782 wxTopLevelWindows
.DeleteObject(this);
1784 if (m_windowValidator
) delete m_windowValidator
;
1786 if (m_clientObject
) delete m_clientObject
;
1789 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1790 const wxPoint
&pos
, const wxSize
&size
,
1791 long style
, const wxString
&name
)
1793 wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") );
1795 m_widget
= (GtkWidget
*) NULL
;
1796 m_wxwindow
= (GtkWidget
*) NULL
;
1799 m_children
.DeleteContents( FALSE
);
1802 if (m_width
== -1) m_width
= 20;
1804 if (m_height
== -1) m_height
= 20;
1809 if (!m_needParent
) /* some reasonable defaults */
1813 m_x
= (gdk_screen_width () - m_width
) / 2;
1814 if (m_x
< 10) m_x
= 10;
1818 m_y
= (gdk_screen_height () - m_height
) / 2;
1819 if (m_y
< 10) m_y
= 10;
1830 m_eventHandler
= this;
1832 m_windowId
= id
== -1 ? wxNewId() : id
;
1836 m_cursor
= *wxSTANDARD_CURSOR
;
1837 m_font
= *wxSWISS_FONT
;
1838 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1839 m_foregroundColour
= *wxBLACK
;
1840 m_windowStyle
= style
;
1841 m_windowName
= name
;
1843 m_constraints
= (wxLayoutConstraints
*) NULL
;
1844 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1845 m_windowSizer
= (wxSizer
*) NULL
;
1846 m_sizerParent
= (wxWindow
*) NULL
;
1847 m_autoLayout
= FALSE
;
1849 m_hasScrolling
= FALSE
;
1850 m_isScrolling
= FALSE
;
1851 m_hAdjust
= (GtkAdjustment
*) NULL
;
1852 m_vAdjust
= (GtkAdjustment
*) NULL
;
1853 m_oldHorizontalPos
= 0.0;
1854 m_oldVerticalPos
= 0.0;
1859 #if wxUSE_DRAG_AND_DROP
1860 m_dropTarget
= (wxDropTarget
*) NULL
;
1863 m_windowValidator
= (wxValidator
*) NULL
;
1864 m_scrollGC
= (GdkGC
*) NULL
;
1865 m_widgetStyle
= (GtkStyle
*) NULL
;
1867 m_clientObject
= (wxClientData
*)NULL
;
1868 m_clientData
= NULL
;
1870 m_isStaticBox
= FALSE
;
1873 m_toolTip
= (wxToolTip
*) NULL
;
1874 #endif // wxUSE_TOOLTIPS
1877 void wxWindow::PostCreation()
1879 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1883 /* these get reported to wxWindows -> wxPaintEvent */
1884 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1885 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1887 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1888 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1890 #if (GTK_MINOR_VERSION > 0)
1891 /* these are called when the "sunken" or "raised" borders are drawn */
1892 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1893 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1895 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1896 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1900 GtkWidget
*connect_widget
= GetConnectWidget();
1902 ConnectWidget( connect_widget
);
1904 /* we cannot set colours, fonts and cursors before the widget has
1905 been realized, so we do this directly after realization */
1906 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1907 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1912 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1914 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1915 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1917 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1918 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1920 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1921 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1923 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1924 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1926 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1927 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1929 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1930 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1932 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1933 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1935 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1936 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1938 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1939 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1942 bool wxWindow::HasVMT()
1947 bool wxWindow::Close( bool force
)
1949 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1951 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1952 event
.SetEventObject(this);
1953 event
.SetCanVeto(!force
);
1955 /* return FALSE if window wasn't closed because the application vetoed the
1957 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1960 bool wxWindow::Destroy()
1962 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1969 bool wxWindow::DestroyChildren()
1972 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1975 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1978 if (m_children
.Member(child
)) delete node
;
1984 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1986 // are we to set fonts here ?
1989 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1991 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1992 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1994 if (m_resizing
) return; /* I don't like recursions */
1997 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1999 /* don't set the size for children of wxNotebook, just take the values. */
2007 int old_width
= m_width
;
2008 int old_height
= m_height
;
2010 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
2012 if (x
!= -1) m_x
= x
;
2013 if (y
!= -1) m_y
= y
;
2014 if (width
!= -1) m_width
= width
;
2015 if (height
!= -1) m_height
= height
;
2025 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2027 if (width
== -1) m_width
= 80;
2030 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2032 if (height
== -1) m_height
= 26;
2035 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2036 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2037 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2038 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2040 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
2042 /* the default button has a border around it */
2045 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
-border
, m_y
-border
);
2047 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
2051 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
2053 if ((old_width
!= m_width
) || (old_height
!= m_height
))
2056 GtkAllocation alloc;
2059 alloc.width = m_width;
2060 alloc.height = m_height;
2061 gtk_widget_size_allocate( m_widget, &alloc );
2063 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2070 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2071 event
.SetEventObject( this );
2072 GetEventHandler()->ProcessEvent( event
);
2077 void wxWindow::OnInternalIdle()
2082 void wxWindow::GetSize( int *width
, int *height
) const
2084 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2086 if (width
) (*width
) = m_width
;
2087 if (height
) (*height
) = m_height
;
2090 void wxWindow::DoSetClientSize( int width
, int height
)
2092 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2096 SetSize( width
, height
);
2103 if (!m_hasScrolling
)
2105 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2107 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2108 (m_windowStyle
& wxSUNKEN_BORDER
))
2110 dw
+= 2 * window_class
->xthickness
;
2111 dh
+= 2 * window_class
->ythickness
;
2116 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2117 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2119 #if (GTK_MINOR_VERSION == 0)
2120 GtkWidget
*viewport
= scroll_window
->viewport
;
2121 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2123 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2124 (m_windowStyle
& wxSUNKEN_BORDER
))
2126 dw
+= 2 * viewport_class
->xthickness
;
2127 dh
+= 2 * viewport_class
->ythickness
;
2132 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2133 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2135 we use this instead: range.slider_width = 11 + 2*2pts edge
2138 if (scroll_window
->vscrollbar_visible
)
2140 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2141 dw
+= scroll_class
->scrollbar_spacing
;
2144 if (scroll_window
->hscrollbar_visible
)
2146 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2147 dw
+= scroll_class
->scrollbar_spacing
;
2151 SetSize( width
+dw
, height
+dh
);
2155 void wxWindow::GetClientSize( int *width
, int *height
) const
2157 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2161 if (width
) (*width
) = m_width
;
2162 if (height
) (*height
) = m_height
;
2169 if (!m_hasScrolling
)
2171 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2173 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2174 (m_windowStyle
& wxSUNKEN_BORDER
))
2176 dw
+= 2 * window_class
->xthickness
;
2177 dh
+= 2 * window_class
->ythickness
;
2182 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2183 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2185 #if (GTK_MINOR_VERSION == 0)
2186 GtkWidget
*viewport
= scroll_window
->viewport
;
2187 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2189 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2190 (m_windowStyle
& wxSUNKEN_BORDER
))
2192 dw
+= 2 * viewport_class
->xthickness
;
2193 dh
+= 2 * viewport_class
->ythickness
;
2197 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2198 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2200 we use this instead: range.slider_width = 11 + 2*2pts edge
2203 if (scroll_window
->vscrollbar_visible
)
2205 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2206 dw
+= scroll_class
->scrollbar_spacing
;
2209 if (scroll_window
->hscrollbar_visible
)
2211 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2212 dh
+= scroll_class
->scrollbar_spacing
;
2216 if (width
) (*width
) = m_width
- dw
;
2217 if (height
) (*height
) = m_height
- dh
;
2221 void wxWindow::GetPosition( int *x
, int *y
) const
2223 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2229 void wxWindow::ClientToScreen( int *x
, int *y
)
2231 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2233 if (!m_widget
->window
) return;
2235 GdkWindow
*source
= (GdkWindow
*) NULL
;
2237 source
= m_wxwindow
->window
;
2239 source
= m_widget
->window
;
2243 gdk_window_get_origin( source
, &org_x
, &org_y
);
2247 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2249 org_x
+= m_widget
->allocation
.x
;
2250 org_y
+= m_widget
->allocation
.y
;
2258 void wxWindow::ScreenToClient( int *x
, int *y
)
2260 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2262 if (!m_widget
->window
) return;
2264 GdkWindow
*source
= (GdkWindow
*) NULL
;
2266 source
= m_wxwindow
->window
;
2268 source
= m_widget
->window
;
2272 gdk_window_get_origin( source
, &org_x
, &org_y
);
2276 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2278 org_x
+= m_widget
->allocation
.x
;
2279 org_y
+= m_widget
->allocation
.y
;
2287 void wxWindow::Centre( int direction
)
2289 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2298 m_parent
->GetSize( &p_w
, &p_h
);
2299 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2300 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2304 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2305 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2311 void wxWindow::Fit()
2313 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2317 wxNode
*node
= m_children
.First();
2320 wxWindow
*win
= (wxWindow
*)node
->Data();
2322 win
->GetPosition(&wx
, &wy
);
2323 win
->GetSize(&ww
, &wh
);
2324 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2325 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2327 node
= node
->Next();
2330 SetClientSize(maxX
+ 7, maxY
+ 14);
2333 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2335 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2343 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2345 /* this is commented because it also is commented
2346 in wxMSW. before I get even more questions about
2348 // if (GetAutoLayout()) Layout();
2351 bool wxWindow::Show( bool show
)
2353 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2355 if (show
== m_isShown
) return TRUE
;
2358 gtk_widget_show( m_widget
);
2360 gtk_widget_hide( m_widget
);
2367 void wxWindow::Enable( bool enable
)
2369 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2371 m_isEnabled
= enable
;
2373 gtk_widget_set_sensitive( m_widget
, enable
);
2374 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2377 int wxWindow::GetCharHeight() const
2379 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2381 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2383 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2385 return font
->ascent
+ font
->descent
;
2388 int wxWindow::GetCharWidth() const
2390 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2392 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2394 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2396 return gdk_string_width( font
, "H" );
2399 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2400 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2402 wxFont fontToUse
= m_font
;
2403 if (theFont
) fontToUse
= *theFont
;
2405 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2407 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2408 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2409 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2410 if (descent
) (*descent
) = font
->descent
;
2411 if (externalLeading
) (*externalLeading
) = 0; // ??
2414 void wxWindow::MakeModal( bool modal
)
2418 // Disable all other windows
2419 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2421 wxNode
*node
= wxTopLevelWindows
.First();
2424 wxWindow
*win
= (wxWindow
*)node
->Data();
2425 if (win
!= this) win
->Enable(!modal
);
2427 node
= node
->Next();
2432 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2434 event
.SetEventType( wxEVT_CHAR
);
2436 if (!GetEventHandler()->ProcessEvent( event
))
2442 void wxWindow::SetFocus()
2444 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2446 GtkWidget
*connect_widget
= GetConnectWidget();
2449 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2451 gtk_widget_grab_focus (connect_widget
);
2453 else if (GTK_IS_CONTAINER(connect_widget
))
2455 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2463 wxWindow
*wxWindow::FindFocus()
2465 return g_focusWindow
;
2468 bool wxWindow::AcceptsFocus() const
2470 return IsEnabled() && IsShown() && m_acceptsFocus
;
2473 void wxWindow::AddChild( wxWindow
*child
)
2475 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2476 wxCHECK_RET( (child
!= NULL
), _T("invalid child") );
2478 m_children
.Append( child
);
2481 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2483 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2485 wxWindow
*oldParent
= GetParent();
2487 if (oldParent
) oldParent
->RemoveChild( this );
2489 gtk_widget_unparent( m_widget
);
2493 newParent
->AddChild( this );
2494 (newParent
->m_insertCallback
)( newParent
, this );
2500 void wxWindow::RemoveChild( wxWindow
*child
)
2502 m_children
.DeleteObject( child
);
2503 child
->m_parent
= (wxWindow
*) NULL
;
2506 void wxWindow::SetReturnCode( int retCode
)
2508 m_retCode
= retCode
;
2511 int wxWindow::GetReturnCode()
2516 void wxWindow::Raise()
2518 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2520 if (!m_widget
->window
) return;
2522 if (m_widget
) gdk_window_raise( m_widget
->window
);
2525 void wxWindow::Lower()
2527 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2529 if (!m_widget
->window
) return;
2531 if (m_widget
) gdk_window_lower( m_widget
->window
);
2534 wxEvtHandler
*wxWindow::GetEventHandler() const
2536 return m_eventHandler
;
2539 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2541 m_eventHandler
= handler
;
2544 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2546 handler
->SetNextHandler(GetEventHandler());
2547 SetEventHandler(handler
);
2550 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2552 if (GetEventHandler())
2554 wxEvtHandler
*handlerA
= GetEventHandler();
2555 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2556 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2557 SetEventHandler(handlerB
);
2561 return (wxEvtHandler
*) NULL
;
2567 return (wxEvtHandler
*) NULL
;
2570 wxValidator
*wxWindow::GetValidator()
2572 return m_windowValidator
;
2575 void wxWindow::SetValidator( const wxValidator
& validator
)
2577 if (m_windowValidator
) delete m_windowValidator
;
2578 m_windowValidator
= (wxValidator
*)validator
.Clone();
2579 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2582 void wxWindow::SetClientObject( wxClientData
*data
)
2584 if (m_clientObject
) delete m_clientObject
;
2585 m_clientObject
= data
;
2588 wxClientData
*wxWindow::GetClientObject()
2590 return m_clientObject
;
2593 void wxWindow::SetClientData( void *data
)
2595 m_clientData
= data
;
2598 void *wxWindow::GetClientData()
2600 return m_clientData
;
2603 bool wxWindow::IsBeingDeleted()
2608 void wxWindow::SetId( wxWindowID id
)
2613 wxWindowID
wxWindow::GetId() const
2618 void wxWindow::SetCursor( const wxCursor
&cursor
)
2620 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2624 if (cursor
== m_cursor
) return;
2629 m_cursor
= *wxSTANDARD_CURSOR
;
2632 if (!m_widget
->window
) return;
2634 gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() );
2636 if ((m_wxwindow
) && (m_wxwindow
->window
))
2637 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() );
2640 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2645 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2647 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2649 if (!m_widget
->window
) return;
2651 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2655 gdk_window_clear_area( m_wxwindow
->window
,
2657 rect
->width
, rect
->height
);
2661 gdk_window_clear( m_wxwindow
->window
);
2668 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2670 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2674 GdkRectangle gdk_rect
;
2675 gdk_rect
.x
= rect
->x
;
2676 gdk_rect
.y
= rect
->y
;
2677 gdk_rect
.width
= rect
->width
;
2678 gdk_rect
.height
= rect
->height
;
2681 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2683 gtk_widget_draw( m_widget
, &gdk_rect
);
2687 wxRegion
wxWindow::GetUpdateRegion() const
2689 return m_updateRegion
;
2692 bool wxWindow::IsExposed( int x
, int y
) const
2694 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2697 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2699 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2702 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2704 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2707 bool wxWindow::IsExposed( const wxRect
& rect
) const
2709 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2712 void wxWindow::Clear()
2714 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2716 if (!m_widget
->window
) return;
2718 if (m_wxwindow
&& m_wxwindow
->window
)
2720 gdk_window_clear( m_wxwindow
->window
);
2725 void wxWindow::SetToolTip( const wxString
&tip
)
2729 m_toolTip
->SetTip( tip
);
2733 SetToolTip( new wxToolTip( tip
) );
2736 // setting empty tooltip text does not remove the tooltip any more for
2737 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2740 void wxWindow::SetToolTip( wxToolTip
*tip
)
2744 m_toolTip
->SetTip( (char*) NULL
);
2751 m_toolTip
->Apply( this );
2754 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2756 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2758 #endif // wxUSE_TOOLTIPS
2760 wxColour
wxWindow::GetBackgroundColour() const
2762 return m_backgroundColour
;
2765 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2767 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2769 if (m_backgroundColour
== colour
) return;
2771 m_backgroundColour
= colour
;
2772 if (!m_backgroundColour
.Ok()) return;
2774 GtkWidget
*connect_widget
= GetConnectWidget();
2775 if (!connect_widget
->window
) return;
2777 if (m_wxwindow
&& m_wxwindow
->window
)
2779 /* wxMSW doesn't clear the window here. I don't do that
2780 either to provide compatibility. call Clear() to do
2783 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2784 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2787 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2789 if (sysbg
.Red() == colour
.Red() &&
2790 sysbg
.Green() == colour
.Green() &&
2791 sysbg
.Blue() == colour
.Blue())
2793 m_backgroundColour
= wxNullColour
;
2795 m_backgroundColour
= sysbg
;
2803 wxColour
wxWindow::GetForegroundColour() const
2805 return m_foregroundColour
;
2808 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2810 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2812 if (m_foregroundColour
== colour
) return;
2814 m_foregroundColour
= colour
;
2815 if (!m_foregroundColour
.Ok()) return;
2817 if (!m_widget
->window
) return;
2819 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2820 if (sysbg
.Red() == colour
.Red() &&
2821 sysbg
.Green() == colour
.Green() &&
2822 sysbg
.Blue() == colour
.Blue())
2824 m_backgroundColour
= wxNullColour
;
2826 m_backgroundColour
= sysbg
;
2834 GtkStyle
*wxWindow::GetWidgetStyle()
2836 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2840 gtk_widget_get_style( m_widget
) );
2842 return m_widgetStyle
;
2845 void wxWindow::SetWidgetStyle()
2847 GtkStyle
*style
= GetWidgetStyle();
2849 gdk_font_unref( style
->font
);
2850 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2852 if (m_foregroundColour
.Ok())
2854 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2855 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2856 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2857 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2860 if (m_backgroundColour
.Ok())
2862 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2863 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2864 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2865 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2866 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2867 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2868 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2869 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2870 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2874 void wxWindow::ApplyWidgetStyle()
2878 bool wxWindow::Validate()
2880 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2882 wxNode
*node
= m_children
.First();
2885 wxWindow
*child
= (wxWindow
*)node
->Data();
2886 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2890 node
= node
->Next();
2895 bool wxWindow::TransferDataToWindow()
2897 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2899 wxNode
*node
= m_children
.First();
2902 wxWindow
*child
= (wxWindow
*)node
->Data();
2903 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2904 !child
->GetValidator()->TransferToWindow() )
2906 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2909 node
= node
->Next();
2914 bool wxWindow::TransferDataFromWindow()
2916 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2918 wxNode
*node
= m_children
.First();
2921 wxWindow
*child
= (wxWindow
*)node
->Data();
2922 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2926 node
= node
->Next();
2931 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2933 m_acceleratorTable
= accel
;
2936 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2938 TransferDataToWindow();
2941 void wxWindow::InitDialog()
2943 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2945 wxInitDialogEvent
event(GetId());
2946 event
.SetEventObject( this );
2947 GetEventHandler()->ProcessEvent(event
);
2950 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2952 menu
->SetInvokingWindow( win
);
2953 wxNode
*node
= menu
->GetItems().First();
2956 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2957 if (menuitem
->IsSubMenu())
2959 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2961 node
= node
->Next();
2965 static gint gs_pop_x
= 0;
2966 static gint gs_pop_y
= 0;
2968 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2970 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2975 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2977 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2979 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2981 SetInvokingWindow( menu
, this );
2989 GTK_MENU(menu
->m_menu
),
2990 (GtkWidget
*) NULL
, // parent menu shell
2991 (GtkWidget
*) NULL
, // parent menu item
2992 (GtkMenuPositionFunc
) pop_pos_callback
,
2993 (gpointer
) this, // client data
2994 0, // button used to activate it
2995 0 //gs_timeLastClick // the time of activation
3000 #if wxUSE_DRAG_AND_DROP
3002 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
3004 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3006 GtkWidget
*dnd_widget
= GetConnectWidget();
3008 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
3010 if (m_dropTarget
) delete m_dropTarget
;
3011 m_dropTarget
= dropTarget
;
3013 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
3016 wxDropTarget
*wxWindow::GetDropTarget() const
3018 return m_dropTarget
;
3023 GtkWidget
* wxWindow::GetConnectWidget()
3025 GtkWidget
*connect_widget
= m_widget
;
3026 if (m_wxwindow
) connect_widget
= m_wxwindow
;
3028 return connect_widget
;
3031 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
3033 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
3034 return (window
== m_widget
->window
);
3037 void wxWindow::SetFont( const wxFont
&font
)
3039 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3041 if (m_font
== font
) return;
3043 if (((wxFont
*)&font
)->Ok())
3046 m_font
= *wxSWISS_FONT
;
3048 if (!m_widget
->window
) return;
3050 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3051 if (sysbg
.Red() == m_backgroundColour
.Red() &&
3052 sysbg
.Green() == m_backgroundColour
.Green() &&
3053 sysbg
.Blue() == m_backgroundColour
.Blue())
3055 m_backgroundColour
= wxNullColour
;
3057 m_backgroundColour
= sysbg
;
3065 void wxWindow::SetWindowStyleFlag( long flag
)
3067 m_windowStyle
= flag
;
3070 long wxWindow::GetWindowStyleFlag() const
3072 return m_windowStyle
;
3075 void wxWindow::CaptureMouse()
3077 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3079 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
3081 if (!m_widget
->window
) return;
3083 GtkWidget
*connect_widget
= GetConnectWidget();
3084 gtk_grab_add( connect_widget
);
3085 gdk_pointer_grab( connect_widget
->window
, FALSE
,
3087 (GDK_BUTTON_PRESS_MASK
|
3088 GDK_BUTTON_RELEASE_MASK
|
3089 GDK_POINTER_MOTION_MASK
),
3096 void wxWindow::ReleaseMouse()
3098 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3100 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
3102 if (!m_widget
->window
) return;
3104 GtkWidget
*connect_widget
= GetConnectWidget();
3105 gtk_grab_remove( connect_widget
);
3106 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3107 g_capturing
= FALSE
;
3110 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
3114 wxString
wxWindow::GetTitle() const
3116 return (wxString
&)m_windowName
;
3119 wxString
wxWindow::GetLabel() const
3124 void wxWindow::SetName( const wxString
&name
)
3126 m_windowName
= name
;
3129 wxString
wxWindow::GetName() const
3131 return (wxString
&)m_windowName
;
3134 bool wxWindow::IsShown() const
3139 bool wxWindow::IsRetained()
3144 wxWindow
*wxWindow::FindWindow( long id
)
3146 if (id
== m_windowId
) return this;
3147 wxNode
*node
= m_children
.First();
3150 wxWindow
*child
= (wxWindow
*)node
->Data();
3151 wxWindow
*res
= child
->FindWindow( id
);
3152 if (res
) return res
;
3153 node
= node
->Next();
3155 return (wxWindow
*) NULL
;
3158 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
3160 if (name
== m_windowName
) return this;
3161 wxNode
*node
= m_children
.First();
3164 wxWindow
*child
= (wxWindow
*)node
->Data();
3165 wxWindow
*res
= child
->FindWindow( name
);
3166 if (res
) return res
;
3167 node
= node
->Next();
3169 return (wxWindow
*) NULL
;
3172 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3173 int range
, bool refresh
)
3175 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3177 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3179 m_hasScrolling
= TRUE
;
3181 if (orient
== wxHORIZONTAL
)
3183 float fpos
= (float)pos
;
3184 float frange
= (float)range
;
3185 float fthumb
= (float)thumbVisible
;
3186 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3187 if (fpos
< 0.0) fpos
= 0.0;
3189 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3190 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3192 SetScrollPos( orient
, pos
, refresh
);
3196 m_oldHorizontalPos
= fpos
;
3198 m_hAdjust
->lower
= 0.0;
3199 m_hAdjust
->upper
= frange
;
3200 m_hAdjust
->value
= fpos
;
3201 m_hAdjust
->step_increment
= 1.0;
3202 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3203 m_hAdjust
->page_size
= fthumb
;
3207 float fpos
= (float)pos
;
3208 float frange
= (float)range
;
3209 float fthumb
= (float)thumbVisible
;
3210 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3211 if (fpos
< 0.0) fpos
= 0.0;
3213 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3214 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3216 SetScrollPos( orient
, pos
, refresh
);
3220 m_oldVerticalPos
= fpos
;
3222 m_vAdjust
->lower
= 0.0;
3223 m_vAdjust
->upper
= frange
;
3224 m_vAdjust
->value
= fpos
;
3225 m_vAdjust
->step_increment
= 1.0;
3226 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3227 m_vAdjust
->page_size
= fthumb
;
3232 if (orient
== wxHORIZONTAL
)
3233 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3235 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3237 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3241 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3243 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3245 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3247 if (orient
== wxHORIZONTAL
)
3249 float fpos
= (float)pos
;
3250 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3251 if (fpos
< 0.0) fpos
= 0.0;
3252 m_oldHorizontalPos
= fpos
;
3254 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3255 m_hAdjust
->value
= fpos
;
3259 float fpos
= (float)pos
;
3260 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3261 if (fpos
< 0.0) fpos
= 0.0;
3262 m_oldVerticalPos
= fpos
;
3264 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3265 m_vAdjust
->value
= fpos
;
3270 if (m_wxwindow
->window
)
3272 if (orient
== wxHORIZONTAL
)
3273 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3275 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3280 int wxWindow::GetScrollThumb( int orient
) const
3282 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3284 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3286 if (orient
== wxHORIZONTAL
)
3287 return (int)(m_hAdjust
->page_size
+0.5);
3289 return (int)(m_vAdjust
->page_size
+0.5);
3292 int wxWindow::GetScrollPos( int orient
) const
3294 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3296 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3298 if (orient
== wxHORIZONTAL
)
3299 return (int)(m_hAdjust
->value
+0.5);
3301 return (int)(m_vAdjust
->value
+0.5);
3304 int wxWindow::GetScrollRange( int orient
) const
3306 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3308 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3310 if (orient
== wxHORIZONTAL
)
3311 return (int)(m_hAdjust
->upper
+0.5);
3313 return (int)(m_vAdjust
->upper
+0.5);
3316 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3318 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3320 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3322 wxNode
*node
= m_children
.First();
3325 wxWindow
*child
= (wxWindow
*) node
->Data();
3326 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3327 node
= node
->Next();
3332 GetClientSize( &cw
, &ch
);
3334 int w
= cw
- abs(dx
);
3335 int h
= ch
- abs(dy
);
3336 if ((h
< 0) || (w
< 0))
3343 if (dx
< 0) s_x
= -dx
;
3344 if (dy
< 0) s_y
= -dy
;
3347 if (dx
> 0) d_x
= dx
;
3348 if (dy
> 0) d_y
= dy
;
3352 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3353 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3356 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3357 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3360 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3361 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3362 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3363 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3365 Refresh( TRUE
, &rect
);
3368 //-------------------------------------------------------------------------------------
3370 //-------------------------------------------------------------------------------------
3372 wxLayoutConstraints
*wxWindow::GetConstraints() const
3374 return m_constraints
;
3377 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3381 UnsetConstraints(m_constraints
);
3382 delete m_constraints
;
3384 m_constraints
= constraints
;
3387 // Make sure other windows know they're part of a 'meaningful relationship'
3388 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3389 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3390 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3391 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3392 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3393 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3394 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3395 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3396 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3397 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3398 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3399 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3400 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3401 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3402 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3403 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3409 void wxWindow::SetAutoLayout( bool autoLayout
)
3411 m_autoLayout
= autoLayout
;
3414 bool wxWindow::GetAutoLayout() const
3416 return m_autoLayout
;
3419 wxSizer
*wxWindow::GetSizer() const
3421 return m_windowSizer
;
3424 void wxWindow::SetSizerParent( wxWindow
*win
)
3426 m_sizerParent
= win
;
3429 wxWindow
*wxWindow::GetSizerParent() const
3431 return m_sizerParent
;
3434 // This removes any dangling pointers to this window
3435 // in other windows' constraintsInvolvedIn lists.
3436 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3440 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3441 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3442 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3443 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3444 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3445 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3446 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3447 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3448 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3449 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3450 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3451 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3452 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3453 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3454 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3455 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3459 // Back-pointer to other windows we're involved with, so if we delete
3460 // this window, we must delete any constraints we're involved with.
3461 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3463 if (!m_constraintsInvolvedIn
)
3464 m_constraintsInvolvedIn
= new wxList
;
3465 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3466 m_constraintsInvolvedIn
->Append(otherWin
);
3469 // REMOVE back-pointer to other windows we're involved with.
3470 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3472 if (m_constraintsInvolvedIn
)
3473 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3476 // Reset any constraints that mention this window
3477 void wxWindow::DeleteRelatedConstraints()
3479 if (m_constraintsInvolvedIn
)
3481 wxNode
*node
= m_constraintsInvolvedIn
->First();
3484 wxWindow
*win
= (wxWindow
*)node
->Data();
3485 wxNode
*next
= node
->Next();
3486 wxLayoutConstraints
*constr
= win
->GetConstraints();
3488 // Reset any constraints involving this window
3491 constr
->left
.ResetIfWin((wxWindow
*)this);
3492 constr
->top
.ResetIfWin((wxWindow
*)this);
3493 constr
->right
.ResetIfWin((wxWindow
*)this);
3494 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3495 constr
->width
.ResetIfWin((wxWindow
*)this);
3496 constr
->height
.ResetIfWin((wxWindow
*)this);
3497 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3498 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3503 delete m_constraintsInvolvedIn
;
3504 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3508 void wxWindow::SetSizer(wxSizer
*sizer
)
3510 m_windowSizer
= sizer
;
3512 sizer
->SetSizerParent((wxWindow
*)this);
3519 bool wxWindow::Layout()
3521 if (GetConstraints())
3524 GetClientSize(&w
, &h
);
3525 GetConstraints()->width
.SetValue(w
);
3526 GetConstraints()->height
.SetValue(h
);
3529 // If top level (one sizer), evaluate the sizer's constraints.
3533 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3534 GetSizer()->LayoutPhase1(&noChanges
);
3535 GetSizer()->LayoutPhase2(&noChanges
);
3536 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3542 // Otherwise, evaluate child constraints
3543 ResetConstraints(); // Mark all constraints as unevaluated
3544 DoPhase(1); // Just one phase need if no sizers involved
3546 SetConstraintSizes(); // Recursively set the real window sizes
3552 // Do a phase of evaluating constraints:
3553 // the default behaviour. wxSizers may do a similar
3554 // thing, but also impose their own 'constraints'
3555 // and order the evaluation differently.
3556 bool wxWindow::LayoutPhase1(int *noChanges
)
3558 wxLayoutConstraints
*constr
= GetConstraints();
3561 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3567 bool wxWindow::LayoutPhase2(int *noChanges
)
3577 // Do a phase of evaluating child constraints
3578 bool wxWindow::DoPhase(int phase
)
3580 int noIterations
= 0;
3581 int maxIterations
= 500;
3585 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3589 wxNode
*node
= m_children
.First();
3592 wxWindow
*child
= (wxWindow
*)node
->Data();
3593 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3595 wxLayoutConstraints
*constr
= child
->GetConstraints();
3598 if (succeeded
.Member(child
))
3603 int tempNoChanges
= 0;
3604 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3605 noChanges
+= tempNoChanges
;
3608 succeeded
.Append(child
);
3613 node
= node
->Next();
3620 void wxWindow::ResetConstraints()
3622 wxLayoutConstraints
*constr
= GetConstraints();
3625 constr
->left
.SetDone(FALSE
);
3626 constr
->top
.SetDone(FALSE
);
3627 constr
->right
.SetDone(FALSE
);
3628 constr
->bottom
.SetDone(FALSE
);
3629 constr
->width
.SetDone(FALSE
);
3630 constr
->height
.SetDone(FALSE
);
3631 constr
->centreX
.SetDone(FALSE
);
3632 constr
->centreY
.SetDone(FALSE
);
3634 wxNode
*node
= m_children
.First();
3637 wxWindow
*win
= (wxWindow
*)node
->Data();
3638 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3639 win
->ResetConstraints();
3640 node
= node
->Next();
3644 // Need to distinguish between setting the 'fake' size for
3645 // windows and sizers, and setting the real values.
3646 void wxWindow::SetConstraintSizes(bool recurse
)
3648 wxLayoutConstraints
*constr
= GetConstraints();
3649 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3650 constr
->width
.GetDone() && constr
->height
.GetDone())
3652 int x
= constr
->left
.GetValue();
3653 int y
= constr
->top
.GetValue();
3654 int w
= constr
->width
.GetValue();
3655 int h
= constr
->height
.GetValue();
3657 // If we don't want to resize this window, just move it...
3658 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3659 (constr
->height
.GetRelationship() != wxAsIs
))
3661 // Calls Layout() recursively. AAAGH. How can we stop that.
3662 // Simply take Layout() out of non-top level OnSizes.
3663 SizerSetSize(x
, y
, w
, h
);
3672 wxChar
*windowClass
= this->GetClassInfo()->GetClassName();
3675 if (GetName() == _T(""))
3676 winName
= _T("unnamed");
3678 winName
= GetName();
3679 wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"),
3680 (const wxChar
*)windowClass
,
3681 (const wxChar
*)winName
);
3682 if (!constr
->left
.GetDone()) wxLogDebug( _T(" unsatisfied 'left' constraint.\n") );
3683 if (!constr
->right
.GetDone()) wxLogDebug( _T(" unsatisfied 'right' constraint.\n") );
3684 if (!constr
->width
.GetDone()) wxLogDebug( _T(" unsatisfied 'width' constraint.\n") );
3685 if (!constr
->height
.GetDone()) wxLogDebug( _T(" unsatisfied 'height' constraint.\n") );
3686 wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") );
3691 wxNode
*node
= m_children
.First();
3694 wxWindow
*win
= (wxWindow
*)node
->Data();
3695 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3696 win
->SetConstraintSizes();
3697 node
= node
->Next();
3702 // This assumes that all sizers are 'on' the same
3703 // window, i.e. the parent of this window.
3704 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3706 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3707 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3711 m_sizerParent
->GetPosition(&xp
, &yp
);
3712 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3717 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3721 TransformSizerToActual(&xx
, &yy
);
3722 SetSize(xx
, yy
, w
, h
);
3725 void wxWindow::SizerMove(int x
, int y
)
3729 TransformSizerToActual(&xx
, &yy
);
3733 // Only set the size/position of the constraint (if any)
3734 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3736 wxLayoutConstraints
*constr
= GetConstraints();
3741 constr
->left
.SetValue(x
);
3742 constr
->left
.SetDone(TRUE
);
3746 constr
->top
.SetValue(y
);
3747 constr
->top
.SetDone(TRUE
);
3751 constr
->width
.SetValue(w
);
3752 constr
->width
.SetDone(TRUE
);
3756 constr
->height
.SetValue(h
);
3757 constr
->height
.SetDone(TRUE
);
3762 void wxWindow::MoveConstraint(int x
, int y
)
3764 wxLayoutConstraints
*constr
= GetConstraints();
3769 constr
->left
.SetValue(x
);
3770 constr
->left
.SetDone(TRUE
);
3774 constr
->top
.SetValue(y
);
3775 constr
->top
.SetDone(TRUE
);
3780 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3782 wxLayoutConstraints
*constr
= GetConstraints();
3785 *w
= constr
->width
.GetValue();
3786 *h
= constr
->height
.GetValue();
3792 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3794 wxLayoutConstraints
*constr
= GetConstraints();
3797 *w
= constr
->width
.GetValue();
3798 *h
= constr
->height
.GetValue();
3801 GetClientSize(w
, h
);
3804 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3806 wxLayoutConstraints
*constr
= GetConstraints();
3809 *x
= constr
->left
.GetValue();
3810 *y
= constr
->top
.GetValue();