+// don't test here as we can release the mouse while being over
+// a different window then the slider
+//
+// if (gdk_event->window != widget->slider) return FALSE;
+
+ win->m_isScrolling = TRUE;
+ g_blockEventsOnScroll = TRUE;
+
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// "button_release_event" from scrollbar
+//-----------------------------------------------------------------------------
+
+static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
+ GdkEventButton *WXUNUSED(gdk_event),
+ wxWindow *win )
+{
+
+// don't test here as we can release the mouse while being over
+// a different window then the slider
+//
+// if (gdk_event->window != widget->slider) return FALSE;
+
+ GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(win->m_widget);
+
+ if (widget == GTK_RANGE(s_window->vscrollbar))
+ gtk_signal_emit_by_name( GTK_OBJECT(win->m_hAdjust), "value_changed" );
+ else
+ gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" );
+
+ win->m_isScrolling = FALSE;
+ g_blockEventsOnScroll = FALSE;
+
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// InsertChild for wxWindow.
+//-----------------------------------------------------------------------------
+
+/* Callback for wxWindow. This very strange beast has to be used because
+ * C++ has no virtual methods in a constructor. We have to emulate a
+ * virtual function here as wxNotebook requires a different way to insert
+ * a child in it. I had opted for creating a wxNotebookPage window class
+ * which would have made this superfluous (such in the MDI window system),
+ * but no-one was listening to me... */
+
+static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child )
+{
+ gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
+ GTK_WIDGET(child->m_widget),
+ child->m_x,
+ child->m_y );
+
+ gtk_widget_set_usize( GTK_WIDGET(child->m_widget),
+ child->m_width,
+ child->m_height );
+
+ if (parent->m_windowStyle & wxTAB_TRAVERSAL)
+ {
+ /* we now allow a window to get the focus as long as it
+ doesn't have any children. */
+ GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// global functions
+//-----------------------------------------------------------------------------
+
+wxWindow* wxGetActiveWindow()
+{
+ return g_focusWindow;
+}
+
+//-----------------------------------------------------------------------------
+// wxWindow
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
+
+BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
+ EVT_SIZE(wxWindow::OnSize)
+ EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
+ EVT_INIT_DIALOG(wxWindow::OnInitDialog)
+ EVT_KEY_DOWN(wxWindow::OnKeyDown)
+END_EVENT_TABLE()
+
+void wxWindow::Init()
+{
+ m_isWindow = TRUE;
+
+ m_widget = (GtkWidget *) NULL;
+ m_wxwindow = (GtkWidget *) NULL;
+ m_parent = (wxWindow *) NULL;
+ m_children.DeleteContents( FALSE );
+
+ m_x = 0;
+ m_y = 0;
+ m_width = 0;
+ m_height = 0;
+ m_minWidth = -1;
+ m_minHeight = -1;
+ m_maxWidth = -1;
+ m_maxHeight = -1;
+
+ m_retCode = 0;
+
+ m_eventHandler = this;
+ m_windowValidator = (wxValidator *) NULL;
+
+ m_windowId = -1;
+
+ m_cursor = (wxCursor *) NULL;
+ m_font = *wxSWISS_FONT;
+ m_windowStyle = 0;
+ m_windowName = "noname";
+
+ m_constraints = (wxLayoutConstraints *) NULL;
+ m_constraintsInvolvedIn = (wxList *) NULL;
+ m_windowSizer = (wxSizer *) NULL;
+ m_sizerParent = (wxWindow *) NULL;
+ m_autoLayout = FALSE;
+
+ m_sizeSet = FALSE;
+ m_hasVMT = FALSE;
+ m_needParent = TRUE;
+
+ m_hasScrolling = FALSE;
+ m_isScrolling = FALSE;
+ m_hAdjust = (GtkAdjustment*) NULL;
+ m_vAdjust = (GtkAdjustment*) NULL;
+ m_oldHorizontalPos = 0.0;
+ m_oldVerticalPos = 0.0;
+
+ m_isShown = FALSE;
+ m_isEnabled = TRUE;
+
+#if wxUSE_DRAG_AND_DROP
+ m_dropTarget = (wxDropTarget*) NULL;
+#endif
+ m_resizing = FALSE;
+ m_scrollGC = (GdkGC*) NULL;
+ m_widgetStyle = (GtkStyle*) NULL;
+
+ m_insertCallback = wxInsertChildInWindow;
+
+ m_clientObject = (wxClientData*) NULL;
+ m_clientData = NULL;
+
+ m_isStaticBox = FALSE;
+ m_acceptsFocus = FALSE;
+
+#if wxUSE_TOOLTIPS
+ m_toolTip = (wxToolTip*) NULL;
+#endif // wxUSE_TOOLTIPS
+}
+
+wxWindow::wxWindow()
+{
+ Init();
+}
+
+wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos, const wxSize &size,
+ long style, const wxString &name )
+{
+ Init();
+
+ Create( parent, id, pos, size, style, name );
+}
+
+bool wxWindow::Create( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos, const wxSize &size,
+ long style, const wxString &name )
+{
+ wxASSERT_MSG( m_isWindow, _T("Init() must have been called before!") );
+
+ PreCreation( parent, id, pos, size, style, name );
+
+ m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
+ GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
+
+ GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget);
+
+ GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+ scroll_class->scrollbar_spacing = 0;
+
+ gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+
+ m_oldHorizontalPos = 0.0;
+ m_oldVerticalPos = 0.0;
+
+ m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
+ m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
+
+ m_wxwindow = gtk_myfixed_new();
+
+ gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
+
+#if (GTK_MINOR_VERSION > 0)
+ GtkMyFixed *myfixed = GTK_MYFIXED(m_wxwindow);
+
+ if (m_windowStyle & wxRAISED_BORDER)
+ {
+ gtk_myfixed_set_shadow_type( myfixed, GTK_SHADOW_OUT );
+ }
+ else if (m_windowStyle & wxSUNKEN_BORDER)
+ {
+ gtk_myfixed_set_shadow_type( myfixed, GTK_SHADOW_IN );
+ }
+ else
+ {
+ gtk_myfixed_set_shadow_type( myfixed, GTK_SHADOW_NONE );
+ }
+#else
+ GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport);
+
+ if (m_windowStyle & wxRAISED_BORDER)
+ {
+ gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
+ }
+ else if (m_windowStyle & wxSUNKEN_BORDER)
+ {
+ gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
+ }
+ else
+ {
+ gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
+ }
+#endif
+
+ if (m_windowStyle & wxTAB_TRAVERSAL)
+ {
+ /* we now allow a window to get the focus as long as it
+ doesn't have any children. */
+ GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+ m_acceptsFocus = FALSE;
+ }
+ else
+ {
+ GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+ m_acceptsFocus = TRUE;
+ }
+
+#if (GTK_MINOR_VERSION == 0)
+ // shut the viewport up
+ gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
+ gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
+#endif
+
+ // I _really_ don't want scrollbars in the beginning
+ m_vAdjust->lower = 0.0;
+ m_vAdjust->upper = 1.0;
+ m_vAdjust->value = 0.0;
+ m_vAdjust->step_increment = 1.0;
+ m_vAdjust->page_increment = 1.0;
+ m_vAdjust->page_size = 5.0;
+ gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
+ m_hAdjust->lower = 0.0;
+ m_hAdjust->upper = 1.0;
+ m_hAdjust->value = 0.0;
+ m_hAdjust->step_increment = 1.0;
+ m_hAdjust->page_increment = 1.0;
+ m_hAdjust->page_size = 5.0;
+ gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
+
+ // these handlers block mouse events to any window during scrolling
+ // such as motion events and prevent GTK and wxWindows from fighting
+ // over where the slider should be
+
+ gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
+ (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
+
+ gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
+ (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
+
+ gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
+ (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
+
+ gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
+ (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
+
+ // these handlers get notified when screen updates are required either when
+ // scrolling or when the window size (and therefore scrollbar configuration)
+ // has changed
+
+ gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
+ (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
+ gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
+ (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
+
+ gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
+ (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
+ gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
+ (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
+
+ gtk_widget_show( m_wxwindow );
+
+ if (m_parent) m_parent->AddChild( this );
+
+ (m_parent->m_insertCallback)( m_parent, this );
+
+ PostCreation();
+
+ Show( TRUE );
+
+ return TRUE;
+}
+
+wxWindow::~wxWindow()
+{
+ m_hasVMT = FALSE;
+
+#if wxUSE_DRAG_AND_DROP
+ if (m_dropTarget)
+ {
+ delete m_dropTarget;
+ m_dropTarget = (wxDropTarget*) NULL;
+ }
+#endif
+
+#if wxUSE_TOOLTIPS
+ if (m_toolTip)
+ {
+ delete m_toolTip;
+ m_toolTip = (wxToolTip*) NULL;
+ }
+#endif // wxUSE_TOOLTIPS
+
+ if (m_widget) Show( FALSE );
+
+ DestroyChildren();
+
+ if (m_parent) m_parent->RemoveChild( this );
+
+ if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
+
+ if (m_scrollGC) gdk_gc_unref( m_scrollGC );
+
+ if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
+
+ if (m_widget) gtk_widget_destroy( m_widget );
+
+ if (m_cursor) delete m_cursor;
+
+ DeleteRelatedConstraints();
+ if (m_constraints)
+ {
+ /* This removes any dangling pointers to this window
+ * in other windows' constraintsInvolvedIn lists. */
+ UnsetConstraints(m_constraints);
+ delete m_constraints;
+ m_constraints = (wxLayoutConstraints *) NULL;
+ }
+
+ if (m_windowSizer)
+ {
+ delete m_windowSizer;
+ m_windowSizer = (wxSizer *) NULL;
+ }
+ /* If this is a child of a sizer, remove self from parent */
+ if (m_sizerParent) m_sizerParent->RemoveChild((wxWindow *)this);
+
+ /* Just in case the window has been Closed, but
+ * we're then deleting immediately: don't leave
+ * dangling pointers. */
+ wxPendingDelete.DeleteObject(this);
+
+ /* Just in case we've loaded a top-level window via
+ * wxWindow::LoadNativeDialog but we weren't a dialog
+ * class */
+ wxTopLevelWindows.DeleteObject(this);
+
+ if (m_windowValidator) delete m_windowValidator;
+
+ if (m_clientObject) delete m_clientObject;
+}
+
+void wxWindow::PreCreation( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos, const wxSize &size,
+ long style, const wxString &name )
+{
+ wxASSERT_MSG( (!m_needParent) || (parent), _T("Need complete parent.") );
+
+ m_widget = (GtkWidget*) NULL;
+ m_wxwindow = (GtkWidget*) NULL;
+ m_hasVMT = FALSE;
+ m_parent = parent;
+ m_children.DeleteContents( FALSE );
+
+ m_width = size.x;
+ if (m_width == -1) m_width = 20;
+ m_height = size.y;
+ if (m_height == -1) m_height = 20;
+
+ m_x = (int)pos.x;
+ m_y = (int)pos.y;
+
+ if (!m_needParent) /* some reasonable defaults */
+ {
+ if (m_x == -1)
+ {
+ m_x = (gdk_screen_width () - m_width) / 2;
+ if (m_x < 10) m_x = 10;
+ }
+ if (m_y == -1)
+ {
+ m_y = (gdk_screen_height () - m_height) / 2;
+ if (m_y < 10) m_y = 10;
+ }
+ }
+
+ m_minWidth = -1;
+ m_minHeight = -1;
+ m_maxWidth = -1;
+ m_maxHeight = -1;
+
+ m_retCode = 0;
+
+ m_eventHandler = this;
+
+ m_windowId = id == -1 ? wxNewId() : id;
+
+ m_sizeSet = FALSE;
+
+ m_cursor = new wxCursor( wxCURSOR_ARROW );
+ m_font = *wxSWISS_FONT;
+ m_backgroundColour = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
+ m_foregroundColour = *wxBLACK;
+ m_windowStyle = style;
+ m_windowName = name;
+
+ m_constraints = (wxLayoutConstraints *) NULL;
+ m_constraintsInvolvedIn = (wxList *) NULL;
+ m_windowSizer = (wxSizer *) NULL;
+ m_sizerParent = (wxWindow *) NULL;
+ m_autoLayout = FALSE;
+
+ m_hasScrolling = FALSE;
+ m_isScrolling = FALSE;
+ m_hAdjust = (GtkAdjustment *) NULL;
+ m_vAdjust = (GtkAdjustment *) NULL;
+ m_oldHorizontalPos = 0.0;
+ m_oldVerticalPos = 0.0;
+
+ m_isShown = FALSE;
+ m_isEnabled = TRUE;
+
+#if wxUSE_DRAG_AND_DROP
+ m_dropTarget = (wxDropTarget *) NULL;
+#endif
+ m_resizing = FALSE;
+ m_windowValidator = (wxValidator *) NULL;
+ m_scrollGC = (GdkGC*) NULL;
+ m_widgetStyle = (GtkStyle*) NULL;
+
+ m_clientObject = (wxClientData*)NULL;
+ m_clientData = NULL;
+
+ m_isStaticBox = FALSE;
+
+#if wxUSE_TOOLTIPS
+ m_toolTip = (wxToolTip*) NULL;
+#endif // wxUSE_TOOLTIPS
+}
+
+void wxWindow::PostCreation()
+{
+ wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+
+ if (m_wxwindow)
+ {
+ /* these get reported to wxWindows -> wxPaintEvent */
+ gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
+ GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
+ GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
+
+#if (GTK_MINOR_VERSION > 0)
+ /* these are called when the "sunken" or "raised" borders are drawn */
+ gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
+ GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(m_widget), "draw",
+ GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
+#endif
+ }
+
+ ConnectWidget( GetConnectWidget() );
+
+ /* we force the creation of wxFrame and wxDialog in the respective code */
+ if (m_parent) gtk_widget_realize( m_widget );
+
+ if (m_wxwindow) gtk_widget_realize( m_wxwindow );
+
+ SetCursor( *wxSTANDARD_CURSOR );
+
+ m_hasVMT = TRUE;
+}
+
+void wxWindow::ConnectWidget( GtkWidget *widget )
+{
+ gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
+ GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "key_release_event",
+ GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
+ GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
+ GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
+ GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
+ GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
+ GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
+ GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
+ GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
+}
+
+bool wxWindow::HasVMT()
+{
+ return m_hasVMT;
+}
+
+bool wxWindow::Close( bool force )
+{
+ wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+
+ wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
+ event.SetEventObject(this);
+ event.SetCanVeto(!force);
+
+ /* return FALSE if window wasn't closed because the application vetoed the
+ * close event */
+ return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
+}
+
+bool wxWindow::Destroy()
+{
+ wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+
+ m_hasVMT = FALSE;
+ delete this;
+ return TRUE;
+}
+
+bool wxWindow::DestroyChildren()
+{
+ wxNode *node;
+ while ((node = m_children.First()) != (wxNode *)NULL)
+ {
+ wxWindow *child;
+ if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL)
+ {
+ delete child;
+ if (m_children.Member(child)) delete node;
+ }
+ }
+ return TRUE;
+}
+
+void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
+{
+ // are we to set fonts here ?
+}
+
+void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
+{
+ wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+ wxASSERT_MSG( (m_parent != NULL), _T("wxWindow::SetSize requires parent.\n") );
+
+ if (m_resizing) return; /* I don't like recursions */
+ m_resizing = TRUE;
+
+ if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */
+ {
+ /* don't set the size for children of wxNotebook, just take the values. */
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
+ }
+ else
+ {
+ int old_width = m_width;
+ int old_height = m_height;
+
+ if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
+ {
+ if (x != -1) m_x = x;
+ if (y != -1) m_y = y;
+ if (width != -1) m_width = width;
+ if (height != -1) m_height = height;
+ }
+ else
+ {
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
+ }
+
+ if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
+ {
+ if (width == -1) m_width = 80;
+ }
+
+ if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
+ {
+ if (height == -1) m_height = 26;
+ }
+
+ if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
+ if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
+ if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
+ if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+
+ if (GTK_WIDGET_HAS_DEFAULT(m_widget))
+ {
+ /* the default button has a border around it */
+ int border = 5;
+
+ gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x-border, m_y-border );
+
+ gtk_widget_set_usize( m_widget, m_width+2*border, m_height+2*border );
+ }
+ else
+ {
+ gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
+
+ if ((old_width != m_width) || (old_height != m_height))
+ gtk_widget_set_usize( m_widget, m_width, m_height );
+ }
+ }
+
+ m_sizeSet = TRUE;
+
+ wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( event );
+
+ m_resizing = FALSE;
+}
+
+void wxWindow::OnInternalIdle()
+{
+ UpdateWindowUI();
+}
+
+void wxWindow::GetSize( int *width, int *height ) const
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (width) (*width) = m_width;
+ if (height) (*height) = m_height;
+}
+
+void wxWindow::DoSetClientSize( int width, int height )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (!m_wxwindow)
+ {
+ SetSize( width, height );
+ }
+ else
+ {
+ int dw = 0;
+ int dh = 0;
+
+ if (!m_hasScrolling)
+ {
+ GtkStyleClass *window_class = m_wxwindow->style->klass;
+
+ if ((m_windowStyle & wxRAISED_BORDER) ||
+ (m_windowStyle & wxSUNKEN_BORDER))
+ {
+ dw += 2 * window_class->xthickness;
+ dh += 2 * window_class->ythickness;
+ }
+ }
+ else
+ {
+ GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+ GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+
+#if (GTK_MINOR_VERSION == 0)
+ GtkWidget *viewport = scroll_window->viewport;
+ GtkStyleClass *viewport_class = viewport->style->klass;
+
+ if ((m_windowStyle & wxRAISED_BORDER) ||
+ (m_windowStyle & wxSUNKEN_BORDER))
+ {
+ dw += 2 * viewport_class->xthickness;
+ dh += 2 * viewport_class->ythickness;
+ }
+#endif
+
+/*
+ GtkWidget *hscrollbar = scroll_window->hscrollbar;
+ GtkWidget *vscrollbar = scroll_window->vscrollbar;
+
+ we use this instead: range.slider_width = 11 + 2*2pts edge
+*/
+
+ if (scroll_window->vscrollbar_visible)
+ {
+ dw += 15; /* dw += vscrollbar->allocation.width; */
+ dw += scroll_class->scrollbar_spacing;
+ }
+
+ if (scroll_window->hscrollbar_visible)
+ {
+ dh += 15; /* dh += hscrollbar->allocation.height; */
+ dw += scroll_class->scrollbar_spacing;
+ }
+ }
+
+ SetSize( width+dw, height+dh );
+ }
+}
+
+void wxWindow::GetClientSize( int *width, int *height ) const
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (!m_wxwindow)
+ {
+ if (width) (*width) = m_width;
+ if (height) (*height) = m_height;
+ }
+ else
+ {
+ int dw = 0;
+ int dh = 0;
+
+ if (!m_hasScrolling)
+ {
+ GtkStyleClass *window_class = m_wxwindow->style->klass;
+
+ if ((m_windowStyle & wxRAISED_BORDER) ||
+ (m_windowStyle & wxSUNKEN_BORDER))
+ {
+ dw += 2 * window_class->xthickness;
+ dh += 2 * window_class->ythickness;
+ }
+ }
+ else
+ {
+ GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+ GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+
+#if (GTK_MINOR_VERSION == 0)
+ GtkWidget *viewport = scroll_window->viewport;
+ GtkStyleClass *viewport_class = viewport->style->klass;
+
+ if ((m_windowStyle & wxRAISED_BORDER) ||
+ (m_windowStyle & wxSUNKEN_BORDER))
+ {
+ dw += 2 * viewport_class->xthickness;
+ dh += 2 * viewport_class->ythickness;
+ }
+#endif
+/*
+ GtkWidget *hscrollbar = scroll_window->hscrollbar;
+ GtkWidget *vscrollbar = scroll_window->vscrollbar;
+
+ we use this instead: range.slider_width = 11 + 2*2pts edge
+*/
+
+ if (scroll_window->vscrollbar_visible)
+ {
+ dw += 15; /* dw += vscrollbar->allocation.width; */
+ dw += scroll_class->scrollbar_spacing;
+ }
+
+ if (scroll_window->hscrollbar_visible)
+ {
+ dh += 15; /* dh += hscrollbar->allocation.height; */
+ dh += scroll_class->scrollbar_spacing;
+ }
+ }
+
+ if (width) (*width) = m_width - dw;
+ if (height) (*height) = m_height - dh;
+ }
+}
+
+void wxWindow::GetPosition( int *x, int *y ) const
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (x) (*x) = m_x;
+ if (y) (*y) = m_y;
+}
+
+void wxWindow::ClientToScreen( int *x, int *y )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ GdkWindow *source = (GdkWindow *) NULL;
+ if (m_wxwindow)
+ source = m_wxwindow->window;
+ else
+ source = m_widget->window;
+
+ int org_x = 0;
+ int org_y = 0;
+ gdk_window_get_origin( source, &org_x, &org_y );
+
+ if (!m_wxwindow)
+ {
+ if (GTK_WIDGET_NO_WINDOW (m_widget))
+ {
+ org_x += m_widget->allocation.x;
+ org_y += m_widget->allocation.y;
+ }
+ }
+
+ if (x) *x += org_x;
+ if (y) *y += org_y;
+}
+
+void wxWindow::ScreenToClient( int *x, int *y )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ GdkWindow *source = (GdkWindow *) NULL;
+ if (m_wxwindow)
+ source = m_wxwindow->window;
+ else
+ source = m_widget->window;
+
+ int org_x = 0;
+ int org_y = 0;
+ gdk_window_get_origin( source, &org_x, &org_y );
+
+ if (!m_wxwindow)
+ {
+ if (GTK_WIDGET_NO_WINDOW (m_widget))
+ {
+ org_x += m_widget->allocation.x;
+ org_y += m_widget->allocation.y;
+ }
+ }
+
+ if (x) *x -= org_x;
+ if (y) *y -= org_y;
+}
+
+void wxWindow::Centre( int direction )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ int x = m_x;
+ int y = m_y;
+
+ if (m_parent)
+ {
+ int p_w = 0;
+ int p_h = 0;
+ m_parent->GetSize( &p_w, &p_h );
+ if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (p_w - m_width) / 2;
+ if (direction & wxVERTICAL == wxVERTICAL) y = (p_h - m_height) / 2;
+ }
+ else
+ {
+ if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
+ if (direction & wxVERTICAL == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
+ }
+
+ Move( x, y );
+}
+
+void wxWindow::Fit()
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ int maxX = 0;
+ int maxY = 0;
+ wxNode *node = m_children.First();
+ while (node)
+ {
+ wxWindow *win = (wxWindow *)node->Data();
+ int wx, wy, ww, wh;
+ win->GetPosition(&wx, &wy);
+ win->GetSize(&ww, &wh);
+ if (wx + ww > maxX) maxX = wx + ww;
+ if (wy + wh > maxY) maxY = wy + wh;
+
+ node = node->Next();
+ }
+
+ SetClientSize(maxX + 7, maxY + 14);
+}
+
+void wxWindow::SetSizeHints( int minW, int minH, int maxW, int maxH, int WXUNUSED(incW), int WXUNUSED(incH) )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ m_minWidth = minW;
+ m_minHeight = minH;
+ m_maxWidth = maxW;
+ m_maxHeight = maxH;
+}
+
+void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+// if (GetAutoLayout()) Layout();
+}
+
+bool wxWindow::Show( bool show )
+{
+ wxCHECK_MSG( (m_widget != NULL), FALSE, _T("invalid window") );
+
+ if (show == m_isShown) return TRUE;
+
+ if (show)
+ gtk_widget_show( m_widget );
+ else
+ gtk_widget_hide( m_widget );
+
+ m_isShown = show;
+
+ return TRUE;
+}
+
+void wxWindow::Enable( bool enable )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ m_isEnabled = enable;
+
+ gtk_widget_set_sensitive( m_widget, enable );
+ if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
+}
+
+int wxWindow::GetCharHeight() const
+{
+ wxCHECK_MSG( (m_widget != NULL), 12, _T("invalid window") );
+
+ wxCHECK_MSG( m_font.Ok(), 12, _T("invalid font") );
+
+ GdkFont *font = m_font.GetInternalFont( 1.0 );
+
+ return font->ascent + font->descent;
+}
+
+int wxWindow::GetCharWidth() const
+{
+ wxCHECK_MSG( (m_widget != NULL), 8, _T("invalid window") );
+
+ wxCHECK_MSG( m_font.Ok(), 8, _T("invalid font") );
+
+ GdkFont *font = m_font.GetInternalFont( 1.0 );
+
+ return gdk_string_width( font, "H" );
+}
+
+void wxWindow::GetTextExtent( const wxString& string, int *x, int *y,
+ int *descent, int *externalLeading, const wxFont *theFont, bool WXUNUSED(use16) ) const
+{
+ wxFont fontToUse = m_font;
+ if (theFont) fontToUse = *theFont;
+
+ wxCHECK_RET( fontToUse.Ok(), _T("invalid font") );
+
+ GdkFont *font = fontToUse.GetInternalFont( 1.0 );
+ if (x) (*x) = gdk_string_width( font, string.mbc_str() );
+ if (y) (*y) = font->ascent + font->descent;
+ if (descent) (*descent) = font->descent;
+ if (externalLeading) (*externalLeading) = 0; // ??
+}
+
+void wxWindow::MakeModal( bool modal )
+{
+ return;
+
+ // Disable all other windows
+ if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxNode *node = wxTopLevelWindows.First();
+ while (node)
+ {
+ wxWindow *win = (wxWindow *)node->Data();
+ if (win != this) win->Enable(!modal);
+
+ node = node->Next();
+ }
+ }
+}
+
+void wxWindow::OnKeyDown( wxKeyEvent &event )
+{
+ event.SetEventType( wxEVT_CHAR );
+
+ if (!GetEventHandler()->ProcessEvent( event ))
+ {
+ event.Skip();
+ }
+}
+
+void wxWindow::SetFocus()
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ GtkWidget *connect_widget = GetConnectWidget();
+ if (connect_widget)
+ {
+ if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
+ {
+ gtk_widget_grab_focus (connect_widget);
+ }
+ else if (GTK_IS_CONTAINER(connect_widget))
+ {
+ gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD );
+ }
+ else
+ {
+ }
+ }
+}
+
+wxWindow *wxWindow::FindFocus()
+{
+ return g_focusWindow;
+}
+
+bool wxWindow::AcceptsFocus() const
+{
+ return IsEnabled() && IsShown() && m_acceptsFocus;
+}
+
+void wxWindow::AddChild( wxWindow *child )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (child != NULL), _T("invalid child") );
+
+ m_children.Append( child );
+}
+
+wxWindow *wxWindow::ReParent( wxWindow *newParent )
+{
+ wxCHECK_MSG( (m_widget != NULL), (wxWindow*) NULL, _T("invalid window") );
+
+ wxWindow *oldParent = GetParent();
+
+ if (oldParent) oldParent->RemoveChild( this );
+
+ gtk_widget_unparent( m_widget );
+
+ if (newParent)
+ {
+ newParent->AddChild( this );
+ (newParent->m_insertCallback)( newParent, this );
+ }
+
+ return oldParent;
+}
+
+void wxWindow::RemoveChild( wxWindow *child )
+{
+ m_children.DeleteObject( child );
+ child->m_parent = (wxWindow *) NULL;
+}
+
+void wxWindow::SetReturnCode( int retCode )
+{
+ m_retCode = retCode;
+}
+
+int wxWindow::GetReturnCode()
+{
+ return m_retCode;
+}
+
+void wxWindow::Raise()
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (m_widget) gdk_window_raise( m_widget->window );
+}
+
+void wxWindow::Lower()
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (m_widget) gdk_window_lower( m_widget->window );
+}
+
+wxEvtHandler *wxWindow::GetEventHandler() const
+{
+ return m_eventHandler;
+}
+
+void wxWindow::SetEventHandler( wxEvtHandler *handler )
+{
+ m_eventHandler = handler;
+}
+
+void wxWindow::PushEventHandler(wxEvtHandler *handler)
+{
+ handler->SetNextHandler(GetEventHandler());
+ SetEventHandler(handler);
+}
+
+wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
+{
+ if (GetEventHandler())
+ {
+ wxEvtHandler *handlerA = GetEventHandler();
+ wxEvtHandler *handlerB = handlerA->GetNextHandler();
+ handlerA->SetNextHandler((wxEvtHandler *) NULL);
+ SetEventHandler(handlerB);
+ if (deleteHandler)
+ {
+ delete handlerA;
+ return (wxEvtHandler*) NULL;
+ }
+ else
+ return handlerA;
+ }
+ else
+ return (wxEvtHandler *) NULL;
+}
+
+wxValidator *wxWindow::GetValidator()
+{
+ return m_windowValidator;
+}
+
+void wxWindow::SetValidator( const wxValidator& validator )
+{
+ if (m_windowValidator) delete m_windowValidator;
+ m_windowValidator = validator.Clone();
+ if (m_windowValidator) m_windowValidator->SetWindow(this);
+}
+
+void wxWindow::SetClientObject( wxClientData *data )
+{
+ if (m_clientObject) delete m_clientObject;
+ m_clientObject = data;
+}
+
+wxClientData *wxWindow::GetClientObject()
+{
+ return m_clientObject;
+}
+
+void wxWindow::SetClientData( void *data )
+{
+ m_clientData = data;
+}
+
+void *wxWindow::GetClientData()
+{
+ return m_clientData;
+}
+
+bool wxWindow::IsBeingDeleted()
+{
+ return FALSE;
+}
+
+void wxWindow::SetId( wxWindowID id )
+{
+ m_windowId = id;
+}
+
+wxWindowID wxWindow::GetId() const
+{
+ return m_windowId;
+}
+
+void wxWindow::SetCursor( const wxCursor &cursor )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (cursor.Ok())
+ {
+ if (cursor == *m_cursor) return;
+ *m_cursor = cursor;
+ }
+ else
+ {
+ *m_cursor = *wxSTANDARD_CURSOR;
+ }
+
+ if ((m_widget) && (m_widget->window))
+ gdk_window_set_cursor( m_widget->window, m_cursor->GetCursor() );
+
+ if ((m_wxwindow) && (m_wxwindow->window))
+ gdk_window_set_cursor( m_wxwindow->window, m_cursor->GetCursor() );
+}
+
+void wxWindow::WarpPointer( int WXUNUSED(x), int WXUNUSED(y) )
+{
+ // TODO
+}
+
+void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
+{
+ wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+ if (eraseBackground && m_wxwindow && m_wxwindow->window)
+ {
+ if (rect)
+ {
+ gdk_window_clear_area( m_wxwindow->window,
+ rect->x, rect->y,
+ rect->width, rect->height );
+ }
+ else
+ {
+ gdk_window_clear( m_wxwindow->window );
+ }
+ }
+
+ if (!rect)
+ {
+ if (m_wxwindow)
+ gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
+ else
+ gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
+ }
+ else
+ {
+ GdkRectangle gdk_rect;
+ gdk_rect.x = rect->x;
+ gdk_rect.y = rect->y;
+ gdk_rect.width = rect->width;
+ gdk_rect.height = rect->height;
+
+ if (m_wxwindow)
+ gtk_widget_draw( m_wxwindow, &gdk_rect );
+ else
+ gtk_widget_draw( m_widget, &gdk_rect );
+ }
+}
+
+wxRegion wxWindow::GetUpdateRegion() const
+{
+ return m_updateRegion;
+}
+
+bool wxWindow::IsExposed( int x, int y) const
+{
+ return (m_updateRegion.Contains( x, y ) != wxOutRegion );
+}
+
+bool wxWindow::IsExposed( int x, int y, int w, int h ) const
+{
+ return (m_updateRegion.Contains( x, y, w, h ) != wxOutRegion );
+}
+
+bool wxWindow::IsExposed( const wxPoint& pt ) const
+{
+ return (m_updateRegion.Contains( pt.x, pt.y ) != wxOutRegion );
+}
+
+bool wxWindow::IsExposed( const wxRect& rect ) const
+{
+ return (m_updateRegion.Contains( rect.x, rect.y, rect.width, rect.height ) != wxOutRegion );
+}
+
+void wxWindow::Clear()
+{
+ wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+
+ if (m_wxwindow && m_wxwindow->window)
+ {
+ gdk_window_clear( m_wxwindow->window );
+ }
+}
+
+#if wxUSE_TOOLTIPS
+void wxWindow::SetToolTip( const wxString &tip )
+{
+ if (m_toolTip)
+ {
+ m_toolTip->SetTip( tip );
+ }
+ else
+ {
+ SetToolTip( new wxToolTip( tip ) );
+ }
+
+ // setting empty tooltip text does not remove the tooltip any more for
+ // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
+}
+
+void wxWindow::SetToolTip( wxToolTip *tip )
+{
+ if (m_toolTip)
+ {
+ m_toolTip->SetTip( (char*) NULL );
+ delete m_toolTip;
+ }
+
+ m_toolTip = tip;
+
+ if (m_toolTip)
+ m_toolTip->Apply( this );
+}
+
+void wxWindow::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
+{
+ gtk_tooltips_set_tip( tips, GetConnectWidget(), wxConv_current->cWX2MB(tip), (gchar*) NULL );
+}
+#endif // wxUSE_TOOLTIPS
+
+wxColour wxWindow::GetBackgroundColour() const
+{
+ return m_backgroundColour;
+}
+
+void wxWindow::SetBackgroundColour( const wxColour &colour )
+{
+ wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+
+ if (m_backgroundColour == colour) return;
+
+ m_backgroundColour = colour;
+ if (!m_backgroundColour.Ok()) return;
+
+ if (m_wxwindow && m_wxwindow->window)
+ {
+ /* wxMSW doesn't clear the window here. I don't do that
+ either to provide compatibility. call Clear() to do
+ the job. */
+
+ m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_wxwindow->window ) );
+ gdk_window_set_background( m_wxwindow->window, m_backgroundColour.GetColor() );
+ }
+
+ wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
+
+ if (sysbg.Red() == colour.Red() &&
+ sysbg.Green() == colour.Green() &&
+ sysbg.Blue() == colour.Blue())
+ {
+ m_backgroundColour = wxNullColour;
+ ApplyWidgetStyle();
+ m_backgroundColour = sysbg;
+ }
+ else
+ {
+ ApplyWidgetStyle();
+ }
+}
+
+wxColour wxWindow::GetForegroundColour() const
+{
+ return m_foregroundColour;
+}
+
+void wxWindow::SetForegroundColour( const wxColour &colour )
+{
+ wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+
+ if (m_foregroundColour == colour) return;
+
+ m_foregroundColour = colour;
+ if (!m_foregroundColour.Ok()) return;
+
+ wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
+ if (sysbg.Red() == colour.Red() &&
+ sysbg.Green() == colour.Green() &&
+ sysbg.Blue() == colour.Blue())
+ {
+ m_backgroundColour = wxNullColour;
+ ApplyWidgetStyle();
+ m_backgroundColour = sysbg;
+ }
+ else
+ {
+ ApplyWidgetStyle();
+ }
+}
+
+GtkStyle *wxWindow::GetWidgetStyle()
+{
+ if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
+
+ m_widgetStyle =
+ gtk_style_copy(
+ gtk_widget_get_style( m_widget ) );
+
+ return m_widgetStyle;
+}
+
+void wxWindow::SetWidgetStyle()
+{
+ GtkStyle *style = GetWidgetStyle();
+
+ gdk_font_unref( style->font );
+ style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
+
+ if (m_foregroundColour.Ok())