save the current status text for each pane inside wxStatusBarPane: native controls now store the (eventually) ellipsized version of the string; remove code for managing the status strings currently inside the [native|generic] control; add ellipsization support under wxMSW; now that all SetFieldsCount() implementation rrely on wxStatusBarBase::SetFieldsCount document how it behaves when adding new panes.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58786 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-02-09 00:33:19 +00:00
parent 4879f2120c
commit 0cd159592e
11 changed files with 117 additions and 90 deletions

View File

@@ -50,7 +50,6 @@ public:
// Set status line text
virtual void SetStatusText(const wxString& text, int number = 0);
virtual wxString GetStatusText(int number = 0) const;
// Set status line widths
virtual void SetStatusWidths(int n, const int widths_field[]);
@@ -97,9 +96,6 @@ protected:
// common part of all ctors
void Init();
// the array of the currently displayed strings
wxArrayString m_statusStrings;
// the last known height of the client rect
int m_lastClientHeight;

View File

@@ -14,6 +14,8 @@
#if wxUSE_NATIVE_STATUSBAR
class WXDLLIMPEXP_CORE wxClientDC;
class WXDLLIMPEXP_CORE wxStatusBar : public wxStatusBarBase
{
public:
@@ -39,7 +41,6 @@ public:
// each field of status line has it's own text
virtual void SetStatusText(const wxString& text, int number = 0);
virtual wxString GetStatusText(int number = 0) const;
// set status line fields' widths
virtual void SetStatusWidths(int n, const int widths_field[]);
@@ -57,17 +58,23 @@ public:
virtual int GetBorderX() const;
virtual int GetBorderY() const;
virtual bool SetFont(const wxFont& font);
virtual WXLRESULT MSWWindowProc(WXUINT nMsg,
WXWPARAM wParam,
WXLPARAM lParam);
protected:
void CopyFieldsWidth(const int widths[]);
void SetFieldsWidth();
void UpdateFieldText(int nField);
// override some base class virtuals
virtual wxSize DoGetBestSize() const;
virtual void DoMoveWindow(int x, int y, int width, int height);
// used by UpdateFieldText
wxClientDC *m_pDC;
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStatusBar)
};

View File

@@ -28,8 +28,9 @@ class WXDLLIMPEXP_CORE wxStatusBarMac : public wxStatusBarGeneric
long style = wxST_SIZEGRIP,
const wxString& name = wxStatusBarNameStr);
virtual void DrawFieldText(wxDC& dc, int i);
virtual void DrawField(wxDC& dc, int i);
virtual void DrawFieldText(wxDC& dc, const wxRect& rc, int i, int textHeight);
virtual void DrawField(wxDC& dc, int i, int textHeight);
virtual void SetStatusText(const wxString& text, int number = 0);
// Implementation

View File

@@ -39,14 +39,16 @@ class wxStatusBarPane
{
public:
wxStatusBarPane(int style = wxSB_NORMAL, size_t width = 0)
: nStyle(style), nWidth(width) {}
: nStyle(style), nWidth(width) { arrStack.Add(wxEmptyString); }
int nStyle;
int nWidth; // the width maybe negative, indicating a variable-width field
// this is the array of the stacked strings of this pane; note that this
// stack does not include the string currently displayed in this pane
// as it's stored in the native status bar control
// stack does include also the string currently displayed in this pane
// as the version stored in the native status bar control is possibly
// ellipsized; note that arrStack.Last() is the top of the stack
// (i.e. the string shown in the status bar)
wxArrayString arrStack;
};
@@ -74,8 +76,10 @@ public:
// field text
// ----------
virtual void SetStatusText(const wxString& text, int number = 0) = 0;
virtual wxString GetStatusText(int number = 0) const = 0;
virtual void SetStatusText(const wxString& text, int number = 0)
{ m_panes[number].arrStack.Last() = text; }
virtual wxString GetStatusText(int number = 0) const
{ return m_panes[number].arrStack.Last(); }
void PushStatusText(const wxString& text, int number = 0);
void PopStatusText(int number = 0);

View File

