[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