]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/window.cpp
Optimized sizers to not call CalcMin more often than neccessary
[wxWidgets.git] / src / gtk1 / window.cpp
index 4b7a6ed8ae89345e0d4be812d52d3a1d786ce100..e471db7e9fbaa9c76ca3dd9970c1ca239d3a0e43 100644 (file)
@@ -145,7 +145,7 @@ extern GtkContainerClass *pizza_parent_class;
    thw wxWindow class has a member variable called m_widget which holds a
    pointer to this widget. When the window class represents a GTK native widget,
    this is (in most cases) the only GTK widget the class manages. E.g. the
-   wxStatitText class handles only a GtkLabel widget a pointer to which you
+   wxStaticText class handles only a GtkLabel widget a pointer to which you
    can find in m_widget (defined in wxWindow)
 
    When the class has a client area for drawing into and for containing children
@@ -1142,7 +1142,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
         key_code = wxTranslateKeySymToWXKey(gdk_event->keyval, FALSE /* isChar */);
         if ( !key_code && win->m_imContext )
         {
-            gtk_im_context_filter_keypress ( (GtkIMContext*) win->m_imContext, gdk_event );
+            gtk_im_context_filter_keypress(win->m_imContext, gdk_event );
             ret = TRUE;
         }
         else
@@ -1274,11 +1274,15 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
     if (event.m_uniChar < 256)
         event.m_keyCode = event.m_uniChar;
 #else
-    gunichar uniChar = g_utf8_get_char( str );
-    // We cannot handle Unicode in non-Unicode mode
-    if (uniChar > 255) return;
-
-    event.m_keyCode = uniChar;
+    wchar_t unistr[2];
+    unistr[0] = g_utf8_get_char(str);
+    unistr[1] = 0;
+    wxCharBuffer ansistr(wxConvLocal.cWC2MB(unistr));
+    // We cannot handle characters that cannot be represented in 
+    // current locale's charset in non-Unicode mode:
+    if (ansistr.data() == NULL) return;
+
+    event.m_keyCode = ansistr[0u];
 #endif
 
 
@@ -1534,8 +1538,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget,
 
     wxEventType event_type = wxEVT_NULL;
 
-    // GdkDisplay is a GTK+ 2.1.0 thing
-#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 1, 0)
+    // GdkDisplay is a GTK+ 2.2.0 thing
+#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 2, 0)
     if ( gdk_event->type == GDK_2BUTTON_PRESS &&
             gdk_event->button >= 1 && gdk_event->button <= 3 )
     {
@@ -2307,17 +2311,11 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
     if (g_isIdle)
         wxapp_install_idle_handler();
         
-    if (win->m_delayedBackgroundColour)
-        win->GtkSetBackgroundColour( win->GetBackgroundColour() );
-
-    if (win->m_delayedForegroundColour)
-        win->GtkSetForegroundColour( win->GetForegroundColour() );
-
 #ifdef __WXGTK20__
     if (win->m_imContext)
     {
         GtkPizza *pizza = GTK_PIZZA( m_widget );
-        gtk_im_context_set_client_window( (GtkIMContext*) win->m_imContext, pizza->bin_window );
+        gtk_im_context_set_client_window( win->m_imContext, pizza->bin_window );
     }
 #endif
 
@@ -2575,9 +2573,6 @@ void wxWindowGTK::Init()
 
     m_cursor = *wxSTANDARD_CURSOR;
 
-    m_delayedForegroundColour = FALSE;
-    m_delayedBackgroundColour = FALSE;
-
 #ifdef __WXGTK20__
     m_imContext = NULL;
     m_x11Context = NULL;
@@ -2622,9 +2617,6 @@ bool wxWindowGTK::Create( wxWindow *parent,
 
     m_insertCallback = wxInsertChildInWindow;
 
-    // always needed for background clearing
-    m_delayedBackgroundColour = TRUE;
-
     m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
@@ -2707,17 +2699,6 @@ bool wxWindowGTK::Create( wxWindow *parent,
     gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
           (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
 
-#ifdef __WXGTK20__
-    // Create input method handler
-    m_imContext = (GtkIMMulticontext*) gtk_im_multicontext_new ();
-
-    // Cannot handle drawing preedited text yet
-    gtk_im_context_set_use_preedit( (GtkIMContext*) m_imContext, FALSE );
-
-    g_signal_connect (G_OBJECT (m_imContext), "commit",
-        G_CALLBACK (gtk_wxwindow_commit_cb), this);
-#endif
-
     gtk_widget_show( m_wxwindow );
 
     if (m_parent)
@@ -2813,18 +2794,18 @@ void wxWindowGTK::PostCreation()
 #else
             // gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), !HasFlag( wxFULL_REPAINT_ON_RESIZE ) );
 #endif
+        }
 
 #ifdef __WXGTK20__
         // Create input method handler
-        m_imContext = (GtkIMMulticontext*) gtk_im_multicontext_new ();
+        m_imContext = gtk_im_multicontext_new();
 
         // Cannot handle drawing preedited text yet
-        gtk_im_context_set_use_preedit( (GtkIMContext*) m_imContext, FALSE );
+        gtk_im_context_set_use_preedit( m_imContext, FALSE );
 
         g_signal_connect (G_OBJECT (m_imContext), "commit",
-            G_CALLBACK (gtk_wxwindow_commit_cb), this);
+                          G_CALLBACK (gtk_wxwindow_commit_cb), this);
 #endif
-        }
 
         // these are called when the "sunken" or "raised" borders are drawn
         gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
@@ -3975,74 +3956,24 @@ void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 }
 #endif // wxUSE_TOOLTIPS
 
