예제 #1
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);
}
예제 #2
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);
}