Example #1
0
/* Default implementation of virtual function "get_parent" */
static XfdashboardStylable* _xfdashboard_stylable_real_get_parent(XfdashboardStylable *self)
{
	XfdashboardStylable		*parent;

	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(self), NULL);

	parent=NULL;

	/* If object implementing this interface is derived from ClutterActor
	 * get actor's parent actor.
	 */
	if(CLUTTER_IS_ACTOR(self))
	{
		ClutterActor		*parentActor;

		/* Get parent and if parent stylable set parent as result */
		parentActor=clutter_actor_get_parent(CLUTTER_ACTOR(self));
		if(parentActor &&
			XFDASHBOARD_IS_STYLABLE(parentActor))
		{
			parent=XFDASHBOARD_STYLABLE(parentActor);
		}
	}

	/* Return stylable parent */
	return(parent);
}
Example #2
0
/* Call virtual function "set_focus" */
void xfdashboard_focusable_set_focus(XfdashboardFocusable *self)
{
	XfdashboardFocusableInterface		*iface;
	ClutterActor						*selection;

	g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(self));

	iface=XFDASHBOARD_FOCUSABLE_GET_IFACE(self);

	/* Call virtual function */
	if(iface->set_focus)
	{
		iface->set_focus(self);
	}

	/* Style newly focused actor */
	if(XFDASHBOARD_IS_STYLABLE(self))
	{
		xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(self), "focus");
	}

	/* If actor supports selection get current selection and style it */
	if(xfdashboard_focusable_supports_selection(self))
	{
		/* Get current selection. If no selection is available then select first item. */
		selection=xfdashboard_focusable_get_selection(self);
		if(!selection)
		{
			selection=xfdashboard_focusable_find_selection(self, NULL, XFDASHBOARD_SELECTION_TARGET_FIRST);
			if(selection) xfdashboard_focusable_set_selection(self, selection);
		}

		/* Style selection if available */
		if(selection &&
			XFDASHBOARD_IS_STYLABLE(selection))
		{
			xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(selection), "selected");
		}

		g_debug("Set selection to %s for focused actor %s",
				G_OBJECT_TYPE_NAME(self),
				selection ? G_OBJECT_TYPE_NAME(selection) : "<nil>");
	}

	/* Emit signal */
	g_signal_emit(self, XfdashboardFocusableSignals[SIGNAL_FOCUS_GAINED], 0, self);
	g_debug("Emitted signal 'focus-gained' for focused actor %s", G_OBJECT_TYPE_NAME(self));
}
Example #3
0
/* Adds a pseudo-class to existing pseudo-classes of an object */
void xfdashboard_stylable_add_pseudo_class(XfdashboardStylable *self, const gchar *inClass)
{
	const gchar		*classes;

	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));
	g_return_if_fail(inClass && inClass[0]);

	/* If pesudo-class is already in list of pseudo-classes do nothing
	 * otherwise set new value.
	 */
	classes=xfdashboard_stylable_get_pseudo_classes(self);
	if(!classes ||
		!_xfdashboard_stylable_list_contains(inClass, -1, classes, ':'))
	{
		gchar					*newClasses;

		/* Create new temporary string by concatenating current pseudo-classes
		 * and new psuedo-class with colon separator. Set this new string
		 * representing list of pseudo-classes.
		 */
		if(classes) newClasses=g_strconcat(classes, ":", inClass, NULL);
			else newClasses=g_strdup(inClass);

		xfdashboard_stylable_set_pseudo_classes(self, newClasses);

		g_free(newClasses);
	}
}
Example #4
0
/* Dump actors */
static void _xfdashboard_dump_actor_print(ClutterActor *inActor, gint inLevel)
{
	XfdashboardStylable		*stylable;
	ClutterActorBox			allocation;
	gint					i;

	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
	g_return_if_fail(inLevel>=0);

	/* Check if actor is stylable to retrieve style configuration */
	stylable=NULL;
	if(XFDASHBOARD_IS_STYLABLE(inActor)) stylable=XFDASHBOARD_STYLABLE(inActor);

	/* Dump actor */
	for(i=0; i<inLevel; i++) g_print("  ");
	clutter_actor_get_allocation_box(inActor, &allocation);
	g_print("+- %s@%p [%s%s%s%s%s%s] - geometry: %.2f,%.2f [%.2fx%.2f], mapped: %s, visible: %s, layout: %s, children: %d\n",
				G_OBJECT_TYPE_NAME(inActor), inActor,
				clutter_actor_get_name(inActor) ? " #" : "",
				clutter_actor_get_name(inActor) ? clutter_actor_get_name(inActor) : "",
				stylable && xfdashboard_stylable_get_classes(stylable) ? "." : "",
				stylable && xfdashboard_stylable_get_classes(stylable) ? xfdashboard_stylable_get_classes(stylable) : "",
				stylable && xfdashboard_stylable_get_pseudo_classes(stylable) ? ":" : "",
				stylable && xfdashboard_stylable_get_pseudo_classes(stylable) ? xfdashboard_stylable_get_pseudo_classes(stylable) : "",
				allocation.x1,
				allocation.y1,
				allocation.x2-allocation.x1,
				allocation.y2-allocation.y1,
				clutter_actor_is_mapped(inActor) ? "yes" : "no",
				clutter_actor_is_visible(inActor) ? "yes" : "no",
				clutter_actor_get_layout_manager(inActor) ? G_OBJECT_TYPE_NAME(clutter_actor_get_layout_manager(inActor)) : "none",
				clutter_actor_get_n_children(inActor));

}
Example #5
0
/* Invalidate all stylable children recursively beginning at given actor */
static void _xfdashboard_actor_invalidate_recursive(ClutterActor *inActor)
{
	ClutterActor			*child;
	ClutterActorIter		actorIter;

	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));

	/* If actor is stylable invalidate it to get its style recomputed */
	if(XFDASHBOARD_IS_STYLABLE(inActor))
	{
		xfdashboard_stylable_invalidate(XFDASHBOARD_STYLABLE(inActor));
	}

	/* Recompute styles for all children recursively */
	clutter_actor_iter_init(&actorIter, inActor);
	while(clutter_actor_iter_next(&actorIter, &child))
	{
		/* Call ourselve recursive with child as top-level actor.
		 * We return immediately if it has no children but invalidate child
		 * before. If it has children it will first invalidated and will be
		 * iterated over its children then. In both cases the child will
		 * be invalidated.
		 */
		_xfdashboard_actor_invalidate_recursive(child);
	}
}
Example #6
0
/* Check if this focusable actor has the focus */
static gboolean _xfdashboard_focusable_has_focus(XfdashboardFocusable *self)
{
	XfdashboardFocusManager		*focusManager;
	gboolean					hasFocus;

	g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(self), FALSE);

	hasFocus=FALSE;

	/* Ask focus manager which actor has the current focus and
	 * check if it is this focusable actor.
	 */
	focusManager=xfdashboard_focus_manager_get_default();
	hasFocus=xfdashboard_focus_manager_has_focus(focusManager, self);
	g_object_unref(focusManager);

	/* If focus manager says this focusable has not the focus then
	 * it might a proxy who has the focus (as seen by focus manager)
	 * but in real this focusable actor is the destination of the
	 * proxy so check for style class "focus" being set.
	 */
	if(!hasFocus &&
		XFDASHBOARD_IS_STYLABLE(self) &&
		xfdashboard_stylable_has_class(XFDASHBOARD_STYLABLE(self), "focus"))
	{
		hasFocus=TRUE;
	}

	return(hasFocus);
}
Example #7
0
/* Check and score this selector against a stylable node.
 * A score below 0 means that they did not match.
 */
