]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/dcclient.cpp
Added wxRichTextXMLHandler::RegisterNodeName so custom content classes can be added...
[wxWidgets.git] / src / gtk / dcclient.cpp
index 234a38f27871b1422c6d5a35158ffe2a868ce498..c427dfa08ceea3c72a4487890b13c7973d763021 100644 (file)
@@ -71,27 +71,42 @@ static GdkPixmap* GetHatch(int style)
     const int i = style - wxBRUSHSTYLE_FIRST_HATCH;
     if (hatches[i] == NULL)
     {
+        // This macro creates a bitmap from an XBM file included above. Notice
+        // the need for the cast because gdk_bitmap_create_from_data() doesn't
+        // accept unsigned data but the arrays in XBM need to be unsigned to
+        // avoid warnings (and even errors in C+0x mode) from g++.
+#define CREATE_FROM_XBM_DATA(name) \
+        gdk_bitmap_create_from_data \
+        ( \
+            NULL, \
+            reinterpret_cast<gchar *>(name ## _bits), \
+            name ## _width, \
+            name ## _height \
+        )
+
         switch (style)
         {
         case wxBRUSHSTYLE_BDIAGONAL_HATCH:
-            hatches[i] = gdk_bitmap_create_from_data(NULL, bdiag_bits, bdiag_width, bdiag_height);
+            hatches[i] = CREATE_FROM_XBM_DATA(bdiag);
             break;
         case wxBRUSHSTYLE_CROSSDIAG_HATCH:
-            hatches[i] = gdk_bitmap_create_from_data(NULL, cdiag_bits, cdiag_width, cdiag_height);
+            hatches[i] = CREATE_FROM_XBM_DATA(cdiag);
             break;
         case wxBRUSHSTYLE_CROSS_HATCH:
-            hatches[i] = gdk_bitmap_create_from_data(NULL, cross_bits, cross_width, cross_height);
+            hatches[i] = CREATE_FROM_XBM_DATA(cross);
             break;
         case wxBRUSHSTYLE_FDIAGONAL_HATCH:
-            hatches[i] = gdk_bitmap_create_from_data(NULL, fdiag_bits, fdiag_width, fdiag_height);
+            hatches[i] = CREATE_FROM_XBM_DATA(fdiag);
             break;
         case wxBRUSHSTYLE_HORIZONTAL_HATCH:
-            hatches[i] = gdk_bitmap_create_from_data(NULL, horiz_bits, horiz_width, horiz_height);
+            hatches[i] = CREATE_FROM_XBM_DATA(horiz);
             break;
         case wxBRUSHSTYLE_VERTICAL_HATCH:
-            hatches[i] = gdk_bitmap_create_from_data(NULL, verti_bits, verti_width, verti_height);
+            hatches[i] = CREATE_FROM_XBM_DATA(verti);
             break;
         }
+
+#undef CREATE_FROM_XBM_DATA
     }
     return hatches[i];
 }
@@ -114,7 +129,11 @@ enum wxPoolGCType
    wxTEXT_SCREEN,
    wxBG_SCREEN,
    wxPEN_SCREEN,
-   wxBRUSH_SCREEN
+   wxBRUSH_SCREEN,
+   wxTEXT_COLOUR_ALPHA,
+   wxBG_COLOUR_ALPHA,
+   wxPEN_COLOUR_ALPHA,
+   wxBRUSH_COLOUR_ALPHA
 };
 
 struct wxGC
@@ -269,6 +288,7 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) :
     m_font = window->GetFont();
 
     GtkWidget *widget = window->m_wxwindow;
+    m_gdkwindow = window->GTKGetDrawingWindow();
 
     // Some controls don't have m_wxwindow - like wxStaticBox, but the user
     // code should still be able to create wxClientDCs for them
@@ -278,7 +298,8 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) :
 
         wxCHECK_RET(widget, "DC needs a widget");
 
