1 /*
2  * view: Abstract class for views, optional with scrollbars
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/view.h>
29 
30 #include <glib/gi18n-lib.h>
31 #include <gtk/gtk.h>
32 
33 #include <libxfdashboard/marshal.h>
34 #include <libxfdashboard/image-content.h>
35 #include <libxfdashboard/utils.h>
36 #include <libxfdashboard/focus-manager.h>
37 #include <libxfdashboard/viewpad.h>
38 #include <libxfdashboard/enums.h>
39 #include <libxfdashboard/compat.h>
40 
41 
42 /* Define this class in GObject system */
43 struct _XfdashboardViewPrivate
44 {
45 	/* Properties related */
46 	gchar					*viewID;
47 
48 	gchar					*viewName;
49 
50 	gchar					*viewIcon;
51 	ClutterContent			*viewIconImage;
52 
53 	XfdashboardViewFitMode	fitMode;
54 
55 	gboolean				isEnabled;
56 
57 	/* Layout manager */
58 	guint					signalChangedID;
59 };
60 
61 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(XfdashboardView,
62 									xfdashboard_view,
63 									XFDASHBOARD_TYPE_ACTOR)
64 
65 /* Properties */
66 enum
67 {
68 	PROP_0,
69 
70 	PROP_VIEW_ID,
71 	PROP_VIEW_NAME,
72 	PROP_VIEW_ICON,
73 
74 	PROP_VIEW_FIT_MODE,
75 
76 	PROP_ENABLED,
77 
78 	PROP_LAST
79 };
80 
81 static GParamSpec* XfdashboardViewProperties[PROP_LAST]={ 0, };
82 
83 /* Signals */
84 enum
85 {
86 	SIGNAL_ACTIVATING,
87 	SIGNAL_ACTIVATED,
88 	SIGNAL_DEACTIVATING,
89 	SIGNAL_DEACTIVATED,
90 
91 	SIGNAL_ENABLING,
92 	SIGNAL_ENABLED,
93 	SIGNAL_DISABLING,
94 	SIGNAL_DISABLED,
95 
96 	SIGNAL_NAME_CHANGED,
97 	SIGNAL_ICON_CHANGED,
98 
99 	SIGNAL_SCROLL_TO,
100 	SIGNAL_CHILD_NEEDS_SCROLL,
101 	SIGNAL_CHILD_ENSURE_VISIBLE,
102 
103 	ACTION_VIEW_ACTIVATE,
104 
105 	SIGNAL_LAST
106 };
107 
108 static guint XfdashboardViewSignals[SIGNAL_LAST]={ 0, };
109 
110 /* IMPLEMENTATION: Private variables and methods */
111 
112 /* Find viewpad which contains this view */
_xfdashboard_view_find_viewpad(XfdashboardView * self)113 static XfdashboardViewpad* _xfdashboard_view_find_viewpad(XfdashboardView *self)
114 {
115 	ClutterActor				*viewpad;
116 
117 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), NULL);
118 
119 	/* Iterate through parent actors and for each viewpad found
120 	 * check if it contains this view.
121 	 */
122 	viewpad=clutter_actor_get_parent(CLUTTER_ACTOR(self));
123 	while(viewpad)
124 	{
125 		/* Check if this parent actor is a viewpad and
126 		 * if it contains this view.
127 		 */
128 		if(XFDASHBOARD_IS_VIEWPAD(viewpad) &&
129 			xfdashboard_viewpad_has_view(XFDASHBOARD_VIEWPAD(viewpad), self))
130 		{
131 			/* Viewpad found so return it */
132 			return(XFDASHBOARD_VIEWPAD(viewpad));
133 		}
134 
135 		/* Continue with next parent actor */
136 		viewpad=clutter_actor_get_parent(viewpad);
137 	}
138 
139 	/* If we get here the viewpad could not be found so return NULL */
140 	return(NULL);
141 }
142 
143 /* Action signal to close currently selected window was emitted */
_xfdashboard_view_activate(XfdashboardView * self,XfdashboardFocusable * inSource,const gchar * inAction,ClutterEvent * inEvent)144 static gboolean _xfdashboard_view_activate(XfdashboardView *self,
145 											XfdashboardFocusable *inSource,
146 											const gchar *inAction,
147 											ClutterEvent *inEvent)
148 {
149 	XfdashboardViewPrivate		*priv;
150 	XfdashboardViewpad			*viewpad;
151 	XfdashboardFocusManager		*focusManager;
152 
153 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), CLUTTER_EVENT_PROPAGATE);
154 
155 	priv=self->priv;
156 
157 	/* Only enabled views can be activated */
158 	if(!priv->isEnabled) return(CLUTTER_EVENT_STOP);
159 
160 	/* Find viewpad which contains this view */
161 	viewpad=_xfdashboard_view_find_viewpad(self);
162 	if(!viewpad) return(CLUTTER_EVENT_STOP);
163 
164 	/* Activate view at viewpad if this view is not the active one */
165 	if(xfdashboard_viewpad_get_active_view(viewpad)!=self)
166 	{
167 		xfdashboard_viewpad_set_active_view(viewpad, self);
168 	}
169 
170 	/* Set focus to view if it has not the focus */
171 	focusManager=xfdashboard_focus_manager_get_default();
172 	if(XFDASHBOARD_IS_FOCUSABLE(self) &&
173 		!xfdashboard_focus_manager_has_focus(focusManager, XFDASHBOARD_FOCUSABLE(self)))
174 	{
175 		xfdashboard_focus_manager_set_focus(focusManager, XFDASHBOARD_FOCUSABLE(self));
176 	}
177 	g_object_unref(focusManager);
178 
179 	/* Action handled */
180 	return(CLUTTER_EVENT_STOP);
181 }
182 
183 /* This view was enabled */
_xfdashboard_view_enabled(XfdashboardView * self)184 static void _xfdashboard_view_enabled(XfdashboardView *self)
185 {
186 	XfdashboardViewpad			*viewpad;
187 
188 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
189 
190 	/* If view is not a child of a viewpad show view actor directly */
191 	viewpad=_xfdashboard_view_find_viewpad(self);
192 	if(!viewpad)
193 	{
194 		clutter_actor_show(CLUTTER_ACTOR(self));
195 	}
196 }
197 
198 /* This view was disabled */
_xfdashboard_view_disabled(XfdashboardView * self)199 static void _xfdashboard_view_disabled(XfdashboardView *self)
200 {
201 	XfdashboardViewpad			*viewpad;
202 
203 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
204 
205 	/* If view is not a child of a viewpad hide view actor directly */
206 	viewpad=_xfdashboard_view_find_viewpad(self);
207 	if(!viewpad)
208 	{
209 		clutter_actor_hide(CLUTTER_ACTOR(self));
210 	}
211 }
212 
213 /* Set view ID */
_xfdashboard_view_set_id(XfdashboardView * self,const gchar * inID)214 static void _xfdashboard_view_set_id(XfdashboardView *self, const gchar *inID)
215 {
216 	XfdashboardViewPrivate	*priv;
217 
218 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
219 	g_return_if_fail(inID && *inID);
220 
221 	priv=self->priv;
222 
223 	/* Set value if changed */
224 	if(g_strcmp0(priv->viewID, inID)!=0)
225 	{
226 		if(priv->viewID) g_free(priv->viewID);
227 		priv->viewID=g_strdup(inID);
228 
229 		/* Notify about property change */
230 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewProperties[PROP_VIEW_ID]);
231 	}
232 }
233 
234 /* IMPLEMENTATION: GObject */
235 
236 /* Dispose this object */
_xfdashboard_view_dispose(GObject * inObject)237 static void _xfdashboard_view_dispose(GObject *inObject)
238 {
239 	XfdashboardView			*self=XFDASHBOARD_VIEW(inObject);
240 	XfdashboardViewPrivate	*priv=self->priv;
241 
242 	/* Release allocated resources */
243 	if(priv->viewID)
244 	{
245 		g_free(priv->viewID);
246 		priv->viewID=NULL;
247 	}
248 
249 	if(priv->viewName)
250 	{
251 		g_free(priv->viewName);
252 		priv->viewName=NULL;
253 	}
254 
255 	if(priv->viewIcon)
256 	{
257 		g_free(priv->viewIcon);
258 		priv->viewIcon=NULL;
259 	}
260 
261 	if(priv->viewIconImage)
262 	{
263 		g_object_unref(priv->viewIconImage);
264 		priv->viewIconImage=NULL;
265 	}
266 
267 	/* Call parent's class dispose method */
268 	G_OBJECT_CLASS(xfdashboard_view_parent_class)->dispose(inObject);
269 }
270 
271 /* Set/get properties */
_xfdashboard_view_set_property(GObject * inObject,guint inPropID,const GValue * inValue,GParamSpec * inSpec)272 static void _xfdashboard_view_set_property(GObject *inObject,
273 											guint inPropID,
274 											const GValue *inValue,
275 											GParamSpec *inSpec)
276 {
277 	XfdashboardView		*self=XFDASHBOARD_VIEW(inObject);
278 
279 	switch(inPropID)
280 	{
281 		case PROP_VIEW_ID:
282 			_xfdashboard_view_set_id(self, g_value_get_string(inValue));
283 			break;
284 
285 		case PROP_VIEW_NAME:
286 			xfdashboard_view_set_name(self, g_value_get_string(inValue));
287 			break;
288 
289 		case PROP_VIEW_ICON:
290 			xfdashboard_view_set_icon(self, g_value_get_string(inValue));
291 			break;
292 
293 		case PROP_VIEW_FIT_MODE:
294 			xfdashboard_view_set_view_fit_mode(self, (XfdashboardViewFitMode)g_value_get_enum(inValue));
295 			break;
296 
297 		case PROP_ENABLED:
298 			xfdashboard_view_set_enabled(self, g_value_get_boolean(inValue));
299 			break;
300 
301 		default:
302 			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
303 			break;
304 	}
305 }
306 
_xfdashboard_view_get_property(GObject * inObject,guint inPropID,GValue * outValue,GParamSpec * inSpec)307 static void _xfdashboard_view_get_property(GObject *inObject,
308 											guint inPropID,
309 											GValue *outValue,
310 											GParamSpec *inSpec)
311 {
312 	XfdashboardView		*self=XFDASHBOARD_VIEW(inObject);
313 
314 	switch(inPropID)
315 	{
316 		case PROP_VIEW_ID:
317 			g_value_set_string(outValue, self->priv->viewID);
318 			break;
319 
320 		case PROP_VIEW_NAME:
321 			g_value_set_string(outValue, self->priv->viewName);
322 			break;
323 
324 		case PROP_VIEW_ICON:
325 			g_value_set_string(outValue, self->priv->viewIcon);
326 			break;
327 
328 		case PROP_VIEW_FIT_MODE:
329 			g_value_set_enum(outValue, self->priv->fitMode);
330 			break;
331 
332 		case PROP_ENABLED:
333 			g_value_set_boolean(outValue, self->priv->isEnabled);
334 			break;
335 
336 		default:
337 			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
338 			break;
339 	}
340 }
341 
342 /* Class initialization
343  * Override functions in parent classes and define properties
344  * and signals
345  */
xfdashboard_view_class_init(XfdashboardViewClass * klass)346 static void xfdashboard_view_class_init(XfdashboardViewClass *klass)
347 {
348 	XfdashboardActorClass	*actorClass=XFDASHBOARD_ACTOR_CLASS(klass);
349 	GObjectClass			*gobjectClass=G_OBJECT_CLASS(klass);
350 
351 	/* Override functions */
352 	gobjectClass->set_property=_xfdashboard_view_set_property;
353 	gobjectClass->get_property=_xfdashboard_view_get_property;
354 	gobjectClass->dispose=_xfdashboard_view_dispose;
355 
356 	klass->view_activate=_xfdashboard_view_activate;
357 	klass->enabled=_xfdashboard_view_enabled;
358 	klass->disabled=_xfdashboard_view_disabled;
359 
360 	/* Define properties */
361 	XfdashboardViewProperties[PROP_VIEW_ID]=
362 		g_param_spec_string("view-id",
363 							"View ID",
364 							"The internal ID used to register this type of view",
365 							NULL,
366 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
367 
368 	XfdashboardViewProperties[PROP_VIEW_NAME]=
369 		g_param_spec_string("view-name",
370 							"View name",
371 							"Name of view used to display",
372 							NULL,
373 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
374 
375 	XfdashboardViewProperties[PROP_VIEW_ICON]=
376 		g_param_spec_string("view-icon",
377 							"View icon",
378 							"Icon of view used to display. Icon name can be a themed icon name or file name",
379 							NULL,
380 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
381 
382 	XfdashboardViewProperties[PROP_VIEW_FIT_MODE]=
383 		g_param_spec_enum("view-fit-mode",
384 							"View fit mode",
385 							"Defines if view should be fit into viewpad and in which directions it should fit into it",
386 							XFDASHBOARD_TYPE_VIEW_FIT_MODE,
387 							XFDASHBOARD_VIEW_FIT_MODE_NONE,
388 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
389 
390 	XfdashboardViewProperties[PROP_ENABLED]=
391 		g_param_spec_boolean("enabled",
392 								"Enabled",
393 								"This flag indicates if is view is enabled and activable",
394 								TRUE,
395 								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
396 
397 	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardViewProperties);
398 
399 	/* Define stylable properties */
400 	xfdashboard_actor_install_stylable_property(actorClass, XfdashboardViewProperties[PROP_VIEW_ICON]);
401 
402 	/* Define signals */
403 	XfdashboardViewSignals[SIGNAL_ACTIVATING]=
404 		g_signal_new("activating",
405 						G_TYPE_FROM_CLASS(klass),
406 						G_SIGNAL_RUN_LAST,
407 						G_STRUCT_OFFSET(XfdashboardViewClass, activating),
408 						NULL,
409 						NULL,
410 						g_cclosure_marshal_VOID__VOID,
411 						G_TYPE_NONE,
412 						0);
413 
414 	XfdashboardViewSignals[SIGNAL_ACTIVATED]=
415 		g_signal_new("activated",
416 						G_TYPE_FROM_CLASS(klass),
417 						G_SIGNAL_RUN_LAST,
418 						G_STRUCT_OFFSET(XfdashboardViewClass, activated),
419 						NULL,
420 						NULL,
421 						g_cclosure_marshal_VOID__VOID,
422 						G_TYPE_NONE,
423 						0);
424 
425 	XfdashboardViewSignals[SIGNAL_DEACTIVATING]=
426 		g_signal_new("deactivating",
427 						G_TYPE_FROM_CLASS(klass),
428 						G_SIGNAL_RUN_LAST,
429 						G_STRUCT_OFFSET(XfdashboardViewClass, deactivating),
430 						NULL,
431 						NULL,
432 						g_cclosure_marshal_VOID__VOID,
433 						G_TYPE_NONE,
434 						0);
435 
436 	XfdashboardViewSignals[SIGNAL_DEACTIVATED]=
437 		g_signal_new("deactivated",
438 						G_TYPE_FROM_CLASS(klass),
439 						G_SIGNAL_RUN_LAST,
440 						G_STRUCT_OFFSET(XfdashboardViewClass, deactivated),
441 						NULL,
442 						NULL,
443 						g_cclosure_marshal_VOID__VOID,
444 						G_TYPE_NONE,
445 						0);
446 
447 	XfdashboardViewSignals[SIGNAL_ENABLING]=
448 		g_signal_new("enabling",
449 						G_TYPE_FROM_CLASS(klass),
450 						G_SIGNAL_RUN_LAST,
451 						G_STRUCT_OFFSET(XfdashboardViewClass, enabling),
452 						NULL,
453 						NULL,
454 						g_cclosure_marshal_VOID__VOID,
455 						G_TYPE_NONE,
456 						0);
457 
458 	XfdashboardViewSignals[SIGNAL_ENABLED]=
459 		g_signal_new("enabled",
460 						G_TYPE_FROM_CLASS(klass),
461 						G_SIGNAL_RUN_LAST,
462 						G_STRUCT_OFFSET(XfdashboardViewClass, enabled),
463 						NULL,
464 						NULL,
465 						g_cclosure_marshal_VOID__VOID,
466 						G_TYPE_NONE,
467 						0);
468 
469 	XfdashboardViewSignals[SIGNAL_DISABLING]=
470 		g_signal_new("disabling",
471 						G_TYPE_FROM_CLASS(klass),
472 						G_SIGNAL_RUN_LAST,
473 						G_STRUCT_OFFSET(XfdashboardViewClass, disabling),
474 						NULL,
475 						NULL,
476 						g_cclosure_marshal_VOID__VOID,
477 						G_TYPE_NONE,
478 						0);
479 
480 	XfdashboardViewSignals[SIGNAL_DISABLED]=
481 		g_signal_new("disabled",
482 						G_TYPE_FROM_CLASS(klass),
483 						G_SIGNAL_RUN_LAST,
484 						G_STRUCT_OFFSET(XfdashboardViewClass, disabled),
485 						NULL,
486 						NULL,
487 						g_cclosure_marshal_VOID__VOID,
488 						G_TYPE_NONE,
489 						0);
490 
491 	XfdashboardViewSignals[SIGNAL_NAME_CHANGED]=
492 		g_signal_new("name-changed",
493 						G_TYPE_FROM_CLASS(klass),
494 						G_SIGNAL_RUN_LAST,
495 						G_STRUCT_OFFSET(XfdashboardViewClass, name_changed),
496 						NULL,
497 						NULL,
498 						g_cclosure_marshal_VOID__STRING,
499 						G_TYPE_NONE,
500 						1,
501 						G_TYPE_STRING);
502 
503 	XfdashboardViewSignals[SIGNAL_ICON_CHANGED]=
504 		g_signal_new("icon-changed",
505 						G_TYPE_FROM_CLASS(klass),
506 						G_SIGNAL_RUN_LAST,
507 						G_STRUCT_OFFSET(XfdashboardViewClass, icon_changed),
508 						NULL,
509 						NULL,
510 						g_cclosure_marshal_VOID__OBJECT,
511 						G_TYPE_NONE,
512 						1,
513 						CLUTTER_TYPE_IMAGE);
514 
515 	XfdashboardViewSignals[SIGNAL_SCROLL_TO]=
516 		g_signal_new("scroll-to",
517 						G_TYPE_FROM_CLASS(klass),
518 						G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
519 						G_STRUCT_OFFSET(XfdashboardViewClass, scroll_to),
520 						NULL,
521 						NULL,
522 						_xfdashboard_marshal_VOID__FLOAT_FLOAT,
523 						G_TYPE_NONE,
524 						2,
525 						G_TYPE_FLOAT,
526 						G_TYPE_FLOAT);
527 
528 	XfdashboardViewSignals[SIGNAL_CHILD_NEEDS_SCROLL]=
529 		g_signal_new("child-needs-scroll",
530 						G_TYPE_FROM_CLASS(klass),
531 						G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
532 						G_STRUCT_OFFSET(XfdashboardViewClass, child_needs_scroll),
533 						NULL,
534 						NULL,
535 						_xfdashboard_marshal_BOOLEAN__OBJECT,
536 						G_TYPE_BOOLEAN,
537 						1,
538 						CLUTTER_TYPE_ACTOR);
539 
540 	XfdashboardViewSignals[SIGNAL_CHILD_ENSURE_VISIBLE]=
541 		g_signal_new("child-ensure-visible",
542 						G_TYPE_FROM_CLASS(klass),
543 						G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
544 						G_STRUCT_OFFSET(XfdashboardViewClass, child_ensure_visible),
545 						NULL,
546 						NULL,
547 						g_cclosure_marshal_VOID__OBJECT,
548 						G_TYPE_NONE,
549 						1,
550 						CLUTTER_TYPE_ACTOR);
551 
552 	/* Define actions */
553 	XfdashboardViewSignals[ACTION_VIEW_ACTIVATE]=
554 		g_signal_new("view-activate",
555 						G_TYPE_FROM_CLASS(klass),
556 						G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
557 						G_STRUCT_OFFSET(XfdashboardViewClass, view_activate),
558 						g_signal_accumulator_true_handled,
559 						NULL,
560 						_xfdashboard_marshal_BOOLEAN__OBJECT_STRING_BOXED,
561 						G_TYPE_BOOLEAN,
562 						3,
563 						XFDASHBOARD_TYPE_FOCUSABLE,
564 						G_TYPE_STRING,
565 						CLUTTER_TYPE_EVENT);
566 }
567 
568 /* Object initialization
569  * Create private structure and set up default values
570  */
xfdashboard_view_init(XfdashboardView * self)571 static void xfdashboard_view_init(XfdashboardView *self)
572 {
573 	XfdashboardViewPrivate	*priv;
574 
575 	priv=self->priv=xfdashboard_view_get_instance_private(self);
576 
577 	/* Set up default values */
578 	priv->viewName=NULL;
579 	priv->viewIcon=NULL;
580 	priv->viewIconImage=NULL;
581 	priv->fitMode=XFDASHBOARD_VIEW_FIT_MODE_NONE;
582 	priv->isEnabled=TRUE;
583 
584 	/* Set up actor */
585 	clutter_actor_set_reactive(CLUTTER_ACTOR(self), TRUE);
586 	xfdashboard_actor_invalidate(XFDASHBOARD_ACTOR(self));
587 }
588 
589 /* IMPLEMENTATION: Public API */
590 
591 /* Get view ID */
xfdashboard_view_get_id(XfdashboardView * self)592 const gchar* xfdashboard_view_get_id(XfdashboardView *self)
593 {
594 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), NULL);
595 
596 	return(self->priv->viewID);
597 }
598 
599 /* Check if view has requested ID */
xfdashboard_view_has_id(XfdashboardView * self,const gchar * inID)600 gboolean xfdashboard_view_has_id(XfdashboardView *self, const gchar *inID)
601 {
602 	XfdashboardViewPrivate	*priv;
603 
604 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), FALSE);
605 	g_return_val_if_fail(inID && *inID, FALSE);
606 
607 	priv=self->priv;
608 
609 	/* Check if requested ID matches the ID of this view */
610 	if(g_strcmp0(priv->viewID, inID)!=0) return(FALSE);
611 
612 	/* If we get here the requested ID matches view's ID */
613 	return(TRUE);
614 }
615 
616 /* Get/set name of view */
xfdashboard_view_get_name(XfdashboardView * self)617 const gchar* xfdashboard_view_get_name(XfdashboardView *self)
618 {
619 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), NULL);
620 
621 	return(self->priv->viewName);
622 }
623 
xfdashboard_view_set_name(XfdashboardView * self,const gchar * inName)624 void xfdashboard_view_set_name(XfdashboardView *self, const gchar *inName)
625 {
626 	XfdashboardViewPrivate	*priv;
627 
628 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
629 	g_return_if_fail(inName!=NULL);
630 
631 	priv=self->priv;
632 
633 	/* Set value if changed */
634 	if(g_strcmp0(priv->viewName, inName)!=0)
635 	{
636 		if(priv->viewName) g_free(priv->viewName);
637 		priv->viewName=g_strdup(inName);
638 
639 		/* Notify about property change */
640 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewProperties[PROP_VIEW_NAME]);
641 		g_signal_emit(self, XfdashboardViewSignals[SIGNAL_NAME_CHANGED], 0, priv->viewName);
642 	}
643 }
644 
645 /* Get/set icon of view */
xfdashboard_view_get_icon(XfdashboardView * self)646 const gchar* xfdashboard_view_get_icon(XfdashboardView *self)
647 {
648   g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), NULL);
649 
650   return(self->priv->viewIcon);
651 }
652 
xfdashboard_view_set_icon(XfdashboardView * self,const gchar * inIcon)653 void xfdashboard_view_set_icon(XfdashboardView *self, const gchar *inIcon)
654 {
655 	XfdashboardViewPrivate	*priv;
656 
657 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
658 	g_return_if_fail(inIcon!=NULL);
659 
660 	priv=self->priv;
661 
662 	/* Set value if changed */
663 	if(g_strcmp0(priv->viewIcon, inIcon)!=0)
664 	{
665 		/* Set new icon name */
666 		if(priv->viewIcon) g_free(priv->viewIcon);
667 		priv->viewIcon=g_strdup(inIcon);
668 
669 		/* Set new icon */
670 		if(priv->viewIconImage) g_object_unref(priv->viewIconImage);
671 		priv->viewIconImage=xfdashboard_image_content_new_for_icon_name(priv->viewIcon, 64.0f);
672 
673 		/* Notify about property change */
674 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewProperties[PROP_VIEW_ICON]);
675 		g_signal_emit(self, XfdashboardViewSignals[SIGNAL_ICON_CHANGED], 0, CLUTTER_IMAGE(priv->viewIconImage));
676 	}
677 }
678 
679 /* Get/set fit mode of view */
xfdashboard_view_get_view_fit_mode(XfdashboardView * self)680 XfdashboardViewFitMode xfdashboard_view_get_view_fit_mode(XfdashboardView *self)
681 {
682   g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), XFDASHBOARD_VIEW_FIT_MODE_NONE);
683 
684   return(self->priv->fitMode);
685 }
686 
xfdashboard_view_set_view_fit_mode(XfdashboardView * self,XfdashboardViewFitMode inFitMode)687 void xfdashboard_view_set_view_fit_mode(XfdashboardView *self, XfdashboardViewFitMode inFitMode)
688 {
689 	XfdashboardViewPrivate	*priv;
690 	XfdashboardViewClass	*klass;
691 
692 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
693 
694 	priv=self->priv;
695 	klass=XFDASHBOARD_VIEW_GET_CLASS(self);
696 
697 	/* Set value if changed */
698 	if(priv->fitMode!=inFitMode)
699 	{
700 		/* Set new fit mode */
701 		priv->fitMode=inFitMode;
702 
703 		/* Call virtual function for setting fit mode */
704 		if(klass->set_view_fit_mode) klass->set_view_fit_mode(self, inFitMode);
705 
706 		/* Notify about property change */
707 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewProperties[PROP_VIEW_FIT_MODE]);
708 	}
709 }
710 
711 /* Get/set enabled state of view */
xfdashboard_view_get_enabled(XfdashboardView * self)712 gboolean xfdashboard_view_get_enabled(XfdashboardView *self)
713 {
714   g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), FALSE);
715 
716   return(self->priv->isEnabled);
717 }
718 
xfdashboard_view_set_enabled(XfdashboardView * self,gboolean inIsEnabled)719 void xfdashboard_view_set_enabled(XfdashboardView *self, gboolean inIsEnabled)
720 {
721 	XfdashboardViewPrivate	*priv;
722 	guint					signalBeforeID, signalAfterID;
723 
724 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
725 
726 	priv=self->priv;
727 
728 	/* Set value if changed */
729 	if(priv->isEnabled!=inIsEnabled)
730 	{
731 		/* Get signal ID to emit depending on enabled state */
732 		signalBeforeID=(inIsEnabled==TRUE ? SIGNAL_ENABLING : SIGNAL_DISABLING);
733 		signalAfterID=(inIsEnabled==TRUE ? SIGNAL_ENABLED : SIGNAL_DISABLED);
734 
735 		/* Set new enabled state */
736 		g_signal_emit(self, XfdashboardViewSignals[signalBeforeID], 0, self);
737 
738 		priv->isEnabled=inIsEnabled;
739 
740 		g_signal_emit(self, XfdashboardViewSignals[signalAfterID], 0, self);
741 
742 		/* Notify about property change */
743 		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewProperties[PROP_ENABLED]);
744 	}
745 }
746 
747 /* Scroll view to requested coordinates */
xfdashboard_view_scroll_to(XfdashboardView * self,gfloat inX,gfloat inY)748 void xfdashboard_view_scroll_to(XfdashboardView *self, gfloat inX, gfloat inY)
749 {
750 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
751 
752 	g_signal_emit(self, XfdashboardViewSignals[SIGNAL_SCROLL_TO], 0, inX, inY);
753 }
754 
755 /* Determine if scrolling is needed to get requested actor visible */
xfdashboard_view_child_needs_scroll(XfdashboardView * self,ClutterActor * inActor)756 gboolean xfdashboard_view_child_needs_scroll(XfdashboardView *self, ClutterActor *inActor)
757 {
758 	gboolean			result;
759 
760 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), FALSE);
761 	g_return_val_if_fail(CLUTTER_IS_ACTOR(inActor), FALSE);
762 
763 	result=FALSE;
764 
765 	/* Only emit signal if given actor is a child of this view */
766 	if(clutter_actor_contains(CLUTTER_ACTOR(self), inActor))
767 	{
768 		g_signal_emit(self, XfdashboardViewSignals[SIGNAL_CHILD_NEEDS_SCROLL], 0, inActor, &result);
769 	}
770 
771 	return(result);
772 }
773 
774 /* Ensure that a child of this view is visible by scrolling if needed */
xfdashboard_view_child_ensure_visible(XfdashboardView * self,ClutterActor * inActor)775 void xfdashboard_view_child_ensure_visible(XfdashboardView *self, ClutterActor *inActor)
776 {
777 	g_return_if_fail(XFDASHBOARD_IS_VIEW(self));
778 	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
779 
780 	/* Only emit signal if given actor is a child of this view */
781 	if(clutter_actor_contains(CLUTTER_ACTOR(self), inActor))
782 	{
783 		g_signal_emit(self, XfdashboardViewSignals[SIGNAL_CHILD_ENSURE_VISIBLE], 0, inActor);
784 	}
785 }
786 
787 /* Determine if view has the focus */
xfdashboard_view_has_focus(XfdashboardView * self)788 gboolean xfdashboard_view_has_focus(XfdashboardView *self)
789 {
790 	XfdashboardViewPrivate		*priv;
791 	XfdashboardFocusManager		*focusManager;
792 	XfdashboardViewpad			*viewpad;
793 
794 	g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), FALSE);
795 
796 	priv=self->priv;
797 
798 	/* The view can only have the focus if this view is enabled, active and
799 	 * has the current focus.
800 	 */
801 	if(!priv->isEnabled)
802 	{
803 		return(FALSE);
804 	}
805 
806 	viewpad=_xfdashboard_view_find_viewpad(self);
807 	if(!viewpad)
808 	{
809 		return(FALSE);
810 	}
811 
812 	if(xfdashboard_viewpad_get_active_view(XFDASHBOARD_VIEWPAD(viewpad))!=self)
813 	{
814 		return(FALSE);
815 	}
816 
817 	focusManager=xfdashboard_focus_manager_get_default();
818 	if(!XFDASHBOARD_IS_FOCUSABLE(self) ||
819 		!xfdashboard_focus_manager_has_focus(focusManager, XFDASHBOARD_FOCUSABLE(self)))
820 	{
821 		g_object_unref(focusManager);
822 		return(FALSE);
823 	}
824 
825 	/* Release allocated resources */
826 	g_object_unref(focusManager);
827 
828 	/* All tests passed so this view has the focus */
829 	return(TRUE);
830 }
831