]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
make sure theme font info is reset if anything is changed
[wxWidgets.git] / src / gtk / window.cpp
index b996ff7fee9d4e807536e2ee7d48faf7fced7626..b72018c1df707b19172bb5d70395e1c4328f8a90 100644 (file)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/gtk/window.cpp
-// Purpose:
+// Purpose:     wxWindowGTK implementation
 // Author:      Robert Roebling
 // Id:          $Id$
 // Copyright:   (c) 1998 Robert Roebling, Julian Smart
@@ -1208,6 +1208,11 @@ bool wxWindowGTK::GTKProcessEvent(wxEvent& event) const
     return HandleWindowEvent(event);
 }
 
+bool wxWindowGTK::GTKShouldIgnoreEvent() const
+{
+    return !m_hasVMT || g_blockEventsOnDrag;
+}
+
 int wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const
 {
     if (!m_hasVMT)
@@ -1828,7 +1833,7 @@ gtk_window_realized_callback(GtkWidget* widget, wxWindow* win)
         gtk_im_context_set_client_window( win->m_imData->context,
                                           widget->window);
     }
-
+    
     // We cannot set colours and fonts before the widget
     // been realized, so we do this directly after realization
     // or otherwise in idle time
@@ -1958,8 +1963,10 @@ wxWindow *wxWindowBase::DoFindFocus()
 
 void wxWindowGTK::AddChildGTK(wxWindowGTK* child)
 {
-    /* the window might have been scrolled already, do we
-       have to adapt the position */
+    wxASSERT_MSG(m_wxwindow, "Cannot add a child to a window without a client area");
+    
+    // the window might have been scrolled already, we
+    // have to adapt the position
     wxPizza* pizza = WX_PIZZA(m_wxwindow);
     child->m_x += pizza->m_scroll_x;
     child->m_y += pizza->m_scroll_y;
@@ -2436,7 +2443,10 @@ bool wxWindowGTK::Destroy()
 void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height)
 {
     gtk_widget_set_size_request(m_widget, width, height);
+    
     // inform the parent to perform the move
+    wxASSERT_MSG(m_parent && m_parent->m_wxwindow, 
+                 "the parent window has no client area?");
     WX_PIZZA(m_parent->m_wxwindow)->move(m_widget, x, y);
 }
 
@@ -2576,8 +2586,8 @@ void wxWindowGTK::OnInternalIdle()
         RealizeTabOrder();
     }
 
-    // Update style if the window was not yet realized
-    // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called
+    // Update style if the window was not yet realized when
+    // SetBackgroundStyle() was called
     if (m_needsStyleChange)
     {
         SetBackgroundStyle(GetBackgroundStyle());
@@ -2819,28 +2829,39 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
 
 bool wxWindowGTK::Show( bool show )
 {
-    wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") );
-
-    if (!wxWindowBase::Show(show))
+    if ( !wxWindowBase::Show(show) )
     {
         // nothing to do
         return false;
     }
 
-    if (show && m_showOnIdle)
+    // notice that we may call Hide() before the window is created and this is
+    // actually useful to create it hidden initially -- but we can't call
+    // Show() before it is created
+    if ( !m_widget )
     {
-        // deferred
+        wxASSERT_MSG( !show, "can't show invalid window" );
+        return true;
     }
-    else
+
+    if ( show )
     {
-        if (show)
-            gtk_widget_show(m_widget);
-        else
-            gtk_widget_hide(m_widget);
-        wxShowEvent eventShow(GetId(), show);
-        eventShow.SetEventObject(this);
-        HandleWindowEvent(eventShow);
+        if ( m_showOnIdle )
+        {
+            // defer until later
+            return true;
+        }
+
+        gtk_widget_show(m_widget);
     }
+    else // hide
+    {
+        gtk_widget_hide(m_widget);
+    }
+
+    wxShowEvent eventShow(GetId(), show);
+    eventShow.SetEventObject(this);
+    HandleWindowEvent(eventShow);
 
     return true;
 }
@@ -2906,12 +2927,12 @@ int wxWindowGTK::GetCharWidth() const
     return (int) PANGO_PIXELS(rect.width);
 }
 
