[Xfce4-commits] [apps/xfdashboard] 01/04: Next attempt to allow overriding draw function of background borders and corner, e.g. interesting for popup-menus to draw an arrow on any side of outline

noreply at xfce.org noreply at xfce.org
Fri Aug 26 13:37:23 CEST 2016


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

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit fc1c520bccbf0eb4d98a5f6abecd2be64db9b9c9
Author: Stephan Haller <nomad at froevel.de>
Date:   Fri Aug 26 12:34:15 2016 +0200

    Next attempt to allow overriding draw function of background borders and corner, e.g. interesting for popup-menus to draw an arrow on any side of outline
    
    This time the XfdashboardOutlineEffect provides a "draw" signal to paint the outline because the original code is the default signal handler.
    
    Next XfdashboardBackground connects to this new signal of XfdashboardOutlineEffect to proxy this signal through itself. It also provides a virtual function (*draw_outline) which will be called if set. That function has to return TRUE if it handled the painting of outline and FALSE if not. If no virtual function was set, XfdashboardBackground will return FALSE to get the next signal handler to draw the outline getting called (usually the default signal handler of XfdashboardOutlineEffect).
---
 libxfdashboard/background.c     |  53 +++++++++++-
 libxfdashboard/background.h     |   5 ++
 libxfdashboard/marshal.list     |   1 +
 libxfdashboard/outline-effect.c | 186 +++++++++++++++++++++++++---------------
 libxfdashboard/outline-effect.h |   8 ++
 5 files changed, 185 insertions(+), 68 deletions(-)

diff --git a/libxfdashboard/background.c b/libxfdashboard/background.c
index 913f426..b982f46 100644
--- a/libxfdashboard/background.c
+++ b/libxfdashboard/background.c
@@ -96,6 +96,49 @@ static GParamSpec* XfdashboardBackgroundProperties[PROP_LAST]={ 0, };
 
 /* IMPLEMENTATION: Private variables and methods */
 
+/* Outline effect emitted signal to draw it so proxy this signal through this
+ * actor object instance first to allow overriding the default draw function.
+ * This function should return TRUE to stop further processing of this signal
+ * and to avoid getting the default signal handler to draw the oultine at
+ * XfdashboardOutlineEffect called. FALSE has to be returned to get it called,
+ * i.e. no custom function to draw outline was set.
+ */
+static gboolean _xfdashboard_background_on_draw_outline(XfdashboardBackground *self,
+														ClutterEffectPaintFlags inFlags,
+														ClutterActor *inTarget,
+														gfloat inWidth,
+														gfloat inHeight,
+														gpointer inUserData)
+{
+	XfdashboardBackgroundPrivate	*priv;
+	XfdashboardBackgroundClass		*klass;
+	gboolean						handled;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_BACKGROUND(self), FALSE);
+	g_return_val_if_fail(CLUTTER_IS_ACTOR(inTarget), FALSE);
+	g_return_val_if_fail(XFDASHBOARD_IS_OUTLINE_EFFECT(inUserData), FALSE);
+
+	priv=self->priv;
+
+	/* By default the signal was not handled */
+	handled=FALSE;
+
+	/* If a custom function to draw outline was set, call it and store handled result */
+	klass=XFDASHBOARD_BACKGROUND_GET_CLASS(self);
+	if(klass->draw_outline)
+	{
+		handled=(klass->draw_outline)(self, inFlags, inTarget, inWidth, inHeight);
+	}
+
+	/* Return handled state. If it is TRUE the further processing of this signal
+	 * will stop and that means that the default draw function of XfdashboardOutlineEffect
+	 * will never be called - it is overriden. If it is FALSE the next signal handler
+	 * (which might be the default signal handler of XfdashboardOutlineEffect and
+	 * therefore the default drawing function for oulines) is called.
+	 */
+	return(handled);
+}
+
 /* Rectangle canvas should be redrawn */
 static gboolean _xfdashboard_background_on_draw_fill_canvas(XfdashboardBackground *self,
 																cairo_t *inContext,
@@ -565,7 +608,15 @@ static void xfdashboard_background_init(XfdashboardBackground *self)
 	clutter_actor_add_effect(CLUTTER_ACTOR(self), CLUTTER_EFFECT(priv->outline));
 
 	/* Connect signals */
-	g_signal_connect_swapped(priv->fillCanvas, "draw", G_CALLBACK(_xfdashboard_background_on_draw_fill_canvas), self);
+	g_signal_connect_swapped(priv->fillCanvas,
+								"draw",
+								G_CALLBACK(_xfdashboard_background_on_draw_fill_canvas),
+								self);
+
+	g_signal_connect_swapped(priv->outline,
+								"draw",
+								G_CALLBACK(_xfdashboard_background_on_draw_outline),
+								self);
 }
 
 /* IMPLEMENTATION: Public API */
