Re: Can I wrap a label when it exceeds the width of parent?



Thanks a lot Peter! You have been very clear. (The code using your
 method is in class MyLabel2). Unfortunately your method is way
 too slow, because of the loop where you add one letter
 at a time. I have a list with hundreds of files, you see... 

To make it faster, I thought of another approach: since Pango Layouts
can wrap a text by themselves, by splitting it into lines, then we could 
make Pango do the wrapping and the read back the lines. We could
 use these lines to build the label text, putting a newline char 
between the lines. The code is in MyLabel3, but I can't extract 
the text from the LayoutLine! Do you happen to know if
I can do that? ( A negative answer would be tragic :-))

	/// A Label with the capability of wrapping itself if its
	/// width exceeds P pixels.
	class MyLabel2 : public Label{
	public:
		MyLabel2(string aTextWithoutNewlines) : Label(aTextWithoutNewlines){
			mTextWithoutNewlines = aTextWithoutNewlines;
			SetWrapPixel(100);
		}
		// Adds newlines in the label, in order not to make it
		// be wider than P pixels. This must be called each
		// time the width of the widget cointaining the label
		// changes.
		//
		//  TOO SLOW. Also, it splits words, which is
		//  undesirable.
		void SetWrapPixel(int p){
			Glib::ustring lTextWithNewlines = "";
			Glib::ustring lPossibleTextWithNewlines = "";
			for (Glib::ustring::iterator curChar=mTextWithoutNewlines.begin(); 
			     curChar!=mTextWithoutNewlines.end(); 
			     curChar++){
				lPossibleTextWithNewlines += *curChar;
				if (pixelWidthOfText(lPossibleTextWithNewlines)<p)
					lTextWithNewlines = lPossibleTextWithNewlines;
				else{
					lTextWithNewlines +='\n';
					lTextWithNewlines += *curChar;
					lPossibleTextWithNewlines = lTextWithNewlines;
				}
			}
			this->set_text(lTextWithNewlines);
		}
	private:
		Glib::ustring mTextWithoutNewlines;
		int pixelWidthOfText(Glib::ustring aTextPossiblyWithNewlines){
			if (mLayout ==0)
				mLayout= create_pango_layout(aTextPossiblyWithNewlines);
			else
				mLayout->set_text(aTextPossiblyWithNewlines);
			int w,h;
			mLayout->get_pixel_size(w, h);
			return w;
		}
		/// optimization: store the layout as member, in order
		/// to avoid to create it each time
		Glib::RefPtr<Pango::Layout> mLayout; 
	};

	/// A Label with the capability of wrapping itself if its
	/// width exceeds P pixels.
	class MyLabel3 : public Label{
	public:
		MyLabel3(string aTextWithoutNewlines) : Label(aTextWithoutNewlines){
			mTextWithoutNewlines = aTextWithoutNewlines;
			SetWrapPixel(100);
		}
		// SetWrapPixel: this function adds newlines to the
		// label text, in order not to make it be wider than P
		// pixels. Also it does not break words. Uses pango
		// for the wrapping. This would be perfect but I can't
		// write the function extract_text_of_line()!
		void SetWrapPixel(int p){
			Glib::ustring lTextWithNewlines = "";
			Glib::RefPtr<Pango::Layout> lLayout = 
                             create_pango_layout(mTextWithoutNewlines);
			lLayout->set_width(p * Pango::SCALE);
			lLayout->set_wrap(Pango::WRAP_WORD_CHAR);
			// Now Pango has correctly done the wrapping,
			// since lLayout->get_line_count() returns
			// more than 1. But I can't get the text of
			// the lines!
			for (int i = 0; i<lLayout->get_line_count(); i++){
				Glib::RefPtr<Pango::LayoutLine> lCurrentLine;
				Glib::ustring lLineText = extract_text_of_line(lCurrentLine);
				lTextWithNewlines += lLineText;
				lTextWithNewlines += '\n';
			}
			this->set_text(lTextWithNewlines);
		}
	private:
		Glib::ustring mTextWithoutNewlines;
		Glib::ustring extract_text_of_line(Glib::RefPtr<Pango::LayoutLine> aLayoutLine){
			///???
		}
	};




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]