gint xfdashboard_css_selector_score_matching_stylable_node(XfdashboardCssSelector *self, XfdashboardStylable *inStylable)
{
	g_return_val_if_fail(XFDASHBOARD_IS_CSS_SELECTOR(self), -1);
	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(inStylable), -1);

	/* Check and score rules */
	return(_xfdashboard_css_selector_score_matching_node(self->priv->rule, inStylable));
}
Example #8
0
/* Call virtual function "unset_focus" */
void xfdashboard_focusable_unset_focus(XfdashboardFocusable *self)
{
	XfdashboardFocusableInterface		*iface;
	ClutterActor						*selection;

	g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(self));

	iface=XFDASHBOARD_FOCUSABLE_GET_IFACE(self);

	/* Call virtual function */
	if(iface->unset_focus)
	{
		iface->unset_focus(self);
	}

	/* Remove style from unfocused actor */
	if(XFDASHBOARD_IS_STYLABLE(self))
	{
		xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(self), "focus");
	}

	/* If actor supports selection get current selection and unstyle it */
	if(xfdashboard_focusable_supports_selection(self))
	{
		/* Get current selection */
		selection=xfdashboard_focusable_get_selection(self);

		/* unstyle selection if available */
		if(selection &&
			XFDASHBOARD_IS_STYLABLE(selection))
		{
			xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(selection), "selected");
		}

		g_debug("Unstyled selection %s for focus loosing actor %s",
				G_OBJECT_TYPE_NAME(self),
				selection ? G_OBJECT_TYPE_NAME(selection) : "<nil>");
	}

	/* Emit signal */
	g_signal_emit(self, XfdashboardFocusableSignals[SIGNAL_FOCUS_LOST], 0, self);
	g_debug("Emitted signal 'focus-lost' for focused actor %s", G_OBJECT_TYPE_NAME(self));
}
Example #9
0
/* Removed a pseudo-class to existing classes of an object */
void xfdashboard_stylable_remove_pseudo_class(XfdashboardStylable *self, const gchar *inClass)
{
	const gchar		*classes;

	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));
	g_return_if_fail(inClass && inClass[0]);

	/* If pseudo-class is not in list of pseudo-classes do nothing
	 * otherwise set new value.
	 */
	classes=xfdashboard_stylable_get_pseudo_classes(self);
	if(classes &&
		_xfdashboard_stylable_list_contains(inClass, -1, classes, ':'))
	{
		gchar					**oldClasses, **entry;
		gchar					*newClasses, *newClassesTemp;

		/* Create new temporary string with all current pseudo-classes
		 * separated by colon not matching pseudo-class to remove.
		 * Set this new string representing list of pseudo-classes.
		 */
		entry=oldClasses=g_strsplit(classes, ":", -1);
		newClasses=NULL;
		while(*entry)
		{
			if(!strcmp(*entry, inClass))
			{
				entry++;
				continue;
			}

			if(newClasses)
			{
				newClassesTemp=g_strconcat(newClasses, ":", *entry, NULL);
				g_free(newClasses);
				newClasses=newClassesTemp;
			}
				else newClasses=g_strdup(*entry);

			entry++;
		}

		xfdashboard_stylable_set_pseudo_classes(self, newClasses);

		g_strfreev(oldClasses);
		g_free(newClasses);
	}
}
Example #10
0
/* Default implementation of virtual function "get_name" */
static const gchar* _xfdashboard_stylable_real_get_name(XfdashboardStylable *self)
{
	const gchar			*name;

	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(self), NULL);

	name=NULL;

	/* If object implementing this interface is derived from ClutterActor
	 * get actor's name.
	 */
	if(CLUTTER_IS_ACTOR(self)) name=clutter_actor_get_name(CLUTTER_ACTOR(self));

	/* Return determined name for stylable object */
	return(name);
}
Example #11
0
/* Get stylable parent of actor */
static XfdashboardStylable* _xfdashboard_actor_stylable_get_parent(XfdashboardStylable *inStylable)
{
	ClutterActor			*self;
	ClutterActor			*parent;

	g_return_val_if_fail(CLUTTER_IS_ACTOR(inStylable), NULL);

	self=CLUTTER_ACTOR(inStylable);

	/* Get parent and check if stylable. If not return NULL. */
	parent=clutter_actor_get_parent(self);
	if(!XFDASHBOARD_IS_STYLABLE(parent)) return(NULL);

	/* Return stylable parent */
	return(XFDASHBOARD_STYLABLE(parent));
}
/* Dispose this object */
static void _xfdashboard_popup_menu_item_meta_dispose(GObject *inObject)
{
	XfdashboardPopupMenuItemMeta			*self=XFDASHBOARD_POPUP_MENU_ITEM_META(inObject);
	XfdashboardPopupMenuItemMetaPrivate		*priv=self->priv;

	/* Release our allocated variables */
	if(priv->popupMenu)
	{
		g_object_remove_weak_pointer(G_OBJECT(priv->popupMenu), (gpointer*)&priv->popupMenu);
		priv->popupMenu=NULL;
	}

	if(priv->menuItem)
	{
		/* Remove style from menu item if possible */
		if(XFDASHBOARD_IS_STYLABLE(priv->menuItem))
		{
			xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(priv->menuItem), "popup-menu-item");
		}

		/* Remove click action from menu item actor */
		if(priv->clickAction)
		{
			clutter_actor_remove_action(priv->menuItem, priv->clickAction);
			priv->clickAction=NULL;
		}

		/* Release menu item actor */
		g_object_remove_weak_pointer(G_OBJECT(priv->menuItem), (gpointer*)&priv->menuItem);
		priv->menuItem=NULL;
	}

	if(priv->callback)
	{
		priv->callback=NULL;
	}

	if(priv->userData)
	{
		priv->userData=NULL;
	}

	/* Call parent's class dispose method */
	G_OBJECT_CLASS(xfdashboard_popup_menu_item_meta_parent_class)->dispose(inObject);
}
Example #13
0
/* Call virtual function "set_pseudo_classes" */
void xfdashboard_stylable_set_pseudo_classes(XfdashboardStylable *self, const gchar *inClasses)
{
	XfdashboardStylableInterface		*iface;

	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));

	iface=XFDASHBOARD_STYLABLE_GET_IFACE(self);

	/* Call virtual function */
	if(iface->set_pseudo_classes)
	{
		iface->set_pseudo_classes(self, inClasses);
		return;
	}

	/* If we get here the virtual function was not overridden */
	XFDASHBOARD_STYLABLE_WARN_NOT_IMPLEMENTED(self, "set_pseudo_classes");
}
Example #14
0
/* Call virtual function "get_classes" */
const gchar* xfdashboard_stylable_get_classes(XfdashboardStylable *self)
{
	XfdashboardStylableInterface		*iface;

	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(self), NULL);

	iface=XFDASHBOARD_STYLABLE_GET_IFACE(self);

	/* Call virtual function */
	if(iface->get_classes)
	{
		return(iface->get_classes(self));
	}

	/* If we get here the virtual function was not overridden */
	XFDASHBOARD_STYLABLE_WARN_NOT_IMPLEMENTED(self, "get_classes");
	return(NULL);
}
Example #15
0
/* Call virtual function "invalidate" */
void xfdashboard_stylable_invalidate(XfdashboardStylable *self)
{
	XfdashboardStylableInterface		*iface;

	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));

	iface=XFDASHBOARD_STYLABLE_GET_IFACE(self);

	/* Call virtual function */
	if(iface->invalidate)
	{
		iface->invalidate(self);
		return;
	}

	/* If we get here the virtual function was not overridden */
	XFDASHBOARD_STYLABLE_WARN_NOT_IMPLEMENTED(self, "invalidate");
}
/* Set menu item actor */
static void _xfdashboard_popup_menu_item_meta_set_menu_item(XfdashboardPopupMenuItemMeta *self,
															ClutterActor *inMenuItem)
{
	XfdashboardPopupMenuItemMetaPrivate		*priv;

	g_return_if_fail(XFDASHBOARD_IS_POPUP_MENU_ITEM_META(self));
	g_return_if_fail(CLUTTER_IS_ACTOR(inMenuItem));

	priv=self->priv;

	/* This function can only be called once so no menu item must be set yet */
	if(priv->menuItem || priv->clickAction)
	{
		g_critical(_("Attempting to set menu item %s at %s but it is already set."),
					G_OBJECT_TYPE_NAME(inMenuItem),
					G_OBJECT_TYPE_NAME(self));
		return;
	}

	/* Set value if changed */
	if(priv->menuItem!=inMenuItem)
	{
		/* Set value */
		priv->menuItem=inMenuItem;
		g_object_add_weak_pointer(G_OBJECT(priv->menuItem), (gpointer*)&priv->menuItem);

		/* Apply style for menu item if possible */
		if(XFDASHBOARD_IS_STYLABLE(priv->menuItem))
		{
			xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(priv->menuItem), "popup-menu-item");
		}

		/* Create click action and add it to menu item actor */
		priv->clickAction=xfdashboard_click_action_new();
		g_signal_connect_swapped(priv->clickAction,
									"clicked",
									G_CALLBACK(_xfdashboard_popup_menu_item_meta_clicked),
									self);
		clutter_actor_add_action(priv->menuItem, priv->clickAction);

		/* Notify about property change */
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardPopupMenuItemMetaProperties[PROP_MENU_ITEM]);
	}
}
Example #17
0
/* Determine if a specific pseudo-class is being set at object */
gboolean xfdashboard_stylable_has_pseudo_class(XfdashboardStylable *self, const gchar *inClass)
{
	const gchar		*classes;
	gboolean		result;

	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(self), FALSE);
	g_return_val_if_fail(inClass && inClass[0], FALSE);

	result=FALSE;

	/* Get classes set at object and check if it has the expected one */
	classes=xfdashboard_stylable_get_pseudo_classes(self);
	if(classes &&
		_xfdashboard_stylable_list_contains(inClass, -1, classes, ':'))
	{
		result=TRUE;
	}

	/* Return result */
	return(result);
}
Example #18
0
/* Internal function to traverse an actor which can be call recursively */
static gboolean _xfdashboard_traverse_actor_internal(ClutterActor *inActor,
														XfdashboardCssSelector *inSelector,
														XfdashboardTraversalCallback inCallback,
														gpointer inUserData)
{
	ClutterActorIter	iter;
	ClutterActor		*child;
	gint				score;
	gboolean			doContinueTraversal;

	g_return_val_if_fail(CLUTTER_IS_ACTOR(inActor), XFDASHBOARD_TRAVERSAL_CONTINUE);
	g_return_val_if_fail(XFDASHBOARD_IS_CSS_SELECTOR(inSelector), XFDASHBOARD_TRAVERSAL_CONTINUE);
	g_return_val_if_fail(inCallback, XFDASHBOARD_TRAVERSAL_CONTINUE);

	/* Check if given actor matches selector if a selector is provided
	 * otherwise each child will match. Call callback for matching children.
	 */
	if(XFDASHBOARD_IS_STYLABLE(inActor))
	{
		score=xfdashboard_css_selector_score_matching_stylable_node(inSelector, XFDASHBOARD_STYLABLE(inActor));
		if(score>=0)
		{
			doContinueTraversal=(inCallback)(inActor, inUserData);
			if(!doContinueTraversal) return(doContinueTraversal);
		}
	}

	/* For each child of actor call ourselve recursive */
	clutter_actor_iter_init(&iter, inActor);
	while(clutter_actor_iter_next(&iter, &child))
	{
		doContinueTraversal=_xfdashboard_traverse_actor_internal(child, inSelector, inCallback, inUserData);
		if(!doContinueTraversal) return(doContinueTraversal);
	}

	/* If we get here return and continue traversal */
	return(XFDASHBOARD_TRAVERSAL_CONTINUE);
}
Example #19
0
/* Find and add parameter specification of a stylable property to hashtable */
gboolean xfdashboard_stylable_add_stylable_property(XfdashboardStylable *self,
													GHashTable *ioStylableProperties,
													const gchar *inProperty)
{
	GParamSpec							*spec;

	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(self), FALSE);

	/* Find property in instance */
	spec=g_object_class_find_property(G_OBJECT_GET_CLASS(self), inProperty);
	if(!spec)
	{
		g_warning(_("Could not find property '%s' for class %s"),
					inProperty,
					G_OBJECT_TYPE_NAME(self));
		return(FALSE);
	}

	/* Add parameter specification of found property to hashtable */
	g_hash_table_insert(ioStylableProperties, g_strdup(inProperty), g_param_spec_ref(spec));

	return(TRUE);
}
Example #20
0
/* Call virtual function "get_stylable_properties" */
GHashTable* xfdashboard_stylable_get_stylable_properties(XfdashboardStylable *self)
{
	XfdashboardStylableInterface		*iface;
	GHashTable							*stylableProperties;

	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(self), NULL);

	iface=XFDASHBOARD_STYLABLE_GET_IFACE(self);

	/* Call virtual function */
	if(iface->get_stylable_properties)
	{
		/* Create hashtable to insert stylable properties at */
		stylableProperties=g_hash_table_new_full(g_str_hash,
													g_str_equal,
													g_free,
													(GDestroyNotify)g_param_spec_unref);

		/* Get stylable properties */
		iface->get_stylable_properties(self, stylableProperties);

		/* If hashtable is empty, destroy it and return NULL */
		if(g_hash_table_size(stylableProperties)==0)
		{
			g_hash_table_destroy(stylableProperties);
			stylableProperties=NULL;
		}

		/* Return hashtable with stylable properties */
		return(stylableProperties);
	}

	/* If we get here the virtual function was not overridden */
	XFDASHBOARD_STYLABLE_WARN_NOT_IMPLEMENTED(self, "get_stylable_properties");
	return(NULL);
}
Example #21
0
/* Call virtual function "set_selection" */
gboolean xfdashboard_focusable_set_selection(XfdashboardFocusable *self, ClutterActor *inSelection)
{
	XfdashboardFocusableInterface		*iface;
	ClutterActor						*oldSelection;
	gboolean							success;

	g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(self), FALSE);
	g_return_val_if_fail(!inSelection || CLUTTER_IS_ACTOR(inSelection), FALSE);

	iface=XFDASHBOARD_FOCUSABLE_GET_IFACE(self);

	/* If this focusable actor does not support selection we should ask for
	 * the current selection and avoid the warning being printed if this
	 * virtual function was not overridden.
	 */
	if(!xfdashboard_focusable_supports_selection(self)) return(FALSE);

	/* First get current selection */
	oldSelection=xfdashboard_focusable_get_selection(self);

	/* Do nothing if new selection is the same as the current one */
	if(inSelection==oldSelection) return(TRUE);

	/* Call virtual function */
	if(iface->set_selection)
	{
		/* Call virtual function to set selection */
		success=iface->set_selection(self, inSelection);

		/* If new selection could be set successfully, remove signal handlers
		 * from old selection and set up signal handlers for new selection.
		 */
		if(success)
		{
			/* Remove signal handlers and styles from old selection */
			if(oldSelection)
			{
				/* Remove signal handlers at old selection*/
				g_signal_handlers_disconnect_by_func(oldSelection,
														G_CALLBACK(_xfdashboard_focusable_on_selection_unavailable),
														self);

				/* Remove style from old selection */
				if(XFDASHBOARD_IS_STYLABLE(oldSelection))
				{
					xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(oldSelection), "selected");
				}
			}

			/* Set up signal handlers and styles at new selection */
			if(inSelection)
			{
				/* Set up signal handlers to get notified if new selection
				 * is going to be unavailable (e.g. hidden or destroyed)
				 */
				g_signal_connect_swapped(inSelection,
											"destroy",
											G_CALLBACK(_xfdashboard_focusable_on_selection_unavailable),
											self);
				g_signal_connect_swapped(inSelection,
											"hide",
											G_CALLBACK(_xfdashboard_focusable_on_selection_unavailable),
											self);

				/* Style new selection if this focusable actor has the focus */
				if(_xfdashboard_focusable_has_focus(self) &&
					XFDASHBOARD_IS_STYLABLE(inSelection))
				{
					xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(inSelection), "selected");
				}
			}

			/* Emit signal */
			g_signal_emit(self, XfdashboardFocusableSignals[SIGNAL_SELECTION_CHANGED], 0, oldSelection, inSelection);
		}

		/* Return result of calling virtual function */
		return(success);
	}

	/* If we get here the virtual function was not overridden */
	XFDASHBOARD_FOCUSABLE_WARN_NOT_IMPLEMENTED(self, "set_selection");
	return(FALSE);
}
Example #22
0
/* Default implementation of virtual function "invalidate" */
static void _xfdashboard_stylable_real_invalidate(XfdashboardStylable *self)
{
	XfdashboardTheme			*theme;
	XfdashboardThemeCSS			*themeCSS;
	GHashTable					*stylableProperties;
	GHashTable					*themeStyleSet;
	GHashTableIter				hashIter;
	gchar						*propertyName;
	GParamSpec					*propertyValueParamSpec;
	XfdashboardThemeCSSValue	*styleValue;

	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));

	/* Get hashtable with all stylable properties and their parameter
	 * specification for default values.
	 */
	stylableProperties=xfdashboard_stylable_get_stylable_properties(self);
	if(!stylableProperties) return;

	/* Get theme CSS */
	theme=xfdashboard_application_get_theme();
	themeCSS=xfdashboard_theme_get_css(theme);

	/* Get styled properties from theme CSS */
	themeStyleSet=xfdashboard_theme_css_get_properties(themeCSS, self);

	/* The 'property-changed' notification will be freezed and thawed
	 * (fired at once) after all stylable properties of this instance are set.
	 */
	g_object_freeze_notify(G_OBJECT(self));

	/* Iterate through stylable properties and check if we got a style of
	 * that name from theme CSS. If we find such a style set the corresponding
	 * property in object otherwise set default value to override any
	 * previous value set by theme CSS to reset it.
	 */
	g_hash_table_iter_init(&hashIter, stylableProperties);
	while(g_hash_table_iter_next(&hashIter, (gpointer*)&propertyName, (gpointer*)&propertyValueParamSpec))
	{
		/* Check if we got a style with this name from theme CSS and
		 * set style's value if found ...
		 */
		if(g_hash_table_lookup_extended(themeStyleSet, propertyName, NULL, (gpointer*)&styleValue))
		{
			GValue				cssValue=G_VALUE_INIT;
			GValue				propertyValue=G_VALUE_INIT;

			/* Convert style value to type of object property and set value
			 * if conversion was successful. Otherwise do nothing.
			 */
			g_value_init(&cssValue, G_TYPE_STRING);
			g_value_set_string(&cssValue, styleValue->string);

			g_value_init(&propertyValue, G_PARAM_SPEC_VALUE_TYPE(propertyValueParamSpec));

			if(g_param_value_convert(propertyValueParamSpec, &cssValue, &propertyValue, FALSE))
			{
				g_object_set_property(G_OBJECT(self), propertyName, &propertyValue);
			}
				else
				{
					g_warning(_("Could not transform CSS string value for property '%s' to type %s of class %s"),
								propertyName,
								g_type_name(G_PARAM_SPEC_VALUE_TYPE(propertyValueParamSpec)),
								G_OBJECT_TYPE_NAME(self));
				}

			/* Release allocated resources */
			g_value_unset(&propertyValue);
			g_value_unset(&cssValue);
		}
			/* ... otherwise set property's default value we got from
			 * stylable interface of object.
			 */
			else
			{
				GValue			propertyValue=G_VALUE_INIT;

				/* Initialize property value to its type and default value */
				g_value_init(&propertyValue, G_PARAM_SPEC_VALUE_TYPE(propertyValueParamSpec));
				g_param_value_set_default(propertyValueParamSpec, &propertyValue);

				/* Set value at object property */
				g_object_set_property(G_OBJECT(self), propertyName, &propertyValue);

				/* Release allocated resources */
				g_value_unset(&propertyValue);
			}
	}

	/* All stylable properties are set now. So thaw 'property-changed'
	 * notification now and fire all notifications at once.
	 */
	g_object_thaw_notify(G_OBJECT(self));

	/* Release allocated resources */
	g_hash_table_destroy(themeStyleSet);
	g_hash_table_destroy(stylableProperties);
}
Example #23
0
/* Check and score this selector against stylable node.
 * A score below 0 means that they did not match.
 */
