[Xfce4-commits] [apps/xfdashboard] 01/01: Add signals to interface XfdashboardStylable for adding and removing classes and pseudo-classes

noreply at xfce.org noreply at xfce.org
Mon Jan 20 13:51:56 CET 2020


This is an automated email from the git hooks/post-receive script.

n   o   m   a   d       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository apps/xfdashboard.

commit 9c8a56389fcdec0b26436734c3103910d1fb4d22
Author: Stephan Haller <nomad at froevel.de>
Date:   Mon Jan 20 13:51:05 2020 +0100

    Add signals to interface XfdashboardStylable for adding and removing classes and pseudo-classes
---
 libxfdashboard/collapse-box.c |   2 +-
 libxfdashboard/stylable.c     | 264 ++++++++++++++++++++++++++++++++++++++++++
 libxfdashboard/stylable.h     |   4 +
 3 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/libxfdashboard/collapse-box.c b/libxfdashboard/collapse-box.c
index 71820c9..3c1aa90 100644
--- a/libxfdashboard/collapse-box.c
+++ b/libxfdashboard/collapse-box.c
@@ -32,9 +32,9 @@
 
 #include <libxfdashboard/enums.h>
 #include <libxfdashboard/focus-manager.h>
+#include <libxfdashboard/animation.h>
 #include <libxfdashboard/utils.h>
 #include <libxfdashboard/compat.h>
-#include <libxfdashboard/animation.h>
 
 
 /* Define this class in GObject system */
diff --git a/libxfdashboard/stylable.c b/libxfdashboard/stylable.c
index 206928c..d306d4c 100644
--- a/libxfdashboard/stylable.c
+++ b/libxfdashboard/stylable.c
@@ -45,17 +45,111 @@ enum
 	/* Signals */
 	SIGNAL_STYLE_REVALIDATED,
 
+	SIGNAL_CLASS_ADDED,
+	SIGNAL_CLASS_REMOVED,
+
+	SIGNAL_PSEUDO_CLASS_ADDED,
+	SIGNAL_PSEUDO_CLASS_REMOVED,
+
 	SIGNAL_LAST
 };
 
 static guint XfdashboardStylableSignals[SIGNAL_LAST]={ 0, };
 
+
 /* IMPLEMENTATION: Private variables and methods */
 #define XFDASHBOARD_STYLABLE_WARN_NOT_IMPLEMENTED(self, vfunc) \
 	g_warning(_("Object of type %s does not implement required virtual function XfdashboardStylable::%s"), \
 				G_OBJECT_TYPE_NAME(self), \
 				vfunc);
 
