1 /*
2 * emblem-effect: Draws an emblem on top of an actor
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 #define COGL_ENABLE_EXPERIMENTAL_API
29 #define CLUTTER_ENABLE_EXPERIMENTAL_API
30
31 #include <libxfdashboard/emblem-effect.h>
32
33 #include <glib/gi18n-lib.h>
34 #include <math.h>
35 #include <cogl/cogl.h>
36
37 #include <libxfdashboard/image-content.h>
38 #include <libxfdashboard/enums.h>
39 #include <libxfdashboard/compat.h>
40 #include <libxfdashboard/debug.h>
41
42
43 /* Define this class in GObject system */
44 struct _XfdashboardEmblemEffectPrivate
45 {
46 /* Properties related */
47 gchar *iconName;
48 gint iconSize;
49 gfloat padding;
50 gfloat xAlign;
51 gfloat yAlign;
52 XfdashboardAnchorPoint anchorPoint;
53
54 /* Instance related */
55 ClutterContent *icon;
56 guint loadSuccessSignalID;
57 guint loadFailedSignalID;
58
59 CoglPipeline *pipeline;
60 };
61
62 G_DEFINE_TYPE_WITH_PRIVATE(XfdashboardEmblemEffect,
63 xfdashboard_emblem_effect,
64 CLUTTER_TYPE_EFFECT)
65
66 /* Properties */
67 enum
68 {
69 PROP_0,
70
71 PROP_ICON_NAME,
72 PROP_ICON_SIZE,
73 PROP_PADDING,
74 PROP_X_ALIGN,
75 PROP_Y_ALIGN,
76 PROP_ANCHOR_POINT,
77
78 PROP_LAST
79 };
80
81 static GParamSpec* XfdashboardEmblemEffectProperties[PROP_LAST]={ 0, };
82
83 /* IMPLEMENTATION: Private variables and methods */
84 static CoglPipeline *_xfdashboard_emblem_effect_base_pipeline=NULL;
85
86 /* Icon image was loaded */
_xfdashboard_emblem_effect_on_load_finished(XfdashboardEmblemEffect * self,gpointer inUserData)87 static void _xfdashboard_emblem_effect_on_load_finished(XfdashboardEmblemEffect *self, gpointer inUserData)
88 {
89 XfdashboardEmblemEffectPrivate *priv;
90
91 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
92
93 priv=self->priv;
94
95 /* Disconnect signal handlers */
96 if(priv->loadSuccessSignalID)
97 {
98 g_signal_handler_disconnect(priv->icon, priv->loadSuccessSignalID);
99 priv->loadSuccessSignalID=0;
100 }
101
102 if(priv->loadFailedSignalID)
103 {
104 g_signal_handler_disconnect(priv->icon, priv->loadFailedSignalID);
105 priv->loadFailedSignalID=0;
106 }
107
108 /* Set image at pipeline */
109 cogl_pipeline_set_layer_texture(priv->pipeline,
110 0,
111 clutter_image_get_texture(CLUTTER_IMAGE(priv->icon)));
112
113 /* Invalidate effect to get it redrawn */
114 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
115 }
116
117 /* IMPLEMENTATION: ClutterEffect */
118
119 /* Draw effect after actor was drawn */
_xfdashboard_emblem_effect_paint(ClutterEffect * inEffect,ClutterEffectPaintFlags inFlags)120 static void _xfdashboard_emblem_effect_paint(ClutterEffect *inEffect, ClutterEffectPaintFlags inFlags)
121 {
122 XfdashboardEmblemEffect *self;
123 XfdashboardEmblemEffectPrivate *priv;
124 ClutterActor *target;
125 gfloat actorWidth;
126 gfloat actorHeight;
127 ClutterActorBox actorBox;
128 ClutterActorBox rectangleBox;
129 XfdashboardImageContentLoadingState loadingState;
130 gfloat textureWidth;
131 gfloat textureHeight;
132 ClutterActorBox textureCoordBox;
133 gfloat offset;
134 gfloat oversize;
135 CoglFramebuffer *framebuffer;
136
137 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(inEffect));
138
139 self=XFDASHBOARD_EMBLEM_EFFECT(inEffect);
140 priv=self->priv;
141
142 /* Chain to the next item in the paint sequence */
143 target=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self));
144 clutter_actor_continue_paint(target);
145
146 /* If no icon name is set do not apply this effect */
147 if(!priv->iconName) return;
148
149 /* Load image if not done yet */
150 if(!priv->icon)
151 {
152 /* Get image from cache */
153 priv->icon=xfdashboard_image_content_new_for_icon_name(priv->iconName, priv->iconSize);
154
155 /* Ensure image is being loaded */
156 loadingState=xfdashboard_image_content_get_state(XFDASHBOARD_IMAGE_CONTENT(priv->icon));
157 if(loadingState==XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_NONE ||
158 loadingState==XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADING)
159 {
160 /* Connect signals just because we need to wait for image being loaded */
161 priv->loadSuccessSignalID=g_signal_connect_swapped(priv->icon,
162 "loaded",
163 G_CALLBACK(_xfdashboard_emblem_effect_on_load_finished),
164 self);
165 priv->loadFailedSignalID=g_signal_connect_swapped(priv->icon,
166 "loading-failed",
167 G_CALLBACK(_xfdashboard_emblem_effect_on_load_finished),
168 self);
169
170 /* If image is not being loaded currently enforce loading now */
171 if(loadingState==XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_NONE)
172 {
173 xfdashboard_image_content_force_load(XFDASHBOARD_IMAGE_CONTENT(priv->icon));
174 }
175 }
176 else
177 {
178 /* Image is already loaded so set image at pipeline */
179 cogl_pipeline_set_layer_texture(priv->pipeline,
180 0,
181 clutter_image_get_texture(CLUTTER_IMAGE(priv->icon)));
182 }
183 }
184
185 /* Get actor size and apply padding. If actor width or height will drop
186 * to zero or below then the emblem could not be drawn and we return here.
187 */
188 clutter_actor_get_content_box(target, &actorBox);
189 actorBox.x1+=priv->padding;
190 actorBox.x2-=priv->padding;
191 actorBox.y1+=priv->padding;
192 actorBox.y2-=priv->padding;
193
194 if(actorBox.x2<=actorBox.x1 ||
195 actorBox.y2<=actorBox.y1)
196 {
197 XFDASHBOARD_DEBUG(self, ACTOR,
198 "Will not draw emblem '%s' because width or height of actor is zero or below after padding was applied.",
199 priv->iconName);
200 return;
201 }
202
203 actorWidth=actorBox.x2-actorBox.x1;
204 actorHeight=actorBox.y2-actorBox.y1;
205
206 /* Get texture size */
207 clutter_content_get_preferred_size(CLUTTER_CONTENT(priv->icon), &textureWidth, &textureHeight);
208 clutter_actor_box_init(&textureCoordBox, 0.0f, 0.0f, 1.0f, 1.0f);
209
210 /* Get boundary in X axis depending on anchorPoint and scaled width */
211 offset=(priv->xAlign*actorWidth);
212 switch(priv->anchorPoint)
213 {
214 /* Align to left boundary.
215 * This is also the default if anchor point is none or undefined.
216 */
217 default:
218 case XFDASHBOARD_ANCHOR_POINT_NONE:
219 case XFDASHBOARD_ANCHOR_POINT_WEST:
220 case XFDASHBOARD_ANCHOR_POINT_NORTH_WEST:
221 case XFDASHBOARD_ANCHOR_POINT_SOUTH_WEST:
222 break;
223
224 /* Align to center of X axis */
225 case XFDASHBOARD_ANCHOR_POINT_CENTER:
226 case XFDASHBOARD_ANCHOR_POINT_NORTH:
227 case XFDASHBOARD_ANCHOR_POINT_SOUTH:
228 offset-=(textureWidth/2.0f);
229 break;
230
231 /* Align to right boundary */
232 case XFDASHBOARD_ANCHOR_POINT_EAST:
233 case XFDASHBOARD_ANCHOR_POINT_NORTH_EAST:
234 case XFDASHBOARD_ANCHOR_POINT_SOUTH_EAST:
235 offset-=textureWidth;
236 break;
237 }
238
239 /* Set boundary in X axis */
240 rectangleBox.x1=actorBox.x1+offset;
241 rectangleBox.x2=rectangleBox.x1+textureWidth;
242
243 /* Clip texture in X axis if it does not fit into allocation */
244 if(rectangleBox.x1<actorBox.x1)
245 {
246 oversize=actorBox.x1-rectangleBox.x1;
247 textureCoordBox.x1=oversize/textureWidth;
248 rectangleBox.x1=actorBox.x1;
249 }
250
251 if(rectangleBox.x2>actorBox.x2)
252 {
253 oversize=rectangleBox.x2-actorBox.x2;
254 textureCoordBox.x2=1.0f-(oversize/textureWidth);
255 rectangleBox.x2=actorBox.x2;
256 }
257
258 /* Get boundary in Y axis depending on anchorPoint and scaled width */
259 offset=(priv->yAlign*actorHeight);
260 switch(priv->anchorPoint)
261 {
262 /* Align to upper boundary.
263 * This is also the default if anchor point is none or undefined.
264 */
265 default:
266 case XFDASHBOARD_ANCHOR_POINT_NONE:
267 case XFDASHBOARD_ANCHOR_POINT_NORTH:
268 case XFDASHBOARD_ANCHOR_POINT_NORTH_WEST:
269 case XFDASHBOARD_ANCHOR_POINT_NORTH_EAST:
270 break;
271
272 /* Align to center of Y axis */
273 case XFDASHBOARD_ANCHOR_POINT_CENTER:
274 case XFDASHBOARD_ANCHOR_POINT_WEST:
275 case XFDASHBOARD_ANCHOR_POINT_EAST:
276 offset-=(textureHeight/2.0f);
277 break;
278
279 /* Align to lower boundary */
280 case XFDASHBOARD_ANCHOR_POINT_SOUTH:
281 case XFDASHBOARD_ANCHOR_POINT_SOUTH_WEST:
282 case XFDASHBOARD_ANCHOR_POINT_SOUTH_EAST:
283 offset-=textureHeight;
284 break;
285 }
286
287 /* Set boundary in Y axis */
288 rectangleBox.y1=actorBox.y1+offset;
289 rectangleBox.y2=rectangleBox.y1+textureHeight;
290
291 /* Clip texture in Y axis if it does not fit into allocation */
292 if(rectangleBox.y1<actorBox.y1)
293 {
294 oversize=actorBox.y1-rectangleBox.y1;
295 textureCoordBox.y1=oversize/textureHeight;
296 rectangleBox.y1=actorBox.y1;
297 }
298
299 if(rectangleBox.y2>actorBox.y2)
300 {
301 oversize=rectangleBox.y2-actorBox.y2;
302 textureCoordBox.y2=1.0f-(oversize/textureHeight);
303 rectangleBox.y2=actorBox.y2;
304 }
305
306 /* Draw icon if image was loaded */
307 loadingState=xfdashboard_image_content_get_state(XFDASHBOARD_IMAGE_CONTENT(priv->icon));
308 if(loadingState!=XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADED_SUCCESSFULLY &&
309 loadingState!=XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADED_FAILED)
310 {
311 XFDASHBOARD_DEBUG(self, ACTOR,
312 "Emblem image '%s' is still being loaded at %s",
313 priv->iconName,
314 G_OBJECT_TYPE_NAME(inEffect));
315 return;
316 }
317
318 framebuffer=cogl_get_draw_framebuffer();
319 cogl_framebuffer_draw_textured_rectangle(framebuffer,
320 priv->pipeline,
321 rectangleBox.x1, rectangleBox.y1,
322 rectangleBox.x2, rectangleBox.y2,
323 textureCoordBox.x1, textureCoordBox.y1,
324 textureCoordBox.x2, textureCoordBox.y2);
325 }
326
327 /* IMPLEMENTATION: GObject */
328
329 /* Dispose this object */
_xfdashboard_emblem_effect_dispose(GObject * inObject)330 static void _xfdashboard_emblem_effect_dispose(GObject *inObject)
331 {
332 /* Release allocated variables */
333 XfdashboardEmblemEffect *self=XFDASHBOARD_EMBLEM_EFFECT(inObject);
334 XfdashboardEmblemEffectPrivate *priv=self->priv;
335
336 if(priv->pipeline)
337 {
338 cogl_object_unref(priv->pipeline);
339 priv->pipeline=NULL;
340 }
341
342 if(priv->icon)
343 {
344 /* Disconnect any connected signal handler */
345 if(priv->loadSuccessSignalID)
346 {
347 g_signal_handler_disconnect(priv->icon, priv->loadSuccessSignalID);
348 priv->loadSuccessSignalID=0;
349 }
350
351 if(priv->loadFailedSignalID)
352 {
353 g_signal_handler_disconnect(priv->icon, priv->loadFailedSignalID);
354 priv->loadFailedSignalID=0;
355 }
356
357 /* Release image itself */
358 g_object_unref(priv->icon);
359 priv->icon=NULL;
360 }
361
362 if(priv->iconName)
363 {
364 g_free(priv->iconName);
365 priv->iconName=NULL;
366 }
367
368 /* Call parent's class dispose method */
369 G_OBJECT_CLASS(xfdashboard_emblem_effect_parent_class)->dispose(inObject);
370 }
371
372 /* Set/get properties */
_xfdashboard_emblem_effect_set_property(GObject * inObject,guint inPropID,const GValue * inValue,GParamSpec * inSpec)373 static void _xfdashboard_emblem_effect_set_property(GObject *inObject,
374 guint inPropID,
375 const GValue *inValue,
376 GParamSpec *inSpec)
377 {
378 XfdashboardEmblemEffect *self=XFDASHBOARD_EMBLEM_EFFECT(inObject);
379
380 switch(inPropID)
381 {
382 case PROP_ICON_NAME:
383 xfdashboard_emblem_effect_set_icon_name(self, g_value_get_string(inValue));
384 break;
385
386 case PROP_ICON_SIZE:
387 xfdashboard_emblem_effect_set_icon_size(self, g_value_get_int(inValue));
388 break;
389
390 case PROP_PADDING:
391 xfdashboard_emblem_effect_set_padding(self, g_value_get_float(inValue));
392 break;
393
394 case PROP_X_ALIGN:
395 xfdashboard_emblem_effect_set_x_align(self, g_value_get_float(inValue));
396 break;
397
398 case PROP_Y_ALIGN:
399 xfdashboard_emblem_effect_set_y_align(self, g_value_get_float(inValue));
400 break;
401
402 case PROP_ANCHOR_POINT:
403 xfdashboard_emblem_effect_set_anchor_point(self, g_value_get_enum(inValue));
404 break;
405
406 default:
407 G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
408 break;
409 }
410 }
411
_xfdashboard_emblem_effect_get_property(GObject * inObject,guint inPropID,GValue * outValue,GParamSpec * inSpec)412 static void _xfdashboard_emblem_effect_get_property(GObject *inObject,
413 guint inPropID,
414 GValue *outValue,
415 GParamSpec *inSpec)
416 {
417 XfdashboardEmblemEffect *self=XFDASHBOARD_EMBLEM_EFFECT(inObject);
418 XfdashboardEmblemEffectPrivate *priv=self->priv;
419
420 switch(inPropID)
421 {
422 case PROP_ICON_NAME:
423 g_value_set_string(outValue, priv->iconName);
424 break;
425
426 case PROP_ICON_SIZE:
427 g_value_set_int(outValue, priv->iconSize);
428 break;
429
430 case PROP_PADDING:
431 g_value_set_float(outValue, priv->padding);
432 break;
433
434 case PROP_X_ALIGN:
435 g_value_set_float(outValue, priv->xAlign);
436 break;
437
438 case PROP_Y_ALIGN:
439 g_value_set_float(outValue, priv->yAlign);
440 break;
441
442 case PROP_ANCHOR_POINT:
443 g_value_set_enum(outValue, priv->anchorPoint);
444 break;
445
446 default:
447 G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
448 break;
449 }
450 }
451
452 /* Class initialization
453 * Override functions in parent classes and define properties
454 * and signals
455 */
xfdashboard_emblem_effect_class_init(XfdashboardEmblemEffectClass * klass)456 static void xfdashboard_emblem_effect_class_init(XfdashboardEmblemEffectClass *klass)
457 {
458 ClutterEffectClass *effectClass=CLUTTER_EFFECT_CLASS(klass);
459 GObjectClass *gobjectClass=G_OBJECT_CLASS(klass);
460
461 /* Override functions */
462 gobjectClass->dispose=_xfdashboard_emblem_effect_dispose;
463 gobjectClass->set_property=_xfdashboard_emblem_effect_set_property;
464 gobjectClass->get_property=_xfdashboard_emblem_effect_get_property;
465
466 effectClass->paint=_xfdashboard_emblem_effect_paint;
467
468 /* Define properties */
469 XfdashboardEmblemEffectProperties[PROP_ICON_NAME]=
470 g_param_spec_string("icon-name",
471 "Icon name",
472 "Themed icon name or file name of icon",
473 N_(""),
474 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
475
476 XfdashboardEmblemEffectProperties[PROP_ICON_SIZE]=
477 g_param_spec_int("icon-size",
478 "Icon size",
479 "Size of icon",
480 1, G_MAXINT,
481 16,
482 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
483
484 XfdashboardEmblemEffectProperties[PROP_PADDING]=
485 g_param_spec_float("padding",
486 "Padding",
487 "Padding around emblem",
488 0.0f, G_MAXFLOAT,
489 0.0f,
490 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
491
492 XfdashboardEmblemEffectProperties[PROP_X_ALIGN]=
493 g_param_spec_float("x-align",
494 "X align",
495 "The alignment of emblem on the X axis within the allocation in normalized coordinate between 0 and 1",
496 0.0f, 1.0f,
497 0.0f,
498 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
499
500 XfdashboardEmblemEffectProperties[PROP_Y_ALIGN]=
501 g_param_spec_float("y-align",
502 "Y align",
503 "The alignment of emblem on the Y axis within the allocation in normalized coordinate between 0 and 1",
504 0.0f, 1.0f,
505 0.0f,
506 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
507
508 XfdashboardEmblemEffectProperties[PROP_ANCHOR_POINT]=
509 g_param_spec_enum("anchor-point",
510 "Anchor point",
511 "The anchor point of emblem",
512 XFDASHBOARD_TYPE_ANCHOR_POINT,
513 XFDASHBOARD_ANCHOR_POINT_NONE,
514 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
515
516 g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardEmblemEffectProperties);
517 }
518
519 /* Object initialization
520 * Create private structure and set up default values
521 */
xfdashboard_emblem_effect_init(XfdashboardEmblemEffect * self)522 static void xfdashboard_emblem_effect_init(XfdashboardEmblemEffect *self)
523 {
524 XfdashboardEmblemEffectPrivate *priv;
525
526 priv=self->priv=xfdashboard_emblem_effect_get_instance_private(self);
527
528 /* Set up default values */
529 priv->iconName=NULL;
530 priv->iconSize=16;
531 priv->padding=0.0f;
532 priv->xAlign=0.0f;
533 priv->yAlign=0.0f;
534 priv->anchorPoint=XFDASHBOARD_ANCHOR_POINT_NONE;
535 priv->icon=NULL;
536 priv->loadSuccessSignalID=0;
537 priv->loadFailedSignalID=0;
538
539 /* Set up pipeline */
540 if(G_UNLIKELY(!_xfdashboard_emblem_effect_base_pipeline))
541 {
542 CoglContext *context;
543
544 /* Get context to create base pipeline */
545 context=clutter_backend_get_cogl_context(clutter_get_default_backend());
546
547 /* Create base pipeline */
548 _xfdashboard_emblem_effect_base_pipeline=cogl_pipeline_new(context);
549 cogl_pipeline_set_layer_null_texture(_xfdashboard_emblem_effect_base_pipeline,
550 0, /* layer number */
551 COGL_TEXTURE_TYPE_2D);
552 }
553
554 priv->pipeline=cogl_pipeline_copy(_xfdashboard_emblem_effect_base_pipeline);
555 }
556
557 /* IMPLEMENTATION: Public API */
558
559 /* Create new actor */
xfdashboard_emblem_effect_new(void)560 ClutterEffect* xfdashboard_emblem_effect_new(void)
561 {
562 return(g_object_new(XFDASHBOARD_TYPE_EMBLEM_EFFECT, NULL));
563 }
564
565 /* Get/set icon name of emblem to draw */
xfdashboard_emblem_effect_get_icon_name(XfdashboardEmblemEffect * self)566 const gchar* xfdashboard_emblem_effect_get_icon_name(XfdashboardEmblemEffect *self)
567 {
568 g_return_val_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self), NULL);
569
570 return(self->priv->iconName);
571 }
572
xfdashboard_emblem_effect_set_icon_name(XfdashboardEmblemEffect * self,const gchar * inIconName)573 void xfdashboard_emblem_effect_set_icon_name(XfdashboardEmblemEffect *self, const gchar *inIconName)
574 {
575 XfdashboardEmblemEffectPrivate *priv;
576
577 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
578 g_return_if_fail(inIconName);
579
580 priv=self->priv;
581
582 /* Set value if changed */
583 if(priv->icon || g_strcmp0(priv->iconName, inIconName)!=0)
584 {
585 /* Set value */
586 if(priv->iconName) g_free(priv->iconName);
587 priv->iconName=g_strdup(inIconName);
588
589 /* Dispose any icon image loaded */
590 if(priv->icon)
591 {
592 g_object_unref(priv->icon);
593 priv->icon=NULL;
594 }
595
596 /* Invalidate effect to get it redrawn */
597 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
598
599 /* Notify about property change */
600 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardEmblemEffectProperties[PROP_ICON_NAME]);
601 }
602 }
603
604 /* Get/set icon size of emblem to draw */
xfdashboard_emblem_effect_get_icon_size(XfdashboardEmblemEffect * self)605 gint xfdashboard_emblem_effect_get_icon_size(XfdashboardEmblemEffect *self)
606 {
607 g_return_val_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self), 0);
608
609 return(self->priv->iconSize);
610 }
611
xfdashboard_emblem_effect_set_icon_size(XfdashboardEmblemEffect * self,const gint inSize)612 void xfdashboard_emblem_effect_set_icon_size(XfdashboardEmblemEffect *self, const gint inSize)
613 {
614 XfdashboardEmblemEffectPrivate *priv;
615
616 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
617 g_return_if_fail(inSize>0);
618
619 priv=self->priv;
620
621 /* Set value if changed */
622 if(priv->iconSize!=inSize)
623 {
624 /* Set value */
625 priv->iconSize=inSize;
626
627 /* Dispose any icon image loaded */
628 if(priv->icon)
629 {
630 g_object_unref(priv->icon);
631 priv->icon=NULL;
632 }
633
634 /* Invalidate effect to get it redrawn */
635 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
636
637 /* Notify about property change */
638 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardEmblemEffectProperties[PROP_ICON_SIZE]);
639 }
640 }
641
642 /* Get/set x align of emblem */
xfdashboard_emblem_effect_get_padding(XfdashboardEmblemEffect * self)643 gfloat xfdashboard_emblem_effect_get_padding(XfdashboardEmblemEffect *self)
644 {
645 g_return_val_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self), 0.0f);
646
647 return(self->priv->padding);
648 }
649
xfdashboard_emblem_effect_set_padding(XfdashboardEmblemEffect * self,const gfloat inPadding)650 void xfdashboard_emblem_effect_set_padding(XfdashboardEmblemEffect *self, const gfloat inPadding)
651 {
652 XfdashboardEmblemEffectPrivate *priv;
653
654 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
655 g_return_if_fail(inPadding>=0.0f);
656
657 priv=self->priv;
658
659 /* Set value if changed */
660 if(priv->padding!=inPadding)
661 {
662 /* Set value */
663 priv->padding=inPadding;
664
665 /* Invalidate effect to get it redrawn */
666 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
667
668 /* Notify about property change */
669 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardEmblemEffectProperties[PROP_PADDING]);
670 }
671 }
672
673 /* Get/set x align of emblem */
xfdashboard_emblem_effect_get_x_align(XfdashboardEmblemEffect * self)674 gfloat xfdashboard_emblem_effect_get_x_align(XfdashboardEmblemEffect *self)
675 {
676 g_return_val_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self), 0.0f);
677
678 return(self->priv->xAlign);
679 }
680
xfdashboard_emblem_effect_set_x_align(XfdashboardEmblemEffect * self,const gfloat inAlign)681 void xfdashboard_emblem_effect_set_x_align(XfdashboardEmblemEffect *self, const gfloat inAlign)
682 {
683 XfdashboardEmblemEffectPrivate *priv;
684
685 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
686 g_return_if_fail(inAlign>=0.0f && inAlign<=1.0f);
687
688 priv=self->priv;
689
690 /* Set value if changed */
691 if(priv->xAlign!=inAlign)
692 {
693 /* Set value */
694 priv->xAlign=inAlign;
695
696 /* Invalidate effect to get it redrawn */
697 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
698
699 /* Notify about property change */
700 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardEmblemEffectProperties[PROP_X_ALIGN]);
701 }
702 }
703
704 /* Get/set y align of emblem */
xfdashboard_emblem_effect_get_y_align(XfdashboardEmblemEffect * self)705 gfloat xfdashboard_emblem_effect_get_y_align(XfdashboardEmblemEffect *self)
706 {
707 g_return_val_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self), 0.0f);
708
709 return(self->priv->xAlign);
710 }
711
xfdashboard_emblem_effect_set_y_align(XfdashboardEmblemEffect * self,const gfloat inAlign)712 void xfdashboard_emblem_effect_set_y_align(XfdashboardEmblemEffect *self, const gfloat inAlign)
713 {
714 XfdashboardEmblemEffectPrivate *priv;
715
716 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
717 g_return_if_fail(inAlign>=0.0f && inAlign<=1.0f);
718
719 priv=self->priv;
720
721 /* Set value if changed */
722 if(priv->yAlign!=inAlign)
723 {
724 /* Set value */
725 priv->yAlign=inAlign;
726
727 /* Invalidate effect to get it redrawn */
728 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
729
730 /* Notify about property change */
731 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardEmblemEffectProperties[PROP_Y_ALIGN]);
732 }
733 }
734
735 /* Get/set anchor point of emblem */
xfdashboard_emblem_effect_get_anchor_point(XfdashboardEmblemEffect * self)736 XfdashboardAnchorPoint xfdashboard_emblem_effect_get_anchor_point(XfdashboardEmblemEffect *self)
737 {
738 g_return_val_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self), XFDASHBOARD_ANCHOR_POINT_NORTH_WEST);
739
740 return(self->priv->anchorPoint);
741 }
742
xfdashboard_emblem_effect_set_anchor_point(XfdashboardEmblemEffect * self,const XfdashboardAnchorPoint inAnchorPoint)743 void xfdashboard_emblem_effect_set_anchor_point(XfdashboardEmblemEffect *self, const XfdashboardAnchorPoint inAnchorPoint)
744 {
745 XfdashboardEmblemEffectPrivate *priv;
746
747 g_return_if_fail(XFDASHBOARD_IS_EMBLEM_EFFECT(self));
748 g_return_if_fail(inAnchorPoint>=XFDASHBOARD_ANCHOR_POINT_NONE);
749 g_return_if_fail(inAnchorPoint<=XFDASHBOARD_ANCHOR_POINT_CENTER);
750
751 priv=self->priv;
752
753 /* Set value if changed */
754 if(priv->anchorPoint!=inAnchorPoint)
755 {
756 /* Set value */
757 priv->anchorPoint=inAnchorPoint;
758
759 /* Invalidate effect to get it redrawn */
760 clutter_effect_queue_repaint(CLUTTER_EFFECT(self));
761
762 /* Notify about property change */
763 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardEmblemEffectProperties[PROP_ANCHOR_POINT]);
764 }
765 }
766