1 /*
2  * label: An actor representing a label and an icon (both optional)
3  *
4  * Copyright 2012-2020 Stephan Haller <nomad@froevel.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  *
21  *
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include <libxfdashboard/label.h>
29 
30 #include <glib/gi18n-lib.h>
31 #include <gdk/gdk.h>
32 #include <math.h>
33 
34 #include <libxfdashboard/enums.h>
35 #include <libxfdashboard/image-content.h>
36 #include <libxfdashboard/compat.h>
37 
38 
39 /* Forward declarations */
40 typedef enum /*< skip,prefix=XFDASHBOARD_LABEL_ICON_TYPE >*/
41 {
42 	XFDASHBOARD_LABEL_ICON_TYPE_ICON_NONE,
43 	XFDASHBOARD_LABEL_ICON_TYPE_ICON_NAME,
44 	XFDASHBOARD_LABEL_ICON_TYPE_ICON_IMAGE,
45 	XFDASHBOARD_LABEL_ICON_TYPE_ICON_GICON
46 } XfdashboardLabelIconType;
47 
48 /* Define this class in GObject system */
49 struct _XfdashboardLabelPrivate
50 {
51 	/* Properties related */
52 	gfloat						padding;
53 	gfloat						spacing;
54 	XfdashboardLabelStyle		style;
55 
56 	gchar						*iconName;
57 	ClutterImage				*iconImage;
58 	GIcon						*iconGIcon;
59 	gboolean					iconSyncSize;
60 	gint						iconSize;
61 	XfdashboardOrientation		iconOrientation;
62 
63 	gchar						*font;
64 	ClutterColor				*labelColor;
65 	PangoEllipsizeMode			labelEllipsize;
66 	gboolean					isSingleLineMode;
67 	PangoAlignment				textJustification;
68 
69 	/* Instance related */
70 	ClutterActor				*actorIcon;
71 	ClutterActor				*actorLabel;
72 
73 	XfdashboardLabelIconType	iconType;
74 };
75 
76 G_DEFINE_TYPE_WITH_PRIVATE(XfdashboardLabel,
77 							xfdashboard_label,
78 							XFDASHBOARD_TYPE_BACKGROUND)
79 
80 /* Properties */
81 enum
82 {
83 	PROP_0,
84 
85 	PROP_PADDING,
86 	PROP_SPACING,
87 	PROP_STYLE,
88 
89 	PROP_ICON_NAME,
90 	PROP_ICON_IMAGE,
91 	PROP_ICON_GICON,
92 	PROP_ICON_SYNC_SIZE,
93 	PROP_ICON_SIZE,
94 	PROP_ICON_ORIENTATION,
95 
96 	PROP_TEXT,
97 	PROP_TEXT_FONT,
98 	PROP_TEXT_COLOR,
99 	PROP_TEXT_ELLIPSIZE_MODE,
100 	PROP_TEXT_SINGLE_LINE,
101 	PROP_TEXT_JUSTIFY,
102 
103 	PROP_LAST
104 };
105 
106 static GParamSpec* XfdashboardLabelProperties[PROP_LAST]={ 0, };
107 
108 
109 /* IMPLEMENTATION: Private variables and methods */
110 
111 /* Get preferred width of icon and label child actors
112  * We do not respect paddings here so if height is given it must be
113  * reduced by padding on all affected sides. The returned sizes are also
114  * without these paddings.
115  */
_xfdashboard_label_get_preferred_width_intern(XfdashboardLabel * self,gboolean inGetPreferred,gfloat inForHeight,gfloat * outIconSize,gfloat * outLabelSize)116 static void _xfdashboard_label_get_preferred_width_intern(XfdashboardLabel *self,
117 															gboolean inGetPreferred,
118 															gfloat inForHeight,
119 															gfloat *outIconSize,
120 															gfloat *outLabelSize)
121 {
122 	XfdashboardLabelPrivate		*priv;
123 	gfloat						iconWidth, iconHeight, iconScale;
124 	gfloat						iconSize, labelSize;
125 	gfloat						minSize, naturalSize;
126 
127 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
128 
129 	priv=self->priv;
130 
131 	/* Initialize sizes */
132 	iconSize=labelSize=0.0f;
133 
134 	/* Calculate sizes
135 	 * No size given so natural layout is requested */
136 	if(inForHeight<0.0f)
137 	{
138 		/* Special case: both actors visible and icon size
139 		 * synchronization is turned on
140 		 */
141 		if(clutter_actor_is_visible(priv->actorLabel) &&
142 			clutter_actor_is_visible(priv->actorIcon) &&
143 			priv->iconSyncSize==TRUE)
144 		{
145 			gfloat		labelHeight;
146 
147 			/* Get size of label */
148 			clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
149 												inForHeight,
150 												&minSize, &naturalSize);
151 			labelSize=(inGetPreferred==TRUE ? naturalSize : minSize);
152 
153 			/* Get size of icon depending on orientation */
154 			if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_LEFT ||
155 				priv->iconOrientation==XFDASHBOARD_ORIENTATION_RIGHT)
156 			{
157 				/* Get both sizes of label to calculate icon size */
158 				clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
159 													labelSize,
160 													&minSize, &naturalSize);
161 				labelHeight=(inGetPreferred==TRUE ? naturalSize : minSize);
162 
163 				/* Get size of icon depending on opposize size of label */
164 				if(CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
165 				{
166 					clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
167 														&iconWidth, &iconHeight);
168 					iconSize=(iconWidth/iconHeight)*labelHeight;
169 				}
170 					else iconSize=labelHeight;
171 			}
172 				else iconSize=labelSize;
173 		}
174 			/* Just get sizes of visible actors */
175 			else
176 			{
177 				/* Get size of label if visible */
178 				if(clutter_actor_is_visible(priv->actorLabel))
179 				{
180 					clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
181 														inForHeight,
182 														&minSize, &naturalSize);
183 					labelSize=(inGetPreferred==TRUE ? naturalSize : minSize);
184 				}
185 
186 				/* Get size of icon if visible */
187 				if(clutter_actor_is_visible(priv->actorIcon))
188 				{
189 					clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorIcon),
190 														inForHeight,
191 														&minSize, &naturalSize);
192 					iconSize=(inGetPreferred==TRUE ? naturalSize : minSize);
193 				}
194 			}
195 	}
196 		/* Special case: Size is given, both actors visible,
197 		 * icon size synchronization is turned on
198 		 */
199 		else if(clutter_actor_is_visible(priv->actorLabel) &&
200 					clutter_actor_is_visible(priv->actorIcon) &&
201 					priv->iconSyncSize==TRUE &&
202 					(priv->iconOrientation==XFDASHBOARD_ORIENTATION_TOP ||
203 						priv->iconOrientation==XFDASHBOARD_ORIENTATION_BOTTOM))
204 		{
205 			gfloat		labelMinimumSize;
206 			gfloat		requestSize, newRequestSize;
207 
208 			/* Reduce size by padding and spacing */
209 			inForHeight-=priv->spacing;
210 			inForHeight-=2*priv->padding;
211 			inForHeight=MAX(0.0f, inForHeight);
212 
213 			/* Get scale factor of icon */
214 			if(CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
215 			{
216 				clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
217 													&iconWidth, &iconHeight);
218 				iconScale=(iconWidth/iconHeight);
219 				iconWidth=(iconHeight/iconWidth)*inForHeight;
220 				iconHeight=iconWidth/iconScale;
221 			}
222 				else iconScale=iconWidth=iconHeight=0.0f;
223 
224 			/* Get minimum size of label because we should never
225 			 * go down below this minimum size
226 			 */
227 			clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
228 												-1.0f,
229 												&labelMinimumSize, NULL);
230 
231 			/* Initialize height with value if it could occupy 100% width and
232 			 * set icon size to negative value to show that its value was not
233 			 * found yet
234 			 */
235 			iconSize=-1.0f;
236 
237 			clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
238 												inForHeight,
239 												&minSize, &naturalSize);
240 			requestSize=(inGetPreferred==TRUE ? naturalSize : minSize);
241 
242 			if(priv->labelEllipsize==PANGO_ELLIPSIZE_NONE ||
243 				clutter_text_get_single_line_mode(CLUTTER_TEXT(priv->actorLabel))==FALSE)
244 			{
245 				do
246 				{
247 					/* Get size of icon */
248 					iconHeight=requestSize;
249 					iconWidth=iconHeight*iconScale;
250 
251 					/* Reduce size for label by size of icon and
252 					 * get its opposize size
253 					 */
254 					clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
255 														inForHeight-iconHeight,
256 														&minSize, &naturalSize);
257 					newRequestSize=(inGetPreferred==TRUE ? naturalSize : minSize);
258 
259 					/* If new opposite size is equal (or unexpectly lower) than
260 					 * initial opposize size we found the sizes
261 					 */
262 					if(newRequestSize<=requestSize)
263 					{
264 						iconSize=iconWidth;
265 						labelSize=newRequestSize;
266 					}
267 					requestSize=newRequestSize;
268 				}
269 				while(iconSize<0.0f && (inForHeight-iconHeight)>labelMinimumSize);
270 			}
271 				else
272 				{
273 					/* Get size of icon */
274 					iconWidth=requestSize;
275 					iconHeight=iconWidth/iconScale;
276 					iconSize=iconWidth;
277 
278 					/* Adjust label size */
279 					labelSize=requestSize-iconWidth;
280 				}
281 		}
282 		/* Size is given but nothing special */
283 		else
284 		{
285 			/* Reduce size by padding and if both icon and label are visible
286 			 * also reduce by spacing
287 			 */
288 			if(clutter_actor_is_visible(priv->actorIcon) &&
289 				(clutter_actor_is_visible(priv->actorLabel)))
290 			{
291 				inForHeight-=priv->spacing;
292 			}
293 			inForHeight-=2*priv->padding;
294 			inForHeight=MAX(0.0f, inForHeight);
295 
296 			/* Get icon size if visible */
297 			if(clutter_actor_is_visible(priv->actorIcon))
298 			{
299 				if(priv->iconSyncSize==TRUE &&
300 					(priv->iconOrientation==XFDASHBOARD_ORIENTATION_LEFT ||
301 						priv->iconOrientation==XFDASHBOARD_ORIENTATION_RIGHT))
302 				{
303 					if(CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
304 					{
305 						/* Get scale factor of icon and scale icon */
306 						clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
307 															&iconWidth, &iconHeight);
308 						minSize=naturalSize=inForHeight*(iconWidth/iconHeight);
309 					}
310 						else minSize=naturalSize=0.0f;
311 				}
312 					else
313 					{
314 						clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorIcon),
315 															inForHeight,
316 															&minSize, &naturalSize);
317 					}
318 
319 				iconSize=(inGetPreferred==TRUE ? naturalSize : minSize);
320 			}
321 
322 			/* Get label size if visible */
323 			if(clutter_actor_is_visible(priv->actorLabel))
324 			{
325 				if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_TOP ||
326 						priv->iconOrientation==XFDASHBOARD_ORIENTATION_BOTTOM)
327 				{
328 					inForHeight-=iconSize;
329 				}
330 
331 				clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
332 													inForHeight,
333 													&minSize, &naturalSize);
334 				labelSize=(inGetPreferred==TRUE ? naturalSize : minSize);
335 			}
336 		}
337 
338 	/* Set computed sizes */
339 	if(outIconSize) *outIconSize=iconSize;
340 	if(outLabelSize) *outLabelSize=labelSize;
341 }
342 
343 /* Get preferred height of icon and label child actors
344  * We do not respect paddings here so if width is given it must be
345  * reduced by paddings and spacing. The returned sizes are alsowithout
346  * these paddings and spacing.
347  */
_xfdashboard_label_get_preferred_height_intern(XfdashboardLabel * self,gboolean inGetPreferred,gfloat inForWidth,gfloat * outIconSize,gfloat * outLabelSize)348 static void _xfdashboard_label_get_preferred_height_intern(XfdashboardLabel *self,
349 															gboolean inGetPreferred,
350 															gfloat inForWidth,
351 															gfloat *outIconSize,
352 															gfloat *outLabelSize)
353 {
354 	XfdashboardLabelPrivate		*priv;
355 	gfloat						iconWidth, iconHeight, iconScale;
356 	gfloat						iconSize, labelSize;
357 	gfloat						minSize, naturalSize;
358 
359 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
360 
361 	priv=self->priv;
362 
363 	/* Initialize sizes */
364 	iconSize=labelSize=0.0f;
365 
366 	/* Calculate sizes
367 	 * No size given so natural layout is requested */
368 	if(inForWidth<0.0f)
369 	{
370 		/* Special case: both actors visible and icon size
371 		 * synchronization is turned on
372 		 */
373 		if(clutter_actor_is_visible(priv->actorLabel) &&
374 			clutter_actor_is_visible(priv->actorIcon) &&
375 			priv->iconSyncSize==TRUE)
376 		{
377 			gfloat		labelWidth;
378 
379 			/* Get size of label */
380 			clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
381 												inForWidth,
382 												&minSize, &naturalSize);
383 			labelSize=(inGetPreferred==TRUE ? naturalSize : minSize);
384 
385 			/* Get size of icon depending on orientation */
386 			if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_TOP ||
387 				priv->iconOrientation==XFDASHBOARD_ORIENTATION_BOTTOM)
388 			{
389 				/* Get both sizes of label to calculate icon size */
390 				clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
391 													labelSize,
392 													&minSize, &naturalSize);
393 				labelWidth=(inGetPreferred==TRUE ? naturalSize : minSize);
394 
395 				/* Get size of icon depending on opposize size of label */
396 				if(CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
397 				{
398 					clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
399 														&iconWidth, &iconHeight);
400 					iconSize=(iconHeight/iconWidth)*labelWidth;
401 				}
402 					else iconSize=labelWidth;
403 			}
404 				else iconSize=labelSize;
405 		}
406 			/* Just get sizes of visible actors */
407 			else
408 			{
409 				/* Get sizes of visible actors */
410 				if(clutter_actor_is_visible(priv->actorIcon))
411 				{
412 					clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorIcon),
413 														inForWidth,
414 														&minSize, &naturalSize);
415 					iconSize=(inGetPreferred==TRUE ? naturalSize : minSize);
416 				}
417 
418 				if(clutter_actor_is_visible(priv->actorLabel))
419 				{
420 					clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
421 														inForWidth,
422 														&minSize, &naturalSize);
423 					labelSize=(inGetPreferred==TRUE ? naturalSize : minSize);
424 				}
425 			}
426 	}
427 		/* Special case: Size is given, both actors visible,
428 		 * icon size synchronization is turned on
429 		 */
430 		else if(clutter_actor_is_visible(priv->actorLabel) &&
431 					clutter_actor_is_visible(priv->actorIcon) &&
432 					priv->iconSyncSize==TRUE &&
433 					(priv->iconOrientation==XFDASHBOARD_ORIENTATION_LEFT ||
434 						priv->iconOrientation==XFDASHBOARD_ORIENTATION_RIGHT))
435 		{
436 			gfloat		labelMinimumSize;
437 			gfloat		requestSize, newRequestSize;
438 
439 			/* Reduce size by padding and spacing */
440 			inForWidth-=priv->spacing;
441 			inForWidth-=2*priv->padding;
442 			inForWidth=MAX(0.0f, inForWidth);
443 
444 			/* Get scale factor of icon */
445 			if(CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
446 			{
447 				clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
448 													&iconWidth, &iconHeight);
449 				iconScale=(iconWidth/iconHeight);
450 				iconWidth=(iconHeight/iconWidth)*inForWidth;
451 				iconHeight=iconWidth/iconScale;
452 			}
453 				else iconScale=iconWidth=iconHeight=0.0f;
454 
455 			/* Get minimum size of label because we should never
456 			 * go down below this minimum size
457 			 */
458 			clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorLabel),
459 												-1.0f,
460 												&labelMinimumSize, NULL);
461 
462 			/* Initialize height with value if it could occupy 100% width and
463 			 * set icon size to negative value to show that its value was not
464 			 * found yet
465 			 */
466 			iconSize=-1.0f;
467 
468 			clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
469 												inForWidth,
470 												&minSize, &naturalSize);
471 			requestSize=(inGetPreferred==TRUE ? naturalSize : minSize);
472 
473 			if(priv->labelEllipsize==PANGO_ELLIPSIZE_NONE ||
474 				clutter_text_get_single_line_mode(CLUTTER_TEXT(priv->actorLabel))==FALSE)
475 			{
476 				do
477 				{
478 					/* Get size of icon */
479 					iconHeight=requestSize;
480 					iconWidth=iconHeight*iconScale;
481 
482 					/* Reduce size for label by size of icon and
483 					 * get its opposize size
484 					 */
485 					clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
486 														inForWidth-iconWidth,
487 														&minSize, &naturalSize);
488 					newRequestSize=(inGetPreferred==TRUE ? naturalSize : minSize);
489 
490 					/* If new opposite size is equal (or unexpectly lower) than
491 					 * initial opposize size we found the sizes
492 					 */
493 					if(newRequestSize<=requestSize)
494 					{
495 						iconSize=iconHeight;
496 						labelSize=newRequestSize;
497 					}
498 					requestSize=newRequestSize;
499 				}
500 				while(iconSize<0.0f && (inForWidth-iconWidth)>labelMinimumSize);
501 			}
502 				else
503 				{
504 					/* Get size of icon */
505 					iconHeight=requestSize;
506 					iconWidth=iconHeight*iconScale;
507 					iconSize=iconHeight;
508 
509 					/* Adjust label size */
510 					labelSize=requestSize-iconHeight;
511 				}
512 		}
513 		/* Size is given but nothing special */
514 		else
515 		{
516 			/* Reduce size by padding and if both icon and label are visible
517 			 * also reduce by spacing
518 			 */
519 			if(clutter_actor_is_visible(priv->actorIcon) &&
520 				(clutter_actor_is_visible(priv->actorLabel)))
521 			{
522 				inForWidth-=priv->spacing;
523 			}
524 			inForWidth-=2*priv->padding;
525 			inForWidth=MAX(0.0f, inForWidth);
526 
527 			/* Get icon size if visible */
528 			if(clutter_actor_is_visible(priv->actorIcon))
529 			{
530 				if(priv->iconSyncSize==TRUE &&
531 					(priv->iconOrientation==XFDASHBOARD_ORIENTATION_TOP ||
532 						priv->iconOrientation==XFDASHBOARD_ORIENTATION_BOTTOM))
533 				{
534 					if(CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
535 					{
536 						/* Get scale factor of icon and scale icon */
537 						clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
538 															&iconWidth, &iconHeight);
539 						minSize=naturalSize=inForWidth*(iconHeight/iconWidth);
540 					}
541 						else minSize=naturalSize=0.0f;
542 				}
543 					else
544 					{
545 						clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorIcon),
546 															inForWidth,
547 															&minSize, &naturalSize);
548 					}
549 				iconSize=(inGetPreferred==TRUE ? naturalSize : minSize);
550 			}
551 
552 			/* Get label size if visible */
553 			if(clutter_actor_is_visible(priv->actorLabel))
554 			{
555 				if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_LEFT ||
556 						priv->iconOrientation==XFDASHBOARD_ORIENTATION_RIGHT)
557 				{
558 					inForWidth-=iconSize;
559 				}
560 
561 				clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorLabel),
562 													inForWidth,
563 													&minSize, &naturalSize);
564 				labelSize=(inGetPreferred==TRUE ? naturalSize : minSize);
565 			}
566 		}
567 
568 	/* Set computed sizes */
569 	if(outIconSize) *outIconSize=iconSize;
570 	if(outLabelSize) *outLabelSize=labelSize;
571 }
572 
573 /* Update icon */
_xfdashboard_label_update_icon_image_size(XfdashboardLabel * self)574 static void _xfdashboard_label_update_icon_image_size(XfdashboardLabel *self)
575 {
576 	XfdashboardLabelPrivate		*priv;
577 	gfloat						iconWidth, iconHeight;
578 	gfloat						maxSize;
579 
580 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
581 
582 	priv=self->priv;
583 	iconWidth=iconHeight=-1.0f;
584 	maxSize=0.0f;
585 
586 	/* Determine maximum size of icon either from label size if icon size
587 	 * should be synchronized or to icon size set if greater than zero.
588 	 * Otherwise the default size of icon will be set
589 	 */
590 	if(priv->iconSyncSize)
591 	{
592 		gfloat					labelWidth, labelHeight;
593 
594 		/* Get size of label */
595 		clutter_actor_get_preferred_size(CLUTTER_ACTOR(priv->actorLabel),
596 											NULL, NULL,
597 											&labelWidth, &labelHeight);
598 
599 		if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_TOP ||
600 			priv->iconOrientation==XFDASHBOARD_ORIENTATION_BOTTOM)
601 		{
602 			maxSize=labelWidth;
603 		}
604 			else
605 			{
606 				maxSize=labelHeight;
607 			}
608 	}
609 		else if(priv->iconSize>0.0f) maxSize=priv->iconSize;
610 
611 	/* Get size of icon if maximum size is set */
612 	if(maxSize>0.0f && CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
613 	{
614 		/* Get preferred size of icon */
615 		clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
616 											&iconWidth, &iconHeight);
617 
618 		/* Determine size of icon */
619 		if(iconWidth>iconHeight)
620 		{
621 			iconHeight=maxSize*(iconHeight/iconWidth);
622 			iconWidth=maxSize;
623 		}
624 			else
625 			{
626 				iconWidth=maxSize*(iconWidth/iconHeight);
627 				iconHeight=maxSize;
628 			}
629 	}
630 
631 	/* Update size of icon actor */
632 	clutter_actor_set_size(priv->actorIcon, iconWidth, iconHeight);
633 
634 	/* Queue a redraw as the actors are now available */
635 	clutter_actor_queue_redraw(CLUTTER_ACTOR(self));
636 }
637 
638 
639 /* IMPLEMENTATION: ClutterActor */
640 
641 /* Show all children of this actor */
_xfdashboard_label_show_all(ClutterActor * self)642 static void _xfdashboard_label_show_all(ClutterActor *self)
643 {
644 	XfdashboardLabelPrivate		*priv=XFDASHBOARD_LABEL(self)->priv;
645 
646 	if(priv->style==XFDASHBOARD_LABEL_STYLE_ICON ||
647 		priv->style==XFDASHBOARD_LABEL_STYLE_BOTH)
648 	{
649 		clutter_actor_show(CLUTTER_ACTOR(priv->actorIcon));
650 	}
651 		else clutter_actor_hide(CLUTTER_ACTOR(priv->actorIcon));
652 
653 	if(priv->style==XFDASHBOARD_LABEL_STYLE_TEXT ||
654 		priv->style==XFDASHBOARD_LABEL_STYLE_BOTH)
655 	{
656 		clutter_actor_show(CLUTTER_ACTOR(priv->actorLabel));
657 	}
658 		else clutter_actor_hide(CLUTTER_ACTOR(priv->actorLabel));
659 
660 	clutter_actor_show(self);
661 }
662 
663 /* Hide all children of this actor */
_xfdashboard_label_hide_all(ClutterActor * self)664 static void _xfdashboard_label_hide_all(ClutterActor *self)
665 {
666 	XfdashboardLabelPrivate		*priv=XFDASHBOARD_LABEL(self)->priv;
667 
668 	clutter_actor_hide(self);
669 	clutter_actor_hide(CLUTTER_ACTOR(priv->actorIcon));
670 	clutter_actor_hide(CLUTTER_ACTOR(priv->actorLabel));
671 }
672 
673 /* Get preferred width/height */
_xfdashboard_label_get_preferred_height(ClutterActor * inActor,gfloat inForWidth,gfloat * outMinHeight,gfloat * outNaturalHeight)674 static void _xfdashboard_label_get_preferred_height(ClutterActor *inActor,
675 														gfloat inForWidth,
676 														gfloat *outMinHeight,
677 														gfloat *outNaturalHeight)
678 {
679 	XfdashboardLabel			*self=XFDASHBOARD_LABEL(inActor);
680 	XfdashboardLabelPrivate		*priv=self->priv;
681 	gfloat						minHeight, naturalHeight;
682 	gfloat						minIconHeight, naturalIconHeight;
683 	gfloat						minLabelHeight, naturalLabelHeight;
684 	gfloat						spacing=priv->spacing;
685 
686 	/* Initialize sizes */
687 	minHeight=naturalHeight=0.0f;
688 	minIconHeight=naturalIconHeight=0.0f;
689 	minLabelHeight=naturalLabelHeight=0.0f;
690 
691 	/* Calculate sizes for requested one (means which can and will be stored) */
692 	if(outMinHeight)
693 	{
694 		_xfdashboard_label_get_preferred_height_intern(self,
695 															FALSE,
696 															inForWidth,
697 															&minIconHeight,
698 															&minLabelHeight);
699 	}
700 
701 	if(outNaturalHeight)
702 	{
703 		_xfdashboard_label_get_preferred_height_intern(self,
704 															TRUE,
705 															inForWidth,
706 															&naturalIconHeight,
707 															&naturalLabelHeight);
708 	}
709 
710 	if(clutter_actor_is_visible(priv->actorLabel)!=TRUE ||
711 		clutter_actor_is_visible(priv->actorIcon)!=TRUE)
712 	{
713 		spacing=0.0f;
714 	}
715 
716 	switch(priv->iconOrientation)
717 	{
718 		case XFDASHBOARD_ORIENTATION_TOP:
719 		case XFDASHBOARD_ORIENTATION_BOTTOM:
720 			minHeight=minIconHeight+minLabelHeight;
721 			naturalHeight=naturalIconHeight+naturalLabelHeight;
722 			break;
723 
724 		default:
725 			minHeight=MAX(minIconHeight, minLabelHeight);
726 			naturalHeight=MAX(naturalIconHeight, naturalLabelHeight);
727 			break;
728 	}
729 
730 	/* Add spacing to size if orientation is top or bottom.
731 	 * Spacing was initially set to spacing in settings but
732 	 * resetted to zero if either text or icon is not visible.
733 	 */
734 	if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_TOP ||
735 		priv->iconOrientation==XFDASHBOARD_ORIENTATION_BOTTOM)
736 	{
737 		minHeight+=spacing;
738 		naturalHeight+=spacing;
739 	}
740 
741 	/* Add padding */
742 	minHeight+=2*priv->padding;
743 	naturalHeight+=2*priv->padding;
744 
745 	/* Store sizes computed */
746 	if(outMinHeight) *outMinHeight=minHeight;
747 	if(outNaturalHeight) *outNaturalHeight=naturalHeight;
748 }
749 
_xfdashboard_label_get_preferred_width(ClutterActor * inActor,gfloat inForHeight,gfloat * outMinWidth,gfloat * outNaturalWidth)750 static void _xfdashboard_label_get_preferred_width(ClutterActor *inActor,
751 													gfloat inForHeight,
752 													gfloat *outMinWidth,
753 													gfloat *outNaturalWidth)
754 {
755 	XfdashboardLabel			*self=XFDASHBOARD_LABEL(inActor);
756 	XfdashboardLabelPrivate		*priv=self->priv;
757 	gfloat						minWidth, naturalWidth;
758 	gfloat						minIconWidth, naturalIconWidth;
759 	gfloat						minLabelWidth, naturalLabelWidth;
760 	gfloat						spacing=priv->spacing;
761 
762 	/* Initialize sizes */
763 	minWidth=naturalWidth=0.0f;
764 	minIconWidth=naturalIconWidth=0.0f;
765 	minLabelWidth=naturalLabelWidth=0.0f;
766 
767 	/* Calculate sizes for requested one (means which can and will be stored) */
768 	if(outMinWidth)
769 	{
770 		_xfdashboard_label_get_preferred_width_intern(self,
771 															FALSE,
772 															inForHeight,
773 															&minIconWidth,
774 															&minLabelWidth);
775 	}
776 
777 	if(outNaturalWidth)
778 	{
779 		_xfdashboard_label_get_preferred_width_intern(self,
780 															TRUE,
781 															inForHeight,
782 															&naturalIconWidth,
783 															&naturalLabelWidth);
784 	}
785 
786 	if(clutter_actor_is_visible(priv->actorLabel)!=TRUE ||
787 		clutter_actor_is_visible(priv->actorIcon)!=TRUE)
788 	{
789 		spacing=0.0f;
790 	}
791 
792 	switch(priv->iconOrientation)
793 	{
794 		case XFDASHBOARD_ORIENTATION_LEFT:
795 		case XFDASHBOARD_ORIENTATION_RIGHT:
796 			minWidth=minIconWidth+minLabelWidth;
797 			naturalWidth=naturalIconWidth+naturalLabelWidth;
798 			break;
799 
800 		default:
801 			minWidth=MAX(minIconWidth, minLabelWidth);
802 			naturalWidth=MAX(naturalIconWidth, naturalLabelWidth);
803 			break;
804 	}
805 
806 	/* Add spacing to size if orientation is left or right.
807 	 * Spacing was initially set to spacing in settings but
808 	 * resetted to zero if either text or icon is not visible.
809 	 */
810 	if(priv->iconOrientation==XFDASHBOARD_ORIENTATION_LEFT ||
811 		priv->iconOrientation==XFDASHBOARD_ORIENTATION_RIGHT)
812 	{
813 		minWidth+=spacing;
814 		naturalWidth+=spacing;
815 	}
816 
817 	/* Add padding */
818 	minWidth+=2*priv->padding;
819 	naturalWidth+=2*priv->padding;
820 
821 	/* Store sizes computed */
822 	if(outMinWidth) *outMinWidth=minWidth;
823 	if(outNaturalWidth) *outNaturalWidth=naturalWidth;
824 }
825 
826 /* Allocate position and size of actor and its children */
_xfdashboard_label_allocate(ClutterActor * inActor,const ClutterActorBox * inBox,ClutterAllocationFlags inFlags)827 static void _xfdashboard_label_allocate(ClutterActor *inActor,
828 											const ClutterActorBox *inBox,
829 											ClutterAllocationFlags inFlags)
830 {
831 	XfdashboardLabel			*self=XFDASHBOARD_LABEL(inActor);
832 	XfdashboardLabelPrivate		*priv=self->priv;
833 	ClutterActorBox				*boxLabel=NULL;
834 	ClutterActorBox				*boxIcon=NULL;
835 	gfloat						left, right, top, bottom;
836 	gfloat						textWidth, textHeight;
837 	gfloat						iconWidth, iconHeight;
838 	gfloat						spacing=priv->spacing;
839 
840 	/* Chain up to store the allocation of the actor */
841 	CLUTTER_ACTOR_CLASS(xfdashboard_label_parent_class)->allocate(inActor, inBox, inFlags);
842 
843 	/* Get sizes of children and determine if we need
844 	 * to add spacing between text and icon. If either
845 	 * icon or text is not visible reset its size to zero
846 	 * and also reset spacing to zero.
847 	 */
848 	if(!clutter_actor_is_visible(priv->actorIcon) ||
849 			!clutter_actor_is_visible(priv->actorLabel))
850 	{
851 		spacing=0.0f;
852 	}
853 
854 	/* Get icon sizes */
855 	iconWidth=iconHeight=0.0f;
856 	if(clutter_actor_is_visible(priv->actorIcon))
857 	{
858 		gfloat					iconScale=1.0f;
859 
860 		if(priv->iconSyncSize==TRUE &&
861 			CLUTTER_IS_CONTENT(clutter_actor_get_content(priv->actorIcon)))
862 		{
863 			clutter_content_get_preferred_size(clutter_actor_get_content(priv->actorIcon),
864 												&iconWidth, &iconHeight);
865 			iconScale=(iconWidth/iconHeight);
866 		}
867 
868 		if(clutter_actor_get_request_mode(CLUTTER_ACTOR(self))==CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
869 		{
870 			_xfdashboard_label_get_preferred_height_intern(self,
871 															TRUE,
872 															clutter_actor_box_get_width(inBox),
873 															&iconHeight,
874 															NULL);
875 			if(priv->iconSyncSize==TRUE) iconWidth=iconHeight*iconScale;
876 				else clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->actorIcon), iconHeight, NULL, &iconWidth);
877 		}
878 			else
879 			{
880 				_xfdashboard_label_get_preferred_width_intern(self,
881 																TRUE,
882 																clutter_actor_box_get_height(inBox),
883 																&iconWidth,
884 																NULL);
885 				if(priv->iconSyncSize==TRUE) iconHeight=iconWidth/iconScale;
886 					else clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->actorIcon), iconWidth, NULL, &iconHeight);
887 			}
888 	}
889 
890 	/* Set allocation of label if visible*/
891 	textWidth=textHeight=0.0f;
892 	if(clutter_actor_is_visible(priv->actorLabel))
893 	{
894 		switch(priv->iconOrientation)
895 		{
896 			case XFDASHBOARD_ORIENTATION_TOP:
897 				textWidth=MAX(0.0f, clutter_actor_box_get_width(inBox)-2*priv->padding);
898 
899 				textHeight=clutter_actor_box_get_height(inBox)-iconHeight-2*priv->padding;
900 				if(clutter_actor_is_visible(priv->actorIcon)) textHeight-=priv->spacing;
901 				textHeight=MAX(0.0f, textHeight);
902 
903 				left=((clutter_actor_box_get_width(inBox)-textWidth)/2.0f);
904 				right=left+textWidth;
905 				top=priv->padding+iconHeight+spacing;
906 				bottom=top+textHeight;
907 				break;
908 
909 			case XFDASHBOARD_ORIENTATION_BOTTOM:
910 				textWidth=MAX(0.0f, clutter_actor_box_get_width(inBox)-2*priv->padding);
911 
912 				textHeight=clutter_actor_box_get_height(inBox)-iconHeight-2*priv->padding;
913 				if(clutter_actor_is_visible(priv->actorIcon)) textHeight-=priv->spacing;
914 				textHeight=MAX(0.0f, textHeight);
915 
916 				left=((clutter_actor_box_get_width(inBox)-textWidth)/2.0f);
917 				right=left+textWidth;
918 				top=priv->padding;
919 				bottom=top+textHeight;
920 				break;
921 
922 			case XFDASHBOARD_ORIENTATION_RIGHT:
923 				textWidth=clutter_actor_box_get_width(inBox)-iconWidth-2*priv->padding;
924 				if(clutter_actor_is_visible(priv->actorIcon)) textWidth-=priv->spacing;
925 				textWidth=MAX(0.0f, textWidth);
926 
927 				textHeight=MAX(0.0f, clutter_actor_box_get_height(inBox)-2*priv->padding);
928 
929 				left=priv->padding;
930 				right=left+textWidth;
931 				top=priv->padding;
932 				bottom=top+textHeight;
933 				break;
934 
935 			case XFDASHBOARD_ORIENTATION_LEFT:
936 			default:
937 				textWidth=clutter_actor_box_get_width(inBox)-iconWidth-2*priv->padding;
938 				if(clutter_actor_is_visible(priv->actorIcon)) textWidth-=priv->spacing;
939 				textWidth=MAX(0.0f, textWidth);
940 
941 				textHeight=MAX(0.0f, clutter_actor_box_get_height(inBox)-2*priv->padding);
942 
943 				left=priv->padding+iconWidth+spacing;
944 				right=left+textWidth;
945 				top=priv->padding;
946 				bottom=top+textHeight;
947 				break;
948 		}
949 
950 		right=MAX(left, right);
951 		bottom=MAX(top, bottom);
952 
953 		boxLabel=clutter_actor_box_new(floor(left), floor(top), floor(right), floor(bottom));
954 		clutter_actor_allocate(CLUTTER_ACTOR(priv->actorLabel), boxLabel, inFlags);
955 	}
956 
957 	/* Set allocation of icon if visible*/
958 	if(clutter_actor_is_visible(priv->actorIcon))
959 	{
960 		switch(priv->iconOrientation)
961 		{
962 			case XFDASHBOARD_ORIENTATION_TOP:
963 				left=((clutter_actor_box_get_width(inBox)-iconWidth)/2.0f);
964 				right=left+iconWidth;
965 				top=priv->padding;
966 				bottom=top+iconHeight;
967 				break;
968 
969 			case XFDASHBOARD_ORIENTATION_BOTTOM:
970 				left=((clutter_actor_box_get_width(inBox)-iconWidth)/2.0f);
971 				right=left+iconWidth;
972 				top=priv->padding+textHeight+spacing;
973 				bottom=top+iconHeight;
974 				break;
975 
976 			case XFDASHBOARD_ORIENTATION_RIGHT:
977 				left=clutter_actor_box_get_width(inBox)-priv->padding-iconWidth;
978 				right=clutter_actor_box_get_width(inBox)-priv->padding;
979 				top=priv->padding;
980 				bottom=top+iconHeight;
981 				break;
982 
983 			case XFDASHBOARD_ORIENTATION_LEFT:
984 			default:
985 				left=priv->padding;
986 				right=left+iconWidth;
987 				top=priv->padding;
988 				bottom=top+iconHeight;
989 				break;
990 		}
991 
992 		right=MAX(left, right);
993 		bottom=MAX(top, bottom);
994 
995 		boxIcon=clutter_actor_box_new(floor(left), floor(top), floor(right), floor(bottom));
996 		clutter_actor_allocate(CLUTTER_ACTOR(priv->actorIcon), boxIcon, inFlags);
997 	}
998 
999 	/* Release allocated memory */
1000 	if(boxLabel) clutter_actor_box_free(boxLabel);
1001 	if(boxIcon) clutter_actor_box_free(boxIcon);
1002 }
1003 
1004 /* Destroy this actor */
_xfdashboard_label_destroy(ClutterActor * self)1005 static void _xfdashboard_label_destroy(ClutterActor *self)
1006 {
1007 	/* Destroy each child actor when this actor is destroyed */
1008 	XfdashboardLabelPrivate		*priv=XFDASHBOARD_LABEL(self)->priv;
1009 
1010 	if(priv->actorIcon)
1011 	{
1012 		clutter_actor_destroy(CLUTTER_ACTOR(priv->actorIcon));
1013 		priv->actorIcon=NULL;
1014 	}
1015 
1016 	if(priv->actorLabel)
1017 	{
1018 		clutter_actor_destroy(CLUTTER_ACTOR(priv->actorLabel));
1019 		priv->actorLabel=NULL;
1020 	}
1021 
1022 	/* Call parent's class destroy method */
1023 	CLUTTER_ACTOR_CLASS(xfdashboard_label_parent_class)->destroy(self);
1024 }
1025 
1026 /* IMPLEMENTATION: GObject */
1027 
1028 /* Dispose this object */
_xfdashboard_label_dispose(GObject * inObject)1029 static void _xfdashboard_label_dispose(GObject *inObject)
1030 {
1031 	/* Release our allocated variables */
1032 	XfdashboardLabel			*self=XFDASHBOARD_LABEL(inObject);
1033 	XfdashboardLabelPrivate		*priv=self->priv;
1034 
1035 	if(priv->iconName)
1036 	{
1037 		g_free(priv->iconName);
1038 		priv->iconName=NULL;
1039 	}
1040 
1041 	if(priv->iconGIcon)
1042 	{
1043 		g_object_unref(priv->iconGIcon);
1044 		priv->iconGIcon=NULL;
1045 	}
1046 
1047 	if(priv->iconImage)
1048 	{
1049 		g_object_unref(priv->iconImage);
1050 		priv->iconImage=NULL;
1051 	}
1052 
1053 	if(priv->font)
1054 	{
1055 		g_free(priv->font);
1056 		priv->font=NULL;
1057 	}
1058 
1059 	if(priv->labelColor)
1060 	{
1061 		clutter_color_free(priv->labelColor);
1062 		priv->labelColor=NULL;
1063 	}
1064 
1065 	/* Call parent's class dispose method */
1066 	G_OBJECT_CLASS(xfdashboard_label_parent_class)->dispose(inObject);
1067 }
1068 
1069 /* Set/get properties */
_xfdashboard_label_set_property(GObject * inObject,guint inPropID,const GValue * inValue,GParamSpec * inSpec)1070 static void _xfdashboard_label_set_property(GObject *inObject,
1071 												guint inPropID,
1072 												const GValue *inValue,
1073 												GParamSpec *inSpec)
1074 {
1075 	XfdashboardLabel			*self=XFDASHBOARD_LABEL(inObject);
1076 
1077 	switch(inPropID)
1078 	{
1079 		case PROP_PADDING:
1080 			xfdashboard_label_set_padding(self, g_value_get_float(inValue));
1081 			break;
1082 
1083 		case PROP_SPACING:
1084 			xfdashboard_label_set_spacing(self, g_value_get_float(inValue));
1085 			break;
1086 
1087 		case PROP_STYLE:
1088 			xfdashboard_label_set_style(self, g_value_get_enum(inValue));
1089 			break;
1090 
1091 		case PROP_ICON_NAME:
1092 			xfdashboard_label_set_icon_name(self, g_value_get_string(inValue));
1093 			break;
1094 
1095 		case PROP_ICON_GICON:
1096 			xfdashboard_label_set_gicon(self, G_ICON(g_value_get_object(inValue)));
1097 			break;
1098 
1099 		case PROP_ICON_IMAGE:
1100 			xfdashboard_label_set_icon_image(self, g_value_get_object(inValue));
1101 			break;
1102 
1103 		case PROP_ICON_SYNC_SIZE:
1104 			xfdashboard_label_set_sync_icon_size(self, g_value_get_boolean(inValue));
1105 			break;
1106 
1107 		case PROP_ICON_SIZE:
1108 			xfdashboard_label_set_icon_size(self, g_value_get_uint(inValue));
1109 			break;
1110 
1111 		case PROP_ICON_ORIENTATION:
1112 			xfdashboard_label_set_icon_orientation(self, g_value_get_enum(inValue));
1113 			break;
1114 
1115 		case PROP_TEXT:
1116 			xfdashboard_label_set_text(self, g_value_get_string(inValue));
1117 			break;
1118 
1119 		case PROP_TEXT_FONT:
1120 			xfdashboard_label_set_font(self, g_value_get_string(inValue));
1121 			break;
1122 
1123 		case PROP_TEXT_COLOR:
1124 			xfdashboard_label_set_color(self, clutter_value_get_color(inValue));
1125 			break;
1126 
1127 		case PROP_TEXT_ELLIPSIZE_MODE:
1128 			xfdashboard_label_set_ellipsize_mode(self, g_value_get_enum(inValue));
1129 			break;
1130 
1131 		case PROP_TEXT_SINGLE_LINE:
1132 			xfdashboard_label_set_single_line_mode(self, g_value_get_boolean(inValue));
1133 			break;
1134 
1135 		case PROP_TEXT_JUSTIFY:
1136 			xfdashboard_label_set_text_justification(self, g_value_get_enum(inValue));
1137 			break;
1138 
1139 		default:
1140 			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
1141 			break;
1142 	}
1143 }
1144 
_xfdashboard_label_get_property(GObject * inObject,guint inPropID,GValue * outValue,GParamSpec * inSpec)1145 static void _xfdashboard_label_get_property(GObject *inObject,
1146 												guint inPropID,
1147 												GValue *outValue,
1148 												GParamSpec *inSpec)
1149 {
1150 	XfdashboardLabel			*self=XFDASHBOARD_LABEL(inObject);
1151 	XfdashboardLabelPrivate		*priv=self->priv;
1152 
1153 	switch(inPropID)
1154 	{
1155 		case PROP_PADDING:
1156 			g_value_set_float(outValue, priv->padding);
1157 			break;
1158 
1159 		case PROP_SPACING:
1160 			g_value_set_float(outValue, priv->spacing);
1161 			break;
1162 
1163 		case PROP_STYLE:
1164 			g_value_set_enum(outValue, priv->style);
1165 			break;
1166 
1167 		case PROP_ICON_NAME:
1168 			g_value_set_string(outValue, priv->iconName);
1169 			break;
1170 
1171 		case PROP_ICON_GICON:
1172 			g_value_set_object(outValue, priv->iconGIcon);
1173 			break;
1174 
1175 		case PROP_ICON_IMAGE:
1176 			g_value_set_object(outValue, priv->iconImage);
1177 			break;
1178 
1179 		case PROP_ICON_SYNC_SIZE:
1180 			g_value_set_boolean(outValue, priv->iconSyncSize);
1181 			break;
1182 
1183 		case PROP_ICON_SIZE:
1184 			g_value_set_uint(outValue, priv->iconSize);
1185 			break;
1186 
1187 		case PROP_ICON_ORIENTATION:
1188 			g_value_set_enum(outValue, priv->iconOrientation);
1189 			break;
1190 
1191 		case PROP_TEXT:
1192 			g_value_set_string(outValue, clutter_text_get_text(CLUTTER_TEXT(priv->actorLabel)));
1193 			break;
1194 
1195 		case PROP_TEXT_FONT:
1196 			g_value_set_string(outValue, priv->font);
1197 			break;
1198 
1199 		case PROP_TEXT_COLOR:
1200 			clutter_value_set_color(outValue, priv->labelColor);
1201 			break;
1202 
1203 		case PROP_TEXT_ELLIPSIZE_MODE:
1204 			g_value_set_enum(outValue, priv->labelEllipsize);
1205 			break;
1206 
1207 		case PROP_TEXT_SINGLE_LINE:
1208 			g_value_set_boolean(outValue, priv->isSingleLineMode);
1209 			break;
1210 
1211 		case PROP_TEXT_JUSTIFY:
1212 			g_value_set_enum(outValue, priv->textJustification);
1213 			break;
1214 
1215 		default:
1216 			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
1217 			break;
1218 	}
1219 }
1220 
1221 /* Class initialization
1222  * Override functions in parent classes and define properties
1223  * and signals
1224  */
xfdashboard_label_class_init(XfdashboardLabelClass * klass)1225 static void xfdashboard_label_class_init(XfdashboardLabelClass *klass)
1226 {
1227 	XfdashboardActorClass	*actorClass=XFDASHBOARD_ACTOR_CLASS(klass);
1228 	ClutterActorClass		*clutterActorClass=CLUTTER_ACTOR_CLASS(klass);
1229 	GObjectClass			*gobjectClass=G_OBJECT_CLASS(klass);
1230 
1231 	/* Override functions */
1232 	gobjectClass->dispose=_xfdashboard_label_dispose;
1233 	gobjectClass->set_property=_xfdashboard_label_set_property;
1234 	gobjectClass->get_property=_xfdashboard_label_get_property;
1235 
1236 	clutterActorClass->show_all=_xfdashboard_label_show_all;
1237 	clutterActorClass->hide_all=_xfdashboard_label_hide_all;
1238 	clutterActorClass->get_preferred_width=_xfdashboard_label_get_preferred_width;
1239 	clutterActorClass->get_preferred_height=_xfdashboard_label_get_preferred_height;
1240 	clutterActorClass->allocate=_xfdashboard_label_allocate;
1241 	clutterActorClass->destroy=_xfdashboard_label_destroy;
1242 
1243 	/* Define properties */
1244 	XfdashboardLabelProperties[PROP_PADDING]=
1245 		g_param_spec_float("padding",
1246 							"Padding",
1247 							"Padding between background and elements",
1248 							0.0f, G_MAXFLOAT,
1249 							4.0f,
1250 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1251 
1252 	XfdashboardLabelProperties[PROP_SPACING]=
1253 		g_param_spec_float("spacing",
1254 							"Spacing",
1255 							"Spacing between text and icon",
1256 							0.0f, G_MAXFLOAT,
1257 							4.0f,
1258 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1259 
1260 	XfdashboardLabelProperties[PROP_STYLE]=
1261 		g_param_spec_enum("label-style",
1262 							"Label style",
1263 							"Style of button showing text and/or icon",
1264 							XFDASHBOARD_TYPE_LABEL_STYLE,
1265 							XFDASHBOARD_LABEL_STYLE_TEXT,
1266 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1267 
1268 	XfdashboardLabelProperties[PROP_ICON_NAME]=
1269 		g_param_spec_string("icon-name",
1270 							"Icon name",
1271 							"Themed icon name or file name of icon",
1272 							N_(""),
1273 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1274 
1275 	XfdashboardLabelProperties[PROP_ICON_GICON]=
1276 		g_param_spec_object("icon-gicon",
1277 							"Icon GIcon",
1278 							"The GIcon of icon",
1279 							G_TYPE_ICON,
1280 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1281 
1282 	XfdashboardLabelProperties[PROP_ICON_IMAGE]=
1283 		g_param_spec_object("icon-image",
1284 							"Icon image",
1285 							"Image of icon",
1286 							CLUTTER_TYPE_IMAGE,
1287 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1288 
1289 	XfdashboardLabelProperties[PROP_ICON_SYNC_SIZE]=
1290 		g_param_spec_boolean("sync-icon-size",
1291 								"Synchronize icon size",
1292 								"Synchronize icon size with text size",
1293 								TRUE,
1294 								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1295 
1296 	XfdashboardLabelProperties[PROP_ICON_SIZE]=
1297 		g_param_spec_uint("icon-size",
1298 							"Icon size",
1299 							"Size of icon if size of icon is not synchronized. -1 is valid for icon images and sets icon image's default size.",
1300 							1, G_MAXUINT,
1301 							16,
1302 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1303 
1304 	XfdashboardLabelProperties[PROP_ICON_ORIENTATION]=
1305 		g_param_spec_enum("icon-orientation",
1306 							"Icon orientation",
1307 							"Orientation of icon to label",
1308 							XFDASHBOARD_TYPE_ORIENTATION,
1309 							XFDASHBOARD_ORIENTATION_LEFT,
1310 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1311 
1312 	XfdashboardLabelProperties[PROP_TEXT]=
1313 		g_param_spec_string("text",
1314 							"Label text",
1315 							"Text of label",
1316 							N_(""),
1317 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1318 
1319 	XfdashboardLabelProperties[PROP_TEXT_FONT]=
1320 		g_param_spec_string("font",
1321 							"Font",
1322 							"Font of label",
1323 							NULL,
1324 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1325 
1326 	XfdashboardLabelProperties[PROP_TEXT_COLOR]=
1327 		clutter_param_spec_color("color",
1328 									"Color",
1329 									"Color of label",
1330 									NULL,
1331 									G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1332 
1333 	XfdashboardLabelProperties[PROP_TEXT_ELLIPSIZE_MODE]=
1334 		g_param_spec_enum("ellipsize-mode",
1335 							"Ellipsize mode",
1336 							"Mode of ellipsize if text in label is too long",
1337 							PANGO_TYPE_ELLIPSIZE_MODE,
1338 							PANGO_ELLIPSIZE_MIDDLE,
1339 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1340 
1341 	XfdashboardLabelProperties[PROP_TEXT_SINGLE_LINE]=
1342 		g_param_spec_boolean("single-line",
1343 								"Single line",
1344 								"Flag to determine if text can only be in one or multiple lines",
1345 								TRUE,
1346 								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1347 
1348 	XfdashboardLabelProperties[PROP_TEXT_JUSTIFY]=
1349 		g_param_spec_enum("text-justify",
1350 							"Text justify",
1351 							"Justification (line alignment) of label",
1352 							PANGO_TYPE_ALIGNMENT,
1353 							PANGO_ALIGN_LEFT,
1354 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1355 
1356 	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardLabelProperties);
1357 
1358 	/* Define stylable properties */
1359 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_PADDING]);
1360 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_SPACING]);
1361 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_STYLE]);
1362 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_ICON_NAME]);
1363 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_ICON_IMAGE]);
1364 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_ICON_SYNC_SIZE]);
1365 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_ICON_SIZE]);
1366 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_ICON_ORIENTATION]);
1367 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_TEXT]);
1368 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_TEXT_FONT]);
1369 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_TEXT_COLOR]);
1370 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_TEXT_ELLIPSIZE_MODE]);
1371 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_TEXT_SINGLE_LINE]);
1372 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLabelProperties[PROP_TEXT_JUSTIFY]);
1373 }
1374 
1375 /* Object initialization
1376  * Create private structure and set up default values
1377  */
xfdashboard_label_init(XfdashboardLabel * self)1378 static void xfdashboard_label_init(XfdashboardLabel *self)
1379 {
1380 	XfdashboardLabelPrivate	*priv;
1381 
1382 	priv=self->priv=xfdashboard_label_get_instance_private(self);
1383 
1384 	/* This actor reacts on events */
1385 	clutter_actor_set_reactive(CLUTTER_ACTOR(self), TRUE);
1386 
1387 	/* Set up default values */
1388 	priv->padding=0.0f;
1389 	priv->spacing=0.0f;
1390 	priv->style=-1;
1391 	priv->iconName=NULL;
1392 	priv->iconImage=NULL;
1393 	priv->iconSyncSize=TRUE;
1394 	priv->iconSize=16;
1395 	priv->iconOrientation=-1;
1396 	priv->font=NULL;
1397 	priv->labelColor=NULL;
1398 	priv->labelEllipsize=-1;
1399 	priv->isSingleLineMode=TRUE;
1400 	priv->iconType=XFDASHBOARD_LABEL_ICON_TYPE_ICON_NONE;
1401 
1402 	/* Create actors */
1403 	priv->actorIcon=clutter_actor_new();
1404 	clutter_actor_add_child(CLUTTER_ACTOR(self), priv->actorIcon);
1405 	clutter_actor_set_reactive(priv->actorIcon, FALSE);
1406 
1407 	priv->actorLabel=clutter_text_new();
1408 	clutter_actor_add_child(CLUTTER_ACTOR(self), priv->actorLabel);
1409 	clutter_actor_set_reactive(CLUTTER_ACTOR(priv->actorLabel), FALSE);
1410 	clutter_text_set_selectable(CLUTTER_TEXT(priv->actorLabel), FALSE);
1411 	clutter_text_set_line_wrap(CLUTTER_TEXT(priv->actorLabel), TRUE);
1412 	clutter_text_set_single_line_mode(CLUTTER_TEXT(priv->actorLabel), priv->isSingleLineMode);
1413 }
1414 
1415 /* IMPLEMENTATION: Public API */
1416 
1417 /* Create new actor */
xfdashboard_label_new(void)1418 ClutterActor* xfdashboard_label_new(void)
1419 {
1420 	return(g_object_new(XFDASHBOARD_TYPE_LABEL,
1421 						"text", N_(""),
1422 						"label-style", XFDASHBOARD_LABEL_STYLE_TEXT,
1423 						NULL));
1424 }
1425 
xfdashboard_label_new_with_text(const gchar * inText)1426 ClutterActor* xfdashboard_label_new_with_text(const gchar *inText)
1427 {
1428 	return(g_object_new(XFDASHBOARD_TYPE_LABEL,
1429 						"text", inText,
1430 						"label-style", XFDASHBOARD_LABEL_STYLE_TEXT,
1431 						NULL));
1432 }
1433 
xfdashboard_label_new_with_icon_name(const gchar * inIconName)1434 ClutterActor* xfdashboard_label_new_with_icon_name(const gchar *inIconName)
1435 {
1436 	return(g_object_new(XFDASHBOARD_TYPE_LABEL,
1437 						"icon-name", inIconName,
1438 						"label-style", XFDASHBOARD_LABEL_STYLE_ICON,
1439 						NULL));
1440 }
1441 
xfdashboard_label_new_with_gicon(GIcon * inIcon)1442 ClutterActor* xfdashboard_label_new_with_gicon(GIcon *inIcon)
1443 {
1444 	return(g_object_new(XFDASHBOARD_TYPE_LABEL,
1445 						"icon-gicon", inIcon,
1446 						"label-style", XFDASHBOARD_LABEL_STYLE_ICON,
1447 						NULL));
1448 }
1449 
xfdashboard_label_new_full_with_icon_name(const gchar * inIconName,const gchar * inText)1450 ClutterActor* xfdashboard_label_new_full_with_icon_name(const gchar *inIconName, const gchar *inText)
1451 {
1452 	return(g_object_new(XFDASHBOARD_TYPE_LABEL,
1453 						"text", inText,
1454 						"icon-name", inIconName,
1455 						"label-style", XFDASHBOARD_LABEL_STYLE_BOTH,
1456 						NULL));
1457 }
1458 
xfdashboard_label_new_full_with_gicon(GIcon * inIcon,const gchar * inText)1459 ClutterActor* xfdashboard_label_new_full_with_gicon(GIcon *inIcon, const gchar *inText)
1460 {
1461 	return(g_object_new(XFDASHBOARD_TYPE_LABEL,
1462 						"text", inText,
1463 						"icon-gicon", inIcon,
1464 						"label-style", XFDASHBOARD_LABEL_STYLE_BOTH,
1465 						NULL));
1466 }
1467 
1468 /* Get/set padding of background to text and icon actors */
xfdashboard_label_get_padding(XfdashboardLabel * self)1469 gfloat xfdashboard_label_get_padding(XfdashboardLabel *self)
1470 {
1471 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), 0);
1472 
1473 	return(self->priv->padding);
1474 }
1475 
xfdashboard_label_set_padding(XfdashboardLabel * self,const gfloat inPadding)1476 void xfdashboard_label_set_padding(XfdashboardLabel *self, const gfloat inPadding)
1477 {
1478 	XfdashboardLabelPrivate		*priv;
1479 
1480 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1481 	g_return_if_fail(inPadding>=0.0f);
1482 
1483 	priv=self->priv;
1484 
1485 	/* Set value if changed */
1486 	if(priv->padding!=inPadding)
1487 	{
1488 		/* Set value */
1489 		priv->padding=inPadding;
1490 		clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
1491 
1492 		/* Update actor */
1493 		xfdashboard_background_set_corner_radius(XFDASHBOARD_BACKGROUND(self), priv->padding);
1494 
1495 		/* Notify about property change */
1496 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_PADDING]);
1497 	}
1498 }
1499 
1500 /* Get/set spacing between text and icon actors */
xfdashboard_label_get_spacing(XfdashboardLabel * self)1501 gfloat xfdashboard_label_get_spacing(XfdashboardLabel *self)
1502 {
1503 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), 0);
1504 
1505 	return(self->priv->spacing);
1506 }
1507 
xfdashboard_label_set_spacing(XfdashboardLabel * self,const gfloat inSpacing)1508 void xfdashboard_label_set_spacing(XfdashboardLabel *self, const gfloat inSpacing)
1509 {
1510 	XfdashboardLabelPrivate		*priv;
1511 
1512 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1513 	g_return_if_fail(inSpacing>=0.0f);
1514 
1515 	priv=self->priv;
1516 
1517 	/* Set value if changed */
1518 	if(priv->spacing!=inSpacing)
1519 	{
1520 		/* Set value */
1521 		priv->spacing=inSpacing;
1522 		clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
1523 
1524 		/* Notify about property change */
1525 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_SPACING]);
1526 	}
1527 }
1528 
1529 /* Get/set style of button */
xfdashboard_label_get_style(XfdashboardLabel * self)1530 XfdashboardLabelStyle xfdashboard_label_get_style(XfdashboardLabel *self)
1531 {
1532 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), XFDASHBOARD_LABEL_STYLE_TEXT);
1533 
1534 	return(self->priv->style);
1535 }
1536 
xfdashboard_label_set_style(XfdashboardLabel * self,const XfdashboardLabelStyle inStyle)1537 void xfdashboard_label_set_style(XfdashboardLabel *self, const XfdashboardLabelStyle inStyle)
1538 {
1539 	XfdashboardLabelPrivate		*priv;
1540 
1541 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1542 
1543 	priv=self->priv;
1544 
1545 	/* Set value if changed */
1546 	if(priv->style!=inStyle)
1547 	{
1548 		/* Set value */
1549 		priv->style=inStyle;
1550 
1551 		/* Show actors depending on style */
1552 		if(priv->style==XFDASHBOARD_LABEL_STYLE_TEXT ||
1553 			priv->style==XFDASHBOARD_LABEL_STYLE_BOTH)
1554 		{
1555 			clutter_actor_show(CLUTTER_ACTOR(priv->actorLabel));
1556 		}
1557 			else clutter_actor_hide(CLUTTER_ACTOR(priv->actorLabel));
1558 
1559 		if(priv->style==XFDASHBOARD_LABEL_STYLE_ICON ||
1560 			priv->style==XFDASHBOARD_LABEL_STYLE_BOTH)
1561 		{
1562 			clutter_actor_show(CLUTTER_ACTOR(priv->actorIcon));
1563 		}
1564 			else clutter_actor_hide(CLUTTER_ACTOR(priv->actorIcon));
1565 
1566 		clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
1567 
1568 		/* Notify about property change */
1569 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_STYLE]);
1570 	}
1571 }
1572 
1573 /* Get/set icon */
xfdashboard_label_get_icon_name(XfdashboardLabel * self)1574 const gchar* xfdashboard_label_get_icon_name(XfdashboardLabel *self)
1575 {
1576 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), NULL);
1577 
1578 	return(self->priv->iconName);
1579 }
1580 
xfdashboard_label_set_icon_name(XfdashboardLabel * self,const gchar * inIconName)1581 void xfdashboard_label_set_icon_name(XfdashboardLabel *self, const gchar *inIconName)
1582 {
1583 	XfdashboardLabelPrivate		*priv;
1584 	ClutterContent				*image;
1585 
1586 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1587 	g_return_if_fail(inIconName);
1588 
1589 	priv=self->priv;
1590 
1591 	/* Set value if changed */
1592 	if(priv->iconType!=XFDASHBOARD_LABEL_ICON_TYPE_ICON_NAME ||
1593 		g_strcmp0(priv->iconName, inIconName)!=0)
1594 	{
1595 		/* Release old values and icons */
1596 		if(priv->iconName)
1597 		{
1598 			g_free(priv->iconName);
1599 			priv->iconName=NULL;
1600 		}
1601 
1602 		if(priv->iconGIcon)
1603 		{
1604 			g_object_unref(priv->iconGIcon);
1605 			priv->iconGIcon=NULL;
1606 		}
1607 
1608 		if(priv->iconImage)
1609 		{
1610 			g_object_unref(priv->iconImage);
1611 			priv->iconImage=NULL;
1612 		}
1613 
1614 		/* Set value */
1615 		priv->iconName=g_strdup(inIconName);
1616 		priv->iconType=XFDASHBOARD_LABEL_ICON_TYPE_ICON_NAME;
1617 
1618 		/* Setup icon image */
1619 		image=xfdashboard_image_content_new_for_icon_name(priv->iconName, priv->iconSize);
1620 		clutter_actor_set_content(priv->actorIcon, image);
1621 		g_object_unref(image);
1622 
1623 		_xfdashboard_label_update_icon_image_size(self);
1624 
1625 		/* Notify about property change */
1626 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_ICON_NAME]);
1627 	}
1628 }
1629 
xfdashboard_label_get_gicon(XfdashboardLabel * self)1630 GIcon* xfdashboard_label_get_gicon(XfdashboardLabel *self)
1631 {
1632 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), NULL);
1633 
1634 	return(self->priv->iconGIcon);
1635 }
1636 
xfdashboard_label_set_gicon(XfdashboardLabel * self,GIcon * inIcon)1637 void xfdashboard_label_set_gicon(XfdashboardLabel *self, GIcon *inIcon)
1638 {
1639 	XfdashboardLabelPrivate		*priv;
1640 	ClutterContent				*image;
1641 
1642 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1643 	g_return_if_fail(G_IS_ICON(inIcon));
1644 
1645 	priv=self->priv;
1646 
1647 	/* Set value if changed */
1648 	if(priv->iconType!=XFDASHBOARD_LABEL_ICON_TYPE_ICON_GICON ||
1649 		!g_icon_equal(priv->iconGIcon, inIcon))
1650 	{
1651 		/* Release old values and icons */
1652 		if(priv->iconName)
1653 		{
1654 			g_free(priv->iconName);
1655 			priv->iconName=NULL;
1656 		}
1657 
1658 		if(priv->iconGIcon)
1659 		{
1660 			g_object_unref(priv->iconGIcon);
1661 			priv->iconGIcon=NULL;
1662 		}
1663 
1664 		if(priv->iconImage)
1665 		{
1666 			g_object_unref(priv->iconImage);
1667 			priv->iconImage=NULL;
1668 		}
1669 
1670 		/* Set value */
1671 		priv->iconGIcon=G_ICON(g_object_ref(inIcon));
1672 		priv->iconType=XFDASHBOARD_LABEL_ICON_TYPE_ICON_GICON;
1673 
1674 		/* Setup icon image */
1675 		image=xfdashboard_image_content_new_for_gicon(priv->iconGIcon, priv->iconSize);
1676 		clutter_actor_set_content(priv->actorIcon, image);
1677 		g_object_unref(image);
1678 
1679 		_xfdashboard_label_update_icon_image_size(self);
1680 
1681 		/* Notify about property change */
1682 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_ICON_GICON]);
1683 	}
1684 }
1685 
xfdashboard_label_get_icon_image(XfdashboardLabel * self)1686 ClutterImage* xfdashboard_label_get_icon_image(XfdashboardLabel *self)
1687 {
1688 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), NULL);
1689 
1690 	return(self->priv->iconImage);
1691 }
1692 
xfdashboard_label_set_icon_image(XfdashboardLabel * self,ClutterImage * inIconImage)1693 void xfdashboard_label_set_icon_image(XfdashboardLabel *self, ClutterImage *inIconImage)
1694 {
1695 	XfdashboardLabelPrivate		*priv;
1696 
1697 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1698 	g_return_if_fail(CLUTTER_IS_IMAGE(inIconImage));
1699 
1700 	priv=self->priv;
1701 
1702 	/* Set value if changed */
1703 	if(priv->iconType!=XFDASHBOARD_LABEL_ICON_TYPE_ICON_IMAGE ||
1704 		inIconImage!=priv->iconImage)
1705 	{
1706 		/* Release old values and icons */
1707 		if(priv->iconName)
1708 		{
1709 			g_free(priv->iconName);
1710 			priv->iconName=NULL;
1711 		}
1712 
1713 		if(priv->iconGIcon)
1714 		{
1715 			g_object_unref(priv->iconGIcon);
1716 			priv->iconGIcon=NULL;
1717 		}
1718 
1719 		if(priv->iconImage)
1720 		{
1721 			g_object_unref(priv->iconImage);
1722 			priv->iconImage=NULL;
1723 		}
1724 
1725 		/* Set value */
1726 		priv->iconImage=g_object_ref(inIconImage);
1727 		priv->iconType=XFDASHBOARD_LABEL_ICON_TYPE_ICON_IMAGE;
1728 
1729 		/* Setup icon image */
1730 		clutter_actor_set_content(priv->actorIcon, CLUTTER_CONTENT(priv->iconImage));
1731 
1732 		_xfdashboard_label_update_icon_image_size(self);
1733 
1734 		/* Notify about property change */
1735 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_ICON_IMAGE]);
1736 	}
1737 }
1738 
1739 /* Get/set size of icon */
xfdashboard_label_get_icon_size(XfdashboardLabel * self)1740 gint xfdashboard_label_get_icon_size(XfdashboardLabel *self)
1741 {
1742 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), 0);
1743 
1744 	return(self->priv->iconSize);
1745 }
1746 
xfdashboard_label_set_icon_size(XfdashboardLabel * self,gint inSize)1747 void xfdashboard_label_set_icon_size(XfdashboardLabel *self, gint inSize)
1748 {
1749 	XfdashboardLabelPrivate		*priv;
1750 
1751 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1752 	g_return_if_fail(inSize==-1 || inSize>0);
1753 
1754 	priv=self->priv;
1755 
1756 	/* Set value if changed */
1757 	if(priv->iconSize!=inSize)
1758 	{
1759 		/* Set value */
1760 		priv->iconSize=inSize;
1761 
1762 		/* Setup icon image */
1763 		if(priv->iconType==XFDASHBOARD_LABEL_ICON_TYPE_ICON_NAME)
1764 		{
1765 			ClutterContent		*image;
1766 
1767 			image=xfdashboard_image_content_new_for_icon_name(priv->iconName, priv->iconSize);
1768 			clutter_actor_set_content(priv->actorIcon, image);
1769 			g_object_unref(image);
1770 		}
1771 
1772 		if(priv->iconType==XFDASHBOARD_LABEL_ICON_TYPE_ICON_GICON)
1773 		{
1774 			ClutterContent		*image;
1775 
1776 			image=xfdashboard_image_content_new_for_gicon(priv->iconGIcon, priv->iconSize);
1777 			clutter_actor_set_content(priv->actorIcon, image);
1778 			g_object_unref(image);
1779 		}
1780 
1781 		_xfdashboard_label_update_icon_image_size(self);
1782 
1783 		/* Notify about property change */
1784 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_ICON_SIZE]);
1785 	}
1786 }
1787 
1788 /* Get/set state if icon size will be synchronized */
xfdashboard_label_get_sync_icon_size(XfdashboardLabel * self)1789 gboolean xfdashboard_label_get_sync_icon_size(XfdashboardLabel *self)
1790 {
1791 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), FALSE);
1792 
1793 	return(self->priv->iconSyncSize);
1794 }
1795 
xfdashboard_label_set_sync_icon_size(XfdashboardLabel * self,gboolean inSync)1796 void xfdashboard_label_set_sync_icon_size(XfdashboardLabel *self, gboolean inSync)
1797 {
1798 	XfdashboardLabelPrivate		*priv;
1799 
1800 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1801 
1802 	priv=self->priv;
1803 
1804 	/* Set value if changed */
1805 	if(priv->iconSyncSize!=inSync)
1806 	{
1807 		/* Set value */
1808 		priv->iconSyncSize=inSync;
1809 
1810 		_xfdashboard_label_update_icon_image_size(self);
1811 
1812 		/* Notify about property change */
1813 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_ICON_SYNC_SIZE]);
1814 	}
1815 }
1816 
1817 /* Get/set orientation of icon to label */
xfdashboard_label_get_icon_orientation(XfdashboardLabel * self)1818 XfdashboardOrientation xfdashboard_label_get_icon_orientation(XfdashboardLabel *self)
1819 {
1820 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), XFDASHBOARD_ORIENTATION_LEFT);
1821 
1822 	return(self->priv->iconOrientation);
1823 }
1824 
xfdashboard_label_set_icon_orientation(XfdashboardLabel * self,const XfdashboardOrientation inOrientation)1825 void xfdashboard_label_set_icon_orientation(XfdashboardLabel *self, const XfdashboardOrientation inOrientation)
1826 {
1827 	XfdashboardLabelPrivate		*priv;
1828 
1829 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1830 
1831 	priv=self->priv;
1832 
1833 	/* Set value if changed */
1834 	if(priv->iconOrientation!=inOrientation)
1835 	{
1836 		/* Set value */
1837 		priv->iconOrientation=inOrientation;
1838 
1839 		clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
1840 
1841 		/* Notify about property change */
1842 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_ICON_ORIENTATION]);
1843 	}
1844 }
1845 
1846 /* Get/set text of label */
xfdashboard_label_get_text(XfdashboardLabel * self)1847 const gchar* xfdashboard_label_get_text(XfdashboardLabel *self)
1848 {
1849 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), NULL);
1850 
1851 	return(clutter_text_get_text(CLUTTER_TEXT(self->priv->actorLabel)));
1852 }
1853 
xfdashboard_label_set_text(XfdashboardLabel * self,const gchar * inMarkupText)1854 void xfdashboard_label_set_text(XfdashboardLabel *self, const gchar *inMarkupText)
1855 {
1856 	XfdashboardLabelPrivate		*priv;
1857 
1858 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1859 
1860 	priv=self->priv;
1861 
1862 	/* Set value if changed */
1863 	if(g_strcmp0(clutter_text_get_text(CLUTTER_TEXT(priv->actorLabel)), inMarkupText)!=0)
1864 	{
1865 		/* Set value */
1866 		clutter_text_set_markup(CLUTTER_TEXT(priv->actorLabel), inMarkupText);
1867 		clutter_actor_queue_relayout(CLUTTER_ACTOR(priv->actorLabel));
1868 
1869 		/* Notify about property change */
1870 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_TEXT]);
1871 	}
1872 }
1873 
1874 /* Get/set font of label */
xfdashboard_label_get_font(XfdashboardLabel * self)1875 const gchar* xfdashboard_label_get_font(XfdashboardLabel *self)
1876 {
1877 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), NULL);
1878 
1879 	if(self->priv->actorLabel) return(self->priv->font);
1880 	return(NULL);
1881 }
1882 
xfdashboard_label_set_font(XfdashboardLabel * self,const gchar * inFont)1883 void xfdashboard_label_set_font(XfdashboardLabel *self, const gchar *inFont)
1884 {
1885 	XfdashboardLabelPrivate		*priv;
1886 
1887 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1888 
1889 	priv=self->priv;
1890 
1891 	/* Set value if changed */
1892 	if(g_strcmp0(priv->font, inFont)!=0)
1893 	{
1894 		/* Set value */
1895 		if(priv->font) g_free(priv->font);
1896 		priv->font=(inFont ? g_strdup(inFont) : NULL);
1897 
1898 		clutter_text_set_font_name(CLUTTER_TEXT(priv->actorLabel), priv->font);
1899 		clutter_actor_queue_redraw(CLUTTER_ACTOR(self));
1900 
1901 		/* Notify about property change */
1902 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_TEXT_FONT]);
1903 	}
1904 }
1905 
1906 /* Get/set color of text in label */
xfdashboard_label_get_color(XfdashboardLabel * self)1907 const ClutterColor* xfdashboard_label_get_color(XfdashboardLabel *self)
1908 {
1909 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), NULL);
1910 
1911 	return(self->priv->labelColor);
1912 }
1913 
xfdashboard_label_set_color(XfdashboardLabel * self,const ClutterColor * inColor)1914 void xfdashboard_label_set_color(XfdashboardLabel *self, const ClutterColor *inColor)
1915 {
1916 	XfdashboardLabelPrivate		*priv;
1917 
1918 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1919 	g_return_if_fail(inColor);
1920 
1921 	priv=self->priv;
1922 
1923 	/* Set value if changed */
1924 	if(!priv->labelColor || !clutter_color_equal(inColor, priv->labelColor))
1925 	{
1926 		/* Set value */
1927 		if(priv->labelColor) clutter_color_free(priv->labelColor);
1928 		priv->labelColor=clutter_color_copy(inColor);
1929 
1930 		clutter_text_set_color(CLUTTER_TEXT(priv->actorLabel), priv->labelColor);
1931 		clutter_actor_queue_redraw(CLUTTER_ACTOR(self));
1932 
1933 		/* Notify about property change */
1934 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_TEXT_COLOR]);
1935 	}
1936 }
1937 
1938 /* Get/set ellipsize mode if label's text is getting too long */
xfdashboard_label_get_ellipsize_mode(XfdashboardLabel * self)1939 PangoEllipsizeMode xfdashboard_label_get_ellipsize_mode(XfdashboardLabel *self)
1940 {
1941 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), 0);
1942 
1943 	return(self->priv->labelEllipsize);
1944 }
1945 
xfdashboard_label_set_ellipsize_mode(XfdashboardLabel * self,const PangoEllipsizeMode inMode)1946 void xfdashboard_label_set_ellipsize_mode(XfdashboardLabel *self, const PangoEllipsizeMode inMode)
1947 {
1948 	XfdashboardLabelPrivate		*priv;
1949 
1950 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1951 
1952 	priv=self->priv;
1953 
1954 	/* Set value if changed */
1955 	if(priv->labelEllipsize!=inMode)
1956 	{
1957 		/* Set value */
1958 		priv->labelEllipsize=inMode;
1959 
1960 		clutter_text_set_ellipsize(CLUTTER_TEXT(priv->actorLabel), priv->labelEllipsize);
1961 		clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
1962 
1963 		/* Notify about property change */
1964 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_TEXT_ELLIPSIZE_MODE]);
1965 	}
1966 }
1967 
1968 /* Get/set single line mode */
xfdashboard_label_get_single_line_mode(XfdashboardLabel * self)1969 gboolean xfdashboard_label_get_single_line_mode(XfdashboardLabel *self)
1970 {
1971 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), FALSE);
1972 
1973 	return(self->priv->isSingleLineMode);
1974 }
1975 
xfdashboard_label_set_single_line_mode(XfdashboardLabel * self,const gboolean inSingleLineMode)1976 void xfdashboard_label_set_single_line_mode(XfdashboardLabel *self, const gboolean inSingleLineMode)
1977 {
1978 	XfdashboardLabelPrivate		*priv;
1979 
1980 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
1981 
1982 	priv=self->priv;
1983 
1984 	/* Set value if changed */
1985 	if(priv->isSingleLineMode!=inSingleLineMode)
1986 	{
1987 		/* Set value */
1988 		priv->isSingleLineMode=inSingleLineMode;
1989 
1990 		clutter_text_set_single_line_mode(CLUTTER_TEXT(priv->actorLabel), priv->isSingleLineMode);
1991 		clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
1992 
1993 		/* Notify about property change */
1994 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_TEXT_SINGLE_LINE]);
1995 	}
1996 }
1997 
1998 /* Get/set justification (line alignment) of label */
xfdashboard_label_get_text_justification(XfdashboardLabel * self)1999 PangoAlignment xfdashboard_label_get_text_justification(XfdashboardLabel *self)
2000 {
2001 	g_return_val_if_fail(XFDASHBOARD_IS_LABEL(self), PANGO_ALIGN_LEFT);
2002 
2003 	return(self->priv->textJustification);
2004 }
2005 
xfdashboard_label_set_text_justification(XfdashboardLabel * self,const PangoAlignment inJustification)2006 void xfdashboard_label_set_text_justification(XfdashboardLabel *self, const PangoAlignment inJustification)
2007 {
2008 	XfdashboardLabelPrivate		*priv;
2009 
2010 	g_return_if_fail(XFDASHBOARD_IS_LABEL(self));
2011 
2012 	priv=self->priv;
2013 
2014 	/* Set value if changed */
2015 	if(priv->textJustification!=inJustification)
2016 	{
2017 		/* Set value */
2018 		priv->textJustification=inJustification;
2019 
2020 		clutter_text_set_line_alignment(CLUTTER_TEXT(priv->actorLabel), priv->textJustification);
2021 		clutter_actor_queue_redraw(CLUTTER_ACTOR(self));
2022 
2023 		/* Notify about property change */
2024 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLabelProperties[PROP_TEXT_SINGLE_LINE]);
2025 	}
2026 }
2027