+/* Create list of added and removed class by difference of current classes string
+ * and new classes string.
+ */
+static void _xfdashboard_stylable_split_into_added_removed_lists(const gchar *inCurrentClasses,
+																	const gchar *inNewClasses,
+																	gchar *inDelimiter,
+																	GSList **outAddedClasses,
+																	GSList **outRemovedClasses)
+{
+	gchar			**currentClasses;
+	gchar			**newClasses;
+	gchar			**iter;
+	gchar			**iterDest;
+
+	g_return_if_fail(inDelimiter!=NULL && *inDelimiter);
+	g_return_if_fail(outAddedClasses!=NULL && *outAddedClasses==NULL);
+	g_return_if_fail(outRemovedClasses!=NULL && *outRemovedClasses==NULL);
+
+	/* Split current classes string into tokens */
+	currentClasses=NULL;
+	if(inCurrentClasses) currentClasses=g_strsplit(inCurrentClasses, inDelimiter, -1);
+
+	/* Split new classes string into tokens */
+	newClasses=NULL;
+	if(inNewClasses) newClasses=g_strsplit(inNewClasses, inDelimiter, -1);
+
+	/* Create list of added classes */
+	for(iter=newClasses; iter && *iter; iter++)
+	{
+		/* Skip empty strings */
+		if(!**iter) continue;
+
+		/* Iterate through current classes and stop further iteration if a match
+		 * was found. If no match is found, add added class to list.
+		 */
+		for(iterDest=currentClasses; iterDest && *iterDest; iterDest++)
+		{
+			/* Skip empty strings */
+			if(!**iterDest) continue;
+
+			/* If new class matches current class, stop iteration */
+			if(g_strcmp0(*iterDest, *iter)==0) break;
+		}
+
+		/* If pointer of iterator for current classes is NULL, then no match
+		 * was found and we have to add the iterated new class to list of added
+		 * classes.
+		 */
+		if(!iterDest || !*iterDest)
+		{
+			*outAddedClasses=g_slist_prepend(*outAddedClasses, g_strdup(*iter));
+		}
+	}
+
+	/* Create list of removed classes */
+	for(iter=currentClasses; iter && *iter; iter++)
+	{
+		/* Skip empty strings */
+		if(!**iter) continue;
+
+		/* Iterate through new classes and stop further iteration if a match
+		 * was found. If no match is found, add removed class to list.
+		 */
+		for(iterDest=newClasses; iterDest && *iterDest; iterDest++)
+		{
+			/* Skip empty strings */
+			if(!**iterDest) continue;
+
+			/* If current class matches new class, stop iteration */
+			if(g_strcmp0(*iterDest, *iter)==0) break;
+		}
+
+		/* If pointer of iterator for new classes is NULL, then no match
+		 * was found and we have to add the iterated current class to list of
+		 * removed classes.
+		 */
+		if(!iterDest || !*iterDest)
+		{
+			*outRemovedClasses=g_slist_prepend(*outRemovedClasses, g_strdup(*iter));
+		}
+	}
+
+	/* Release allocated resources */
+	if(currentClasses) g_strfreev(currentClasses);
+	if(newClasses) g_strfreev(newClasses);
+}
+
 /* Check if haystack contains needle.
  * The haystack is a string representing a list which entries is seperated
  * by a seperator character. This function looks up the haystack if it
@@ -255,6 +349,7 @@ static void _xfdashboard_stylable_real_invalidate(XfdashboardStylable *self)
 	g_signal_emit(self, XfdashboardStylableSignals[SIGNAL_STYLE_REVALIDATED], 0);
 }
 
+
 /* IMPLEMENTATION: GObject */
 
 /* Interface initialization
@@ -322,11 +417,104 @@ void xfdashboard_stylable_default_init(XfdashboardStylableInterface *iface)
 							G_TYPE_NONE,
 							0);
 
+		/**
+		 * XfdashboardStylable::class-added:
+		 * @self: A #XfdashboardStylable
+		 * @inClass: The class added to @self
+		 *
+		 * The ::class-added signal is emitted when the class @inClass, e.g. ".foo",
+		 * was added to @self.
+		 *
+		 * This signal is only emitted when the class @inClass added to @self was
+		 * not set before. If the class @inClass was already set, this signal will
+		 * not be emitted again.
+		 */
+		XfdashboardStylableSignals[SIGNAL_CLASS_ADDED]=
+			g_signal_new("class-added",
+							G_TYPE_FROM_INTERFACE(iface),
+							G_SIGNAL_RUN_LAST,
+							G_STRUCT_OFFSET(XfdashboardStylableInterface, class_added),
+							NULL,
+							NULL,
+							g_cclosure_marshal_VOID__STRING,
+							G_TYPE_NONE,
+							1,
+							G_TYPE_STRING);
+
+		/**
+		 * XfdashboardStylable::class-remove:
+		 * @self: A #XfdashboardStylable
+		 * @inClass: The class remove from @self
+		 *
+		 * The ::class-removed signal is emitted when the class @inClass, e.g. ".foo",
+		 * was removed from @self.
+		 *
+		 * This signal is only emitted when the class @inClass was set at @self.
+		 */
+		XfdashboardStylableSignals[SIGNAL_CLASS_REMOVED]=
+			g_signal_new("class-removed",
+							G_TYPE_FROM_INTERFACE(iface),
+							G_SIGNAL_RUN_LAST,
+							G_STRUCT_OFFSET(XfdashboardStylableInterface, class_removed),
+							NULL,
+							NULL,
+							g_cclosure_marshal_VOID__STRING,
+							G_TYPE_NONE,
+							1,
+							G_TYPE_STRING);
+
+		/**
+		 * XfdashboardStylable::pseudo-class-added:
+		 * @self: A #XfdashboardStylable
+		 * @inClass: The pseudo-class added to @self
+		 *
+		 * The ::pseudo-class-added signal is emitted when the pseudo-class @inClass,
+		 * e.g. ".foo", was added to @self.
+		 *
+		 * This signal is only emitted when the psuedo-class @inClass added to @self
+		 * was not set before. If the pseudo-class @inClass was already set, this signal
+		 * will not be emitted again.
+		 */
+		XfdashboardStylableSignals[SIGNAL_PSEUDO_CLASS_ADDED]=
+			g_signal_new("pseudo-class-added",
+							G_TYPE_FROM_INTERFACE(iface),
+							G_SIGNAL_RUN_LAST,
+							G_STRUCT_OFFSET(XfdashboardStylableInterface, pseudo_class_added),
+							NULL,
+							NULL,
+							g_cclosure_marshal_VOID__STRING,
+							G_TYPE_NONE,
+							1,
+							G_TYPE_STRING);
+
+		/**
+		 * XfdashboardStylable::pseudo-class-remove:
+		 * @self: A #XfdashboardStylable
+		 * @inClass: The pseudo-class remove from @self
+		 *
+		 * The ::pseudo-class-removed signal is emitted when the pseudo-class
+		 * @inClass, e.g. ".foo", was removed from @self.
+		 *
+		 * This signal is only emitted when the class @inClass was set at @self.
+		 */
+		XfdashboardStylableSignals[SIGNAL_PSEUDO_CLASS_REMOVED]=
+			g_signal_new("pseudo-class-removed",
+							G_TYPE_FROM_INTERFACE(iface),
+							G_SIGNAL_RUN_LAST,
+							G_STRUCT_OFFSET(XfdashboardStylableInterface, pseudo_class_removed),
+							NULL,
+							NULL,
+							g_cclosure_marshal_VOID__STRING,
+							G_TYPE_NONE,
+							1,
+							G_TYPE_STRING);
+
 		/* Set flag that base initialization was done for this interface */
 		initialized=TRUE;
 	}
 }
 
