summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-07-14 13:06:20 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-07-14 13:06:20 (GMT)
commit6c751d40ab1b84a6979c143ed47702207edebed8 (patch)
treee789491530d641f89e574f8eacb4f0e66bd93a91 /plugins/pychrysalide/glibext
parentde82c8165e61e3c19be184dbc00f66bfc7479c76 (diff)
Updated the Python bindings for the loaded panel interface.
Diffstat (limited to 'plugins/pychrysalide/glibext')
-rw-r--r--plugins/pychrysalide/glibext/constants.c135
-rw-r--r--plugins/pychrysalide/glibext/constants.h14
-rw-r--r--plugins/pychrysalide/glibext/loadedpanel.c191
3 files changed, 277 insertions, 63 deletions
diff --git a/plugins/pychrysalide/glibext/constants.c b/plugins/pychrysalide/glibext/constants.c
index 47bd00d..a7938cb 100644
--- a/plugins/pychrysalide/glibext/constants.c
+++ b/plugins/pychrysalide/glibext/constants.c
@@ -25,9 +25,11 @@
#include "constants.h"
+#include <i18n.h>
#include <glibext/linesegment.h>
#include <glibext/gbinportion.h>
#include <glibext/gbufferline.h>
+#include <glibext/gloadedpanel.h>
#include "../helpers.h"
@@ -148,6 +150,105 @@ int convert_to_portion_access_rights(PyObject *arg, void *dst)
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
* *
+* Description : Définit les constantes relatives aux lignes de tampon. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_buffer_line_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", BLF_NONE);
+ if (result) result = add_const_to_group(values, "HAS_CODE", BLF_HAS_CODE);
+ if (result) result = add_const_to_group(values, "IS_LABEL", BLF_IS_LABEL);
+ if (result) result = add_const_to_group(values, "ENTRYPOINT", BLF_ENTRYPOINT);
+ if (result) result = add_const_to_group(values, "BOOKMARK", BLF_BOOKMARK);
+ if (result) result = add_const_to_group(values, "WIDTH_MANAGER", BLF_WIDTH_MANAGER);
+ if (result) result = add_const_to_group(values, "ALL", BLF_ALL);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, true, "BufferLineFlags", values,
+ "Optional flags linked to a rendering line.");
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 constante BufferLineFlags. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_buffer_line_flags(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur transcrite */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 BufferLineFlags");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if ((value & BLF_ALL) != value)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value for BufferLineFlags");
+ result = 0;
+ }
+
+ else
+ *((BufferLineFlags *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
* Description : Définit les constantes relatives aux segments de ligne. *
* *
* Retour : true en cas de succès de l'opération, false sinon. *
@@ -258,7 +359,7 @@ int convert_to_rendering_tag_type(PyObject *arg, void *dst)
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
* *
-* Description : Définit les constantes relatives aux lignes de tampon. *
+* Description : Définit les constantes relatives aux panneaux de chargement. *
* *
* Retour : true en cas de succès de l'opération, false sinon. *
* *
@@ -266,20 +367,17 @@ int convert_to_rendering_tag_type(PyObject *arg, void *dst)
* *
******************************************************************************/
-bool define_buffer_line_constants(PyTypeObject *type)
+bool define_loaded_panel_constants(PyTypeObject *type)
{
bool result; /* Bilan à retourner */
PyObject *values; /* Groupe de valeurs à établir */
values = PyDict_New();
- result = add_const_to_group(values, "NONE", BLF_NONE);
- if (result) result = add_const_to_group(values, "HAS_CODE", BLF_HAS_CODE);
- if (result) result = add_const_to_group(values, "IS_LABEL", BLF_IS_LABEL);
- if (result) result = add_const_to_group(values, "ENTRYPOINT", BLF_ENTRYPOINT);
- if (result) result = add_const_to_group(values, "BOOKMARK", BLF_BOOKMARK);
- if (result) result = add_const_to_group(values, "WIDTH_MANAGER", BLF_WIDTH_MANAGER);
- if (result) result = add_const_to_group(values, "ALL", BLF_ALL);
+ result = add_const_to_group(values, "RAW", SPT_RAW);
+ if (result) result = add_const_to_group(values, "TOP", SPT_TOP);
+ if (result) result = add_const_to_group(values, "CENTER", SPT_CENTER);
+ if (result) result = add_const_to_group(values, "BOTTOM", SPT_BOTTOM);
if (!result)
{
@@ -287,8 +385,8 @@ bool define_buffer_line_constants(PyTypeObject *type)
goto exit;
}
- result = attach_constants_group_to_type(type, true, "BufferLineFlags", values,
- "Optional flags linked to a rendering line.");
+ result = attach_constants_group_to_type(type, false, "ScrollPositionTweak", values,
+ "Details for adjusting the displayed position while scrolling.");
exit:
@@ -302,7 +400,7 @@ bool define_buffer_line_constants(PyTypeObject *type)
* 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 constante BufferLineFlags. *
+* Description : Tente de convertir en constante ScrollPositionTweak. *
* *
* Retour : Bilan de l'opération, voire indications supplémentaires. *
* *
@@ -310,10 +408,10 @@ bool define_buffer_line_constants(PyTypeObject *type)
* *
******************************************************************************/
-int convert_to_buffer_line_flags(PyObject *arg, void *dst)
+int convert_to_scroll_position_tweak(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- unsigned long value; /* Valeur transcrite */
+ unsigned long value; /* Valeur récupérée */
result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type);
@@ -325,20 +423,21 @@ int convert_to_buffer_line_flags(PyObject *arg, void *dst)
break;
case 0:
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to BufferLineFlags");
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to ScrollPositionTweak");
break;
case 1:
+
value = PyLong_AsUnsignedLong(arg);
- if ((value & BLF_ALL) != value)
+ if (!IS_VALID_STP(value))
{
- PyErr_SetString(PyExc_TypeError, "invalid value for BufferLineFlags");
result = 0;
+ PyErr_SetString(PyExc_ValueError, _("invalid position tweak"));
}
else
- *((BufferLineFlags *)dst) = value;
+ *((ScrollPositionTweak *)dst) = value;
break;
diff --git a/plugins/pychrysalide/glibext/constants.h b/plugins/pychrysalide/glibext/constants.h
index b815586..f509866 100644
--- a/plugins/pychrysalide/glibext/constants.h
+++ b/plugins/pychrysalide/glibext/constants.h
@@ -37,17 +37,23 @@ bool define_binary_portion_constants(PyTypeObject *);
/* Tente de convertir en constante PortionAccessRights. */
int convert_to_portion_access_rights(PyObject *, void *);
+/* Définit les constantes relatives aux lignes de tampon. */
+bool define_buffer_line_constants(PyTypeObject *);
+
+/* Tente de convertir en constante BufferLineFlags. */
+int convert_to_buffer_line_flags(PyObject *, void *);
+
/* Définit les constantes relatives aux segments de ligne. */
bool define_line_segment_constants(PyTypeObject *);
/* Tente de convertir en constante RenderingTagType. */
int convert_to_rendering_tag_type(PyObject *, void *);
-/* Définit les constantes relatives aux lignes de tampon. */
-bool define_buffer_line_constants(PyTypeObject *);
+/* Définit les constantes relatives aux panneaux de chargement. */
+bool define_loaded_panel_constants(PyTypeObject *);
-/* Tente de convertir en constante BufferLineFlags. */
-int convert_to_buffer_line_flags(PyObject *, void *);
+/* Tente de convertir en constante ScrollPositionTweak. */
+int convert_to_scroll_position_tweak(PyObject *, void *);
diff --git a/plugins/pychrysalide/glibext/loadedpanel.c b/plugins/pychrysalide/glibext/loadedpanel.c
index d6b743b..6e87cde 100644
--- a/plugins/pychrysalide/glibext/loadedpanel.c
+++ b/plugins/pychrysalide/glibext/loadedpanel.c
@@ -30,29 +30,46 @@
#include <i18n.h>
-#include <glibext/gloadedpanel.h>
+#include <glibext/gloadedpanel-int.h>
+#include "constants.h"
#include "linecursor.h"
#include "../access.h"
#include "../helpers.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_loaded_panel_interface_init(GLoadedPanelIface *, gpointer *);
+
+/* S'assure qu'un emplacement donné est visible à l'écran. */
+static void py_loaded_panel_scroll_to_cursor_wrapper(GLoadedPanel *, const GLineCursor *, ScrollPositionTweak, bool);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
/* S'assure qu'un emplacement donné est visible à l'écran. */
static PyObject *py_loaded_panel_scroll_to_cursor(PyObject *, PyObject *);
-/* Définit les constantes pour l'affichage des contenus chargés. */
-static bool py_loaded_panel_define_constants(PyTypeObject *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
/******************************************************************************
* *
-* Paramètres : self = classe représentant un tampon de code. *
-* args = arguments fournis à l'appel. *
+* Paramètres : iface = interface GLib à initialiser. *
+* unused = adresse non utilisée ici. *
* *
-* Description : S'assure qu'un emplacement donné est visible à l'écran. *
+* Description : Procède à l'initialisation de l'interface de génération. *
* *
* Retour : - *
* *
@@ -60,56 +77,143 @@ static bool py_loaded_panel_define_constants(PyTypeObject *);
* *
******************************************************************************/
-static PyObject *py_loaded_panel_scroll_to_cursor(PyObject *self, PyObject *args)
+static void py_loaded_panel_interface_init(GLoadedPanelIface *iface, gpointer *unused)
{
- GLineCursor *cursor; /* Emplacement à cibler */
- unsigned long tweak; /* Adapation à effectuer */
- int move; /* Déplacement à l'écran ? */
- int ret; /* Bilan de lecture des args. */
- GLoadedPanel *panel; /* Panneau à manipuler */
- ret = PyArg_ParseTuple(args, "O&kp", convert_to_line_cursor, &cursor, &tweak, &move);
- if (!ret) return NULL;
+#define LOADED_PANEL_DOC \
+ "LoadPanel defines an interface for all panels which can be included" \
+ " inside the main graphical window.\n" \
+ "\n" \
+ "A typical class declaration for a new implementation looks like:\n" \
+ "\n" \
+ " class NewImplem(GObject.Object, LoadedPanel():\n" \
+ " ...\n" \
+ "\n" \
+ "The following methods have to be defined for new implementations:\n" \
+ "* pychrysalide.glibext.LoadedPanel._scroll_to_cursor();\n"
+
+ iface->scroll = py_loaded_panel_scroll_to_cursor_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK à manipuler. *
+* cursor = emplacement à présenter à l'écran. *
+* tweak = adaptation finale à effectuer. *
+* move = doit-on déplacer le curseur à l'adresse indiquée ? *
+* *
+* Description : S'assure qu'un emplacement donné est visible à l'écran. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- if (!IS_VALID_STP(tweak))
+static void py_loaded_panel_scroll_to_cursor_wrapper(GLoadedPanel *panel, const GLineCursor *cursor, ScrollPositionTweak tweak, bool move)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *tweak_obj; /* Détails en versionPython */
+ PyObject *move_obj; /* Consigne de déplacement */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define LOADED_PANEL_SCROLL_TO_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _scroll_to_cursor, "$self, cursor, tweak, move, /", \
+ METH_VARARGS, \
+ "Abstract method used to ensure a given address is displayed in the view" \
+ " panel.\n" \
+ "\n" \
+ "The *cursor* argument is a pychrysalide.glibext.LineCursor location. The" \
+ " *tweak* parameter defines the final adjustment for new location and the" \
+ " *move* order is a boolean value which implies a scroll operation if" \
+ " requiered." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(panel));
+
+ if (has_python_method(pyobj, "_scroll_to_cursor"))
{
- PyErr_SetString(PyExc_ValueError, _("invalid position tweak"));
- return NULL;
- }
+ tweak_obj = cast_with_constants_group_from_type(get_python_loaded_panel_type(),
+ "ScrollPositionTweak", tweak);
- panel = G_LOADED_PANEL(pygobject_get(self));
+ move_obj = (move ? Py_True : Py_False);
+ Py_INCREF(move_obj);
- g_loaded_panel_scroll_to_cursor(panel, cursor, tweak, move);
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(cursor)));
+ PyTuple_SetItem(args, 1, tweak_obj);
+ PyTuple_SetItem(args, 2, move_obj);
- Py_RETURN_NONE;
+ pyret = run_python_method(pyobj, "_scroll_to_cursor", args);
+
+ Py_XDECREF(pyret);
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
}
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* Paramètres : self = classe représentant un tampon de code. *
+* args = arguments fournis à l'appel. *
* *
-* Description : Définit les constantes pour l'affichage des contenus chargés.*
+* Description : S'assure qu'un emplacement donné est visible à l'écran. *
* *
-* Retour : true en cas de succès de l'opération, false sinon. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool py_loaded_panel_define_constants(PyTypeObject *obj_type)
+static PyObject *py_loaded_panel_scroll_to_cursor(PyObject *self, PyObject *args)
{
- bool result; /* Bilan à retourner */
+ GLineCursor *cursor; /* Emplacement à cibler */
+ ScrollPositionTweak tweak; /* Adapation à effectuer */
+ int move; /* Déplacement à l'écran ? */
+ int ret; /* Bilan de lecture des args. */
+ GLoadedPanel *panel; /* Panneau à manipuler */
+
+#define LOADED_PANEL_SCROLL_TO_CURSOR_METHOD PYTHON_METHOD_DEF \
+( \
+ scroll_to_cursor, "$self, cursor, tweak, move, /", \
+ METH_VARARGS, py_loaded_panel, \
+ "Ensure a given address is displayed in the view panel.\n" \
+ "\n" \
+ "The *cursor* argument is a pychrysalide.glibext.LineCursor location. The" \
+ " *tweak* parameter defines the final adjustment for new location and the" \
+ " *move* order is a boolean value which implies a scroll operation if" \
+ " requiered." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&O&p", convert_to_line_cursor, &cursor,
+ convert_to_scroll_position_tweak, &tweak, &move);
+ if (!ret) return NULL;
- result = true;
+ panel = G_LOADED_PANEL(pygobject_get(self));
- result &= PyDict_AddULongMacro(obj_type, SPT_RAW);
- result &= PyDict_AddULongMacro(obj_type, SPT_TOP);
- result &= PyDict_AddULongMacro(obj_type, SPT_CENTER);
- result &= PyDict_AddULongMacro(obj_type, SPT_BOTTOM);
+ g_loaded_panel_scroll_to_cursor(panel, cursor, tweak, move);
- return result;
+ Py_RETURN_NONE;
}
@@ -129,11 +233,8 @@ static bool py_loaded_panel_define_constants(PyTypeObject *obj_type)
PyTypeObject *get_python_loaded_panel_type(void)
{
static PyMethodDef py_loaded_panel_methods[] = {
- {
- "scroll_to_cursor", py_loaded_panel_scroll_to_cursor,
- METH_VARARGS,
- "scroll_to_cursor($self, cursor, tweak, move, /)\n--\n\nEnsure a given address is displayed in the view panel."
- },
+ LOADED_PANEL_SCROLL_TO_CURSOR_WRAPPER,
+ LOADED_PANEL_SCROLL_TO_CURSOR_METHOD,
{ NULL }
};
@@ -146,11 +247,11 @@ PyTypeObject *get_python_loaded_panel_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "pychrysalide.glibext.LoadedPanel",
- //.tp_basicsize = sizeof(PyGObject),
+ .tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide loaded panel",
+ .tp_doc = LOADED_PANEL_DOC,
.tp_methods = py_loaded_panel_methods,
.tp_getset = py_loaded_panel_getseters,
@@ -180,6 +281,14 @@ bool ensure_python_loaded_panel_is_registered(void)
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
+ static GInterfaceInfo info = { /* Paramètres d'inscription */
+
+ .interface_init = (GInterfaceInitFunc)py_loaded_panel_interface_init,
+ .interface_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
type = get_python_loaded_panel_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -188,10 +297,10 @@ bool ensure_python_loaded_panel_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_LOADED_PANEL, type))
+ if (!register_interface_for_pygobject_2(dict, G_TYPE_LOADED_PANEL, type, &info))
return false;
- if (!py_loaded_panel_define_constants(type))
+ if (!define_loaded_panel_constants(type))
return false;
}