1. iterate over update region in wxTextCtrl

2. fixed DC clipping under wxMSW
3. fixes to enable clipboard under wxMSW


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8432 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-09-28 00:19:14 +00:00
parent f0b67b1c57
commit 3ab62a0f7f
14 changed files with 157 additions and 88 deletions

View File

@@ -140,6 +140,9 @@ public:
const wxBitmap& GetSelectedBitmap() const { return m_selectedBitmap; } const wxBitmap& GetSelectedBitmap() const { return m_selectedBitmap; }
wxBitmap& GetSelectedBitmap() { return m_selectedBitmap; } wxBitmap& GetSelectedBitmap() { return m_selectedBitmap; }
// update the internal clip box variables
void UpdateClipBox();
protected: protected:
virtual void DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, virtual void DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
int style = wxFLOOD_SURFACE); int style = wxFLOOD_SURFACE);

View File

@@ -293,6 +293,9 @@ private:
#define GetHfont() ((HFONT)GetHFONT()) #define GetHfont() ((HFONT)GetHFONT())
#define GetHfontOf(font) ((HFONT)(font).GetHFONT()) #define GetHfontOf(font) ((HFONT)(font).GetHFONT())
#define GetHrgn() ((HRGN)GetHRGN())
#define GetHrgnOf(rgn) ((HRGN)(rgn).GetHRGN())
#endif // wxUSE_GUI #endif // wxUSE_GUI
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -126,7 +126,8 @@
#define wxUSE_MS_HTML_HELP 0 #define wxUSE_MS_HTML_HELP 0
#define wxUSE_RESOURCES 0 #define wxUSE_RESOURCES 0
#define wxUSE_CONSTRAINTS 0 #define wxUSE_CONSTRAINTS 0
#define wxUSE_CLIPBOARD 0 #define wxUSE_CLIPBOARD 1
#define wxUSE_DATAOBJ 1
#define wxUSE_SPLINES 0 #define wxUSE_SPLINES 0
#define wxUSE_DRAG_AND_DROP 0 #define wxUSE_DRAG_AND_DROP 0
#define wxUSE_XPM_IN_MSW 1 #define wxUSE_XPM_IN_MSW 1

View File

@@ -231,6 +231,8 @@ protected:
const wxString& text, const wxString& text,
long selStart, long selEnd); long selStart, long selEnd);
void DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate);
virtual void DoDraw(wxControlRenderer *renderer); virtual void DoDraw(wxControlRenderer *renderer);
// calc the size from the text extent // calc the size from the text extent

View File

