Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of pygame.(F)Rect.rel_center #3089

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions buildconfig/stubs/pygame/rect.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class _GenericRect(Collection[_N]):
@center.setter
def center(self, value: Coordinate) -> None: ...
@property
def rel_center(self) -> Tuple[_N, _N]: ...
@rel_center.setter
def rel_center(self, value: Point) -> None: ...
@property
def centerx(self) -> _N: ...
@centerx.setter
def centerx(self, value: float) -> None: ...
Expand Down
21 changes: 20 additions & 1 deletion docs/reST/ref/rect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
center, rel_center, centerx, centery
size, width, height
w,h

Expand Down Expand Up @@ -92,6 +92,25 @@
However, the subclass's ``__init__()`` method is not called,
and ``__new__()`` is assumed to take no arguments. So these methods should be
overridden if any extra attributes need to be copied.

.. versionadded:: 2.5.2
``rel_center`` added to Rect / FRect. This will return you a ``Point`` of
the center relative to the topleft of the Rect. Setting a ``Point`` to it will
modify the size of the rect to 2 times the ``Point`` used. Below you can find a
code example of how it should work :

.. code-block:: python

> my_rect = pygame.Rect(0, 0, 2, 2)
> my_rect.rel_center
> (1, 1)
> my_rect.rel_center = (128, 128)
> my_rect.rel_center, my_rect.size
> ((128, 128), (256, 256))

Beware of non integer relative centers ! Using a Rect instead of FRect will round down
the values of the returned ``Point``.


.. method:: copy

Expand Down
8 changes: 8 additions & 0 deletions src_c/rect.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ four_floats_from_obj(PyObject *obj, float *val1, float *val2, float *val3,
#define RectExport_setmidright pg_rect_setmidright
#define RectExport_getcenter pg_rect_getcenter
#define RectExport_setcenter pg_rect_setcenter
#define RectExport_getrelcenter pg_rect_getrelcenter
#define RectExport_setrelcenter pg_rect_setrelcenter
#define RectExport_getsize pg_rect_getsize
#define RectExport_setsize pg_rect_setsize
#define RectImport_primitiveType int
Expand Down Expand Up @@ -250,6 +252,8 @@ four_floats_from_obj(PyObject *obj, float *val1, float *val2, float *val3,
#define RectExport_setmidright pg_frect_setmidright
#define RectExport_getcenter pg_frect_getcenter
#define RectExport_setcenter pg_frect_setcenter
#define RectExport_getrelcenter pg_frect_getrelcenter
#define RectExport_setrelcenter pg_frect_setrelcenter
#define RectExport_getsize pg_frect_getsize
#define RectExport_setsize pg_frect_setsize
#define RectImport_primitiveType float
Expand Down Expand Up @@ -684,6 +688,8 @@ static PyGetSetDef pg_frect_getsets[] = {
{"size", (getter)pg_frect_getsize, (setter)pg_frect_setsize, NULL, NULL},
{"center", (getter)pg_frect_getcenter, (setter)pg_frect_setcenter, NULL,
NULL},
{"rel_center", (getter)pg_frect_getrelcenter,
(setter)pg_frect_setrelcenter, NULL, NULL},

{"__safe_for_unpickling__", (getter)pg_rect_getsafepickle, NULL, NULL,
NULL},
Expand Down Expand Up @@ -726,6 +732,8 @@ static PyGetSetDef pg_rect_getsets[] = {
{"size", (getter)pg_rect_getsize, (setter)pg_rect_setsize, NULL, NULL},
{"center", (getter)pg_rect_getcenter, (setter)pg_rect_setcenter, NULL,
NULL},
{"rel_center", (getter)pg_rect_getrelcenter, (setter)pg_rect_setrelcenter,
NULL, NULL},

{"__safe_for_unpickling__", (getter)pg_rect_getsafepickle, NULL, NULL,
NULL},
Expand Down
39 changes: 39 additions & 0 deletions src_c/rect_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@
#ifndef RectExport_setcenter
#error RectExport_setcenter needs to be defined
#endif
#ifndef RectExport_getrelcenter
#error RectExport_getrelcenter needs to be defined
#endif
#ifndef RectExport_setrelcenter
#error RectExport_setrelcenter needs to be defined
#endif
#ifndef RectExport_getsize
#error RectExport_getsize needs to be defined
#endif
Expand Down Expand Up @@ -604,6 +610,10 @@ RectExport_getcenter(RectObject *self, void *closure);
static int
RectExport_setcenter(RectObject *self, PyObject *value, void *closure);
static PyObject *
RectExport_getrelcenter(RectObject *self, void *closure);
static int
RectExport_setrelcenter(RectObject *self, PyObject *value, void *closure);
static PyObject *
RectExport_getsize(RectObject *self, void *closure);
static int
RectExport_setsize(RectObject *self, PyObject *value, void *closure);
Expand Down Expand Up @@ -2804,6 +2814,33 @@ RectExport_getcenter(RectObject *self, void *closure)
self->r.y + (self->r.h / 2));
}

/*center*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relcenter

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you brought up a point, should it be rel_center or relcenter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of hate it, but probably relcenter for consistency with the other pre-existing rect attributes.

static PyObject *
RectExport_getrelcenter(RectObject *self, void *closure)
{
return TupleFromTwoPrimitives(self->r.w / 2, self->r.h / 2);
}

static int
RectExport_setrelcenter(RectObject *self, PyObject *value, void *closure)
{
PrimitiveType val1, val2;

if (NULL == value) {
/* Attribute deletion not supported. */
PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
return -1;
}

if (!twoPrimitivesFromObj(value, &val1, &val2)) {
PyErr_SetString(PyExc_TypeError, "invalid rect assignment");
return -1;
}
self->r.w = val1 * 2;
self->r.h = val2 * 2;
return 0;
}

static int
RectExport_setcenter(RectObject *self, PyObject *value, void *closure)
{
Expand Down Expand Up @@ -2958,6 +2995,8 @@ RectExport_iterator(RectObject *self)
#undef RectExport_setmidright
#undef RectExport_getcenter
#undef RectExport_setcenter
#undef RectExport_getrelcenter
#undef RectExport_setrelcenter
#undef RectExport_getsize
#undef RectExport_setsize
#undef RectExport_iterator
Expand Down
Loading
Loading