-void wxWindowGTK::GetTextExtent( const wxString& string,
-                                 int *x,
-                                 int *y,
-                                 int *descent,
-                                 int *externalLeading,
-                                 const wxFont *theFont ) const
+void wxWindowGTK::DoGetTextExtent( const wxString& string,
+                                   int *x,
+                                   int *y,
+                                   int *descent,
+                                   int *externalLeading,
+                                   const wxFont *theFont ) const
 {
     wxFont fontToUse = theFont ? *theFont : GetFont();
 
@@ -3526,38 +3547,45 @@ bool wxWindowGTK::ScrollPages(int pages)
     return DoScrollByUnits(ScrollDir_Vert, ScrollUnit_Page, pages);
 }
 
-#include "wx/treectrl.h"
-
 void wxWindowGTK::Refresh(bool WXUNUSED(eraseBackground),
                           const wxRect *rect)
 {
-    GtkWidget* widget;
-    if (m_wxwindow)
-        widget = m_wxwindow;
-    else if (m_widget)
-        widget = m_widget;
-    else
-        return;
-
-    if (!widget->window)
+    if ( !m_widget )
+    {
+        // it is valid to call Refresh() for a window which hasn't been created
+        // yet, it simply doesn't do anything in this case
         return;
+    }
 
-    if (rect == NULL)
+    if (!m_wxwindow)
     {
-        gdk_window_invalidate_rect( widget->window, NULL, TRUE );
+        if (rect)
+            gtk_widget_queue_draw_area( m_widget, rect->x, rect->y, rect->width, rect->height );
+        else
+            gtk_widget_queue_draw( m_widget );
     }
     else
     {
-        int x = rect->x;
-        if (GetLayoutDirection() == wxLayout_RightToLeft)
-            x = GetClientSize().x - x - rect->width;
-            
-        GdkRectangle r;
-        r.x = rect->x;
-        r.y = rect->y;
-        r.width = rect->width;
-        r.height = rect->height;
-        gdk_window_invalidate_rect( m_wxwindow->window, &r, TRUE );
+        // Just return if the widget or one of its ancestors isn't mapped
+        GtkWidget *w;
+        for (w = m_wxwindow; w != NULL; w = w->parent)
+            if (!GTK_WIDGET_MAPPED (w))
+                return;
+
+        if (rect)
+        {
+            int x = rect->x;
+            if (GetLayoutDirection() == wxLayout_RightToLeft)
+                x = GetClientSize().x - x - rect->width;
+            GdkRectangle r;
+            r.x = rect->x;
+            r.y = rect->y;
+            r.width = rect->width;
+            r.height = rect->height;
+            gdk_window_invalidate_rect( m_wxwindow->window, &r, TRUE );
+        }
+        else
+            gdk_window_invalidate_rect( m_wxwindow->window, NULL, TRUE );
     }
 }
 
@@ -3570,8 +3598,8 @@ void wxWindowGTK::Update()
         // This ensures nothing will overwrite the drawing we are about to do.
         gdk_display_sync(display);
 
-        gdk_window_process_updates(m_widget->window, true);
-
+        gdk_window_process_updates(m_widget->window, TRUE);
+        
         // Flush again, but no need to wait for it to finish
         gdk_display_flush(display);
     }
@@ -3627,54 +3655,74 @@ void wxWindowGTK::GtkSendPaintEvents()
         }
     }
 