@@ -53,6 +53,8 @@
#include "wx/univ/theme.h" #include "wx/univ/theme.h"
#define TEST_TEXT_ONLY
//#define DEBUG_SCROLL //#define DEBUG_SCROLL
//#define DEBUG_LISTBOX //#define DEBUG_LISTBOX
@@ -214,7 +216,9 @@ bool MyUnivApp::OnInit()
#ifdef DEBUG_LISTBOX #ifdef DEBUG_LISTBOX
wxLog::AddTraceMask(_T("listbox")); wxLog::AddTraceMask(_T("listbox"));
#endif #endif
#ifdef TEST_TEXT_ONLY
wxLog::AddTraceMask(_T("text")); wxLog::AddTraceMask(_T("text"));
#endif
return TRUE; return TRUE;
} }
@@ -226,7 +230,7 @@ bool MyUnivApp::OnInit()
MyUnivFrame::MyUnivFrame(const wxString& title) MyUnivFrame::MyUnivFrame(const wxString& title)
: wxFrame(NULL, -1, title, : wxFrame(NULL, -1, title,
wxDefaultPosition, wxDefaultPosition,
#if 0 #ifndef TEST_TEXT_ONLY
wxSize(700, 700) wxSize(700, 700)
#else #else
wxSize(240, 150) wxSize(240, 150)
@@ -236,7 +240,7 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
SetBackgroundColour(wxGetApp().GetBgColour()); SetBackgroundColour(wxGetApp().GetBgColour());
new wxStaticText(this, _T("Test static text"), wxPoint(10, 10)); new wxStaticText(this, _T("Test static text"), wxPoint(10, 10));
#if 0 #ifndef TEST_TEXT_ONLY
new wxStaticText(this, new wxStaticText(this,
_T("&Multi line\n(and very very very very long)\nstatic text"), _T("&Multi line\n(and very very very very long)\nstatic text"),
wxPoint(210, 10)); wxPoint(210, 10));
@@ -378,10 +382,10 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
new wxTextCtrl(this, -1, _T("Hello, Universe!"), new wxTextCtrl(this, -1, _T("Hello, Universe!"),
wxPoint(550, 150), wxDefaultSize); wxPoint(550, 150), wxDefaultSize);
#else // 1 #else // TEST_TEXT_ONLY
new wxTextCtrl(this, -1, _T("Hello, Universe!"), new wxTextCtrl(this, -1, _T("Hello, Universe!"),
wxPoint(10, 50), wxSize(200, -1)); wxPoint(10, 40), wxSize(200, -1));
#endif // 0/1 #endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
} }
void MyUnivFrame::OnButton(wxCommandEvent& event) void MyUnivFrame::OnButton(wxCommandEvent& event)
@@ -438,13 +442,15 @@ void MyUnivCanvas::OnPaint(wxPaintEvent& event)
static bool s_oddRepaint = TRUE; static bool s_oddRepaint = TRUE;
s_oddRepaint = !s_oddRepaint; s_oddRepaint = !s_oddRepaint;
#ifdef DEBUG_SCROLL
wxCoord x, y; wxCoord x, y;
GetViewStart(&x, &y); GetViewStart(&x, &y);
#ifdef DEBUG_SCROLL
wxLogDebug("Repainting with %s pen (at %dx%d)", wxLogDebug("Repainting with %s pen (at %dx%d)",
s_oddRepaint ? "red" : "green", s_oddRepaint ? "red" : "green",
x, y); x, y);
#endif // DEBUG_SCROLL #endif // DEBUG_SCROLL
dc.SetPen(s_oddRepaint ? *wxRED_PEN: *wxGREEN_PEN); dc.SetPen(s_oddRepaint ? *wxRED_PEN: *wxGREEN_PEN);
dc.SetTextForeground(s_oddRepaint ? *wxRED : *wxGREEN); dc.SetTextForeground(s_oddRepaint ? *wxRED : *wxGREEN);
@@ -452,7 +458,5 @@ void MyUnivCanvas::OnPaint(wxPaintEvent& event)
dc.DrawText(_T("This is the top of the canvas"), 10, 10); dc.DrawText(_T("This is the top of the canvas"), 10, 10);
dc.DrawLabel(_T("This is the bottom of the canvas"), dc.DrawLabel(_T("This is the bottom of the canvas"),
wxRect(0, 950, 950, 50), wxALIGN_RIGHT | wxBOTTOM); wxRect(0, 950, 950, 50), wxALIGN_RIGHT | wxBOTTOM);
//event.Skip();
} }

View File

@@ -239,7 +239,7 @@ bool wxApp::Initialize()
#endif // __WIN95__ #endif // __WIN95__
#if wxUSE_OLE #if wxUSE_OLE || wxUSE_DRAG_AND_DROP || wxUSE_DATAOBJ
#ifdef __WIN16__ #ifdef __WIN16__
// for OLE, enlarge message queue to be as large as possible // for OLE, enlarge message queue to be as large as possible
@@ -250,6 +250,7 @@ bool wxApp::Initialize()
// we need to initialize OLE library // we need to initialize OLE library
if ( FAILED(::OleInitialize(NULL)) ) if ( FAILED(::OleInitialize(NULL)) )
wxLogError(_("Cannot initialize OLE")); wxLogError(_("Cannot initialize OLE"));
#endif // wxUSE_OLE #endif // wxUSE_OLE
#if wxUSE_CTL3D #if wxUSE_CTL3D
@@ -257,7 +258,7 @@ bool wxApp::Initialize()
wxLogError(wxT("Cannot register CTL3D")); wxLogError(wxT("Cannot register CTL3D"));
Ctl3dAutoSubclass(wxhInstance); Ctl3dAutoSubclass(wxhInstance);
#endif #endif // wxUSE_CTL3D
// VZ: these icons are not in wx.rc anyhow (but should they?)! // VZ: these icons are not in wx.rc anyhow (but should they?)!
#if 0 #if 0