diff --git a/libxfdashboard/background.h b/libxfdashboard/background.h
index 3d02f01..7315b23 100644
--- a/libxfdashboard/background.h
+++ b/libxfdashboard/background.h
@@ -86,6 +86,11 @@ struct _XfdashboardBackgroundClass
 
 	/*< public >*/
 	/* Virtual functions */
+	gboolean (*draw_outline)(XfdashboardBackground *self,
+								ClutterEffectPaintFlags inFlags,
+								ClutterActor *inTarget,
+								gfloat inWidth,
+								gfloat inHeight);
 };
 
 /* Public API */
diff --git a/libxfdashboard/marshal.list b/libxfdashboard/marshal.list
index 0120dfc..5658f40 100644
--- a/libxfdashboard/marshal.list
+++ b/libxfdashboard/marshal.list
@@ -8,6 +8,7 @@ VOID:STRING,BOOLEAN
 BOOLEAN:OBJECT
 BOOLEAN:OBJECT,ENUM
 BOOLEAN:OBJECT,FLOAT,FLOAT
+BOOLEAN:FLAGS,OBJECT,FLOAT,FLOAT
 BOOLEAN:OBJECT,STRING,OBJECT
 BOOLEAN:VOID
 OBJECT:VOID
diff --git a/libxfdashboard/outline-effect.c b/libxfdashboard/outline-effect.c
index 1c5607a..ff2361e 100644
--- a/libxfdashboard/outline-effect.c
+++ b/libxfdashboard/outline-effect.c
@@ -31,6 +31,7 @@
 #include <math.h>
 
 #include <libxfdashboard/enums.h>
+#include <libxfdashboard/marshal.h>
 #include <libxfdashboard/compat.h>
 
 
@@ -69,35 +70,41 @@ enum
 
 static GParamSpec* XfdashboardOutlineEffectProperties[PROP_LAST]={ 0, };
 
+/* Signals */
+enum
+{
+	SIGNAL_DRAW,
+
+	SIGNAL_LAST
+};
+
+static guint XfdashboardOutlineEffectSignals[SIGNAL_LAST]={ 0, };
+
+
 /* IMPLEMENTATION: Private variables and methods */
 
-/* Draw effect after actor was drawn */
-static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEffectPaintFlags inFlags)
+/* Draw outline effect */
+static gboolean _xfdashboard_outline_effect_draw(XfdashboardOutlineEffect *self,
+													ClutterEffectPaintFlags inFlags,
+													ClutterActor *inTarget,
+													gfloat inWidth,
+													gfloat inHeight)
 {
-	XfdashboardOutlineEffect			*self;
 	XfdashboardOutlineEffectPrivate		*priv;
-	ClutterActor						*target;
-	gfloat								width, height;
 	gfloat								lineWidth;
 
-	g_return_if_fail(XFDASHBOARD_IS_OUTLINE_EFFECT(inEffect));
+	g_return_val_if_fail(XFDASHBOARD_IS_OUTLINE_EFFECT(self), FALSE);
 
-	self=XFDASHBOARD_OUTLINE_EFFECT(inEffect);
 	priv=self->priv;
 
-	/* Chain to the next item in the paint sequence */
-	target=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self));
-	clutter_actor_continue_paint(target);
-
-	/* Get size of outline to draw */
-	clutter_actor_get_size(target, &width, &height);
-
-	/* Round line width for better looking and check if we can draw
-	 * outline with configured line width. That means it needs to be
-	 * greater or equal to 1.0
+	/* Round line inWidth for better looking and check if we can draw
+	 * outline with configured line inWidth. That means it needs to be
+	 * greater or equal to 1.0. If it's not then return with TRUE from here
+	 * to stop further signal handling processing. That means this one was the
+	 * last one called for drawing the outline and it did nothing actual.
 	 */
 	lineWidth=floor(priv->width+0.5);
-	if(lineWidth<1.0f) return;
+	if(lineWidth<1.0f) return(TRUE);
 
 	/* Draw outline */
 	if(priv->color)
@@ -113,12 +120,12 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 		gfloat							outerRadius, innerRadius;
 
 		/* Determine radius for rounded corners of outer and inner lines */
