diff --git a/src/lib/aqdiagram/draw/0BUILD b/src/lib/aqdiagram/draw/0BUILD
index 7b6b0f0..d989dae 100644
--- a/src/lib/aqdiagram/draw/0BUILD
+++ b/src/lib/aqdiagram/draw/0BUILD
@@ -70,16 +70,19 @@
context_cairo.h
+ o_drawable.h
context_cairo_p.h
+ o_drawable_p.h
$(local/typefiles)
context_cairo.c
+ o_drawable.c
diff --git a/src/lib/aqdiagram/draw/o_drawable.c b/src/lib/aqdiagram/draw/o_drawable.c
new file mode 100644
index 0000000..933cc11
--- /dev/null
+++ b/src/lib/aqdiagram/draw/o_drawable.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "o_drawable_p.h"
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+static GWENHYWFAR_CB void _freeData(void *bp, void *p);
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+GWEN_INHERIT(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE);
+
+
+
+AQDG_OBJECT *AQDG_DrawableObject_new(AQDG_OBJECT *parent, uint32_t options)
+{
+ AQDG_OBJECT *object;
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ object=AQDG_Object_new();
+ GWEN_NEW_OBJECT(AQDG_OBJECT_DRAWABLE, xo);
+ GWEN_INHERIT_SETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object, xo, _freeData);
+
+ AQDG_Object_SetOptions(object, options);
+
+ if (parent && GWEN_INHERIT_ISOFTYPE(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, parent)) {
+ xo->fontId=AQDG_DrawableObject_GetFontId(parent);
+ xo->foregroundPenId=AQDG_DrawableObject_GetForegroundPenId(parent);
+ xo->backgroundPenId=AQDG_DrawableObject_GetBackgroundPenId(parent);
+ }
+
+ if (parent)
+ AQDG_Object_Tree2_AddChild(parent, object);
+ return object;
+}
+
+
+
+GWENHYWFAR_CB void _freeData(void *bp, void *p)
+{
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=(AQDG_OBJECT_DRAWABLE*) p;
+ free(xo->text);
+ GWEN_FREE_OBJECT(xo);
+}
+
+
+
+int AQDG_DrawableObject_GetFontId(const AQDG_OBJECT *object)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ return xo?xo->fontId:0;
+ }
+ return 0;
+}
+
+
+
+void AQDG_DrawableObject_SetFontId(AQDG_OBJECT *object, int i)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ if (xo)
+ xo->fontId=i;
+ }
+}
+
+
+
+int AQDG_DrawableObject_GetForegroundPenId(const AQDG_OBJECT *object)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ return xo?xo->foregroundPenId:0;
+ }
+ return 0;
+}
+
+
+
+void AQDG_DrawableObject_SetForegroundPenId(AQDG_OBJECT *object, int i)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ if (xo)
+ xo->foregroundPenId=i;
+ }
+}
+
+
+
+int AQDG_DrawableObject_GetBackgroundPenId(const AQDG_OBJECT *object)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ return xo?xo->backgroundPenId:0;
+ }
+ return 0;
+}
+
+
+
+void AQDG_DrawableObject_SetBackgroundPenId(AQDG_OBJECT *object, int i)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ if (xo)
+ xo->backgroundPenId=i;
+ }
+}
+
+
+
+const char *AQDG_DrawableObject_GetText(const AQDG_OBJECT *object)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ return xo?xo->text:NULL;
+ }
+ return NULL;
+}
+
+
+
+void AQDG_DrawableObject_SetText(AQDG_OBJECT *object, const char *s)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ if (xo) {
+ free(xo->text);
+ xo->text=s?strdup(s):NULL;
+ }
+ }
+}
+
+
+
+AQDG_OBJECT_DRAWABLE_DRAW_FN AQDG_DrawableObject_SetDrawFn(AQDG_OBJECT *object, AQDG_OBJECT_DRAWABLE_DRAW_FN fn)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ if (xo) {
+ AQDG_OBJECT_DRAWABLE_DRAW_FN oldFn;
+
+ oldFn=xo->drawFn;
+ xo->drawFn=fn;
+ return oldFn;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+int AQDG_DrawableObject_Draw(AQDG_OBJECT *object, AQDG_DRAW_CONTEXT *g)
+{
+ if (object) {
+ AQDG_OBJECT_DRAWABLE *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_OBJECT_DRAWABLE, object);
+ if (xo) {
+ if (xo->drawFn)
+ return xo->drawFn(object, g);
+ else {
+ AQDG_OBJECT *child;
+
+ AQDG_Draw_Context_DrawFilledRect(g,
+ xo->backgroundPenId,
+ AQDG_Object_GetAbsoluteX(object),
+ AQDG_Object_GetAbsoluteY(object),
+ AQDG_Object_GetWidth(object),
+ AQDG_Object_GetHeight(object));
+ child=AQDG_Object_Tree2_GetFirstChild(object);
+ while(child) {
+ AQDG_DrawableObject_Draw(child, g);
+ child=AQDG_Object_Tree2_GetNext(child);
+ }
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/aqdiagram/draw/o_drawable.h b/src/lib/aqdiagram/draw/o_drawable.h
new file mode 100644
index 0000000..0754111
--- /dev/null
+++ b/src/lib/aqdiagram/draw/o_drawable.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQDG_DRAW_O_DRAWABLE_H
+#define AQDG_DRAW_O_DRAWABLE_H
+
+#include
+
+#include
+#include
+
+
+typedef int (*AQDG_OBJECT_DRAWABLE_DRAW_FN)(AQDG_OBJECT *object, AQDG_DRAW_CONTEXT *g);
+
+
+
+AQDG_API AQDG_OBJECT *AQDG_DrawableObject_new(AQDG_OBJECT *parent, uint32_t options);
+
+AQDG_API int AQDG_DrawableObject_GetFontId(const AQDG_OBJECT *object);
+AQDG_API void AQDG_DrawableObject_SetFontId(AQDG_OBJECT *object, int i);
+
+AQDG_API int AQDG_DrawableObject_GetForegroundPenId(const AQDG_OBJECT *object);
+AQDG_API void AQDG_DrawableObject_SetForegroundPenId(AQDG_OBJECT *object, int i);
+
+AQDG_API int AQDG_DrawableObject_GetBackgroundPenId(const AQDG_OBJECT *object);
+AQDG_API void AQDG_DrawableObject_SetBackgroundPenId(AQDG_OBJECT *object, int i);
+
+AQDG_API const char *AQDG_DrawableObject_GetText(const AQDG_OBJECT *object);
+AQDG_API void AQDG_DrawableObject_SetText(AQDG_OBJECT *object, const char *s);
+
+
+AQDG_API AQDG_OBJECT_DRAWABLE_DRAW_FN AQDG_DrawableObject_SetDrawFn(AQDG_OBJECT *object, AQDG_OBJECT_DRAWABLE_DRAW_FN fn);
+
+AQDG_API int AQDG_DrawableObject_Draw(AQDG_OBJECT *object, AQDG_DRAW_CONTEXT *g);
+
+
+#endif
+
diff --git a/src/lib/aqdiagram/draw/o_drawable_p.h b/src/lib/aqdiagram/draw/o_drawable_p.h
new file mode 100644
index 0000000..677ceb6
--- /dev/null
+++ b/src/lib/aqdiagram/draw/o_drawable_p.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQDG_DRAW_O_DRAWABLE_P_H
+#define AQDG_DRAW_O_DRAWABLE_P_H
+
+#include
+
+
+typedef struct AQDG_OBJECT_DRAWABLE AQDG_OBJECT_DRAWABLE;
+struct AQDG_OBJECT_DRAWABLE {
+ int fontId;
+ int foregroundPenId;
+ int backgroundPenId;
+
+ char *text;
+
+ AQDG_OBJECT_DRAWABLE_DRAW_FN drawFn;
+};
+
+
+
+#endif
+