+
 /* IMPLEMENTATION: Public API */
 
 /* Call virtual function "get_stylable_properties" */
@@ -456,11 +644,49 @@ const gchar* xfdashboard_stylable_get_classes(XfdashboardStylable *self)
 void xfdashboard_stylable_set_classes(XfdashboardStylable *self, const gchar *inClasses)
 {
 	XfdashboardStylableInterface		*iface;
+	const gchar							*currentClasses;
+	GSList								*addedClasses;
+	GSList								*removedClasses;
+	GSList								*iter;
 
 	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));
 
 	iface=XFDASHBOARD_STYLABLE_GET_IFACE(self);
 
+	/* Split new classes to set into lists of added classes and removed ones. */
+	currentClasses=xfdashboard_stylable_get_classes(self);
+	addedClasses=NULL;
+	removedClasses=NULL;
+	_xfdashboard_stylable_split_into_added_removed_lists(currentClasses,
+															inClasses,
+															".",
+															&addedClasses,
+															&removedClasses);
+
+	/* Iterate through list of newly added classes and emit "class-added" signal
+	 * for each new class.
+	 */
+	if(addedClasses)
+	{
+		for(iter=addedClasses; iter; iter=g_slist_next(iter))
+		{
+			g_signal_emit(self, XfdashboardStylableSignals[SIGNAL_CLASS_ADDED], 0, iter->data);
+		}
+		g_slist_free_full(addedClasses, g_free);
+	}
+
+	/* Iterate through list of removed classes and emit "class-removed" signal
+	 * for each class removed.
+	 */
+	if(removedClasses)
+	{
+		for(iter=removedClasses; iter; iter=g_slist_next(iter))
+		{
+			g_signal_emit(self, XfdashboardStylableSignals[SIGNAL_CLASS_REMOVED], 0, iter->data);
+		}
+		g_slist_free_full(removedClasses, g_free);
+	}
+
 	/* Call virtual function */
 	if(iface->set_classes)
 	{
@@ -595,11 +821,49 @@ const gchar* xfdashboard_stylable_get_pseudo_classes(XfdashboardStylable *self)
 void xfdashboard_stylable_set_pseudo_classes(XfdashboardStylable *self, const gchar *inClasses)
 {
 	XfdashboardStylableInterface		*iface;
+	const gchar							*currentClasses;
+	GSList								*addedClasses;
+	GSList								*removedClasses;
+	GSList								*iter;
 
 	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));
 
 	iface=XFDASHBOARD_STYLABLE_GET_IFACE(self);
 
+	/* Split new classes to set into lists of added classes and removed ones. */
+	currentClasses=xfdashboard_stylable_get_pseudo_classes(self);
+	addedClasses=NULL;
+	removedClasses=NULL;
+	_xfdashboard_stylable_split_into_added_removed_lists(currentClasses,
+															inClasses,
+															":",
+															&addedClasses,
+															&removedClasses);
+
+	/* Iterate through list of newly added classes and emit "pseudo-class-added"
+	 * signal for each new pseudo-class.
+	 */
+	if(addedClasses)
+	{
+		for(iter=addedClasses; iter; iter=g_slist_next(iter))
+		{
+			g_signal_emit(self, XfdashboardStylableSignals[SIGNAL_PSEUDO_CLASS_ADDED], 0, iter->data);
+		}
+		g_slist_free_full(addedClasses, g_free);
+	}
+
+	/* Iterate through list of removed classes and emit "pseudo-class-removed"
+	 * signal for each pseudo-class removed.
+	 */
+	if(removedClasses)
+	{
+		for(iter=removedClasses; iter; iter=g_slist_next(iter))
+		{
+			g_signal_emit(self, XfdashboardStylableSignals[SIGNAL_PSEUDO_CLASS_REMOVED], 0, iter->data);
+		}
+		g_slist_free_full(removedClasses, g_free);
+	}
+
 	/* Call virtual function */
 	if(iface->set_pseudo_classes)
 	{
diff --git a/libxfdashboard/stylable.h b/libxfdashboard/stylable.h
index d884354..57a03f3 100644
--- a/libxfdashboard/stylable.h
+++ b/libxfdashboard/stylable.h
@@ -57,9 +57,13 @@ struct _XfdashboardStylableInterface
 
 	const gchar* (*get_classes)(XfdashboardStylable *self);
 	void (*set_classes)(XfdashboardStylable *self, const gchar *inClasses);
+	void (*class_added)(XfdashboardStylable *self, const gchar *inClass);
+	void (*class_removed)(XfdashboardStylable *self, const gchar *inClass);
 
 	const gchar* (*get_pseudo_classes)(XfdashboardStylable *self);
 	void (*set_pseudo_classes)(XfdashboardStylable *self, const gchar *inClasses);
+	void (*pseudo_class_added)(XfdashboardStylable *self, const gchar *inClass);
+	void (*pseudo_class_removed)(XfdashboardStylable *self, const gchar *inClass);
 
 	void (*invalidate)(XfdashboardStylable *self);
 };

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list