-    if (GetThemeEnabled() && (GetBackgroundStyle() == wxBG_STYLE_SYSTEM))
+    switch ( GetBackgroundStyle() )
     {
-        // find ancestor from which to steal background
-        wxWindow *parent = wxGetTopLevelParent((wxWindow *)this);
-        if (!parent)
-            parent = (wxWindow*)this;
-
-        if (GTK_WIDGET_MAPPED(parent->m_widget))
-        {
-            wxRegionIterator upd( m_nativeUpdateRegion );
-            while (upd)
+        case wxBG_STYLE_ERASE:
             {
-                GdkRectangle rect;
-                rect.x = upd.GetX();
-                rect.y = upd.GetY();
-                rect.width = upd.GetWidth();
-                rect.height = upd.GetHeight();
-
-                gtk_paint_flat_box( parent->m_widget->style,
-                            m_wxwindow->window,
-                            (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
-                            GTK_SHADOW_NONE,
-                            &rect,
-                            parent->m_widget,
-                            (char *)"base",
-                            0, 0, -1, -1 );
-
-                ++upd;
+                wxWindowDC dc( (wxWindow*)this );
+                dc.SetDeviceClippingRegion( m_updateRegion );
+
+                // Work around gtk-qt <= 0.60 bug whereby the window colour
+                // remains grey
+                if ( UseBgCol() &&
+                        wxSystemOptions::
+                            GetOptionInt("gtk.window.force-background-colour") )
+                {
+                    dc.SetBackground(GetBackgroundColour());
+                    dc.Clear();
+                }
+
+                wxEraseEvent erase_event( GetId(), &dc );
+                erase_event.SetEventObject( this );
+
+                if ( HandleWindowEvent(erase_event) )
+                {
+                    // background erased, don't do it again
+                    break;
+                }
             }
-        }
-    }
-    else
-    {
-        wxWindowDC dc( (wxWindow*)this );
-        dc.SetDeviceClippingRegion( m_updateRegion );
+            // fall through
 
-        // Work around gtk-qt <= 0.60 bug whereby the window colour
-        // remains grey
-        if (GetBackgroundStyle() == wxBG_STYLE_COLOUR && GetBackgroundColour().Ok() && wxSystemOptions::GetOptionInt(wxT("gtk.window.force-background-colour")) == 1)
-        {
-            dc.SetBackground(wxBrush(GetBackgroundColour()));
-            dc.Clear();
-        }
+        case wxBG_STYLE_SYSTEM:
+            if ( GetThemeEnabled() )
+            {
+                // find ancestor from which to steal background
+                wxWindow *parent = wxGetTopLevelParent((wxWindow *)this);
+                if (!parent)
+                    parent = (wxWindow*)this;
 
-        wxEraseEvent erase_event( GetId(), &dc );
-        erase_event.SetEventObject( this );
+                if (GTK_WIDGET_MAPPED(parent->m_widget))
+                {
+                    wxRegionIterator upd( m_nativeUpdateRegion );
+                    while (upd)
+                    {
+                        GdkRectangle rect;
+                        rect.x = upd.GetX();
+                        rect.y = upd.GetY();
+                        rect.width = upd.GetWidth();
+                        rect.height = upd.GetHeight();
+
+                        gtk_paint_flat_box( parent->m_widget->style,
+                                    m_wxwindow->window,
+                                    (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
+                                    GTK_SHADOW_NONE,
+                                    &rect,
+                                    parent->m_widget,
+                                    (char *)"base",
+                                    0, 0, -1, -1 );
+
+                        ++upd;
+                    }
+                }
+            }
+            break;
+
+        case wxBG_STYLE_PAINT:
+            // nothing to do: window will be painted over in EVT_PAINT
+            break;
 
-        HandleWindowEvent(erase_event);
+        default:
+            wxFAIL_MSG( "unsupported background style" );
     }
 
     wxNcPaintEvent nc_paint_event( GetId() );
@@ -3739,8 +3787,7 @@ bool wxWindowGTK::SetBackgroundColour( const wxColour &colour )
 
     // apply style change (forceStyle=true so that new style is applied
     // even if the bg colour changed from valid to wxNullColour)
-    if (GetBackgroundStyle() != wxBG_STYLE_CUSTOM)
-        GTKApplyWidgetStyle(true);
+    GTKApplyWidgetStyle(true);
 
     return true;
 }
@@ -3868,7 +3915,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style)
 {
     wxWindowBase::SetBackgroundStyle(style);
 
-    if (style == wxBG_STYLE_CUSTOM)
+    if ( style == wxBG_STYLE_PAINT )
     {
         GdkWindow *window;
         if ( m_wxwindow )
@@ -3906,6 +3953,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style)
         // even if the bg colour changed from valid to wxNullColour):
         GTKApplyWidgetStyle(true);
     }
+
     return true;
 }