Skip to content

Commit

Permalink
release 0.5a0
Browse files Browse the repository at this point in the history
  • Loading branch information
hx2A committed Jul 18, 2021
1 parent 800820a commit 55b3baf
Show file tree
Hide file tree
Showing 66 changed files with 2,342 additions and 630 deletions.
3 changes: 1 addition & 2 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ representative at an online or offline event.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[INSERT CONTACT METHOD].
reported to the community leaders responsible for enforcement.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
Expand Down
53 changes: 50 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,59 @@
py5
---

py5 is a new version of Processing_ for Python 3.8+. It makes the Processing_ Java libraries available to the CPython interpreter using JPype_.
.. image:: https://img.shields.io/pypi/dm/py5?label=py5%20PyPI%20downloads

This entire repository is created by the meta-programming project py5generator_. Therefore, this code should not be edited manually. Any issues, etc, should be directed to the py5generator_ repository.
.. image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/hx2A/py5examples/HEAD?urlpath=lab

py5 is a new version of Processing_ for Python 3.8+. It makes the Processing_ Java libraries available to the CPython interpreter using JPype_. It can do just about everything Processing_ can do, except with Python instead of Java code.

The goal of py5 is to create a new version of Processing that is integrated into the Python ecosystem. Built into the library are thoughtful choices about how to best get py5 to work with other popular Python libraries such as `numpy
<https://www.numpy.org/>`_ or `Pillow
<https://python-pillow.org/>`_.

Here is a simple example of a working py5 Sketch:

.. code::
import py5
def setup():
py5.size(200, 200)
py5.rect_mode(py5.CENTER)
def draw():
py5.square(py5.mouse_x, py5.mouse_y, 10)
py5.run_sketch()
If you have Java 11 installed on your computer, you can install py5 using pip:

.. code::
pip install py5
`Detailed installation instructions
<http://py5.ixora.io/install/>`_ are available on the documentation website. There are some `Special Notes for Mac Users
<http://py5.ixora.io/tutorials/mac-users/>`_ that you should read if you use OSX.

There are currently four basic ways to use py5. They are:

- **module mode**, as shown above
- **class mode**: create a Python class inherited from ``py5.Sketch``, and support multiple Sketches running at the same time.
- **imported mode**: simplified code that omits the ``py5.`` prefix. This mode is supported by the py5 Jupyter notebook kernel and the ``run_sketch`` command line utility.
- **static mode**: functionless code to create static images. This mode is supported by the py5bot Jupyter notebook kernel and the ``%%py5bot`` IPython magic.

The py5 library is created by the meta-programming project py5generator_. Therefore, the py5 code should not be changed manually. Any issues, etc, should be directed to the py5generator_ repository.

The `py5 documentation website
<http://py5.ixora.io/>`_ provides basic tutorials and reference documentation. See py5examples_ for example code.
<http://py5.ixora.io/>`_ provides basic tutorials and reference documentation. The website is very much a work in progress. The `reference documentation
<http://py5.ixora.io/reference/>`_ is solid but the how-to's and tutorials need a lot of work. See the py5examples_ repository for some working examples.

.. _Processing: https://github.com/processing/processing4
.. _JPype: https://github.com/jpype-project/jpype
Expand Down
736 changes: 464 additions & 272 deletions py5/__init__.py

Large diffs are not rendered by default.

44 changes: 24 additions & 20 deletions py5/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from jpype import JClass

from .base import Py5Base
from .mixins import PixelMixin
from .mixins import PixelPy5GraphicsMixin
from .font import Py5Font # noqa
from .shader import Py5Shader, _return_py5shader, _load_py5shader # noqa
from .shape import Py5Shape, _return_py5shape, _load_py5shape # noqa
Expand All @@ -49,7 +49,7 @@ def decorated(self_, *args):
_Py5GraphicsHelper = JClass('py5.core.Py5GraphicsHelper')


