python: Removed old implementation

pull/1662/head
igo95862 3 years ago committed by Nick Black
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, &notcurses_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, &notcurses_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, &notcurses_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, &notcurses_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, &notcurses_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, &notcurses_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, &notcurses_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, &notcurses_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, &notcurses_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…
Cancel
Save