1 /**
2  * Text specific module.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module tkd.widget.common.canvas.textspecific;
8 
9 /**
10  * These are common commands that apply to all widgets that have them injected.
11  */
12 mixin template TextSpecific()
13 {
14 	import std.typecons : Nullable;
15 
16 	/**
17 	 * The angle of the text.
18 	 */
19 	private Nullable!(double) _angle;
20 
21 	/**
22 	 * The font.
23 	 */
24 	private string _font;
25 
26 	/**
27 	 * The alignment.
28 	 */
29 	private string _alignment;
30 
31 	/**
32 	 * The text.
33 	 */
34 	private string _text;
35 
36 	/**
37 	 * The maximum line length.
38 	 */
39 	private Nullable!(int) _maxLineLength;
40 
41 	/**
42 	 * Get the text angle.
43 	 *
44 	 * Returns:
45 	 *     The text angle.
46 	 */
47 	public double getAngle()
48 	{
49 		if (this._parent)
50 		{
51 			this._tk.eval("%s itemcget %s -angle", this._parent.id, this.id);
52 			this._angle = this._tk.getResult!(double);
53 		}
54 
55 		return this._angle.isNull ? 0.0 : this._angle;
56 	}
57 
58 	/**
59 	 * Specifies how many degrees to rotate the text anticlockwise about the 
60 	 * positioning point for the text; it may have any floating-point value 
61 	 * from 0.0 to 360.0. For example, if rotationDegrees is 90, then the text 
62 	 * will be drawn vertically from bottom to top. This option defaults to 
63 	 * 0.0. Degrees is given in units of degrees measured counter-clockwise 
64 	 * from the 3-o'clock position; it may be either positive or negative.
65 	 *
66 	 * Params:
67 	 *    angle = The text angle.
68 	 *
69 	 * Returns:
70 	 *     This item to aid method chaining.
71 	 */
72 	public auto setAngle(this T, A)(A angle) if (is(A == double) || is(A == Nullable!(double)))
73 	{
74 		static if (is(A == Nullable!(double)))
75 		{
76 			if (angle.isNull)
77 			{
78 				return cast(T) this;
79 			}
80 		}
81 
82 		this._angle = angle;
83 
84 		if (this._parent)
85 		{
86 			this._tk.eval("%s itemconfigure %s -angle %s", this._parent.id, this.id, this._angle);
87 		}
88 
89 		return cast(T) this;
90 	}
91 
92 	/**
93 	 * Get the font.
94 	 *
95 	 * Returns:
96 	 *     The font.
97 	 */
98 	public string getFont()
99 	{
100 		if (this._parent)
101 		{
102 			this._tk.eval("%s itemcget %s -font", this._parent.id, this.id);
103 			this._font = this._tk.getResult!(string);
104 		}
105 
106 		return this._font;
107 	}
108 
109 	/**
110 	 * Specifies the font to use for the text item. The format of the string to 
111 	 * pass when specifing a font is as follows.
112 	 *
113 	 * "Times New Roman" [[12] [bold] [italic] [overstrike] [underline]]
114 	 *
115 	 * Params:
116 	 *    font = The font.
117 	 *
118 	 * Returns:
119 	 *     This item to aid method chaining.
120 	 */
121 	public auto setFont(this T)(string font)
122 	{
123 		this._font = font;
124 
125 		if (this._parent && this._font.length)
126 		{
127 			// String concatentation is used here to avoid the character escaping done on args.
128 			this._tk.eval("%s itemconfigure %s -font {"~ this._font ~"}", this._parent.id, this.id);
129 		}
130 
131 		return cast(T) this;
132 	}
133 
134 	/**
135 	 * Get the alignment
136 	 *
137 	 * Returns:
138 	 *     The alignment.
139 	 */
140 	public string getAlignment()
141 	{
142 		if (this._parent)
143 		{
144 			this._tk.eval("%s itemcget %s -justify", this._parent.id, this.id);
145 			this._alignment = this._tk.getResult!(string);
146 		}
147 
148 		return this._alignment;
149 	}
150 
151 	/**
152 	 * Specifies how to justify the text within its bounding region.
153 	 *
154 	 * Params:
155 	 *    alignment = The alignment.
156 	 *
157 	 * Returns:
158 	 *     This item to aid method chaining.
159 	 *
160 	 * See_Also:
161 	 *     $(LINK2 ./alignment.html, tkd.widget.alignment)
162 	 */
163 	public auto setAlignment(this T)(string alignment)
164 	{
165 		this._alignment = alignment;
166 
167 		if (this._parent && this._alignment.length)
168 		{
169 			this._tk.eval("%s itemconfigure %s -justify {%s}", this._parent.id, this.id, this._alignment);
170 		}
171 
172 		return cast(T) this;
173 	}
174 
175 	/**
176 	 * Get the text.
177 	 *
178 	 * Returns:
179 	 *     The text.
180 	 */
181 	public string getText()
182 	{
183 		if (this._parent)
184 		{
185 			this._tk.eval("%s itemcget %s -text", this._parent.id, this.id);
186 			this._text = this._tk.getResult!(string);
187 		}
188 
189 		return this._text;
190 	}
191 
192 	/**
193 	 * Specifies the characters to be displayed in the text item.  Newline 
194 	 * characters cause line breaks.
195 	 *
196 	 * Params:
197 	 *    text = The text.
198 	 *
199 	 * Returns:
200 	 *     This item to aid method chaining.
201 	 */
202 	public auto setText(this T)(string text)
203 	{
204 		this._text = text;
205 
206 		if (this._parent && this._text.length)
207 		{
208 			this._tk.eval("%s itemconfigure %s -text {%s}", this._parent.id, this.id, this._text);
209 		}
210 
211 		return cast(T) this;
212 	}
213 
214 	/**
215 	 * Get max line length.
216 	 *
217 	 * Returns:
218 	 *     The max line length.
219 	 */
220 	public int getMaxLineLength()
221 	{
222 		if (this._parent)
223 		{
224 			this._tk.eval("%s itemcget %s -width", this._parent.id, this.id);
225 			this._maxLineLength = this._tk.getResult!(int);
226 		}
227 
228 		return this._maxLineLength.isNull ? 0 : this._maxLineLength;
229 	}
230 
231 	/**
232 	 * Specifies a maximum line length for the text. If this option is zero 
233 	 * (the default) the text is broken into lines only at newline characters.  
234 	 * However, if this option is non-zero then any line that would be longer 
235 	 * than line length is broken just before a space character to make the 
236 	 * line shorter than lineLength; the space character is treated as if it 
237 	 * were a newline character.
238 	 *
239 	 * Params:
240 	 *    maxLineLength = The max line length.
241 	 *
242 	 * Returns:
243 	 *     This item to aid method chaining.
244 	 */
245 	public auto setMaxLineLength(this T, L)(L maxLineLength) if (is(L == int) || is(L == Nullable!(int)))
246 	{
247 		static if (is(L == Nullable!(int)))
248 		{
249 			if (maxLineLength.isNull)
250 			{
251 				return cast(T) this;
252 			}
253 		}
254 
255 		this._maxLineLength = maxLineLength;
256 
257 		if (this._parent)
258 		{
259 			this._tk.eval("%s itemconfigure %s -width %s", this._parent.id, this.id, this._maxLineLength);
260 		}
261 
262 		return cast(T) this;
263 	}
264 }