View File

@@ -59,7 +59,7 @@
// wxDataObject is tied to OLE/drag and drop implementation, therefore so are // wxDataObject is tied to OLE/drag and drop implementation, therefore so are
// the functions using wxDataObject in wxClipboard // the functions using wxDataObject in wxClipboard
#define wxUSE_DATAOBJ wxUSE_DRAG_AND_DROP //#define wxUSE_DATAOBJ wxUSE_DRAG_AND_DROP
#if wxUSE_DATAOBJ #if wxUSE_DATAOBJ
#include "wx/dataobj.h" #include "wx/dataobj.h"

View File

@@ -252,39 +252,45 @@ void wxDC::SelectOldObjects(WXHDC dc)
// clipping // clipping
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#define DO_SET_CLIPPING_BOX() \ void wxDC::UpdateClipBox()
{ \ {
RECT rect; \ RECT rect;
\ GetClipBox(GetHdc(), &rect);
GetClipBox(GetHdc(), &rect); \
\ m_clipX1 = (wxCoord) XDEV2LOG(rect.left);
m_clipX1 = (wxCoord) XDEV2LOG(rect.left); \ m_clipY1 = (wxCoord) YDEV2LOG(rect.top);
m_clipY1 = (wxCoord) YDEV2LOG(rect.top); \ m_clipX2 = (wxCoord) XDEV2LOG(rect.right);
m_clipX2 = (wxCoord) XDEV2LOG(rect.right); \ m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom);
m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); \
} }
void wxDC::DoSetClippingRegion(wxCoord cx, wxCoord cy, wxCoord cw, wxCoord ch) void wxDC::DoSetClippingRegion(wxCoord cx, wxCoord cy, wxCoord cw, wxCoord ch)
{ {
m_clipping = TRUE; m_clipping = TRUE;
IntersectClipRect(GetHdc(), XLOG2DEV(cx), YLOG2DEV(cy),
XLOG2DEV(cx + cw), YLOG2DEV(cy + ch)); // NB: IntersectClipRect() accepts clogical coords and, as usual, excludes
DO_SET_CLIPPING_BOX() // the right and bottom edges, so account for it
if ( IntersectClipRect(GetHdc(),
cx, cy, cx + cw + 1, cy + ch + 1) == ERROR )
{
wxLogLastError(wxT("IntersectClipRect"));
}
UpdateClipBox();
} }
void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region) void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region)
{ {
wxCHECK_RET( region.GetHRGN(), wxT("invalid clipping region") ); wxCHECK_RET( GetHrgnOf(region), wxT("invalid clipping region") );
m_clipping = TRUE; m_clipping = TRUE;
#ifdef __WIN16__ #ifdef __WIN16__
SelectClipRgn(GetHdc(), (HRGN) region.GetHRGN()); SelectClipRgn(GetHdc(), GetHrgnOf(region));
#else #else // Win32
ExtSelectClipRgn(GetHdc(), (HRGN) region.GetHRGN(), RGN_AND); ExtSelectClipRgn(GetHdc(), GetHrgnOf(region), RGN_AND);
#endif #endif // Win16/32
DO_SET_CLIPPING_BOX() UpdateClipBox();
} }
void wxDC::DestroyClippingRegion() void wxDC::DestroyClippingRegion()
@@ -298,6 +304,7 @@ void wxDC::DestroyClippingRegion()
SelectClipRgn(GetHdc(), rgn); SelectClipRgn(GetHdc(), rgn);
DeleteObject(rgn); DeleteObject(rgn);
} }
m_clipping = FALSE; m_clipping = FALSE;
} }

View File

