refactor wxStaticText::Ellipsize so it's a static public utility function; document it and a couple of other useful functions
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57622 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -24,10 +24,14 @@
|
|||||||
#define wxST_NO_AUTORESIZE 0x0001
|
#define wxST_NO_AUTORESIZE 0x0001
|
||||||
#define wxST_MARKUP 0x0002
|
#define wxST_MARKUP 0x0002
|
||||||
|
|
||||||
#define wxST_ELLIPSIZE_START 0x0004
|
// NOTE: the members of this enum are used both as window styles for wxStaticText
|
||||||
#define wxST_ELLIPSIZE_MIDDLE 0x0008
|
// and both as enumeration values for wxStaticText::Ellipsize static function
|
||||||
#define wxST_ELLIPSIZE_END 0x0010
|
enum wxEllipsizeMode
|
||||||
|
{
|
||||||
|
wxST_ELLIPSIZE_START = 0x0004,
|
||||||
|
wxST_ELLIPSIZE_MIDDLE = 0x0008,
|
||||||
|
wxST_ELLIPSIZE_END = 0x0010
|
||||||
|
};
|
||||||
|
|
||||||
extern WXDLLIMPEXP_DATA_CORE(const char) wxStaticTextNameStr[];
|
extern WXDLLIMPEXP_DATA_CORE(const char) wxStaticTextNameStr[];
|
||||||
|
|
||||||
@@ -65,10 +69,13 @@ public:
|
|||||||
// and then returns the cleaned string
|
// and then returns the cleaned string
|
||||||
static wxString RemoveMarkup(const wxString& str);
|
static wxString RemoveMarkup(const wxString& str);
|
||||||
|
|
||||||
// escapes the alls special symbols (<>"'&) present inside the given string
|
// escapes all special symbols (<>"'&) present in the given string
|
||||||
// using the corresponding entities (< > " ' &)
|
// using the corresponding entities (< > " ' &)
|
||||||
static wxString EscapeMarkup(const wxString& str);
|
static wxString EscapeMarkup(const wxString& str);
|
||||||
|
|
||||||
|
// replaces parts of the string with ellipsis if needed
|
||||||
|
static wxString Ellipsize(const wxString& label, const wxDC& dc,
|
||||||
|
wxEllipsizeMode mode, int maxWidth);
|
||||||
|
|
||||||
protected: // functions required for wxST_ELLIPSIZE_* support
|
protected: // functions required for wxST_ELLIPSIZE_* support
|
||||||
|
|
||||||
|
@@ -43,18 +43,23 @@ public:
|
|||||||
wxString GetLabelText() const;
|
wxString GetLabelText() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the given @a label string without mnemonics.
|
Returns the given @a label string without mnemonics ("&" characters).
|
||||||
*/
|
*/
|
||||||
static wxString GetLabelText(const wxString& label);
|
static wxString GetLabelText(const wxString& label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Removes the mnemonics ("&" characters) from the given string.
|
||||||
|
*/
|
||||||
|
static wxString RemoveMnemonics(const wxString& str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the item's text.
|
Sets the item's text.
|
||||||
|
|
||||||
Any "&" characters in the @a label are special and indicate that the
|
Any "&" characters in the @a label are special and indicate that the
|
||||||
following character is a mnemonic for this control and can be used to
|
following character is a @e mnemonic for this control and can be used to
|
||||||
activate it from the keyboard (typically by using @e Alt key in
|
activate it from the keyboard (typically by using @e Alt key in
|
||||||
combination with it). To insert a literal ampersand character, you need
|
combination with it).
|
||||||
to double it, i.e. use "&&".
|
To insert a literal ampersand character, you need to double it, i.e. use "&&".
|
||||||
*/
|
*/
|
||||||
void SetLabel(const wxString& label);
|
void SetLabel(const wxString& label);
|
||||||
};
|
};
|
||||||
|
@@ -6,10 +6,27 @@
|
|||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
The different ellipsization modes supported by wxStaticText and by
|
||||||
|
wxStaticText::Ellipsize function.
|
||||||
|
|
||||||
|
@note
|
||||||
|
The members of this enum are used both as window styles for wxStaticText
|
||||||
|
and both as enumeration values for wxStaticText::Ellipsize static function.
|
||||||
|
*/
|
||||||
|
enum wxEllipsizeMode
|
||||||
|
{
|
||||||
|
wxST_ELLIPSIZE_START = 0x0004,
|
||||||
|
wxST_ELLIPSIZE_MIDDLE = 0x0008,
|
||||||
|
wxST_ELLIPSIZE_END = 0x0010
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class wxStaticText
|
@class wxStaticText
|
||||||
|
|
||||||
A static text control displays one or more lines of read-only text.
|
A static text control displays one or more lines of read-only text.
|
||||||
|
wxStaticText supports the three classic text alignments, label ellipsization
|
||||||
|
and formatting markup.
|
||||||
|
|
||||||
@beginStyleTable
|
@beginStyleTable
|
||||||
@style{wxALIGN_LEFT}
|
@style{wxALIGN_LEFT}
|
||||||
@@ -26,15 +43,16 @@
|
|||||||
CENTER style because otherwise they won't make sense any longer
|
CENTER style because otherwise they won't make sense any longer
|
||||||
after a call to SetLabel)
|
after a call to SetLabel)
|
||||||
@style{wxST_ELLIPSIZE_START}
|
@style{wxST_ELLIPSIZE_START}
|
||||||
If the text width exceeds the control width, replace the beginning
|
If the labeltext width exceeds the control width, replace the beginning
|
||||||
of the text with an ellipsis
|
of the label with an ellipsis
|
||||||
@style{wxST_ELLIPSIZE_MIDDLE}
|
@style{wxST_ELLIPSIZE_MIDDLE}
|
||||||
Same as above, but replace the text in the middle of the control
|
If the label text width exceeds the control width, replace the middle
|
||||||
with an ellipsis
|
of the label with an ellipsis
|
||||||
@style{wxST_ELLIPSIZE_END}
|
@style{wxST_ELLIPSIZE_END}
|
||||||
Same as above, but replace the end of the text with an ellipsis
|
If the label text width exceeds the control width, replace the end
|
||||||
|
of the label with an ellipsis
|
||||||
@style{wxST_MARKUP}
|
@style{wxST_MARKUP}
|
||||||
Support markup in the label; see SetLabel for more information
|
Support markup in the label; see SetLabel() for more information
|
||||||
@endStyleTable
|
@endStyleTable
|
||||||
|
|
||||||
@library{wxcore}
|
@library{wxcore}
|
||||||
@@ -86,6 +104,30 @@ public:
|
|||||||
const wxSize& size = wxDefaultSize, long style = 0,
|
const wxSize& size = wxDefaultSize, long style = 0,
|
||||||
const wxString& name = wxStaticTextNameStr);
|
const wxString& name = wxStaticTextNameStr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Escapes all the symbols of @a str that have a special meaning (<tt><>"'&</tt>) for
|
||||||
|
wxStaticText objects with the @c wxST_MARKUP style.
|
||||||
|
Those symbols are replaced the corresponding entities (< > " ' &).
|
||||||
|
*/
|
||||||
|
static wxString EscapeMarkup(const wxString& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Replaces parts of the @a label string with ellipsis, if needed, so
|
||||||
|
that it doesn't exceed @a maxWidth.
|
||||||
|
|
||||||
|
@param label
|
||||||
|
The string to ellipsize
|
||||||
|
@param dc
|
||||||
|
The DC used to retrieve the character widths through the
|
||||||
|
wxDC::GetPartialTextExtents() function.
|
||||||
|
@param mode
|
||||||
|
The ellipsization modes. See ::wxEllipsizeMode.
|
||||||
|
@param maxWidth
|
||||||
|
The maximum width of the returned string in pixels.
|
||||||
|
*/
|
||||||
|
static wxString Ellipsize(const wxString& label, const wxDC& dc,
|
||||||
|
wxEllipsizeMode mode, int maxWidth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the contents of the control.
|
Returns the contents of the control.
|
||||||
|
|
||||||
@@ -107,6 +149,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
static wxString GetLabelText(const wxString& label);
|
static wxString GetLabelText(const wxString& label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if the window styles for this control contains one of the
|
||||||
|
@c wxST_ELLIPSIZE_START, @c wxST_ELLIPSIZE_MIDDLE or @c wxST_ELLIPSIZE_END styles.
|
||||||
|
*/
|
||||||
|
bool IsEllipsized() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Removes the markup accepted by wxStaticText when the @c wxST_MARKUP style is used,
|
||||||
|
and then returns the cleaned string.
|
||||||
|
|
||||||
|
See SetLabel() for more info about the markup.
|
||||||
|
*/
|
||||||
|
static wxString RemoveMarkup(const wxString& str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the static text label and updates the controls size to exactly fit the
|
Sets the static text label and updates the controls size to exactly fit the
|
||||||
label unless the control has wxST_NO_AUTORESIZE flag.
|
label unless the control has wxST_NO_AUTORESIZE flag.
|
||||||
|
@@ -269,63 +269,12 @@ wxString wxStaticTextBase::EscapeMarkup(const wxString& text)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void wxStaticTextBase::UpdateLabel()
|
|
||||||
{
|
|
||||||
if (!IsEllipsized())
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxString newlabel = GetEllipsizedLabelWithoutMarkup();
|
|
||||||
|
|
||||||
// we need to touch the "real" label (i.e. the text set inside the control,
|
|
||||||
// using port-specific functions) instead of the string returned by GetLabel().
|
|
||||||
//
|
|
||||||
// In fact, we must be careful not to touch the original label passed to
|
|
||||||
// SetLabel() otherwise GetLabel() will behave in a strange way to the user
|
|
||||||
// (e.g. returning a "Ver...ing" instead of "Very long string") !
|
|
||||||
if (newlabel == DoGetLabel())
|
|
||||||
return;
|
|
||||||
DoSetLabel(newlabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const
|
|
||||||
{
|
|
||||||
// this function should be used only by ports which do not support
|
|
||||||
// ellipsis in static texts: we first remove markup (which cannot
|
|
||||||
// be handled safely by Ellipsize()) and then ellipsize the result.
|
|
||||||
|
|
||||||
wxString ret(m_labelOrig);
|
|
||||||
|
|
||||||
// the order of the following two blocks is important!
|
|
||||||
|
|
||||||
if (HasFlag(wxST_MARKUP))
|
|
||||||
ret = RemoveMarkup(ret);
|
|
||||||
|
|
||||||
if (IsEllipsized())
|
|
||||||
ret = Ellipsize(ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define wxELLIPSE_REPLACEMENT wxT("...")
|
#define wxELLIPSE_REPLACEMENT wxT("...")
|
||||||
|
|
||||||
wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
/* static */
|
||||||
|
wxString wxStaticTextBase::Ellipsize(const wxString& label, const wxDC& dc,
|
||||||
|
wxEllipsizeMode mode, int maxFinalWidth)
|
||||||
{
|
{
|
||||||
wxSize sz(GetSize());
|
|
||||||
if (sz.GetWidth() < 2 || sz.GetHeight() < 2)
|
|
||||||
{
|
|
||||||
// the size of this window is not valid (yet)
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxClientDC dc(const_cast<wxStaticTextBase*>(this));
|
|
||||||
dc.SetFont(GetFont());
|
|
||||||
|
|
||||||
wxArrayInt charOffsets;
|
wxArrayInt charOffsets;
|
||||||
wxString ret;
|
wxString ret;
|
||||||
|
|
||||||
@@ -333,7 +282,7 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
|||||||
int replacementWidth = dc.GetTextExtent(wxELLIPSE_REPLACEMENT).GetWidth();
|
int replacementWidth = dc.GetTextExtent(wxELLIPSE_REPLACEMENT).GetWidth();
|
||||||
int marginWidth = dc.GetCharWidth()*2;
|
int marginWidth = dc.GetCharWidth()*2;
|
||||||
|
|
||||||
// handle correctly labels with newlines
|
// NB: we must handle correctly labels with newlines:
|
||||||
wxString curLine;
|
wxString curLine;
|
||||||
wxSize reqsize;
|
wxSize reqsize;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -348,17 +297,17 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
|||||||
wxASSERT(charOffsets.GetCount() == len);
|
wxASSERT(charOffsets.GetCount() == len);
|
||||||
|
|
||||||
size_t totalWidth = charOffsets.Last();
|
size_t totalWidth = charOffsets.Last();
|
||||||
if ( totalWidth > (size_t)sz.GetWidth() )
|
if ( totalWidth > (size_t)maxFinalWidth )
|
||||||
{
|
{
|
||||||
// we need to ellipsize this row
|
// we need to ellipsize this row
|
||||||
int excessPixels = totalWidth - sz.GetWidth() +
|
int excessPixels = totalWidth - maxFinalWidth +
|
||||||
replacementWidth +
|
replacementWidth +
|
||||||
marginWidth; // security margin (NEEDED!)
|
marginWidth; // security margin (NEEDED!)
|
||||||
|
|
||||||
// remove characters in excess
|
// remove characters in excess
|
||||||
size_t initialChar, // index of first char to erase
|
size_t initialChar, // index of first char to erase
|
||||||
nChars; // how many chars do we need to erase?
|
nChars; // how many chars do we need to erase?
|
||||||
if (HasFlag(wxST_ELLIPSIZE_START))
|
if (mode == wxST_ELLIPSIZE_START)
|
||||||
{
|
{
|
||||||
initialChar = 0;
|
initialChar = 0;
|
||||||
for (nChars=0;
|
for (nChars=0;
|
||||||
@@ -366,7 +315,7 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
|||||||
nChars++)
|
nChars++)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
else if (HasFlag(wxST_ELLIPSIZE_MIDDLE))
|
else if (mode == wxST_ELLIPSIZE_MIDDLE)
|
||||||
{
|
{
|
||||||
// the start & end of the removed span of chars
|
// the start & end of the removed span of chars
|
||||||
initialChar = len/2;
|
initialChar = len/2;
|
||||||
@@ -410,7 +359,7 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxASSERT(HasFlag(wxST_ELLIPSIZE_END));
|
wxASSERT(mode == wxST_ELLIPSIZE_END);
|
||||||
wxASSERT(len > 0);
|
wxASSERT(len > 0);
|
||||||
|
|
||||||
int maxWidth = totalWidth - excessPixels;
|
int maxWidth = totalWidth - excessPixels;
|
||||||
@@ -442,13 +391,13 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
|||||||
curLine.erase(initialChar, nChars+1);
|
curLine.erase(initialChar, nChars+1);
|
||||||
|
|
||||||
// if there is space for the replacement dots, add them
|
// if there is space for the replacement dots, add them
|
||||||
if (sz.GetWidth() > replacementWidth)
|
if (maxFinalWidth > replacementWidth)
|
||||||
curLine.insert(initialChar, wxELLIPSE_REPLACEMENT);
|
curLine.insert(initialChar, wxELLIPSE_REPLACEMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if everything was ok, we should have shortened this line
|
// if everything was ok, we should have shortened this line
|
||||||
// enough to make it fit in sz.GetWidth():
|
// enough to make it fit in sz.maxFinalWidth:
|
||||||
wxASSERT(dc.GetTextExtent(curLine).GetWidth() < sz.GetWidth());
|
wxASSERT(dc.GetTextExtent(curLine).GetWidth() < maxFinalWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +434,70 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxStaticTextBase::UpdateLabel()
|
||||||
|
{
|
||||||
|
if (!IsEllipsized())
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString newlabel = GetEllipsizedLabelWithoutMarkup();
|
||||||
|
|
||||||
|
// we need to touch the "real" label (i.e. the text set inside the control,
|
||||||
|
// using port-specific functions) instead of the string returned by GetLabel().
|
||||||
|
//
|
||||||
|
// In fact, we must be careful not to touch the original label passed to
|
||||||
|
// SetLabel() otherwise GetLabel() will behave in a strange way to the user
|
||||||
|
// (e.g. returning a "Ver...ing" instead of "Very long string") !
|
||||||
|
if (newlabel == DoGetLabel())
|
||||||
|
return;
|
||||||
|
DoSetLabel(newlabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const
|
||||||
|
{
|
||||||
|
// this function should be used only by ports which do not support
|
||||||
|
// ellipsis in static texts: we first remove markup (which cannot
|
||||||
|
// be handled safely by Ellipsize()) and then ellipsize the result.
|
||||||
|
|
||||||
|
wxString ret(m_labelOrig);
|
||||||
|
|
||||||
|
// the order of the following two blocks is important!
|
||||||
|
|
||||||
|
if (HasFlag(wxST_MARKUP))
|
||||||
|
ret = RemoveMarkup(ret);
|
||||||
|
|
||||||
|
if (IsEllipsized())
|
||||||
|
ret = Ellipsize(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxStaticTextBase::Ellipsize(const wxString& label) const
|
||||||
|
{
|
||||||
|
wxSize sz(GetSize());
|
||||||
|
if (sz.GetWidth() < 2 || sz.GetHeight() < 2)
|
||||||
|
{
|
||||||
|
// the size of this window is not valid (yet)
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxClientDC dc(const_cast<wxStaticTextBase*>(this));
|
||||||
|
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;
|
||||||
|
|
||||||
|
return Ellipsize(label, dc, mode, sz.GetWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_STATTEXT
|
#endif // wxUSE_STATTEXT
|
||||||
|
Reference in New Issue
Block a user