static gint _xfdashboard_css_selector_score_matching_node(XfdashboardCssSelectorRule *inRule,
															XfdashboardStylable *inStylable)
{
	gint					score;
	gint					a, b, c;
	const gchar				*classes;
	const gchar				*pseudoClasses;
	const gchar				*id;

	g_return_val_if_fail(inRule, -1);
	g_return_val_if_fail(XFDASHBOARD_IS_STYLABLE(inStylable), -1);

	/* For information about how the scoring is done, see documentation
	 * "Cascading Style Sheets, level 1" of W3C, section "3.2 Cascading order"
	 * URL: http://www.w3.org/TR/2008/REC-CSS1-20080411/#cascading-order
	 *
	 * 1. Find all declarations that apply to the element/property in question.
	 *    Declarations apply if the selector matches the element in question.
	 *    If no declarations apply, the inherited value is used. If there is
	 *    no inherited value (this is the case for the 'HTML' element and
	 *    for properties that do not inherit), the initial value is used.
	 * 2. Sort the declarations by explicit weight: declarations marked
	 *    '!important' carry more weight than unmarked (normal) declarations.
	 * 3. Sort by origin: the author's style sheets override the reader's
	 *    style sheet which override the UA's default values. An imported
	 *    style sheet has the same origin as the style sheet from which it
	 *    is imported.
	 * 4. Sort by specificity of selector: more specific selectors will
	 *    override more general ones. To find the specificity, count the
	 *    number of ID attributes in the selector (a), the number of CLASS
	 *    attributes in the selector (b), and the number of tag names in
	 *    the selector (c). Concatenating the three numbers (in a number
	 *    system with a large base) gives the specificity.
	 *    Pseudo-elements and pseudo-classes are counted as normal elements
	 *    and classes, respectively.
	 * 5. Sort by order specified: if two rules have the same weight, the
	 *    latter specified wins. Rules in imported style sheets are considered
	 *    to be before any rules in the style sheet itself.
	 *
	 * NOTE: Keyword '!important' is not supported.
	 */
	a=b=c=0;

	/* Get properties for given stylable */
	id=xfdashboard_stylable_get_name(XFDASHBOARD_STYLABLE(inStylable));
	classes=xfdashboard_stylable_get_classes(XFDASHBOARD_STYLABLE(inStylable));
	pseudoClasses=xfdashboard_stylable_get_pseudo_classes(XFDASHBOARD_STYLABLE(inStylable));

	/* Check and score type of selectors but ignore NULL or universal selectors */
	if(inRule->type && inRule->type[0]!='*')
	{
		GType						ruleTypeID;
		GType						nodeTypeID;

		/* Get type of this rule */
		ruleTypeID=g_type_from_name(inRule->type);
		if(!ruleTypeID) return(-1);

		/* Get type of other rule to check against and score it */
		nodeTypeID=G_OBJECT_TYPE(inStylable);
		if(!nodeTypeID) return(-1);

		/* Check if type of this rule matches type of other rule */
		if(!g_type_is_a(nodeTypeID, ruleTypeID)) return(-1);

		/* Determine depth difference between both types
		 * which is the score of this test with a maximum of 99
		 */
		c=g_type_depth(ruleTypeID)-g_type_depth(nodeTypeID);
		c=MAX(ABS(c), 99);
	}

	/* Check and score ID */
	if(inRule->id)
	{
		/* If node has no ID return immediately */
		if(!id || strcmp(inRule->id, id)) return(-1);

		/* Score ID */
		a+=10;
	}

	/* Check and score classes */
	if(inRule->classes)
	{
		gchar				*needle;
		gint				numberMatches;

		/* If node has no pseudo class return immediately */
		if(!classes) return(-1);

		/* Check that each class from the selector's rule appears in the
		 * list of classes from the node, i.e. the selector's rule class list
		 * is a subset of the node's class list
		 */
		numberMatches=0;
		for(needle=inRule->classes; needle; needle=strchr(needle, '.'))
		{
			gint			needleLength;
			gchar			*nextNeedle;

			/* Move pointer of needle beyond class seperator '.' */
			if(needle[0]=='.') needle++;

			/* Get length of needle */
			nextNeedle=strchr(needle, '.');
			if(nextNeedle) needleLength=nextNeedle-needle;
				else needleLength=strlen(needle);

			/* If pseudo-class from the selector does not appear in the
			 * list of pseudo-classes from the node, then this is not a
			 * match
			 */
			if(!_xfdashboard_css_selector_list_contains(needle, needleLength, classes, '.')) return(-1);
			numberMatches++;
		}

		/* Score matching class */
		b=b+(10*numberMatches);
	}

	/* Check and score pseudo classes */
	if(inRule->pseudoClasses)
	{
		gchar				*needle;
		gint				numberMatches;

		/* If node has no pseudo class return immediately */
		if(!pseudoClasses) return(-1);

		/* Check that each pseudo-class from the selector appears in the
		 * pseudo-classes from the node, i.e. the selector pseudo-class list
		 * is a subset of the node's pseudo-class list
		 */
		numberMatches=0;
		for(needle=inRule->pseudoClasses; needle; needle=strchr(needle, ':'))
		{
			gint			needleLength;
			gchar			*nextNeedle;

			/* Move pointer of needle beyond pseudo-class seperator ':' */
			if(needle[0]==':') needle++;

			/* Get length of needle */
			nextNeedle=strchr(needle, ':');
			if(nextNeedle) needleLength=nextNeedle-needle;
				else needleLength=strlen(needle);

			/* If pseudo-class from the selector does not appear in the
			 * list of pseudo-classes from the node, then this is not a
			 * match
			 */
			if(!_xfdashboard_css_selector_list_contains(needle, needleLength, pseudoClasses, ':')) return(-1);
			numberMatches++;
		}

		/* Score matching pseudo-class */
		b=b+(10*numberMatches);
	}

	/* Check and score parent */
	if(inRule->parentRule &&
		inRule->parentRuleMode==XFDASHBOARD_CSS_SELECTOR_RULE_MODE_PARENT)
	{
		gint					parentScore;
		XfdashboardStylable		*parent;

		/* If node has no parent, no parent can match ;) so return immediately */
		parent=xfdashboard_stylable_get_parent(inStylable);
		if(!parent || !XFDASHBOARD_IS_STYLABLE(parent)) return(-1);

		/* Check if there are matching parents. If not return immediately. */
		parentScore=_xfdashboard_css_selector_score_matching_node(inRule->parentRule, parent);
		if(parentScore<0) return(-1);

		/* Score matching parents */
		c+=parentScore;
	}

	/* Check and score ancestor */
	if(inRule->parentRule &&
		inRule->parentRuleMode==XFDASHBOARD_CSS_SELECTOR_RULE_MODE_ANCESTOR)
	{
		gint					ancestorScore;
		XfdashboardStylable		*ancestor;

		ancestor=inStylable;

		/* If node has no parents, no ancestor can match so return immediately */
		do
		{
			ancestor=xfdashboard_stylable_get_parent(ancestor);
		}
		while(ancestor && !XFDASHBOARD_IS_STYLABLE(ancestor));

		if(!ancestor || !XFDASHBOARD_IS_STYLABLE(ancestor)) return(-1);

		/* Iterate through ancestors and check and score them */
		while(ancestor)
		{
			/* Get number of matches for ancestor and if at least one matches,
			 * stop search and score
			 */
			ancestorScore=_xfdashboard_css_selector_score_matching_node(inRule->parentRule, ancestor);
			if(ancestorScore>=0)
			{
				c+=ancestorScore;
				break;
			}

			/* Get next ancestor to check but skip actors not implementing
			 * the XfdashboardStylable interface
			 */
			do
			{
				ancestor=xfdashboard_stylable_get_parent(ancestor);
			}
			while(ancestor && !XFDASHBOARD_IS_STYLABLE(ancestor));

			if(!ancestor || !XFDASHBOARD_IS_STYLABLE(ancestor)) return(-1);
		}
	}

	/* Calculate final score */
	score=(a*10000)+(b*100)+c;
	return(score);
}
Example #24
0
void xfdashboard_focus_manager_register_after(XfdashboardFocusManager *self, XfdashboardFocusable *inFocusable, XfdashboardFocusable *inAfterFocusable)
{
	XfdashboardFocusManagerPrivate	*priv;

	g_return_if_fail(XFDASHBOARD_IS_FOCUS_MANAGER(self));
	g_return_if_fail(inFocusable);
	g_return_if_fail(!inAfterFocusable || XFDASHBOARD_IS_FOCUSABLE(inAfterFocusable));

	priv=self->priv;

	/* Check if given focusable actor is really focusable and stylable */
	if(!XFDASHBOARD_IS_FOCUSABLE(inFocusable))
	{
		g_warning(_("Object %s does not inherit %s and cannot be registered"),
					G_OBJECT_TYPE_NAME(inFocusable),
					g_type_name(XFDASHBOARD_TYPE_FOCUSABLE));
		return;
	}

	if(!XFDASHBOARD_IS_STYLABLE(inFocusable))
	{
		g_warning(_("Object %s does not inherit %s and cannot be registered"),
					G_OBJECT_TYPE_NAME(inFocusable),
					g_type_name(XFDASHBOARD_TYPE_STYLABLE));
		return;
	}

	/* Register focusable actor if not already registered */
	if(g_list_find(priv->registeredFocusables, inFocusable)==NULL)
	{
		gint						insertPosition;

		g_debug("Registering focusable %s", G_OBJECT_TYPE_NAME(inFocusable));

		/* If requested find position of focusable actor to insert new focusable actor after.
		 * Increase found position by one and add new focusable actor to list of registered
		 * focusable actors at this position. Otherwise add new focusable actor to end of list.
		 */
		insertPosition=-1;
		if(inAfterFocusable)
		{
			insertPosition=g_list_index(priv->registeredFocusables, inAfterFocusable);
			if(insertPosition!=-1) insertPosition++;
				else
				{
					g_warning(_("Could not find registered focusable object %s to register object %s - appending to end of list."),
								G_OBJECT_TYPE_NAME(inAfterFocusable),
								G_OBJECT_TYPE_NAME(inFocusable));
				}
		}
		priv->registeredFocusables=g_list_insert(priv->registeredFocusables, inFocusable, insertPosition);

		/* Connect to signals to get notified if actor is going to be destroy,
		 * unrealized or hidden to remove it from list of focusable actors.
		 */
		g_signal_connect_swapped(inFocusable,
									"destroy",
									G_CALLBACK(_xfdashboard_focus_manager_on_focusable_destroy),
									self);
		g_signal_connect_swapped(inFocusable,
									"realize",
									G_CALLBACK(_xfdashboard_focus_manager_on_focusable_hide),
									self);
		g_signal_connect_swapped(inFocusable,
									"hide",
									G_CALLBACK(_xfdashboard_focus_manager_on_focusable_hide),
									self);

		/* Emit signal */
		g_signal_emit(self, XfdashboardFocusManagerSignals[SIGNAL_REGISTERED], 0, inFocusable);
	}
}
Example #25
0
/* The current selection of a focusable actor (if focussed or not) is not available anymore
 * (e.g. hidden or destroyed). So move selection at focusable actor to next available and
 * selectable item.
 */