-void wxWindowGTK::GtkSetBackgroundColour( const wxColour &colour )
-{
-    GdkWindow *window = (GdkWindow*) NULL;
-    if (m_wxwindow)
-        window = GTK_PIZZA(m_wxwindow)->bin_window;
-    else
-        window = GetConnectWidget()->window;
-
-    wxASSERT( window );
-
-    // This will work around the fact that I don't know what to do to reset to
-    // theme settings when colour == wxNullColour, GetBackgroundColour will
-    // fetch the default if needed, giving us a valid colour to use below.
-    // Vaclav needs to help here to implement the RightThing...
-    wxColour newColour = GetBackgroundColour();
-    
-    // We need the pixel value e.g. for background clearing.
-    newColour.CalcPixel( gdk_window_get_colormap( window ) );
-
-    if (m_wxwindow)
-    {
-        // wxMSW doesn't clear the window here, either.
-        gdk_window_set_background( window, newColour.GetColor() );
-    }
-
-    ApplyWidgetStyle();
-}
-
 bool wxWindowGTK::SetBackgroundColour( const wxColour &colour )
 {
-    wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
+    wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
 
     if (!wxWindowBase::SetBackgroundColour(colour))
         return false;
 
-    GdkWindow *window = (GdkWindow*) NULL;
-    if (m_wxwindow)
-        window = GTK_PIZZA(m_wxwindow)->bin_window;
-    else
-        window = GetConnectWidget()->window;
-
-    if (!window)
+    if (colour.Ok())
     {
-        // indicate that a new style has been set
-        // but it couldn't get applied as the
-        // widget hasn't been realized yet.
-        m_delayedBackgroundColour = true;
-        return true;
+        // We need the pixel value e.g. for background clearing.
+        m_backgroundColour.CalcPixel(gtk_widget_get_colormap(m_widget));
     }
-    else
-    {
-        GtkSetBackgroundColour( colour );
-    }
-
-    return true;
-}
-
-void wxWindowGTK::GtkSetForegroundColour( const wxColour &colour )
-{
-    GdkWindow *window = (GdkWindow*) NULL;
-    if (m_wxwindow)
-        window = GTK_PIZZA(m_wxwindow)->bin_window;
-    else
-        window = GetConnectWidget()->window;
 
-    wxASSERT( window );
+    // apply style change (forceStyle=true so that new style is applied
+    // even if the bg colour changed from valid to wxNullColour):
+    ApplyWidgetStyle(true);
 
-    ApplyWidgetStyle();
+    return true;
 }
 
 bool wxWindowGTK::SetForegroundColour( const wxColour &colour )
@@ -4051,29 +3982,19 @@ bool wxWindowGTK::SetForegroundColour( const wxColour &colour )
 
     if (!wxWindowBase::SetForegroundColour(colour))
     {
-        // don't leave if the GTK widget has just
-        // been realized
-        if (!m_delayedForegroundColour) return false;
-    }
-
-    GdkWindow *window = (GdkWindow*) NULL;
-    if (m_wxwindow)
-        window = GTK_PIZZA(m_wxwindow)->bin_window;
-    else
-        window = GetConnectWidget()->window;
-
-    if (!window)
-    {
-        // indicate that a new style has been set
-        // but it couldn't get applied as the
-        // widget hasn't been realized yet.
-        m_delayedForegroundColour = true;
+        return false;
     }
-    else
+    
+    if (colour.Ok())
     {
-       GtkSetForegroundColour( colour );
+        // We need the pixel value e.g. for background clearing.
+        m_foregroundColour.CalcPixel(gtk_widget_get_colormap(m_widget));
     }
 
+    // apply style change (forceStyle=true so that new style is applied
+    // even if the bg colour changed from valid to wxNullColour):
+    ApplyWidgetStyle(true);
+
     return true;
 }
 
@@ -4092,18 +4013,19 @@ PangoContext *wxWindowGTK::GtkGetPangoX11Context()
 }
 #endif
  