class Py5Graphics(PixelMixin, Py5Base):
class Py5Graphics(PixelPy5GraphicsMixin, Py5Base):
"""Main graphics and rendering context, as well as the base ``API`` implementation
for processing "core".

Expand All @@ -65,6 +65,11 @@ class Py5Graphics(PixelMixin, Py5Base):
``Py5Graphics.end_draw()`` methods (see example) are necessary to set up the
buffer and to finalize it. The fields and methods for this class are extensive.

It is critically important that calls to this object's drawing methods are only
used between ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``.
Forgetting to call ``Py5Graphics.begin_draw()`` will likely result in an ugly
and unhelpful Java exception.

To create a new graphics context, use the ``create_graphics()`` function. Do not
use the syntax ``Py5Graphics()``.
"""
Expand Down Expand Up @@ -306,21 +311,19 @@ def _get_pixel_density(self) -> int:
pixel_density: int = property(fget=_get_pixel_density)

def _get_pixel_height(self) -> int:
"""When ``pixel_density(2)`` was used in ``settings()`` to make use of a high
resolution display (called a Retina display on OSX or high-dpi on Windows and
Linux), the width and height of the Py5Graphics drawing surface does not change,
but the number of pixels is doubled.
"""Height of the Py5Graphics drawing surface in pixels.

Underlying Java field: PGraphics.pixelHeight

Notes
-----

