File: elabel.cs

package info (click to toggle)
mono-tools 4.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 13,868 kB
  • sloc: cs: 100,909; sh: 3,845; makefile: 2,040; xml: 126
file content (121 lines) | stat: -rw-r--r-- 2,305 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//
// elabel.cs: An ellipsizing label widget
//
// Author:
//   Alp Toker (alp@atoker.com)
//
// (C) 2003 Alp Toker
//
using System;
using Gtk;

public class ELabel : Label {
	string text = "";
	const string ellipsis = "...";
	const string en_char = "n";
	int ellipsis_width, en_width, tmp;
	int old_width;
	Pango.Layout layout;
	bool refreshed = false;

	public ELabel (string text) : base ("")
	{
		int width, height;
		GetSizeRequest (out width, out height);
		SetSizeRequest (0, height);
		SizeAllocated += new SizeAllocatedHandler (OnSizeAllocated);

		Text = text;
	}

	new public string Text
	{
		get {
			return text;
		} set {
			text = value;
			Reload ();
			Refresh ();
		}
	}

	void OnSizeAllocated (object o, SizeAllocatedArgs args)
	{
		if (refreshed) {
			refreshed = false;
			return;
		}

		if (Allocation.Width != old_width) 
			Refresh ();
		old_width = Allocation.Width;

		refreshed = true;
	}

	void Reload ()
	{
		layout = Layout.Copy ();

		layout.SetText (ellipsis);
		layout.GetPixelSize (out ellipsis_width, out tmp);

		layout.SetText (en_char);
		layout.GetPixelSize (out en_width, out tmp);
	}

	void Refresh ()
	{
		string ellipsized = Ellipsize (layout, text, Allocation.Width, ellipsis_width, en_width);
		if (base.Text != ellipsized)
			base.Text = ellipsized;
	}

	public static string Ellipsize (Pango.Layout layout, string newtext, int bound, int ellipsis_width, int en_width)
	{
		int width, tmp;

		layout.SetText (newtext);
		layout.GetPixelSize (out width, out tmp);

		if (width < bound)
			return newtext;

		if (bound <= ellipsis_width)
			return ellipsis;

		string ellipsized = "";
		int i = 0;

		//make a guess of where to start
		i = (bound - ellipsis_width) / (en_width);
		if (i >= newtext.Length)
			i = 0;
		ellipsized = newtext.Substring (0, i);

		//add chars one by one to determine how many are allowed
		while (true)
		{
			ellipsized = ellipsized + newtext[i];
			layout.SetText (ellipsized);
			layout.GetPixelSize (out width, out tmp);

			if (i == newtext.Length - 1) {
				//bad guess, start from the beginning
				ellipsized = "";
				i = 0;
				continue;
			}

			if (width > bound - ellipsis_width)
				break;

			i++;
		}

		ellipsized = ellipsized.Remove (ellipsized.Length - 1, 1);
		ellipsized += ellipsis;

		return ellipsized;
	}
}