/* Allocation of a view changed */ static void _xfdashboard_viewpad_update_scrollbars(XfdashboardViewpad *self) { XfdashboardViewpadPrivate *priv; gfloat w, h; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); priv=self->priv; /* Set range of scroll bar to width and height of active view * But we need to check for nan-values here - I do not get rid of it :( */ if(priv->activeView) clutter_actor_get_size(CLUTTER_ACTOR(priv->activeView), &w, &h); else w=h=1.0f; xfdashboard_scrollbar_set_range(XFDASHBOARD_SCROLLBAR(priv->hScrollbar), isnan(w)==0 ? w : 0.0f); xfdashboard_scrollbar_set_range(XFDASHBOARD_SCROLLBAR(priv->vScrollbar), isnan(h)==0 ? h : 0.0f); /* If any scroll bar policy is automatic then reallocate the * same allocation again in an unkindly way to force a recalculation * if scroll bars needed to shown (or hidden what is unlikely) */ if(CLUTTER_ACTOR_IS_VISIBLE(self) && (priv->hScrollbarPolicy==XFDASHBOARD_POLICY_AUTOMATIC || priv->vScrollbarPolicy==XFDASHBOARD_POLICY_AUTOMATIC)) { ClutterActorBox box; clutter_actor_get_allocation_box(CLUTTER_ACTOR(self), &box); _xfdashboard_viewpad_allocate(CLUTTER_ACTOR(self), &box, CLUTTER_DELEGATE_LAYOUT); } }
/* Virtual function "handle_key_event" was called */ static gboolean _xfdashboard_viewpad_focusable_handle_key_event(XfdashboardFocusable *inFocusable, const ClutterEvent *inEvent) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; gboolean handledEvent; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(inFocusable), CLUTTER_EVENT_PROPAGATE); self=XFDASHBOARD_VIEWPAD(inFocusable); priv=self->priv; /* Set handled key eventto CLUTTER_EVENT_PROPAGATE. It might be set to * CLUTTER_EVENT_STOP if current active view is focusable and it handled * the key event by its virtual function. */ handledEvent=CLUTTER_EVENT_PROPAGATE; /* Viewpad is just a proxy for the current active view. * So check if current active view is focusable and call its * virtual function. */ if(priv->activeView && XFDASHBOARD_IS_FOCUSABLE(priv->activeView)) { handledEvent=xfdashboard_focusable_handle_key_event(XFDASHBOARD_FOCUSABLE(priv->activeView), inEvent); } /* Return focusable state */ return(handledEvent); }
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); } }
/* The value of a scrollbar has changed */ static void _xfdashboard_viewpad_on_scrollbar_value_changed(XfdashboardViewpad *self, gfloat inValue, gpointer inUserData) { XfdashboardViewpadPrivate *priv; ClutterActor *scrollbar; gfloat x, y, w, h; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); g_return_if_fail(XFDASHBOARD_IS_SCROLLBAR(inUserData)); priv=self->priv; scrollbar=CLUTTER_ACTOR(inUserData); /* Update clipping */ if(clutter_actor_has_clip(CLUTTER_ACTOR(priv->activeView))) { clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, &w, &h); if(scrollbar==priv->hScrollbar) x=inValue; else if(scrollbar==priv->vScrollbar) y=inValue; } else { x=y=0.0f; clutter_actor_get_size(CLUTTER_ACTOR(priv->activeView), &w, &h); } clutter_actor_set_clip(CLUTTER_ACTOR(priv->activeView), x, y, w, h); /* Update viewport */ _xfdashboard_viewpad_update_view_viewport(self); }
/* Find viewpad which contains this view */ static XfdashboardViewpad* _xfdashboard_view_find_viewpad(XfdashboardView *self) { ClutterActor *viewpad; g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), NULL); /* Iterate through parent actors and for each viewpad found * check if it contains this view. */ viewpad=clutter_actor_get_parent(CLUTTER_ACTOR(self)); while(viewpad) { /* Check if this parent actor is a viewpad and * if it contains this view. */ if(XFDASHBOARD_IS_VIEWPAD(viewpad) && xfdashboard_viewpad_has_view(XFDASHBOARD_VIEWPAD(viewpad), self)) { /* Viewpad found so return it */ return(XFDASHBOARD_VIEWPAD(viewpad)); } /* Continue with next parent actor */ viewpad=clutter_actor_get_parent(viewpad); } /* If we get here the viewpad could not be found so return NULL */ return(NULL); }
/* 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); }
/* Scroll event happened at this actor because it was not handled * with any child actor */ static gboolean _xfdashboard_viewpad_on_scroll_event(ClutterActor *inActor, ClutterEvent *inEvent, gpointer inUserData) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; gboolean result; g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(inActor), FALSE); g_return_val_if_fail(inEvent, FALSE); self=XFDASHBOARD_VIEWPAD(inActor); priv=self->priv; result=CLUTTER_EVENT_PROPAGATE; /* If vertical scroll bar is visible emit scroll event there */ if(priv->vScrollbarVisible) { result=clutter_actor_event(priv->vScrollbar, inEvent, FALSE); } /* Otherwise try horizontal scroll bar if visible */ else if(priv->hScrollbarVisible) { result=clutter_actor_event(priv->hScrollbar, inEvent, FALSE); } return(result); }
/* 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); }
/* Determine if actor can get the focus */ static gboolean _xfdashboard_viewpad_focusable_can_focus(XfdashboardFocusable *inFocusable) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; gboolean canFocus; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), FALSE); g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(inFocusable), FALSE); self=XFDASHBOARD_VIEWPAD(inFocusable); priv=self->priv; /* Set current focusable result to FALSE (not focusable). It will be set * to TRUE automatically if current active view is focusable and its * virtual function will also return TRUE. */ canFocus=FALSE; /* Viewpad is just a proxy for the current active view. * So check if current active view is focusable and call its * virtual function. */ if(priv->activeView && XFDASHBOARD_IS_FOCUSABLE(priv->activeView)) { canFocus=xfdashboard_focusable_can_focus(XFDASHBOARD_FOCUSABLE(priv->activeView)); } /* Return focusable state */ return(canFocus); }
/* Unset focus from actor */ static void _xfdashboard_viewpad_focusable_unset_focus(XfdashboardFocusable *inFocusable) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; XfdashboardFocusableInterface *selfIface; XfdashboardFocusableInterface *parentIface; g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable)); g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(inFocusable)); self=XFDASHBOARD_VIEWPAD(inFocusable); priv=self->priv; /* Viewpad is just a proxy for the current active view. * So check if current active view is focusable and call its * virtual function. */ if(priv->activeView && XFDASHBOARD_IS_FOCUSABLE(priv->activeView)) { /* Call virtual function of view to unset focus */ xfdashboard_focusable_unset_focus(XFDASHBOARD_FOCUSABLE(priv->activeView)); /* Call parent class interface function of this actor */ selfIface=XFDASHBOARD_FOCUSABLE_GET_IFACE(inFocusable); parentIface=g_type_interface_peek_parent(selfIface); if(parentIface && parentIface->unset_focus) { parentIface->unset_focus(inFocusable); } } }
/* Called when a new view type was registered */ static void _xfdashboard_viewpad_on_view_registered(XfdashboardViewpad *self, GType inViewType, gpointer inUserData) { g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); _xfdashboard_viewpad_add_view(self, inViewType); }
/* A view was enabled */ static void _xfdashboard_viewpad_on_view_enabled(XfdashboardViewpad *self, XfdashboardView *inView) { XfdashboardViewpadPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); g_return_if_fail(XFDASHBOARD_IS_VIEW(inView)); priv=self->priv; /* If no view is active this new enabled view will be activated */ if(!priv->activeView) _xfdashboard_viewpad_activate_view(self, inView); }
void xfdashboard_viewpad_set_active_view(XfdashboardViewpad *self, XfdashboardView *inView) { XfdashboardViewpadPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); g_return_if_fail(XFDASHBOARD_IS_VIEW(inView)); priv=self->priv; /* Only activate view if it changes */ if(priv->activeView!=inView) _xfdashboard_viewpad_activate_view(self, inView); }
/* Allocation of a view changed */ static gboolean _xfdashboard_viewpad_on_allocation_changed_repaint_callback(gpointer inUserData) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(inUserData), G_SOURCE_REMOVE); self=XFDASHBOARD_VIEWPAD(inUserData); priv=self->priv; /* Update scrollbars */ _xfdashboard_viewpad_update_scrollbars(self); /* Do not call this callback again */ priv->scrollbarUpdateID=0; return(G_SOURCE_REMOVE); }
void xfdashboard_viewpad_set_vertical_scrollbar_policy(XfdashboardViewpad *self, XfdashboardPolicy inPolicy) { XfdashboardViewpadPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); priv=self->priv; /* Only set new value if it differs from current value */ if(priv->vScrollbarPolicy==inPolicy) return; /* Set new value */ priv->vScrollbarPolicy=inPolicy; clutter_actor_queue_relayout(CLUTTER_ACTOR(self)); /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_VSCROLLBAR_POLICY]); }
/* 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); } }
/* 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)); } }
/** * 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]); }
/* Update view depending on scrollbar values */ static void _xfdashboard_viewpad_update_view_viewport(XfdashboardViewpad *self) { XfdashboardViewpadPrivate *priv; ClutterMatrix transform; gfloat x, y, w, h; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); priv=self->priv; /* Check for active view */ if(priv->activeView==NULL) { g_warning(_("Cannot update viewport of view because no one is active")); return; } /* Get offset from scrollbars and view size from clipping */ if(clutter_actor_has_clip(CLUTTER_ACTOR(priv->activeView))) { clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, &w, &h); } else { x=y=0.0f; clutter_actor_get_size(CLUTTER_ACTOR(priv->activeView), &w, &h); } /* To avoid blur convert float to ints (virtually) */ x=ceil(x); y=ceil(y); w=ceil(w); h=ceil(h); /* Set transformation (offset) */ cogl_matrix_init_identity(&transform); cogl_matrix_translate(&transform, -x, -y, 0.0f); clutter_actor_set_transform(CLUTTER_ACTOR(priv->activeView), &transform); /* Set new clipping */ clutter_actor_set_clip(CLUTTER_ACTOR(priv->activeView), x, y, w, h); }
/* Get list of views */ GList* xfdashboard_viewpad_get_views(XfdashboardViewpad *self) { ClutterActorIter iter; ClutterActor *child; GList *list; g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), NULL); list=NULL; /* Iterate through children and create list of views */ clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self)); while(clutter_actor_iter_next(&iter, &child)) { /* Check if child is a view and add to list */ if(XFDASHBOARD_IS_VIEW(child)==TRUE) list=g_list_prepend(list, child); } list=g_list_reverse(list); return(list); }
/* 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); } }
/* 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)); }
void xfdashboard_viewpad_set_spacing(XfdashboardViewpad *self, gfloat inSpacing) { XfdashboardViewpadPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); g_return_if_fail(inSpacing>=0.0f); priv=self->priv; /* Only set value if it changes */ if(inSpacing==priv->spacing) return; /* Set new value */ priv->spacing=inSpacing; if(priv->layout) { clutter_grid_layout_set_column_spacing(CLUTTER_GRID_LAYOUT(priv->layout), priv->spacing); clutter_grid_layout_set_row_spacing(CLUTTER_GRID_LAYOUT(priv->layout), priv->spacing); } clutter_actor_queue_relayout(CLUTTER_ACTOR(self)); /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_SPACING]); }
/* Set new active view and deactive current one */ static void _xfdashboard_viewpad_activate_view(XfdashboardViewpad *self, XfdashboardView *inView) { XfdashboardViewpadPrivate *priv; gfloat x, y; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); g_return_if_fail(inView==NULL || XFDASHBOARD_IS_VIEW(inView)); priv=self->priv; /* Only set value if it changes */ if(inView==priv->activeView) return; /* Check if view is a child of this actor */ if(inView && clutter_actor_contains(CLUTTER_ACTOR(self), CLUTTER_ACTOR(inView))==FALSE) { g_warning(_("View %s is not a child of %s and cannot be activated"), G_OBJECT_TYPE_NAME(inView), G_OBJECT_TYPE_NAME(self)); return; } /* Only allow enabled views to be activated */ if(inView && !xfdashboard_view_get_enabled(inView)) { g_warning(_("Cannot activate disabled view %s at %s"), G_OBJECT_TYPE_NAME(inView), G_OBJECT_TYPE_NAME(self)); return; } /* Deactivate current view */ if(priv->activeView) { /* Hide current view and emit signal before and after deactivation */ g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_DEACTIVATING], 0, priv->activeView); g_signal_emit_by_name(priv->activeView, "deactivating"); clutter_actor_hide(CLUTTER_ACTOR(priv->activeView)); g_debug("Deactivated view %s", G_OBJECT_TYPE_NAME(priv->activeView)); g_signal_emit_by_name(priv->activeView, "deactivated"); g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_DEACTIVATED], 0, priv->activeView); g_object_unref(priv->activeView); priv->activeView=NULL; } /* Activate new view (if available) by showing new view, setting up * scrollbars and emitting signal before and after activation. * Prevent signal handling for scrollbars' "value-changed" as it will * mess up with clipping and viewport. We only need to set value of * scrollbars but we do not need to handle the changed value. */ if(inView) { priv->activeView=g_object_ref(inView); g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_ACTIVATING], 0, priv->activeView); g_signal_emit_by_name(priv->activeView, "activating"); g_signal_handlers_block_by_func(priv->hScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); g_signal_handlers_block_by_func(priv->vScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); x=y=0.0f; clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, NULL, NULL); _xfdashboard_viewpad_update_scrollbars(self); xfdashboard_scrollbar_set_value(XFDASHBOARD_SCROLLBAR(priv->hScrollbar), x); xfdashboard_scrollbar_set_value(XFDASHBOARD_SCROLLBAR(priv->vScrollbar), y); _xfdashboard_viewpad_update_view_viewport(self); clutter_actor_show(CLUTTER_ACTOR(priv->activeView)); g_debug("Activated view %s", G_OBJECT_TYPE_NAME(priv->activeView)); g_signal_handlers_unblock_by_func(priv->hScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); g_signal_handlers_unblock_by_func(priv->vScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); g_signal_emit_by_name(priv->activeView, "activated"); g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_ACTIVATED], 0, priv->activeView); } /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_ACTIVE_VIEW]); }
/* Get/set active view */ XfdashboardView* xfdashboard_viewpad_get_active_view(XfdashboardViewpad *self) { g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), NULL); return(self->priv->activeView); }
gboolean xfdashboard_viewpad_get_vertical_scrollbar_visible(XfdashboardViewpad *self) { g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), FALSE); return(self->priv->vScrollbarVisible); }
XfdashboardPolicy xfdashboard_viewpad_get_vertical_scrollbar_policy(XfdashboardViewpad *self) { g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), XFDASHBOARD_POLICY_AUTOMATIC); return(self->priv->vScrollbarPolicy); }
/* 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); } } }
/* Get/set spacing */ gfloat xfdashboard_viewpad_get_spacing(XfdashboardViewpad *self) { g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(self), 0.0f); return(self->priv->spacing); }