-        if (GTK_WIDGET_NO_WINDOW(widget))
+        m_gdkwindow = widget->window;
+        if (!gtk_widget_get_has_window(widget))
             SetDeviceLocalOrigin(widget->allocation.x, widget->allocation.y);
     }
 
@@ -286,8 +307,6 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) :
     m_layout = pango_layout_new( m_context );
     m_fontdesc = pango_font_description_copy( widget->style->font_desc );
 
-    m_gdkwindow = widget->window;
-
     // Window not realized ?
     if (!m_gdkwindow)
     {
@@ -360,6 +379,18 @@ void wxWindowDCImpl::SetUpDC( bool isMemDC )
             m_textGC = wxGetPoolGC( m_gdkwindow, wxTEXT_SCREEN );
             m_bgGC = wxGetPoolGC( m_gdkwindow, wxBG_SCREEN );
         }
+#if GTK_CHECK_VERSION(2,12,0)
+        // gdk_screen_get_rgba_colormap was added in 2.8, but this code is for
+        // compositing which requires 2.12
+        else if (gtk_check_version(2,12,0) == NULL &&
+            m_cmap == gdk_screen_get_rgba_colormap(gdk_colormap_get_screen(m_cmap)))
+        {
+            m_penGC = wxGetPoolGC( m_gdkwindow, wxPEN_COLOUR_ALPHA );
+            m_brushGC = wxGetPoolGC( m_gdkwindow, wxBRUSH_COLOUR_ALPHA );
+            m_textGC = wxGetPoolGC( m_gdkwindow, wxTEXT_COLOUR_ALPHA );
+            m_bgGC = wxGetPoolGC( m_gdkwindow, wxBG_COLOUR_ALPHA );
+        }
+#endif
         else
         {
             m_penGC = wxGetPoolGC( m_gdkwindow, wxPEN_COLOUR );
@@ -419,7 +450,7 @@ void wxWindowDCImpl::SetUpDC( bool isMemDC )
 
 void wxWindowDCImpl::DoGetSize( int* width, int* height ) const
 {
-    wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
+    wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") );
 
     m_window->GetSize(width, height);
 }
@@ -477,7 +508,7 @@ void wxWindowDCImpl::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2
 {
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+    if ( m_pen.IsNonTransparent() )
     {
         if (m_gdkwindow)
             gdk_draw_line( m_gdkwindow, m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
@@ -491,7 +522,7 @@ void wxWindowDCImpl::DoCrossHair( wxCoord x, wxCoord y )
 {
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+    if ( m_pen.IsNonTransparent() )
     {
         int w = 0;
         int h = 0;
@@ -589,7 +620,7 @@ void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
 
     if (m_gdkwindow)
     {
-        if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+        if ( m_brush.IsNonTransparent() )
         {
             GdkGC* gc;
             bool originChanged;
@@ -601,11 +632,11 @@ void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
                 gdk_gc_set_ts_origin(gc, 0, 0);
         }
 
-        if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+        if ( m_pen.IsNonTransparent() )
         {
             gdk_draw_arc( m_gdkwindow, m_penGC, FALSE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
 
-            if ((m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) && (alpha2 - alpha1 != 360*64))
+            if ( m_brush.IsNonTransparent() && (alpha2 - alpha1 != 360*64) )
             {
                 gdk_draw_line( m_gdkwindow, m_penGC, xx1, yy1, xxc, yyc );
                 gdk_draw_line( m_gdkwindow, m_penGC, xxc, yyc, xx2, yy2 );
@@ -635,7 +666,7 @@ void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxC
         wxCoord start = wxCoord(sa * 64.0);
         wxCoord end = wxCoord((ea-sa) * 64.0);
 
-        if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+        if ( m_brush.IsNonTransparent() )
         {
             GdkGC* gc;
             bool originChanged;
@@ -647,7 +678,7 @@ void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxC
                 gdk_gc_set_ts_origin(gc, 0, 0);
         }
 
-        if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+        if ( m_pen.IsNonTransparent() )
             gdk_draw_arc( m_gdkwindow, m_penGC, FALSE, xx, yy, ww, hh, start, end );
     }
 
@@ -659,7 +690,7 @@ void wxWindowDCImpl::DoDrawPoint( wxCoord x, wxCoord y )
 {
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    if ((m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) && m_gdkwindow)
+    if ( m_pen.IsNonTransparent() && m_gdkwindow )
         gdk_draw_point( m_gdkwindow, m_penGC, XLOG2DEV(x), YLOG2DEV(y) );
 
     CalcBoundingBox (x, y);
@@ -669,9 +700,11 @@ void wxWindowDCImpl::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCo
 {
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    if (m_pen.GetStyle() == wxPENSTYLE_TRANSPARENT) return;
     if (n <= 0) return;
 
+    if ( m_pen.IsTransparent() )
+        return;
+
     //Check, if scaling is necessary
     const bool doScale =
         xoffset != 0 || yoffset != 0 || XLOG2DEV(10) != 10 || YLOG2DEV(10) != 10;
@@ -730,7 +763,7 @@ void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[],
 
     if (m_gdkwindow)
     {
-        if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+        if ( m_brush.IsNonTransparent() )
         {
             GdkGC* gc;
             bool originChanged;
@@ -742,7 +775,7 @@ void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[],
                 gdk_gc_set_ts_origin(gc, 0, 0);
         }
 
-        if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+        if ( m_pen.IsNonTransparent() )
         {
 /*
             for (i = 0 ; i < n ; i++)
@@ -781,7 +814,7 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo
 
     if (m_gdkwindow)
     {
-        if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+        if ( m_brush.IsNonTransparent() )
         {
             GdkGC* gc;
             bool originChanged;
@@ -793,9 +826,8 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo
                 gdk_gc_set_ts_origin(gc, 0, 0);
         }
 
-        if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+        if ( m_pen.IsNonTransparent() )
         {
-#if 1
             if ((m_pen.GetWidth() == 2) && (m_pen.GetCap() == wxCAP_ROUND) &&
                 (m_pen.GetJoin() == wxJOIN_ROUND) && (m_pen.GetStyle() == wxPENSTYLE_SOLID))
             {
@@ -818,7 +850,6 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo
                 gdk_gc_set_line_attributes( m_penGC, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND );
             }
             else
-#endif
             {
                 // Just use X11 for other cases
                 gdk_draw_rectangle( m_gdkwindow, m_penGC, FALSE, xx, yy, ww-1, hh-1 );
@@ -859,7 +890,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width
 
     // CMB: adjust size if outline is drawn otherwise the result is
     // 1 pixel too wide and high
-    if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+    if ( m_pen.IsNonTransparent() )
     {
         ww--;
         hh--;
@@ -874,7 +905,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width
         if (dd > hh) dd = hh;
         rr = dd / 2;
 
-        if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+        if ( m_brush.IsNonTransparent() )
         {
             GdkGC* gc;
             bool originChanged;
@@ -891,7 +922,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width
                 gdk_gc_set_ts_origin(gc, 0, 0);
         }
 
-        if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+        if ( m_pen.IsNonTransparent() )
         {
             gdk_draw_line( m_gdkwindow, m_penGC, xx+rr+1, yy, xx+ww-rr, yy );
             gdk_draw_line( m_gdkwindow, m_penGC, xx+rr+1, yy+hh, xx+ww-rr, yy+hh );
@@ -924,7 +955,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord
 
     if (m_gdkwindow)
     {
-        if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+        if ( m_brush.IsNonTransparent() )
         {
             GdkGC* gc;
             bool originChanged;
@@ -932,7 +963,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord
 
             // If the pen is transparent pen we increase the size
             // for better compatibility with other platforms.
-            if (m_pen.GetStyle() == wxPENSTYLE_TRANSPARENT)
+            if (m_pen.IsTransparent())
             {
                 ++ww;
                 ++hh;
@@ -944,7 +975,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord
                 gdk_gc_set_ts_origin(gc, 0, 0);
         }
 
-        if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+        if ( m_pen.IsNonTransparent() )
             gdk_draw_arc( m_gdkwindow, m_penGC, false, xx, yy, ww, hh, 0, 360*64 );
     }
 
@@ -1059,8 +1090,11 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap,
     const int w = bitmap.GetWidth();
     const int h = bitmap.GetHeight();
 
+    // notice that as the bitmap is not drawn upside down (or right to left)
+    // even if the corresponding axis direction is inversed, we need to take it
+    // into account when calculating its bounding box
     CalcBoundingBox(x, y);
-    CalcBoundingBox(x + w, y + h);
+    CalcBoundingBox(x + m_signX*w, y + m_signY*h);
 
     // device coords
     int xx = LogicalToDeviceX(x);
@@ -1335,7 +1369,9 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest,
     return true;
 }
 
-void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
+void wxWindowDCImpl::DoDrawText(const wxString& text,
+                                wxCoord xLogical,
+                                wxCoord yLogical)
 {
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
@@ -1343,8 +1379,8 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
 
     if (text.empty()) return;
 
-    x = XLOG2DEV(x);
-    y = YLOG2DEV(y);
+    wxCoord x = XLOG2DEV(xLogical),
+            y = YLOG2DEV(yLogical);
 
     wxCHECK_RET( m_context, wxT("no Pango context") );
     wxCHECK_RET( m_layout, wxT("no Pango layout") );
@@ -1352,69 +1388,12 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
 
     gdk_pango_context_set_colormap( m_context, m_cmap );  // not needed in gtk+ >= 2.6
 
-    bool underlined = m_font.IsOk() && m_font.GetUnderlined();
-
     wxCharBuffer data = wxGTK_CONV(text);
     if ( !data )
         return;
-    size_t datalen = strlen(data);
-
-    // in Pango >= 1.16 the "underline of leading/trailing spaces" bug
-    // has been fixed and thus the hack implemented below should never be used
-    static bool pangoOk = !wx_pango_version_check(1, 16, 0);
-
-    bool needshack = underlined && !pangoOk;
-
-    if (needshack)
-    {
-        // a PangoLayout which has leading/trailing spaces with underlined font
-        // is not correctly drawn by this pango version: Pango won't underline the spaces.
-        // This can be a problem; e.g. wxHTML rendering of underlined text relies on
-        // this behaviour. To workaround this problem, we use a special hack here
-        // suggested by pango maintainer Behdad Esfahbod: we prepend and append two
-        // empty space characters and give them a dummy colour attribute.
-        // This will force Pango to underline the leading/trailing spaces, too.
-
-        wxCharBuffer data_tmp(datalen + 6);
-        // copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
-        memcpy(data_tmp.data(), "\342\200\214", 3);
-        // copy the user string
-        memcpy(data_tmp.data() + 3, data, datalen);
-        // copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
-        memcpy(data_tmp.data() + 3 + datalen, "\342\200\214", 3);
 
-        data = data_tmp;
-        datalen += 6;
-    }
-
-    pango_layout_set_text(m_layout, data, datalen);
-
-    if (underlined)
-    {
-        PangoAttrList *attrs = pango_attr_list_new();
-        PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
-        a->start_index = 0;
-        a->end_index = datalen;
-        pango_attr_list_insert(attrs, a);
-
-        if (needshack)
-        {
-            // dummy colour for the leading space
-            a = pango_attr_foreground_new (0x0057, 0x52A9, 0xD614);
-            a->start_index = 0;
-            a->end_index = 1;
-            pango_attr_list_insert(attrs, a);
-
-            // dummy colour for the trailing space
-            a = pango_attr_foreground_new (0x0057, 0x52A9, 0xD614);
-            a->start_index = datalen - 1;
-            a->end_index = datalen;
-            pango_attr_list_insert(attrs, a);
-        }
-
-        pango_layout_set_attributes(m_layout, attrs);
-        pango_attr_list_unref(attrs);
-    }
+    pango_layout_set_text(m_layout, data, data.length());
+    const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout);
 
     int oldSize = 0;
     const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
@@ -1453,14 +1432,14 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
          // actually apply unscaled font
          pango_layout_set_font_description( m_layout, m_fontdesc );
     }
-    if (underlined)
+    if (setAttrs)
     {
         // undo underline attributes setting:
         pango_layout_set_attributes(m_layout, NULL);
     }
 
-    CalcBoundingBox(x + int(w / m_scaleX), y + int(h / m_scaleY));
-    CalcBoundingBox(x, y);
+    CalcBoundingBox(xLogical + int(w / m_scaleX), yLogical + int(h / m_scaleY));
+    CalcBoundingBox(xLogical, yLogical);
 }
 
 // TODO: When GTK2.6 is required, merge DoDrawText and DoDrawRotatedText to
@@ -1472,23 +1451,14 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord
 
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-#if __WXGTK26__
+#ifdef __WXGTK26__
     if (!gtk_check_version(2,6,0))
     {
         x = XLOG2DEV(x);
         y = YLOG2DEV(y);
 
         pango_layout_set_text(m_layout, wxGTK_CONV(text), -1);
-
-        if (m_font.GetUnderlined())
-        {
-            PangoAttrList *attrs = pango_attr_list_new();
-            PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
-            pango_attr_list_insert(attrs, a);
-            pango_layout_set_attributes(m_layout, attrs);
-            pango_attr_list_unref(attrs);
-        }
-
+        const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout);
         int oldSize = 0;
         const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
         if (isScaled)
@@ -1541,7 +1511,7 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord
         gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x+minX, y+minY,
                                     m_layout, NULL, bg_col);
 
-        if (m_font.GetUnderlined())
+        if (setAttrs)
             pango_layout_set_attributes(m_layout, NULL);
 
         // clean up the transformation matrix
@@ -1778,7 +1748,7 @@ wxCoord wxWindowDCImpl::GetCharWidth() const
 wxCoord wxWindowDCImpl::GetCharHeight() const
 {
     PangoFontMetrics *metrics = pango_context_get_metrics (m_context, m_fontdesc, pango_context_get_language(m_context));
-    wxCHECK_MSG( metrics, -1, _T("failed to get pango font metrics") );
+    wxCHECK_MSG( metrics, -1, wxT("failed to get pango font metrics") );
 
     wxCoord h = PANGO_PIXELS (pango_font_metrics_get_descent (metrics) +
                               pango_font_metrics_get_ascent (metrics));
@@ -2284,7 +2254,6 @@ int wxWindowDCImpl::GetDepth() const
     return gdk_drawable_get_depth(m_gdkwindow);
 }
 
-
 //-----------------------------------------------------------------------------
 // wxClientDCImpl
 //-----------------------------------------------------------------------------
@@ -2299,7 +2268,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner )
 wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win )
           : wxWindowDCImpl( owner, win )
 {
-    wxCHECK_RET( win, _T("NULL window in wxClientDCImpl::wxClientDC") );
+    wxCHECK_RET( win, wxT("NULL window in wxClientDCImpl::wxClientDC") );
 
 #ifdef __WXUNIVERSAL__
     wxPoint ptOrigin = win->GetClientAreaOrigin();
@@ -2312,7 +2281,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win )
 
 void wxClientDCImpl::DoGetSize(int *width, int *height) const
 {
-    wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
+    wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") );
 
     m_window->GetClientSize( width, height );
 }