Account for the margins used by Windows around status bar text.
Because Windows uses margins around the text drawn in the status bar, naively setting a field width to the size of the text didn't work (see previous commit for an example). As this seems a natural enough thing to do, account for this margin inside wxStatusBar itself to avoid the user code the trouble of having to call some special function to do it. Notice that this does mean that fields not containing text may be slightly larger than needed, but we consider that this (rarer) case is less important. Also account correctly for the status bar grip size. And while we still hard code its size, do it in a clearly named function instead of using completely mysterious constants here and there. Closes #10696. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61992 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
bced985eb0
commit
edd608b18a
@ -79,6 +79,28 @@ protected:
|
|||||||
wxVector<wxToolTip*> m_tooltips;
|
wxVector<wxToolTip*> m_tooltips;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct MSWBorders
|
||||||
|
{
|
||||||
|
int horz,
|
||||||
|
vert,
|
||||||
|
between;
|
||||||
|
};
|
||||||
|
|
||||||
|
// retrieve all status bar borders using SB_GETBORDERS
|
||||||
|
MSWBorders MSWGetBorders() const;
|
||||||
|
|
||||||
|
// return the size of the border between the fields
|
||||||
|
int MSWGetBorderWidth() const;
|
||||||
|
|
||||||
|
struct MSWMetrics
|
||||||
|
{
|
||||||
|
int gripWidth,
|
||||||
|
textMargin;
|
||||||
|
};
|
||||||
|
|
||||||
|
// return the various status bar metrics
|
||||||
|
static const MSWMetrics& MSWGetMetrics();
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStatusBar)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStatusBar)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,6 +9,14 @@
|
|||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// for compilers that support precompilation, includes "wx.h".
|
// for compilers that support precompilation, includes "wx.h".
|
||||||
#include "wx/wxprec.h"
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
@ -38,8 +46,17 @@
|
|||||||
#include "wx/msw/uxtheme.h"
|
#include "wx/msw/uxtheme.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
// no idea for a default width, just choose something
|
// no idea for a default width, just choose something
|
||||||
#define DEFAULT_FIELD_WIDTH 25
|
static const int DEFAULT_FIELD_WIDTH = 25;
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// macros
|
// macros
|
||||||
@ -212,30 +229,35 @@ void wxStatusBar::MSWUpdateFieldsWidths()
|
|||||||
if ( m_panes.IsEmpty() )
|
if ( m_panes.IsEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int aBorders[3];
|
const int count = m_panes.GetCount();
|
||||||
SendMessage(GetHwnd(), SB_GETBORDERS, 0, (LPARAM)aBorders);
|
|
||||||
|
|
||||||
int extraWidth = aBorders[2]; // space between fields
|
const int extraWidth = MSWGetBorderWidth() + MSWGetMetrics().textMargin;
|
||||||
|
|
||||||
|
// compute the effectively available amount of space:
|
||||||
|
int widthAvailable = GetClientSize().x; // start with the entire width
|
||||||
|
widthAvailable -= extraWidth*(count - 1); // extra space between fields
|
||||||
|
widthAvailable -= MSWGetMetrics().textMargin; // and for the last field
|
||||||
|
|
||||||
|
if ( HasFlag(wxSTB_SIZEGRIP) )
|
||||||
|
widthAvailable -= MSWGetMetrics().gripWidth;
|
||||||
|
|
||||||
// distribute the available space (client width) among the various fields:
|
// distribute the available space (client width) among the various fields:
|
||||||
|
|
||||||
wxArrayInt widthsAbs =
|
wxArrayInt widthsAbs = CalculateAbsWidths(widthAvailable);
|
||||||
CalculateAbsWidths(GetClientSize().x - extraWidth*(m_panes.GetCount() - 1));
|
|
||||||
|
|
||||||
|
|
||||||
// update the field widths in the native control:
|
// update the field widths in the native control:
|
||||||
|
|
||||||
int *pWidths = new int[m_panes.GetCount()];
|
int *pWidths = new int[count];
|
||||||
|
|
||||||
int nCurPos = 0;
|
int nCurPos = 0;
|
||||||
for ( size_t i = 0; i < m_panes.GetCount(); i++ )
|
for ( int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
nCurPos += widthsAbs[i] + extraWidth;
|
nCurPos += widthsAbs[i] + extraWidth;
|
||||||
pWidths[i] = nCurPos;
|
pWidths[i] = nCurPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !StatusBar_SetParts(GetHwnd(), m_panes.GetCount(), pWidths) )
|
if ( !StatusBar_SetParts(GetHwnd(), count, pWidths) )
|
||||||
{
|
{
|
||||||
wxLogLastError("StatusBar_SetParts");
|
wxLogLastError("StatusBar_SetParts");
|
||||||
}
|
}
|
||||||
@ -271,13 +293,8 @@ void wxStatusBar::DoUpdateStatusText(int nField)
|
|||||||
wxRect rc;
|
wxRect rc;
|
||||||
GetFieldRect(nField, rc);
|
GetFieldRect(nField, rc);
|
||||||
|
|
||||||
int margin;
|
const int maxWidth = rc.GetWidth() - MSWGetMetrics().textMargin;
|
||||||
if (nField == GetFieldsCount()-1)
|
|
||||||
margin = -6; // windows reports a smaller rect for the last field; enlarge it
|
|
||||||
else
|
|
||||||
margin = 4;
|
|
||||||
|
|
||||||
int maxWidth = rc.GetWidth() - margin; // leave a small margin
|
|
||||||
wxString text = GetStatusText(nField);
|
wxString text = GetStatusText(nField);
|
||||||
|
|
||||||
// do we need to ellipsize this string?
|
// do we need to ellipsize this string?
|
||||||
@ -345,20 +362,59 @@ void wxStatusBar::DoUpdateStatusText(int nField)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxStatusBar::GetBorderX() const
|
wxStatusBar::MSWBorders wxStatusBar::MSWGetBorders() const
|
||||||
{
|
{
|
||||||
int aBorders[3];
|
int aBorders[3];
|
||||||
SendMessage(GetHwnd(), SB_GETBORDERS, 0, (LPARAM)aBorders);
|
SendMessage(GetHwnd(), SB_GETBORDERS, 0, (LPARAM)aBorders);
|
||||||
|
|
||||||
return aBorders[0];
|
MSWBorders borders;
|
||||||
|
borders.horz = aBorders[0];
|
||||||
|
borders.vert = aBorders[1];
|
||||||
|
borders.between = aBorders[2];
|
||||||
|
return borders;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxStatusBar::GetBorderX() const
|
||||||
|
{
|
||||||
|
return MSWGetBorders().horz;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxStatusBar::GetBorderY() const
|
int wxStatusBar::GetBorderY() const
|
||||||
{
|
{
|
||||||
int aBorders[3];
|
return MSWGetBorders().vert;
|
||||||
SendMessage(GetHwnd(), SB_GETBORDERS, 0, (LPARAM)aBorders);
|
}
|
||||||
|
|
||||||
return aBorders[1];
|
int wxStatusBar::MSWGetBorderWidth() const
|
||||||
|
{
|
||||||
|
return MSWGetBorders().between;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const wxStatusBar::MSWMetrics& wxStatusBar::MSWGetMetrics()
|
||||||
|
{
|
||||||
|
static MSWMetrics s_metrics = { 0 };
|
||||||
|
if ( !s_metrics.textMargin )
|
||||||
|
{
|
||||||
|
// Grip size should be self explanatory (the only problem with it is
|
||||||
|
// that it's hard coded as we don't know how to find its size using
|
||||||
|
// API) but the margin might merit an explanation: Windows offsets the
|
||||||
|
// text drawn in status bar panes so we need to take this extra margin
|
||||||
|
// into account to make sure the text drawn by user fits inside the
|
||||||
|
// pane. Notice that it's not the value returned by SB_GETBORDERS
|
||||||
|
// which, at least on this Windows 2003 system, returns {0, 2, 2}
|
||||||
|
if ( wxUxThemeEngine::GetIfActive() )
|
||||||
|
{
|
||||||
|
s_metrics.gripWidth = 20;
|
||||||
|
s_metrics.textMargin = 8;
|
||||||
|
}
|
||||||
|
else // classic/unthemed look
|
||||||
|
{
|
||||||
|
s_metrics.gripWidth = 18;
|
||||||
|
s_metrics.textMargin = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxStatusBar::SetMinHeight(int height)
|
void wxStatusBar::SetMinHeight(int height)
|
||||||
@ -399,13 +455,20 @@ bool wxStatusBar::GetFieldRect(int i, wxRect& rect) const
|
|||||||
|
|
||||||
wxCopyRECTToRect(r, rect);
|
wxCopyRECTToRect(r, rect);
|
||||||
|
|
||||||
|
// Windows seems to under-report the size of the last field rectangle,
|
||||||
|
// presumably in order to prevent the buggy applications from overflowing
|
||||||
|
// onto the size grip but we want to return the real size to wx users
|
||||||
|
if ( HasFlag(wxSTB_SIZEGRIP) && i == (int)m_panes.GetCount() - 1 )
|
||||||
|
{
|
||||||
|
rect.width += MSWGetMetrics().gripWidth - MSWGetBorderWidth();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize wxStatusBar::DoGetBestSize() const
|
wxSize wxStatusBar::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
int borders[3];
|
const MSWBorders borders = MSWGetBorders();
|
||||||
SendMessage(GetHwnd(), SB_GETBORDERS, 0, (LPARAM)borders);
|
|
||||||
|
|
||||||
// calculate width
|
// calculate width
|
||||||
int width = 0;
|
int width = 0;
|
||||||
@ -425,7 +488,7 @@ wxSize wxStatusBar::DoGetBestSize() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add the space between fields
|
// add the space between fields
|
||||||
width += borders[2];
|
width += borders.between;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !width )
|
if ( !width )
|
||||||
@ -438,7 +501,7 @@ wxSize wxStatusBar::DoGetBestSize() const
|
|||||||
int height;
|
int height;
|
||||||
wxGetCharSize(GetHWND(), NULL, &height, GetFont());
|
wxGetCharSize(GetHWND(), NULL, &height, GetFont());
|
||||||
height = EDIT_HEIGHT_FROM_CHAR_HEIGHT(height);
|
height = EDIT_HEIGHT_FROM_CHAR_HEIGHT(height);
|
||||||
height += borders[1];
|
height += borders.vert;
|
||||||
|
|
||||||
wxSize best(width, height);
|
wxSize best(width, height);
|
||||||
CacheBestSize(best);
|
CacheBestSize(best);
|
||||||
|
Loading…
Reference in New Issue
Block a user