-		outerRadius=MIN(priv->cornersRadius+(lineWidth/2.0f), width/2.0f);
-		outerRadius=MIN(outerRadius, width/2.0f);
+		outerRadius=MIN(priv->cornersRadius+(lineWidth/2.0f), inWidth/2.0f);
+		outerRadius=MIN(outerRadius, inWidth/2.0f);
 		outerRadius=MAX(outerRadius, 0.0f);
 
-		innerRadius=MIN(priv->cornersRadius-(lineWidth/2.0f), width/2.0f);
-		innerRadius=MIN(innerRadius, width/2.0f);
+		innerRadius=MIN(priv->cornersRadius-(lineWidth/2.0f), inWidth/2.0f);
+		innerRadius=MIN(innerRadius, inWidth/2.0f);
 		innerRadius=MAX(innerRadius, 0.0f);
 
 		/* Top-left corner */
@@ -147,8 +154,8 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 
 			cogl_path_new();
 			cogl_path_move_to(offset1, 0);
-			cogl_path_line_to(width-offset2, 0);
-			cogl_path_line_to(width-offset2, outerRadius-innerRadius);
+			cogl_path_line_to(inWidth-offset2, 0);
+			cogl_path_line_to(inWidth-offset2, outerRadius-innerRadius);
 			cogl_path_line_to(offset1, outerRadius-innerRadius);
 			cogl_path_line_to(offset1, 0);
 			cogl_path_fill_preserve();
@@ -161,11 +168,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			priv->borders & XFDASHBOARD_BORDERS_RIGHT)
 		{
 			cogl_path_new();
-			cogl_path_move_to(width-outerRadius, 0);
-			cogl_path_arc(width-outerRadius, outerRadius, outerRadius, outerRadius, 270, 360);
-			cogl_path_line_to(width-outerRadius+innerRadius, outerRadius);
-			cogl_path_arc(width-outerRadius, outerRadius, innerRadius, innerRadius, 360, 270);
-			cogl_path_line_to(width-outerRadius, 0);
+			cogl_path_move_to(inWidth-outerRadius, 0);
+			cogl_path_arc(inWidth-outerRadius, outerRadius, outerRadius, outerRadius, 270, 360);
+			cogl_path_line_to(inWidth-outerRadius+innerRadius, outerRadius);
+			cogl_path_arc(inWidth-outerRadius, outerRadius, innerRadius, innerRadius, 360, 270);
+			cogl_path_line_to(inWidth-outerRadius, 0);
 			cogl_path_fill_preserve();
 			cogl_path_close();
 		}
@@ -180,11 +187,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			if(priv->corners & XFDASHBOARD_CORNERS_BOTTOM_RIGHT) offset2=outerRadius;
 
 			cogl_path_new();
-			cogl_path_move_to(width, offset1);
-			cogl_path_line_to(width, height-offset2);
-			cogl_path_line_to(width-outerRadius+innerRadius, height-offset2);
-			cogl_path_line_to(width-outerRadius+innerRadius, offset1);
-			cogl_path_line_to(width, offset1);
+			cogl_path_move_to(inWidth, offset1);
+			cogl_path_line_to(inWidth, inHeight-offset2);
+			cogl_path_line_to(inWidth-outerRadius+innerRadius, inHeight-offset2);
+			cogl_path_line_to(inWidth-outerRadius+innerRadius, offset1);
+			cogl_path_line_to(inWidth, offset1);
 			cogl_path_fill_preserve();
 			cogl_path_close();
 		}
@@ -195,11 +202,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			priv->borders & XFDASHBOARD_BORDERS_BOTTOM)
 		{
 			cogl_path_new();
-			cogl_path_move_to(width, height-outerRadius);
-			cogl_path_arc(width-outerRadius, height-outerRadius, outerRadius, outerRadius, 0, 90);
-			cogl_path_line_to(width-outerRadius, height-outerRadius+innerRadius);
-			cogl_path_arc(width-outerRadius, height-outerRadius, innerRadius, innerRadius, 90, 0);
-			cogl_path_line_to(width, height-outerRadius);
+			cogl_path_move_to(inWidth, inHeight-outerRadius);
+			cogl_path_arc(inWidth-outerRadius, inHeight-outerRadius, outerRadius, outerRadius, 0, 90);
+			cogl_path_line_to(inWidth-outerRadius, inHeight-outerRadius+innerRadius);
+			cogl_path_arc(inWidth-outerRadius, inHeight-outerRadius, innerRadius, innerRadius, 90, 0);
+			cogl_path_line_to(inWidth, inHeight-outerRadius);
 			cogl_path_fill_preserve();
 			cogl_path_close();
 		}
