Full code listing for a blogpost of mine - https://alcarney.me/blog/til-python-cmd/
import cmd | |
import textwrap | |
import matplotlib.pyplot as plt | |
from stylo import __version__ | |
from stylo.color import FillColor | |
from stylo.image import LayeredImage | |
from stylo.shape import Circle, Square | |
intro_text = """\ | |
Interactive Shell for Stylo v{} | |
---------------------------------- | |
Type `q` or `Ctrl-D` to quit. | |
Type `help` or `?` for an overview `help <command>` for more details. | |
""" | |
doc_text = """\ | |
Interactive Shell for Stylo v{} | |
------------------------------- | |
This is an interactive shell interface to the Stylo Python package. | |
Commands: | |
--------- | |
""" | |
class StyloPrompt(cmd.Cmd): | |
prompt = "-> " | |
ruler = "" | |
intro = intro_text.format(__version__) | |
doc_header = doc_text.format(__version__) | |
def __init__(self): | |
super().__init__() | |
self.image = LayeredImage() | |
self.fig, self.ax = plt.subplots(1, figsize=(12, 12)) | |
self.ax.get_yaxis().set_visible(False) | |
self.ax.get_xaxis().set_visible(False) | |
self.update_image() | |
def do_reset(self, args): | |
"""reset <size> <color> | |
Reset the image back to a blank canvas with a given <size> | |
and background <color>. | |
The <size> parameter is a dimensionless scale applied to the image | |
and corresponds to the distance between the top and bottom of the | |
image. | |
The <color> parameter is a 6 digit hex number which represents the | |
color in RGB format. | |
Example: | |
-> reset 2.5 00aaff | |
""" | |
size, color = args.split(" ") | |
size = float(size) | |
self.image = LayeredImage(background=color, scale=size) | |
def do_save(self, args): | |
"""save <width> <height> <filename> | |
Save the current image to <filename> with a given <width> and | |
<height>. Dimensions are in pixels. | |
Example: | |
-> save 1920 1080 image.png | |
""" | |
width, height, filename = args.split(" ") | |
width = int(width) | |
height = int(height) | |
self.image(width, height, filename=filename) | |
def do_circle(self, args): | |
"""circle <x> <y> <r> <color> | |
This command will draw a circle centered at the coordinates (<x>, <y>) | |
with radius given by <r>. The <color> argument is a 6 digit hex | |
representing a color in RGB format. | |
Example: | |
-> circle 0.5 0.5 1 ff0000 | |
""" | |
x, y, r, color = args.split(" ") | |
circle = Circle(float(x), float(y), float(r), fill=True) | |
self.image.add_layer(circle, FillColor(color)) | |
def do_square(self, args): | |
"""square <x> <y> <size> <color> | |
This command will draw a square centered as (<x>, <y>) with side | |
length given by <size>. The <color> argument is a 6 digit hex color | |
representing a color in RGB format. | |
Example: | |
-> square -0.2 0.4 1.5 00ff00 | |
""" | |
x, y, size, color = args.split(" ") | |
square = Square(float(x), float(y), float(size)) | |
self.image.add_layer(square, FillColor(color)) | |
def default(self, line): | |
"""This method is called whenever the command doesn't match any of | |
the builtin commands or the commands defined above.""" | |
if line == "q" or line == "EOF": | |
return True | |
return super().default(line) | |
def postcmd(self, stop, line): | |
"""This method is called after each command has been processed and | |
this is where we can add feddback for the user by drawing the image | |
they have defined so far. | |
""" | |
if stop: | |
return True | |
self.update_image() | |
def update_image(self): | |
# Re-render the image | |
self.image(1920, 1080) | |
# Update the preview | |
self.ax.imshow(self.image.data) | |
self.fig.show() | |
if __name__ == "__main__": | |
prompt = StyloPrompt() | |
prompt.cmdloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment