/* Virtual function "can_focus" was called */ static gboolean _xfdashboard_text_box_focusable_can_focus(XfdashboardFocusable *inFocusable) { XfdashboardTextBox *self; XfdashboardTextBoxPrivate *priv; XfdashboardFocusableInterface *selfIface; XfdashboardFocusableInterface *parentIface; g_return_val_if_fail(XFDASHBOARD_IS_TEXT_BOX(inFocusable), CLUTTER_EVENT_PROPAGATE); self=XFDASHBOARD_TEXT_BOX(inFocusable); priv=self->priv; /* Check if actor could be focused at all ... */ selfIface=XFDASHBOARD_FOCUSABLE_GET_IFACE(inFocusable); parentIface=g_type_interface_peek_parent(selfIface); if(parentIface && parentIface->can_focus) { if(!parentIface->can_focus(inFocusable)) return(FALSE); } /* ... then only an editable text box can be focused */ if(priv->isEditable) return(TRUE); /* If we get here this actor cannot be focused */ return(FALSE); }
/* Unset focus from actor */ static void _xfdashboard_text_box_focusable_unset_focus(XfdashboardFocusable *inFocusable) { ClutterActor *self; XfdashboardFocusableInterface *selfIface; XfdashboardFocusableInterface *parentIface; ClutterStage *stage; g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable)); g_return_if_fail(XFDASHBOARD_IS_ACTOR(inFocusable)); self=CLUTTER_ACTOR(inFocusable); /* Call parent class interface function */ selfIface=XFDASHBOARD_FOCUSABLE_GET_IFACE(inFocusable); parentIface=g_type_interface_peek_parent(selfIface); if(parentIface && parentIface->unset_focus) { parentIface->unset_focus(inFocusable); } /* Get stage of actor to tell it where the keyboard focus to set to */ stage=CLUTTER_STAGE(clutter_actor_get_stage(self)); if(!stage) { g_warning(_("Focusable actor %s is not on a stage"), G_OBJECT_TYPE_NAME(self)); return; } clutter_stage_set_key_focus(stage, NULL); }
/* 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); } } }
/* Call virtual function "find_selection" */ ClutterActor* xfdashboard_focusable_find_selection(XfdashboardFocusable *self, ClutterActor *inSelection, XfdashboardSelectionTarget inDirection) { XfdashboardFocusableInterface *iface; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(self), NULL); g_return_val_if_fail(!inSelection || CLUTTER_IS_ACTOR(inSelection), NULL); g_return_val_if_fail(inDirection>XFDASHBOARD_SELECTION_TARGET_NONE, NULL); g_return_val_if_fail(inDirection<=XFDASHBOARD_SELECTION_TARGET_NEXT, NULL); 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(NULL); /* Call virtual function */ if(iface->find_selection) { return(iface->find_selection(self, inSelection, inDirection)); } /* If we get here the virtual function was not overridden */ XFDASHBOARD_FOCUSABLE_WARN_NOT_IMPLEMENTED(self, "find_selection"); return(NULL); }
/* Call virtual function "activate_selection" */ gboolean xfdashboard_focusable_activate_selection(XfdashboardFocusable *self, ClutterActor *inSelection) { XfdashboardFocusableInterface *iface; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(self), FALSE); g_return_val_if_fail(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); /* Call virtual function */ if(iface->activate_selection) { return(iface->activate_selection(self, inSelection)); } /* If we get here the virtual function was not overridden */ XFDASHBOARD_FOCUSABLE_WARN_NOT_IMPLEMENTED(self, "activate_selection"); return(FALSE); }
/* 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)); }
/* Call virtual function "supports_selection" */ gboolean xfdashboard_focusable_supports_selection(XfdashboardFocusable *self) { XfdashboardFocusableInterface *iface; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(self), FALSE); iface=XFDASHBOARD_FOCUSABLE_GET_IFACE(self); /* Call virtual function */ if(iface->supports_selection) { return(iface->supports_selection(self)); } /* If we get here the virtual function was not overridden */ XFDASHBOARD_FOCUSABLE_WARN_NOT_IMPLEMENTED(self, "supports_selection"); return(FALSE); }
/* 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)); }
/* Determine if actor can get the focus */ static gboolean _xfdashboard_action_button_focusable_can_focus(XfdashboardFocusable *inFocusable) { XfdashboardFocusableInterface *selfIface; XfdashboardFocusableInterface *parentIface; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), FALSE); g_return_val_if_fail(XFDASHBOARD_IS_ACTION_BUTTON(inFocusable), FALSE); /* Call parent class interface function */ selfIface=XFDASHBOARD_FOCUSABLE_GET_IFACE(inFocusable); parentIface=g_type_interface_peek_parent(selfIface); if(parentIface && parentIface->can_focus) { if(!parentIface->can_focus(inFocusable)) return(FALSE); } /* If we get here this actor can be focused */ return(TRUE); }
/* 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); }
/* 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); }