X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/62cb3cd8a1e15670c0f9dab2782945db07f42da8..83afe21166ad23a402185eef5dd47782597e8f91:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index d3dac9b822..6691ffd0ce 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -48,12 +48,14 @@ #include "wx/intl.h" #include "wx/settings.h" #include "wx/log.h" +#include "wx/fontutil.h" #ifdef __WXDEBUG__ #include "wx/thread.h" #endif #include +#include #include "wx/gtk/private.h" #include @@ -508,6 +510,22 @@ static int gtk_window_expose_callback( GtkWidget *widget, } #endif +#ifdef __WXGTK20__ + // This callback gets called in drawing-idle time under + // GTK 2.0, so we don't need to defer anything to idle + // time anymore. + + win->GetUpdateRegion() = wxRegion( gdk_event->region ); + + win->GtkSendPaintEvents(); + + // Draw window less widgets + (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); +#else + // This gets called immediately after an expose event + // under GTK 1.2 so we collect the calls and wait for + // the idle handler to pick things up. + win->GetUpdateRegion().Union( gdk_event->area.x, gdk_event->area.y, gdk_event->area.width, @@ -519,13 +537,9 @@ static int gtk_window_expose_callback( GtkWidget *widget, // Actual redrawing takes place in idle time. // win->GtkUpdate(); - -#ifdef __WXGTK20__ - - (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); - #endif + return TRUE; } @@ -2691,16 +2705,14 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags { if (x != -1) m_x = x + pizza->xoffset; if (y != -1) m_y = y + pizza->yoffset; - if (width != -1) m_width = width; - if (height != -1) m_height = height; } else { m_x = x + pizza->xoffset; m_y = y + pizza->yoffset; - m_width = width; - m_height = height; } + if (width != -1) m_width = width; + if (height != -1) m_height = height; if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) { @@ -3139,12 +3151,55 @@ void wxWindowGTK::GetTextExtent( const wxString& string, if (theFont) fontToUse = *theFont; wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") ); + + if (string.IsEmpty()) + { + if (x) (*x) = 0; + if (y) (*y) = 0; + return; + } +#ifdef __WXGTK20__ + PangoContext *context = NULL; + if (m_widget) + gtk_widget_get_pango_context( m_widget ); + + if (!context) + { + if (x) (*x) = 0; + if (y) (*y) = 0; + return; + } + + PangoFontDescription *desc = fontToUse.GetNativeFontInfo()->description; + PangoLayout *layout = pango_layout_new(context); + pango_layout_set_font_description(layout, desc); + { + const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); + pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + } + PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data; + + PangoRectangle rect; + pango_layout_line_get_extents(line, NULL, &rect); + + if (x) (*x) = (wxCoord) (rect.width / PANGO_SCALE); + if (y) (*y) = (wxCoord) (rect.height / PANGO_SCALE); + if (descent) + { + // Do something about metrics here + (*descent) = 0; + } + if (externalLeading) (*externalLeading) = 0; // ?? + + g_object_unref( G_OBJECT( layout ) ); +#else GdkFont *font = fontToUse.GetInternalFont( 1.0 ); - if (x) (*x) = gdk_string_width( font, string.mbc_str() ); + if (x) (*x) = gdk_string_width( font, wxGTK_CONV( string ) ); if (y) (*y) = font->ascent + font->descent; if (descent) (*descent) = font->descent; if (externalLeading) (*externalLeading) = 0; // ?? +#endif } void wxWindowGTK::SetFocus() @@ -3393,27 +3448,31 @@ void wxWindowGTK::GtkUpdate() #ifdef __WXGTK20__ if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window) gdk_window_process_updates( GTK_PIZZA(m_wxwindow)->bin_window, FALSE ); -#endif - +#else if (!m_updateRegion.IsEmpty()) GtkSendPaintEvents(); +#endif } void wxWindowGTK::GtkSendPaintEvents() { if (!m_wxwindow) { +#ifndef __WXGTK20__ m_clearRegion.Clear(); +#endif m_updateRegion.Clear(); return; } + // Clip to paint region in wxClientDC + m_clipPaintRegion = TRUE; + +#ifndef __WXGTK20__ // widget to draw on GtkPizza *pizza = GTK_PIZZA (m_wxwindow); - // Clip to paint region in wxClientDC - m_clipPaintRegion = TRUE; - + // later for GTK 2.0, too. if (GetThemeEnabled()) { // find ancestor from which to steal background @@ -3445,7 +3504,20 @@ void wxWindowGTK::GtkSendPaintEvents() } } else - // if (!m_clearRegion.IsEmpty()) // always send an erase event +#endif + +#ifdef __WXGTK20__ + { + wxWindowDC dc( (wxWindow*)this ); + dc.SetClippingRegion( m_updateRegion ); + + wxEraseEvent erase_event( GetId(), &dc ); + erase_event.SetEventObject( this ); + + GetEventHandler()->ProcessEvent(erase_event); + } +#else + // if (!m_clearRegion.IsEmpty()) // Always send an erase event under GTK 1.2 { wxWindowDC dc( (wxWindow*)this ); if (m_clearRegion.IsEmpty()) @@ -3475,6 +3547,7 @@ void wxWindowGTK::GtkSendPaintEvents() } m_clearRegion.Clear(); } +#endif wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); @@ -3537,6 +3610,7 @@ void wxWindowGTK::Clear() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); +#ifndef __WXGTK20__ if (m_wxwindow && m_wxwindow->window) { m_clearRegion.Clear(); @@ -3546,6 +3620,7 @@ void wxWindowGTK::Clear() // Better do this in idle? GtkUpdate(); } +#endif } #if wxUSE_TOOLTIPS