/* 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); }
/* 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); }
/* 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); } } }
/* 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); }
/* 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); }
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); } }
/* Set/get properties */ static void _xfdashboard_viewpad_set_property(GObject *inObject, guint inPropID, const GValue *inValue, GParamSpec *inSpec) { XfdashboardViewpad *self=XFDASHBOARD_VIEWPAD(inObject); switch(inPropID) { case PROP_SPACING: xfdashboard_viewpad_set_spacing(self, g_value_get_float(inValue)); break; case PROP_HSCROLLBAR_POLICY: xfdashboard_viewpad_set_horizontal_scrollbar_policy(self, (XfdashboardPolicy)g_value_get_enum(inValue)); break; case PROP_VSCROLLBAR_POLICY: xfdashboard_viewpad_set_vertical_scrollbar_policy(self, (XfdashboardPolicy)g_value_get_enum(inValue)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec); break; } }
/* Set/get properties */ static void _xfdashboard_view_selector_set_property(GObject *inObject, guint inPropID, const GValue *inValue, GParamSpec *inSpec) { XfdashboardViewSelector *self=XFDASHBOARD_VIEW_SELECTOR(inObject); switch(inPropID) { case PROP_VIEWPAD: xfdashboard_view_selector_set_viewpad(self, XFDASHBOARD_VIEWPAD(g_value_get_object(inValue))); break; case PROP_SPACING: xfdashboard_view_selector_set_spacing(self, g_value_get_float(inValue)); break; case PROP_ORIENTATION: xfdashboard_view_selector_set_orientation(self, g_value_get_enum(inValue)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec); break; } }
/* Show this actor and the current active view */ static void _xfdashboard_viewpad_show(ClutterActor *self) { XfdashboardViewpadPrivate *priv=XFDASHBOARD_VIEWPAD(self)->priv; ClutterActorClass *actorClass=CLUTTER_ACTOR_CLASS(xfdashboard_viewpad_parent_class); /* Only show active view again */ if(priv->activeView) clutter_actor_show(CLUTTER_ACTOR(priv->activeView)); /* Call parent's class show method */ if(actorClass->show) actorClass->show(self); }
/* 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); }
/* Dispose this object */ static void _xfdashboard_viewpad_dispose(GObject *inObject) { XfdashboardViewpad *self=XFDASHBOARD_VIEWPAD(inObject); XfdashboardViewpadPrivate *priv=self->priv; /* Deactivate current view */ if(priv->activeView) _xfdashboard_viewpad_activate_view(self, NULL); /* Disconnect signals handlers */ if(priv->viewManager) { g_signal_handlers_disconnect_by_data(priv->viewManager, self); g_object_unref(priv->viewManager); priv->viewManager=NULL; } /* Call parent's class dispose method */ G_OBJECT_CLASS(xfdashboard_viewpad_parent_class)->dispose(inObject); }
/* Determine if view has the focus */ gboolean xfdashboard_view_has_focus(XfdashboardView *self) { XfdashboardViewPrivate *priv; XfdashboardFocusManager *focusManager; XfdashboardViewpad *viewpad; g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), FALSE); priv=self->priv; /* The view can only have the focus if this view is enabled, active and * has the current focus. */ if(!priv->isEnabled) { return(FALSE); } viewpad=_xfdashboard_view_find_viewpad(self); if(!viewpad) { return(FALSE); } if(xfdashboard_viewpad_get_active_view(XFDASHBOARD_VIEWPAD(viewpad))!=self) { return(FALSE); } focusManager=xfdashboard_focus_manager_get_default(); if(!XFDASHBOARD_IS_FOCUSABLE(self) || !xfdashboard_focus_manager_has_focus(focusManager, XFDASHBOARD_FOCUSABLE(self))) { g_object_unref(focusManager); return(FALSE); } /* Release allocated resources */ g_object_unref(focusManager); /* All tests passed so this view has the focus */ return(TRUE); }
/** * 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]); }
static void _xfdashboard_viewpad_get_property(GObject *inObject, guint inPropID, GValue *outValue, GParamSpec *inSpec) { XfdashboardViewpad *self=XFDASHBOARD_VIEWPAD(inObject); switch(inPropID) { case PROP_SPACING: g_value_set_float(outValue, self->priv->spacing); break; case PROP_ACTIVE_VIEW: g_value_set_object(outValue, self->priv->activeView); break; case PROP_HSCROLLBAR_POLICY: g_value_set_enum(outValue, self->priv->hScrollbarPolicy); break; case PROP_HSCROLLBAR_VISIBLE: g_value_set_boolean(outValue, self->priv->hScrollbarVisible); break; case PROP_VSCROLLBAR_POLICY: g_value_set_enum(outValue, self->priv->vScrollbarPolicy); break; case PROP_VSCROLLBAR_VISIBLE: g_value_set_boolean(outValue, self->priv->vScrollbarVisible); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec); break; } }
/* 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]); } }