Skip to content

Commit

Permalink
implement draw functions
Browse files Browse the repository at this point in the history
  • Loading branch information
TabulateJarl8 committed May 15, 2021
1 parent 7b10a9f commit a083dd7
Show file tree
Hide file tree
Showing 7 changed files with 619 additions and 161 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ ti842py is a TI-BASIC to Python 3 transpiler. A transpiler is a piece of softwar
- `Menu()`
- `toString()`
- `randInt()`

- **Some drawing functions**

### Planned Features
- `Return`
- `eval()`/`expr()`
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

install_requires = [
"basically-ti-basic>=0.1.4",
"keyboard>=0.13.5",
"pythondialog>=3.5.1"
"pythondialog>=3.5.1",
"graphics.py>=5.0.0"
]

with open("README.md", "r") as fh:
Expand Down
2 changes: 1 addition & 1 deletion ti842py/__version__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__title__ = "ti842py"
__description__ = "TI-BASIC to Python 3 Transpiler"
__url__ = "https://github.com/TabulateJarl8/ti842py"
__version__ = "0.3.1"
__version__ = "0.4.0"
__author__ = "Tabulate"
__author_email__ = "[email protected]"
__license__ = "GPLv3"
Expand Down
70 changes: 69 additions & 1 deletion ti842py/tiParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ def __init__(self, basic):
self.UTILS[os.path.splitext(file)[0]]["imports"] = [line.rstrip() for line in f.readlines() if line.startswith("import ") or line.startswith("from ")]
self.UTILS[os.path.splitext(file)[0]]["enabled"] = False

self.drawLock = False

def convertLine(self, index, line):
statement = ""
# TODO: Make rules for :, dont fully understand it yet
Expand Down Expand Up @@ -259,13 +261,74 @@ def convertLine(self, index, line):
options.extend([tiMenu[i].strip(" \""), tiMenu[i + 1].strip(" \"")])
statement = menu(title, options)
self.UTILS["menu"]["enabled"] = True
# Line(
elif line.startswith('Line('):
statement = closeOpen(line.replace('Line(', 'draw.line('))
self.UTILS['draw']['enabled'] = True

# BackgroundOff
elif line == 'BackgroundOff':
statement = 'draw.backgroundOff()'
self.UTILS['draw']['enabled'] = True

# Background On
elif line.startswith('BackgroundOn '):
statement = line.replace('BackgroundOn ', 'draw.backgroundOn(')
statement = statement.split('(')[0] + '("' + statement.split('(')[1] + '")'
self.UTILS['draw']['enabled'] = True

# ClrDraw
elif line == 'ClrDraw':
statement = 'draw.clrDraw()'
self.UTILS['draw']['enabled'] = True

# Circle
elif line.startswith('Circle('):
statement = closeOpen(line.replace('Circle(', 'draw.circle('))
self.UTILS['draw']['enabled'] = True

# Text
elif line.startswith('Text('):
statement = closeOpen(line.replace('Text(', 'draw.text('))
self.UTILS['draw']['enabled'] = True

# Pxl-On
elif line.startswith('Pxl-On('):
statement = closeOpen(line.replace('Pxl-On(', 'draw.pxlOn('))
self.UTILS['draw']['enabled'] = True

# Pxl-Off
elif line.startswith('Pxl-Off('):
statement = closeOpen(line.replace('Pxl-Off(', 'draw.pxlOff('))
self.UTILS['draw']['enabled'] = True

# pxl-Test
elif line.startswith('pxl-Test('):
statement = closeOpen(line.replace('pxl-Test(', 'draw.pxlTest('))
self.UTILS['draw']['enabled'] = True

# Pt-On
elif line.startswith('Pt-On('):
statement = closeOpen(line.replace('Pt-On(', 'draw.ptOn('))
self.UTILS['draw']['enabled'] = True

# Pt-Off
elif line.startswith('Pt-Off('):
statement = closeOpen(line.replace('Pt-Off(', 'draw.ptOff('))
self.UTILS['draw']['enabled'] = True

# TextColor
elif line.startswith('TextColor('):
statement = closeOpen(line.replace('TextColor(', 'draw.textColor('))
self.UTILS['draw']['enabled'] = True

else:
# Things that can be alone on a line
if line.startswith("getKey") or line.startswith("abs") or line.startswith("sqrt") or line.startswith("toString(") or line.startswith('randInt('):
statement = line
else:
statement = "# UNKNOWN INDENTIFIER: {}".format(line)
logger.warning("Unknown indentifier on line %s", index)
logger.warning("Unknown indentifier on line %s", index + 1)

# Fix things contained within statement

Expand Down Expand Up @@ -313,6 +376,11 @@ def convertLine(self, index, line):
statement = ' '.join(split_statement)

self.UTILS['random']['enabled'] = True

if self.UTILS['draw']['enabled'] == True and self.drawLock == False:
self.drawLock = True
statement = ['draw = Draw()', 'draw.openWindow()', statement]

return statement

def toPython(self):
Expand Down
160 changes: 160 additions & 0 deletions ti842py/utils/draw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
from graphics import *
import time

class Draw:
def __init__(self):
self.win = None
self.pixels = {}
self.points = {}
self.colors = {'BLUE': 'blue', 'RED': 'red', 'BLACK': 'black', 'MAGENTA': 'magenta', 'GREEN': 'green', 'ORANGE': 'orange', 'BROWN': 'brown', 'NAVY': 'navy', 'LTBLUE': 'light sky blue', 'YELLOW': 'yellow', 'WHITE': 'white', 'LTGRAY': 'light gray', 'MEDGRAY': 'dark gray', 'GRAY': 'gray', 'DARKGRAY': 'dark slate gray'}
self.colorNumbers = {'10': 'blue', '11': 'red', '12': 'black', '13': 'magenta', '14': 'green', '15': 'orange', '16': 'brown', '17': 'navy', '18': 'light sky blue', '19': 'yellow', '20': 'white', '21': 'light gray', '22': 'dark gray', '23': 'gray', '24': 'dark slate gray'}
self.currentTextColor = 'blue'