@@ -214,11 +221,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			if(priv->corners & XFDASHBOARD_CORNERS_BOTTOM_RIGHT) offset2=outerRadius;
 
 			cogl_path_new();
-			cogl_path_move_to(offset1, height);
-			cogl_path_line_to(width-offset2, height);
-			cogl_path_line_to(width-offset2, height-outerRadius+innerRadius);
-			cogl_path_line_to(offset1, height-outerRadius+innerRadius);
-			cogl_path_line_to(offset1, height);
+			cogl_path_move_to(offset1, inHeight);
+			cogl_path_line_to(inWidth-offset2, inHeight);
+			cogl_path_line_to(inWidth-offset2, inHeight-outerRadius+innerRadius);
+			cogl_path_line_to(offset1, inHeight-outerRadius+innerRadius);
+			cogl_path_line_to(offset1, inHeight);
 			cogl_path_fill_preserve();
 			cogl_path_close();
 		}
@@ -229,11 +236,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			priv->borders & XFDASHBOARD_BORDERS_LEFT)
 		{
 			cogl_path_new();
-			cogl_path_move_to(outerRadius, height);
-			cogl_path_arc(outerRadius, height-outerRadius, outerRadius, outerRadius, 90, 180);
-			cogl_path_line_to(outerRadius-innerRadius, height-outerRadius);
-			cogl_path_arc(outerRadius, height-outerRadius, innerRadius, innerRadius, 180, 90);
-			cogl_path_line_to(outerRadius, height);
+			cogl_path_move_to(outerRadius, inHeight);
+			cogl_path_arc(outerRadius, inHeight-outerRadius, outerRadius, outerRadius, 90, 180);
+			cogl_path_line_to(outerRadius-innerRadius, inHeight-outerRadius);
+			cogl_path_arc(outerRadius, inHeight-outerRadius, innerRadius, innerRadius, 180, 90);
+			cogl_path_line_to(outerRadius, inHeight);
 			cogl_path_fill_preserve();
 			cogl_path_close();
 		}
@@ -249,8 +256,8 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 
 			cogl_path_new();
 			cogl_path_move_to(0, offset1);
-			cogl_path_line_to(0, height-offset2);
-			cogl_path_line_to(outerRadius-innerRadius, height-offset2);
+			cogl_path_line_to(0, inHeight-offset2);
+			cogl_path_line_to(outerRadius-innerRadius, inHeight-offset2);
 			cogl_path_line_to(outerRadius-innerRadius, offset1);
 			cogl_path_line_to(0, offset1);
 			cogl_path_fill_preserve();
@@ -264,8 +271,8 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			{
 				cogl_path_new();
 				cogl_path_move_to(0, 0);
-				cogl_path_line_to(width, 0);
-				cogl_path_line_to(width, lineWidth);
+				cogl_path_line_to(inWidth, 0);
+				cogl_path_line_to(inWidth, lineWidth);
 				cogl_path_line_to(0, lineWidth);
 				cogl_path_line_to(0, 0);
 				cogl_path_fill_preserve();
@@ -276,11 +283,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			if(priv->borders & XFDASHBOARD_BORDERS_RIGHT)
 			{
 				cogl_path_new();
-				cogl_path_move_to(width, 0);
-				cogl_path_line_to(width, height);
-				cogl_path_line_to(width-lineWidth, height);
-				cogl_path_line_to(width-lineWidth, 0);
-				cogl_path_line_to(width, 0);
+				cogl_path_move_to(inWidth, 0);
+				cogl_path_line_to(inWidth, inHeight);
+				cogl_path_line_to(inWidth-lineWidth, inHeight);
+				cogl_path_line_to(inWidth-lineWidth, 0);
+				cogl_path_line_to(inWidth, 0);
 				cogl_path_fill_preserve();
 				cogl_path_close();
 			}
@@ -289,11 +296,11 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			if(priv->borders & XFDASHBOARD_BORDERS_BOTTOM)
 			{
 				cogl_path_new();
-				cogl_path_move_to(0, height);
-				cogl_path_line_to(width, height);
-				cogl_path_line_to(width, height-lineWidth);
-				cogl_path_line_to(0, height-lineWidth);
-				cogl_path_line_to(0, height);
+				cogl_path_move_to(0, inHeight);
+				cogl_path_line_to(inWidth, inHeight);
+				cogl_path_line_to(inWidth, inHeight-lineWidth);
+				cogl_path_line_to(0, inHeight-lineWidth);
+				cogl_path_line_to(0, inHeight);
 				cogl_path_fill_preserve();
 				cogl_path_close();
 			}
@@ -303,8 +310,8 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			{
 				cogl_path_new();
 				cogl_path_move_to(0, 0);
-				cogl_path_line_to(0, height);
-				cogl_path_line_to(lineWidth, height);
+				cogl_path_line_to(0, inHeight);
+				cogl_path_line_to(lineWidth, inHeight);
 				cogl_path_line_to(lineWidth, 0);
 				cogl_path_line_to(0, 0);
 				cogl_path_fill_preserve();
@@ -312,6 +319,33 @@ static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEf
 			}
 		}
 
