mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-20 07:11:12 -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); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
|     multiline_text = text; | ||||
|  | @ -136,3 +254,9 @@ void Label::SetWindowStyleFlag(long style) | |||
|     } | ||||
|     Refresh(); | ||||
| } | ||||
| 
 | ||||
| void Label::Wrap(int width) | ||||
| { | ||||
|     wxLabelWrapper2 wrapper; | ||||
|     wrapper.WrapLabel(this, width); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 chunmao.guo
						chunmao.guo