@@ -46,7 +46,6 @@ public:
// get/set the text of the given field
virtual void SetStatusText(const wxString& text, int number = 0);
virtual wxString GetStatusText(int number = 0) const;
// Get the position and size of the field's internal bounding rectangle
virtual bool GetFieldRect(int i, wxRect& rect) const;
@@ -96,7 +95,7 @@ protected:
private:
// the current status fields strings
wxArrayString m_statusText;
//wxArrayString m_statusText;
// the absolute status fields widths
wxArrayInt m_widthsAbs;

View File

@@ -121,7 +121,8 @@ public:
Sets the number of fields, and optionally the field widths.
@param number
The number of fields.
The number of fields. If this is greater than the previous number,
then new fields with empty strings will be added to the status bar.
@param widths
An array of n integers interpreted in the same way as
in SetStatusWidths().

View File

@@ -194,12 +194,15 @@ void wxStatusBarBase::PushStatusText(const wxString& text, int number)
// save current status text in the stack
m_panes[number].arrStack.push_back(GetStatusText(number));
// update current status text
SetStatusText(text, number);
// update current status text (eventually also in the native control)
}
void wxStatusBarBase::PopStatusText(int number)
{
wxASSERT_MSG(m_panes[number].arrStack.GetCount() == 1,
"can't pop any further string");
wxString text = m_panes[number].arrStack.back();
m_panes[number].arrStack.pop_back(); // also remove it from the stack

View File

@@ -119,21 +119,9 @@ void wxStatusBarGeneric::SetFieldsCount(int number, const int *widths)
{
wxASSERT_MSG( number >= 0, _T("negative number of fields in wxStatusBar?") );
// enlarge the m_statusStrings array if needed:
for (size_t i = m_panes.GetCount(); i < (size_t)number; ++i)
m_statusStrings.Add( wxEmptyString );
// shrink the m_statusStrings array if needed:
for (int j = (int)m_panes.GetCount() - 1; j >= number; --j)
m_statusStrings.RemoveAt(j);
// forget the old cached pixel widths
m_widthsAbs.Empty();
// this will result in a call to SetStatusWidths() and thus an update to our
// m_widthsAbs cache
wxStatusBarBase::SetFieldsCount(number, widths);
wxASSERT_MSG( m_panes.GetCount() == m_statusStrings.GetCount(),
_T("This really should never happen, can we do away with m_panes.GetCount() here?") );
}
void wxStatusBarGeneric::SetStatusText(const wxString& text, int number)
@@ -141,10 +129,10 @@ void wxStatusBarGeneric::SetStatusText(const wxString& text, int number)
wxCHECK_RET( (number >= 0) && ((size_t)number < m_panes.GetCount()),
_T("invalid status bar field index") );
wxString oldText = m_statusStrings[number];
wxString oldText = GetStatusText(number);
if (oldText != text)
{
m_statusStrings[number] = text;
wxStatusBarBase::SetStatusText(text, number);
wxRect rect;
GetFieldRect(number, rect);
@@ -158,23 +146,17 @@ void wxStatusBarGeneric::SetStatusText(const wxString& text, int number)
}
}
wxString wxStatusBarGeneric::GetStatusText(int n) const
{
wxCHECK_MSG( (n >= 0) && ((size_t)n < m_panes.GetCount()), wxEmptyString,
_T("invalid status bar field index") );
return m_statusStrings[n];
}
void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[])
{
// only set status widths when n == number of statuswindows
wxCHECK_RET( (size_t)n == m_panes.GetCount(), _T("status bar field count mismatch") );
// forget the old cached pixel widths
m_widthsAbs.Empty();
wxStatusBarBase::SetStatusWidths(n, widths_field);
// update cache
int width;
GetClientSize(&width, &m_lastClientHeight);
m_widthsAbs = CalculateAbsWidths(width);
}
bool wxStatusBarGeneric::ShowsSizeGrip() const

View File

