Beispiel #1
0
/* Find view by internal name */
XfdashboardView* xfdashboard_viewpad_find_view_by_name(XfdashboardViewpad *self, const gchar *inInternalName)
{
	ClutterActorIter			iter;
	ClutterActor				*child;
	XfdashboardView				*view;

	g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), NULL);

	view=NULL;

	/* Iterate through children and lookup view matching requested name */
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self));
	while(!view && clutter_actor_iter_next(&iter, &child))
	{
		/* Check if child is a view and its internal name matches requested name */
		if(XFDASHBOARD_IS_VIEW(child)==TRUE &&
			g_strcmp0(xfdashboard_view_get_internal_name(XFDASHBOARD_VIEW(child)), inInternalName)==0)
		{
			view=XFDASHBOARD_VIEW(child);
		}
	}

	/* Return view found which may be NULL if no view of requested type was found */
	return(view);
}
Beispiel #2
0
static void _xfdashboard_viewpad_on_allocation_changed(ClutterActor *inActor,
														ClutterActorBox *inBox,
														ClutterAllocationFlags inFlags,
														gpointer inUserData)
{
	XfdashboardViewpad			*self;
	XfdashboardViewpadPrivate	*priv;
	XfdashboardView				*view G_GNUC_UNUSED;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(inActor));
	g_return_if_fail(XFDASHBOARD_IS_VIEW(inUserData));

	self=XFDASHBOARD_VIEWPAD(inActor);
	priv=self->priv;
	view=XFDASHBOARD_VIEW(inUserData);

	/* Defer updating scrollbars but only if view whose allocation
	 * has changed is the active one
	 */
	if(priv->scrollbarUpdateID==0)
	{
		priv->scrollbarUpdateID=
			clutter_threads_add_repaint_func_full(CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD | CLUTTER_REPAINT_FLAGS_POST_PAINT,
													_xfdashboard_viewpad_on_allocation_changed_repaint_callback,
													self,
													NULL);
	}
}
Beispiel #3
0
static void _xfdashboard_view_get_property(GObject *inObject,
											guint inPropID,
											GValue *outValue,
											GParamSpec *inSpec)
{
	XfdashboardView		*self=XFDASHBOARD_VIEW(inObject);

	switch(inPropID)
	{
		case PROP_VIEW_INTERNAL_NAME:
			g_value_set_string(outValue, self->priv->viewInternalName);
			break;

		case PROP_VIEW_NAME:
			g_value_set_string(outValue, self->priv->viewName);
			break;

		case PROP_VIEW_ICON:
			g_value_set_string(outValue, self->priv->viewIcon);
			break;

		case PROP_FIT_MODE:
			g_value_set_enum(outValue, self->priv->fitMode);
			break;

		case PROP_ENABLED:
			g_value_set_boolean(outValue, self->priv->isEnabled);
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
			break;
	}
}
Beispiel #4
0
/* Find view by type */
XfdashboardView* xfdashboard_viewpad_find_view_by_type(XfdashboardViewpad *self, GType inType)
{
	ClutterActorIter			iter;
	ClutterActor				*child;
	XfdashboardView				*view;

	g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), NULL);

	view=NULL;

	/* Iterate through children and create list of views */
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self));
	while(!view && clutter_actor_iter_next(&iter, &child))
	{
		/* Check if child is a view and of type looking for */
		if(XFDASHBOARD_IS_VIEW(child)==TRUE &&
			G_OBJECT_TYPE(child)==inType)
		{
			view=XFDASHBOARD_VIEW(child);
		}
	}

	/* Return view found which may be NULL if no view of requested type was found */
	return(view);
}
Beispiel #5
0
/* Set/get properties */
static void _xfdashboard_view_set_property(GObject *inObject,
											guint inPropID,
											const GValue *inValue,
											GParamSpec *inSpec)
{
	XfdashboardView		*self=XFDASHBOARD_VIEW(inObject);
	
	switch(inPropID)
	{
		case PROP_VIEW_INTERNAL_NAME:
			xfdashboard_view_set_internal_name(self, g_value_get_string(inValue));
			break;

		case PROP_VIEW_NAME:
			xfdashboard_view_set_name(self, g_value_get_string(inValue));
			break;
			
		case PROP_VIEW_ICON:
			xfdashboard_view_set_icon(self, g_value_get_string(inValue));
			break;

		case PROP_FIT_MODE:
			xfdashboard_view_set_fit_mode(self, (XfdashboardFitMode)g_value_get_enum(inValue));
			break;

		case PROP_ENABLED:
			xfdashboard_view_set_enabled(self, g_value_get_boolean(inValue));
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
			break;
	}
}
Beispiel #6
0
/* Dispose this object */
static void _xfdashboard_view_dispose(GObject *inObject)
{
	XfdashboardView			*self=XFDASHBOARD_VIEW(inObject);
	XfdashboardViewPrivate	*priv=self->priv;

	/* Release allocated resources */
	if(priv->viewInternalName)
	{
		g_free(priv->viewInternalName);
		priv->viewInternalName=NULL;
	}

	if(priv->viewName)
	{
		g_free(priv->viewName);
		priv->viewName=NULL;
	}

	if(priv->viewIcon)
	{
		g_free(priv->viewIcon);
		priv->viewIcon=NULL;
	}

	if(priv->viewIconImage)
	{
		g_object_unref(priv->viewIconImage);
		priv->viewIconImage=NULL;
	}

	/* Call parent's class dispose method */
	G_OBJECT_CLASS(xfdashboard_view_parent_class)->dispose(inObject);
}
Beispiel #7
0
/* Called when a view was removed to viewpad */
static void _xfdashboard_view_selector_on_view_removed(XfdashboardViewSelector *self,
														XfdashboardView *inView,
														gpointer inUserData)
{
	ClutterActorIter					iter;
	ClutterActor						*child;
	gpointer							view;

	g_return_if_fail(XFDASHBOARD_IS_VIEW_SELECTOR(self));

	/* Iterate through create views and lookup view of given type */
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self));
	while(clutter_actor_iter_next(&iter, &child))
	{
		/* Check if child is a button otherwise continue iterating */
		if(!XFDASHBOARD_IS_TOGGLE_BUTTON(child)) continue;

		/* If button has reference to view destroy it */
		view=g_object_get_data(G_OBJECT(child), "view");
		if(XFDASHBOARD_IS_VIEW(view) && XFDASHBOARD_VIEW(view)==inView)
		{
			clutter_actor_destroy(child);
		}
	}
}
Beispiel #8
0
/* A view was disabled */
static void _xfdashboard_viewpad_on_view_disabled(XfdashboardViewpad *self, XfdashboardView *inView)
{
	XfdashboardViewpadPrivate	*priv;
	ClutterActorIter			iter;
	ClutterActor				*child;
	XfdashboardView				*firstActivatableView;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self));
	g_return_if_fail(XFDASHBOARD_IS_VIEW(inView));

	priv=self->priv;
	firstActivatableView=NULL;

	/* If the currently disabled view is the active one, activate a next available view */
	if(inView==priv->activeView)
	{
		/* Iterate through create views and lookup view of given type */
		clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self));
		while(clutter_actor_iter_next(&iter, &child))
		{
			/* Check if child is a view otherwise continue iterating */
			if(XFDASHBOARD_IS_VIEW(child)!=TRUE) continue;

			/* If child is not the view being disabled check if it could
			 * become the next activatable view
			 * the first activatable view after we destroyed all views found.
			 */
			if(XFDASHBOARD_VIEW(child)!=inView &&
				xfdashboard_view_get_enabled(XFDASHBOARD_VIEW(child)))
			{
				firstActivatableView=XFDASHBOARD_VIEW(child);
			}
		}

		/* Now activate the first activatable view we found during iteration.
		 * It can also be no view (NULL pointer).
		 */
		g_debug("Disabled view %s was the active view in %s - will activate %s",
					G_OBJECT_TYPE_NAME(inView),
					G_OBJECT_TYPE_NAME(self),
					firstActivatableView ? G_OBJECT_TYPE_NAME(firstActivatableView) : "no other view");
		_xfdashboard_viewpad_activate_view(self, firstActivatableView);
	}
}
Beispiel #9
0
/* Create view of given type and add to this actor */
static void _xfdashboard_viewpad_add_view(XfdashboardViewpad *self, GType inViewType)
{
	XfdashboardViewpadPrivate	*priv;
	GObject						*view;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self));

	priv=self->priv;

	/* Create instance and check if it is a view */
	g_debug("Creating view %s for viewpad", g_type_name(inViewType));

	view=g_object_new(inViewType, NULL);
	if(view==NULL)
	{
		g_critical(_("Failed to create view instance of %s"), g_type_name(inViewType));
		return;
	}

	if(XFDASHBOARD_IS_VIEW(view)!=TRUE)
	{
		g_critical(_("Instance %s is not a %s and cannot be added to %s"),
					g_type_name(inViewType), g_type_name(XFDASHBOARD_TYPE_VIEW), G_OBJECT_TYPE_NAME(self));
		return;
	}

	/* Add new view instance to this actor but hidden */
	clutter_actor_hide(CLUTTER_ACTOR(view));
	clutter_actor_add_child(CLUTTER_ACTOR(self), CLUTTER_ACTOR(view));
	g_signal_connect_swapped(view, "allocation-changed", G_CALLBACK(_xfdashboard_viewpad_on_allocation_changed), self);
	g_signal_connect_swapped(view, "scroll-to", G_CALLBACK(_xfdashboard_viewpad_on_view_scroll_to), self);
	g_signal_connect_swapped(view, "ensure-visible", G_CALLBACK(_xfdashboard_viewpad_on_view_ensure_visible), self);
	g_signal_connect_swapped(view, "disabled", G_CALLBACK(_xfdashboard_viewpad_on_view_disabled), self);
	g_signal_connect_swapped(view, "enabled", G_CALLBACK(_xfdashboard_viewpad_on_view_enabled), self);
	g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_ADDED], 0, view);

	/* Set active view if none active (usually it is the first view created) */
	if(priv->activeView==NULL &&
		xfdashboard_view_get_enabled(XFDASHBOARD_VIEW(view)))
	{
		_xfdashboard_viewpad_activate_view(self, XFDASHBOARD_VIEW(view));
	}
}
Beispiel #10
0
/* Called when a view type was unregistered */
static void _xfdashboard_viewpad_on_view_unregistered(XfdashboardViewpad *self,
														GType inViewType,
														gpointer inUserData)
{
	XfdashboardViewpadPrivate	*priv;
	ClutterActorIter			iter;
	ClutterActor				*child;
	ClutterActor				*firstActivatableView;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self));

	priv=self->priv;
	firstActivatableView=NULL;

	/* Iterate through create views and lookup view of given type */
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self));
	while(clutter_actor_iter_next(&iter, &child))
	{
		/* Check if child is a view otherwise continue iterating */
		if(XFDASHBOARD_IS_VIEW(child)!=TRUE) continue;

		/* If child is not of type being unregistered it will get
		 * the first activatable view after we destroyed all views found.
		 */
		if(G_OBJECT_TYPE(child)!=inViewType)
		{
			if(xfdashboard_view_get_enabled(XFDASHBOARD_VIEW(child))) firstActivatableView=child;
		}
			else
			{
				if(G_OBJECT(child)==G_OBJECT(priv->activeView)) _xfdashboard_viewpad_activate_view(self, NULL);
				g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_REMOVED], 0, child);
				clutter_actor_destroy(child);
			}
	}

	/* Now activate the first activatable view we found during iteration */
	if(firstActivatableView) _xfdashboard_viewpad_activate_view(self, XFDASHBOARD_VIEW(firstActivatableView));
}
Beispiel #11
0
/* A view button was clicked to activate it */
static void _xfdashboard_view_selector_on_view_button_clicked(XfdashboardViewSelector *self, gpointer inUserData)
{
	XfdashboardViewSelectorPrivate		*priv;
	XfdashboardToggleButton				*button;
	XfdashboardView						*view;

	g_return_if_fail(XFDASHBOARD_IS_VIEW_SELECTOR(self));
	g_return_if_fail(XFDASHBOARD_IS_BUTTON(inUserData));

	priv=self->priv;
	button=XFDASHBOARD_TOGGLE_BUTTON(inUserData);

	view=XFDASHBOARD_VIEW(g_object_get_data(G_OBJECT(button), "view"));

	xfdashboard_viewpad_set_active_view(priv->viewpad, view);
}
Beispiel #12
0
/**
 * xfdashboard_view_selector_set_viewpad:
 * @self: A #XfdashboardViewSelector
 * @inViewpad: The #XfdashboardViewpad whose views to show at this actor
 *
 * Sets the #XfdashboardViewpad whose views to show as a choice of views
 * at @self.
 */
void xfdashboard_view_selector_set_viewpad(XfdashboardViewSelector *self, XfdashboardViewpad *inViewpad)
{
	XfdashboardViewSelectorPrivate		*priv;
	GList								*views, *entry;

	g_return_if_fail(XFDASHBOARD_IS_VIEW_SELECTOR(self));
	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(inViewpad));

	priv=self->priv;

	/* Only set new value if it differs from current value */
	if(priv->viewpad==inViewpad) return;

	/* Release old viewpad if available */
	if(priv->viewpad)
	{
		/* Destroy all children */
		clutter_actor_destroy_all_children(CLUTTER_ACTOR(self));

		/* Release old viewpad */
		g_signal_handlers_disconnect_by_data(priv->viewpad, self);
		g_object_unref(priv->viewpad);
		priv->viewpad=NULL;
	}

	/* Set new value */
	priv->viewpad=XFDASHBOARD_VIEWPAD(g_object_ref(inViewpad));
	g_signal_connect_swapped(priv->viewpad, "view-added", G_CALLBACK(_xfdashboard_view_selector_on_view_added), self);
	g_signal_connect_swapped(priv->viewpad, "view-removed", G_CALLBACK(_xfdashboard_view_selector_on_view_removed), self);

	/* Create instance of each registered view type and add it to this actor
	 * and connect signals
	 */
	views=xfdashboard_viewpad_get_views(priv->viewpad);
	for(entry=views; entry; entry=g_list_next(entry))
	{
		_xfdashboard_view_selector_on_view_added(self, XFDASHBOARD_VIEW(entry->data), NULL);
	}
	g_list_free(views);

	/* Notify about property change */
	g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewSelectorProperties[PROP_VIEWPAD]);
}
Beispiel #13
0
/* Scroll to requested position in view */
static void _xfdashboard_viewpad_on_view_scroll_to(XfdashboardViewpad *self,
													gfloat inX,
													gfloat inY,
													gpointer inUserData)
{
	XfdashboardViewpadPrivate	*priv;
	XfdashboardView				*view;
	gfloat						x, y, w, h;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self));
	g_return_if_fail(XFDASHBOARD_IS_VIEW(inUserData));

	priv=self->priv;
	view=XFDASHBOARD_VIEW(inUserData);

	/* If to-scroll view is the active view in viewpad
	 * just set scrollbar value to the new ones
	 */
	if(view==priv->activeView)
	{
		if(inX>=0.0f) xfdashboard_scrollbar_set_value(XFDASHBOARD_SCROLLBAR(priv->hScrollbar), inX);
		if(inY>=0.0f) xfdashboard_scrollbar_set_value(XFDASHBOARD_SCROLLBAR(priv->vScrollbar), inY);
	}
		/* If to-scroll view is not the active one update its clipping */
		else
		{
			if(clutter_actor_has_clip(CLUTTER_ACTOR(view)))
			{
				clutter_actor_get_clip(CLUTTER_ACTOR(view), &x, &y, &w, &h);
				if(inX>=0.0f) x=inX;
				if(inY>=0.0f) y=inY;
			}
				else
				{
					x=y=0.0f;
					clutter_actor_get_size(CLUTTER_ACTOR(view), &w, &h);
				}
			clutter_actor_set_clip(CLUTTER_ACTOR(view), x, y, w, h);
		}
}
Beispiel #14
0
/* Allocate position and size of actor and its children */
static void _xfdashboard_viewpad_allocate(ClutterActor *self,
											const ClutterActorBox *inBox,
											ClutterAllocationFlags inFlags)
{
	XfdashboardViewpadPrivate	*priv=XFDASHBOARD_VIEWPAD(self)->priv;
	ClutterActorClass			*actorClass=CLUTTER_ACTOR_CLASS(xfdashboard_viewpad_parent_class);
	gfloat						viewWidth, viewHeight;
	gfloat						vScrollbarWidth, vScrollbarHeight;
	gfloat						hScrollbarWidth, hScrollbarHeight;
	gboolean					hScrollbarVisible, vScrollbarVisible;
	ClutterActorBox				*box;
	gfloat						x, y, w, h;

	/* Chain up to store the allocation of the actor */
	if(actorClass->allocate) actorClass->allocate(self, inBox, inFlags);

	/* Initialize largest possible allocation for view and determine
	 * real size of view to show. The real size is used to determine
	 * scroll bar visibility if policy is automatic */
	viewWidth=clutter_actor_box_get_width(inBox);
	viewHeight=clutter_actor_box_get_height(inBox);

	/* Determine visibility of scroll bars */
	hScrollbarVisible=FALSE;
	if(priv->hScrollbarPolicy==XFDASHBOARD_POLICY_ALWAYS ||
		(priv->hScrollbarPolicy==XFDASHBOARD_POLICY_AUTOMATIC &&
			xfdashboard_scrollbar_get_range(XFDASHBOARD_SCROLLBAR(priv->hScrollbar))>viewWidth))
	{
		hScrollbarVisible=TRUE;
	}
	if(xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_HORIZONTAL ||
		xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_BOTH)
	{
		hScrollbarVisible=FALSE;
	}

	vScrollbarVisible=FALSE;
	if(priv->vScrollbarPolicy==XFDASHBOARD_POLICY_ALWAYS ||
		(priv->vScrollbarPolicy==XFDASHBOARD_POLICY_AUTOMATIC &&
			xfdashboard_scrollbar_get_range(XFDASHBOARD_SCROLLBAR(priv->vScrollbar))>viewHeight))
	{
		vScrollbarVisible=TRUE;
	}
	if(xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_VERTICAL ||
		xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_BOTH)
	{
		vScrollbarVisible=FALSE;
	}

	/* Set allocation for visible scroll bars */
	vScrollbarWidth=0.0f;
	vScrollbarHeight=viewHeight;
	clutter_actor_get_preferred_width(priv->vScrollbar, -1, NULL, &vScrollbarWidth);

	hScrollbarWidth=viewWidth;
	hScrollbarHeight=0.0f;
	clutter_actor_get_preferred_height(priv->hScrollbar, -1, NULL, &hScrollbarHeight);

	if(hScrollbarVisible && vScrollbarVisible)
	{
		vScrollbarHeight-=hScrollbarHeight;
		hScrollbarWidth-=vScrollbarWidth;
	}

	if(vScrollbarVisible==FALSE) box=clutter_actor_box_new(0, 0, 0, 0);
		else box=clutter_actor_box_new(viewWidth-vScrollbarWidth, 0, viewWidth, vScrollbarHeight);
	clutter_actor_allocate(priv->vScrollbar, box, inFlags);
	clutter_actor_box_free(box);

	if(hScrollbarVisible==FALSE) box=clutter_actor_box_new(0, 0, 0, 0);
		else box=clutter_actor_box_new(0, viewHeight-hScrollbarHeight, hScrollbarWidth, viewHeight);
	clutter_actor_allocate(priv->hScrollbar, box, inFlags);
	clutter_actor_box_free(box);

	/* Reduce allocation for view by any visible scroll bar
	 * and set allocation and clipping of view
	 */
	if(priv->activeView)
	{
		/* Set allocation */
		if(vScrollbarVisible) viewWidth-=vScrollbarWidth;
		if(hScrollbarVisible) viewHeight-=hScrollbarHeight;

		x=y=0.0f;
		if(clutter_actor_has_clip(CLUTTER_ACTOR(priv->activeView)))
		{
			clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, NULL, NULL);
		}

		switch(xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView)))
		{
			case XFDASHBOARD_FIT_MODE_BOTH:
				w=viewWidth;
				h=viewHeight;
				break;

			case XFDASHBOARD_FIT_MODE_HORIZONTAL:
				w=viewWidth;
				clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->activeView), w, NULL, &h);
				break;

			case XFDASHBOARD_FIT_MODE_VERTICAL:
				h=viewHeight;
				clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->activeView), h, NULL, &w);
				break;

			default:
				clutter_actor_get_preferred_size(CLUTTER_ACTOR(priv->activeView), NULL, NULL, &w, &h);
				break;
		}

		box=clutter_actor_box_new(0, 0, w, h);
		clutter_actor_allocate(CLUTTER_ACTOR(priv->activeView), box, inFlags);
		clutter_actor_box_free(box);

		clutter_actor_set_clip(CLUTTER_ACTOR(priv->activeView), x, y, viewWidth, viewHeight);
	}

	/* Only set value if it changes */
	if(priv->hScrollbarVisible!=hScrollbarVisible)
	{
		/* Set new value */
		priv->hScrollbarVisible=hScrollbarVisible;

		/* Notify about property change */
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_HSCROLLBAR_VISIBLE]);
	}

	if(priv->vScrollbarVisible!=vScrollbarVisible)
	{
		/* Set new value */
		priv->vScrollbarVisible=vScrollbarVisible;

		/* Notify about property change */
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_VSCROLLBAR_VISIBLE]);
	}
}
Beispiel #15
0
/* Ensure that a child of a view is visible by scrolling if needed */
static void _xfdashboard_viewpad_on_view_ensure_visible(XfdashboardViewpad *self,
														ClutterActor *inActor,
														gpointer inUserData)
{
	XfdashboardViewpadPrivate	*priv;
	XfdashboardView				*view;
	ClutterVertex				origin;
	ClutterVertex				transformedUpperLeft;
	ClutterVertex				transformedLowerRight;
	gfloat						x, y, w, h;
	gboolean					needScrolling;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self));
	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
	g_return_if_fail(XFDASHBOARD_IS_VIEW(inUserData));

	priv=self->priv;
	view=XFDASHBOARD_VIEW(inUserData);
	needScrolling=FALSE;
	origin.z=0.0f;

	/* Get position and size of view but respect scrolled position */
	if(view==priv->activeView)
	{
		x=xfdashboard_scrollbar_get_value(XFDASHBOARD_SCROLLBAR(priv->hScrollbar));
		y=xfdashboard_scrollbar_get_value(XFDASHBOARD_SCROLLBAR(priv->vScrollbar));
		clutter_actor_get_size(CLUTTER_ACTOR(self), &w, &h);
	}
		else
		{
			if(clutter_actor_has_clip(CLUTTER_ACTOR(view)))
			{
				clutter_actor_get_clip(CLUTTER_ACTOR(view), &x, &y, &w, &h);
			}
				else
				{
					x=y=0.0f;
					clutter_actor_get_size(CLUTTER_ACTOR(view), &w, &h);
				}
		}

	/* Check that upper left point of actor is visible otherwise set flag for scrolling */
	origin.x=origin.y=0.0f;
	clutter_actor_apply_relative_transform_to_point(inActor, CLUTTER_ACTOR(view), &origin, &transformedUpperLeft);
	if(transformedUpperLeft.x<x ||
		transformedUpperLeft.x>(x+w) ||
		transformedUpperLeft.y<y ||
		transformedUpperLeft.y>(y+h))
	{
		needScrolling=TRUE;
	}

	/* Check that lower right point of actor is visible otherwise set flag for scrolling */
	clutter_actor_get_size(inActor, &origin.x, &origin.y);
	clutter_actor_apply_relative_transform_to_point(inActor, CLUTTER_ACTOR(view), &origin, &transformedLowerRight);
	if(transformedLowerRight.x<x ||
		transformedLowerRight.x>(x+w) ||
		transformedLowerRight.y<y ||
		transformedLowerRight.y>(y+h))
	{
		needScrolling=TRUE;
	}

	/* Check if we need to scroll */
	if(needScrolling)
	{
		gfloat					distanceUpperLeft;
		gfloat					distanceLowerRight;

		/* Find shortest way to scroll and then scroll */
		distanceUpperLeft=sqrtf(powf(transformedUpperLeft.x-x, 2.0f)+powf(transformedUpperLeft.y-y, 2.0f));
		distanceLowerRight=sqrtf(powf(transformedLowerRight.x-(x+w), 2.0f)+powf(transformedLowerRight.y-(y+h), 2.0f));

		if(distanceUpperLeft<=distanceLowerRight)
		{
			_xfdashboard_viewpad_on_view_scroll_to(self, transformedUpperLeft.x, transformedUpperLeft.y, view);
		}
			else
			{
				_xfdashboard_viewpad_on_view_scroll_to(self, transformedUpperLeft.x, transformedLowerRight.y-h, view);
			}
	}
}