+	/* Return TRUE to stop further signal handling processing. That means this
+	 * one was the last one called for drawing the outline.
+	 */
+	return(TRUE);
+}
+
+/* Draw effect after actor was drawn */
+static void _xfdashboard_outline_effect_paint(ClutterEffect *inEffect, ClutterEffectPaintFlags inFlags)
+{
+	XfdashboardOutlineEffect			*self;
+	ClutterActor						*target;
+	gfloat								width, height;
+	gboolean							result;
+
+	g_return_if_fail(XFDASHBOARD_IS_OUTLINE_EFFECT(inEffect));
+
+	self=XFDASHBOARD_OUTLINE_EFFECT(inEffect);
+
+	/* Chain to the next item in the paint sequence */
+	target=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self));
+	clutter_actor_continue_paint(target);
+
+	/* Get size of outline to draw */
+	clutter_actor_get_size(target, &width, &height);
+
+	/* Emit signal 'draw' to get outline drawn */
+	g_signal_emit(self, XfdashboardOutlineEffectSignals[SIGNAL_DRAW], 0, inFlags, target, width, height, &result);
 }
 
 /* IMPLEMENTATION: GObject */
@@ -415,12 +449,14 @@ static void xfdashboard_outline_effect_class_init(XfdashboardOutlineEffectClass
 	GObjectClass					*gobjectClass=G_OBJECT_CLASS(klass);
 
 	/* Override functions */
+	klass->draw=_xfdashboard_outline_effect_draw;
+
+	effectClass->paint=_xfdashboard_outline_effect_paint;
+
 	gobjectClass->dispose=_xfdashboard_outline_effect_dispose;
 	gobjectClass->set_property=_xfdashboard_outline_effect_set_property;
 	gobjectClass->get_property=_xfdashboard_outline_effect_get_property;
 
-	effectClass->paint=_xfdashboard_outline_effect_paint;
-
 	/* Set up private structure */
 	g_type_class_add_private(klass, sizeof(XfdashboardOutlineEffectPrivate));
 
@@ -465,6 +501,22 @@ static void xfdashboard_outline_effect_class_init(XfdashboardOutlineEffectClass
 							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardOutlineEffectProperties);
+
+	/* Define signals */
+	XfdashboardOutlineEffectSignals[SIGNAL_DRAW]=
+		g_signal_new("draw",
+						G_TYPE_FROM_CLASS(klass),
+						G_SIGNAL_RUN_LAST,
+						G_STRUCT_OFFSET(XfdashboardOutlineEffectClass, draw),
+						g_signal_accumulator_true_handled,
+						NULL,
+						_xfdashboard_marshal_BOOLEAN__FLAGS_OBJECT_FLOAT_FLOAT,
+						G_TYPE_BOOLEAN,
+						4,
+						CLUTTER_TYPE_EFFECT_PAINT_FLAGS,
+						CLUTTER_TYPE_ACTOR,
+						G_TYPE_FLOAT,
+						G_TYPE_FLOAT);
 }
 
 /* Object initialization
diff --git a/libxfdashboard/outline-effect.h b/libxfdashboard/outline-effect.h
index 1fab09f..44266b7 100644
--- a/libxfdashboard/outline-effect.h
+++ b/libxfdashboard/outline-effect.h
@@ -60,6 +60,14 @@ struct _XfdashboardOutlineEffectClass
 	/*< private >*/
 	/* Parent class */
 	ClutterEffectClass					parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+	gboolean (*draw)(XfdashboardOutlineEffect *self,
+						ClutterEffectPaintFlags inFlags,
+						ClutterActor *inTarget,
+						gfloat inWidth,
+						gfloat inHeight);
 };
 
 /* Public API */

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


More information about the Xfce4-commits mailing list