reworked image generation
This commit is contained in:
@@ -47,6 +47,9 @@ class generic_instruction(instruction):
|
||||
def get_block_height(self):
|
||||
return super().get_block_height()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.instruction_text
|
||||
|
||||
|
||||
|
||||
class if_instruction(instruction):
|
||||
@@ -57,8 +60,9 @@ class if_instruction(instruction):
|
||||
|
||||
def convert_to_image(self, x: int, y: int, width: int) -> int:
|
||||
true_width = self.get_true_width()
|
||||
block_height = self.get_block_height()
|
||||
|
||||
true_x, true_y, false_x, false_y = cti.draw_if_statement(self.instruction_text, x, y, true_width, width)
|
||||
true_x, true_y, false_x, false_y = cti.draw_if_statement(self.instruction_text, x, y, true_width, width, block_height)
|
||||
|
||||
self.draw_children(true_x, true_y, true_width, false_x, false_y, width-true_width)
|
||||
|
||||
@@ -120,6 +124,18 @@ class if_instruction(instruction):
|
||||
|
||||
return height
|
||||
|
||||
def __str__(self) -> str:
|
||||
res = "if\n"
|
||||
for instruction in self.true_case:
|
||||
res += '\t' + str(instruction) + '\n'
|
||||
|
||||
if self.false_case:
|
||||
res += "else\n"
|
||||
for instruction in self.false_case:
|
||||
res += '\t' + str(instruction) + '\n'
|
||||
|
||||
return res
|
||||
|
||||
|
||||
|
||||
class while_instruction_front(instruction):
|
||||
@@ -156,6 +172,12 @@ class while_instruction_front(instruction):
|
||||
|
||||
return height
|
||||
|
||||
def __str__(self) -> str:
|
||||
res = "while\n"
|
||||
for instruction in self.children:
|
||||
res += '\t' + str(instruction) + '\n'
|
||||
return res
|
||||
|
||||
class while_instruction_back(while_instruction_front):
|
||||
def __init__(self, condition_text: str, child_instructions: List[instruction]) -> None:
|
||||
super().__init__(condition_text, child_instructions)
|
||||
@@ -168,7 +190,12 @@ class while_instruction_back(while_instruction_front):
|
||||
|
||||
return y + block_height
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
res = "do\n"
|
||||
for instruction in self.children:
|
||||
res += '\t' + str(instruction) + '\n'
|
||||
res += "while"
|
||||
return res
|
||||
|
||||
class for_instruction(while_instruction_front):
|
||||
def __init__(self, variable_text: str, condition_text: str, child_instruction: List[instruction]) -> None:
|
||||
@@ -176,5 +203,26 @@ class for_instruction(while_instruction_front):
|
||||
self.variable_instruction = generic_instruction(variable_text)
|
||||
|
||||
def convert_to_image(self, x: int, y: int, width: int) -> int:
|
||||
block_height = super().get_block_height()
|
||||
|
||||
y = self.variable_instruction.convert_to_image(x, y, width)
|
||||
return super().convert_to_image(x,y, width)
|
||||
|
||||
children_x, children_y, children_width = cti.draw_while_loop_front(self.instruction_text, x, y, width, block_height)
|
||||
self.draw_children(children_x, children_y, children_width)
|
||||
|
||||
return y + block_height
|
||||
|
||||
def get_block_width(self):
|
||||
return max(super().get_block_width(), self.variable_instruction.get_block_width())
|
||||
|
||||
def get_block_height(self):
|
||||
return super().get_block_height() + self.variable_instruction.get_block_height()
|
||||
|
||||
def __str__(self) -> str:
|
||||
res = str(self.variable_instruction) + '\n'
|
||||
res += "for\n"
|
||||
|
||||
for instruction in self.children:
|
||||
res += "\t" + str(instruction) + '\n'
|
||||
|
||||
return res
|
||||
@@ -73,7 +73,7 @@ def draw_generic_instruction(instruction: str, x: int, y: int, width:int, height
|
||||
|
||||
|
||||
|
||||
def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_width:int) -> Tuple[int, int, int, int]:
|
||||
def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_width:int, block_height: int) -> Tuple[int, int, int, int]:
|
||||
"""Draw an if statement into the NSD"""
|
||||
if not output_img:
|
||||
raise Exception(ERROR_TEXT)
|
||||
@@ -91,6 +91,8 @@ def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_wid
|
||||
output_img.text((x + 5, y + text_height), "true", font = font, fill = (0), anchor="ld")
|
||||
output_img.text((x + block_width - 5, y + text_height), "false", font = font, fill = (0), anchor="rd")
|
||||
|
||||
output_img.line((x + true_width, y + text_height) + (x + true_width, y + block_height), fill=(0))
|
||||
|
||||
#x and y of "true" and "false" label
|
||||
return x, y + text_height, x + true_width, y + text_height
|
||||
|
||||
@@ -105,11 +107,9 @@ def draw_while_loop_front(condition: str, x: int, y: int, block_width: int, bloc
|
||||
|
||||
#the box
|
||||
output_img.line((x,y) + (x + block_width, y), fill=(0))
|
||||
output_img.line((x,y) + (x, y + block_width), fill=(0))
|
||||
output_img.line((x,y) + (x, y + block_height), fill=(0))
|
||||
output_img.line((x + block_offset, y + text_height) + (x + block_width, y + text_height), fill=(0))
|
||||
output_img.line((x + block_width, y) + (x + block_width, y + text_height), fill=(0))
|
||||
output_img.line((x, y + block_height) + (x + block_offset, y + block_height ), fill=(0))
|
||||
output_img.line((x + block_offset, y + block_height) + (x + block_offset, y + text_height), fill=(0))
|
||||
output_img.line((x + block_width, y) + (x + block_width, y+text_height), fill=(0))
|
||||
|
||||
#the text
|
||||
output_img.text((x + block_offset, y + text_height * .5), condition, font = font, fill = (0), anchor="lm")
|
||||
@@ -124,19 +124,21 @@ def draw_while_loop_back(condition: str, x: int, y: int, block_width: int, block
|
||||
|
||||
text_height = get_text_size(condition)[1]
|
||||
|
||||
block_offset = int(block_width * BLOCK_OFFSET_RATIO)
|
||||
|
||||
#the box
|
||||
output_img.line((x,y) + (x + block_width * .1, y), fill=0)
|
||||
output_img.line((x + block_width * .1, y) + (x + block_width * .1, y + block_height - text_height), fill=0)
|
||||
output_img.line((x + block_width * .1, y + block_height - text_height) + (x + block_width, y + block_height - text_height), fill=0)
|
||||
output_img.line((x,y) + (x + block_offset, y), fill=0)
|
||||
output_img.line((x + block_offset, y) + (x + block_offset, y + block_height - text_height), fill=0)
|
||||
output_img.line((x + block_offset, y + block_height - text_height) + (x + block_width, y + block_height - text_height), fill=0)
|
||||
output_img.line((x + block_width, y + block_height - text_height) + (x + block_width, y + block_height), fill=0)
|
||||
output_img.line((x,y + block_height) + (x + block_width, y + block_height), fill=0)
|
||||
output_img.line((x,y) + (x, y + block_height), fill=0)
|
||||
|
||||
#the text
|
||||
output_img.multiline_text((x + block_width * .1, y + block_height - text_height * .5), condition, font = font, fill = (0), anchor="lm")
|
||||
output_img.multiline_text((x + block_offset, y + block_height - text_height * .5), condition, font = font, fill = (0), anchor="lm")
|
||||
|
||||
#the x, y offset then the x,y draw size (the canvas)
|
||||
return x + block_width * .1, y, block_width * .9
|
||||
#x, y and width of children
|
||||
return x + block_offset, y, block_width - block_offset
|
||||
|
||||
def NSD_save(filepath: str):
|
||||
"""Save the created file"""
|
||||
|
||||
@@ -43,7 +43,8 @@ class NassiShneidermanDiagram:
|
||||
height = scope.get_height()
|
||||
with NSD_writer(output_path, width, height):
|
||||
y = 0
|
||||
for instruction in scope:
|
||||
for instruction in scope:
|
||||
print(instruction.instruction_text)
|
||||
y = instruction.convert_to_image(0, y, width)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -6,7 +6,7 @@ from enum import IntEnum
|
||||
from typing import Union
|
||||
|
||||
NUMERIC_CONSTANT_PATTERN = re.compile(r"""([0-9]+)|(true)|(false)""")
|
||||
KEYWORD_PATTERN = re.compile(r"""(return)|(continue)|(break)|(new)""")
|
||||
KEYWORD_PATTERN = re.compile(r"""(return)$|(continue)$|(break)$|(new)$""")
|
||||
STRING_LITERAL_PATTERN = re.compile(r"""('|\")(.*)(\"|')""")
|
||||
MATH_OP_PATTERN = re.compile(r"""\+|-|\*|/|<|>""")
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ class Function_scope(Iterable):
|
||||
self.args = args
|
||||
|
||||
def get_height(self) -> int:
|
||||
h = 0.0
|
||||
h = 0
|
||||
for inst in self.contents:
|
||||
h += inst.get_block_height()
|
||||
return int(h)
|
||||
return max(h, 5) #a NSD has to be at least 5 pixels tall
|
||||
|
||||
def get_width(self) -> int:
|
||||
w = 200 #minimum width for every block
|
||||
|
||||
Reference in New Issue
Block a user