@@ -146,12 +146,18 @@ void wxClientDC::InitDC()
SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID)); SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
// clip the DC to avoid overwriting the non client area // in wxUniv build we must manually do some DC adjustments usually
// performed by Windows for us
#ifdef __WXUNIVERSAL__ #ifdef __WXUNIVERSAL__
wxPoint ptOrigin = m_canvas->GetClientAreaOrigin(); wxPoint ptOrigin = m_canvas->GetClientAreaOrigin();
SetDeviceOrigin(ptOrigin.x, ptOrigin.y); if ( ptOrigin.x || ptOrigin.y )
wxSize size = m_canvas->GetClientSize(); {
SetClippingRegion(wxPoint(0, 0), size); // no need to shift DC origin if shift is null
SetDeviceOrigin(ptOrigin.x, ptOrigin.y);
}
// clip the DC to avoid overwriting the non client area
SetClippingRegion(wxPoint(0, 0), m_canvas->GetClientSize());
#endif // __WXUNIVERSAL__ #endif // __WXUNIVERSAL__
} }

View File

@@ -56,7 +56,7 @@ bool IsIidFromList(REFIID riid, const IID *aIids[], size_t nCount)
return FALSE; return FALSE;
} }
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP || wxUSE_DATAOBJ
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Debug support // Debug support

View File

@@ -26,15 +26,13 @@
#include "wx/setup.h" #include "wx/setup.h"
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP || wxUSE_DATAOBJ
// standard headers // standard headers
#include <rpc.h> // UUID related functions #include <rpc.h> // UUID related functions
#include "wx/msw/ole/uuid.h" #include "wx/msw/ole/uuid.h"
// ============================================================================ // ============================================================================
// Implementation // Implementation
// ============================================================================ // ============================================================================

View File