@@ -36,6 +36,9 @@
#include "wx/msw/uxtheme.h"
#endif
// no idea for a default width, just choose something
#define DEFAULT_FIELD_WIDTH 25
// ----------------------------------------------------------------------------
// macros
// ----------------------------------------------------------------------------
@@ -59,6 +62,7 @@ wxStatusBar::wxStatusBar()
SetParent(NULL);
m_hWnd = 0;
m_windowId = 0;
m_pDC = NULL;
}
bool wxStatusBar::Create(wxWindow *parent,
@@ -131,6 +135,9 @@ bool wxStatusBar::Create(wxWindow *parent,
// work correctly, we need to wait until we return to the main loop
PostSizeEventToParent();
// cache the DC instance used by UpdateFieldText
m_pDC = new wxClientDC(this);
return true;
}
@@ -142,6 +149,15 @@ wxStatusBar::~wxStatusBar()
PostSizeEventToParent();
}
bool wxStatusBar::SetFont(const wxFont& font)
{
if (!wxWindow::SetFont(font))
return false;
m_pDC->SetFont(font);
return true;
}
void wxStatusBar::SetFieldsCount(int nFields, const int *widths)
{
// this is a Windows limitation
@@ -198,6 +214,16 @@ void wxStatusBar::SetStatusText(const wxString& strText, int nField)
return;
}
wxStatusBarBase::SetStatusText(strText, nField);
UpdateFieldText(nField);
}
void wxStatusBar::UpdateFieldText(int nField)
{
if (!m_pDC)
return;
// Get field style, if any
int style;
switch(m_panes[nField].nStyle)
@@ -215,29 +241,30 @@ void wxStatusBar::SetStatusText(const wxString& strText, int nField)
break;
}
wxRect rc;
GetFieldRect(nField, rc);
int margin;
if (nField == GetFieldsCount()-1)
margin = -6; // windows reports a smaller rect for the last field; enlarge it
else
margin = 4;
// do we need to ellipsize this string?
wxString ellipsizedStr =
wxControl::Ellipsize(GetStatusText(nField), *m_pDC,
GetLayoutDirection() == wxLayout_RightToLeft ? wxELLIPSIZE_START : wxELLIPSIZE_END,
rc.GetWidth() - margin, // leave a small margin
wxELLIPSIZE_EXPAND_TAB);
// Pass both field number and style. MSDN library doesn't mention
// that nField and style have to be 'ORed'
if ( !StatusBar_SetText(GetHwnd(), nField | style, strText.wx_str()) )
if ( !StatusBar_SetText(GetHwnd(), nField | style, ellipsizedStr.wx_str()) )
{
wxLogLastError(wxT("StatusBar_SetText"));
}
}
wxString wxStatusBar::GetStatusText(int nField) const
{
wxCHECK_MSG( (nField >= 0) && ((size_t)nField < m_panes.GetCount()), wxEmptyString,
_T("invalid statusbar field index") );
wxString str;
int len = StatusBar_GetTextLen(GetHwnd(), nField);
if ( len > 0 )
{
StatusBar_GetText(GetHwnd(), nField, wxStringBuffer(str, len));
}
return str;
}
int wxStatusBar::GetBorderX() const
{
int aBorders[3];
@@ -295,9 +322,6 @@ bool wxStatusBar::GetFieldRect(int i, wxRect& rect) const
return true;
}
// no idea for a default width, just choose something
#define DEFAULT_FIELD_WIDTH 25
wxSize wxStatusBar::DoGetBestSize() const
{
int borders[3];
@@ -330,7 +354,6 @@ wxSize wxStatusBar::DoGetBestSize() const
width = 2*DEFAULT_FIELD_WIDTH;
}
// calculate height
int height;
wxGetCharSize(GetHWND(), NULL, &height, GetFont());
@@ -454,6 +477,14 @@ wxStatusBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
}
#endif
if ( nMsg == WM_SIZE )
{
for (int i=0; i<GetFieldsCount(); i++)
UpdateFieldText(i);
// re-set the field text, in case we need to ellipsize
// (or de-ellipsize) some parts of it
}
return wxStatusBarBase::MSWWindowProc(nMsg, wParam, lParam);
}

View File

