python: Removed old implementation
parent
d7ade1f4b8
commit
92f1b63988
@ -1,998 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
/*
|
|
||||||
Copyright 2020 igo95862
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
|
||||||
#include <Python.h>
|
|
||||||
#include <notcurses/notcurses.h>
|
|
||||||
#include <notcurses/direct.h>
|
|
||||||
#include "structmember.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
uint64_t ncchannels_ptr;
|
|
||||||
} NcChannelsObject;
|
|
||||||
|
|
||||||
static PyMethodDef NcChannels_methods[] = {
|
|
||||||
{NULL, NULL, 0, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject NcChannelsType = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "notcurses._notcurses._NcChannels",
|
|
||||||
.tp_doc = "Notcurses Channels",
|
|
||||||
.tp_basicsize = sizeof(NcChannelsObject),
|
|
||||||
.tp_itemsize = 0,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
|
||||||
.tp_new = PyType_GenericNew,
|
|
||||||
.tp_init = NULL,
|
|
||||||
.tp_methods = NcChannels_methods,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
struct ncplane *ncplane_ptr;
|
|
||||||
} NcPlaneObject;
|
|
||||||
|
|
||||||
static PyMethodDef NcPlane_methods[] = {
|
|
||||||
{NULL, NULL, 0, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject NcPlaneType = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "notcurses._notcurses._NcPlane",
|
|
||||||
.tp_doc = "Notcurses Plane",
|
|
||||||
.tp_basicsize = sizeof(NcPlaneObject),
|
|
||||||
.tp_itemsize = 0,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
|
||||||
.tp_new = PyType_GenericNew,
|
|
||||||
.tp_init = NULL,
|
|
||||||
.tp_methods = NcPlane_methods,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
struct notcurses_options options;
|
|
||||||
struct notcurses *notcurses_context_ptr;
|
|
||||||
} NotcursesContextObject;
|
|
||||||
|
|
||||||
static PyMethodDef NotcursesContext_methods[] = {
|
|
||||||
{NULL, NULL, 0, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject NotcursesContextType = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "notcurses._notcurses._NotcursesContext",
|
|
||||||
.tp_doc = "Notcurses Context",
|
|
||||||
.tp_basicsize = sizeof(NotcursesContextObject),
|
|
||||||
.tp_itemsize = 0,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
|
||||||
.tp_new = PyType_GenericNew,
|
|
||||||
.tp_methods = NotcursesContext_methods,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
struct ncdirect *ncdirect_ptr;
|
|
||||||
} NcDirectObject;
|
|
||||||
|
|
||||||
static PyMethodDef NcDirect_methods[] = {
|
|
||||||
{NULL, NULL, 0, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject NcDirectType = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "notcurses._notcurses._NcDirect",
|
|
||||||
.tp_doc = "Notcurses Direct",
|
|
||||||
.tp_basicsize = sizeof(NcDirectObject),
|
|
||||||
.tp_itemsize = 0,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
|
||||||
.tp_new = PyType_GenericNew,
|
|
||||||
.tp_methods = NcDirect_methods,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
long codepoint;
|
|
||||||
int y_pos;
|
|
||||||
int x_pos;
|
|
||||||
bool is_alt;
|
|
||||||
bool is_shift;
|
|
||||||
bool is_ctrl;
|
|
||||||
uint64_t seqnum;
|
|
||||||
} NcInputObject;
|
|
||||||
|
|
||||||
static PyMemberDef NcInput_members[] = {
|
|
||||||
{"codepoint", T_LONG, offsetof(NcInputObject, codepoint), READONLY, "Codepoint"},
|
|
||||||
{"y_pos", T_INT, offsetof(NcInputObject, y_pos), READONLY, "Y axis positions"},
|
|
||||||
{"x_pos", T_INT, offsetof(NcInputObject, x_pos), READONLY, "X axis positions"},
|
|
||||||
{"is_alt", T_BOOL, offsetof(NcInputObject, is_alt), READONLY, "Is alt pressed"},
|
|
||||||
{"is_shift", T_BOOL, offsetof(NcInputObject, is_shift), READONLY, "Is shift pressed"},
|
|
||||||
{"is_ctrl", T_BOOL, offsetof(NcInputObject, is_ctrl), READONLY, "Is ctrl pressed"},
|
|
||||||
{"seqnum", T_ULONGLONG, offsetof(NcInputObject, seqnum), READONLY, "Sequence number"},
|
|
||||||
{NULL}};
|
|
||||||
|
|
||||||
static PyMethodDef NcInput_methods[] = {
|
|
||||||
{NULL, NULL, 0, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject NcInputType = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "notcurses._notcurses._NcInput",
|
|
||||||
.tp_doc = "Notcurses Input",
|
|
||||||
.tp_basicsize = sizeof(NcInputObject),
|
|
||||||
.tp_itemsize = 0,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
|
||||||
.tp_new = PyType_GenericNew,
|
|
||||||
.tp_members = NcInput_members,
|
|
||||||
.tp_methods = NcInput_methods,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Functions
|
|
||||||
|
|
||||||
/* Prototype
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_ncdirect_init(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_init arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct ncdirect *ncdirect_ptr = ncdirect_init(NULL, NULL, 0);
|
|
||||||
if (ncdirect_ptr != NULL)
|
|
||||||
{
|
|
||||||
ncdirect_ref->ncdirect_ptr = ncdirect_ptr;
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse NcDirect_init arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
// NcDirect
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_init(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_init arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct ncdirect *ncdirect_ptr = ncdirect_init(NULL, NULL, 0);
|
|
||||||
if (ncdirect_ptr != NULL)
|
|
||||||
{
|
|
||||||
ncdirect_ref->ncdirect_ptr = ncdirect_ptr;
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcDirectObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_stop(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_init arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = ncdirect_stop(ncdirect_ref->ncdirect_ptr);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to stop NcDirectObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_putstr(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
const char *string = NULL;
|
|
||||||
const NcChannelsObject *channels_object = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!s|O",
|
|
||||||
&NcDirectType, &ncdirect_ref,
|
|
||||||
&string,
|
|
||||||
&channels_object))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_putstr arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
uint64_t channels = 0;
|
|
||||||
if (PyObject_IsInstance((PyObject *)channels_object, (PyObject *)&NcChannelsType))
|
|
||||||
{
|
|
||||||
channels = channels_object->ncchannels_ptr;
|
|
||||||
}
|
|
||||||
else if ((PyObject *)channels_object == (PyObject *)Py_None)
|
|
||||||
{
|
|
||||||
channels = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unknown _NcChannels type");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = ncdirect_putstr(ncdirect_ref->ncdirect_ptr, channels, string);
|
|
||||||
if (return_code >= 0)
|
|
||||||
{
|
|
||||||
return PyLong_FromLong(return_code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed put string on NcDirect");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_get_dim_x(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_get_dim_x arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (ncdirect_ref != NULL)
|
|
||||||
{
|
|
||||||
return PyLong_FromLong(ncdirect_dim_x(ncdirect_ref->ncdirect_ptr));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcDirectObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_get_dim_y(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_get_dim_y arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (ncdirect_ref != NULL)
|
|
||||||
{
|
|
||||||
return PyLong_FromLong(ncdirect_dim_y(ncdirect_ref->ncdirect_ptr));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcDirectObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_disable_cursor(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_disable_cursor arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (ncdirect_ref != NULL)
|
|
||||||
{
|
|
||||||
ncdirect_cursor_disable(ncdirect_ref->ncdirect_ptr);
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcDirectObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_direct_enable_cursor(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcDirectObject *ncdirect_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcDirectType, &ncdirect_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncdirect_enable_cursor arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (ncdirect_ref != NULL)
|
|
||||||
{
|
|
||||||
ncdirect_cursor_enable(ncdirect_ref->ncdirect_ptr);
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcDirectObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// NcChannels
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_channels_set_background_rgb(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcChannelsObject *nchannels_ref = NULL;
|
|
||||||
int red = 0;
|
|
||||||
int green = 0;
|
|
||||||
int blue = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!iii",
|
|
||||||
&NcChannelsType, &nchannels_ref,
|
|
||||||
&red, &green, &blue))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncchannels_set_background_rgb arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nchannels_ref == NULL)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcChannelsObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = channels_set_bg_rgb8(&(nchannels_ref->ncchannels_ptr), red, green, blue);
|
|
||||||
if (return_code != 0)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to set channel background colors");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_channels_set_foreground_rgb(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcChannelsObject *nchannels_ref = NULL;
|
|
||||||
int red = 0;
|
|
||||||
int green = 0;
|
|
||||||
int blue = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!iii",
|
|
||||||
&NcChannelsType, &nchannels_ref,
|
|
||||||
&red, &green, &blue))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _ncchannels_set_foreground_rgb arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nchannels_ref == NULL)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcChannelsObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = channels_set_fg_rgb8(&(nchannels_ref->ncchannels_ptr), red, green, blue);
|
|
||||||
if (return_code != 0)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to set channel foreground colors");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotcursesContext
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_init(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_init arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct notcurses *notcurses_context_ptr = notcurses_init(NULL, NULL);
|
|
||||||
if (notcurses_context_ptr != NULL)
|
|
||||||
{
|
|
||||||
notcurses_context_ref->notcurses_context_ptr = notcurses_context_ptr;
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed initialize Notcurses");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_stop(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_stop arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = notcurses_stop(notcurses_context_ref->notcurses_context_ptr);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to stop notcurses context");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_render(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_render arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = notcurses_render(notcurses_context_ref->notcurses_context_ptr);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to render");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_mouse_disable(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_mouse_disable arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = notcurses_mouse_disable(notcurses_context_ref->notcurses_context_ptr);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to disable mouse");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_mouse_enable(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_mouse_enable arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = notcurses_mouse_enable(notcurses_context_ref->notcurses_context_ptr);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to enable mouse");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_cursor_disable(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_cursor_disable arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = notcurses_cursor_disable(notcurses_context_ref->notcurses_context_ptr);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to disable cursor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_notcurses_context_cursor_enable(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
int y = 0;
|
|
||||||
int x = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!|ii", &NotcursesContextType, ¬curses_context_ref,
|
|
||||||
&y, &x))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_cursor_enable arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int return_code = notcurses_cursor_enable(notcurses_context_ref->notcurses_context_ptr, y, x);
|
|
||||||
if (return_code == 0)
|
|
||||||
{
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to enable cursor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NcPlaneObject *
|
|
||||||
_notcurses_context_get_std_plane(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_cursor_enable arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct ncplane *std_plane = notcurses_stdplane(notcurses_context_ref->notcurses_context_ptr);
|
|
||||||
NcPlaneObject *ncplane_ref = PyObject_NEW(NcPlaneObject, &NcPlaneType);
|
|
||||||
|
|
||||||
if (ncplane_ref != NULL && std_plane != NULL)
|
|
||||||
{
|
|
||||||
ncplane_ref->ncplane_ptr = std_plane;
|
|
||||||
return ncplane_ref;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to get std plane");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NcInputObject *
|
|
||||||
_notcurses_context_get_input_blocking(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NotcursesContextObject *notcurses_context_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NotcursesContextType, ¬curses_context_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _notcurses_context_get_input_blocking arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct ncinput nc_input_ptr = {0};
|
|
||||||
char32_t code_point = notcurses_getc_blocking(notcurses_context_ref->notcurses_context_ptr, &nc_input_ptr);
|
|
||||||
NcInputObject *nc_input_ref = PyObject_NEW(NcInputObject, &NcInputType);
|
|
||||||
PyObject_INIT(nc_input_ref, &NcInputType);
|
|
||||||
if (code_point != (char32_t)-1)
|
|
||||||
{
|
|
||||||
|
|
||||||
nc_input_ref->codepoint = (long)nc_input_ptr.id;
|
|
||||||
nc_input_ref->y_pos = nc_input_ptr.y;
|
|
||||||
nc_input_ref->x_pos = nc_input_ptr.x;
|
|
||||||
nc_input_ref->is_alt = nc_input_ptr.alt;
|
|
||||||
nc_input_ref->is_shift = nc_input_ptr.shift;
|
|
||||||
nc_input_ref->is_ctrl = nc_input_ptr.ctrl;
|
|
||||||
nc_input_ref->seqnum = nc_input_ptr.seqnum;
|
|
||||||
|
|
||||||
return nc_input_ref;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to get input");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NcPlane
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_set_background_rgb(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
int red = 0;
|
|
||||||
int green = 0;
|
|
||||||
int blue = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!iii",
|
|
||||||
&NcPlaneType, &nc_plane_ref,
|
|
||||||
&red, &green, &blue))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_set_background_rgb arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nc_plane_ref == NULL)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcPlaneObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = ncplane_set_bg_rgb8(nc_plane_ref->ncplane_ptr, red, green, blue);
|
|
||||||
if (return_code != 0)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to set plane background colors");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_set_foreground_rgb(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
int red = 0;
|
|
||||||
int green = 0;
|
|
||||||
int blue = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!iii",
|
|
||||||
&NcPlaneType, &nc_plane_ref,
|
|
||||||
&red, &green, &blue))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_set_foreground_rgb arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nc_plane_ref == NULL)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcPlaneObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = ncplane_set_fg_rgb8(nc_plane_ref->ncplane_ptr, red, green, blue);
|
|
||||||
if (return_code != 0)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to set plane foreground colors");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_putstr(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
int y_pos = -1;
|
|
||||||
int x_pos = -1;
|
|
||||||
const char *string = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!sii",
|
|
||||||
&NcPlaneType, &nc_plane_ref,
|
|
||||||
&string,
|
|
||||||
&y_pos, &x_pos))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_putstr arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nc_plane_ref == NULL)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcPlaneObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = ncplane_putstr_yx(nc_plane_ref->ncplane_ptr, y_pos, x_pos, string);
|
|
||||||
return PyLong_FromLong(return_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_putstr_aligned(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
int y_pos = -1;
|
|
||||||
ncalign_e align = NCALIGN_UNALIGNED;
|
|
||||||
const char *string = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!sii",
|
|
||||||
&NcPlaneType, &nc_plane_ref,
|
|
||||||
&string,
|
|
||||||
&y_pos, &align))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_putstr_aligned arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int return_code = ncplane_putstr_aligned(nc_plane_ref->ncplane_ptr, y_pos, align, string);
|
|
||||||
return PyLong_FromLong(return_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_dimensions_yx(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
int y_dim = 0;
|
|
||||||
int x_dim = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!",
|
|
||||||
&NcPlaneType, &nc_plane_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_set_foreground_rgb arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nc_plane_ref == NULL)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to acquire NcPlaneObject");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ncplane_dim_yx(nc_plane_ref->ncplane_ptr, &y_dim, &x_dim);
|
|
||||||
return PyTuple_Pack(2, PyLong_FromLong(y_dim), PyLong_FromLong(x_dim));
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_polyfill_yx(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
int y_dim = -1;
|
|
||||||
int x_dim = -1;
|
|
||||||
const char *cell_str = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!iis",
|
|
||||||
&NcPlaneType, &nc_plane_ref,
|
|
||||||
&y_dim, &x_dim,
|
|
||||||
&cell_str))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_polyfill_yx arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
cell cell_to_fill_with = CELL_CHAR_INITIALIZER(*cell_str);
|
|
||||||
int return_code = ncplane_polyfill_yx(nc_plane_ref->ncplane_ptr, y_dim, x_dim, &cell_to_fill_with);
|
|
||||||
if (return_code != -1)
|
|
||||||
{
|
|
||||||
return PyLong_FromLong((long)return_code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to polyfill");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_nc_plane_erase(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_ref = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!", &NcPlaneType, &nc_plane_ref))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_erase arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ncplane_erase(nc_plane_ref->ncplane_ptr);
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NcPlaneObject *
|
|
||||||
_nc_plane_create(PyObject *Py_UNUSED(self), PyObject *args)
|
|
||||||
{
|
|
||||||
NcPlaneObject *nc_plane_parent = NULL;
|
|
||||||
int y_pos, x_pos, rows_num, cols_num;
|
|
||||||
if (!PyArg_ParseTuple(args, "O!iiii",
|
|
||||||
&NcPlaneType, &nc_plane_parent,
|
|
||||||
&y_pos, &x_pos,
|
|
||||||
&rows_num, &cols_num))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to parse _nc_plane_create arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ncplane_options create_options = {
|
|
||||||
.y = y_pos,
|
|
||||||
.x = x_pos,
|
|
||||||
.rows = rows_num,
|
|
||||||
.cols = cols_num,
|
|
||||||
};
|
|
||||||
struct ncplane *new_nc_plane = ncplane_create(nc_plane_parent->ncplane_ptr, &create_options);
|
|
||||||
if (new_nc_plane != NULL)
|
|
||||||
{
|
|
||||||
NcPlaneObject *ncplane_ref = PyObject_NEW(NcPlaneObject, &NcPlaneType);
|
|
||||||
|
|
||||||
ncplane_ref->ncplane_ptr = new_nc_plane;
|
|
||||||
return ncplane_ref;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to create NcPlane");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
get_notcurses_version_str(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
|
|
||||||
{
|
|
||||||
const char *verstion_str = notcurses_version();
|
|
||||||
return PyUnicode_FromString(verstion_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy pasta
|
|
||||||
// {"_nc_direct_init", (PyCFunction)_ncdirect_init, METH_VARARGS, NULL},
|
|
||||||
static PyMethodDef NotcursesMethods[] = {
|
|
||||||
{"_nc_direct_init", (PyCFunction)_nc_direct_init, METH_VARARGS, NULL},
|
|
||||||
{"_nc_direct_stop", (PyCFunction)_nc_direct_stop, METH_VARARGS, NULL},
|
|
||||||
{"_nc_direct_putstr", (PyCFunction)_nc_direct_putstr, METH_VARARGS, NULL},
|
|
||||||
{"_nc_direct_get_dim_x", (PyCFunction)_nc_direct_get_dim_x, METH_VARARGS, NULL},
|
|
||||||
{"_nc_direct_get_dim_y", (PyCFunction)_nc_direct_get_dim_y, METH_VARARGS, NULL},
|
|
||||||
{"_nc_direct_disable_cursor", (PyCFunction)_nc_direct_disable_cursor, METH_VARARGS, NULL},
|
|
||||||
{"_nc_direct_enable_cursor", (PyCFunction)_nc_direct_enable_cursor, METH_VARARGS, NULL},
|
|
||||||
{"_nc_channels_set_background_rgb", (PyCFunction)_nc_channels_set_background_rgb, METH_VARARGS, NULL},
|
|
||||||
{"_nc_channels_set_foreground_rgb", (PyCFunction)_nc_channels_set_foreground_rgb, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_init", (PyCFunction)_notcurses_context_init, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_stop", (PyCFunction)_notcurses_context_stop, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_render", (PyCFunction)_notcurses_context_render, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_mouse_disable", (PyCFunction)_notcurses_context_mouse_disable, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_mouse_enable", (PyCFunction)_notcurses_context_mouse_enable, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_cursor_disable", (PyCFunction)_notcurses_context_cursor_disable, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_cursor_enable", (PyCFunction)_notcurses_context_cursor_enable, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_get_std_plane", (PyCFunction)_notcurses_context_get_std_plane, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_set_background_rgb", (PyCFunction)_nc_plane_set_background_rgb, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_set_foreground_rgb", (PyCFunction)_nc_plane_set_foreground_rgb, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_putstr", (PyCFunction)_nc_plane_putstr, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_putstr_aligned", (PyCFunction)_nc_plane_putstr_aligned, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_dimensions_yx", (PyCFunction)_nc_plane_dimensions_yx, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_polyfill_yx", (PyCFunction)_nc_plane_polyfill_yx, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_erase", (PyCFunction)_nc_plane_erase, METH_VARARGS, NULL},
|
|
||||||
{"_nc_plane_create", (PyCFunction)_nc_plane_create, METH_VARARGS, NULL},
|
|
||||||
{"_notcurses_context_get_input_blocking", (PyCFunction)_notcurses_context_get_input_blocking, METH_VARARGS, NULL},
|
|
||||||
{"get_notcurses_version", (PyCFunction)get_notcurses_version_str, METH_NOARGS, NULL},
|
|
||||||
{NULL, NULL, 0, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct PyModuleDef NotcursesModule = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
.m_name = "Notcurses", /* name of module */
|
|
||||||
.m_doc = "Notcurses.", /* module documentation, may be NULL */
|
|
||||||
.m_size = -1, /* size of per-interpreter state of the module,
|
|
||||||
or -1 if the module keeps state in global variables. */
|
|
||||||
NotcursesMethods,
|
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit__notcurses(void)
|
|
||||||
{
|
|
||||||
PyObject *py_module; // create the module
|
|
||||||
if (PyType_Ready(&NotcursesContextType) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyType_Ready(&NcPlaneType) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyType_Ready(&NcDirectType) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyType_Ready(&NcChannelsType) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyType_Ready(&NcInputType) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
py_module = PyModule_Create(&NotcursesModule);
|
|
||||||
if (py_module == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Py_INCREF(&NotcursesContextType);
|
|
||||||
if (PyModule_AddObject(py_module, "_NotcursesContext", (PyObject *)&NotcursesContextType) < 0)
|
|
||||||
{
|
|
||||||
Py_DECREF(&NotcursesContextType);
|
|
||||||
Py_DECREF(py_module);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(&NcPlaneType);
|
|
||||||
if (PyModule_AddObject(py_module, "_NcPlane", (PyObject *)&NcPlaneType) < 0)
|
|
||||||
{
|
|
||||||
Py_DECREF(&NcPlaneType);
|
|
||||||
Py_DECREF(py_module);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(&NcDirectType);
|
|
||||||
if (PyModule_AddObject(py_module, "_NcDirect", (PyObject *)&NcDirectType) < 0)
|
|
||||||
{
|
|
||||||
Py_DECREF(&NcDirectType);
|
|
||||||
Py_DECREF(py_module);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(&NcChannelsType);
|
|
||||||
if (PyModule_AddObject(py_module, "_NcChannels", (PyObject *)&NcChannelsType) < 0)
|
|
||||||
{
|
|
||||||
Py_DECREF(&NcChannelsType);
|
|
||||||
Py_DECREF(py_module);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(&NcInputType);
|
|
||||||
if (PyModule_AddObject(py_module, "_NcInput", (PyObject *)&NcInputType) < 0)
|
|
||||||
{
|
|
||||||
Py_DECREF(&NcInputType);
|
|
||||||
Py_DECREF(py_module);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constants PyModule_AddIntMacro(py_module, );
|
|
||||||
int constants_control_value = 0;
|
|
||||||
// Inputs
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_INVALID);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_RESIZE);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_UP);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_RIGHT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_DOWN);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_LEFT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_INS);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_DEL);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_BACKSPACE);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_PGDOWN);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_PGUP);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_HOME);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_END);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F00);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F01);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F02);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F03);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F04);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F05);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F06);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F07);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F08);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F09);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F10);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F11);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_F12);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_ENTER);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_CLS);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_DLEFT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_DRIGHT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_ULEFT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_URIGHT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_CENTER);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_BEGIN);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_CANCEL);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_CLOSE);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_COMMAND);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_COPY);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_EXIT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_PRINT);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_REFRESH);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_BUTTON1);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_BUTTON2);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_BUTTON3);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_SCROLL_UP);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_SCROLL_DOWN);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_BUTTON6);
|
|
||||||
constants_control_value |= PyModule_AddIntMacro(py_module, NCKEY_RELEASE);
|
|
||||||
// Nc Align
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCALIGN_UNALIGNED", NCALIGN_UNALIGNED);
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCALIGN_LEFT", NCALIGN_LEFT);
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCALIGN_CENTER", NCALIGN_CENTER);
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCALIGN_RIGHT", NCALIGN_RIGHT);
|
|
||||||
// Scale
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCSCALE_NONE", NCSCALE_NONE);
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCSCALE_SCALE", NCSCALE_SCALE);
|
|
||||||
constants_control_value |= PyModule_AddIntConstant(py_module, "NCSCALE_STRETCH", NCSCALE_STRETCH);
|
|
||||||
if (constants_control_value < 0)
|
|
||||||
{
|
|
||||||
Py_DECREF(py_module);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return py_module;
|
|
||||||
}
|
|
@ -1,255 +0,0 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
# Copyright 2020 igo95862
|
|
||||||
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import Optional, Tuple
|
|
||||||
|
|
||||||
|
|
||||||
class _NcChannels:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class _NcPlane:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class _NotcursesContext:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class _NcDirect:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class _NcInput:
|
|
||||||
@property
|
|
||||||
def codepoint(self) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
@property
|
|
||||||
def y_pos(self) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
@property
|
|
||||||
def x_pos(self) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_alt(self) -> bool:
|
|
||||||
...
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_shift(self) -> bool:
|
|
||||||
...
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_ctrl(self) -> bool:
|
|
||||||
...
|
|
||||||
|
|
||||||
@property
|
|
||||||
def seqnum(self) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_init(ncdirect: _NcDirect, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_stop(ncdirect: _NcDirect, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_putstr(nc_direct: _NcDirect,
|
|
||||||
string: str,
|
|
||||||
nc_channels: Optional[_NcChannels], /) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_get_dim_x(nc_direct: _NcDirect, /) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_get_dim_y(nc_direct: _NcDirect, /) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_disable_cursor(nc_direct: _NcDirect, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_direct_enable_cursor(nc_direct: _NcDirect, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_channels_set_background_rgb(
|
|
||||||
nc_channels: _NcChannels,
|
|
||||||
red: int, green: int, blue: int, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_channels_set_foreground_rgb(
|
|
||||||
nc_channels: _NcChannels,
|
|
||||||
red: int, green: int, blue: int, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_init(nc_context: _NotcursesContext, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_stop(nc_context: _NotcursesContext, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_render(nc_context: _NotcursesContext, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_mouse_disable(nc_context: _NotcursesContext, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_mouse_enable(nc_context: _NotcursesContext, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_cursor_disable(
|
|
||||||
nc_context: _NotcursesContext, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_cursor_enable(
|
|
||||||
nc_context: _NotcursesContext,
|
|
||||||
y_pos: int, x_pos: int, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_get_std_plane(
|
|
||||||
nc_context: _NotcursesContext, /) -> _NcPlane:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _notcurses_context_get_input_blocking(
|
|
||||||
nc_context: _NotcursesContext, /) -> _NcInput:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_set_background_rgb(
|
|
||||||
nc_plane: _NcPlane,
|
|
||||||
red: int, green: int, blue: int, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_set_foreground_rgb(
|
|
||||||
nc_plane: _NcPlane,
|
|
||||||
red: int, green: int, blue: int, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_putstr(
|
|
||||||
nc_plane: _NcPlane, string: str,
|
|
||||||
y_pos: int, x_pos: int, /) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_putstr_aligned(
|
|
||||||
nc_plane: _NcPlane, string: str,
|
|
||||||
y_pos: int, align: int, /) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_dimensions_yx(nc_plane: _NcPlane, /) -> Tuple[int, int]:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_polyfill_yx(
|
|
||||||
nc_plane: _NcPlane,
|
|
||||||
y_pos: int, x_pos: int, cell_str: str, /) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_erase(nc_plane: _NcPlane, /) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def _nc_plane_create(
|
|
||||||
nc_plane: _NcPlane,
|
|
||||||
y_pos: int, x_pos: int,
|
|
||||||
rows_num: int, cols_num: int, /) -> _NcPlane:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def get_notcurses_version() -> str:
|
|
||||||
"""Returns notcurses version from library"""
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Assign 0 to make this stub file importable
|
|
||||||
NCKEY_INVALID: int = 0
|
|
||||||
NCKEY_UP: int = 0
|
|
||||||
NCKEY_RESIZE: int = 0
|
|
||||||
NCKEY_RIGHT: int = 0
|
|
||||||
NCKEY_DOWN: int = 0
|
|
||||||
NCKEY_LEFT: int = 0
|
|
||||||
NCKEY_INS: int = 0
|
|
||||||
NCKEY_DEL: int = 0
|
|
||||||
NCKEY_BACKSPACE: int = 0
|
|
||||||
NCKEY_PGDOWN: int = 0
|
|
||||||
NCKEY_PGUP: int = 0
|
|
||||||
NCKEY_HOME: int = 0
|
|
||||||
NCKEY_END: int = 0
|
|
||||||
NCKEY_F00: int = 0
|
|
||||||
NCKEY_F01: int = 0
|
|
||||||
NCKEY_F02: int = 0
|
|
||||||
NCKEY_F03: int = 0
|
|
||||||
NCKEY_F04: int = 0
|
|
||||||
NCKEY_F05: int = 0
|
|
||||||
NCKEY_F06: int = 0
|
|
||||||
NCKEY_F07: int = 0
|
|
||||||
NCKEY_F08: int = 0
|
|
||||||
NCKEY_F09: int = 0
|
|
||||||
NCKEY_F10: int = 0
|
|
||||||
NCKEY_F11: int = 0
|
|
||||||
NCKEY_F12: int = 0
|
|
||||||
NCKEY_ENTER: int = 0
|
|
||||||
NCKEY_CLS: int = 0
|
|
||||||
NCKEY_DLEFT: int = 0
|
|
||||||
NCKEY_DRIGHT: int = 0
|
|
||||||
NCKEY_ULEFT: int = 0
|
|
||||||
NCKEY_URIGHT: int = 0
|
|
||||||
NCKEY_CENTER: int = 0
|
|
||||||
NCKEY_BEGIN: int = 0
|
|
||||||
NCKEY_CANCEL: int = 0
|
|
||||||
NCKEY_CLOSE: int = 0
|
|
||||||
NCKEY_COMMAND: int = 0
|
|
||||||
NCKEY_COPY: int = 0
|
|
||||||
NCKEY_EXIT: int = 0
|
|
||||||
NCKEY_PRINT: int = 0
|
|
||||||
NCKEY_REFRESH: int = 0
|
|
||||||
NCKEY_BUTTON1: int = 0
|
|
||||||
NCKEY_BUTTON2: int = 0
|
|
||||||
NCKEY_BUTTON3: int = 0
|
|
||||||
NCKEY_SCROLL_UP: int = 0
|
|
||||||
NCKEY_SCROLL_DOWN: int = 0
|
|
||||||
NCKEY_BUTTON6: int = 0
|
|
||||||
NCKEY_RELEASE: int = 0
|
|
||||||
NCALIGN_UNALIGNED: int = 0
|
|
||||||
NCALIGN_LEFT: int = 0
|
|
||||||
NCALIGN_CENTER: int = 0
|
|
||||||
NCALIGN_RIGHT: int = 0
|
|
||||||
NCSCALE_NONE: int = 0
|
|
||||||
NCSCALE_SCALE: int = 0
|
|
||||||
NCSCALE_STRETCH: int = 0
|
|
@ -1,634 +0,0 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
# Copyright 2020 igo95862
|
|
||||||
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
"""
|
|
||||||
Notcurses python module
|
|
||||||
"""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from enum import IntEnum
|
|
||||||
from typing import Dict, Iterable, Optional, Tuple, Union
|
|
||||||
|
|
||||||
from . import _notcurses
|
|
||||||
from ._notcurses import (_nc_channels_set_background_rgb,
|
|
||||||
_nc_channels_set_foreground_rgb,
|
|
||||||
_nc_direct_disable_cursor, _nc_direct_enable_cursor,
|
|
||||||
_nc_direct_get_dim_x, _nc_direct_get_dim_y,
|
|
||||||
_nc_direct_init, _nc_direct_putstr, _nc_direct_stop,
|
|
||||||
_nc_plane_create, _nc_plane_dimensions_yx,
|
|
||||||
_nc_plane_erase, _nc_plane_putstr,
|
|
||||||
_nc_plane_putstr_aligned,
|
|
||||||
_nc_plane_set_background_rgb,
|
|
||||||
_nc_plane_set_foreground_rgb, _NcChannels, _NcDirect,
|
|
||||||
_NcInput, _NcPlane, _notcurses_context_cursor_disable,
|
|
||||||
_notcurses_context_cursor_enable,
|
|
||||||
_notcurses_context_get_input_blocking,
|
|
||||||
_notcurses_context_get_std_plane,
|
|
||||||
_notcurses_context_init,
|
|
||||||
_notcurses_context_mouse_disable,
|
|
||||||
_notcurses_context_mouse_enable,
|
|
||||||
_notcurses_context_render, _notcurses_context_stop,
|
|
||||||
_NotcursesContext)
|
|
||||||
|
|
||||||
|
|
||||||
class NcAlign(IntEnum):
|
|
||||||
"""
|
|
||||||
Enum containing alignment types
|
|
||||||
|
|
||||||
:cvar UNALIGNED: No alignment
|
|
||||||
:cvar LEFT: Left alignment
|
|
||||||
:cvar CENTER: Center alignment
|
|
||||||
:cvar RIGHT: Right alignment
|
|
||||||
"""
|
|
||||||
UNALIGNED = _notcurses.NCALIGN_UNALIGNED
|
|
||||||
LEFT = _notcurses.NCALIGN_LEFT
|
|
||||||
CENTER = _notcurses.NCALIGN_CENTER
|
|
||||||
RIGHT = _notcurses.NCALIGN_RIGHT
|
|
||||||
|
|
||||||
|
|
||||||
class NotcursesContext:
|
|
||||||
"""
|
|
||||||
Notcurses Context
|
|
||||||
|
|
||||||
This class controls the attached terminal and should only be
|
|
||||||
initialized once per terminal.
|
|
||||||
|
|
||||||
Using :py:func:`get_std_plane` is recommended in most cases instead
|
|
||||||
of directly initializing the context.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
start_immediately: bool = True):
|
|
||||||
"""
|
|
||||||
Create the context
|
|
||||||
|
|
||||||
:param bool start_immediately: Whether or not to acquire the terminal
|
|
||||||
"""
|
|
||||||
self._nc_context = _NotcursesContext()
|
|
||||||
self._has_started = False
|
|
||||||
if start_immediately:
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
def render(self) -> None:
|
|
||||||
"""
|
|
||||||
Updates the terminal window with the actual content
|
|
||||||
This should be called after the you have filled the
|
|
||||||
plane with such function as :py:meth:`NcPlane.put_lines`
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
This method is not thread safe.
|
|
||||||
"""
|
|
||||||
_notcurses_context_render(self._nc_context)
|
|
||||||
|
|
||||||
def start(self) -> None:
|
|
||||||
"""Notcurses acquires the terminal."""
|
|
||||||
_notcurses_context_init(self._nc_context)
|
|
||||||
self._has_started = True
|
|
||||||
|
|
||||||
def stop(self) -> None:
|
|
||||||
"""
|
|
||||||
Notcurses releases the terminal.
|
|
||||||
|
|
||||||
This will be automatically called with the context object
|
|
||||||
gets garbage collected.
|
|
||||||
"""
|
|
||||||
_notcurses_context_stop(self._nc_context)
|
|
||||||
self._has_started = False
|
|
||||||
|
|
||||||
def get_input_blocking(self) -> NcInput:
|
|
||||||
"""
|
|
||||||
Waits synchronously for an :py:class:`NcInput` event.
|
|
||||||
"""
|
|
||||||
return NcInput(
|
|
||||||
_notcurses_context_get_input_blocking(self._nc_context)
|
|
||||||
)
|
|
||||||
|
|
||||||
def enable_mouse(self) -> None:
|
|
||||||
"""Enables mouse on the terminal"""
|
|
||||||
_notcurses_context_mouse_enable(self._nc_context)
|
|
||||||
|
|
||||||
def disable_mouse(self) -> None:
|
|
||||||
"""Disables mouse on the terminal"""
|
|
||||||
_notcurses_context_mouse_disable(self._nc_context)
|
|
||||||
|
|
||||||
def enable_cursor(self) -> None:
|
|
||||||
"""Enables cursor on the terminal"""
|
|
||||||
_notcurses_context_cursor_enable(self._nc_context, 0, 0)
|
|
||||||
|
|
||||||
def disable_cursor(self) -> None:
|
|
||||||
"""Disables cursor on the terminal"""
|
|
||||||
_notcurses_context_cursor_disable(self._nc_context)
|
|
||||||
|
|
||||||
def __del__(self) -> None:
|
|
||||||
if self._has_started:
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
|
|
||||||
class NcInput:
|
|
||||||
"""Represents an input event"""
|
|
||||||
|
|
||||||
def __init__(self, nc_input: _NcInput):
|
|
||||||
self._nc_input = nc_input
|
|
||||||
|
|
||||||
@property
|
|
||||||
def code(self) -> Union[str, NcInputCodes]:
|
|
||||||
"""
|
|
||||||
Either a single character or an enum of :py:class:`NcInputCodes`
|
|
||||||
|
|
||||||
For example, `q` represents a button Q on keyboard.
|
|
||||||
`NcInputCodes.MOUSE_LEFT_BUTTON` represents left mouse button click.
|
|
||||||
|
|
||||||
The keys references can be found in :py:class:`NcInputCodes`
|
|
||||||
|
|
||||||
:rtype: Union[str, NcInputCodes]
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return NC_INPUT_CODES[self._nc_input.codepoint]
|
|
||||||
except KeyError:
|
|
||||||
return chr(self._nc_input.codepoint)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def y_pos(self) -> int:
|
|
||||||
"""
|
|
||||||
Y position of event
|
|
||||||
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
return self._nc_input.y_pos
|
|
||||||
|
|
||||||
@property
|
|
||||||
def x_pos(self) -> int:
|
|
||||||
"""
|
|
||||||
X position of event
|
|
||||||
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
return self._nc_input.x_pos
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_alt(self) -> bool:
|
|
||||||
"""
|
|
||||||
Was Alt key pressed during event?
|
|
||||||
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return self._nc_input.is_alt
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_shift(self) -> bool:
|
|
||||||
"""
|
|
||||||
Was Shift key pressed during event?
|
|
||||||
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return self._nc_input.is_shift
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_ctrl(self) -> bool:
|
|
||||||
"""
|
|
||||||
Was Ctrl key pressed during event?
|
|
||||||
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return self._nc_input.is_ctrl
|
|
||||||
|
|
||||||
@property
|
|
||||||
def seqnum(self) -> int:
|
|
||||||
"""
|
|
||||||
Sequence number
|
|
||||||
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
return self._nc_input.seqnum
|
|
||||||
|
|
||||||
|
|
||||||
class NcPlane:
|
|
||||||
"""Class representing a drawing surface"""
|
|
||||||
|
|
||||||
def __init__(self, plane: _NcPlane, context: NotcursesContext) -> None:
|
|
||||||
"""
|
|
||||||
NcPlane should not be initialized directly by user.
|
|
||||||
Use :py:meth:`NcPlane.create_sub_plane` to create sub planes from the
|
|
||||||
standard plane
|
|
||||||
"""
|
|
||||||
self._nc_plane = plane
|
|
||||||
self.context = context
|
|
||||||
|
|
||||||
@property
|
|
||||||
def dimensions_yx(self) -> Tuple[int, int]:
|
|
||||||
"""
|
|
||||||
Returns Y and X dimensions of the plane
|
|
||||||
|
|
||||||
:rtype: Tuple[int, int]
|
|
||||||
"""
|
|
||||||
return _nc_plane_dimensions_yx(self._nc_plane)
|
|
||||||
|
|
||||||
def putstr(
|
|
||||||
self,
|
|
||||||
string: str,
|
|
||||||
y_pos: int = -1, x_pos: int = -1) -> int:
|
|
||||||
"""
|
|
||||||
Puts a string on the plane
|
|
||||||
|
|
||||||
:param str string: String to put
|
|
||||||
:param int y_pos: Y position to put string.
|
|
||||||
By default is the cursor position.
|
|
||||||
:param int x_pos: X position to put string.
|
|
||||||
By default is the cursor position.
|
|
||||||
:returns: Number of characters written.
|
|
||||||
Negative if some characters could not be written.
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
return _nc_plane_putstr(
|
|
||||||
self._nc_plane,
|
|
||||||
string,
|
|
||||||
y_pos,
|
|
||||||
x_pos,
|
|
||||||
)
|
|
||||||
|
|
||||||
def putstr_aligned(self,
|
|
||||||
string: str,
|
|
||||||
y_pos: int = -1,
|
|
||||||
align: NcAlign = NcAlign.UNALIGNED) -> int:
|
|
||||||
"""
|
|
||||||
Puts a string on the plane with specified alignment
|
|
||||||
instead of X coordinate
|
|
||||||
|
|
||||||
:param str string: String to put
|
|
||||||
:param int y_pos: Y position to put string.
|
|
||||||
By default is the cursor position.
|
|
||||||
:param NcAlign align: Use specific alignment.
|
|
||||||
:returns: Number of characters written.
|
|
||||||
Negative if some characters could not be written.
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
return _nc_plane_putstr_aligned(
|
|
||||||
self._nc_plane,
|
|
||||||
string,
|
|
||||||
y_pos,
|
|
||||||
align,
|
|
||||||
)
|
|
||||||
|
|
||||||
def put_lines(
|
|
||||||
self, lines_iter: Iterable[str], wrap_lines: bool = False
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Puts string from the iterator on the plane.
|
|
||||||
Each string is put on a new line.
|
|
||||||
|
|
||||||
:param iter[str] lines_iter: Iterator of lines to put on the plane
|
|
||||||
:param bool wrap_lines: If line is longer that the surface
|
|
||||||
should it be continued on the next line? Default false.
|
|
||||||
"""
|
|
||||||
y_pos = 0
|
|
||||||
|
|
||||||
for line in lines_iter:
|
|
||||||
# TODO: needs to stop if we are outside the plane
|
|
||||||
chars_put = self.putstr(line, y_pos, 0)
|
|
||||||
y_pos += 1
|
|
||||||
|
|
||||||
if not wrap_lines:
|
|
||||||
continue
|
|
||||||
|
|
||||||
while chars_put < 0:
|
|
||||||
line = line[abs(chars_put):]
|
|
||||||
chars_put = self.putstr(line, y_pos, 0)
|
|
||||||
y_pos += 1
|
|
||||||
|
|
||||||
def erase(self) -> None:
|
|
||||||
"""Remove all symbols from plane"""
|
|
||||||
return _nc_plane_erase(self._nc_plane)
|
|
||||||
|
|
||||||
def set_background_rgb(
|
|
||||||
self, red: int, green: int, blue: int) -> None:
|
|
||||||
"""
|
|
||||||
Sets the background color
|
|
||||||
|
|
||||||
:param int red: Red color component given as integer from 0 to 255
|
|
||||||
:param int green: Green color component given as integer from 0 to 255
|
|
||||||
:param int blue: Blue color component given as integer from 0 to 255
|
|
||||||
"""
|
|
||||||
_nc_plane_set_background_rgb(self._nc_plane, red, green, blue)
|
|
||||||
|
|
||||||
def set_foreground_rgb(
|
|
||||||
self, red: int, green: int, blue: int) -> None:
|
|
||||||
"""
|
|
||||||
Sets the foreground color
|
|
||||||
|
|
||||||
:param int red: Red color component given as integer from 0 to 255
|
|
||||||
:param int green: Green color component given as integer from 0 to 255
|
|
||||||
:param int blue: Blue color component given as integer from 0 to 255
|
|
||||||
"""
|
|
||||||
_nc_plane_set_foreground_rgb(self._nc_plane, red, green, blue)
|
|
||||||
|
|
||||||
def create_sub_plane(
|
|
||||||
self,
|
|
||||||
y_pos: int = 0,
|
|
||||||
x_pos: int = 0,
|
|
||||||
rows_num: Optional[int] = None,
|
|
||||||
cols_num: Optional[int] = None
|
|
||||||
) -> NcPlane:
|
|
||||||
"""
|
|
||||||
Creates a new plane within this plane
|
|
||||||
|
|
||||||
:param int y_pos: top left corner Y coordinate
|
|
||||||
relative to top left corner of parent
|
|
||||||
|
|
||||||
:param int x_pos: top left corner X coordinate
|
|
||||||
relative to top left corner of parent
|
|
||||||
|
|
||||||
:param int rows_num: Number of rows (i.e. Y size)
|
|
||||||
:param int cols_num: Number of columns (i.e. X size)
|
|
||||||
:returns: New plane
|
|
||||||
:rtype: NcPlane
|
|
||||||
"""
|
|
||||||
|
|
||||||
if cols_num is None:
|
|
||||||
y_dim, _ = self.dimensions_yx
|
|
||||||
cols_num = y_dim // 2
|
|
||||||
|
|
||||||
if rows_num is None:
|
|
||||||
_, x_dim = self.dimensions_yx
|
|
||||||
rows_num = x_dim
|
|
||||||
|
|
||||||
new_plane = _nc_plane_create(
|
|
||||||
self._nc_plane,
|
|
||||||
y_pos, x_pos, rows_num, cols_num
|
|
||||||
)
|
|
||||||
|
|
||||||
return NcPlane(new_plane, self.context)
|
|
||||||
|
|
||||||
|
|
||||||
_default_context: Optional[NotcursesContext] = None
|
|
||||||
|
|
||||||
|
|
||||||
def get_std_plane() -> NcPlane:
|
|
||||||
"""
|
|
||||||
Initializes context and returns the standard plane.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
The terminal will be acquired by notcurses and uncontrollable until
|
|
||||||
the standard plane will be dereferenced.
|
|
||||||
|
|
||||||
:return: Standard plane of the terminal
|
|
||||||
:rtype: NcPlane
|
|
||||||
"""
|
|
||||||
global _default_context
|
|
||||||
if _default_context is None:
|
|
||||||
_default_context = NotcursesContext()
|
|
||||||
|
|
||||||
std_plane_ref = _notcurses_context_get_std_plane(
|
|
||||||
_default_context._nc_context)
|
|
||||||
return NcPlane(std_plane_ref, _default_context)
|
|
||||||
|
|
||||||
|
|
||||||
class NcChannels:
|
|
||||||
"""
|
|
||||||
Class that hold the colors and transparency values
|
|
||||||
|
|
||||||
Can be used in some functions instead of directly specifying colors.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self._nc_channels = _NcChannels()
|
|
||||||
|
|
||||||
def set_background_rgb(self, red: int, green: int, blue: int) -> None:
|
|
||||||
"""
|
|
||||||
Sets the background color
|
|
||||||
|
|
||||||
:param int red: Red color component given as integer from 0 to 255
|
|
||||||
:param int green: Green color component given as integer from 0 to 255
|
|
||||||
:param int blue: Blue color component given as integer from 0 to 255
|
|
||||||
"""
|
|
||||||
_nc_channels_set_background_rgb(
|
|
||||||
self._nc_channels,
|
|
||||||
red, green, blue,
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_foreground_rgb(self, red: int, green: int, blue: int) -> None:
|
|
||||||
"""
|
|
||||||
Sets the foreground color
|
|
||||||
|
|
||||||
:param int red: Red color component given as integer from 0 to 255
|
|
||||||
:param int green: Green color component given as integer from 0 to 255
|
|
||||||
:param int blue: Blue color component given as integer from 0 to 255
|
|
||||||
"""
|
|
||||||
_nc_channels_set_foreground_rgb(
|
|
||||||
self._nc_channels,
|
|
||||||
red, green, blue,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class NcDirect:
|
|
||||||
"""
|
|
||||||
NcDirect is a subset of Notcurses.
|
|
||||||
It does not clear entire terminal but instead draws on to normal
|
|
||||||
terminal surface. That means the output is preserved after the application
|
|
||||||
has exited and can be scrolled back.
|
|
||||||
|
|
||||||
NcDirect has only one main plane.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
start_immediately: bool = True):
|
|
||||||
"""
|
|
||||||
Create the main direct plane.
|
|
||||||
|
|
||||||
:param bool start_immediately: Whether or not to start NcDirect on
|
|
||||||
initialization.
|
|
||||||
"""
|
|
||||||
self._nc_direct = _NcDirect()
|
|
||||||
self._is_cursor_enabled: Optional[bool] = None
|
|
||||||
self._has_started = False
|
|
||||||
if start_immediately:
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
def __del__(self) -> None:
|
|
||||||
if self._has_started:
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
def start(self) -> None:
|
|
||||||
"""
|
|
||||||
Start NcDirect.
|
|
||||||
"""
|
|
||||||
_nc_direct_init(self._nc_direct)
|
|
||||||
self._has_started = True
|
|
||||||
|
|
||||||
def stop(self) -> None:
|
|
||||||
"""
|
|
||||||
Stop NcDirect
|
|
||||||
|
|
||||||
Will be automatically called if NcDirect object gets garbage collected
|
|
||||||
"""
|
|
||||||
_nc_direct_stop(self._nc_direct)
|
|
||||||
|
|
||||||
def putstr(
|
|
||||||
self, string: str,
|
|
||||||
nc_channels: Optional[NcChannels] = None) -> int:
|
|
||||||
"""
|
|
||||||
Puts a string on the plane.
|
|
||||||
This will immediately take effect. There is not `render` function for
|
|
||||||
NcDirect.
|
|
||||||
|
|
||||||
:param Optional[NcChannels] nc_channels: The colors string will use
|
|
||||||
:returns: Number of characters written.
|
|
||||||
Negative if some characters could not be written.
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
|
|
||||||
return _nc_direct_putstr(
|
|
||||||
self._nc_direct,
|
|
||||||
string,
|
|
||||||
nc_channels._nc_channels
|
|
||||||
if nc_channels is not None else nc_channels,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def dimensions_yx(self) -> Tuple[int, int]:
|
|
||||||
"""
|
|
||||||
Returns Y and X dimensions of the plane
|
|
||||||
|
|
||||||
:rtype: Tuple[int, int]
|
|
||||||
"""
|
|
||||||
return (_nc_direct_get_dim_y(self._nc_direct),
|
|
||||||
_nc_direct_get_dim_x(self._nc_direct))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def cursor_enabled(self) -> Optional[bool]:
|
|
||||||
"""
|
|
||||||
Is the cursor enabled?
|
|
||||||
|
|
||||||
Assign boolean to enable or disable cursor.
|
|
||||||
|
|
||||||
:type: bool
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return self._is_cursor_enabled
|
|
||||||
|
|
||||||
@cursor_enabled.setter
|
|
||||||
def cursor_enabled(self, set_to_what: Optional[bool]) -> None:
|
|
||||||
self._is_cursor_enabled = set_to_what
|
|
||||||
if set_to_what:
|
|
||||||
_nc_direct_enable_cursor(self._nc_direct)
|
|
||||||
else:
|
|
||||||
_nc_direct_disable_cursor(self._nc_direct)
|
|
||||||
|
|
||||||
|
|
||||||
class NcInputCodes(IntEnum):
|
|
||||||
"""
|
|
||||||
Enum containing special keys mapping
|
|
||||||
|
|
||||||
:cvar INVALID:
|
|
||||||
:cvar UP:
|
|
||||||
:cvar RESIZE:
|
|
||||||
:cvar RIGHT:
|
|
||||||
:cvar DOWN:
|
|
||||||
:cvar LEFT:
|
|
||||||
:cvar INSERT:
|
|
||||||
:cvar DELETE:
|
|
||||||
:cvar BACKSPACE:
|
|
||||||
:cvar PAGE_DOWN:
|
|
||||||
:cvar PAGE_UP:
|
|
||||||
:cvar HOME:
|
|
||||||
:cvar EBD:
|
|
||||||
:cvar F0:
|
|
||||||
:cvar F1:
|
|
||||||
:cvar F2:
|
|
||||||
:cvar F3:
|
|
||||||
:cvar F4:
|
|
||||||
:cvar F5:
|
|
||||||
:cvar F6:
|
|
||||||
:cvar F7:
|
|
||||||
:cvar F8:
|
|
||||||
:cvar F9:
|
|
||||||
:cvar F10:
|
|
||||||
:cvar F11:
|
|
||||||
:cvar F12:
|
|
||||||
:cvar ENTER:
|
|
||||||
:cvar CAPS_LOCL:
|
|
||||||
:cvar DOWN_LEFT:
|
|
||||||
:cvar DOWN_RIGHT:
|
|
||||||
:cvar UP_LEFT:
|
|
||||||
:cvar UP_RIGHT:
|
|
||||||
:cvar CENTER:
|
|
||||||
:cvar BEGIN:
|
|
||||||
:cvar CANCEL:
|
|
||||||
:cvar CLOSE:
|
|
||||||
:cvar COMMAND:
|
|
||||||
:cvar COPY:
|
|
||||||
:cvar EXIT:
|
|
||||||
:cvar PRINT:
|
|
||||||
:cvar REFRESH:
|
|
||||||
:cvar MOUSE_LEFT_BUTTON:
|
|
||||||
:cvar MOUSE_MIDDLE_BUTTON:
|
|
||||||
:cvar MOUSE_RIGHT_BUTTON:
|
|
||||||
:cvar MOUSE_SCROLL_UP:
|
|
||||||
:cvar MOUSE_SCROLL_DOWN:
|
|
||||||
:cvar MOUSE_6:
|
|
||||||
:cvar MOUSE_RELEASE:
|
|
||||||
"""
|
|
||||||
INVALID = _notcurses.NCKEY_INVALID
|
|
||||||
UP = _notcurses.NCKEY_UP
|
|
||||||
RESIZE = _notcurses.NCKEY_RESIZE
|
|
||||||
RIGHT = _notcurses.NCKEY_RIGHT
|
|
||||||
DOWN = _notcurses.NCKEY_DOWN
|
|
||||||
LEFT = _notcurses.NCKEY_LEFT
|
|
||||||
INSERT = _notcurses.NCKEY_INS
|
|
||||||
DELETE = _notcurses.NCKEY_DEL
|
|
||||||
BACKSPACE = _notcurses.NCKEY_BACKSPACE
|
|
||||||
PAGE_DOWN = _notcurses.NCKEY_PGDOWN
|
|
||||||
PAGE_UP = _notcurses.NCKEY_PGUP
|
|
||||||
HOME = _notcurses.NCKEY_HOME
|
|
||||||
EBD = _notcurses.NCKEY_END
|
|
||||||
F0 = _notcurses.NCKEY_F00
|
|
||||||
F1 = _notcurses.NCKEY_F01
|
|
||||||
F2 = _notcurses.NCKEY_F02
|
|
||||||
F3 = _notcurses.NCKEY_F03
|
|
||||||
F4 = _notcurses.NCKEY_F04
|
|
||||||
F5 = _notcurses.NCKEY_F05
|
|
||||||
F6 = _notcurses.NCKEY_F06
|
|
||||||
F7 = _notcurses.NCKEY_F07
|
|
||||||
F8 = _notcurses.NCKEY_F08
|
|
||||||
F9 = _notcurses.NCKEY_F09
|
|
||||||
F10 = _notcurses.NCKEY_F10
|
|
||||||
F11 = _notcurses.NCKEY_F11
|
|
||||||
F12 = _notcurses.NCKEY_F12
|
|
||||||
ENTER = _notcurses.NCKEY_ENTER
|
|
||||||
CAPS_LOCL = _notcurses.NCKEY_CLS
|
|
||||||
DOWN_LEFT = _notcurses.NCKEY_DLEFT
|
|
||||||
DOWN_RIGHT = _notcurses.NCKEY_DRIGHT
|
|
||||||
UP_LEFT = _notcurses.NCKEY_ULEFT
|
|
||||||
UP_RIGHT = _notcurses.NCKEY_URIGHT
|
|
||||||
CENTER = _notcurses.NCKEY_CENTER
|
|
||||||
BEGIN = _notcurses.NCKEY_BEGIN
|
|
||||||
CANCEL = _notcurses.NCKEY_CANCEL
|
|
||||||
CLOSE = _notcurses.NCKEY_CLOSE
|
|
||||||
COMMAND = _notcurses.NCKEY_COMMAND
|
|
||||||
COPY = _notcurses.NCKEY_COPY
|
|
||||||
EXIT = _notcurses.NCKEY_EXIT
|
|
||||||
PRINT = _notcurses.NCKEY_PRINT
|
|
||||||
REFRESH = _notcurses.NCKEY_REFRESH
|
|
||||||
MOUSE_LEFT_BUTTON = _notcurses.NCKEY_BUTTON1
|
|
||||||
MOUSE_MIDDLE_BUTTON = _notcurses.NCKEY_BUTTON2
|
|
||||||
MOUSE_RIGHT_BUTTON = _notcurses.NCKEY_BUTTON3
|
|
||||||
MOUSE_SCROLL_UP = _notcurses.NCKEY_SCROLL_UP
|
|
||||||
MOUSE_SCROLL_DOWN = _notcurses.NCKEY_SCROLL_DOWN
|
|
||||||
MOUSE_6 = _notcurses.NCKEY_BUTTON6
|
|
||||||
MOUSE_RELEASE = _notcurses.NCKEY_RELEASE
|
|
||||||
|
|
||||||
|
|
||||||
NC_INPUT_CODES: Dict[int, NcInputCodes] = {
|
|
||||||
element.value: element for element in NcInputCodes
|
|
||||||
}
|
|
Loading…
Reference in New Issue