-GtkRcStyle *wxWindowGTK::CreateWidgetStyle()
+GtkRcStyle *wxWindowGTK::CreateWidgetStyle(bool forceStyle)
 {
     // do we need to apply any changes at all?
-    if ( !m_hasFont && !m_hasFgCol &&
-         (!m_hasBgCol || !m_backgroundColour.Ok()) )
+    if ( !forceStyle &&
+         !m_font.Ok() &&
+         !m_foregroundColour.Ok() && !m_backgroundColour.Ok() )
     {
         return NULL;
     }
 
     GtkRcStyle *style = gtk_rc_style_new();
 
-    if ( m_hasFont )
+    if ( m_font.Ok() )
     {
 #ifdef __WXGTK20__
         style->font_desc = 
@@ -4114,41 +4036,41 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle()
 #endif
     }
 
-    if ( m_hasFgCol )
+    if ( m_foregroundColour.Ok() )
     {
-        m_foregroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) );
+        GdkColor *fg = m_foregroundColour.GetColor();
         
-        style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
+        style->fg[GTK_STATE_NORMAL] = *fg;
         style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG;
         
-        style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
+        style->fg[GTK_STATE_PRELIGHT] = *fg;
         style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG;
         
-        style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
+        style->fg[GTK_STATE_ACTIVE] = *fg;
         style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG;
     }
 
-    if ( m_hasBgCol && m_backgroundColour.Ok() )
+    if ( m_backgroundColour.Ok() )
     {
-        m_backgroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) );
-        
-        style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
+        GdkColor *bg = m_backgroundColour.GetColor();
+
+        style->bg[GTK_STATE_NORMAL] = *bg;
+        style->base[GTK_STATE_NORMAL] = *bg;
         style->color_flags[GTK_STATE_NORMAL] = (GtkRcFlags)
             (style->color_flags[GTK_STATE_NORMAL] | GTK_RC_BG | GTK_RC_BASE);
         
-        style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
+        style->bg[GTK_STATE_PRELIGHT] = *bg;
+        style->base[GTK_STATE_PRELIGHT] = *bg;
         style->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags)
             (style->color_flags[GTK_STATE_PRELIGHT] | GTK_RC_BG | GTK_RC_BASE);
         
-        style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
+        style->bg[GTK_STATE_ACTIVE] = *bg;
+        style->base[GTK_STATE_ACTIVE] = *bg;
         style->color_flags[GTK_STATE_ACTIVE] = (GtkRcFlags)
             (style->color_flags[GTK_STATE_ACTIVE] | GTK_RC_BG | GTK_RC_BASE);
         
-        style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
+        style->bg[GTK_STATE_INSENSITIVE] = *bg;
+        style->base[GTK_STATE_INSENSITIVE] = *bg;
         style->color_flags[GTK_STATE_INSENSITIVE] = (GtkRcFlags)
             (style->color_flags[GTK_STATE_INSENSITIVE] | GTK_RC_BG | GTK_RC_BASE);
     }
@@ -4156,10 +4078,26 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle()
     return style;
 }
 
-void wxWindowGTK::ApplyWidgetStyle()
+void wxWindowGTK::ApplyWidgetStyle(bool forceStyle)
 {
+    GtkRcStyle *style = CreateWidgetStyle(forceStyle);
+    if ( style )
+    {
+        DoApplyWidgetStyle(style);
+        gtk_rc_style_unref(style);
+    }
 }
 
+void wxWindowGTK::DoApplyWidgetStyle(GtkRcStyle *style)
+{
+    if (m_wxwindow)
+        // should we also do m_widget in this case?
+        gtk_widget_modify_style(m_wxwindow, style);
+    else
+        gtk_widget_modify_style(m_widget, style);
+}
+
+
 //-----------------------------------------------------------------------------
 // Pop-up menu stuff
 //-----------------------------------------------------------------------------
@@ -4302,24 +4240,16 @@ bool wxWindowGTK::IsOwnGtkWindow( GdkWindow *window )
 
 bool wxWindowGTK::SetFont( const wxFont &font )
 {
-    if (!wxWindowBase::SetFont(font) || !m_widget)
-    {
-        return FALSE;
-    }
+    wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
 
-    wxColour sysbg = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
-    if ( sysbg == m_backgroundColour )
-    {
-        m_backgroundColour = wxNullColour;
-        ApplyWidgetStyle();
-        m_backgroundColour = sysbg;
-    }
-    else
-    {
-        ApplyWidgetStyle();
-    }
+    if (!wxWindowBase::SetFont(font))
+        return false;
 
-    return TRUE;
+    // apply style change (forceStyle=true so that new style is applied
+    // even if the font changed from valid to wxNullFont):
+    ApplyWidgetStyle(true);    
+
+    return true;
 }
 
 void wxWindowGTK::DoCaptureMouse()