/* Drag handle has changed so unset styles on old handle and set style on new one */ static void _xfdashboard_drag_action_on_drag_handle_changed(XfdashboardDragAction *self, GParamSpec *inSpec, gpointer inUserData) { XfdashboardDragActionPrivate *priv; gchar *styleClass; g_return_if_fail(XFDASHBOARD_IS_DRAG_ACTION(self)); priv=self->priv; /* Unset styles on current drag handle */ if(priv->dragHandle && XFDASHBOARD_IS_ACTOR(priv->dragHandle)) { /* Unset style */ if(priv->source) { styleClass=g_strdup_printf("drag-source-%s", G_OBJECT_TYPE_NAME(priv->source)); xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); } styleClass=g_strdup_printf("drag-actor-%s", G_OBJECT_TYPE_NAME(priv->actor)); xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->dragHandle), "drag-handle"); /* Forget drag handle */ priv->dragHandle=NULL; } /* Remember new drag handle and set styles */ priv->dragHandle=clutter_drag_action_get_drag_handle(CLUTTER_DRAG_ACTION(self)); if(priv->dragHandle && XFDASHBOARD_IS_ACTOR(priv->dragHandle)) { /* Set style */ if(priv->source) { styleClass=g_strdup_printf("drag-source-%s", G_OBJECT_TYPE_NAME(priv->source)); xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); } styleClass=g_strdup_printf("drag-actor-%s", G_OBJECT_TYPE_NAME(priv->actor)); xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(priv->dragHandle), "drag-handle"); } }
/* 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); }
/* Set source actor */ static void _xfdashboard_drag_action_set_source(XfdashboardDragAction *self, ClutterActor *inSource) { XfdashboardDragActionPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_DRAG_ACTION(self)); g_return_if_fail(inSource==NULL || CLUTTER_IS_ACTOR(inSource)); priv=self->priv; /* Release old source actor */ if(priv->source) { /* Unset style */ if(XFDASHBOARD_IS_ACTOR(priv->source)) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->source), "current-drag-source"); } /* Release actor */ g_object_unref(priv->source); priv->source=NULL; } /* Set new source actor */ if(inSource) { /* Set actor */ priv->source=CLUTTER_ACTOR(g_object_ref(inSource)); } }
/* Actor's reactive state changed */ static void _xfdashboard_actor_on_reactive_changed(GObject *inObject, GParamSpec *inSpec, gpointer inUserData) { XfdashboardActor *self; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inObject)); self=XFDASHBOARD_ACTOR(inObject); /* Add pseudo-class ':insensitive' if actor is now not reactive * and remove this pseudo-class if actor is now reactive. */ if(clutter_actor_get_reactive(CLUTTER_ACTOR(self))) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(self), "insensitive"); } else { xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(self), "insensitive"); } /* Invalide styling to get it recomputed */ _xfdashboard_actor_invalidate_recursive(CLUTTER_ACTOR(self)); }
static void _xfdashboard_actor_stylable_set_pseudo_classes(XfdashboardStylable *inStylable, const gchar *inStylePseudoClasses) { XfdashboardActor *self; XfdashboardActorPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable)); self=XFDASHBOARD_ACTOR(inStylable); priv=self->priv; /* Set value if changed */ if(g_strcmp0(priv->stylePseudoClasses, inStylePseudoClasses)) { /* Set value */ if(priv->stylePseudoClasses) { g_free(priv->stylePseudoClasses); priv->stylePseudoClasses=NULL; } if(inStylePseudoClasses) priv->stylePseudoClasses=g_strdup(inStylePseudoClasses); /* Invalidate style to get it restyled and redrawn. Also invalidate * children as they might reference the old, invalid pseudo-classes * or the new, valid ones. */ _xfdashboard_actor_invalidate_recursive(CLUTTER_ACTOR(self)); /* Notify about property change */ g_object_notify(G_OBJECT(self), "style-pseudo-classes"); } }
/* Set press state */ static void _xfdashboard_click_action_set_pressed(XfdashboardClickAction *self, gboolean isPressed) { XfdashboardClickActionPrivate *priv; ClutterActor *actor; g_return_if_fail(XFDASHBOARD_IS_CLICK_ACTION(self)); priv=self->priv; /* Set value if changed */ isPressed=!!isPressed; if(priv->isPressed!=isPressed) { /* Set value */ priv->isPressed=isPressed; /* Style state */ actor=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self)); if(XFDASHBOARD_IS_ACTOR(actor)) { if(priv->isPressed) xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(actor), "pressed"); else xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(actor), "pressed"); } /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardClickActionProperties[PROP_PRESSED]); } }
/* Get/set style pseudo-classes of actor */ static const gchar* _xfdashboard_actor_stylable_get_pseudo_classes(XfdashboardStylable *inStylable) { XfdashboardActor *self; g_return_val_if_fail(XFDASHBOARD_IS_ACTOR(inStylable), NULL); self=XFDASHBOARD_ACTOR(inStylable); return(self->priv->stylePseudoClasses); }
/* Unset focus from actor */ static void _xfdashboard_actor_focusable_unset_focus(XfdashboardFocusable *self) { XfdashboardActor *actor; g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(self)); g_return_if_fail(XFDASHBOARD_IS_ACTOR(self)); actor=XFDASHBOARD_ACTOR(self); /* Set focus and style for focus */ xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(actor), "focus"); }
/* Actor was mapped or unmapped */ static void _xfdashboard_actor_on_mapped_changed(GObject *inObject, GParamSpec *inSpec, gpointer inUserData) { XfdashboardActor *self; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inObject)); self=XFDASHBOARD_ACTOR(inObject); /* Invalide styling to get it recomputed */ xfdashboard_stylable_invalidate(XFDASHBOARD_STYLABLE(self)); }
/* Called when attaching and detaching a ClutterActorMeta instance to a ClutterActor */ static void _xfdashboard_drop_action_set_actor(ClutterActorMeta *inActorMeta, ClutterActor *inActor) { XfdashboardDropAction *self; XfdashboardDropActionPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_DROP_ACTION(inActorMeta)); g_return_if_fail(inActor==NULL || CLUTTER_IS_ACTOR(inActor)); self=XFDASHBOARD_DROP_ACTION(inActorMeta); priv=self->priv; /* Unregister current drop target */ if(priv->actor) { /* Disconnect signals */ if(priv->destroySignalID) g_signal_handler_disconnect(priv->actor, priv->destroySignalID); /* Unset style */ if(XFDASHBOARD_IS_ACTOR(priv->actor)) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->actor), "drop-target"); } /* Unregister drop target */ _xfdashboard_drop_action_unregister_target(self); priv->destroySignalID=0; priv->actor=NULL; } /* Register new drop target */ if(inActor) { priv->actor=inActor; /* Register drop target */ _xfdashboard_drop_action_register_target(self); /* Connect signals */ priv->destroySignalID=g_signal_connect_swapped(priv->actor, "destroy", G_CALLBACK(_xfdashboard_drop_action_on_target_actor_destroy), self); } /* Call parent's class method */ CLUTTER_ACTOR_META_CLASS(xfdashboard_drop_action_parent_class)->set_actor(inActorMeta, inActor); }
/* Actor was (re)named */ static void _xfdashboard_actor_on_name_changed(GObject *inObject, GParamSpec *inSpec, gpointer inUserData) { XfdashboardActor *self; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inObject)); self=XFDASHBOARD_ACTOR(inObject); /* Invalide styling to get it recomputed because its ID (from point * of view of css) has changed. Also invalidate children as they * might reference the old, invalid ID or the new, valid one. */ _xfdashboard_actor_invalidate_recursive(CLUTTER_ACTOR(self)); }
/* Default signal handler for "drag-leave" */ static void _xfdashboard_drop_action_class_real_drag_leave(XfdashboardDropAction *self, XfdashboardDragAction *inDragAction) { XfdashboardDropActionPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_DROP_ACTION(self)); priv=self->priv; /* Unset style */ if(priv->actor && XFDASHBOARD_IS_ACTOR(priv->actor)) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->actor), "drop-target"); } }
void xfdashboard_actor_set_effects(XfdashboardActor *self, const gchar *inEffects) { XfdashboardActorPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_ACTOR(self)); priv=self->priv; /* Set value if changed */ if(g_strcmp0(priv->effects, inEffects)!=0) { /* Set value */ _xfdashboard_actor_update_effects(self, inEffects); /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardActorProperties[PROP_EFFECTS]); } }
/* Unregister a drop target */ static void _xfdashboard_drop_action_unregister_target(XfdashboardDropAction *self) { XfdashboardDropActionPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_DROP_ACTION(self)); priv=self->priv; /* Unset style */ if(priv->actor && XFDASHBOARD_IS_ACTOR(priv->actor)) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->actor), "drop-target"); } /* Remove target from list of dropable targets */ _xfdashboard_drop_action_targets=g_slist_remove(_xfdashboard_drop_action_targets, self); }
void xfdashboard_actor_set_can_focus(XfdashboardActor *self, gboolean inCanFous) { XfdashboardActorPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_ACTOR(self)); priv=self->priv; /* Set value if changed */ if(priv->canFocus!=inCanFous) { /* Set value */ priv->canFocus=inCanFous; /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardActorProperties[PROP_CAN_FOCUS]); } }
/* Actor was (re)parented */ static void _xfdashboard_actor_parent_set(ClutterActor *inActor, ClutterActor *inOldParent) { XfdashboardActor *self; XfdashboardActorPrivate *priv; ClutterActorClass *parentClass; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inActor)); self=XFDASHBOARD_ACTOR(inActor); priv=self->priv; /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_actor_parent_class); if(parentClass->parent_set) { parentClass->parent_set(inActor, inOldParent); } /* Check if it is a newly created actor which is parented for the first time. * Then emit 'actor-created' signal on stage. */ if(priv->isFirstParent && !inOldParent && clutter_actor_get_parent(inActor)) { ClutterActor *stage; /* Get stage where this actor belongs to and emit signal at stage */ stage=clutter_actor_get_stage(inActor); if(XFDASHBOARD_IS_STAGE(stage)) { g_signal_emit_by_name(stage, "actor-created", inActor, NULL); } /* Set flag that a parent set and signal was emitted */ priv->isFirstParent=FALSE; } /* Invalide styling to get it recomputed because its ID (from point * of view of css) has changed. Also invalidate children as they might * reference the old, invalid parent or the new, valid one. */ _xfdashboard_actor_invalidate_recursive(CLUTTER_ACTOR(self)); }
/* Pointer entered actor */ static gboolean _xfdashboard_actor_enter_event(ClutterActor *inActor, ClutterCrossingEvent *inEvent) { XfdashboardActor *self; ClutterActorClass *parentClass; g_return_val_if_fail(XFDASHBOARD_IS_ACTOR(inActor), CLUTTER_EVENT_PROPAGATE); self=XFDASHBOARD_ACTOR(inActor); /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_actor_parent_class); if(parentClass->enter_event) { parentClass->enter_event(inActor, inEvent); } /* Add pseudo-class ":hover" because pointer entered actor */ xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(self), "hover"); return(CLUTTER_EVENT_PROPAGATE); }
/* Actor is hidden */ static void _xfdashboard_actor_hide(ClutterActor *inActor) { XfdashboardActor *self; ClutterActorClass *parentClass; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inActor)); self=XFDASHBOARD_ACTOR(inActor); /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_actor_parent_class); if(parentClass->hide) { parentClass->hide(inActor); } /* Actor is hidden now so remove pseudo-class ":hover" because pointer cannot * be in an actor hidden. */ xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(self), "hover"); }
/* Actor was (re)parented */ static void _xfdashboard_actor_parent_set(ClutterActor *inActor, ClutterActor *inOldParent) { XfdashboardActor *self; ClutterActorClass *parentClass; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inActor)); self=XFDASHBOARD_ACTOR(inActor); /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_actor_parent_class); if(parentClass->parent_set) { parentClass->parent_set(inActor, inOldParent); } /* Invalide styling to get it recomputed because its ID (from point * of view of css) has changed. Also invalidate children as they might * reference the old, invalid parent or the new, valid one. */ _xfdashboard_actor_invalidate_recursive(CLUTTER_ACTOR(self)); }
/* Check if actor can get focus */ static gboolean _xfdashboard_actor_focusable_can_focus(XfdashboardFocusable *inFocusable) { XfdashboardActor *self; XfdashboardActorPrivate *priv; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), FALSE); g_return_val_if_fail(XFDASHBOARD_IS_ACTOR(inFocusable), FALSE); self=XFDASHBOARD_ACTOR(inFocusable); priv=self->priv; /* This actor can only be focused if it is mapped, visible and reactive */ if(priv->canFocus && clutter_actor_is_mapped(CLUTTER_ACTOR(self)) && clutter_actor_is_visible(CLUTTER_ACTOR(self)) && clutter_actor_get_reactive(CLUTTER_ACTOR(self))) { return(TRUE); } /* If we get here this actor does not fulfill the requirements to get focus */ return(FALSE); }
/* Actor is shown */ static void _xfdashboard_actor_show(ClutterActor *inActor) { XfdashboardActor *self; ClutterActorClass *parentClass; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inActor)); self=XFDASHBOARD_ACTOR(inActor); /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_actor_parent_class); if(parentClass->show) { parentClass->show(inActor); } /* If actor is visible now check if pointer is inside this actor * then add pseudo-class ":hover" to it */ if(clutter_actor_has_pointer(inActor)) { xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(self), "hover"); } }
/* Dragging of actor begins */ static void _xfdashboard_drag_action_drag_begin(ClutterDragAction *inAction, ClutterActor *inActor, gfloat inStageX, gfloat inStageY, ClutterModifierType inModifiers) { XfdashboardDragAction *self; XfdashboardDragActionPrivate *priv; ClutterDragActionClass *dragActionClass; GSList *list; g_return_if_fail(XFDASHBOARD_IS_DRAG_ACTION(inAction)); self=XFDASHBOARD_DRAG_ACTION(inAction); priv=self->priv; dragActionClass=CLUTTER_DRAG_ACTION_CLASS(xfdashboard_drag_action_parent_class); /* Call parent's class method */ if(dragActionClass->drag_begin) dragActionClass->drag_begin(inAction, inActor, inStageX, inStageY, inModifiers); /* Remember dragged actor while dragging and listen to possible 'destroy' signal emissions */ priv->actor=inActor; priv->actorDestroySignalID=g_signal_connect_swapped(priv->actor, "destroy", G_CALLBACK(_xfdashboard_drag_action_on_dragged_actor_destroyed), self); /* Get list of drop targets. It is a new list with all current * drop targets already reffed. So the drop targets will be valid * while dragging */ priv->targets=xfdashboard_drop_action_get_targets(); /* Emit "begin" signal on all drop targets to determine if they * can handle dragged actor and to prepare them for dragging. * All targets returning TRUE (and therefore telling us they * can handle dragged actor and are prepared for drag'n'drop) * will be sorted. */ list=priv->targets; while(list) { XfdashboardDropAction *dropTarget=XFDASHBOARD_DROP_ACTION(list->data); gboolean canHandle=FALSE; g_signal_emit_by_name(dropTarget, "begin", self, &canHandle); if(!canHandle) { GSList *next; /* Drop target cannot handle dragged actor so unref it and * remove it from list of drop targets */ next=g_slist_next(list); priv->targets=g_slist_remove_link(priv->targets, list); g_object_unref(list->data); g_slist_free_1(list); list=next; } else list=g_slist_next(list); } _xfdashboard_drag_action_sort_targets(self); /* We should listen to allocation changes for each actor which * is an active drop target. */ for(list=priv->targets; list; list=g_slist_next(list)) { XfdashboardDropAction *dropTarget=XFDASHBOARD_DROP_ACTION(list->data); ClutterActorMeta *actorMeta=CLUTTER_ACTOR_META(dropTarget); ClutterActor *actor=clutter_actor_meta_get_actor(actorMeta); g_signal_connect_swapped(actor, "allocation-changed", G_CALLBACK(_xfdashboard_drag_on_drop_target_allocation_changed), self); } /* Setup for dragging */ priv->dragCancelled=FALSE; priv->lastDropTarget=NULL; priv->lastMotionActors=NULL; /* Set styles */ if(priv->source && XFDASHBOARD_IS_ACTOR(priv->source)) { xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(priv->source), "drag-source"); } if(XFDASHBOARD_IS_ACTOR(priv->actor)) { xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(priv->actor), "dragged"); } priv->dragHandle=clutter_drag_action_get_drag_handle(CLUTTER_DRAG_ACTION(self)); if(priv->dragHandle && XFDASHBOARD_IS_ACTOR(priv->dragHandle)) { gchar *styleClass; if(priv->source) { styleClass=g_strdup_printf("drag-source-%s", G_OBJECT_TYPE_NAME(priv->source)); xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); } styleClass=g_strdup_printf("drag-actor-%s", G_OBJECT_TYPE_NAME(priv->actor)); xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); xfdashboard_stylable_add_pseudo_class(XFDASHBOARD_STYLABLE(priv->dragHandle), "drag-handle"); /* Get notified if drag handle changes */ priv->dragHandleChangedID=g_signal_connect(self, "notify::drag-handle", G_CALLBACK(_xfdashboard_drag_action_on_drag_handle_changed), NULL); } }
/* Get/set "can-focus" flag of actor to indicate * if this actor is focusable or not. */ gboolean xfdashboard_actor_get_can_focus(XfdashboardActor *self) { g_return_val_if_fail(XFDASHBOARD_IS_ACTOR(self), FALSE); return(self->priv->canFocus); }
/* Invalidate style to recompute styles */ static void _xfdashboard_actor_stylable_invalidate(XfdashboardStylable *inStylable) { XfdashboardActor *self; XfdashboardActorPrivate *priv; XfdashboardActorClass *klass; XfdashboardTheme *theme; XfdashboardThemeCSS *themeCSS; GHashTable *possibleStyleSet; GParamSpec *paramSpec; GHashTableIter hashIter; GHashTable *themeStyleSet; gchar *styleName; XfdashboardThemeCSSValue *styleValue; gboolean didChange; #ifdef DEBUG gboolean doDebug=FALSE; #endif g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable)); self=XFDASHBOARD_ACTOR(inStylable); priv=self->priv; klass=XFDASHBOARD_ACTOR_GET_CLASS(self); didChange=FALSE; /* Only recompute style for mapped actors or if revalidation was forced */ if(!priv->forceStyleRevalidation && !clutter_actor_is_mapped(CLUTTER_ACTOR(self))) return; /* Get theme CSS */ theme=xfdashboard_application_get_theme(NULL); themeCSS=xfdashboard_theme_get_css(theme); /* First get list of all stylable properties of this and parent classes. * It is used to determine if key in theme style sets are valid. */ possibleStyleSet=xfdashboard_actor_get_stylable_properties_full(klass); #ifdef DEBUG if(doDebug) { gint i=0; gchar *defaultsKey; GValue defaultsVal=G_VALUE_INIT; gchar *defaultsValStr; GParamSpec *realParamSpec; XFDASHBOARD_DEBUG(self, STYLE, "Got param specs for %p (%s) with class '%s' and pseudo-class '%s'", self, G_OBJECT_TYPE_NAME(self), priv->styleClasses, priv->stylePseudoClasses); g_hash_table_iter_init(&hashIter, possibleStyleSet); while(g_hash_table_iter_next(&hashIter, (gpointer*)&defaultsKey, (gpointer*)¶mSpec)) { realParamSpec=(GParamSpec*)g_param_spec_get_qdata(paramSpec, XFDASHBOARD_ACTOR_PARAM_SPEC_REF); g_value_init(&defaultsVal, G_PARAM_SPEC_VALUE_TYPE(realParamSpec)); g_param_value_set_default(realParamSpec, &defaultsVal); defaultsValStr=g_strdup_value_contents(&defaultsVal); XFDASHBOARD_DEBUG(self, STYLE, "%d: param spec [%s] %s=%s\n", ++i, G_OBJECT_CLASS_NAME(klass), defaultsKey, defaultsValStr); g_free(defaultsValStr); g_value_unset(&defaultsVal); } XFDASHBOARD_DEBUG(self, STYLE, "End of param specs"); } #endif /* Get style information from theme */ themeStyleSet=xfdashboard_theme_css_get_properties(themeCSS, XFDASHBOARD_STYLABLE(self)); #ifdef DEBUG if(doDebug) { gint i=0; XFDASHBOARD_DEBUG(self, STYLE, "Got styles from theme for %p (%s) with class '%s' and pseudo-class '%s'", self, G_OBJECT_TYPE_NAME(self), priv->styleClasses, priv->stylePseudoClasses); g_hash_table_iter_init(&hashIter, themeStyleSet); while(g_hash_table_iter_next(&hashIter, (gpointer*)&styleName, (gpointer*)&styleValue)) { XFDASHBOARD_DEBUG(self, STYLE, "%d: [%s] %s=%s\n", ++i, styleValue->source, (gchar*)styleName, styleValue->string); } XFDASHBOARD_DEBUG(self, STYLE, "End of styles from theme"); } #endif /* The 'property-changed' notification will be freezed and thawed * (fired at once) after all stylable properties of this instance are set. */ g_object_freeze_notify(G_OBJECT(self)); /* Iterate through style information retrieved from theme and * set the corresponding property in object instance if key * is valid. */ g_hash_table_iter_init(&hashIter, themeStyleSet); while(g_hash_table_iter_next(&hashIter, (gpointer*)&styleName, (gpointer*)&styleValue)) { GValue cssValue=G_VALUE_INIT; GValue propertyValue=G_VALUE_INIT; GParamSpec *realParamSpec; /* Check if key is a valid object property name */ if(!g_hash_table_lookup_extended(possibleStyleSet, styleName, NULL, (gpointer*)¶mSpec)) continue; /* Get original referenced parameter specification. It does not need * to be referenced while converting because it is valid as this * value is stored in hashtable. */ realParamSpec=(GParamSpec*)g_param_spec_get_qdata(paramSpec, XFDASHBOARD_ACTOR_PARAM_SPEC_REF); /* Convert style value to type of object property and set value * if conversion was successful. Otherwise do nothing. */ g_value_init(&cssValue, G_TYPE_STRING); g_value_set_string(&cssValue, styleValue->string); g_value_init(&propertyValue, G_PARAM_SPEC_VALUE_TYPE(realParamSpec)); if(g_param_value_convert(realParamSpec, &cssValue, &propertyValue, FALSE)) { g_object_set_property(G_OBJECT(self), styleName, &propertyValue); didChange=TRUE; #ifdef DEBUG if(doDebug) { gchar *valstr; valstr=g_strdup_value_contents(&propertyValue); XFDASHBOARD_DEBUG(self, STYLE, "Setting theme value of style property [%s] %s=%s\n", G_OBJECT_CLASS_NAME(klass), styleName, valstr); g_free(valstr); } #endif } else { g_warning(_("Could not transform CSS string value for property '%s' to type %s of class %s"), styleName, g_type_name(G_PARAM_SPEC_VALUE_TYPE(realParamSpec)), G_OBJECT_CLASS_NAME(klass)); } /* Release allocated resources */ g_value_unset(&propertyValue); g_value_unset(&cssValue); } /* Now remove all duplicate keys in set of properties changed we set the last * time. The remaining keys determine the properties which were set the last * time but not this time and should be restored to their default values. */ if(priv->lastThemeStyleSet) { /* Remove duplicate keys from set of last changed properties */ g_hash_table_foreach_remove(priv->lastThemeStyleSet, (GHRFunc)_xfdashboard_actor_hashtable_is_duplicate_key, themeStyleSet); /* Iterate through remaining key and restore corresponding object properties * to their default values. */ g_hash_table_iter_init(&hashIter, priv->lastThemeStyleSet); while(g_hash_table_iter_next(&hashIter, (gpointer*)&styleName, (gpointer*)¶mSpec)) { GValue propertyValue=G_VALUE_INIT; GParamSpec *realParamSpec; /* Check if key is a valid object property name */ if(!g_hash_table_lookup_extended(possibleStyleSet, styleName, NULL, (gpointer*)¶mSpec)) continue; /* Get original referenced parameter specification. It does not need * to be referenced while converting because it is valid as this * value is stored in hashtable. */ realParamSpec=(GParamSpec*)g_param_spec_get_qdata(paramSpec, XFDASHBOARD_ACTOR_PARAM_SPEC_REF); /* Initialize property value to its type and default value */ g_value_init(&propertyValue, G_PARAM_SPEC_VALUE_TYPE(realParamSpec)); g_param_value_set_default(realParamSpec, &propertyValue); /* Set value at object property */ g_object_set_property(G_OBJECT(self), styleName, &propertyValue); didChange=TRUE; #ifdef DEBUG if(doDebug) { gchar *valstr; valstr=g_strdup_value_contents(&propertyValue); XFDASHBOARD_DEBUG(self, STYLE, "Restoring default value of style property [%s] %s=%s\n", G_OBJECT_CLASS_NAME(klass), styleName, valstr); g_free(valstr); } #endif /* Release allocated resources */ g_value_unset(&propertyValue); } /* Release resources of set of last changed properties as we do not need * it anymore. */ g_hash_table_destroy(priv->lastThemeStyleSet); priv->lastThemeStyleSet=NULL; } /* Remember this set of changed properties for next time to determine properties * which need to be restored to their default value. */ priv->lastThemeStyleSet=themeStyleSet; /* Release allocated resources */ g_hash_table_destroy(possibleStyleSet); /* Force a redraw if any change was made at this actor */ if(didChange) clutter_actor_queue_redraw(CLUTTER_ACTOR(self)); /* Reset force style revalidation flag because it's done now */ priv->forceStyleRevalidation=FALSE; /* All stylable properties are set now. So thaw 'property-changed' * notification now and fire all notifications at once. */ g_object_thaw_notify(G_OBJECT(self)); }
/* Get/set space-seperated list of IDs of effects used by this actor */ const gchar* xfdashboard_actor_get_effects(XfdashboardActor *self) { g_return_val_if_fail(XFDASHBOARD_IS_ACTOR(self), NULL); return(self->priv->effects); }
/* Update effects of actor with string of list of effect IDs */ static void _xfdashboard_actor_update_effects(XfdashboardActor *self, const gchar *inEffects) { XfdashboardActorPrivate *priv; XfdashboardTheme *theme; XfdashboardThemeEffects *themeEffects; gchar **effectIDs; gchar **iter; gchar *effectsList; g_return_if_fail(XFDASHBOARD_IS_ACTOR(self)); priv=self->priv; effectIDs=NULL; effectsList=NULL; /* Get theme effect instance which is needed to create effect objects. * Also take a reference on theme effect instance as it needs to be alive * while iterating through list of effect IDs and creating these effects. */ theme=xfdashboard_application_get_theme(NULL); themeEffects=xfdashboard_theme_get_effects(theme); g_object_ref(themeEffects); /* Get array of effect ID to create */ if(inEffects) effectIDs=xfdashboard_split_string(inEffects, " \t\r\n"); /* Remove all effects from actor */ clutter_actor_clear_effects(CLUTTER_ACTOR(self)); /* Create effects by their ID, add them to actor and * build result string with new list of effect IDs */ iter=effectIDs; while(iter && *iter) { ClutterEffect *effect; /* Create effect and if it was created successfully * add it to actor and update final string with list * of effect IDs. */ effect=xfdashboard_theme_effects_create_effect(themeEffects, *iter); if(effect) { clutter_actor_add_effect(CLUTTER_ACTOR(self), effect); if(effectsList) { gchar *tempEffectsList; tempEffectsList=g_strconcat(effectsList, " ", *iter, NULL); g_free(effectsList); effectsList=tempEffectsList; } else effectsList=g_strdup(*iter); } /* Continue with next ID */ iter++; } /* Set new string with list of effects */ if(priv->effects) g_free(priv->effects); priv->effects=g_strdup(effectsList); /* Release allocated resources */ if(effectsList) g_free(effectsList); if(effectIDs) g_strfreev(effectIDs); g_object_unref(themeEffects); }
/* Force restyling actor by theme next time stylable invalidation * function of this actor is called */ void xfdashboard_actor_invalidate(XfdashboardActor *self) { g_return_if_fail(XFDASHBOARD_IS_ACTOR(self)); self->priv->forceStyleRevalidation=TRUE; }
/* Dragging of actor ended */ static void _xfdashboard_drag_action_drag_end(ClutterDragAction *inAction, ClutterActor *inActor, gfloat inStageX, gfloat inStageY, ClutterModifierType inModifiers) { XfdashboardDragAction *self; XfdashboardDragActionPrivate *priv; ClutterDragActionClass *dragActionClass; GSList *list; XfdashboardDropAction *dropTarget; gfloat dropX, dropY; gboolean canDrop; g_return_if_fail(XFDASHBOARD_IS_DRAG_ACTION(inAction)); self=XFDASHBOARD_DRAG_ACTION(inAction); priv=self->priv; dragActionClass=CLUTTER_DRAG_ACTION_CLASS(xfdashboard_drag_action_parent_class); canDrop=FALSE; dropTarget=NULL; /* Hold a reference on ourselve as ClutterAction as the actor where we are bound to * may be destroyed in this function. We need to keep alive this action until * function ends. */ g_object_ref(self); /* Unset styles */ if(priv->source && XFDASHBOARD_IS_ACTOR(priv->source)) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->source), "drag-source"); } if(XFDASHBOARD_IS_ACTOR(priv->actor)) { xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->actor), "dragged"); } if(priv->dragHandle && XFDASHBOARD_IS_ACTOR(priv->dragHandle)) { gchar *styleClass; if(priv->source) { styleClass=g_strdup_printf("drag-source-%s", G_OBJECT_TYPE_NAME(priv->source)); xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); } styleClass=g_strdup_printf("drag-actor-%s", G_OBJECT_TYPE_NAME(priv->actor)); xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(priv->dragHandle), styleClass); g_free(styleClass); xfdashboard_stylable_remove_pseudo_class(XFDASHBOARD_STYLABLE(priv->dragHandle), "drag-handle"); priv->dragHandle=NULL; } if(priv->dragHandleChangedID) { g_signal_handler_disconnect(self, priv->dragHandleChangedID); priv->dragHandleChangedID=0; } /* Remove 'destroy' signal on dragged actor */ if(priv->actorDestroySignalID) { g_signal_handler_disconnect(priv->actor, priv->actorDestroySignalID); priv->actorDestroySignalID=0; } /* Remove our listerners for allocation changes */ for(list=priv->targets; list; list=g_slist_next(list)) { XfdashboardDropAction *target=XFDASHBOARD_DROP_ACTION(list->data); ClutterActorMeta *actorMeta=CLUTTER_ACTOR_META(target); ClutterActor *actor=clutter_actor_meta_get_actor(actorMeta); g_signal_handlers_disconnect_by_func(actor, G_CALLBACK(_xfdashboard_drag_on_drop_target_allocation_changed), self); } /* Find drop target at stage coordinate if dragged actor was not destroyed */ if(!priv->dragCancelled) dropTarget=_xfdashboard_drag_action_find_drop_traget_at_coord(self, inStageX, inStageY); /* If drop target was found check if we are allowed to drop on it. */ if(dropTarget) { /* Transform event coordinates relative to drop target */ _xfdashboard_drag_action_transform_stage_point(dropTarget, inStageX, inStageY, &dropX, &dropY); /* Ask drop target if we are allowed to drop dragged actor on it */ g_signal_emit_by_name(dropTarget, "can-drop", self, dropX, dropY, &canDrop); } /* If we cannot drop the draggged actor emit "drag-cancel" on dragged actor */ if(!canDrop) g_signal_emit_by_name(inAction, "drag-cancel", priv->actor, inStageX, inStageY, NULL); /* Iterate through list of drop targets to emit the "end" signal to the ones * on which the dragged actor will not be drop (either they were not the target * or it did not allow to drop on it). The real drop target gets the "drop" * signal. */ for(list=priv->targets; list; list=g_slist_next(list)) { XfdashboardDropAction *target=XFDASHBOARD_DROP_ACTION(list->data); if(canDrop && target && target==dropTarget) { g_signal_emit_by_name(dropTarget, "drop", self, dropX, dropY, NULL); } else { g_signal_emit_by_name(target, "end", self, NULL); } } /* Call parent's class method at last */ if(dragActionClass->drag_end) dragActionClass->drag_end(inAction, inActor, inStageX, inStageY, inModifiers); /* Forget dragged actor as dragging has ended now */ priv->actor=NULL; /* Free list of drop targets and unref each drop target */ if(priv->targets) g_slist_free_full(priv->targets, g_object_unref); priv->targets=NULL; /* Free list of actor we crossed by motion */ if(priv->lastMotionActors) { g_slist_foreach(priv->lastMotionActors, _xfdashboard_drag_action_on_motion_actor_destroyed, self); if(priv->lastMotionActors) g_slist_free(priv->lastMotionActors); priv->lastMotionActors=NULL; } /* Reset variables */ priv->lastDropTarget=NULL; /* Release the reference we took at function beginning */ g_object_unref(self); }