@@ -32,13 +32,13 @@
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/log.h" #include "wx/log.h"
#include "wx/clipbrd.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/validate.h" #include "wx/validate.h"
#include "wx/textctrl.h" #include "wx/textctrl.h"
#endif #endif
#include "wx/clipbrd.h"
#include "wx/caret.h" #include "wx/caret.h"
#include "wx/univ/inphand.h" #include "wx/univ/inphand.h"
@@ -878,6 +878,9 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
void wxTextCtrl::ShowHorzPosition(wxCoord pos) void wxTextCtrl::ShowHorzPosition(wxCoord pos)
{ {
// pos is the logical position to show
// m_ofsHorz is the fisrt logical position shown
if ( pos < m_ofsHorz ) if ( pos < m_ofsHorz )
{ {
// scroll backwards // scroll backwards
@@ -896,7 +899,8 @@ void wxTextCtrl::ShowHorzPosition(wxCoord pos)
width = m_rectText.width; width = m_rectText.width;
} }
if ( pos > width ) // m_ofsHorz + width is the last logical position shown
if ( pos > m_ofsHorz + width)
{ {
// scroll forward // scroll forward
long col; long col;
@@ -1051,37 +1055,18 @@ void wxTextCtrl::DrawTextLine(wxDC& dc, const wxRect& rect,
} }
} }
void wxTextCtrl::DoDraw(wxControlRenderer *renderer) void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
{ {
// hide the caret while we're redrawing the window and show it after we are
// done with it
wxCaretSuspend cs(this);
// prepare the DC
wxDC& dc = renderer->GetDC();
dc.SetFont(GetFont());
dc.SetTextForeground(GetForegroundColour());
// get the intersection of the update region with the text area: note that
// the update region is in window coord and text area is in the client
// ones, so it must be shifted before computing intesection
wxRegion rgnUpdate = GetUpdateRegion();
wxRect rectTextArea = m_rectText;
wxPoint pt = GetClientAreaOrigin();
rectTextArea.x += pt.x;
rectTextArea.y += pt.y;
rgnUpdate.Intersect(rectTextArea);
wxRect rectUpdate = rgnUpdate.GetBox();
// FIXME: why is this needed (at least under MSW)?
rectUpdate.Inflate(2, 1);
// debugging trick to see the update rect visually // debugging trick to see the update rect visually
#if 0 #if 1
static int s_count = 0; if ( 0 )
dc.SetBrush(*(++s_count % 2 ? wxRED_BRUSH : wxGREEN_BRUSH)); {
dc.SetPen(*wxTRANSPARENT_PEN); wxWindowDC dc(this);
dc.DrawRectangle(rectUpdate); static int s_count = 0;
dc.SetBrush(*(++s_count % 2 ? wxRED_BRUSH : wxGREEN_BRUSH));
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(rectUpdate);
}
#endif #endif
// calculate the range of lines to refresh // calculate the range of lines to refresh
@@ -1105,8 +1090,6 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
rectText.y = m_rectText.y + lineStart*rectText.height; rectText.y = m_rectText.y + lineStart*rectText.height;
// do draw the invalidated parts of each line // do draw the invalidated parts of each line
// shouldn't be needed: dc.SetClippingRegion(rectUpdate);
DoPrepareDC(dc); // adjust for scrolling
for ( long line = lineStart; line <= lineEnd; line++ ) for ( long line = lineStart; line <= lineEnd; line++ )
{ {
// calculate the update rect in text positions for this line // calculate the update rect in text positions for this line
@@ -1140,6 +1123,14 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
rectText.x = m_rectText.x + GetTextWidth(textLine.Left(colStart)); rectText.x = m_rectText.x + GetTextWidth(textLine.Left(colStart));
rectText.width = GetTextWidth(text); rectText.width = GetTextWidth(text);
// check that the string that we draw fits entirely into the text area,
// we don't want to draw just a part of characters
while ( rectText.GetRight() > m_ofsHorz + m_rectText.width )
{
rectText.width -= GetTextWidth(text.Last());
text.RemoveLast();
}
// do draw the text // do draw the text
DrawTextLine(dc, rectText, text, selStart, selEnd); DrawTextLine(dc, rectText, text, selStart, selEnd);
wxLogTrace(_T("text"), _T("Line %ld: positions %ld-%ld redrawn."), wxLogTrace(_T("text"), _T("Line %ld: positions %ld-%ld redrawn."),
@@ -1152,6 +1143,47 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
} }
} }
void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
{
// hide the caret while we're redrawing the window and show it after we are
// done with it
wxCaretSuspend cs(this);
// prepare the DC
wxDC& dc = renderer->GetDC();
dc.SetFont(GetFont());
dc.SetTextForeground(GetForegroundColour());
// get the intersection of the update region with the text area: note that
// the update region is in window coord and text area is in the client
// ones, so it must be shifted before computing intesection
wxRegion rgnUpdate = GetUpdateRegion();
wxRect rectTextArea = m_rectText;
wxPoint pt = GetClientAreaOrigin();
rectTextArea.x += pt.x;
rectTextArea.y += pt.y;
rgnUpdate.Intersect(rectTextArea);
#if 0
// even though the drawing is already clipped to the update region, we must
// explicitly clip it to the rect we will use as otherwise parts of letters
// might be drawn outside of it (if even a small part of a charater is
// inside, HitTest() will return its column and DrawText() can't draw only
// the part of the character, of course)
dc.SetClippingRegion(m_rectText);
#endif // 0
// adjust for scrolling
DoPrepareDC(dc);
// and now refresh thei nvalidated parts of the window
wxRegionIterator iter(rgnUpdate);
for ( ; iter.HaveRects(); iter++ )
{
DoDrawTextInRect(dc, iter.GetRect());
}
}
wxCoord wxTextCtrl::GetCaretPosition() const wxCoord wxTextCtrl::GetCaretPosition() const
{ {
wxString textBeforeCaret(GetLineText(m_curLine), (size_t)m_curRow); wxString textBeforeCaret(GetLineText(m_curLine), (size_t)m_curRow);

View File

@@ -41,6 +41,12 @@
#include "wx/univ/colschem.h" #include "wx/univ/colschem.h"
#include "wx/univ/theme.h" #include "wx/univ/theme.h"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
static const int BORDER_THICKNESS = 20;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxWin32Renderer: draw the GUI elements in Win32 style // wxWin32Renderer: draw the GUI elements in Win32 style
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1068,13 +1074,18 @@ void wxWin32Renderer::DrawBorder(wxDC& dc,
int WXUNUSED(flags), int WXUNUSED(flags),
wxRect *rectIn) wxRect *rectIn)
{ {
int i;
wxRect rect = rectTotal; wxRect rect = rectTotal;
switch ( border ) switch ( border )
{ {
case wxBORDER_SUNKEN: case wxBORDER_SUNKEN:
DrawShadedRect(dc, &rect, m_penDarkGrey, m_penHighlight); for ( i = 0; i < BORDER_THICKNESS / 2; i++ )
DrawShadedRect(dc, &rect, m_penBlack, m_penLightGrey); {
DrawShadedRect(dc, &rect, m_penDarkGrey, m_penHighlight);
DrawShadedRect(dc, &rect, m_penBlack, m_penLightGrey);
}
break; break;
case wxBORDER_STATIC: case wxBORDER_STATIC:
@@ -1082,7 +1093,8 @@ void wxWin32Renderer::DrawBorder(wxDC& dc,
break; break;
case wxBORDER_RAISED: case wxBORDER_RAISED:
DrawRaisedBorder(dc, &rect); for ( i = 0; i < BORDER_THICKNESS / 2; i++ )
DrawRaisedBorder(dc, &rect);
break; break;
case wxBORDER_DOUBLE: case wxBORDER_DOUBLE:
@@ -1114,7 +1126,7 @@ wxRect wxWin32Renderer::GetBorderDimensions(wxBorder border) const
{ {
case wxBORDER_RAISED: case wxBORDER_RAISED:
case wxBORDER_SUNKEN: case wxBORDER_SUNKEN:
width = 2; width = BORDER_THICKNESS;
break; break;
case wxBORDER_SIMPLE: case wxBORDER_SIMPLE:

View File

@@ -377,7 +377,8 @@ wxPoint wxWindow::GetClientAreaOrigin() const
void wxWindow::DoGetClientSize(int *width, int *height) const void wxWindow::DoGetClientSize(int *width, int *height) const
{ {
wxWindowNative::DoGetClientSize(width, height); int w, h;
wxWindowNative::DoGetClientSize(&w, &h);
// we assume that the scrollbars are positioned correctly (by a previous // we assume that the scrollbars are positioned correctly (by a previous
// call to PositionScrollbars()) here // call to PositionScrollbars()) here
@@ -386,33 +387,32 @@ void wxWindow::DoGetClientSize(int *width, int *height) const
if ( m_renderer ) if ( m_renderer )
rectBorder = m_renderer->GetBorderDimensions(GetBorder()); rectBorder = m_renderer->GetBorderDimensions(GetBorder());
wxSize size = GetSize();
bool inside = m_renderer->AreScrollbarsInsideBorder(); bool inside = m_renderer->AreScrollbarsInsideBorder();
if ( width ) if ( width )
{ {
// in any case, take account of the scrollbar // in any case, take account of the scrollbar
if ( m_scrollbarVert ) if ( m_scrollbarVert )
*width -= size.x - m_scrollbarVert->GetPosition().x; w -= m_scrollbarVert->GetSize().x;
// if we don't have scrollbar or if it is outside the border (and not // if we don't have scrollbar or if it is outside the border (and not
// blended into it), take account of the right border as well // blended into it), take account of the right border as well
if ( !m_scrollbarVert || !inside ) if ( !m_scrollbarVert || inside )
*width -= rectBorder.width; w -= rectBorder.width;
*width -= rectBorder.x; // and always account for the left border
*width = w - rectBorder.x;
} }
if ( height ) if ( height )
{ {
if ( m_scrollbarHorz ) if ( m_scrollbarHorz )
*height -= size.y - m_scrollbarHorz->GetPosition().y; h -= m_scrollbarHorz->GetSize().y;
if ( !m_scrollbarHorz || !inside ) if ( !m_scrollbarHorz || inside )
*height -= rectBorder.height; h -= rectBorder.height;
*height -= rectBorder.y; *height = h - rectBorder.y;
} }
} }