mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 15:37:30 -06:00
ENH: Label Wrap
Change-Id: I7492f058f731a68e441ab9b78693872364fc00ab
This commit is contained in:
parent
4d4fcc1780
commit
d2b112d1c1
2 changed files with 126 additions and 0 deletions
|
@ -61,6 +61,124 @@ void Label::initSysFont()
|
||||||
Body_9 = Label::sysFont(9, false);
|
Body_9 = Label::sysFont(9, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_CORE wxTextWrapper2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxTextWrapper2() { m_eol = false; }
|
||||||
|
|
||||||
|
// win is used for getting the font, text is the text to wrap, width is the
|
||||||
|
// max line width or -1 to disable wrapping
|
||||||
|
void Wrap(wxWindow *win, const wxString &text, int widthMax)
|
||||||
|
{
|
||||||
|
const wxClientDC dc(win);
|
||||||
|
|
||||||
|
const wxArrayString ls = wxSplit(text, '\n', '\0');
|
||||||
|
for (wxArrayString::const_iterator i = ls.begin(); i != ls.end(); ++i) {
|
||||||
|
wxString line = *i;
|
||||||
|
|
||||||
|
if (i != ls.begin()) {
|
||||||
|
// Do this even if the line is empty, except if it's the first one.
|
||||||
|
OnNewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this a special case when wrapping is disabled?
|
||||||
|
if (widthMax < 0) {
|
||||||
|
DoOutputLine(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bool newLine = false; !line.empty(); newLine = true) {
|
||||||
|
if (newLine) OnNewLine();
|
||||||
|
|
||||||
|
wxArrayInt widths;
|
||||||
|
dc.GetPartialTextExtents(line, widths);
|
||||||
|
|
||||||
|
const size_t posEnd = std::lower_bound(widths.begin(), widths.end(), widthMax) - widths.begin();
|
||||||
|
|
||||||
|
// Does the entire remaining line fit?
|
||||||
|
if (posEnd == line.length()) {
|
||||||
|
DoOutputLine(line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the last word to chop off.
|
||||||
|
size_t lastSpace = posEnd;
|
||||||
|
while (lastSpace != size_t(-1)) {
|
||||||
|
auto c = line[lastSpace];
|
||||||
|
if (c == ' ' || c > 0x4E00)
|
||||||
|
break;
|
||||||
|
--lastSpace;
|
||||||
|
}
|
||||||
|
if (lastSpace == size_t(-1)) {
|
||||||
|
// No spaces, so can't wrap.
|
||||||
|
DoOutputLine(line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output the part that fits.
|
||||||
|
DoOutputLine(line.substr(0, lastSpace));
|
||||||
|
|
||||||
|
// And redo the layout with the rest.
|
||||||
|
if (line[lastSpace] == ' ') ++lastSpace;
|
||||||
|
line = line.substr(lastSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't need it, but just to avoid compiler warnings
|
||||||
|
virtual ~wxTextWrapper2() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// line may be empty
|
||||||
|
virtual void OnOutputLine(const wxString &line) = 0;
|
||||||
|
|
||||||
|
// called at the start of every new line (except the very first one)
|
||||||
|
virtual void OnNewLine() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// call OnOutputLine() and set m_eol to true
|
||||||
|
void DoOutputLine(const wxString &line)
|
||||||
|
{
|
||||||
|
OnOutputLine(line);
|
||||||
|
|
||||||
|
m_eol = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function is a destructive inspector: when it returns true it also
|
||||||
|
// resets the flag to false so calling it again wouldn't return true any
|
||||||
|
// more
|
||||||
|
bool IsStartOfNewLine()
|
||||||
|
{
|
||||||
|
if (!m_eol) return false;
|
||||||
|
|
||||||
|
m_eol = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_eol;
|
||||||
|
};
|
||||||
|
|
||||||
|
class wxLabelWrapper2 : public wxTextWrapper2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void WrapLabel(wxWindow *text, int widthMax)
|
||||||
|
{
|
||||||
|
m_text.clear();
|
||||||
|
Wrap(text, text->GetLabel(), widthMax);
|
||||||
|
text->SetLabel(m_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnOutputLine(const wxString &line) wxOVERRIDE { m_text += line; }
|
||||||
|
|
||||||
|
virtual void OnNewLine() wxOVERRIDE { m_text += wxT('\n'); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString m_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
wxSize Label::split_lines(wxDC &dc, int width, const wxString &text, wxString &multiline_text)
|
wxSize Label::split_lines(wxDC &dc, int width, const wxString &text, wxString &multiline_text)
|
||||||
{
|
{
|
||||||
multiline_text = text;
|
multiline_text = text;
|
||||||
|
@ -136,3 +254,9 @@ void Label::SetWindowStyleFlag(long style)
|
||||||
}
|
}
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Label::Wrap(int width)
|
||||||
|
{
|
||||||
|
wxLabelWrapper2 wrapper;
|
||||||
|
wrapper.WrapLabel(this, width);
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ public:
|
||||||
|
|
||||||
void SetWindowStyleFlag(long style) override;
|
void SetWindowStyleFlag(long style) override;
|
||||||
|
|
||||||
|
void Wrap(int width);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxFont font;
|
wxFont font;
|
||||||
wxColour color;
|
wxColour color;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue