move Ellipsize() to wxControl so it can be easily used by other controls
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57625 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -269,175 +269,6 @@ wxString wxStaticTextBase::EscapeMarkup(const wxString& text)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define wxELLIPSE_REPLACEMENT wxT("...")
|
||||
|
||||
/* static */
|
||||
wxString wxStaticTextBase::Ellipsize(const wxString& label, const wxDC& dc,
|
||||
wxEllipsizeMode mode, int maxFinalWidth)
|
||||
{
|
||||
wxArrayInt charOffsets;
|
||||
wxString ret;
|
||||
|
||||
// these cannot be cached as they can change because of e.g. a font change
|
||||
int replacementWidth = dc.GetTextExtent(wxELLIPSE_REPLACEMENT).GetWidth();
|
||||
int marginWidth = dc.GetCharWidth()*2;
|
||||
|
||||
// NB: we must handle correctly labels with newlines:
|
||||
wxString curLine;
|
||||
wxSize reqsize;
|
||||
size_t len;
|
||||
for ( wxString::const_iterator pc = label.begin(); ; ++pc )
|
||||
{
|
||||
if ( pc == label.end() || *pc == _T('\n') )
|
||||
{
|
||||
len = curLine.length();
|
||||
if (len > 0 &&
|
||||
dc.GetPartialTextExtents(curLine, charOffsets))
|
||||
{
|
||||
wxASSERT(charOffsets.GetCount() == len);
|
||||
|
||||
size_t totalWidth = charOffsets.Last();
|
||||
if ( totalWidth > (size_t)maxFinalWidth )
|
||||
{
|
||||
// we need to ellipsize this row
|
||||
int excessPixels = totalWidth - maxFinalWidth +
|
||||
replacementWidth +
|
||||
marginWidth; // security margin (NEEDED!)
|
||||
|
||||
// remove characters in excess
|
||||
size_t initialChar, // index of first char to erase
|
||||
nChars; // how many chars do we need to erase?
|
||||
if (mode == wxST_ELLIPSIZE_START)
|
||||
{
|
||||
initialChar = 0;
|
||||
for (nChars=0;
|
||||
nChars < len && charOffsets[nChars] < excessPixels;
|
||||
nChars++)
|
||||
;
|
||||
}
|
||||
else if (mode == wxST_ELLIPSIZE_MIDDLE)
|
||||
{
|
||||
// the start & end of the removed span of chars
|
||||
initialChar = len/2;
|
||||
size_t endChar = len/2;
|
||||
|
||||
int removed = 0;
|
||||
for ( ; removed < excessPixels; )
|
||||
{
|
||||
if (initialChar > 0)
|
||||
{
|
||||
// width of the initialChar-th character
|
||||
int width = charOffsets[initialChar] -
|
||||
charOffsets[initialChar-1];
|
||||
|
||||
// remove the initialChar-th character
|
||||
removed += width;
|
||||
initialChar--;
|
||||
}
|
||||
|
||||
if (endChar < len - 1 &&
|
||||
removed < excessPixels)
|
||||
{
|
||||
// width of the (endChar+1)-th character
|
||||
int width = charOffsets[endChar+1] -
|
||||
charOffsets[endChar];
|
||||
|
||||
// remove the endChar-th character
|
||||
removed += width;
|
||||
endChar++;
|
||||
}
|
||||
|
||||
if (initialChar == 0 && endChar == len-1)
|
||||
{
|
||||
nChars = len+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
initialChar++;
|
||||
nChars = endChar - initialChar + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxASSERT(mode == wxST_ELLIPSIZE_END);
|
||||
wxASSERT(len > 0);
|
||||
|
||||
int maxWidth = totalWidth - excessPixels;
|
||||
for (initialChar=0;
|
||||
initialChar < len &&
|
||||
charOffsets[initialChar] < maxWidth;
|
||||
initialChar++)
|
||||
;
|
||||
|
||||
if (initialChar == 0)
|
||||
{
|
||||
nChars = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
initialChar--; // go back one character
|
||||
nChars = len - initialChar;
|
||||
}
|
||||
}
|
||||
|
||||
if (nChars > len)
|
||||
{
|
||||
// need to remove the entire row!
|
||||
curLine.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// erase nChars characters after initialChar (included):
|
||||
curLine.erase(initialChar, nChars+1);
|
||||
|
||||
// if there is space for the replacement dots, add them
|
||||
if (maxFinalWidth > replacementWidth)
|
||||
curLine.insert(initialChar, wxELLIPSE_REPLACEMENT);
|
||||
}
|
||||
|
||||
// if everything was ok, we should have shortened this line
|
||||
// enough to make it fit in sz.maxFinalWidth:
|
||||
wxASSERT(dc.GetTextExtent(curLine).GetWidth() < maxFinalWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// add this (ellipsized) row to the rest of the label
|
||||
ret << curLine;
|
||||
if ( pc == label.end() )
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret << *pc;
|
||||
curLine.clear();
|
||||
}
|
||||
}
|
||||
// we need to remove mnemonics from the label for correct calculations
|
||||
else if ( *pc == _T('&') )
|
||||
{
|
||||
// pc+1 is safe: at worst we'll be at end()
|
||||
wxString::const_iterator next = pc + 1;
|
||||
if ( next != label.end() && *next == _T('&') )
|
||||
curLine += _T('&'); // && becomes &
|
||||
//else: remove this ampersand
|
||||
}
|
||||
// we need also to expand tabs to properly calc their size
|
||||
else if ( *pc == _T('\t') )
|
||||
{
|
||||
// Windows natively expands the TABs to 6 spaces. Do the same:
|
||||
curLine += wxT(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
curLine += *pc;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support
|
||||
@@ -493,11 +324,11 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
||||
dc.SetFont(GetFont());
|
||||
|
||||
wxEllipsizeMode mode;
|
||||
if (HasFlag(wxST_ELLIPSIZE_START)) mode = wxST_ELLIPSIZE_START;
|
||||
else if (HasFlag(wxST_ELLIPSIZE_MIDDLE)) mode = wxST_ELLIPSIZE_MIDDLE;
|
||||
else if (HasFlag(wxST_ELLIPSIZE_END)) mode = wxST_ELLIPSIZE_END;
|
||||
if (HasFlag(wxST_ELLIPSIZE_START)) mode = wxELLIPSIZE_START;
|
||||
else if (HasFlag(wxST_ELLIPSIZE_MIDDLE)) mode = wxELLIPSIZE_MIDDLE;
|
||||
else if (HasFlag(wxST_ELLIPSIZE_END)) mode = wxELLIPSIZE_END;
|
||||
|
||||
return Ellipsize(label, dc, mode, sz.GetWidth());
|
||||
return wxControl::Ellipsize(label, dc, mode, sz.GetWidth());
|
||||
}
|
||||
|
||||
#endif // wxUSE_STATTEXT
|
||||
|
Reference in New Issue
Block a user