summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/gui/panels
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-12-14 16:38:10 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-12-14 16:38:10 (GMT)
commit97fa09113c7988e4b4639190ba9bc51f9ced4d33 (patch)
tree1b4fe85843b4cdbf685e5116a96c4f387a865561 /plugins/pychrysalide/gui/panels
parente526727b94444030a3ae4dc6d4431cb72aea31e0 (diff)
Extended the Python API to build custom GUI panels.
Diffstat (limited to 'plugins/pychrysalide/gui/panels')
-rw-r--r--plugins/pychrysalide/gui/panels/panel.c213
-rw-r--r--plugins/pychrysalide/gui/panels/panel.h3
2 files changed, 201 insertions, 15 deletions
diff --git a/plugins/pychrysalide/gui/panels/panel.c b/plugins/pychrysalide/gui/panels/panel.c
index 37b682f..1df0670 100644
--- a/plugins/pychrysalide/gui/panels/panel.c
+++ b/plugins/pychrysalide/gui/panels/panel.c
@@ -28,21 +28,37 @@
#include <pygobject.h>
+#include <i18n.h>
#include <core/params.h>
#include <gui/core/panels.h>
-#include <gui/panels/panel.h>
+#include <gui/panels/panel-int.h>
#include "../editem.h"
#include "../../access.h"
+#include "../../dt.h"
#include "../../helpers.h"
#include "../../gtkext/dockable.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_panel_item_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise la classe des panneaux pour l'interface graphique. */
+static void py_panel_item_init_gclass(GPanelItemClass *, gpointer);
+
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds);
+
+
+/* -------------------------- FONCTIONNALITES D'UN PANNEAU -------------------------- */
+
+
/* Place un panneau dans l'ensemble affiché. */
static PyObject *py_panel_item_dock(PyObject *, PyObject *);
@@ -51,6 +67,102 @@ static bool py_panel_item_define_constants(PyTypeObject *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type du nouvel objet à mettre en place. *
+* args = éventuelle liste d'arguments. *
+* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* *
+* Description : Accompagne la création d'une instance dérivée en Python. *
+* *
+* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Objet à retourner */
+ bool abstract; /* Validation du type parent */
+ GType gtype; /* Nouveau type de processeur */
+ PyObject *sys_mod_dict; /* Dictionnaire des modules */
+ PyObject *modname; /* Nom du module du type */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire dudit module */
+
+ /* Validations diverses */
+
+ abstract = (type == get_python_panel_item_type());
+
+ if (abstract)
+ {
+ result = NULL;
+ PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
+ goto exit;
+ }
+
+ /* Mise en place d'un type dédié */
+
+ gtype = built_dynamic_type(G_TYPE_PANEL_ITEM, type->tp_name,
+ (GClassInitFunc)py_panel_item_init_gclass);
+
+ /* Enregistrement du nouveau GType dans Python */
+
+ sys_mod_dict = PyImport_GetModuleDict();
+
+ modname = PyDict_GetItemString(type->tp_dict, "__module__");
+
+ module = PyObject_GetItem(sys_mod_dict, modname);
+
+ dict = PyModule_GetDict(module);
+
+ if (!_register_class_for_pygobject(dict, gtype, type,
+ &PyGObject_Type, get_python_panel_item_type(), NULL))
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ Py_DECREF(module);
+ Py_DECREF(modname);
+
+ /* On créé, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe à initialiser. *
+* unused = données non utilisées ici. *
+* *
+* Description : Initialise la classe des panneaux pour l'interface graphique.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_panel_item_init_gclass(GPanelItemClass *class, gpointer unused)
+{
+ py_editor_item_init_gclass(G_EDITOR_ITEM_CLASS(class), NULL);
+
+}
+
+
/******************************************************************************
* *
* Paramètres : self = objet à initialiser (théoriquement). *
@@ -74,16 +186,41 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
int startup; /* Recommandation au démarrage */
const char *path; /* Placement à l'affichage */
int ret; /* Bilan de lecture des args. */
- GPanelItem *item; /* Elément de l'éditeur */
+ PyObject *new_kwds; /* Nouveau dictionnaire épuré */
+ GPanelItem *panel; /* Panneau à manipuler */
+ GEditorItem *item; /* Version basique d'instance */
+
+ static char *kwlist[] = { "name", "widget", "personality", "lname", "dock", "path", NULL };
+
+ /* Récupération des paramètres */
- ret = PyArg_ParseTuple(args, "kssOps", &personality, &name, &lname, &widget, &startup, &path);
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "sOksps", kwlist,
+ &name, &widget, &personality, &lname, &startup, &path);
if (!ret) return -1;
- item = g_panel_item_new(personality, name, lname,
- GTK_WIDGET(pygobject_get(widget)), startup, path);
+ /* Initialisation d'un objet GLib */
- /* FIXME ? Est-ce à l'utilisateur de s'enregistrer ? */
- register_panel_item(item, get_main_configuration());
+ new_kwds = PyDict_New();
+
+ ret = PyGObject_Type.tp_init(self, args, new_kwds);
+
+ Py_DECREF(new_kwds);
+
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ panel = G_PANEL_ITEM(pygobject_get(self));
+
+ item = G_EDITOR_ITEM(panel);
+
+ item->name = strdup(name);;
+ item->widget = GTK_WIDGET(pygobject_get(widget));
+
+ panel->personality = personality;
+ panel->lname = strdup(lname);
+ panel->dock_at_startup = startup;
+ panel->path = strdup(path);
/**
* Si Python ne voit plus la variable représentant le panneau utilisée,
@@ -92,18 +229,17 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
* On sera donc en situation de Use-After-Free, dont les conséquences
* arrivent très vite.
*/
- g_object_ref(GTK_WIDGET(pygobject_get(widget)));
- Py_INCREF(self);
+ g_object_ref(G_OBJECT(item->widget));
- /* Enregistrement auprès de PyGObject */
+ return 0;
- ((PyGObject *)self)->obj = G_OBJECT(item);
+}
- pygobject_register_wrapper(self);
- return 0;
-}
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES D'UN PANNEAU */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -172,7 +308,9 @@ PyTypeObject *get_python_panel_item_type(void)
.tp_methods = py_panel_item_methods,
.tp_getset = py_panel_item_getseters,
- .tp_init = (initproc)py_panel_item_init
+
+ .tp_init = py_panel_item_init,
+ .tp_new = py_panel_item_new,
};
@@ -256,3 +394,48 @@ bool ensure_python_panel_item_is_registered(void)
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en panneau pour GUI. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_panel_item(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_panel_item_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to executable format");
+ break;
+
+ case 1:
+ *((GPanelItem **)dst) = G_PANEL_ITEM(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/gui/panels/panel.h b/plugins/pychrysalide/gui/panels/panel.h
index 7fb473b..907c650 100644
--- a/plugins/pychrysalide/gui/panels/panel.h
+++ b/plugins/pychrysalide/gui/panels/panel.h
@@ -37,6 +37,9 @@ PyTypeObject *get_python_panel_item_type(void);
/* Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. */
bool ensure_python_panel_item_is_registered(void);
+/* Tente de convertir en panneau pour GUI. */
+int convert_to_panel_item(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_GUI_PANELS_PANEL_H */