static void _xfdashboard_focusable_on_selection_unavailable(XfdashboardFocusable *self,
															gpointer inUserData)
{
	XfdashboardFocusableInterface		*iface;
	ClutterActor						*oldSelection;
	ClutterActor						*newSelection;
	gboolean							success;
	XfdashboardApplication				*application;

	g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(self));
	g_return_if_fail(CLUTTER_IS_ACTOR(inUserData));

	iface=XFDASHBOARD_FOCUSABLE_GET_IFACE(self);
	oldSelection=CLUTTER_ACTOR(inUserData);
	newSelection=NULL;
	success=FALSE;

	/* If application is not quitting then call virtual function to set selection
	 * which have to be available because this signal handler was set in
	 * xfdashboard_focusable_set_selection() when this virtual function was available
	 * and successfully called.
	 * If setting new selection was unsuccessful we set selection to nothing (NULL);
	 */
	application=xfdashboard_application_get_default();
	if(!xfdashboard_application_is_quitting(application))
	{
		/* Get next selection */
		newSelection=xfdashboard_focusable_find_selection(self, oldSelection, XFDASHBOARD_SELECTION_TARGET_NEXT);

		/* Set new selection */
		success=iface->set_selection(self, newSelection);
		if(!success)
		{
			success=iface->set_selection(self, newSelection);
			if(!success)
			{
				g_critical(_("Old selection %s at %s is unavailable but setting new selection either to %s or nothing failed!"),
							G_OBJECT_TYPE_NAME(oldSelection),
							G_OBJECT_TYPE_NAME(self),
							newSelection ? G_OBJECT_TYPE_NAME(newSelection) : "<nil>");
			}

			/* Now reset new selection to NULL regardless if setting selection at
			 * focusable actor was successful or not. A critical warning was displayed
			 * if is was unsuccessful because setting nothing (NULL) must succeed usually.
			 */
			newSelection=NULL;
		}
	}

	/* Regardless if setting selection was successful, remove signal handlers
	 * and styles from old selection.
	 */
	if(oldSelection)
	{
		/* Remove signal handlers at old selection*/
		g_signal_handlers_disconnect_by_func(oldSelection,
												G_CALLBACK(_xfdashboard_focusable_on_selection_unavailable),
												self);

		/* Remove style from old selection */
		if(XFDASHBOARD_IS_STYLABLE(oldSelection))
		{
			xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(oldSelection), "selected");
		}
	}

	/* If setting selection was successful, set up signal handlers and styles at new selection */
	if(success && newSelection)
	{
		/* Set up signal handlers to get notified if new selection
		 * is going to be unavailable (e.g. hidden or destroyed)
		 */
		g_signal_connect_swapped(newSelection,
									"destroy",
									G_CALLBACK(_xfdashboard_focusable_on_selection_unavailable),
									self);
		g_signal_connect_swapped(newSelection,
									"hide",
									G_CALLBACK(_xfdashboard_focusable_on_selection_unavailable),
									self);

		/* Check if this focusable actor has the focus because if it has
		 * the have to style new selection.
		 */
		if(_xfdashboard_focusable_has_focus(self) &&
			XFDASHBOARD_IS_STYLABLE(newSelection))
		{
			xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(newSelection), "selected");
		}
	}

	/* Emit signal because at least old selection has changed */
	g_signal_emit(self, XfdashboardFocusableSignals[SIGNAL_SELECTION_CHANGED], 0, oldSelection, newSelection);
}