X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d44c23ceb6f816dedd0162f0ca9269ef5f97d0f5..2365e5cbcf5bffc6d1ffb363b187455e8f093445:/src/gtk1/window.cpp diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 2786d91934..ad3161a7d5 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/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; } @@ -3137,12 +3151,61 @@ 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); + { +#if wxUSE_UNICODE + const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); + pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); +#else + const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string ); + const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); + pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); +#endif + } + 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() @@ -3391,27 +3454,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 @@ -3443,7 +3510,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()) @@ -3473,6 +3553,7 @@ void wxWindowGTK::GtkSendPaintEvents() } m_clearRegion.Clear(); } +#endif wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); @@ -3535,6 +3616,7 @@ void wxWindowGTK::Clear() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); +#ifndef __WXGTK20__ if (m_wxwindow && m_wxwindow->window) { m_clearRegion.Clear(); @@ -3544,6 +3626,7 @@ void wxWindowGTK::Clear() // Better do this in idle? GtkUpdate(); } +#endif } #if wxUSE_TOOLTIPS