def _slow(function):
def child_function(*args, **kwargs):
function(*args, **kwargs)
time.sleep(0.01)
return child_function

def openWindow(self):
# The TI-84 Plus CE has a graph resolution of 250x160 pixels
# Not to be confused with the screen resolution of 320x240 pixels
self.win = GraphWin('ti842py', 250, 160)
self.win.setBackground('white')

def closeWindow(self):
self.win.close()

def graphCoordsToPixels(self, x, y, minX=-10, maxX=10, minY=-10, maxY=10):
# Can work for vertical or horizontal coords
xs = (maxX - minX) / 250
ys = (minY - maxY) / 160
horiz = (x - minX) / xs
vertical = (y - maxY) / ys
return horiz, vertical

def tiColorToGraphicsColor(self, color):
color = str(color)
for color1, color2 in self.colors.items():
color = color.replace(color1, color2)
for color1, color2 in self.colorNumbers.items():
color = color.replace(color1, color2)
return color

@_slow
def backgroundOn(self, color):
self.win.setBackground(self.tiColorToGraphicsColor(color))

@_slow
def backgroundOff(self):
self.win.setBackground('white')

def clrDraw(self):
for item in self.win.items[:]:
item.undraw()
self.win.update()

@_slow
def circle(self, x, y, r, color='blue', linestyle=''):
# TODO: Implement linestyle
c = Circle(Point(self.graphCoordsToPixels(x), self.graphCoordsToPixels(y)), r)
c.setOutline(self.tiColorToGraphicsColor(color))
c.draw(self.win)

@_slow
def line(self, x1, y1, x2, y2, erase=1, color='blue', style=1):
# TODO: Erase and style not implemented yet
x1, y1 = self.graphCoordsToPixels(x1, y1)
x2, y2 = self.graphCoordsToPixels(x2, y2)
line = Line(Point(x1, y1), Point(x2, y2))
line.setOutline(self.tiColorToGraphicsColor(color))
line.draw(self.win)

@_slow
def textColor(self, color):
self.currentTextColor = self.tiColorToGraphicsColor(color)

@_slow
def text(self, row, column, *args):
# TODO: Set font size and use row/column instead of x and y
text = ''.join(args)
message = Text(Point(column, row), text.upper())
message.setTextColor(self.currentTextColor)
message.draw(self.win)

@_slow
def pxlOn(self, row, column, color='blue'):
# Row = y; Column = x
pnt = Point(column, row)
pnt.setOutline(self.tiColorToGraphicsColor(color))
if not column in self.pixels:
self.pixels[str(column)] = {}
self.pixels[str(column)][str(row)] = pnt

pnt.draw(self.win)

@_slow
def pxlOff(self, row, column):
if str(column) in self.pixels:
if str(row) in self.pixels[str(column)]:
self.pixels[str(column)][str(row)].undraw()
del self.pixels[str(column)][str(row)]

@_slow
def pxlTest(self, row, column):
if str(column) in self.pixels and str(row) in self.pixels[str(column)]:
return True
return False

@_slow
def ptOn(self, x, y, mark=1, color='blue'):
x, y = self.graphCoordsToPixels(x, y)

if str(x) not in self.points:
self.points[str(x)] = {}
if str(y) not in self.points[str(x)]:
self.points[str(x)][str(y)] = {}


# If mark is unknown, it will default to 1, so test for 1 with `else`

if mark in [2, 6]:
# 3x3 box
p1x = (x - 3 / 2)
p1y = (y + 3 / 2)
p2x = (x + 3 / 2)
p2y = (y - 3 / 2)
rec = Rectangle(Point(p1x, p1y), Point(p2x, p2y))
rec.setOutline(self.tiColorToGraphicsColor(color))
rec.draw(self.win)
self.points[str(x)][str(y)][str(mark)] = (rec,)
elif mark in [3, 7]:
# 3x3 cross
line1 = Line(Point(x - 2, y), Point(x + 2, y))
line1.setOutline(self.tiColorToGraphicsColor(color))
line1.draw(self.win)
line2 = Line(Point(x, y - 2), Point(x, y + 2))
line2.setOutline(self.tiColorToGraphicsColor(color))
line2.draw(self.win)
self.points[str(x)][str(y)][str(mark)] = (line1, line2)
else:
# Dot
p1x = (x - 2 / 2)
p1y = (y + 2 / 2)
p2x = (x + 2 / 2)
p2y = (y - 2 / 2)
rec = Rectangle(Point(p1x, p1y), Point(p2x, p2y))
rec.setFill(self.tiColorToGraphicsColor(color))
rec.setOutline(self.tiColorToGraphicsColor(color))
rec.draw(self.win)
self.points[str(x)][str(y)][str(mark)] = (rec,)

@_slow
def ptOff(self, x, y, mark=1):
x, y = self.graphCoordsToPixels(x, y)
if str(x) in self.points:
if str(y) in self.points[str(x)]:
if str(mark) in self.points[str(x)][str(y)]:
for item in self.points[str(x)][str(y)][str(mark)]:
item.undraw()
del self.points[str(x)][str(y)][str(mark)]
Loading

0 comments on commit a083dd7

Please sign in to comment.