@@ -23,6 +23,9 @@
#include "wx/osx/private.h"
// Margin between the field text and the field rect
#define wxFIELD_TEXT_MARGIN 2
BEGIN_EVENT_TABLE(wxStatusBarMac, wxStatusBarGeneric)
EVT_PAINT(wxStatusBarMac::OnPaint)
@@ -67,55 +70,60 @@ bool wxStatusBarMac::Create(wxWindow *parent, wxWindowID id,
return true;
}
void wxStatusBarMac::DrawFieldText(wxDC& dc, int i)
void wxStatusBarMac::DrawFieldText(wxDC& dc, const wxRect& rect, int i, int textHeight)
{
int w, h;
GetSize( &w , &h );
wxRect rect;
GetFieldRect( i, rect );
if ( !MacIsReallyHilited() )
dc.SetTextForeground( wxColour( 0x80, 0x80, 0x80 ) );
wxString text(GetStatusText( i ));
wxCoord x, y;
dc.GetTextExtent(text, &x, &y);
/*wxCoord x, y;
dc.GetTextExtent(text, &x, &y); -- seems unused (FM)*/
int leftMargin = 2;
int xpos = rect.x + leftMargin + 1;
int xpos = rect.x + wxFIELD_TEXT_MARGIN + 1;
int ypos = 1;
if ( MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL )
ypos++;
dc.SetClippingRegion(rect.x, 0, rect.width, h);
dc.DrawText(text, xpos, ypos);
dc.DestroyClippingRegion();
}
void wxStatusBarMac::DrawField(wxDC& dc, int i)
void wxStatusBarMac::DrawField(wxDC& dc, int i, int textHeight)
{
DrawFieldText(dc, i);
wxRect rect;
GetFieldRect(i, rect);
DrawFieldText(dc, rect, i, textHeight);
}
void wxStatusBarMac::SetStatusText(const wxString& text, int number)
{
// NOTE: seems this function is identic to wxStatusBarGeneric::SetStatusText;
// probably can be removed without problems (FM)
wxCHECK_RET( (number >= 0) && ((size_t)number < m_panes.GetCount()),
wxT("invalid status bar field index") );
if ( m_statusStrings[number] == text )
return ;
if ( GetStatusText(number) == text )
return;
wxStatusBarGeneric::SetStatusText(text, number);
m_statusStrings[number] = text;
wxRect rect;
GetFieldRect(number, rect);
int w, h;
GetSize( &w, &h );
rect.y = 0;
rect.height = h ;
Refresh( true, &rect );
Update();
}
@@ -162,12 +170,15 @@ void wxStatusBarMac::OnPaint(wxPaintEvent& WXUNUSED(event))
dc.DrawLine(0, 0, w, 0);
}
if ( GetFont().Ok() )
if ( GetFont().IsOk() )
dc.SetFont(GetFont());
dc.SetBackgroundMode(wxTRANSPARENT);
// compute char height only once for all panes:
int textHeight = dc.GetCharHeight();
for ( size_t i = 0; i < m_panes.GetCount(); i ++ )
DrawField(dc, i);
DrawField(dc, i, textHeight);
}
void wxStatusBarMac::MacHiliteChanged()

View File

@@ -134,7 +134,7 @@ void wxStatusBarUniv::DoDraw(wxControlRenderer *renderer)
flags |= wxCONTROL_SIZEGRIP;
}
m_renderer->DrawStatusField(dc, rect, m_statusText[n], flags, m_panes[n].nStyle);
m_renderer->DrawStatusField(dc, rect, GetStatusText(n), flags, m_panes[n].nStyle);
}
rect.x += rect.width + borderBetweenFields;
@@ -159,24 +159,17 @@ void wxStatusBarUniv::SetStatusText(const wxString& text, int number)
wxCHECK_RET( number >= 0 && (size_t)number < m_panes.GetCount(),
_T("invalid status bar field index in SetStatusText()") );
if ( text == m_statusText[number] )
if ( text == GetStatusText(number) )
{
// nothing changed
return;
}
m_statusText[number] = text;
wxStatusBarBase::SetStatusText(text, number);
RefreshField(number);
}
wxString wxStatusBarUniv::GetStatusText(int number) const
{
wxCHECK_MSG( number >= 0 && (size_t)number < m_panes.GetCount(), wxEmptyString,
_T("invalid status bar field index") );
return m_statusText[number];
}
// ----------------------------------------------------------------------------
// fields count/widths
@@ -184,7 +177,6 @@ wxString wxStatusBarUniv::GetStatusText(int number) const
void wxStatusBarUniv::SetFieldsCount(int number, const int *widths)
{
m_statusText.SetCount(number);
wxStatusBarBase::SetFieldsCount(number, widths);
m_widthsAbs.Empty();