When ``pixel_density(2)`` was used in ``settings()`` to make use of a high
resolution display (called a Retina display on OSX or high-dpi on Windows and
Linux), the width and height of the Py5Graphics drawing surface does not change,
but the number of pixels is doubled. As a result, all operations that use pixels
(like ``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this
Height of the Py5Graphics drawing surface in pixels. When ``pixel_density(2)``
was used in ``settings()`` to make use of a high resolution display (called a
Retina display on OSX or high-dpi on Windows and Linux), the width and height of
the Py5Graphics drawing surface does not change, but the number of pixels is
doubled. As a result, all operations that use pixels (like
``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this
doubled space. As a convenience, the variables ``Py5Graphics.pixel_width`` and
``pixel_height`` hold the actual width and height of the drawing surface in
pixels. This is useful for any Py5Graphics objects that use the
Expand All @@ -335,21 +338,19 @@ def _get_pixel_height(self) -> int:
pixel_height: int = property(fget=_get_pixel_height)

def _get_pixel_width(self) -> int:
"""When ``pixel_density(2)`` was used in ``settings()`` to make use of a high
resolution display (called a Retina display on OSX or high-dpi on Windows and
Linux), the width and height of the Py5Graphics drawing surface does not change,
but the number of pixels is doubled.
"""Width of the Py5Graphics drawing surface in pixels.

Underlying Java field: PGraphics.pixelWidth

Notes
-----

When ``pixel_density(2)`` was used in ``settings()`` to make use of a high
resolution display (called a Retina display on OSX or high-dpi on Windows and
Linux), the width and height of the Py5Graphics drawing surface does not change,
but the number of pixels is doubled. As a result, all operations that use pixels
(like ``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this
Width of the Py5Graphics drawing surface in pixels. When ``pixel_density(2)``
was used in ``settings()`` to make use of a high resolution display (called a
Retina display on OSX or high-dpi on Windows and Linux), the width and height of
the Py5Graphics drawing surface does not change, but the number of pixels is
doubled. As a result, all operations that use pixels (like
``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this
doubled space. As a convenience, the variables ``pixel_width`` and
``Py5Graphics.pixel_height`` hold the actual width and height of the drawing
surface in pixels. This is useful for any Py5Graphics objects that use the
Expand Down Expand Up @@ -7220,6 +7221,9 @@ def hint(self, which: int, /) -> None:
options might graduate to standard features instead of hints over time, or be
added and removed between (major) releases.

Like other ``Py5Graphics`` methods, ``hint()`` can only be used between calls to
``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``.

Hints used by the Default Renderer
----------------------------------

Expand Down
49 changes: 47 additions & 2 deletions py5/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from typing import overload, List, Union # noqa

from .base import Py5Base
from .mixins import PixelMixin
from .mixins import PixelPy5ImageMixin


def _return_py5image(f):
Expand All @@ -37,7 +37,7 @@ def decorated(self_, *args):
return decorated


class Py5Image(PixelMixin, Py5Base):
class Py5Image(PixelPy5ImageMixin, Py5Base):
"""Datatype for storing images.
Underlying Java class: PImage.PImage
Expand Down Expand Up @@ -117,6 +117,51 @@ def _get_height(self) -> int:
return self._instance.height
height: int = property(fget=_get_height)

def _get_pixel_density(self) -> int:
"""Pixel density of the Py5Image object.
Underlying Java field: PImage.pixelDensity
Notes
-----
Pixel density of the Py5Image object. This will always be equal to 1, even if
the Sketch used ``pixel_density()`` to set the pixel density to a value greater
than 1.
"""
return self._instance.pixelDensity
pixel_density: int = property(fget=_get_pixel_density)

def _get_pixel_height(self) -> int:
"""Height of the Py5Image object in pixels.
Underlying Java field: PImage.pixelHeight
Notes
-----
Height of the Py5Image object in pixels. This will be the same as
``Py5Image.height``, even if the Sketch used ``pixel_density()`` to set the
pixel density to a value greater than 1.
"""
return self._instance.pixelHeight
pixel_height: int = property(fget=_get_pixel_height)

def _get_pixel_width(self) -> int:
"""Width of the Py5Image object in pixels.
Underlying Java field: PImage.pixelWidth
Notes
-----
Width of the Py5Image object in pixels. This will be the same as
``Py5Image.width``, even if the Sketch used ``pixel_density()`` to set the pixel
density to a value greater than 1.
"""
return self._instance.pixelWidth
pixel_width: int = property(fget=_get_pixel_width)

def _get_pixels(self) -> NDArray[(Any,), Int]:
"""The pixels[] array contains the values for all the pixels in the image.
Expand Down
Binary file modified py5/jars/core.jar
Binary file not shown.
Binary file modified py5/jars/dxf/dxf.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-linux-aarch64.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-linux-amd64.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-linux-armv6hf.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-linux-i586.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-macosx-universal.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-windows-amd64.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt-natives-windows-i586.jar
Binary file not shown.
Binary file modified py5/jars/gluegen-rt.jar
Binary file not shown.
Binary file removed py5/jars/javafx-swt.jar
Binary file not shown.
Binary file removed py5/jars/javafx.base.jar
Binary file not shown.
Binary file removed py5/jars/javafx.controls.jar
Binary file not shown.
Binary file removed py5/jars/javafx.fxml.jar
Binary file not shown.
Binary file removed py5/jars/javafx.graphics.jar
Binary file not shown.
Binary file removed py5/jars/javafx.media.jar
Binary file not shown.
Binary file removed py5/jars/javafx.swing.jar
Binary file not shown.
Binary file removed py5/jars/javafx.web.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-linux-aarch64.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-linux-amd64.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-linux-armv6hf.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-linux-i586.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-macosx-universal.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-windows-amd64.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all-natives-windows-i586.jar
Binary file not shown.
Binary file modified py5/jars/jogl-all.jar
Binary file not shown.
Binary file modified py5/jars/pdf/pdf.jar
Binary file not shown.
Binary file modified py5/jars/py5.jar
Binary file not shown.
Binary file modified py5/jars/svg/svg.jar
Binary file not shown.
2 changes: 2 additions & 0 deletions py5/java_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ def init_jpype_converters():
data = [
("processing.core.PImage", Py5Image),
("processing.core.PImage", Py5Graphics),
("processing.core.PGraphics", Py5Graphics),
("processing.core.PFont", Py5Font),
("processing.core.PShape", Py5Shape),
("processing.opengl.PShader", Py5Shader),
("processing.core.PApplet", Sketch),
("py5.core.Sketch", Sketch),
]

def convert(jcls, obj):
Expand Down
30 changes: 22 additions & 8 deletions py5/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,31 @@
#
# *****************************************************************************
import sys
import re
from pathlib import Path
from collections import defaultdict
from typing import Union
import line_profiler

from jpype import JImplements, JOverride, JString, JClass
from jpype import JImplements, JOverride, JString

import stackprinter

import py5_tools
from . import custom_exceptions


_JavaNullPointerException = JClass('java.lang.NullPointerException')

# *** stacktrace configuration ***
# set stackprinter color style. Default is plaintext. Other choices are darkbg,
# darkbg2, darkbg3, lightbg, lightbg2, lightbg3.
_stackprinter_style = 'plaintext'
# prune tracebacks to only show only show stack levels in the user's py5 code.
_prune_tracebacks = True
_module_install_dir = str(Path(__file__).parent)

_MODULE_INSTALL_DIR = str(Path(__file__).parent)
_PY5TOOLS_MODULE_INSTALL_DIR = str(Path(py5_tools.__file__).parent)

_PY5_STATIC_CODE_FILENAME_REGEX = re.compile(
r'File "[^\"]*?_PY5_STATIC_(SETUP|SETTINGS|FRAMEWORK)_CODE_\.py", line \d+, in .*')

_EXCEPTION_MSGS = {
**custom_exceptions.CUSTOM_EXCEPTION_MSGS,
Expand Down Expand Up @@ -78,11 +81,16 @@ def handle_exception(println, exc_type, exc_value, exc_tb):
tb = exc_tb.tb_next
while hasattr(tb, 'tb_next') and hasattr(tb, 'tb_frame'):
f_code = tb.tb_frame.f_code
if f_code.co_filename.startswith(_module_install_dir):
py5info.append((Path(f_code.co_filename[(len(_module_install_dir) + 1):]).parts,
if f_code.co_filename.startswith(_MODULE_INSTALL_DIR):
py5info.append((Path(f_code.co_filename[(len(_MODULE_INSTALL_DIR) + 1):]).parts,
f_code.co_name))
if trim_tb is None:
trim_tb = prev_tb
elif f_code.co_filename.startswith(_PY5TOOLS_MODULE_INSTALL_DIR):
py5info.append((Path(f_code.co_filename[(
len(_PY5TOOLS_MODULE_INSTALL_DIR) + 1):]).parts, f_code.co_name))
if trim_tb is None:
trim_tb = prev_tb
prev_tb = tb
tb = tb.tb_next
if trim_tb:
Expand All @@ -97,7 +105,8 @@ def handle_exception(println, exc_type, exc_value, exc_tb):
show_vals='line',
style=_stackprinter_style,
suppressed_paths=[r"lib/python.*?/site-packages/numpy/",
r"lib/python.*?/site-packages/py5/"])
r"lib/python.*?/site-packages/py5/",
r"lib/python.*?/site-packages/py5tools/"])

if _prune_tracebacks:
errmsg = errmsg.replace(
Expand All @@ -108,6 +117,11 @@ def handle_exception(println, exc_type, exc_value, exc_tb):
str(exc_value),
py5info))

m = _PY5_STATIC_CODE_FILENAME_REGEX.search(errmsg)
if m:
errmsg = "py5 encountered an error in your code:" + \
errmsg[m.span()[1]:]

println(errmsg, stderr=True)

sys.last_type, sys.last_value, sys.last_traceback = exc_type, exc_value, exc_tb
Expand Down
2 changes: 1 addition & 1 deletion py5/mixins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
from .math import MathMixin # noqa
from .data import DataMixin # noqa
from .threads import ThreadsMixin # noqa
from .pixels import PixelMixin # noqa
from .pixels import PixelMixin, PixelPy5GraphicsMixin, PixelPy5ImageMixin # noqa
from .print_tools import PrintlnStream, _WidgetPrintlnStream, _DefaultPrintlnStream, _DisplayPubPrintlnStream # noqa
Loading

0 comments on commit 55b3baf

Please sign in to comment.